X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2F3c503.c;h=7e34c4f07b70723668d27a4baa2c48d1a1c8a011;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=66644b0eb678efcaf7bf7034696ed1f1570db6e1;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index 66644b0eb..7e34c4f07 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -79,9 +79,9 @@ static void el2_block_input(struct net_device *dev, int count, struct sk_buff *s int ring_offset); static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static struct ethtool_ops netdev_ethtool_ops; +static const struct ethtool_ops netdev_ethtool_ops; + - /* This routine probes for a memory-mapped 3c503 board by looking for the "location register" at the end of the jumpered boot PROM space. This works even if a PROM isn't there. @@ -96,15 +96,22 @@ static int __init do_el2_probe(struct net_device *dev) int irq = dev->irq; SET_MODULE_OWNER(dev); - + if (base_addr > 0x1ff) /* Check a single specified location. */ return el2_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ 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) @@ -120,7 +127,7 @@ static int __init do_el2_probe(struct net_device *dev) /* Try all of the locations that aren't obviously empty. This touches a lot of locations, and is much riskier than the code above. */ -static int __init +static int __init el2_pio_probe(struct net_device *dev) { int i; @@ -141,12 +148,7 @@ 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) { struct net_device *dev = alloc_ei_netdev(); @@ -161,31 +163,27 @@ 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); } +#endif /* Probe for the Etherlink II card at I/O port base IOADDR, returning non-zero on success. If found, set the station address and memory parameters in DEVICE. */ -static int __init +static int __init el2_probe1(struct net_device *dev, int ioaddr) { int i, iobase_reg, membase_reg, saved_406, wordlength, retval; static unsigned version_printed; unsigned long vendor_id; - if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name)) + if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME)) return -EBUSY; - if (!request_region(ioaddr + 0x400, 8, dev->name)) { + if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) { retval = -EBUSY; goto out; } @@ -260,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"; } } @@ -341,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, @@ -361,7 +367,7 @@ out: release_region(ioaddr, EL2_IO_EXTENT); return retval; } - + static int el2_open(struct net_device *dev) { @@ -379,7 +385,7 @@ el2_open(struct net_device *dev) outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); outb_p(0x00, E33G_IDCFR); if (*irqp == probe_irq_off(cookie) /* It's a good IRQ line! */ - && ((retval = request_irq(dev->irq = *irqp, + && ((retval = request_irq(dev->irq = *irqp, ei_interrupt, 0, dev->name, dev)) == 0)) break; } @@ -469,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; } @@ -539,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; } @@ -579,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; } @@ -660,7 +666,7 @@ static void netdev_get_drvinfo(struct net_device *dev, sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); } -static struct ethtool_ops netdev_ethtool_ops = { +static const struct ethtool_ops netdev_ethtool_ops = { .get_drvinfo = netdev_get_drvinfo, }; @@ -671,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)"); @@ -682,7 +688,7 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ -int +int __init init_module(void) { struct net_device *dev; @@ -700,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]); @@ -715,7 +718,15 @@ init_module(void) return -ENXIO; } -void +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 __exit cleanup_module(void) { int this_dev;