lkml.org 
[lkml]   [2003]   [Feb]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] fix 3c509.c for MCA drivers
From
Date


The attached fixes the MCA version of the 3c509 and updates it to the
new MCA API.

Someone who knows PNP-ISA should migrate it to a probing API for that
too.

I've put the el3_probe back into Space.c for ISA only otherwise the
driver won't work for ISA (could someone with an ISA card test this).

James

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.956 -> 1.957
# drivers/net/3c509.c 1.29 -> 1.30
# drivers/net/Space.c 1.15 -> 1.16
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/02 jejb@mulgrave.(none) 1.957
# 3c509 fixes: correct MCA probing, add back ISA probe to Space.c
# --------------------------------------------
#
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c Sun Feb 2 22:04:26 2003
+++ b/drivers/net/3c509.c Sun Feb 2 22:04:26 2003
@@ -103,6 +103,10 @@
static int el3_debug = 2;
#endif

+/* Used to do a global count of all the cards in the system. Must be
+ * a global variable so that the mca/eisa probe routines can increment
+ * it */
+static int el3_cards = 0;

/* To minimize the size of the driver source I only define operating
constants if they are used several times. You'll need the manual
@@ -167,16 +171,15 @@
/* skb send-queue */
int head, size;
struct sk_buff *queue[SKB_QUEUE_SIZE];
- char mca_slot;
#ifdef CONFIG_PM
struct pm_dev *pmdev;
#endif
-#ifdef __ISAPNP__
- struct pnp_dev *pnpdev;
-#endif
-#ifdef CONFIG_EISA
- struct eisa_device *edev;
-#endif
+ enum {
+ EL3_MCA,
+ EL3_PNP,
+ EL3_EISA,
+ } type; /* type of device */
+ struct device *dev;
};
static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/
static struct net_device *el3_root_dev;
@@ -200,6 +203,8 @@
static int el3_resume(struct pm_dev *pdev);
static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
#endif
+/* generic device remove for all device types */
+static int el3_device_remove (struct device *device);

#ifdef CONFIG_EISA
struct eisa_device_id el3_eisa_ids[] = {
@@ -209,31 +214,46 @@
};

static int el3_eisa_probe (struct device *device);
-static int el3_eisa_remove (struct device *device);

struct eisa_driver el3_eisa_driver = {
.id_table = el3_eisa_ids,
.driver = {
.name = "3c509",
.probe = el3_eisa_probe,
- .remove = __devexit_p (el3_eisa_remove)
+ .remove = __devexit_p (el3_device_remove)
}
};
#endif

