patch-2.3.99-pre4 linux/drivers/net/defxx.c

Next file: linux/drivers/net/defxx.h
Previous file: linux/drivers/net/Space.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre3/linux/drivers/net/defxx.c linux/drivers/net/defxx.c
@@ -194,11 +194,12 @@
  *		12-Sep-96	LVS		Reset current address to factory address during
  *							device open.  Updated transmit path to post a
  *							single fragment which includes PRH->end of data.
+ *		Mar 2000	AC		Did various cleanups for 2.3.x
  */
 
 /* Version information string - should be updated prior to each new release!!! */
 
-static const char *version = "defxx.c:v1.04 09/16/96  Lawrence V. Stefani (stefani@lkg.dec.com)\n";
+static const char *version = "defxx.c:v1.05 2000/03/26  Lawrence V. Stefani (stefani@lkg.dec.com) and others\n";
 
 /* Include files */
 
@@ -236,11 +237,11 @@
 
 /* Define global routines */
 
-int	dfx_probe(struct net_device *dev);
+int	dfx_probe(void);
 
 /* Define module-wide (static) routines */
 
-static struct net_device *dfx_alloc_device(struct net_device *dev, u16 iobase);
+static struct net_device *dfx_alloc_device(u16 iobase);
 
 static void		dfx_bus_init(struct net_device *dev);
 static void		dfx_bus_config_check(DFX_board_t *bp);
@@ -402,29 +403,9 @@
  *   dev - pointer to device information
  *
  * Functional Description:
- *   This routine is called by the OS for each FDDI device name (fddi0,
- *   fddi1,...,fddi6, fddi7) specified in drivers/net/Space.c.  Since
- *   the DEFXX.C driver currently does not support being loaded as a
- *   module, dfx_probe() will initialize all devices the first time
- *   it is called.
- *
- *   Let's say that dfx_probe() is getting called to initialize fddi0.
- *   Furthermore, let's say there are three supported controllers in the
- *   system.  Before dfx_probe() leaves, devices fddi0, fddi1, and fddi2
- *   will be initialized and a global flag will be set to indicate that
- *   dfx_probe() has already been called.
- *
- *   However...the OS doesn't know that we've already initialized
- *   devices fddi1 and fddi2 so dfx_probe() gets called again and again
- *   until it reaches the end of the device list for FDDI (presently,
- *   fddi7).  It's important that the driver "pretend" to probe for
- *   devices fddi1 and fddi2 and return success.  Devices fddi3
- *   through fddi7 will return failure since they weren't initialized.
- *
- *   This algorithm seems to work for the time being.  As other FDDI
- *   drivers are written for Linux, a more generic approach (perhaps
- *   similar to the Ethernet card approach) may need to be implemented.
- *   
+ *   This routine is called by the OS once at startup to scan for
+ *   DEFXX cards.
+ *
  * Return Codes:
  *   0		 - This device (fddi0, fddi1, etc) configured successfully
  *   -ENODEV - No devices present, or no Digital FDDI EISA or PCI device
@@ -446,7 +427,9 @@
  *   the device structure.
  */
 
