X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2F3c503.c;h=dcc98afa65d717c7abe1f7360c0c9a90c75c3ce7;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=c4524decb9e97e4b627a761be865aa75f8da6783;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index c4524decb..dcc98afa6 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -103,8 +103,15 @@ static int __init do_el2_probe(struct net_device *dev) return -ENXIO; for (addr = addrs; *addr; addr++) { - unsigned base_bits = isa_readb(*addr); - int i = ffs(base_bits) - 1; + void __iomem *p = ioremap(*addr, 1); + unsigned base_bits; + int i; + + if (!p) + continue; + base_bits = readb(p); + iounmap(p); + i = ffs(base_bits) - 1; if (i == -1 || base_bits != (1 << i)) continue; if (el2_probe1(dev, netcard_portlist[i]) == 0) @@ -141,12 +148,6 @@ el2_pio_probe(struct net_device *dev) return -ENODEV; } -static void cleanup_card(struct net_device *dev) -{ - /* NB: el2_close() handles free_irq */ - release_region(dev->base_addr, EL2_IO_EXTENT); -} - #ifndef MODULE struct net_device * __init el2_probe(int unit) { @@ -162,12 +163,7 @@ struct net_device * __init el2_probe(int unit) err = do_el2_probe(dev); if (err) goto out; - err = register_netdev(dev); - if (err) - goto out1; return dev; -out1: - cleanup_card(dev); out: free_netdev(dev); return ERR_PTR(err); @@ -262,42 +258,46 @@ el2_probe1(struct net_device *dev, int ioaddr) if ((membase_reg & 0xf0) == 0) { dev->mem_start = 0; ei_status.name = "3c503-PIO"; + ei_status.mem = NULL; } else { dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) + ((membase_reg & 0xA0) ? 0x4000 : 0); - #define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256 + ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE); + #ifdef EL2MEMTEST /* This has never found an error, but someone might care. Note that it only tests the 2nd 8kB on 16kB 3c503/16 cards between card addr. 0x2000 and 0x3fff. */ { /* Check the card's memory. */ - unsigned long mem_base = dev->mem_start; + void __iomem *mem_base = ei_status.mem; unsigned int test_val = 0xbbadf00d; - isa_writel(0xba5eba5e, mem_base); + writel(0xba5eba5e, mem_base); for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) { - isa_writel(test_val, mem_base + i); - if (isa_readl(mem_base) != 0xba5eba5e - || isa_readl(mem_base + i) != test_val) { + writel(test_val, mem_base + i); + if (readl(mem_base) != 0xba5eba5e + || readl(mem_base + i) != test_val) { printk("3c503: memory failure or memory address conflict.\n"); dev->mem_start = 0; ei_status.name = "3c503-PIO"; + iounmap(mem_base); + ei_status.mem = NULL; break; } test_val += 0x55555555; - isa_writel(0, mem_base + i); + writel(0, mem_base + i); } } #endif /* EL2MEMTEST */ if (dev->mem_start) - dev->mem_end = ei_status.rmem_end = dev->mem_start + EL2_MEMSIZE; + dev->mem_end = dev->mem_start + EL2_MEMSIZE; if (wordlength) { /* No Tx pages to skip over to get to Rx */ - ei_status.rmem_start = dev->mem_start; + ei_status.priv = 0; ei_status.name = "3c503/16"; } else { - ei_status.rmem_start = TX_PAGES*256 + dev->mem_start; + ei_status.priv = TX_PAGES * 256; ei_status.name = "3c503"; } } @@ -343,6 +343,10 @@ el2_probe1(struct net_device *dev, int ioaddr) dev->poll_controller = ei_poll; #endif + retval = register_netdev(dev); + if (retval) + goto out1; + if (dev->mem_start) printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", dev->name, ei_status.name, (wordlength+1)<<3, @@ -471,16 +475,16 @@ el2_block_output(struct net_device *dev, int count, unsigned short int *wrd; int boguscount; /* timeout counter */ unsigned short word; /* temporary for better machine code */ + void __iomem *base = ei_status.mem; if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */ outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR); else outb(EGACFR_NORM, E33G_GACFR); - if (dev->mem_start) { /* Shared memory transfer */ - unsigned long dest_addr = dev->mem_start + - ((start_page - ei_status.tx_start_page) << 8); - isa_memcpy_toio(dest_addr, buf, count); + if (base) { /* Shared memory transfer */ + memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8), + buf, count); outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */ return; } @@ -541,11 +545,12 @@ static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int boguscount; - unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8); + void __iomem *base = ei_status.mem; unsigned short word; - if (dev->mem_start) { /* Use the shared memory. */ - isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + if (base) { /* Use the shared memory. */ + void __iomem *hdr_start = base + ((ring_page - EL2_MB1_START_PG)<<8); + memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); hdr->count = le16_to_cpu(hdr->count); return; } @@ -581,23 +586,22 @@ static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int boguscount = 0; + void __iomem *base = ei_status.mem; unsigned short int *buf; unsigned short word; - int end_of_ring = ei_status.rmem_end; - /* Maybe enable shared memory just be to be safe... nahh.*/ - if (dev->mem_start) { /* Use the shared memory. */ + if (base) { /* Use the shared memory. */ ring_offset -= (EL2_MB1_START_PG<<8); - if (dev->mem_start + ring_offset + count > end_of_ring) { + if (ring_offset + count > EL2_MEMSIZE) { /* We must wrap the input move. */ - int semi_count = end_of_ring - (dev->mem_start + ring_offset); - isa_memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count); + int semi_count = EL2_MEMSIZE - ring_offset; + memcpy_fromio(skb->data, base + ring_offset, semi_count); count -= semi_count; - isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count); + memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - isa_eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0); + eth_io_copy_and_sum(skb, base + ring_offset, count, 0); } return; } @@ -673,9 +677,9 @@ static struct net_device *dev_el2[MAX_EL2_CARDS]; static int io[MAX_EL2_CARDS]; static int irq[MAX_EL2_CARDS]; static int xcvr[MAX_EL2_CARDS]; /* choose int. or ext. xcvr */ -MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i"); -MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i"); -MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i"); +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(xcvr, int, NULL, 0); MODULE_PARM_DESC(io, "I/O base address(es)"); MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)"); @@ -702,11 +706,8 @@ init_module(void) dev->base_addr = io[this_dev]; dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */ if (do_el2_probe(dev) == 0) { - if (register_netdev(dev) == 0) { - dev_el2[found++] = dev; - continue; - } - cleanup_card(dev); + dev_el2[found++] = dev; + continue; } free_netdev(dev); printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]); @@ -717,6 +718,14 @@ init_module(void) return -ENXIO; } +static void cleanup_card(struct net_device *dev) +{ + /* NB: el2_close() handles free_irq */ + release_region(dev->base_addr, EL2_IO_EXTENT); + if (ei_status.mem) + iounmap(ei_status.mem); +} + void cleanup_module(void) {