#ifdef CONFIG_MCA
-struct el3_mca_adapters_struct {
- char* name;
- int id;
+static int el3_mca_probe(struct device *dev);
+
+static short el3_mca_adapter_ids[] __initdata = {
+ 0x627c,
+ 0x627d,
+ 0x62db,
+ 0x62f6,
+ 0x62f7,
+ 0x0000
+};
+
+static char *el3_mca_adapter_names[] __initdata = {
+ "3Com 3c529 EtherLink III (10base2)",
+ "3Com 3c529 EtherLink III (10baseT)",
+ "3Com 3c529 EtherLink III (test mode)",
+ "3Com 3c529 EtherLink III (TP or coax)",
+ "3Com 3c529 EtherLink III (TP)",
+ NULL
};

-static struct el3_mca_adapters_struct el3_mca_adapters[] __initdata = {
- { "3Com 3c529 EtherLink III (10base2)", 0x627c },
- { "3Com 3c529 EtherLink III (10baseT)", 0x627d },
- { "3Com 3c529 EtherLink III (test mode)", 0x62db },
- { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
- { "3Com 3c529 EtherLink III (TP)", 0x62f7 },
- { NULL, 0 },
+static struct mca_driver el3_mca_driver = {
+ .id_table = el3_mca_adapter_ids,
+ .driver = {
+ .name = "3c529",
+ .bus = &mca_bus_type,
+ .probe = el3_mca_probe,
+ .remove = __devexit_p(el3_device_remove),
+ },
};
#endif /* CONFIG_MCA */

@@ -264,12 +284,12 @@
};

static u16 el3_isapnp_phys_addr[8][3];
-#endif /* __ISAPNP__ */
static int nopnp;
+#endif /* __ISAPNP__ */

/* With the driver model introduction for EISA devices, both init
* and cleanup have been split :
- * - EISA devices probe/remove starts in el3_eisa_probe/el3_eisa_remove
+ * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove
* - MCA/ISA still use el3_probe
*
* Both call el3_common_init/el3_common_remove. */
@@ -278,10 +298,9 @@
{
struct el3_private *lp = dev->priv;
short i;
-
-#ifdef CONFIG_EISA
- if (!lp->edev) /* EISA devices are not chained */
-#endif
+
+ el3_cards++;
+ if (!lp->dev) /* probed devices are not chained */
{
lp->next_dev = el3_root_dev;
el3_root_dev = dev;
@@ -337,17 +356,13 @@
struct el3_private *lp = dev->priv;

(void) lp; /* Keep gcc quiet... */
-#ifdef CONFIG_MCA
- if(lp->mca_slot!=-1)
- mca_mark_as_unused(lp->mca_slot);
-#endif
#ifdef CONFIG_PM
if (lp->pmdev)
pm_unregister(lp->pmdev);
#endif
#ifdef __ISAPNP__
- if (lp->pnpdev)
- pnp_device_detach(lp->pnpdev);
+ if (lp->type == EL3_PNP)
+ pnp_device_detach(to_pnp_dev(lp->dev));
#endif

unregister_netdev (dev);
@@ -363,76 +378,11 @@
int ioaddr, irq, if_port;
u16 phys_addr[3];
static int current_tag;
- int mca_slot = -1;
#ifdef __ISAPNP__
static int pnp_cards;
struct pnp_dev *idev = NULL;
#endif /* __ISAPNP__ */

-#ifdef CONFIG_MCA
- /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
- * modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
- * to support standard MCA probing.
- *
- * redone for multi-card detection by ZP Gu (zpg@castle.net)
- * now works as a module
- */
-
- if( MCA_bus ) {
- int slot, j;
- u_char pos4, pos5;
-
- for( j = 0; el3_mca_adapters[j].name != NULL; j ++ ) {
- slot = 0;
- while( slot != MCA_NOTFOUND ) {
- slot = mca_find_unused_adapter(
- el3_mca_adapters[j].id, slot );
- if( slot == MCA_NOTFOUND ) break;
-
- /* if we get this far, an adapter has been
- * detected and is enabled
- */
-
- pos4 = mca_read_stored_pos( slot, 4 );
- pos5 = mca_read_stored_pos( slot, 5 );
-
- ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
- irq = pos5 & 0x0f;
-
- /* probing for a card at a particular IO/IRQ */
- if(dev && ((dev->irq >= 1 && dev->irq != irq) ||
- (dev->base_addr >= 1 && dev->base_addr != ioaddr))) {
- slot++; /* probing next slot */
- continue;
- }
-
- printk("3c509: found %s at slot %d\n",
- el3_mca_adapters[j].name, slot + 1 );
-
- /* claim the slot */
- mca_set_adapter_name(slot, el3_mca_adapters[j].name);
- mca_set_adapter_procfn(slot, NULL, NULL);
- mca_mark_as_used(slot);
-
- if_port = pos4 & 0x03;
- if (el3_debug > 2) {
- printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
- }
- EL3WINDOW(0);
- for (i = 0; i < 3; i++) {
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
- }
-
- mca_slot = slot;
-
- goto found;
- }
- }
- /* if we get here, we didn't find an MCA adapter */
- return -ENODEV;
- }
-#endif /* CONFIG_MCA */
-
#ifdef __ISAPNP__
if (nopnp == 1)
goto no_pnp;
@@ -580,7 +530,7 @@

/* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ);
- found:
+
dev = init_etherdev(NULL, sizeof(struct el3_private));
if (dev == NULL) {
release_region(ioaddr, EL3_IO_EXTENT);
@@ -594,13 +544,80 @@
dev->if_port = if_port;
lp = dev->priv;
#ifdef __ISAPNP__
- lp->pnpdev = idev;
+ lp->dev = &idev->dev;
#endif
- lp->mca_slot = mca_slot;

return el3_common_init (dev);
}

+#ifdef CONFIG_MCA
+static int __init el3_mca_probe(struct device *device) {
+ /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
+ * heavily modified by Chris Beauregard
+ * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
+ * probing.
+ *
+ * redone for multi-card detection by ZP Gu (zpg@castle.net)
+ * now works as a module */
+
+ struct el3_private *lp;
+ short i;
+ int ioaddr, irq, if_port;
+ u16 phys_addr[3];
+ struct net_device *dev = NULL;
+ u_char pos4, pos5;
+ struct mca_device *mdev = to_mca_device(device);
+ int slot = mdev->slot;
+
+ pos4 = mca_device_read_stored_pos(mdev, 4);
+ pos5 = mca_device_read_stored_pos(mdev, 5);
+
+ ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
+ irq = pos5 & 0x0f;
+
+
+ printk("3c529: found %s at slot %d\n",
+ el3_mca_adapter_names[mdev->index], slot + 1);
+
+ /* claim the slot */
+ strncpy(device->name, el3_mca_adapter_names[mdev->index],
+ sizeof(device->name));
+ mca_device_set_claim(mdev, 1);
+
+ if_port = pos4 & 0x03;
+
+ irq = mca_device_transform_irq(mdev, irq);
+ ioaddr = mca_device_transform_ioport(mdev, ioaddr);
+ if (el3_debug > 2) {
+ printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
+ }
+ EL3WINDOW(0);
+ for (i = 0; i < 3; i++) {
+ phys_addr[i] = htons(read_eeprom(ioaddr, i));
+ }
+
+ dev = init_etherdev(NULL, sizeof(struct el3_private));
+ if (dev == NULL) {
+ release_region(ioaddr, EL3_IO_EXTENT);
+ return -ENOMEM;
+ }
+
+ SET_MODULE_OWNER(dev);
+
+ memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ dev->if_port = if_port;
+ lp = dev->priv;
+ lp->dev = device;
+ lp->type = EL3_MCA;
+ device->driver_data = dev;
+
+ return el3_common_init (dev);
+}
+
+#endif /* CONFIG_MCA */
+
#ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device)
{
@@ -642,25 +659,26 @@
dev->irq = irq;
dev->if_port = if_port;
lp = dev->priv;
- lp->mca_slot = -1;
- lp->edev = edev;
+ lp->dev = device;
+ lp->type = EL3_EISA;
eisa_set_drvdata (edev, dev);

return el3_common_init (dev);
}
+#endif

-static int __devexit el3_eisa_remove (struct device *device)
+/* This remove works for all device types.
+ *
+ * The net dev must be stored in the driver_data field */
+static int __devexit el3_device_remove (struct device *device)
{
- struct eisa_device *edev;
struct net_device *dev;

- edev = to_eisa_device (device);
- dev = eisa_get_drvdata (edev);
+ dev = device->driver_data;

el3_common_remove (dev);
return 0;
}
-#endif

/* Read a word from the EEPROM using the regular EEPROM access register.
Assume that we are in register window zero.
@@ -1080,7 +1098,7 @@
free_irq(dev->irq, dev);
/* Switching back to window 0 disables the IRQ. */
EL3WINDOW(0);
- if (!lp->edev) {
+ if (lp->type != EL3_EISA) {
/* But we explicitly zero the IRQ line select anyway. Don't do
* it on EISA cards, it prevents the module from getting an
* IRQ after unload+reload... */
@@ -1530,7 +1548,7 @@

static int __init el3_init_module(void)
{
- int el3_cards = 0;
+ el3_cards = 0;

if (debug >= 0)
el3_debug = debug;
@@ -1548,8 +1566,9 @@
if (eisa_driver_register (&el3_eisa_driver) < 0) {
eisa_driver_unregister (&el3_eisa_driver);
}
- else
- el3_cards++; /* Found an eisa card */
+#endif
+#ifdef CONFIG_MCA
+ mca_register_driver(&el3_mca_driver);
#endif
return el3_cards ? 0 : -ENODEV;
}
@@ -1568,6 +1587,9 @@

#ifdef CONFIG_EISA
eisa_driver_unregister (&el3_eisa_driver);
+#endif
+#ifdef CONFIG_MCA
+ mca_unregister_driver(&el3_mca_driver);
#endif
}

diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c Sun Feb 2 22:04:26 2003
+++ b/drivers/net/Space.c Sun Feb 2 22:04:26 2003
@@ -224,6 +224,9 @@
#ifdef CONFIG_EL2 /* 3c503 */
{el2_probe, 0},
#endif
+#ifdef CONFIG_EL3
+ {el3_probe, 0},
+#endif
#ifdef CONFIG_HPLAN
{hp_probe, 0},
#endif
\
 
 \ /
  Last update: 2005-03-22 13:32    [W:1.375 / U:0.204 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site