patch-2.3.99-pre3 linux/drivers/net/ne2k-pci.c
Next file: linux/drivers/net/net_init.c
Previous file: linux/drivers/net/irda/w83977af_ir.c
Back to the patch index
Back to the overall index
- Lines: 395
- Date:
Tue Mar 21 11:02:09 2000
- Orig file:
v2.3.99-pre2/linux/drivers/net/ne2k-pci.c
- Orig date:
Thu Feb 10 17:11:10 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
@@ -71,28 +71,55 @@
STOP_PG_0x60=0x100,
};
-/* This will eventually be converted to the standard PCI probe table. */
+
+enum ne2k_pci_chipsets {
+ CH_RealTek_RTL_8029 = 0,
+ CH_Winbond_89C940,
+ CH_Compex_RL2000,
+ CH_KTI_ET32P2,
+ CH_NetVin_NV5000SC,
+ CH_Via_86C926,
+ CH_SureCom_NE34,
+ CH_Winbond_W89C940F,
+ CH_Holtek_HT80232,
+ CH_Holtek_HT80229,
+};
+
static struct {
- unsigned short vendor, dev_id;
char *name;
int flags;
-}
-pci_clone_list[] __initdata = {
- {0x10ec, 0x8029, "RealTek RTL-8029", 0},
- {0x1050, 0x0940, "Winbond 89C940", 0},
- {0x11f6, 0x1401, "Compex RL2000", 0},
- {0x8e2e, 0x3000, "KTI ET32P2", 0},
- {0x4a14, 0x5000, "NetVin NV5000SC", 0},
- {0x1106, 0x0926, "Via 86C926", ONLY_16BIT_IO},
- {0x10bd, 0x0e34, "SureCom NE34", 0},
- {0x1050, 0x5a5a, "Winbond W89C940F", 0},
- {0x12c3, 0x0058, "Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX},
- {0x12c3, 0x5598, "Holtek HT80229",
- ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 },
+} pci_clone_list[] __devinitdata = {
+ {"RealTek RTL-8029", 0},
+ {"Winbond 89C940", 0},
+ {"Compex RL2000", 0},
+ {"KTI ET32P2", 0},
+ {"NetVin NV5000SC", 0},
+ {"Via 86C926", ONLY_16BIT_IO},
+ {"SureCom NE34", 0},
+ {"Winbond W89C940F", 0},
+ {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX},
+ {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 },
{0,}
};
+
+static struct pci_device_id ne2k_pci_tbl[] __devinitdata = {
+ { 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 },
+ { 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 },
+ { 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 },
+ { 0x8e2e, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_KTI_ET32P2 },
+ { 0x4a14, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_NetVin_NV5000SC },
+ { 0x1106, 0x0926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Via_86C926 },
+ { 0x10bd, 0x0e34, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_SureCom_NE34 },
+ { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F },
+ { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 },
+ { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl);
+
+
/* ---- No user-serviceable parts below ---- */
#define NE_BASE (dev->base_addr)
@@ -104,8 +131,6 @@
#define NESM_START_PG 0x40 /* First page of TX buffer */
#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
-static int ne2k_pci_probe(void);
-static struct net_device *ne2k_pci_probe1(long ioaddr, int irq, int chip_idx);
static int ne2k_pci_open(struct net_device *dev);
static int ne2k_pci_close(struct net_device *dev);
@@ -122,47 +147,11 @@
/* No room in the standard 8390 structure for extra info we need. */
struct ne2k_pci_card {
- struct ne2k_pci_card *next;
struct net_device *dev;
struct pci_dev *pci_dev;
};
-/* A list of all installed devices, for removing the driver module. */
-static struct ne2k_pci_card *ne2k_card_list = NULL;
-static int __init ne2k_pci_init_module(void)
-{
- /* We must emit version information. */
- if (debug)
- printk(KERN_INFO "%s", version);
- if (ne2k_pci_probe()) {
- printk(KERN_NOTICE "ne2k-pci.c: No useable cards found, driver NOT installed.\n");
- return -ENODEV;
- }
- lock_8390_module();
- return 0;
-}
-
-static void __exit ne2k_pci_cleanup_module(void)
-{
- struct net_device *dev;
- struct ne2k_pci_card *this_card;
-
- /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
- while (ne2k_card_list) {
- dev = ne2k_card_list->dev;
- unregister_netdev(dev);
- release_region(dev->base_addr, NE_IO_EXTENT);
- kfree(dev);
- this_card = ne2k_card_list;
- ne2k_card_list = ne2k_card_list->next;
- kfree(this_card);
- }
- unlock_8390_module();
-}
-
-module_init(ne2k_pci_init_module);
-module_exit(ne2k_pci_cleanup_module);
/*
NEx000-clone boards have a Station Address (SA) PROM (SAPROM) in the packet
@@ -177,96 +166,42 @@
in the 'dev' and 'ei_status' structures.
*/
-#ifdef HAVE_DEVLIST
-struct netdev_entry netcard_drv =
-{"ne2k_pci", ne2k_pci_probe1, NE_IO_EXTENT, 0};
-#endif
-static int __init ne2k_pci_probe(void)
+static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
- struct pci_dev *pdev = NULL;
- int cards_found = 0;
- int i;
struct net_device *dev;
+ int i, irq, reg0, start_page, stop_page;
+ unsigned char SA_prom[32];
+ int chip_idx = ent->driver_data;
+ static unsigned version_printed = 0;
+ long ioaddr;
+
+ if (version_printed++ == 0)
+ printk(KERN_INFO "%s", version);
- if ( ! pci_present())
+ ioaddr = pci_resource_start (pdev, 0);
+ irq = pdev->irq;
+
+ if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) {
+ printk (KERN_ERR "ne2k-pci: no I/O resource at PCI BAR #0\n");
return -ENODEV;
-
- while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev)) != NULL) {
- int pci_irq_line;
- u16 pci_command, new_command;
- unsigned long pci_ioaddr;
-
- /* Note: some vendor IDs (RealTek) have non-NE2k cards as well. */
- for (i = 0; pci_clone_list[i].vendor != 0; i++)
- if (pci_clone_list[i].vendor == pdev->vendor
- && pci_clone_list[i].dev_id == pdev->device)
- break;
- if (pci_clone_list[i].vendor == 0)
- continue;
-
- pci_ioaddr = pdev->resource[0].start;
- pci_irq_line = pdev->irq;
- pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-
- /* Avoid already found cards from previous calls */
- if (check_region(pci_ioaddr, NE_IO_EXTENT))
- continue;
-
- {
- static unsigned version_printed = 0;
- if (version_printed++ == 0)
- printk(KERN_INFO "%s", version);
- }
-
- /* Activate the card: fix for brain-damaged Win98 BIOSes. */
- new_command = pci_command | PCI_COMMAND_IO;
- if (pci_command != new_command) {
- printk(KERN_INFO " The PCI BIOS has not enabled this"
- " NE2k clone! Updating PCI command %4.4x->%4.4x.\n",
- pci_command, new_command);
- pci_write_config_word(pdev, PCI_COMMAND, new_command);
- }
-#ifndef __sparc__
- if (pci_irq_line <= 0 || pci_irq_line >= NR_IRQS)
- printk(KERN_WARNING " WARNING: The PCI BIOS assigned this PCI NE2k"
- " card to IRQ %d, which is unlikely to work!.\n"
- KERN_WARNING " You should use the PCI BIOS setup to assign"
- " a valid IRQ line.\n", pci_irq_line);
-#endif
- printk("ne2k-pci.c: PCI NE2000 clone '%s' at I/O %#lx, IRQ %d.\n",
- pci_clone_list[i].name, pci_ioaddr, pci_irq_line);
- dev = ne2k_pci_probe1(pci_ioaddr, pci_irq_line, i);
- if (dev == 0) {
- /* Should not happen. */
- printk(KERN_ERR "ne2k-pci: Probe of PCI card at %#lx failed.\n",
- pci_ioaddr);
- continue;
- } else {
- struct ne2k_pci_card *ne2k_card =
- kmalloc(sizeof(struct ne2k_pci_card), GFP_KERNEL);
- ne2k_card->next = ne2k_card_list;
- ne2k_card_list = ne2k_card;
- ne2k_card->dev = dev;
- ne2k_card->pci_dev = pdev;
- }
-
- cards_found++;
}
-
- return cards_found ? 0 : -ENODEV;
-}
-
-static struct net_device __init *ne2k_pci_probe1(long ioaddr, int irq, int chip_idx)
-{
- struct net_device *dev;
- int i;
- unsigned char SA_prom[32];
- int start_page, stop_page;
- int reg0 = inb(ioaddr);
-
+
+ if (pci_enable_device (pdev)) {
+ printk (KERN_ERR "ne2k-pci: cannot enable device\n");
+ return -EIO;
+ }
+
+ if (request_region (ioaddr, NE_IO_EXTENT, "ne2k-pci") == NULL) {
+ printk (KERN_ERR "ne2k-pci: I/O resource 0x%x @ 0x%lx busy\n",
+ NE_IO_EXTENT, ioaddr);
+ return -EBUSY;
+ }
+
+ reg0 = inb(ioaddr);
if (reg0 == 0xFF)
- return 0;
+ goto err_out_free_res;
/* Do a preliminary verification that we have a 8390. */
{
@@ -279,12 +214,16 @@
if (inb(ioaddr + EN0_COUNTER0) != 0) {
outb(reg0, ioaddr);
outb(regd, ioaddr + 0x0d); /* Restore the old values. */
- return 0;
+ goto err_out_free_res;
}
}
dev = init_etherdev(NULL, 0);
-
+ if (!dev) {
+ printk (KERN_ERR "ne2k-pci: cannot allocate ethernet device\n");
+ goto err_out_free_res;
+ }
+
/* Reset card. Who knows what dain-bramaged state it was left in. */
{
unsigned long reset_start_time = jiffies;
@@ -298,14 +237,15 @@
/* Limit wait: '2' avoids jiffy roll-over. */
if (jiffies - reset_start_time > 2) {
printk("ne2k-pci: Card failure (no reset ack).\n");
- return 0;
+ goto err_out_free_netdev;
}
outb(0xff, ioaddr + EN0_ISR); /* Ack all intr. */
}
if (load_8390_module("ne2k-pci.c")) {
- return 0;
+ printk (KERN_ERR "ne2k-pci: cannot load 8390 module\n");
+ goto err_out_free_netdev;
}
/* Read the 16 bytes of station address PROM.
@@ -355,12 +295,10 @@
/* Allocate dev->priv and fill in 8390 specific dev fields. */
if (ethdev_init(dev)) {
- printk ("%s: unable to get memory for dev->priv.\n", dev->name);
- return 0;
+ printk (KERN_ERR "%s: unable to get memory for dev->priv.\n", dev->name);
+ goto err_out_free_netdev;
}
- request_region(ioaddr, NE_IO_EXTENT, dev->name);
-
printk("%s: %s found at %#lx, IRQ %d, ",
dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq);
for(i = 0; i < 6; i++) {
@@ -387,16 +325,26 @@
dev->open = &ne2k_pci_open;
dev->stop = &ne2k_pci_close;
NS8390_init(dev, 0);
- return dev;
+ return 0;
+
+err_out_free_netdev:
+ unregister_netdev (dev);
+ kfree (dev);
+err_out_free_res:
+ release_region (ioaddr, NE_IO_EXTENT);
+ return -ENODEV;
+
}
static int
ne2k_pci_open(struct net_device *dev)
{
- if (request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev))
+ MOD_INC_USE_COUNT;
+ if (request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev)) {
+ MOD_DEC_USE_COUNT;
return -EAGAIN;
+ }
ei_open(dev);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -588,6 +536,58 @@
ei_status.dmaing &= ~0x01;
return;
}
+
+
+static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
+{
+ struct net_device *dev = pdev->driver_data;
+
+ if (!dev) {
+ printk (KERN_ERR "bug! ne2k_pci_remove_one called w/o net_device\n");
+ return;
+ }
+
+ unregister_netdev (dev);
+ release_region (dev->base_addr, NE_IO_EXTENT);
+ kfree (dev);
+}
+
+
+static struct pci_driver ne2k_driver = {
+ name: "ne2k-pci",
+ probe: ne2k_pci_init_one,
+ remove: ne2k_pci_remove_one,
+ id_table: ne2k_pci_tbl,
+};
+
+
+static int __init ne2k_pci_init(void)
+{
+ int rc;
+
+ MOD_INC_USE_COUNT;
+ lock_8390_module();
+
+ rc = pci_module_init (&ne2k_driver);
+
+ /* XXX should this test CONFIG_HOTPLUG like pci_module_init? */
+ if (rc <= 0)
+ unlock_8390_module();
+
+ MOD_DEC_USE_COUNT;
+
+ return rc;
+}
+
+
+static void __exit ne2k_pci_cleanup(void)
+{
+ pci_unregister_driver (&ne2k_driver);
+ unlock_8390_module();
+}
+
+module_init(ne2k_pci_init);
+module_exit(ne2k_pci_cleanup);
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)