X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=drivers%2Fnet%2Fmyri_sbus.c;fp=drivers%2Fnet%2Fmyri_sbus.c;h=6c86dca62e2a565b6d611178d3894ee7120d9874;hp=1b965a2b56e4fc22e0de85e5a9c2f0fbf60fe5ae;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 1b965a2b5..6c86dca62 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1,12 +1,13 @@ -/* myri_sbus.c: MyriCOM MyriNET SBUS card driver. +/* myri_sbus.h: MyriCOM MyriNET SBUS card driver. * - * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) */ static char version[] = - "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n"; + "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; #include +#include #include #include #include @@ -80,6 +81,10 @@ static char version[] = #define DHDR(x) #endif +#ifdef MODULE +static struct myri_eth *root_myri_dev; +#endif + static void myri_reset_off(void __iomem *lp, void __iomem *cregs) { /* Clear IRQ mask. */ @@ -891,9 +896,8 @@ static void dump_eeprom(struct myri_eth *mp) } #endif -static int __init myri_ether_init(struct sbus_dev *sdev) +static int __init myri_ether_init(struct sbus_dev *sdev, int num) { - static int num; static unsigned version_printed; struct net_device *dev; struct myri_eth *mp; @@ -909,9 +913,6 @@ static int __init myri_ether_init(struct sbus_dev *sdev) if (version_printed++ == 0) printk(version); - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); - mp = (struct myri_eth *) dev->priv; spin_lock_init(&mp->irq_lock); mp->myri_sdev = sdev; @@ -1069,7 +1070,7 @@ static int __init myri_ether_init(struct sbus_dev *sdev) /* Register interrupt handler now. */ DET(("Requesting MYRIcom IRQ line.\n")); if (request_irq(dev->irq, &myri_interrupt, - IRQF_SHARED, "MyriCOM Ethernet", (void *) dev)) { + SA_SHIRQ, "MyriCOM Ethernet", (void *) dev)) { printk("MyriCOM: Cannot register interrupt handler.\n"); goto err; } @@ -1091,9 +1092,10 @@ static int __init myri_ether_init(struct sbus_dev *sdev) goto err_free_irq; } - dev_set_drvdata(&sdev->ofdev.dev, mp); - - num++; +#ifdef MODULE + mp->next_module = root_myri_dev; + root_myri_dev = mp; +#endif printk("%s: MyriCOM MyriNET Ethernet ", dev->name); @@ -1112,68 +1114,61 @@ err: return -ENODEV; } - -static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match) +static int __init myri_sbus_match(struct sbus_dev *sdev) { - struct sbus_dev *sdev = to_sbus_device(&dev->dev); + char *name = sdev->prom_name; + + if (!strcmp(name, "MYRICOM,mlanai") || + !strcmp(name, "myri")) + return 1; - return myri_ether_init(sdev); + return 0; } -static int __devexit myri_sbus_remove(struct of_device *dev) +static int __init myri_sbus_probe(void) { - struct myri_eth *mp = dev_get_drvdata(&dev->dev); - struct net_device *net_dev = mp->dev; + struct sbus_bus *bus; + struct sbus_dev *sdev = NULL; + static int called; + int cards = 0, v; - unregister_netdevice(net_dev); - - free_irq(net_dev->irq, net_dev); +#ifdef MODULE + root_myri_dev = NULL; +#endif - if (mp->eeprom.cpuvers < CPUVERS_4_0) { - sbus_iounmap(mp->regs, mp->reg_size); - } else { - sbus_iounmap(mp->cregs, PAGE_SIZE); - sbus_iounmap(mp->lregs, (256 * 1024)); - sbus_iounmap(mp->lanai, (512 * 1024)); + if (called) + return -ENODEV; + called++; + + for_each_sbus(bus) { + for_each_sbusdev(sdev, bus) { + if (myri_sbus_match(sdev)) { + cards++; + DET(("Found myricom myrinet as %s\n", sdev->prom_name)); + if ((v = myri_ether_init(sdev, (cards - 1)))) + return v; + } + } } - - free_netdev(net_dev); - - dev_set_drvdata(&dev->dev, NULL); - + if (!cards) + return -ENODEV; return 0; } -static struct of_device_id myri_sbus_match[] = { - { - .name = "MYRICOM,mlanai", - }, - { - .name = "myri", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, myri_sbus_match); - -static struct of_platform_driver myri_sbus_driver = { - .name = "myri", - .match_table = myri_sbus_match, - .probe = myri_sbus_probe, - .remove = __devexit_p(myri_sbus_remove), -}; - -static int __init myri_sbus_init(void) -{ - return of_register_driver(&myri_sbus_driver, &sbus_bus_type); -} - -static void __exit myri_sbus_exit(void) +static void __exit myri_sbus_cleanup(void) { - of_unregister_driver(&myri_sbus_driver); +#ifdef MODULE + while (root_myri_dev) { + struct myri_eth *next = root_myri_dev->next_module; + + unregister_netdev(root_myri_dev->dev); + /* this will also free the co-allocated 'root_myri_dev' */ + free_netdev(root_myri_dev->dev); + root_myri_dev = next; + } +#endif /* MODULE */ } -module_init(myri_sbus_init); -module_exit(myri_sbus_exit); - +module_init(myri_sbus_probe); +module_exit(myri_sbus_cleanup); MODULE_LICENSE("GPL");