diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/sunlance.c | 173 |
1 files changed, 97 insertions, 76 deletions
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 6381243d8d00..2c239ab63a80 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c | |||
@@ -266,7 +266,6 @@ struct lance_private { | |||
266 | char *name; | 266 | char *name; |
267 | dma_addr_t init_block_dvma; | 267 | dma_addr_t init_block_dvma; |
268 | struct net_device *dev; /* Backpointer */ | 268 | struct net_device *dev; /* Backpointer */ |
269 | struct lance_private *next_module; | ||
270 | struct sbus_dev *sdev; | 269 | struct sbus_dev *sdev; |
271 | struct timer_list multicast_timer; | 270 | struct timer_list multicast_timer; |
272 | }; | 271 | }; |
@@ -298,8 +297,6 @@ int sparc_lance_debug = 2; | |||
298 | 297 | ||
299 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) | 298 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) |
300 | 299 | ||
301 | static struct lance_private *root_lance_dev; | ||
302 | |||
303 | /* Load the CSR registers */ | 300 | /* Load the CSR registers */ |
304 | static void load_csrs(struct lance_private *lp) | 301 | static void load_csrs(struct lance_private *lp) |
305 | { | 302 | { |
@@ -1327,9 +1324,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = { | |||
1327 | .get_link = sparc_lance_get_link, | 1324 | .get_link = sparc_lance_get_link, |
1328 | }; | 1325 | }; |
1329 | 1326 | ||
1330 | static int __init sparc_lance_init(struct sbus_dev *sdev, | 1327 | static int __init sparc_lance_probe_one(struct sbus_dev *sdev, |
1331 | struct sbus_dma *ledma, | 1328 | struct sbus_dma *ledma, |
1332 | struct sbus_dev *lebuffer) | 1329 | struct sbus_dev *lebuffer) |
1333 | { | 1330 | { |
1334 | static unsigned version_printed; | 1331 | static unsigned version_printed; |
1335 | struct net_device *dev; | 1332 | struct net_device *dev; |
@@ -1473,6 +1470,7 @@ no_link_test: | |||
1473 | 1470 | ||
1474 | lp->dev = dev; | 1471 | lp->dev = dev; |
1475 | SET_MODULE_OWNER(dev); | 1472 | SET_MODULE_OWNER(dev); |
1473 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
1476 | dev->open = &lance_open; | 1474 | dev->open = &lance_open; |
1477 | dev->stop = &lance_close; | 1475 | dev->stop = &lance_close; |
1478 | dev->hard_start_xmit = &lance_start_xmit; | 1476 | dev->hard_start_xmit = &lance_start_xmit; |
@@ -1500,8 +1498,7 @@ no_link_test: | |||
1500 | goto fail; | 1498 | goto fail; |
1501 | } | 1499 | } |
1502 | 1500 | ||
1503 | lp->next_module = root_lance_dev; | 1501 | dev_set_drvdata(&sdev->ofdev.dev, lp); |
1504 | root_lance_dev = lp; | ||
1505 | 1502 | ||
1506 | printk(KERN_INFO "%s: LANCE ", dev->name); | 1503 | printk(KERN_INFO "%s: LANCE ", dev->name); |
1507 | 1504 | ||
@@ -1536,88 +1533,112 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | |||
1536 | #include <asm/machines.h> | 1533 | #include <asm/machines.h> |
1537 | 1534 | ||
1538 | /* Find all the lance cards on the system and initialize them */ | 1535 | /* Find all the lance cards on the system and initialize them */ |
1539 | static int __init sparc_lance_probe(void) | 1536 | static struct sbus_dev sun4_sdev; |
1537 | static int __init sparc_lance_init(void) | ||
1540 | { | 1538 | { |
1541 | static struct sbus_dev sdev; | ||
1542 | static int called; | ||
1543 | |||
1544 | root_lance_dev = NULL; | ||
1545 | |||
1546 | if (called) | ||
1547 | return -ENODEV; | ||
1548 | called++; | ||
1549 | |||
1550 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || | 1539 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || |
1551 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | 1540 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { |
1552 | memset(&sdev, 0, sizeof(sdev)); | 1541 | memset(&sun4_sdev, 0, sizeof(sdev)); |
1553 | sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; | 1542 | sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; |
1554 | sdev.irqs[0] = 6; | 1543 | sun4_sdev.irqs[0] = 6; |
1555 | return sparc_lance_init(&sdev, NULL, NULL); | 1544 | return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); |
1556 | } | 1545 | } |
1557 | return -ENODEV; | 1546 | return -ENODEV; |
1558 | } | 1547 | } |
1559 | 1548 | ||
1560 | #else /* !CONFIG_SUN4 */ | 1549 | static int __exit sunlance_sun4_remove(void) |
1561 | |||
1562 | /* Find all the lance cards on the system and initialize them */ | ||
1563 | static int __init sparc_lance_probe(void) | ||
1564 | { | 1550 | { |
1565 | struct sbus_bus *bus; | 1551 | struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); |
1566 | struct sbus_dev *sdev = NULL; | 1552 | struct net_device *net_dev = lp->dev; |
1567 | struct sbus_dma *ledma = NULL; | 1553 | |
1568 | static int called; | 1554 | unregister_netdevice(net_dev); |
1569 | int cards = 0, v; | 1555 | |
1570 | 1556 | lance_free_hwresources(root_lance_dev); | |
1571 | root_lance_dev = NULL; | 1557 | |
1572 | 1558 | free_netdev(net_dev); | |
1573 | if (called) | 1559 | |
1574 | return -ENODEV; | 1560 | dev_set_drvdata(&sun4_sdev->dev, NULL); |
1575 | called++; | 1561 | |
1576 | |||
1577 | for_each_sbus (bus) { | ||
1578 | for_each_sbusdev (sdev, bus) { | ||
1579 | if (strcmp(sdev->prom_name, "le") == 0) { | ||
1580 | cards++; | ||
1581 | if ((v = sparc_lance_init(sdev, NULL, NULL))) | ||
1582 | return v; | ||
1583 | continue; | ||
1584 | } | ||
1585 | if (strcmp(sdev->prom_name, "ledma") == 0) { | ||
1586 | cards++; | ||
1587 | ledma = find_ledma(sdev); | ||
1588 | if ((v = sparc_lance_init(sdev->child, | ||
1589 | ledma, NULL))) | ||
1590 | return v; | ||
1591 | continue; | ||
1592 | } | ||
1593 | if (strcmp(sdev->prom_name, "lebuffer") == 0){ | ||
1594 | cards++; | ||
1595 | if ((v = sparc_lance_init(sdev->child, | ||
1596 | NULL, sdev))) | ||
1597 | return v; | ||
1598 | continue; | ||
1599 | } | ||
1600 | } /* for each sbusdev */ | ||
1601 | } /* for each sbus */ | ||
1602 | if (!cards) | ||
1603 | return -ENODEV; | ||
1604 | return 0; | 1562 | return 0; |
1605 | } | 1563 | } |
1606 | #endif /* !CONFIG_SUN4 */ | ||
1607 | 1564 | ||
1608 | static void __exit sparc_lance_cleanup(void) | 1565 | #else /* !CONFIG_SUN4 */ |
1566 | |||
1567 | static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) | ||
1609 | { | 1568 | { |
1610 | struct lance_private *lp; | 1569 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
1570 | struct device_node *dp = dev->node; | ||
1571 | int err; | ||
1572 | |||
1573 | if (!strcmp(dp->name, "le")) { | ||
1574 | err = sparc_lance_probe_one(sdev, NULL, NULL); | ||
1575 | } else if (!strcmp(dp->name, "ledma")) { | ||
1576 | struct sbus_dma *ledma = find_ledma(sdev); | ||
1611 | 1577 | ||
1612 | while (root_lance_dev) { | 1578 | err = sparc_lance_probe_one(sdev->child, ledma, NULL); |
1613 | lp = root_lance_dev->next_module; | 1579 | } else { |
1580 | BUG_ON(strcmp(dp->name, "lebuffer")); | ||
1614 | 1581 | ||
1615 | unregister_netdev(root_lance_dev->dev); | 1582 | err = sparc_lance_probe_one(sdev->child, NULL, sdev); |
1616 | lance_free_hwresources(root_lance_dev); | ||
1617 | free_netdev(root_lance_dev->dev); | ||
1618 | root_lance_dev = lp; | ||
1619 | } | 1583 | } |
1584 | |||
1585 | return err; | ||
1586 | } | ||
1587 | |||
1588 | static int __devexit sunlance_sbus_remove(struct of_device *dev) | ||
1589 | { | ||
1590 | struct lance_private *lp = dev_get_drvdata(&dev->dev); | ||
1591 | struct net_device *net_dev = lp->dev; | ||
1592 | |||
1593 | unregister_netdevice(net_dev); | ||
1594 | |||
1595 | lance_free_hwresources(lp); | ||
1596 | |||
1597 | free_netdev(net_dev); | ||
1598 | |||
1599 | dev_set_drvdata(&dev->dev, NULL); | ||
1600 | |||
1601 | return 0; | ||
1602 | } | ||
1603 | |||
1604 | static struct of_device_id sunlance_sbus_match[] = { | ||
1605 | { | ||
1606 | .name = "le", | ||
1607 | }, | ||
1608 | { | ||
1609 | .name = "ledma", | ||
1610 | }, | ||
1611 | { | ||
1612 | .name = "lebuffer", | ||
1613 | }, | ||
1614 | {}, | ||
1615 | }; | ||
1616 | |||
1617 | MODULE_DEVICE_TABLE(of, sunlance_sbus_match); | ||
1618 | |||
1619 | static struct of_platform_driver sunlance_sbus_driver = { | ||
1620 | .name = "sunlance", | ||
1621 | .match_table = sunlance_sbus_match, | ||
1622 | .probe = sunlance_sbus_probe, | ||
1623 | .remove = __devexit_p(sunlance_sbus_remove), | ||
1624 | }; | ||
1625 | |||
1626 | |||
1627 | /* Find all the lance cards on the system and initialize them */ | ||
1628 | static int __init sparc_lance_init(void) | ||
1629 | { | ||
1630 | return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type); | ||
1631 | } | ||
1632 | #endif /* !CONFIG_SUN4 */ | ||
1633 | |||
1634 | static void __exit sparc_lance_exit(void) | ||
1635 | { | ||
1636 | #ifdef CONFIG_SUN4 | ||
1637 | sunlance_sun4_remove(); | ||
1638 | #else | ||
1639 | of_unregister_driver(&sunlance_sbus_driver); | ||
1640 | #endif | ||
1620 | } | 1641 | } |
1621 | 1642 | ||
1622 | module_init(sparc_lance_probe); | 1643 | module_init(sparc_lance_init); |
1623 | module_exit(sparc_lance_cleanup); | 1644 | module_exit(sparc_lance_exit); |