-int __init dfx_probe(struct net_device *dev)
+static struct net_device *bp_root;
+
+int __init dfx_probe(void)
 {
 	int				i;				/* used in for loops */
 	int				version_disp;	/* was version info string already displayed? */
@@ -456,44 +439,26 @@
 	u16				command;		/* PCI Configuration space Command register val */
 	u32				slot_id;		/* EISA hardware (slot) ID read from adapter */
 	DFX_board_t		*bp;			/* board pointer */
+	struct net_device *dev;
 
 	DBG_printk("In dfx_probe...\n");
 
-	/*
-	 * Verify whether we're going through dfx_probe() again
-	 *
-	 * If so, see if we're going through for a subsequent fddi device that
-	 * we've already initialized.  If we are, return success (0).  If not,
-	 * return failure (-ENODEV).
-	 */
-
 	version_disp = 0;				/* default to version string not displayed */
-	if (already_probed)
-		{
-		DBG_printk("Already entered dfx_probe\n");
-		if (dev != NULL)
-			if ((strncmp(dev->name, "fddi", 4) == 0) && (dev->base_addr != 0))
-				{
-				DBG_printk("In dfx_probe for fddi adapter (%s) we've already initialized it, so return success\n", dev->name);
-				return(0);
-				}
-		return(-ENODEV);
-		}
-	already_probed = 1;			/* set global flag */
+	already_probed = 1;				/* set global flag */
 
 	/* Scan for FDDI EISA controllers */
 
 	for (i=0; i < DFX_MAX_EISA_SLOTS; i++)		/* only scan for up to 16 EISA slots */
-		{
+	{
 		port = (i << 12) + PI_ESIC_K_SLOT_ID;	/* port = I/O address for reading slot ID */
 		slot_id = inl(port);					/* read EISA HW (slot) ID */
 		if ((slot_id & 0xF0FFFFFF) == DEFEA_PRODUCT_ID)
-			{
+		{
 			if (!version_disp)					/* display version info if adapter is found */
-				{
+			{
 				version_disp = 1;				/* set display flag to TRUE so that */
 				printk(version);				/* we only display this string ONCE */
-				}
+			}
 				
 			port = (i << 12);					/* recalc base addr */
 
@@ -501,46 +466,47 @@
 
 			port_len = PI_ESIC_K_CSR_IO_LEN;
 			if (check_region(port, port_len) == 0)
-				{
+			{
 				/* Allocate a new device structure for this adapter */
 
-				dev = dfx_alloc_device(dev, port);
+				dev = dfx_alloc_device(port);
 				if (dev != NULL)
-					{
+				{
 					/* Initialize board structure with bus-specific info */
-
 					bp = (DFX_board_t *) dev->priv;
+					bp->next = bp_root;
+					bp_root = dev;
 					bp->dev = dev;
 					bp->bus_type = DFX_BUS_TYPE_EISA;
 					if (dfx_driver_init(dev) == DFX_K_SUCCESS)
 						num_boards++;		/* only increment global board count on success */
 					else
 						dev->base_addr = 0;	/* clear port address field in device structure on failure */
-					}
 				}
+			}
 			else
 				printk("I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));
-			}
 		}
+	}
 
 	/* Scan for FDDI PCI controllers */
 
 	if (pci_present())						/* is PCI even present? */
 		while ((pdev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, pdev)))
-			{
+		{
 			if (!version_disp)					/* display version info if adapter is found */
-				{
+			{
 				version_disp = 1;				/* set display flag to TRUE so that */
 				printk(version);				/* we only display this string ONCE */
-				}
+			}
 
 			/* Verify that I/O enable bit is set (PCI slot is enabled) */
 
 			pci_read_config_word(pdev, PCI_COMMAND, &command);
 			if ((command & PCI_COMMAND_IO) == 0)
-				printk("I/O enable bit not set!  Verify that slot is enabled\n");
+				printk(KERN_ERR "defxx: I/O enable bit not set!  Verify that slot is enabled\n");
 			else
-				{
+			{
 				/* Turn off memory mapped space and enable mastering */
 
 				command |= PCI_COMMAND_MASTER;
@@ -556,28 +522,30 @@
 				port_len = PFI_K_CSR_IO_LEN;
 
 				if (check_region(port, port_len) == 0)
-					{
+				{
 					/* Allocate a new device structure for this adapter */
 
-					dev = dfx_alloc_device(dev, port);
+					dev = dfx_alloc_device(port);
 					if (dev != NULL)
-						{
+					{
 						/* Initialize board structure with bus-specific info */
 
 						bp = (DFX_board_t *) dev->priv;
 						bp->dev = dev;
+						bp->next = bp_root;
+						bp_root = dev;
 						bp->bus_type = DFX_BUS_TYPE_PCI;
 						bp->pci_dev = pdev;
 						if (dfx_driver_init(dev) == DFX_K_SUCCESS)
 							num_boards++;		/* only increment global board count on success */
 						else
 							dev->base_addr = 0;	/* clear port address field in device structure on failure */
-						}
 					}
-				else
-					printk("I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));
 				}
+				else
+					printk(KERN_ERR "defxx: I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));
 			}
+		}
 
 	/*
 	 * If we're at this point we're going through dfx_probe() for the first
@@ -589,7 +557,7 @@
 		return(0);
 	else
 		return(-ENODEV);
-	}
+}
 
 
 /*
@@ -639,32 +607,32 @@
  *   None
  */
 
-struct net_device __init *dfx_alloc_device( struct net_device *dev, u16 iobase)
+struct net_device __init *dfx_alloc_device(u16 iobase)
 {
 	struct net_device *tmp_dev;		/* pointer to a device structure */
+	int err;
 
 	DBG_printk("In dfx_alloc_device...\n");
 
 	/* Find next free fddi entry */
 
-	for (tmp_dev = dev; tmp_dev != NULL; tmp_dev = tmp_dev->next)
-		if ((strncmp(tmp_dev->name, "fddi", 4) == 0) && (tmp_dev->base_addr == 0))
-			break;
+	tmp_dev = dev_alloc("fddi%d", &err);
 	if (tmp_dev == NULL)
-		{
-		printk("Could not find free FDDI device structure for this adapter!\n");
+	{
+		printk(KERN_ERR "Could not find free FDDI device structure for this adapter!\n");
 		return(NULL);
-		}
+	}
 	DBG_printk("Device entry free, device name = %s\n", tmp_dev->name);
 
 	/* Allocate space for private board structure */
 
 	tmp_dev->priv = (void *) kmalloc(sizeof(DFX_board_t), GFP_KERNEL);
 	if (tmp_dev->priv == NULL)
-		{
-		printk("Could not allocate memory for private board structure!\n");
+	{
+		printk(KERN_ERR "defxx: Could not allocate memory for private board structure!\n");
+		kfree(tmp_dev);
 		return(NULL);
-		}
+	}
 	memset(tmp_dev->priv, 0, sizeof(DFX_board_t));	/* clear structure */
 
 	/* Initialize new device structure */
@@ -696,7 +664,7 @@
 
 	fddi_setup(tmp_dev);
 	return(tmp_dev);
-	}
+}
 
 
 /*
@@ -1370,22 +1338,22 @@
  *   if the open is successful.
  */
 
-int dfx_open(
-	struct net_device *dev
-	)
-
-	{
+int dfx_open(struct net_device *dev)
+{
 	DFX_board_t	*bp = (DFX_board_t *)dev->priv;
 
 	DBG_printk("In dfx_open...\n");
+	
+	MOD_INC_USE_COUNT;
 
 	/* Register IRQ - support shared interrupts by passing device ptr */
 
 	if (request_irq(dev->irq, (void *)dfx_interrupt, SA_SHIRQ, dev->name, dev))
-		{
-		printk("%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
-		return(-EAGAIN);
-		}
+	{
+		printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
+		MOD_DEC_USE_COUNT;
+		return -EAGAIN;
+	}
 
 	/*
 	 * Set current address to factory MAC address
@@ -1416,16 +1384,17 @@
 
 	bp->reset_type = PI_PDATA_A_RESET_M_SKIP_ST;	/* skip self-test */
 	if (dfx_adap_init(bp) != DFX_K_SUCCESS)
-		{
-		printk("%s: Adapter open failed!\n", dev->name);
-		return(-EAGAIN);
-		}
+	{
+		printk(KERN_ERR "%s: Adapter open failed!\n", dev->name);
+		free_irq(dev->irq, dev);
+		MOD_DEC_USE_COUNT;
+		return -EAGAIN;
+	}
 
 	/* Set device structure info */
-
 	netif_start_queue(dev);
 	return(0);
-	}
+}
 
 
 /*
@@ -1460,11 +1429,8 @@
  *   routine.
  */
 
-int dfx_close(
-	struct net_device *dev
-	)
-
-	{
+int dfx_close(struct net_device *dev)
+{
 	DFX_board_t	*bp = (DFX_board_t *)dev->priv;
 
 	DBG_printk("In dfx_close...\n");
@@ -1514,8 +1480,10 @@
 	/* Deregister (free) IRQ */
 
 	free_irq(dev->irq, dev);
+	
+	MOD_DEC_USE_COUNT;
 	return(0);
-	}
+}
 
 
 /*
@@ -3491,6 +3459,30 @@
 	bp->cons_block_virt->xmt_rcv_data = prod_cons;
 	return;
 	}
+
+
+#ifdef MODULE
+
+int init_module(void)
+{
+	if(dfx_probe()<0)
+		return -ENODEV;
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	while(bp_root!=NULL)
+	{
+		struct net_device *tmp=bp_root;
+		DFX_board_t *priv=tmp->priv;
+		bp_root=priv->next;
+		kfree(tmp->priv);
+		kfree(tmp);
+	}
+}
+
+#endif
 
 
 /*

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)