diff options
Diffstat (limited to 'drivers/net/sunlance.c')
-rw-r--r-- | drivers/net/sunlance.c | 233 |
1 files changed, 124 insertions, 109 deletions
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 6381243d8d0..feb42db10ee 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c | |||
@@ -64,14 +64,13 @@ | |||
64 | * David S. Miller (davem@redhat.com) | 64 | * David S. Miller (davem@redhat.com) |
65 | * 2.01: | 65 | * 2.01: |
66 | * 11/08/01: Use library crc32 functions (Matt_Domsch@dell.com) | 66 | * 11/08/01: Use library crc32 functions (Matt_Domsch@dell.com) |
67 | * | 67 | * |
68 | */ | 68 | */ |
69 | 69 | ||
70 | #undef DEBUG_DRIVER | 70 | #undef DEBUG_DRIVER |
71 | 71 | ||
72 | static char lancestr[] = "LANCE"; | 72 | static char lancestr[] = "LANCE"; |
73 | 73 | ||
74 | #include <linux/config.h> | ||
75 | #include <linux/module.h> | 74 | #include <linux/module.h> |
76 | #include <linux/kernel.h> | 75 | #include <linux/kernel.h> |
77 | #include <linux/types.h> | 76 | #include <linux/types.h> |
@@ -210,7 +209,7 @@ struct lance_tx_desc { | |||
210 | s16 length; /* Length is 2s complement (negative)! */ | 209 | s16 length; /* Length is 2s complement (negative)! */ |
211 | u16 misc; | 210 | u16 misc; |
212 | }; | 211 | }; |
213 | 212 | ||
214 | /* The LANCE initialization block, described in databook. */ | 213 | /* The LANCE initialization block, described in databook. */ |
215 | /* On the Sparc, this block should be on a DMA region */ | 214 | /* On the Sparc, this block should be on a DMA region */ |
216 | struct lance_init_block { | 215 | struct lance_init_block { |
@@ -223,11 +222,11 @@ struct lance_init_block { | |||
223 | u16 rx_len; /* receive len and high addr */ | 222 | u16 rx_len; /* receive len and high addr */ |
224 | u16 tx_ptr; /* transmit descriptor addr */ | 223 | u16 tx_ptr; /* transmit descriptor addr */ |
225 | u16 tx_len; /* transmit len and high addr */ | 224 | u16 tx_len; /* transmit len and high addr */ |
226 | 225 | ||
227 | /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */ | 226 | /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */ |
228 | struct lance_rx_desc brx_ring[RX_RING_SIZE]; | 227 | struct lance_rx_desc brx_ring[RX_RING_SIZE]; |
229 | struct lance_tx_desc btx_ring[TX_RING_SIZE]; | 228 | struct lance_tx_desc btx_ring[TX_RING_SIZE]; |
230 | 229 | ||
231 | u8 tx_buf [TX_RING_SIZE][TX_BUFF_SIZE]; | 230 | u8 tx_buf [TX_RING_SIZE][TX_BUFF_SIZE]; |
232 | u8 pad[2]; /* align rx_buf for copy_and_sum(). */ | 231 | u8 pad[2]; /* align rx_buf for copy_and_sum(). */ |
233 | u8 rx_buf [RX_RING_SIZE][RX_BUFF_SIZE]; | 232 | u8 rx_buf [RX_RING_SIZE][RX_BUFF_SIZE]; |
@@ -244,12 +243,12 @@ struct lance_private { | |||
244 | void __iomem *dregs; /* DMA controller regs. */ | 243 | void __iomem *dregs; /* DMA controller regs. */ |
245 | struct lance_init_block __iomem *init_block_iomem; | 244 | struct lance_init_block __iomem *init_block_iomem; |
246 | struct lance_init_block *init_block_mem; | 245 | struct lance_init_block *init_block_mem; |
247 | 246 | ||
248 | spinlock_t lock; | 247 | spinlock_t lock; |
249 | 248 | ||
250 | int rx_new, tx_new; | 249 | int rx_new, tx_new; |
251 | int rx_old, tx_old; | 250 | int rx_old, tx_old; |
252 | 251 | ||
253 | struct net_device_stats stats; | 252 | struct net_device_stats stats; |
254 | struct sbus_dma *ledma; /* If set this points to ledma */ | 253 | struct sbus_dma *ledma; /* If set this points to ledma */ |
255 | char tpe; /* cable-selection is TPE */ | 254 | char tpe; /* cable-selection is TPE */ |
@@ -266,7 +265,6 @@ struct lance_private { | |||
266 | char *name; | 265 | char *name; |
267 | dma_addr_t init_block_dvma; | 266 | dma_addr_t init_block_dvma; |
268 | struct net_device *dev; /* Backpointer */ | 267 | struct net_device *dev; /* Backpointer */ |
269 | struct lance_private *next_module; | ||
270 | struct sbus_dev *sdev; | 268 | struct sbus_dev *sdev; |
271 | struct timer_list multicast_timer; | 269 | struct timer_list multicast_timer; |
272 | }; | 270 | }; |
@@ -298,8 +296,6 @@ int sparc_lance_debug = 2; | |||
298 | 296 | ||
299 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) | 297 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) |
300 | 298 | ||
301 | static struct lance_private *root_lance_dev; | ||
302 | |||
303 | /* Load the CSR registers */ | 299 | /* Load the CSR registers */ |
304 | static void load_csrs(struct lance_private *lp) | 300 | static void load_csrs(struct lance_private *lp) |
305 | { | 301 | { |
@@ -329,7 +325,7 @@ static void lance_init_ring_dvma(struct net_device *dev) | |||
329 | dma_addr_t aib = lp->init_block_dvma; | 325 | dma_addr_t aib = lp->init_block_dvma; |
330 | __u32 leptr; | 326 | __u32 leptr; |
331 | int i; | 327 | int i; |
332 | 328 | ||
333 | /* Lock out other processes while setting up hardware */ | 329 | /* Lock out other processes while setting up hardware */ |
334 | netif_stop_queue(dev); | 330 | netif_stop_queue(dev); |
335 | lp->rx_new = lp->tx_new = 0; | 331 | lp->rx_new = lp->tx_new = 0; |
@@ -367,12 +363,12 @@ static void lance_init_ring_dvma(struct net_device *dev) | |||
367 | } | 363 | } |
368 | 364 | ||
369 | /* Setup the initialization block */ | 365 | /* Setup the initialization block */ |
370 | 366 | ||
371 | /* Setup rx descriptor pointer */ | 367 | /* Setup rx descriptor pointer */ |
372 | leptr = LANCE_ADDR(aib + libdesc_offset(brx_ring, 0)); | 368 | leptr = LANCE_ADDR(aib + libdesc_offset(brx_ring, 0)); |
373 | ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16); | 369 | ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16); |
374 | ib->rx_ptr = leptr; | 370 | ib->rx_ptr = leptr; |
375 | 371 | ||
376 | /* Setup tx descriptor pointer */ | 372 | /* Setup tx descriptor pointer */ |
377 | leptr = LANCE_ADDR(aib + libdesc_offset(btx_ring, 0)); | 373 | leptr = LANCE_ADDR(aib + libdesc_offset(btx_ring, 0)); |
378 | ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16); | 374 | ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16); |
@@ -385,7 +381,7 @@ static void lance_init_ring_pio(struct net_device *dev) | |||
385 | struct lance_init_block __iomem *ib = lp->init_block_iomem; | 381 | struct lance_init_block __iomem *ib = lp->init_block_iomem; |
386 | u32 leptr; | 382 | u32 leptr; |
387 | int i; | 383 | int i; |
388 | 384 | ||
389 | /* Lock out other processes while setting up hardware */ | 385 | /* Lock out other processes while setting up hardware */ |
390 | netif_stop_queue(dev); | 386 | netif_stop_queue(dev); |
391 | lp->rx_new = lp->tx_new = 0; | 387 | lp->rx_new = lp->tx_new = 0; |
@@ -426,13 +422,13 @@ static void lance_init_ring_pio(struct net_device *dev) | |||
426 | } | 422 | } |
427 | 423 | ||
428 | /* Setup the initialization block */ | 424 | /* Setup the initialization block */ |
429 | 425 | ||
430 | /* Setup rx descriptor pointer */ | 426 | /* Setup rx descriptor pointer */ |
431 | leptr = libdesc_offset(brx_ring, 0); | 427 | leptr = libdesc_offset(brx_ring, 0); |
432 | sbus_writew((LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16), | 428 | sbus_writew((LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16), |
433 | &ib->rx_len); | 429 | &ib->rx_len); |
434 | sbus_writew(leptr, &ib->rx_ptr); | 430 | sbus_writew(leptr, &ib->rx_ptr); |
435 | 431 | ||
436 | /* Setup tx descriptor pointer */ | 432 | /* Setup tx descriptor pointer */ |
437 | leptr = libdesc_offset(btx_ring, 0); | 433 | leptr = libdesc_offset(btx_ring, 0); |
438 | sbus_writew((LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16), | 434 | sbus_writew((LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16), |
@@ -548,7 +544,7 @@ static void lance_rx_dvma(struct net_device *dev) | |||
548 | lp->rx_new = RX_NEXT(entry); | 544 | lp->rx_new = RX_NEXT(entry); |
549 | return; | 545 | return; |
550 | } | 546 | } |
551 | 547 | ||
552 | lp->stats.rx_bytes += len; | 548 | lp->stats.rx_bytes += len; |
553 | 549 | ||
554 | skb->dev = dev; | 550 | skb->dev = dev; |
@@ -588,10 +584,10 @@ static void lance_tx_dvma(struct net_device *dev) | |||
588 | /* If we hit a packet not owned by us, stop */ | 584 | /* If we hit a packet not owned by us, stop */ |
589 | if (bits & LE_T1_OWN) | 585 | if (bits & LE_T1_OWN) |
590 | break; | 586 | break; |
591 | 587 | ||
592 | if (bits & LE_T1_ERR) { | 588 | if (bits & LE_T1_ERR) { |
593 | u16 status = td->misc; | 589 | u16 status = td->misc; |
594 | 590 | ||
595 | lp->stats.tx_errors++; | 591 | lp->stats.tx_errors++; |
596 | if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; | 592 | if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; |
597 | if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; | 593 | if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; |
@@ -640,7 +636,7 @@ static void lance_tx_dvma(struct net_device *dev) | |||
640 | 636 | ||
641 | lp->stats.tx_packets++; | 637 | lp->stats.tx_packets++; |
642 | } | 638 | } |
643 | 639 | ||
644 | j = TX_NEXT(j); | 640 | j = TX_NEXT(j); |
645 | } | 641 | } |
646 | lp->tx_old = j; | 642 | lp->tx_old = j; |
@@ -722,7 +718,7 @@ static void lance_rx_pio(struct net_device *dev) | |||
722 | lp->rx_new = RX_NEXT(entry); | 718 | lp->rx_new = RX_NEXT(entry); |
723 | return; | 719 | return; |
724 | } | 720 | } |
725 | 721 | ||
726 | lp->stats.rx_bytes += len; | 722 | lp->stats.rx_bytes += len; |
727 | 723 | ||
728 | skb->dev = dev; | 724 | skb->dev = dev; |
@@ -760,10 +756,10 @@ static void lance_tx_pio(struct net_device *dev) | |||
760 | /* If we hit a packet not owned by us, stop */ | 756 | /* If we hit a packet not owned by us, stop */ |
761 | if (bits & LE_T1_OWN) | 757 | if (bits & LE_T1_OWN) |
762 | break; | 758 | break; |
763 | 759 | ||
764 | if (bits & LE_T1_ERR) { | 760 | if (bits & LE_T1_ERR) { |
765 | u16 status = sbus_readw(&td->misc); | 761 | u16 status = sbus_readw(&td->misc); |
766 | 762 | ||
767 | lp->stats.tx_errors++; | 763 | lp->stats.tx_errors++; |
768 | if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; | 764 | if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; |
769 | if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; | 765 | if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; |
@@ -812,7 +808,7 @@ static void lance_tx_pio(struct net_device *dev) | |||
812 | 808 | ||
813 | lp->stats.tx_packets++; | 809 | lp->stats.tx_packets++; |
814 | } | 810 | } |
815 | 811 | ||
816 | j = TX_NEXT(j); | 812 | j = TX_NEXT(j); |
817 | } | 813 | } |
818 | lp->tx_old = j; | 814 | lp->tx_old = j; |
@@ -829,27 +825,27 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
829 | struct net_device *dev = (struct net_device *)dev_id; | 825 | struct net_device *dev = (struct net_device *)dev_id; |
830 | struct lance_private *lp = netdev_priv(dev); | 826 | struct lance_private *lp = netdev_priv(dev); |
831 | int csr0; | 827 | int csr0; |
832 | 828 | ||
833 | sbus_writew(LE_CSR0, lp->lregs + RAP); | 829 | sbus_writew(LE_CSR0, lp->lregs + RAP); |
834 | csr0 = sbus_readw(lp->lregs + RDP); | 830 | csr0 = sbus_readw(lp->lregs + RDP); |
835 | 831 | ||
836 | /* Acknowledge all the interrupt sources ASAP */ | 832 | /* Acknowledge all the interrupt sources ASAP */ |
837 | sbus_writew(csr0 & (LE_C0_INTR | LE_C0_TINT | LE_C0_RINT), | 833 | sbus_writew(csr0 & (LE_C0_INTR | LE_C0_TINT | LE_C0_RINT), |
838 | lp->lregs + RDP); | 834 | lp->lregs + RDP); |
839 | 835 | ||
840 | if ((csr0 & LE_C0_ERR) != 0) { | 836 | if ((csr0 & LE_C0_ERR) != 0) { |
841 | /* Clear the error condition */ | 837 | /* Clear the error condition */ |
842 | sbus_writew((LE_C0_BABL | LE_C0_ERR | LE_C0_MISS | | 838 | sbus_writew((LE_C0_BABL | LE_C0_ERR | LE_C0_MISS | |
843 | LE_C0_CERR | LE_C0_MERR), | 839 | LE_C0_CERR | LE_C0_MERR), |
844 | lp->lregs + RDP); | 840 | lp->lregs + RDP); |
845 | } | 841 | } |
846 | 842 | ||
847 | if (csr0 & LE_C0_RINT) | 843 | if (csr0 & LE_C0_RINT) |
848 | lp->rx(dev); | 844 | lp->rx(dev); |
849 | 845 | ||
850 | if (csr0 & LE_C0_TINT) | 846 | if (csr0 & LE_C0_TINT) |
851 | lp->tx(dev); | 847 | lp->tx(dev); |
852 | 848 | ||
853 | if (csr0 & LE_C0_BABL) | 849 | if (csr0 & LE_C0_BABL) |
854 | lp->stats.tx_errors++; | 850 | lp->stats.tx_errors++; |
855 | 851 | ||
@@ -934,7 +930,7 @@ static int lance_open(struct net_device *dev) | |||
934 | 930 | ||
935 | STOP_LANCE(lp); | 931 | STOP_LANCE(lp); |
936 | 932 | ||
937 | if (request_irq(dev->irq, &lance_interrupt, SA_SHIRQ, | 933 | if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED, |
938 | lancestr, (void *) dev)) { | 934 | lancestr, (void *) dev)) { |
939 | printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq); | 935 | printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq); |
940 | return -EAGAIN; | 936 | return -EAGAIN; |
@@ -996,7 +992,7 @@ static int lance_reset(struct net_device *dev) | |||
996 | { | 992 | { |
997 | struct lance_private *lp = netdev_priv(dev); | 993 | struct lance_private *lp = netdev_priv(dev); |
998 | int status; | 994 | int status; |
999 | 995 | ||
1000 | STOP_LANCE(lp); | 996 | STOP_LANCE(lp); |
1001 | 997 | ||
1002 | /* On the 4m, reset the dma too */ | 998 | /* On the 4m, reset the dma too */ |
@@ -1173,7 +1169,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1173 | 1169 | ||
1174 | dev->trans_start = jiffies; | 1170 | dev->trans_start = jiffies; |
1175 | dev_kfree_skb(skb); | 1171 | dev_kfree_skb(skb); |
1176 | 1172 | ||
1177 | return 0; | 1173 | return 0; |
1178 | } | 1174 | } |
1179 | 1175 | ||
@@ -1193,7 +1189,7 @@ static void lance_load_multicast(struct net_device *dev) | |||
1193 | int i; | 1189 | int i; |
1194 | u32 crc; | 1190 | u32 crc; |
1195 | u32 val; | 1191 | u32 val; |
1196 | 1192 | ||
1197 | /* set all multicast bits */ | 1193 | /* set all multicast bits */ |
1198 | if (dev->flags & IFF_ALLMULTI) | 1194 | if (dev->flags & IFF_ALLMULTI) |
1199 | val = ~0; | 1195 | val = ~0; |
@@ -1212,7 +1208,7 @@ static void lance_load_multicast(struct net_device *dev) | |||
1212 | 1208 | ||
1213 | if (dev->flags & IFF_ALLMULTI) | 1209 | if (dev->flags & IFF_ALLMULTI) |
1214 | return; | 1210 | return; |
1215 | 1211 | ||
1216 | /* Add addresses */ | 1212 | /* Add addresses */ |
1217 | for (i = 0; i < dev->mc_count; i++) { | 1213 | for (i = 0; i < dev->mc_count; i++) { |
1218 | addrs = dmi->dmi_addr; | 1214 | addrs = dmi->dmi_addr; |
@@ -1322,14 +1318,14 @@ static u32 sparc_lance_get_link(struct net_device *dev) | |||
1322 | return 1; | 1318 | return 1; |
1323 | } | 1319 | } |
1324 | 1320 | ||
1325 | static struct ethtool_ops sparc_lance_ethtool_ops = { | 1321 | static const struct ethtool_ops sparc_lance_ethtool_ops = { |
1326 | .get_drvinfo = sparc_lance_get_drvinfo, | 1322 | .get_drvinfo = sparc_lance_get_drvinfo, |
1327 | .get_link = sparc_lance_get_link, | 1323 | .get_link = sparc_lance_get_link, |
1328 | }; | 1324 | }; |
1329 | 1325 | ||
1330 | static int __init sparc_lance_init(struct sbus_dev *sdev, | 1326 | static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, |
1331 | struct sbus_dma *ledma, | 1327 | struct sbus_dma *ledma, |
1332 | struct sbus_dev *lebuffer) | 1328 | struct sbus_dev *lebuffer) |
1333 | { | 1329 | { |
1334 | static unsigned version_printed; | 1330 | static unsigned version_printed; |
1335 | struct net_device *dev; | 1331 | struct net_device *dev; |
@@ -1473,6 +1469,7 @@ no_link_test: | |||
1473 | 1469 | ||
1474 | lp->dev = dev; | 1470 | lp->dev = dev; |
1475 | SET_MODULE_OWNER(dev); | 1471 | SET_MODULE_OWNER(dev); |
1472 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
1476 | dev->open = &lance_open; | 1473 | dev->open = &lance_open; |
1477 | dev->stop = &lance_close; | 1474 | dev->stop = &lance_close; |
1478 | dev->hard_start_xmit = &lance_start_xmit; | 1475 | dev->hard_start_xmit = &lance_start_xmit; |
@@ -1500,8 +1497,7 @@ no_link_test: | |||
1500 | goto fail; | 1497 | goto fail; |
1501 | } | 1498 | } |
1502 | 1499 | ||
1503 | lp->next_module = root_lance_dev; | 1500 | dev_set_drvdata(&sdev->ofdev.dev, lp); |
1504 | root_lance_dev = lp; | ||
1505 | 1501 | ||
1506 | printk(KERN_INFO "%s: LANCE ", dev->name); | 1502 | printk(KERN_INFO "%s: LANCE ", dev->name); |
1507 | 1503 | ||
@@ -1519,7 +1515,7 @@ fail: | |||
1519 | } | 1515 | } |
1520 | 1516 | ||
1521 | /* On 4m, find the associated dma for the lance chip */ | 1517 | /* On 4m, find the associated dma for the lance chip */ |
1522 | static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | 1518 | static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev) |
1523 | { | 1519 | { |
1524 | struct sbus_dma *p; | 1520 | struct sbus_dma *p; |
1525 | 1521 | ||
@@ -1536,88 +1532,107 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | |||
1536 | #include <asm/machines.h> | 1532 | #include <asm/machines.h> |
1537 | 1533 | ||
1538 | /* Find all the lance cards on the system and initialize them */ | 1534 | /* Find all the lance cards on the system and initialize them */ |
1539 | static int __init sparc_lance_probe(void) | 1535 | static struct sbus_dev sun4_sdev; |
1536 | static int __devinit sparc_lance_init(void) | ||
1540 | { | 1537 | { |
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)) || | 1538 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || |
1551 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | 1539 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { |
1552 | memset(&sdev, 0, sizeof(sdev)); | 1540 | memset(&sun4_sdev, 0, sizeof(struct sbus_dev)); |
1553 | sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; | 1541 | sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; |
1554 | sdev.irqs[0] = 6; | 1542 | sun4_sdev.irqs[0] = 6; |
1555 | return sparc_lance_init(&sdev, NULL, NULL); | 1543 | return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); |
1556 | } | 1544 | } |
1557 | return -ENODEV; | 1545 | return -ENODEV; |
1558 | } | 1546 | } |
1559 | 1547 | ||
1548 | static int __exit sunlance_sun4_remove(void) | ||
1549 | { | ||
1550 | struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev); | ||
1551 | struct net_device *net_dev = lp->dev; | ||
1552 | |||
1553 | unregister_netdevice(net_dev); | ||
1554 | |||
1555 | lance_free_hwresources(lp); | ||
1556 | |||
1557 | free_netdev(net_dev); | ||
1558 | |||
1559 | dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL); | ||
1560 | |||
1561 | return 0; | ||
1562 | } | ||
1563 | |||
1560 | #else /* !CONFIG_SUN4 */ | 1564 | #else /* !CONFIG_SUN4 */ |
1561 | 1565 | ||
1562 | /* Find all the lance cards on the system and initialize them */ | 1566 | static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) |
1563 | static int __init sparc_lance_probe(void) | ||
1564 | { | 1567 | { |
1565 | struct sbus_bus *bus; | 1568 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
1566 | struct sbus_dev *sdev = NULL; | 1569 | int err; |
1567 | struct sbus_dma *ledma = NULL; | 1570 | |
1568 | static int called; | 1571 | if (sdev->parent) { |
1569 | int cards = 0, v; | 1572 | struct of_device *parent = &sdev->parent->ofdev; |
1570 | 1573 | ||
1571 | root_lance_dev = NULL; | 1574 | if (!strcmp(parent->node->name, "ledma")) { |
1572 | 1575 | struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev)); | |
1573 | if (called) | 1576 | |
1574 | return -ENODEV; | 1577 | err = sparc_lance_probe_one(sdev, ledma, NULL); |
1575 | called++; | 1578 | } else if (!strcmp(parent->node->name, "lebuffer")) { |
1576 | 1579 | err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev)); | |
1577 | for_each_sbus (bus) { | 1580 | } else |
1578 | for_each_sbusdev (sdev, bus) { | 1581 | err = sparc_lance_probe_one(sdev, NULL, NULL); |
1579 | if (strcmp(sdev->prom_name, "le") == 0) { | 1582 | } else |
1580 | cards++; | 1583 | err = sparc_lance_probe_one(sdev, NULL, NULL); |
1581 | if ((v = sparc_lance_init(sdev, NULL, NULL))) | 1584 | |
1582 | return v; | 1585 | return err; |
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; | ||
1605 | } | 1586 | } |
1606 | #endif /* !CONFIG_SUN4 */ | ||
1607 | 1587 | ||
1608 | static void __exit sparc_lance_cleanup(void) | 1588 | static int __devexit sunlance_sbus_remove(struct of_device *dev) |
1609 | { | 1589 | { |
1610 | struct lance_private *lp; | 1590 | struct lance_private *lp = dev_get_drvdata(&dev->dev); |
1591 | struct net_device *net_dev = lp->dev; | ||
1611 | 1592 | ||
1612 | while (root_lance_dev) { | 1593 | unregister_netdevice(net_dev); |
1613 | lp = root_lance_dev->next_module; | ||
1614 | 1594 | ||
1615 | unregister_netdev(root_lance_dev->dev); | 1595 | lance_free_hwresources(lp); |
1616 | lance_free_hwresources(root_lance_dev); | 1596 | |
1617 | free_netdev(root_lance_dev->dev); | 1597 | free_netdev(net_dev); |
1618 | root_lance_dev = lp; | 1598 | |
1619 | } | 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 | }; | ||
1610 | |||
1611 | MODULE_DEVICE_TABLE(of, sunlance_sbus_match); | ||
1612 | |||
1613 | static struct of_platform_driver sunlance_sbus_driver = { | ||
1614 | .name = "sunlance", | ||
1615 | .match_table = sunlance_sbus_match, | ||
1616 | .probe = sunlance_sbus_probe, | ||
1617 | .remove = __devexit_p(sunlance_sbus_remove), | ||
1618 | }; | ||
1619 | |||
1620 | |||
1621 | /* Find all the lance cards on the system and initialize them */ | ||
1622 | static int __init sparc_lance_init(void) | ||
1623 | { | ||
1624 | return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type); | ||
1625 | } | ||
1626 | #endif /* !CONFIG_SUN4 */ | ||
1627 | |||
1628 | static void __exit sparc_lance_exit(void) | ||
1629 | { | ||
1630 | #ifdef CONFIG_SUN4 | ||
1631 | sunlance_sun4_remove(); | ||
1632 | #else | ||
1633 | of_unregister_driver(&sunlance_sbus_driver); | ||
1634 | #endif | ||
1620 | } | 1635 | } |
1621 | 1636 | ||
1622 | module_init(sparc_lance_probe); | 1637 | module_init(sparc_lance_init); |
1623 | module_exit(sparc_lance_cleanup); | 1638 | module_exit(sparc_lance_exit); |