diff options
author | Jaccon Bastiaansen <jaccon.bastiaansen@gmail.com> | 2012-05-17 03:11:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-17 19:01:40 -0400 |
commit | 09dcd604aea065b121c635e40baf4ed2ce60e3f0 (patch) | |
tree | 19ae4b300638bf742b6be6d52b9b221294e566e9 /drivers/net/ethernet/cirrus | |
parent | a508da6cc0093171833efb8376b00473f24221b9 (diff) |
CS89x0 : Use ioread16/iowrite16 on all platforms
The use of the inw/outw functions by the cs89x0 platform driver
results in NULL pointer references on ARM platforms and
platforms that do not provide ISA-style programmed I/O accessors.
Using inw/outw also accesses the wrong address space on platforms
that have a PCI I/O space that is not identity-mapped into the
physical address space.
Signed-off-by: Jaccon Bastiaansen <jaccon.bastiaansen@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cirrus')
-rw-r--r-- | drivers/net/ethernet/cirrus/cs89x0.c | 341 |
1 files changed, 183 insertions, 158 deletions
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index b9406cbfc180..1d59030e7d94 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c | |||
@@ -222,6 +222,8 @@ struct net_local { | |||
222 | int send_underrun; /* keep track of how many underruns in a row we get */ | 222 | int send_underrun; /* keep track of how many underruns in a row we get */ |
223 | int force; /* force various values; see FORCE* above. */ | 223 | int force; /* force various values; see FORCE* above. */ |
224 | spinlock_t lock; | 224 | spinlock_t lock; |
225 | void __iomem *virt_addr;/* CS89x0 virtual address. */ | ||
226 | unsigned long size; /* Length of CS89x0 memory region. */ | ||
225 | #if ALLOW_DMA | 227 | #if ALLOW_DMA |
226 | int use_dma; /* Flag: we're using dma */ | 228 | int use_dma; /* Flag: we're using dma */ |
227 | int dma; /* DMA channel */ | 229 | int dma; /* DMA channel */ |
@@ -230,16 +232,9 @@ struct net_local { | |||
230 | unsigned char *end_dma_buff; /* points to the end of the buffer */ | 232 | unsigned char *end_dma_buff; /* points to the end of the buffer */ |
231 | unsigned char *rx_dma_ptr; /* points to the next packet */ | 233 | unsigned char *rx_dma_ptr; /* points to the next packet */ |
232 | #endif | 234 | #endif |
233 | #ifdef CONFIG_CS89x0_PLATFORM | ||
234 | void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */ | ||
235 | unsigned long phys_addr;/* Physical address for accessing the CS89x0. */ | ||
236 | unsigned long size; /* Length of CS89x0 memory region. */ | ||
237 | #endif | ||
238 | }; | 235 | }; |
239 | 236 | ||
240 | /* Index to functions, as function prototypes. */ | 237 | /* Index to functions, as function prototypes. */ |
241 | |||
242 | static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular); | ||
243 | static int net_open(struct net_device *dev); | 238 | static int net_open(struct net_device *dev); |
244 | static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev); | 239 | static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev); |
245 | static irqreturn_t net_interrupt(int irq, void *dev_id); | 240 | static irqreturn_t net_interrupt(int irq, void *dev_id); |
@@ -267,7 +262,8 @@ static void release_dma_buff(struct net_local *lp); | |||
267 | /* | 262 | /* |
268 | * Permit 'cs89x0_dma=N' in the kernel boot environment | 263 | * Permit 'cs89x0_dma=N' in the kernel boot environment |
269 | */ | 264 | */ |
270 | #if !defined(MODULE) && (ALLOW_DMA != 0) | 265 | #if !defined(MODULE) |
266 | #if ALLOW_DMA | ||
271 | static int g_cs89x0_dma; | 267 | static int g_cs89x0_dma; |
272 | 268 | ||
273 | static int __init dma_fn(char *str) | 269 | static int __init dma_fn(char *str) |
@@ -277,9 +273,8 @@ static int __init dma_fn(char *str) | |||
277 | } | 273 | } |
278 | 274 | ||
279 | __setup("cs89x0_dma=", dma_fn); | 275 | __setup("cs89x0_dma=", dma_fn); |
280 | #endif /* !defined(MODULE) && (ALLOW_DMA != 0) */ | 276 | #endif /* ALLOW_DMA */ |
281 | 277 | ||
282 | #ifndef MODULE | ||
283 | static int g_cs89x0_media__force; | 278 | static int g_cs89x0_media__force; |
284 | 279 | ||
285 | static int __init media_fn(char *str) | 280 | static int __init media_fn(char *str) |
@@ -291,58 +286,6 @@ static int __init media_fn(char *str) | |||
291 | } | 286 | } |
292 | 287 | ||
293 | __setup("cs89x0_media=", media_fn); | 288 | __setup("cs89x0_media=", media_fn); |
294 | |||
295 | |||
296 | #ifndef CONFIG_CS89x0_PLATFORM | ||
297 | /* Check for a network adaptor of this type, and return '0' iff one exists. | ||
298 | If dev->base_addr == 0, probe all likely locations. | ||
299 | If dev->base_addr == 1, always return failure. | ||
300 | If dev->base_addr == 2, allocate space for the device and return success | ||
301 | (detachable devices only). | ||
302 | Return 0 on success. | ||
303 | */ | ||
304 | |||
305 | struct net_device * __init cs89x0_probe(int unit) | ||
306 | { | ||
307 | struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); | ||
308 | unsigned *port; | ||
309 | int err = 0; | ||
310 | int irq; | ||
311 | int io; | ||
312 | |||
313 | if (!dev) | ||
314 | return ERR_PTR(-ENODEV); | ||
315 | |||
316 | sprintf(dev->name, "eth%d", unit); | ||
317 | netdev_boot_setup_check(dev); | ||
318 | io = dev->base_addr; | ||
319 | irq = dev->irq; | ||
320 | |||
321 | if (net_debug) | ||
322 | printk("cs89x0:cs89x0_probe(0x%x)\n", io); | ||
323 | |||
324 | if (io > 0x1ff) { /* Check a single specified location. */ | ||
325 | err = cs89x0_probe1(dev, io, 0); | ||
326 | } else if (io != 0) { /* Don't probe at all. */ | ||
327 | err = -ENXIO; | ||
328 | } else { | ||
329 | for (port = netcard_portlist; *port; port++) { | ||
330 | if (cs89x0_probe1(dev, *port, 0) == 0) | ||
331 | break; | ||
332 | dev->irq = irq; | ||
333 | } | ||
334 | if (!*port) | ||
335 | err = -ENODEV; | ||
336 | } | ||
337 | if (err) | ||
338 | goto out; | ||
339 | return dev; | ||
340 | out: | ||
341 | free_netdev(dev); | ||
342 | printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); | ||
343 | return ERR_PTR(err); | ||
344 | } | ||
345 | #endif | ||
346 | #endif | 289 | #endif |
347 | 290 | ||
348 | #if defined(CONFIG_MACH_IXDP2351) | 291 | #if defined(CONFIG_MACH_IXDP2351) |
@@ -369,36 +312,22 @@ writeword(unsigned long base_addr, int portno, u16 value) | |||
369 | { | 312 | { |
370 | __raw_writel(value, base_addr + (portno << 1)); | 313 | __raw_writel(value, base_addr + (portno << 1)); |
371 | } | 314 | } |
372 | #else | ||
373 | static u16 | ||
374 | readword(unsigned long base_addr, int portno) | ||
375 | { | ||
376 | return inw(base_addr + portno); | ||
377 | } | ||
378 | |||
379 | static void | ||
380 | writeword(unsigned long base_addr, int portno, u16 value) | ||
381 | { | ||
382 | outw(value, base_addr + portno); | ||
383 | } | ||
384 | #endif | 315 | #endif |
385 | 316 | ||
386 | static void | 317 | static void readwords(struct net_local *lp, int portno, void *buf, int length) |
387 | readwords(unsigned long base_addr, int portno, void *buf, int length) | ||
388 | { | 318 | { |
389 | u8 *buf8 = (u8 *)buf; | 319 | u8 *buf8 = (u8 *)buf; |
390 | 320 | ||
391 | do { | 321 | do { |
392 | u16 tmp16; | 322 | u16 tmp16; |
393 | 323 | ||
394 | tmp16 = readword(base_addr, portno); | 324 | tmp16 = ioread16(lp->virt_addr + portno); |
395 | *buf8++ = (u8)tmp16; | 325 | *buf8++ = (u8)tmp16; |
396 | *buf8++ = (u8)(tmp16 >> 8); | 326 | *buf8++ = (u8)(tmp16 >> 8); |
397 | } while (--length); | 327 | } while (--length); |
398 | } | 328 | } |
399 | 329 | ||
400 | static void | 330 | static void writewords(struct net_local *lp, int portno, void *buf, int length) |
401 | writewords(unsigned long base_addr, int portno, void *buf, int length) | ||
402 | { | 331 | { |
403 | u8 *buf8 = (u8 *)buf; | 332 | u8 *buf8 = (u8 *)buf; |
404 | 333 | ||
@@ -407,22 +336,26 @@ writewords(unsigned long base_addr, int portno, void *buf, int length) | |||
407 | 336 | ||
408 | tmp16 = *buf8++; | 337 | tmp16 = *buf8++; |
409 | tmp16 |= (*buf8++) << 8; | 338 | tmp16 |= (*buf8++) << 8; |
410 | writeword(base_addr, portno, tmp16); | 339 | iowrite16(tmp16, lp->virt_addr + portno); |
411 | } while (--length); | 340 | } while (--length); |
412 | } | 341 | } |
413 | 342 | ||
414 | static u16 | 343 | static u16 |
415 | readreg(struct net_device *dev, u16 regno) | 344 | readreg(struct net_device *dev, u16 regno) |
416 | { | 345 | { |
417 | writeword(dev->base_addr, ADD_PORT, regno); | 346 | struct net_local *lp = netdev_priv(dev); |
418 | return readword(dev->base_addr, DATA_PORT); | 347 | |
348 | iowrite16(regno, lp->virt_addr + ADD_PORT); | ||
349 | return ioread16(lp->virt_addr + DATA_PORT); | ||
419 | } | 350 | } |
420 | 351 | ||
421 | static void | 352 | static void |
422 | writereg(struct net_device *dev, u16 regno, u16 value) | 353 | writereg(struct net_device *dev, u16 regno, u16 value) |
423 | { | 354 | { |
424 | writeword(dev->base_addr, ADD_PORT, regno); | 355 | struct net_local *lp = netdev_priv(dev); |
425 | writeword(dev->base_addr, DATA_PORT, value); | 356 | |
357 | iowrite16(regno, lp->virt_addr + ADD_PORT); | ||
358 | iowrite16(value, lp->virt_addr + DATA_PORT); | ||
426 | } | 359 | } |
427 | 360 | ||
428 | static int __init | 361 | static int __init |
@@ -505,7 +438,7 @@ static const struct net_device_ops net_ops = { | |||
505 | */ | 438 | */ |
506 | 439 | ||
507 | static int __init | 440 | static int __init |
508 | cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) | 441 | cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular) |
509 | { | 442 | { |
510 | struct net_local *lp = netdev_priv(dev); | 443 | struct net_local *lp = netdev_priv(dev); |
511 | static unsigned version_printed; | 444 | static unsigned version_printed; |
@@ -529,50 +462,22 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) | |||
529 | #endif | 462 | #endif |
530 | lp->force = g_cs89x0_media__force; | 463 | lp->force = g_cs89x0_media__force; |
531 | #endif | 464 | #endif |
532 | |||
533 | } | 465 | } |
534 | 466 | ||
535 | /* Grab the region so we can find another board if autoIRQ fails. */ | 467 | printk(KERN_DEBUG "PP_addr at %p[%x]: 0x%x\n", |
536 | /* WTF is going on here? */ | 468 | ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT)); |
537 | if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) { | 469 | iowrite16(PP_ChipID, ioaddr + ADD_PORT); |
538 | printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n", | ||
539 | DRV_NAME, ioaddr, NETCARD_IO_EXTENT); | ||
540 | retval = -EBUSY; | ||
541 | goto out1; | ||
542 | } | ||
543 | 470 | ||
544 | /* if they give us an odd I/O address, then do ONE write to | 471 | tmp = ioread16(ioaddr + DATA_PORT); |
545 | the address port, to get it back to address zero, where we | ||
546 | expect to find the EISA signature word. An IO with a base of 0x3 | ||
547 | will skip the test for the ADD_PORT. */ | ||
548 | if (ioaddr & 1) { | ||
549 | if (net_debug > 1) | ||
550 | printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr); | ||
551 | if ((ioaddr & 2) != 2) | ||
552 | if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) { | ||
553 | printk(KERN_ERR "%s: bad signature 0x%x\n", | ||
554 | dev->name, readword(ioaddr & ~3, ADD_PORT)); | ||
555 | retval = -ENODEV; | ||
556 | goto out2; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | ioaddr &= ~3; | ||
561 | printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n", | ||
562 | ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT)); | ||
563 | writeword(ioaddr, ADD_PORT, PP_ChipID); | ||
564 | |||
565 | tmp = readword(ioaddr, DATA_PORT); | ||
566 | if (tmp != CHIP_EISA_ID_SIG) { | 472 | if (tmp != CHIP_EISA_ID_SIG) { |
567 | printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!=" | 473 | printk(KERN_DEBUG "%s: incorrect signature at %p[%x]: 0x%x!=" |
568 | CHIP_EISA_ID_SIG_STR "\n", | 474 | CHIP_EISA_ID_SIG_STR "\n", |
569 | dev->name, ioaddr, DATA_PORT, tmp); | 475 | dev->name, ioaddr, DATA_PORT, tmp); |
570 | retval = -ENODEV; | 476 | retval = -ENODEV; |
571 | goto out2; | 477 | goto out1; |
572 | } | 478 | } |
573 | 479 | ||
574 | /* Fill in the 'dev' fields. */ | 480 | lp->virt_addr = ioaddr; |
575 | dev->base_addr = ioaddr; | ||
576 | 481 | ||
577 | /* get the chip type */ | 482 | /* get the chip type */ |
578 | rev_type = readreg(dev, PRODUCT_ID_ADD); | 483 | rev_type = readreg(dev, PRODUCT_ID_ADD); |
@@ -590,12 +495,12 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) | |||
590 | if (net_debug && version_printed++ == 0) | 495 | if (net_debug && version_printed++ == 0) |
591 | printk(version); | 496 | printk(version); |
592 | 497 | ||
593 | printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#3lx ", | 498 | printk(KERN_INFO "%s: cs89%c0%s rev %c found at %p ", |
594 | dev->name, | 499 | dev->name, |
595 | lp->chip_type==CS8900?'0':'2', | 500 | lp->chip_type==CS8900?'0':'2', |
596 | lp->chip_type==CS8920M?"M":"", | 501 | lp->chip_type==CS8920M?"M":"", |
597 | lp->chip_revision, | 502 | lp->chip_revision, |
598 | dev->base_addr); | 503 | lp->virt_addr); |
599 | 504 | ||
600 | reset_chip(dev); | 505 | reset_chip(dev); |
601 | 506 | ||
@@ -787,16 +692,125 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) | |||
787 | 692 | ||
788 | retval = register_netdev(dev); | 693 | retval = register_netdev(dev); |
789 | if (retval) | 694 | if (retval) |
790 | goto out3; | 695 | goto out2; |
791 | return 0; | 696 | return 0; |
792 | out3: | ||
793 | writeword(dev->base_addr, ADD_PORT, PP_ChipID); | ||
794 | out2: | 697 | out2: |
795 | release_region(ioaddr & ~3, NETCARD_IO_EXTENT); | 698 | iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT); |
796 | out1: | 699 | out1: |
797 | return retval; | 700 | return retval; |
798 | } | 701 | } |
799 | 702 | ||
703 | #ifndef CONFIG_CS89x0_PLATFORM | ||
704 | /* | ||
705 | * This function converts the I/O port addres used by the cs89x0_probe() and | ||
706 | * init_module() functions to the I/O memory address used by the | ||
707 | * cs89x0_probe1() function. | ||
708 | */ | ||
709 | static int __init | ||
710 | cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular) | ||
711 | { | ||
712 | struct net_local *lp = netdev_priv(dev); | ||
713 | int ret; | ||
714 | void __iomem *io_mem; | ||
715 | |||
716 | if (!lp) | ||
717 | return -ENOMEM; | ||
718 | |||
719 | dev->base_addr = ioport; | ||
720 | |||
721 | if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) { | ||
722 | ret = -EBUSY; | ||
723 | goto out; | ||
724 | } | ||
725 | |||
726 | io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT); | ||
727 | if (!io_mem) { | ||
728 | ret = -ENOMEM; | ||
729 | goto release; | ||
730 | } | ||
731 | |||
732 | /* if they give us an odd I/O address, then do ONE write to | ||
733 | the address port, to get it back to address zero, where we | ||
734 | expect to find the EISA signature word. An IO with a base of 0x3 | ||
735 | will skip the test for the ADD_PORT. */ | ||
736 | if (ioport & 1) { | ||
737 | if (net_debug > 1) | ||
738 | printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", | ||
739 | dev->name, | ||
740 | ioport); | ||
741 | if ((ioport & 2) != 2) | ||
742 | if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) != | ||
743 | ADD_SIG) { | ||
744 | printk(KERN_ERR "%s: bad signature 0x%x\n", | ||
745 | dev->name, | ||
746 | ioread16(io_mem + ADD_PORT)); | ||
747 | ret = -ENODEV; | ||
748 | goto unmap; | ||
749 | } | ||
750 | } | ||
751 | |||
752 | ret = cs89x0_probe1(dev, io_mem, modular); | ||
753 | if (!ret) | ||
754 | goto out; | ||
755 | unmap: | ||
756 | ioport_unmap(io_mem); | ||
757 | release: | ||
758 | release_region(ioport, NETCARD_IO_EXTENT); | ||
759 | out: | ||
760 | return ret; | ||
761 | } | ||
762 | |||
763 | #ifndef MODULE | ||
764 | /* Check for a network adaptor of this type, and return '0' iff one exists. | ||
765 | If dev->base_addr == 0, probe all likely locations. | ||
766 | If dev->base_addr == 1, always return failure. | ||
767 | If dev->base_addr == 2, allocate space for the device and return success | ||
768 | (detachable devices only). | ||
769 | Return 0 on success. | ||
770 | */ | ||
771 | |||
772 | struct net_device * __init cs89x0_probe(int unit) | ||
773 | { | ||
774 | struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); | ||
775 | unsigned *port; | ||
776 | int err = 0; | ||
777 | int irq; | ||
778 | int io; | ||
779 | |||
780 | if (!dev) | ||
781 | return ERR_PTR(-ENODEV); | ||
782 | |||
783 | sprintf(dev->name, "eth%d", unit); | ||
784 | netdev_boot_setup_check(dev); | ||
785 | io = dev->base_addr; | ||
786 | irq = dev->irq; | ||
787 | |||
788 | if (net_debug) | ||
789 | printk(KERN_INFO "cs89x0:cs89x0_probe(0x%x)\n", io); | ||
790 | |||
791 | if (io > 0x1ff) { /* Check a single specified location. */ | ||
792 | err = cs89x0_ioport_probe(dev, io, 0); | ||
793 | } else if (io != 0) { /* Don't probe at all. */ | ||
794 | err = -ENXIO; | ||
795 | } else { | ||
796 | for (port = netcard_portlist; *port; port++) { | ||
797 | if (cs89x0_ioport_probe(dev, *port, 0) == 0) | ||
798 | break; | ||
799 | dev->irq = irq; | ||
800 | } | ||
801 | if (!*port) | ||
802 | err = -ENODEV; | ||
803 | } | ||
804 | if (err) | ||
805 | goto out; | ||
806 | return dev; | ||
807 | out: | ||
808 | free_netdev(dev); | ||
809 | printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n"); | ||
810 | return ERR_PTR(err); | ||
811 | } | ||
812 | #endif | ||
813 | #endif | ||
800 | 814 | ||
801 | /********************************* | 815 | /********************************* |
802 | * This page contains DMA routines | 816 | * This page contains DMA routines |
@@ -956,7 +970,6 @@ static void __init reset_chip(struct net_device *dev) | |||
956 | #if !defined(CONFIG_MACH_MX31ADS) | 970 | #if !defined(CONFIG_MACH_MX31ADS) |
957 | #if !defined(CS89x0_NONISA_IRQ) | 971 | #if !defined(CS89x0_NONISA_IRQ) |
958 | struct net_local *lp = netdev_priv(dev); | 972 | struct net_local *lp = netdev_priv(dev); |
959 | int ioaddr = dev->base_addr; | ||
960 | #endif /* CS89x0_NONISA_IRQ */ | 973 | #endif /* CS89x0_NONISA_IRQ */ |
961 | int reset_start_time; | 974 | int reset_start_time; |
962 | 975 | ||
@@ -968,13 +981,15 @@ static void __init reset_chip(struct net_device *dev) | |||
968 | #if !defined(CS89x0_NONISA_IRQ) | 981 | #if !defined(CS89x0_NONISA_IRQ) |
969 | if (lp->chip_type != CS8900) { | 982 | if (lp->chip_type != CS8900) { |
970 | /* Hardware problem requires PNP registers to be reconfigured after a reset */ | 983 | /* Hardware problem requires PNP registers to be reconfigured after a reset */ |
971 | writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT); | 984 | iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT); |
972 | outb(dev->irq, ioaddr + DATA_PORT); | 985 | iowrite8(dev->irq, lp->virt_addr + DATA_PORT); |
973 | outb(0, ioaddr + DATA_PORT + 1); | 986 | iowrite8(0, lp->virt_addr + DATA_PORT + 1); |
974 | 987 | ||
975 | writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB); | 988 | iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT); |
976 | outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT); | 989 | iowrite8((dev->mem_start >> 16) & 0xff, |
977 | outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1); | 990 | lp->virt_addr + DATA_PORT); |
991 | iowrite8((dev->mem_start >> 8) & 0xff, | ||
992 | lp->virt_addr + DATA_PORT + 1); | ||
978 | } | 993 | } |
979 | #endif /* CS89x0_NONISA_IRQ */ | 994 | #endif /* CS89x0_NONISA_IRQ */ |
980 | 995 | ||
@@ -1092,6 +1107,7 @@ detect_tp(struct net_device *dev) | |||
1092 | static int | 1107 | static int |
1093 | send_test_pkt(struct net_device *dev) | 1108 | send_test_pkt(struct net_device *dev) |
1094 | { | 1109 | { |
1110 | struct net_local *lp = netdev_priv(dev); | ||
1095 | char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, | 1111 | char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, |
1096 | 0, 46, /* A 46 in network order */ | 1112 | 0, 46, /* A 46 in network order */ |
1097 | 0, 0, /* DSAP=0 & SSAP=0 fields */ | 1113 | 0, 0, /* DSAP=0 & SSAP=0 fields */ |
@@ -1103,8 +1119,8 @@ send_test_pkt(struct net_device *dev) | |||
1103 | memcpy(test_packet, dev->dev_addr, ETH_ALEN); | 1119 | memcpy(test_packet, dev->dev_addr, ETH_ALEN); |
1104 | memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN); | 1120 | memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN); |
1105 | 1121 | ||
1106 | writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL); | 1122 | iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT); |
1107 | writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN); | 1123 | iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT); |
1108 | 1124 | ||
1109 | /* Test to see if the chip has allocated memory for the packet */ | 1125 | /* Test to see if the chip has allocated memory for the packet */ |
1110 | while (jiffies - timenow < 5) | 1126 | while (jiffies - timenow < 5) |
@@ -1114,7 +1130,7 @@ send_test_pkt(struct net_device *dev) | |||
1114 | return 0; /* this shouldn't happen */ | 1130 | return 0; /* this shouldn't happen */ |
1115 | 1131 | ||
1116 | /* Write the contents of the packet */ | 1132 | /* Write the contents of the packet */ |
1117 | writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1); | 1133 | writewords(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN+1) >> 1); |
1118 | 1134 | ||
1119 | if (net_debug > 1) printk("Sending test packet "); | 1135 | if (net_debug > 1) printk("Sending test packet "); |
1120 | /* wait a couple of jiffies for packet to be received */ | 1136 | /* wait a couple of jiffies for packet to be received */ |
@@ -1458,8 +1474,8 @@ static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev) | |||
1458 | netif_stop_queue(dev); | 1474 | netif_stop_queue(dev); |
1459 | 1475 | ||
1460 | /* initiate a transmit sequence */ | 1476 | /* initiate a transmit sequence */ |
1461 | writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd); | 1477 | iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT); |
1462 | writeword(dev->base_addr, TX_LEN_PORT, skb->len); | 1478 | iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT); |
1463 | 1479 | ||
1464 | /* Test to see if the chip has allocated memory for the packet */ | 1480 | /* Test to see if the chip has allocated memory for the packet */ |
1465 | if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { | 1481 | if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { |
@@ -1473,7 +1489,7 @@ static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev) | |||
1473 | return NETDEV_TX_BUSY; | 1489 | return NETDEV_TX_BUSY; |
1474 | } | 1490 | } |
1475 | /* Write the contents of the packet */ | 1491 | /* Write the contents of the packet */ |
1476 | writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); | 1492 | writewords(lp, TX_FRAME_PORT, skb->data, (skb->len+1) >> 1); |
1477 | spin_unlock_irqrestore(&lp->lock, flags); | 1493 | spin_unlock_irqrestore(&lp->lock, flags); |
1478 | dev->stats.tx_bytes += skb->len; | 1494 | dev->stats.tx_bytes += skb->len; |
1479 | dev_kfree_skb (skb); | 1495 | dev_kfree_skb (skb); |
@@ -1499,10 +1515,9 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) | |||
1499 | { | 1515 | { |
1500 | struct net_device *dev = dev_id; | 1516 | struct net_device *dev = dev_id; |
1501 | struct net_local *lp; | 1517 | struct net_local *lp; |
1502 | int ioaddr, status; | 1518 | int status; |
1503 | int handled = 0; | 1519 | int handled = 0; |
1504 | 1520 | ||
1505 | ioaddr = dev->base_addr; | ||
1506 | lp = netdev_priv(dev); | 1521 | lp = netdev_priv(dev); |
1507 | 1522 | ||
1508 | /* we MUST read all the events out of the ISQ, otherwise we'll never | 1523 | /* we MUST read all the events out of the ISQ, otherwise we'll never |
@@ -1512,7 +1527,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) | |||
1512 | course, if you're on a slow machine, and packets are arriving | 1527 | course, if you're on a slow machine, and packets are arriving |
1513 | faster than you can read them off, you're screwed. Hasta la | 1528 | faster than you can read them off, you're screwed. Hasta la |
1514 | vista, baby! */ | 1529 | vista, baby! */ |
1515 | while ((status = readword(dev->base_addr, ISQ_PORT))) { | 1530 | while ((status = ioread16(lp->virt_addr + ISQ_PORT))) { |
1516 | if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status); | 1531 | if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status); |
1517 | handled = 1; | 1532 | handled = 1; |
1518 | switch(status & ISQ_EVENT_MASK) { | 1533 | switch(status & ISQ_EVENT_MASK) { |
@@ -1608,12 +1623,12 @@ count_rx_errors(int status, struct net_device *dev) | |||
1608 | static void | 1623 | static void |
1609 | net_rx(struct net_device *dev) | 1624 | net_rx(struct net_device *dev) |
1610 | { | 1625 | { |
1626 | struct net_local *lp = netdev_priv(dev); | ||
1611 | struct sk_buff *skb; | 1627 | struct sk_buff *skb; |
1612 | int status, length; | 1628 | int status, length; |
1613 | 1629 | ||
1614 | int ioaddr = dev->base_addr; | 1630 | status = ioread16(lp->virt_addr + RX_FRAME_PORT); |
1615 | status = readword(ioaddr, RX_FRAME_PORT); | 1631 | length = ioread16(lp->virt_addr + RX_FRAME_PORT); |
1616 | length = readword(ioaddr, RX_FRAME_PORT); | ||
1617 | 1632 | ||
1618 | if ((status & RX_OK) == 0) { | 1633 | if ((status & RX_OK) == 0) { |
1619 | count_rx_errors(status, dev); | 1634 | count_rx_errors(status, dev); |
@@ -1631,9 +1646,9 @@ net_rx(struct net_device *dev) | |||
1631 | } | 1646 | } |
1632 | skb_reserve(skb, 2); /* longword align L3 header */ | 1647 | skb_reserve(skb, 2); /* longword align L3 header */ |
1633 | 1648 | ||
1634 | readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1); | 1649 | readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1); |
1635 | if (length & 1) | 1650 | if (length & 1) |
1636 | skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT); | 1651 | skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT); |
1637 | 1652 | ||
1638 | if (net_debug > 3) { | 1653 | if (net_debug > 3) { |
1639 | printk( "%s: received %d byte packet of type %x\n", | 1654 | printk( "%s: received %d byte packet of type %x\n", |
@@ -1886,7 +1901,7 @@ int __init init_module(void) | |||
1886 | goto out; | 1901 | goto out; |
1887 | } | 1902 | } |
1888 | #endif | 1903 | #endif |
1889 | ret = cs89x0_probe1(dev, io, 1); | 1904 | ret = cs89x0_ioport_probe(dev, io, 1); |
1890 | if (ret) | 1905 | if (ret) |
1891 | goto out; | 1906 | goto out; |
1892 | 1907 | ||
@@ -1900,8 +1915,11 @@ out: | |||
1900 | void __exit | 1915 | void __exit |
1901 | cleanup_module(void) | 1916 | cleanup_module(void) |
1902 | { | 1917 | { |
1918 | struct net_local *lp = netdev_priv(dev_cs89x0); | ||
1919 | |||
1903 | unregister_netdev(dev_cs89x0); | 1920 | unregister_netdev(dev_cs89x0); |
1904 | writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID); | 1921 | iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT); |
1922 | ioport_unmap(lp->virt_addr); | ||
1905 | release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); | 1923 | release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); |
1906 | free_netdev(dev_cs89x0); | 1924 | free_netdev(dev_cs89x0); |
1907 | } | 1925 | } |
@@ -1913,6 +1931,7 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev) | |||
1913 | struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); | 1931 | struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); |
1914 | struct net_local *lp; | 1932 | struct net_local *lp; |
1915 | struct resource *mem_res; | 1933 | struct resource *mem_res; |
1934 | void __iomem *virt_addr; | ||
1916 | int err; | 1935 | int err; |
1917 | 1936 | ||
1918 | if (!dev) | 1937 | if (!dev) |
@@ -1928,22 +1947,21 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev) | |||
1928 | goto free; | 1947 | goto free; |
1929 | } | 1948 | } |
1930 | 1949 | ||
1931 | lp->phys_addr = mem_res->start; | ||
1932 | lp->size = resource_size(mem_res); | 1950 | lp->size = resource_size(mem_res); |
1933 | if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) { | 1951 | if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) { |
1934 | dev_warn(&dev->dev, "request_mem_region() failed.\n"); | 1952 | dev_warn(&dev->dev, "request_mem_region() failed.\n"); |
1935 | err = -EBUSY; | 1953 | err = -EBUSY; |
1936 | goto free; | 1954 | goto free; |
1937 | } | 1955 | } |
1938 | 1956 | ||
1939 | lp->virt_addr = ioremap(lp->phys_addr, lp->size); | 1957 | virt_addr = ioremap(mem_res->start, lp->size); |
1940 | if (!lp->virt_addr) { | 1958 | if (!virt_addr) { |
1941 | dev_warn(&dev->dev, "ioremap() failed.\n"); | 1959 | dev_warn(&dev->dev, "ioremap() failed.\n"); |
1942 | err = -ENOMEM; | 1960 | err = -ENOMEM; |
1943 | goto release; | 1961 | goto release; |
1944 | } | 1962 | } |
1945 | 1963 | ||
1946 | err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0); | 1964 | err = cs89x0_probe1(dev, virt_addr, 0); |
1947 | if (err) { | 1965 | if (err) { |
1948 | dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n"); | 1966 | dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n"); |
1949 | goto unmap; | 1967 | goto unmap; |
@@ -1953,9 +1971,9 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev) | |||
1953 | return 0; | 1971 | return 0; |
1954 | 1972 | ||
1955 | unmap: | 1973 | unmap: |
1956 | iounmap(lp->virt_addr); | 1974 | iounmap(virt_addr); |
1957 | release: | 1975 | release: |
1958 | release_mem_region(lp->phys_addr, lp->size); | 1976 | release_mem_region(mem_res->start, lp->size); |
1959 | free: | 1977 | free: |
1960 | free_netdev(dev); | 1978 | free_netdev(dev); |
1961 | return err; | 1979 | return err; |
@@ -1965,10 +1983,17 @@ static int cs89x0_platform_remove(struct platform_device *pdev) | |||
1965 | { | 1983 | { |
1966 | struct net_device *dev = platform_get_drvdata(pdev); | 1984 | struct net_device *dev = platform_get_drvdata(pdev); |
1967 | struct net_local *lp = netdev_priv(dev); | 1985 | struct net_local *lp = netdev_priv(dev); |
1986 | struct resource *mem_res; | ||
1968 | 1987 | ||
1988 | /* | ||
1989 | * This platform_get_resource() call will not return NULL, because | ||
1990 | * the same call in cs89x0_platform_probe() has returned a non NULL | ||
1991 | * value. | ||
1992 | */ | ||
1993 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1969 | unregister_netdev(dev); | 1994 | unregister_netdev(dev); |
1970 | iounmap(lp->virt_addr); | 1995 | iounmap(lp->virt_addr); |
1971 | release_mem_region(lp->phys_addr, lp->size); | 1996 | release_mem_region(mem_res->start, lp->size); |
1972 | free_netdev(dev); | 1997 | free_netdev(dev); |
1973 | return 0; | 1998 | return 0; |
1974 | } | 1999 | } |