patch-2.4.0-test3 linux/drivers/net/defxx.c
Next file: linux/drivers/net/eepro.c
Previous file: linux/drivers/net/cs89x0.c
Back to the patch index
Back to the overall index
- Lines: 285
- Date:
Wed Jul 5 10:56:13 2000
- Orig file:
v2.4.0-test2/linux/drivers/net/defxx.c
- Orig date:
Fri Jun 23 21:55:09 2000
diff -u --recursive --new-file v2.4.0-test2/linux/drivers/net/defxx.c linux/drivers/net/defxx.c
@@ -195,16 +195,12 @@
* 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
+ * Jun 2000 jgarzik PCI and resource alloc cleanups
*/
-/* Version information string - should be updated prior to each new release!!! */
-
-static const char *version = "defxx.c:v1.05 2000/03/26 Lawrence V. Stefani (stefani@lkg.dec.com) and others\n";
-
/* Include files */
#include <linux/module.h>
-
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
@@ -226,6 +222,10 @@
#include "defxx.h"
+/* Version information string - should be updated prior to each new release!!! */
+static char version[] __initdata =
+ "defxx.c:v1.05a 2000/06/11 Lawrence V. Stefani (stefani@lkg.dec.com) and others\n";
+
#define DYNAMIC_BUFFERS 1
#define SKBUFF_RX_COPYBREAK 200
@@ -235,10 +235,6 @@
*/
#define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128)
-/* Define global routines */
-
-int dfx_probe(void);
-
/* Define module-wide (static) routines */
static struct net_device *dfx_alloc_device(u16 iobase);
@@ -428,22 +424,92 @@
*/
static struct net_device *bp_root;
+static int version_disp;
+static int have_pci_driver;
+
+static struct pci_device_id dfx_pci_tbl[] __initdata = {
+ { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, PCI_ANY_ID, PCI_ANY_ID, },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, dfx_pci_tbl);
-int __init dfx_probe(void)
+static int __init dfx_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct net_device *dev;
+ DFX_board_t *bp; /* board pointer */
+ int port;
+
+ 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 */
+ }
+
+ if (pci_enable_device (pdev))
+ goto err_out;
+ pci_set_master (pdev);
+
+ /* Get I/O base address from PCI Configuration Space */
+ port = pci_resource_start (pdev, 1);
+
+ if (!request_region (port, PFI_K_CSR_IO_LEN, "defxx")) {
+ printk (KERN_ERR
+ "defxx: I/O range allocated to adapter (0x%X-0x%X) is already being used!\n",
+ port, (port + PFI_K_CSR_IO_LEN - 1));
+ goto err_out;
+ }
+
+ /* Allocate a new device structure for this adapter */
+ dev = dfx_alloc_device (port);
+ if (dev == NULL) {
+ printk (KERN_ERR "defxx: alloc device failed\n");
+ goto err_out_region;
+ }
+
+ /* 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;
+
+ /*
+ * FIXME FIXME FIXME
+ * Suck! The original driver didn't clean up after
+ * itself at this stage, so we won't either. Someone
+ * needs to go back and see what (if anything) we need
+ * to free here... -jgarzik
+ */
+ if (dfx_driver_init (dev) != DFX_K_SUCCESS) {
+ dev->base_addr = 0; /* clear port address field in device structure on failure */
+ goto err_out_region;
+ }
+
+ return 0;
+
+err_out_region:
+ release_region (port, PFI_K_CSR_IO_LEN);
+err_out:
+ return -ENODEV;
+};
+
+static struct pci_driver dfx_driver = {
+ name: "defxx",
+ id_table: dfx_pci_tbl,
+ probe: dfx_init_one,
+};
+
+static int __init dfx_probe(void)
{
int i; /* used in for loops */
- int version_disp; /* was version info string already displayed? */
- int port_len; /* length of port address range (in bytes) */
u16 port; /* temporary I/O (port) address */
- struct pci_dev * pdev = NULL; /* PCI device record */
- 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");
- version_disp = 0; /* default to version string not displayed */
already_probed = 1; /* set global flag */
/* Scan for FDDI EISA controllers */
@@ -463,9 +529,7 @@
port = (i << 12); /* recalc base addr */
/* Verify port address range is not already being used */
-
- port_len = PI_ESIC_K_CSR_IO_LEN;
- if (check_region(port, port_len) == 0)
+ if (request_region(port, PI_ESIC_K_CSR_IO_LEN, "defxx"))
{
/* Allocate a new device structure for this adapter */
@@ -485,70 +549,17 @@
}
}
else
- printk("I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));
+ printk("I/O range allocated to adapter (0x%X-0x%X) is already being used!\n",
+ port, (port + PI_ESIC_K_CSR_IO_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 */
- }
-
- if (pci_enable_device(pdev))
- continue;
-
- /* 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(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;
- command &= ~PCI_COMMAND_MEMORY;
- pci_write_config_word(pdev, PCI_COMMAND, command);
-
- /* Get I/O base address from PCI Configuration Space */
-
- port = pci_resource_start (pdev, 1);
-
- /* Verify port address range is not already being used */
-
- 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(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(KERN_ERR "defxx: I/O range allocated to adapter (0x%X-0x%X) is already being used!\n", port, (port + port_len-1));
- }
- }
+ i = pci_register_driver (&dfx_driver);
+ if (i > 0) {
+ num_boards += i;
+ have_pci_driver = 1;
+ }
/*
* If we're at this point we're going through dfx_probe() for the first
@@ -556,10 +567,7 @@
* Otherwise, return failure (-ENODEV).
*/
- if (num_boards > 0)
- return(0);
- else
- return(-ENODEV);
+ return (num_boards > 0) ? 0 : -ENODEV;
}
@@ -3464,28 +3472,34 @@
}
-#ifdef MODULE
-
-int init_module(void)
-{
- if(dfx_probe()<0)
- return -ENODEV;
- return 0;
-}
-void cleanup_module(void)
+static void __exit dfx_cleanup(void)
{
while(bp_root!=NULL)
{
struct net_device *tmp=bp_root;
DFX_board_t *priv=tmp->priv;
bp_root=priv->next;
+
+ /* FIXME: need to unregister FDDI device here?
+ * The original driver didn't do it, but I think so..
+ * -jgarzik
+ */
+
+ if (priv->bus_type == DFX_BUS_TYPE_EISA)
+ release_region(tmp->base_addr, PI_ESIC_K_CSR_IO_LEN);
+ else
+ release_region(tmp->base_addr, PFI_K_CSR_IO_LEN);
+
kfree(tmp->priv);
kfree(tmp);
}
+ if (have_pci_driver)
+ pci_unregister_driver(&dfx_driver);
}
-#endif
+module_init(dfx_probe);
+module_exit(dfx_cleanup);
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)