diff options
Diffstat (limited to 'drivers/net/pcmcia')
-rw-r--r-- | drivers/net/pcmcia/3c574_cs.c | 148 | ||||
-rw-r--r-- | drivers/net/pcmcia/3c575_cb.c | 108 | ||||
-rw-r--r-- | drivers/net/pcmcia/3c589_cs.c | 137 | ||||
-rw-r--r-- | drivers/net/pcmcia/Config.in | 4 | ||||
-rw-r--r-- | drivers/net/pcmcia/fmvj18x_cs.c | 152 | ||||
-rw-r--r-- | drivers/net/pcmcia/netwave_cs.c | 88 | ||||
-rw-r--r-- | drivers/net/pcmcia/nmclan_cs.c | 417 | ||||
-rw-r--r-- | drivers/net/pcmcia/pcnet_cs.c | 77 | ||||
-rw-r--r-- | drivers/net/pcmcia/smc91c92_cs.c | 372 | ||||
-rw-r--r-- | drivers/net/pcmcia/tulip_cb.c | 323 | ||||
-rw-r--r-- | drivers/net/pcmcia/wavelan_cs.c | 6 | ||||
-rw-r--r-- | drivers/net/pcmcia/xirc2ps_cs.c | 193 |
12 files changed, 837 insertions, 1188 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 0e9110a8b..4e4fc4157 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -119,7 +119,7 @@ static int irq_list[4] = { -1 }; #define TX_TIMEOUT ((800*HZ)/1000) /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static int max_interrupt_work = 64; +static int max_interrupt_work = 32; /* Force full duplex modes? */ static int full_duplex = 0; @@ -207,6 +207,8 @@ enum Window4 { /* Window 4: Xcvr/media bits. */ #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ struct el3_private { + dev_link_t link; + struct net_device dev; dev_node_t node; struct net_device_stats stats; u16 advertising, partner; /* NWay media advertisement */ @@ -253,13 +255,11 @@ static void media_check(u_long arg); static int el3_open(struct net_device *dev); static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void update_stats(ioaddr_t addr, struct net_device *dev); +static void update_stats(struct net_device *dev); static struct net_device_stats *el3_get_stats(struct net_device *dev); static int el3_rx(struct net_device *dev, int worklimit); static int el3_close(struct net_device *dev); -#ifdef HAVE_PRIVATE_IOCTL -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -#endif +static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void set_rx_mode(struct net_device *dev); static dev_info_t dev_info = "3c574_cs"; @@ -307,6 +307,7 @@ static int tc574_init(struct net_device *dev) static dev_link_t *tc574_attach(void) { + struct el3_private *lp; client_reg_t client_reg; dev_link_t *link; struct net_device *dev; @@ -316,8 +317,12 @@ static dev_link_t *tc574_attach(void) flush_stale_links(); /* Create the PC card device object. */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + lp = kmalloc(sizeof(*lp), GFP_KERNEL); + if (!lp) return NULL; + memset(lp, 0, sizeof(*lp)); + link = &lp->link; dev = &lp->dev; + link->priv = dev->priv = link->irq.Instance = lp; + link->release.function = &tc574_release; link->release.data = (u_long)link; link->io.NumPorts1 = 32; @@ -336,33 +341,18 @@ static dev_link_t *tc574_attach(void) link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - /* Create the network device object. */ - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - - /* Make up a Odie-specific data structure. */ - dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL); - memset(dev->priv, 0, sizeof(struct el3_private)); - /* The EL3-specific entries in the device structure. */ dev->hard_start_xmit = &el3_start_xmit; dev->get_stats = &el3_get_stats; -#ifdef HAVE_PRIVATE_IOCTL - dev->do_ioctl = &private_ioctl; -#endif + dev->do_ioctl = &el3_ioctl; dev->set_multicast_list = &set_rx_mode; ether_setup(dev); - dev->name = ((struct el3_private *)dev->priv)->node.dev_name; + dev->name = lp->node.dev_name; dev->init = &tc574_init; dev->open = &el3_open; dev->stop = &el3_close; dev->tbusy = 1; - link->priv = dev; -#if CS_RELEASE_CODE > 0x2911 - link->irq.Instance = dev; -#endif - /* Register with Card Services */ link->next = dev_list; dev_list = link; @@ -396,6 +386,7 @@ static dev_link_t *tc574_attach(void) static void tc574_detach(dev_link_t *link) { + struct el3_private *lp = link->priv; dev_link_t **linkp; long flags; @@ -428,15 +419,9 @@ static void tc574_detach(dev_link_t *link) /* Unlink device structure, free bits */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree(dev->priv); - kfree(link->priv); - } - kfree(link); + if (link->dev) + unregister_netdev(&lp->dev); + kfree(lp); } /* tc574_detach */ @@ -451,9 +436,9 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed static void tc574_config(dev_link_t *link) { - client_handle_t handle; - struct net_device *dev; - struct el3_private *lp; + client_handle_t handle = link->handle; + struct el3_private *lp = link->priv; + struct net_device *dev = &lp->dev; tuple_t tuple; cisparse_t parse; u_short buf[32]; @@ -462,8 +447,6 @@ static void tc574_config(dev_link_t *link) u16 *phys_addr; char *cardname; - handle = link->handle; - dev = link->priv; phys_addr = (u16 *)dev->dev_addr; DEBUG(0, "3c574_config(0x%p)\n", link); @@ -528,7 +511,6 @@ static void tc574_config(dev_link_t *link) link->state &= ~DEV_CONFIG_PENDING; ioaddr = dev->base_addr; - lp = (struct el3_private *)dev->priv; link->dev = &lp->node; /* The 3c574 normally uses an EEPROM for configuration info, including @@ -641,7 +623,8 @@ failed: static void tc574_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; - struct net_device *dev = link->priv; + struct el3_private *lp = link->priv; + struct net_device *dev = &lp->dev; DEBUG(0, "3c574_release(0x%p)\n", link); @@ -675,7 +658,8 @@ static int tc574_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; + struct el3_private *lp = link->priv; + struct net_device *dev = &lp->dev; DEBUG(1, "3c574_event(0x%06x)\n", event); @@ -922,10 +906,8 @@ static void tc574_reset(struct net_device *dev) static int el3_open(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; - dev_link_t *link; + dev_link_t *link = &lp->link; - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (!DEV_OK(link)) return -ENODEV; @@ -935,14 +917,14 @@ static int el3_open(struct net_device *dev) tc574_reset(dev); lp->media.function = &media_check; - lp->media.data = (u_long)dev; + lp->media.data = (u_long)lp; lp->media.expires = jiffies + HZ; add_timer(&lp->media); DEBUG(2, "%s: opened, status %4.4x.\n", dev->name, inw(dev->base_addr + EL3_STATUS)); - return 0; /* Always succeed */ + return 0; } static void el3_tx_timeout(struct net_device *dev) @@ -1054,14 +1036,13 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The EL3 interrupt handler. */ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = (struct net_device *)dev_id; - struct el3_private *lp; + struct el3_private *lp = dev_id; + struct net_device *dev = &lp->dev; ioaddr_t ioaddr, status; int work_budget = max_interrupt_work; - if ((dev == NULL) || !dev->start) + if ((lp == NULL) || !dev->start) return; - lp = (struct el3_private *)dev->priv; ioaddr = dev->base_addr; #ifdef PCMCIA_DEBUG @@ -1098,7 +1079,7 @@ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status & (AdapterFailure | RxEarly | StatsFull)) { /* Handle all uncommon interrupts. */ if (status & StatsFull) - update_stats(ioaddr, dev); + update_stats(dev); if (status & RxEarly) { work_budget = el3_rx(dev, work_budget); outw(AckIntr | RxEarly, ioaddr + EL3_CMD); @@ -1151,8 +1132,8 @@ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ static void media_check(u_long arg) { - struct net_device *dev = (struct net_device *)(arg); - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = (struct el3_private *)arg; + struct net_device *dev = &lp->dev; ioaddr_t ioaddr = dev->base_addr; u_long flags; u_short /* cable, */ media, partner; @@ -1165,7 +1146,7 @@ static void media_check(u_long arg) (inb(ioaddr + Timer) == 0xff)) { if (!lp->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - el3_interrupt(dev->irq, dev, NULL); + el3_interrupt(dev->irq, lp, NULL); lp->fast_poll = HZ; } if (lp->fast_poll) { @@ -1228,7 +1209,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) struct el3_private *lp = (struct el3_private *)dev->priv; if (dev->start) - update_stats(dev->base_addr, dev); + update_stats(dev); return &lp->stats; } @@ -1236,9 +1217,10 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) Suprisingly this need not be run single-threaded, but it effectively is. The counters clear when read, so the adds must merely be atomic. */ -static void update_stats(ioaddr_t ioaddr, struct net_device *dev) +static void update_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; + ioaddr_t ioaddr = dev->base_addr; u8 upper_cnt; DEBUG(2, "%s: updating the statistics.\n", dev->name); @@ -1252,16 +1234,16 @@ static void update_stats(ioaddr_t ioaddr, struct net_device *dev) lp->stats.tx_carrier_errors += inb(ioaddr + 0); lp->stats.tx_heartbeat_errors += inb(ioaddr + 1); /* Multiple collisions. */ inb(ioaddr + 2); - lp->stats.collisions += inb(ioaddr + 3); - lp->stats.tx_window_errors += inb(ioaddr + 4); - lp->stats.rx_fifo_errors += inb(ioaddr + 5); - lp->stats.tx_packets += inb(ioaddr + 6); - upper_cnt = inb(ioaddr + 9); - lp->stats.tx_packets += (upper_cnt&0x30) << 4; - /* Rx packets */ inb(ioaddr + 7); - /* Tx deferrals */ inb(ioaddr + 8); - lp->stats.rx_bytes += inw(ioaddr + 10); - lp->stats.tx_bytes += inw(ioaddr + 12); + lp->stats.collisions += inb(ioaddr + 3); + lp->stats.tx_window_errors += inb(ioaddr + 4); + lp->stats.rx_fifo_errors += inb(ioaddr + 5); + lp->stats.tx_packets += inb(ioaddr + 6); + upper_cnt = inb(ioaddr + 9); + lp->stats.tx_packets += (upper_cnt&0x30) << 4; + /* Rx packets */ inb(ioaddr + 7); + /* Tx deferrals */ inb(ioaddr + 8); + lp->stats.rx_bytes += inw(ioaddr + 10); + lp->stats.tx_bytes += inw(ioaddr + 12); /* With Vortex and later we must also clear the BadSSD counter. */ EL3WINDOW(4); @@ -1284,12 +1266,12 @@ static int el3_rx(struct net_device *dev, int worklimit) short error = rx_status & 0x3800; lp->stats.rx_errors++; switch (error) { - case 0x0000: lp->stats.rx_over_errors++; break; - case 0x0800: lp->stats.rx_length_errors++; break; - case 0x1000: lp->stats.rx_frame_errors++; break; - case 0x1800: lp->stats.rx_length_errors++; break; - case 0x2000: lp->stats.rx_frame_errors++; break; - case 0x2800: lp->stats.rx_crc_errors++; break; + case 0x0000: lp->stats.rx_over_errors++; break; + case 0x0800: lp->stats.rx_length_errors++; break; + case 0x1000: lp->stats.rx_frame_errors++; break; + case 0x1800: lp->stats.rx_length_errors++; break; + case 0x2000: lp->stats.rx_frame_errors++; break; + case 0x2800: lp->stats.rx_crc_errors++; break; } } else { short pkt_len = rx_status & 0x7ff; @@ -1343,14 +1325,13 @@ static int el3_rx(struct net_device *dev, int worklimit) return worklimit; } -#ifdef HAVE_PRIVATE_IOCTL /* Provide ioctl() calls to examine the MII xcvr state. */ -static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct el3_private *vp = (struct el3_private *)dev->priv; + struct el3_private *lp = (struct el3_private *)dev->priv; ioaddr_t ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; - int phy = vp->phys[0] & 0x1f; + int phy = lp->phys[0] & 0x1f; DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n", dev->name, rq->ifr_ifrn.ifrn_name, cmd, @@ -1378,7 +1359,7 @@ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int saved_window; long flags; - if (!suser()) + if (!capable(CAP_NET_ADMIN)) return -EPERM; save_flags(flags); cli(); @@ -1393,7 +1374,6 @@ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return -EOPNOTSUPP; } } -#endif /* HAVE_PRIVATE_IOCTL */ /* The Odie chip has a 64 bin multicast filter, but the bit layout is not documented. Until it is we revert to receiving all multicast frames when @@ -1419,12 +1399,8 @@ static void set_rx_mode(struct net_device *dev) static int el3_close(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; - - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; + struct el3_private *lp = dev->priv; + dev_link_t *link = &lp->link; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); @@ -1439,12 +1415,12 @@ static int el3_close(struct net_device *dev) /* Note: Switching to window 0 may disable the IRQ. */ EL3WINDOW(0); - update_stats(ioaddr, dev); + update_stats(dev); } link->open--; dev->start = 0; - del_timer(&((struct el3_private *)dev->priv)->media); + del_timer(&lp->media); if (link->state & DEV_STALE_CONFIG) { link->release.expires = jiffies + HZ/20; link->state |= DEV_RELEASE_PENDING; diff --git a/drivers/net/pcmcia/3c575_cb.c b/drivers/net/pcmcia/3c575_cb.c index d5b3e95a0..82f534f0c 100644 --- a/drivers/net/pcmcia/3c575_cb.c +++ b/drivers/net/pcmcia/3c575_cb.c @@ -24,7 +24,7 @@ static const int rx_copybreak = 200; /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */ static const int mtu = 1500; /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ -static int max_interrupt_work = 20; +static int max_interrupt_work = 32; /* Put out somewhat more debugging messages. (0: no msg, 1 minimal .. 6). */ #define vortex_debug debug @@ -40,7 +40,7 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits; /* A few values that may be tweaked. */ /* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT (2*HZ) +#define TX_TIMEOUT ((400*HZ)/1000) /* Keep the ring sizes a power of two for efficiency. */ #define TX_RING_SIZE 16 @@ -442,13 +442,15 @@ struct vortex_private { full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ hw_csums:1, /* Has hardware checksums. */ tx_full:1, - open:1; + open:1, + reap:1; u16 status_enable; u16 intr_enable; u16 available_media; /* From Wn3_Options. */ u16 capabilities, info1, info2; /* Various, from EEPROM. */ u16 advertising; /* NWay media advertisement */ unsigned char phys[2]; /* MII device addresses. */ + u16 deferred; }; /* The action to take with a media selection timer tick. @@ -520,6 +522,22 @@ static int compaq_ioaddr = 0, compaq_irq = 0, compaq_device_id = 0x5900; #include <pcmcia/driver_ops.h> +static void vortex_reap(void) +{ + struct net_device **devp, **next; + printk(KERN_DEBUG "vortex_reap()\n"); + for (devp = &root_vortex_dev; *devp; devp = next) { + struct vortex_private *vp = (*devp)->priv; + next = &vp->next_module; + if (vp->open || !vp->reap) continue; + unregister_netdev(*devp); + if (vp->cb_fn_base) iounmap(vp->cb_fn_base); + kfree(*devp); + kfree(vp->priv_addr); + *devp = *next; next = devp; + } +} + static dev_node_t *vortex_attach(dev_locator_t *loc) { u16 dev_id, vendor_id; @@ -528,6 +546,7 @@ static dev_node_t *vortex_attach(dev_locator_t *loc) struct net_device *dev; int chip_idx; + vortex_reap(); if (loc->bus != LOC_PCI) return NULL; bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io); @@ -567,23 +586,16 @@ static dev_node_t *vortex_attach(dev_locator_t *loc) static void vortex_detach(dev_node_t *node) { - struct net_device **devp, **next; - printk(KERN_INFO "vortex_detach(%s)\n", node->dev_name); - for (devp = &root_vortex_dev; *devp; devp = next) { - next = &((struct vortex_private *)(*devp)->priv)->next_module; - if (strcmp((*devp)->name, node->dev_name) == 0) break; + struct net_device *dev, *next; + printk(KERN_DEBUG "vortex_detach(%s)\n", node->dev_name); + for (dev = root_vortex_dev; dev; dev = next) { + next = ((struct vortex_private *)dev->priv)->next_module; + if (strcmp(dev->name, node->dev_name) == 0) break; } - if (*devp) { - struct net_device *dev = *devp; + if (dev && dev->priv) { struct vortex_private *vp = dev->priv; - if (dev->flags & IFF_UP) - vortex_close(dev); - dev->flags &= ~(IFF_UP|IFF_RUNNING); - unregister_netdev(dev); - if (vp->cb_fn_base) iounmap(vp->cb_fn_base); - kfree(dev); - *devp = *next; - kfree(vp->priv_addr); + if (vp->open) vortex_down(dev); + vp->reap = 1; kfree(node); MOD_DEC_USE_COUNT; } @@ -592,7 +604,7 @@ static void vortex_detach(dev_node_t *node) static void vortex_suspend(dev_node_t *node) { struct net_device *dev, *next; - printk(KERN_INFO "vortex_suspend(%s)\n", node->dev_name); + printk(KERN_DEBUG "vortex_suspend(%s)\n", node->dev_name); for (dev = root_vortex_dev; dev; dev = next) { next = ((struct vortex_private *)dev->priv)->next_module; if (strcmp(dev->name, node->dev_name) == 0) break; @@ -606,7 +618,7 @@ static void vortex_suspend(dev_node_t *node) static void vortex_resume(dev_node_t *node) { struct net_device *dev, *next; - printk(KERN_INFO "vortex_resume(%s)\n", node->dev_name); + printk(KERN_DEBUG "vortex_resume(%s)\n", node->dev_name); for (dev = root_vortex_dev; dev; dev = next) { next = ((struct vortex_private *)dev->priv)->next_module; if (strcmp(dev->name, node->dev_name) == 0) break; @@ -797,9 +809,9 @@ static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, { void *mem = kmalloc(sizeof(*vp) + 15, GFP_KERNEL); vp = (void *)(((long)mem + 15) & ~15); + memset(vp, 0, sizeof(*vp)); vp->priv_addr = mem; } - memset(vp, 0, sizeof(*vp)); dev->priv = vp; vp->next_module = root_vortex_dev; @@ -1133,7 +1145,9 @@ vortex_up(struct net_device *dev) dev->hard_start_xmit = &boomerang_start_xmit; vp->cur_tx = vp->dirty_tx = 0; outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */ - /* Clear the Tx ring. */ + /* Clear the Rx, Tx rings. */ + for (i = 0; i < RX_RING_SIZE; i++) + vp->rx_ring[i].status = 0; for (i = 0; i < TX_RING_SIZE; i++) vp->tx_skbuff[i] = 0; outl(0, ioaddr + DownListPtr); @@ -1172,6 +1186,10 @@ vortex_open(struct net_device *dev) struct vortex_private *vp = (struct vortex_private *)dev->priv; int i; +#ifdef CARDBUS + if (vp->reap) + return -ENODEV; +#endif /* Use the now-standard shared IRQ implementation. */ if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ, dev->name, dev)) { return -EAGAIN; @@ -1306,6 +1324,8 @@ static void vortex_timer(unsigned long data) vp->timer.expires = RUN_AT(next_tick); add_timer(&vp->timer); + if (vp->deferred) + outw(FakeIntr, ioaddr + EL3_CMD); return; } @@ -1431,10 +1451,10 @@ vortex_error(struct net_device *dev, int status) dev->name, fifo_diag); /* Adapter failure requires Tx/Rx reset and reinit. */ if (vp->full_bus_master_tx) { + /* In this case, blow the card away */ + vortex_down(dev); wait_for_completion(dev, TotalReset | 0xff); - /* Re-enable the receiver. */ - outw(RxEnable, ioaddr + EL3_CMD); - outw(TxEnable, ioaddr + EL3_CMD); + vortex_up(dev); } else if (fifo_diag & 0x0400) do_tx_reset = 1; if (fifo_diag & 0x3000) { @@ -1597,6 +1617,10 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) ioaddr = dev->base_addr; latency = inb(ioaddr + Timer); status = inw(ioaddr + EL3_STATUS); + if (status & IntReq) { + status |= vp->deferred; + vp->deferred = 0; + } if (status == 0xffff) goto handler_exit; @@ -1665,19 +1689,20 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (--work_done < 0) { - if ((status & (0x7fe - (UpComplete | DownComplete))) == 0) { - /* Just ack these and return. */ - outw(AckIntr | UpComplete | DownComplete, ioaddr + EL3_CMD); - } else { - printk(KERN_WARNING "%s: Too much work in interrupt, status " - "%4.4x. Temporarily disabling functions (%4.4x).\n", - dev->name, status, SetStatusEnb | ((~status) & 0x7FE)); - /* Disable all pending interrupts. */ - outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD); - outw(AckIntr | 0x7FF, ioaddr + EL3_CMD); - /* The timer will reenable interrupts. */ - break; - } + printk(KERN_WARNING "%s: Too much work in interrupt, status " + "%4.4x.\n", dev->name, status); + /* Disable all pending interrupts. */ + do { + vp->deferred |= status; + outw(SetStatusEnb | (~vp->deferred & vp->status_enable), + ioaddr + EL3_CMD); + outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD); + } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch); + /* The timer will reenable interrupts. */ + del_timer(&vp->timer); + vp->timer.expires = RUN_AT(1); + add_timer(&vp->timer); + break; } /* Acknowledge the IRQ. */ outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); @@ -1758,12 +1783,8 @@ static int vortex_rx(struct net_device *dev) printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of " "size %d.\n", dev->name, pkt_len); } - outw(RxDiscard, ioaddr + EL3_CMD); vp->stats.rx_dropped++; - /* Wait a limited time to skip this packet. */ - for (i = 200; i >= 0; i--) - if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) - break; + wait_for_completion(dev, RxDiscard); } return 0; @@ -2185,6 +2206,7 @@ void cleanup_module(void) #ifdef CARDBUS unregister_driver(&vortex_ops); + vortex_reap(); #endif /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 40e5a643f..e95b87104 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -4,7 +4,7 @@ Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org - 3c589_cs.c 1.137 1999/11/08 20:46:17 + 3c589_cs.c 1.143 1999/12/30 21:28:10 The network driver code is based on Donald Becker's 3c589 code: @@ -99,13 +99,15 @@ enum RxFilter { #define TX_TIMEOUT ((400*HZ)/1000) struct el3_private { - dev_node_t node; + dev_link_t link; + struct net_device dev; + dev_node_t node; struct net_device_stats stats; /* For transceiver monitoring */ - struct timer_list media; - u_short media_status; - u_short fast_poll; - u_long last_irq; + struct timer_list media; + u_short media_status; + u_short fast_poll; + u_long last_irq; }; static char *if_names[] = { "auto", "10baseT", "10base2", "AUI" }; @@ -115,7 +117,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"3c589_cs.c 1.137 1999/11/08 20:46:17 (David Hinds)"; +"3c589_cs.c 1.143 1999/12/30 21:28:10 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -149,7 +151,7 @@ static int el3_config(struct net_device *dev, struct ifmap *map); static int el3_open(struct net_device *dev); static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void update_stats(ioaddr_t addr, struct net_device *dev); +static void update_stats(struct net_device *dev); static struct net_device_stats *el3_get_stats(struct net_device *dev); static int el3_rx(struct net_device *dev); static int el3_close(struct net_device *dev); @@ -211,6 +213,7 @@ static int tc589_init(struct net_device *dev) static dev_link_t *tc589_attach(void) { + struct el3_private *lp; client_reg_t client_reg; dev_link_t *link; struct net_device *dev; @@ -220,8 +223,12 @@ static dev_link_t *tc589_attach(void) flush_stale_links(); /* Create new ethernet device */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + lp = kmalloc(sizeof(*lp), GFP_KERNEL); + if (!lp) return NULL; + memset(lp, 0, sizeof(*lp)); + link = &lp->link; dev = &lp->dev; + link->priv = dev->priv = link->irq.Instance = lp; + link->release.function = &tc589_release; link->release.data = (u_long)link; link->io.NumPorts1 = 16; @@ -240,25 +247,17 @@ static dev_link_t *tc589_attach(void) link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - - /* Make up a EL3-specific-data structure. */ - dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL); - memset(dev->priv, 0, sizeof(struct el3_private)); - /* The EL3-specific entries in the device structure. */ dev->hard_start_xmit = &el3_start_xmit; dev->set_config = &el3_config; dev->get_stats = &el3_get_stats; dev->set_multicast_list = &set_multicast_list; ether_setup(dev); - dev->name = ((struct el3_private *)dev->priv)->node.dev_name; + dev->name = lp->node.dev_name; dev->init = &tc589_init; dev->open = &el3_open; dev->stop = &el3_close; dev->tbusy = 1; - link->priv = link->irq.Instance = dev; /* Register with Card Services */ link->next = dev_list; @@ -293,6 +292,7 @@ static dev_link_t *tc589_attach(void) static void tc589_detach(dev_link_t *link) { + struct el3_private *lp = link->priv; dev_link_t **linkp; long flags; @@ -325,15 +325,9 @@ static void tc589_detach(dev_link_t *link) /* Unlink device structure, free bits */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree(dev->priv); - kfree(link->priv); - } - kfree(link); + if (link->dev) + unregister_netdev(&lp->dev); + kfree(lp); } /* tc589_detach */ @@ -350,8 +344,9 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed static void tc589_config(dev_link_t *link) { - client_handle_t handle; - struct net_device *dev; + client_handle_t handle = link->handle; + struct el3_private *lp = link->priv; + struct net_device *dev = &lp->dev; tuple_t tuple; cisparse_t parse; u_short buf[32], *phys_addr; @@ -359,12 +354,9 @@ static void tc589_config(dev_link_t *link) ioaddr_t ioaddr; char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; - handle = link->handle; - dev = link->priv; - phys_addr = (u_short *)dev->dev_addr; - DEBUG(0, "3c589_config(0x%p)\n", link); + phys_addr = (u_short *)dev->dev_addr; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; CS_CHECK(GetFirstTuple, handle, &tuple); @@ -434,7 +426,7 @@ static void tc589_config(dev_link_t *link) } } - link->dev = &((struct el3_private *)dev->priv)->node; + link->dev = &lp->node; /* The address and resource configuration register aren't loaded from the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version. */ @@ -507,7 +499,8 @@ static int tc589_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; + struct el3_private *lp = link->priv; + struct net_device *dev = &lp->dev; DEBUG(1, "3c589_event(0x%06x)\n", event); @@ -683,10 +676,8 @@ static int el3_config(struct net_device *dev, struct ifmap *map) static int el3_open(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; - dev_link_t *link; + dev_link_t *link = &lp->link; - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (!DEV_OK(link)) return -ENODEV; @@ -696,14 +687,14 @@ static int el3_open(struct net_device *dev) tc589_reset(dev); lp->media.function = &media_check; - lp->media.data = (u_long)dev; + lp->media.data = (u_long)lp; lp->media.expires = jiffies + HZ; add_timer(&lp->media); DEBUG(1, "%s: opened, status %4.4x.\n", dev->name, inw(dev->base_addr + EL3_STATUS)); - return 0; /* Always succeed */ + return 0; } static void el3_tx_timeout(struct net_device *dev) @@ -746,7 +737,6 @@ static void pop_tx_status(struct net_device *dev) static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct el3_private *lp = (struct el3_private *)dev->priv; ioaddr_t ioaddr = dev->base_addr; /* Transmitter timeout, serious problems. */ @@ -765,6 +755,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_NOTICE "%s: transmitter access conflict.\n", dev->name); else { + struct el3_private *lp = (struct el3_private *)dev->priv; lp->stats.tx_bytes += skb->len; /* Put out the doubleword header... */ outw(skb->len, ioaddr + TX_FIFO); @@ -789,14 +780,13 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The EL3 interrupt handler. */ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = (struct net_device *)dev_id; - struct el3_private *lp; + struct el3_private *lp = dev_id; + struct net_device *dev = &lp->dev; ioaddr_t ioaddr, status; int i = 0; - if ((dev == NULL) || !dev->start) + if ((lp == NULL) || !dev->start) return; - lp = (struct el3_private *)dev->priv; ioaddr = dev->base_addr; #ifdef PCMCIA_DEBUG @@ -834,7 +824,7 @@ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status & (AdapterFailure | RxEarly | StatsFull)) { /* Handle all uncommon interrupts. */ if (status & StatsFull) /* Empty statistics. */ - update_stats(ioaddr, dev); + update_stats(dev); if (status & RxEarly) { /* Rx early is unused. */ el3_rx(dev); outw(AckIntr | RxEarly, ioaddr + EL3_CMD); @@ -883,14 +873,14 @@ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) static void media_check(u_long arg) { - struct net_device *dev = (struct net_device *)(arg); - struct el3_private *lp = (struct el3_private *)dev->priv; + struct el3_private *lp = (struct el3_private *)(arg); + struct net_device *dev = &lp->dev; ioaddr_t ioaddr = dev->base_addr; u_short media, errs; u_long flags; if (dev->start == 0) goto reschedule; - + EL3WINDOW(1); /* Check for pending interrupt with expired latency timer: with this, we can limp along even if the interrupt is blocked */ @@ -898,7 +888,7 @@ static void media_check(u_long arg) (inb(ioaddr + EL3_TIMER) == 0xff)) { if (!lp->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - el3_interrupt(dev->irq, dev, NULL); + el3_interrupt(dev->irq, lp, NULL); lp->fast_poll = HZ; } if (lp->fast_poll) { @@ -965,14 +955,12 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; unsigned long flags; - dev_link_t *link; + dev_link_t *link = &lp->link; - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (DEV_OK(link)) { save_flags(flags); cli(); - update_stats(dev->base_addr, dev); + update_stats(dev); restore_flags(flags); } return &lp->stats; @@ -984,10 +972,11 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev) operation, and it's simpler for the rest of the driver to assume that window 1 is always valid rather than use a special window-state variable. */ -static void update_stats(ioaddr_t ioaddr, struct net_device *dev) +static void update_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; - + ioaddr_t ioaddr = dev->base_addr; + DEBUG(2, "%s: updating the statistics.\n", dev->name); /* Turn off statistics updates while reading. */ outw(StatsDisable, ioaddr + EL3_CMD); @@ -1002,8 +991,8 @@ static void update_stats(ioaddr_t ioaddr, struct net_device *dev) lp->stats.tx_packets += inb(ioaddr + 6); /* Rx packets */ inb(ioaddr + 7); /* Tx deferrals */ inb(ioaddr + 8); - inw(ioaddr + 10); /* Total Rx and Tx octets. */ - inw(ioaddr + 12); + /* Rx octets */ inw(ioaddr + 10); + /* Tx octets */ inw(ioaddr + 12); /* Back to window 1, and turn statistics back on. */ EL3WINDOW(1); @@ -1025,12 +1014,12 @@ static int el3_rx(struct net_device *dev) short error = rx_status & 0x3800; lp->stats.rx_errors++; switch (error) { - case 0x0000: lp->stats.rx_over_errors++; break; - case 0x0800: lp->stats.rx_length_errors++; break; - case 0x1000: lp->stats.rx_frame_errors++; break; - case 0x1800: lp->stats.rx_length_errors++; break; - case 0x2000: lp->stats.rx_frame_errors++; break; - case 0x2800: lp->stats.rx_crc_errors++; break; + case 0x0000: lp->stats.rx_over_errors++; break; + case 0x0800: lp->stats.rx_length_errors++; break; + case 0x1000: lp->stats.rx_frame_errors++; break; + case 0x1800: lp->stats.rx_length_errors++; break; + case 0x2000: lp->stats.rx_frame_errors++; break; + case 0x2800: lp->stats.rx_crc_errors++; break; } } else { short pkt_len = rx_status & 0x7ff; @@ -1073,10 +1062,10 @@ static int el3_rx(struct net_device *dev) */ static void set_multicast_list(struct net_device *dev) { + struct el3_private *lp = dev->priv; + dev_link_t *link = &lp->link; ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; + if (!(DEV_OK(link))) return; #ifdef PCMCIA_DEBUG if (pc_debug > 2) { @@ -1099,13 +1088,9 @@ static void set_multicast_list(struct net_device *dev) static int el3_close(struct net_device *dev) { + struct el3_private *lp = dev->priv; + dev_link_t *link = &lp->link; ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; - - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; DEBUG(1, "%s: shutting down ethercard.\n", dev->name); @@ -1133,12 +1118,12 @@ static int el3_close(struct net_device *dev) /* Check if the card still exists */ if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000) - update_stats(ioaddr, dev); + update_stats(dev); } link->open--; dev->start = 0; - del_timer(&((struct el3_private *)dev->priv)->media); + del_timer(&lp->media); if (link->state & DEV_STALE_CONFIG) { link->release.expires = jiffies + HZ/20; link->state |= DEV_RELEASE_PENDING; diff --git a/drivers/net/pcmcia/Config.in b/drivers/net/pcmcia/Config.in index 243b5c896..be83dc205 100644 --- a/drivers/net/pcmcia/Config.in +++ b/drivers/net/pcmcia/Config.in @@ -31,6 +31,8 @@ if [ "$CONFIG_NET_PCMCIA" = "y" ]; then fi fi +endmenu + if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \ "$CONFIG_PCMCIA_FMVJ18X" = "y" -o "$CONFIG_PCMCIA_PCNET" = "y" -o \ "$CONFIG_PCMCIA_NMCLAN" = "y" -o "$CONFIG_PCMCIA_SMC91C92" = "y" -o \ @@ -38,5 +40,3 @@ if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \ "$CONFIG_PCMCIA_NETWAVE" = "y" -o "$CONFIG_PCMCIA_WAVELAN" = "y" ]; then define_bool CONFIG_PCMCIA_NETCARD y fi - -endmenu diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 82e3ce57a..9dd2c188e 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -69,16 +69,6 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) #endif -/* - For debugging this driver you may need more information. - To enable printing registers or status, set 'fmvj18x_debug=#' option . - */ -#ifdef FMVJ18X_DEBUG -static int fmvj18x_debug = FMVJ18X_DEBUG; -#else -static int fmvj18x_debug = 2; -#endif /* FMVJ18X_DEBUG */ - /* Bit map of interrupts to choose from */ /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ static u_int irq_mask = 0xdeb8; @@ -138,6 +128,8 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501 } cardtype_t; driver specific data structure */ typedef struct local_info_t { + dev_link_t link; + struct net_device dev; dev_node_t node; struct net_device_stats stats; long open_time; @@ -273,17 +265,21 @@ static void cs_error(client_handle_t handle, int func, int ret) static dev_link_t *fmvj18x_attach(void) { - client_reg_t client_reg; + local_info_t *lp; dev_link_t *link; struct net_device *dev; + client_reg_t client_reg; int i, ret; DEBUG(0, "fmvj18x_attach()\n"); flush_stale_links(); - /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + /* Make up a FMVJ18x specific data structure */ + lp = kmalloc(sizeof(*lp), GFP_KERNEL); + if (!lp) return NULL; + memset(lp, 0, sizeof(*lp)); + link = &lp->link; dev = &lp->dev; + link->priv = dev->priv = link->irq.Instance = lp; link->release.function = &fmvj18x_release; link->release.data = (u_long)link; @@ -308,24 +304,17 @@ static dev_link_t *fmvj18x_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Make up a FMVJ18x specific data structure */ - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - dev->priv = kmalloc(sizeof(local_info_t), GFP_KERNEL); - memset(dev->priv, 0, sizeof(local_info_t)); - /* The FMVJ18x specific entries in the device structure. */ dev->hard_start_xmit = &fjn_start_xmit; dev->set_config = &fjn_config; dev->get_stats = &fjn_get_stats; dev->set_multicast_list = &set_rx_mode; ether_setup(dev); - dev->name = ((local_info_t *)dev->priv)->node.dev_name; + dev->name = lp->node.dev_name; dev->init = &fmvj18x_init; dev->open = &fjn_open; dev->stop = &fjn_close; dev->tbusy = 0xFF; - link->priv = link->irq.Instance = dev; /* Register with Card Services */ link->next = dev_list; @@ -353,6 +342,7 @@ static dev_link_t *fmvj18x_attach(void) static void fmvj18x_detach(dev_link_t *link) { + local_info_t *lp = link->priv; dev_link_t **linkp; long flags; @@ -386,15 +376,9 @@ static void fmvj18x_detach(dev_link_t *link) /* Unlink device structure, free pieces */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree(dev->priv); - kfree(dev); - } - kfree(link); + if (link->dev) + unregister_netdev(&lp->dev); + kfree(lp); } /* fmvj18x_detach */ @@ -405,10 +389,11 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed static void fmvj18x_config(dev_link_t *link) { - client_handle_t handle; + client_handle_t handle = link->handle; + local_info_t *lp = link->priv; + struct net_device *dev = &lp->dev; tuple_t tuple; cisparse_t parse; - struct net_device *dev; u_short buf[32]; int i, last_fn, last_ret; ioaddr_t ioaddr; @@ -416,9 +401,6 @@ static void fmvj18x_config(dev_link_t *link) char *card_name = "unknown"; u_char *node_id; - handle = link->handle; - dev =link->priv; - DEBUG(0, "fmvj18x_config(0x%p)\n", link); /* @@ -538,10 +520,10 @@ static void fmvj18x_config(dev_link_t *link) break; } - link->dev = &((local_info_t *)dev->priv)->node; + link->dev = &lp->node; link->state &= ~DEV_CONFIG_PENDING; - ((struct local_info_t *)dev->priv)->cardtype = cardtype ; + lp->cardtype = cardtype; /* print current configuration */ printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ", dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", @@ -594,7 +576,8 @@ static int fmvj18x_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; + local_info_t *lp = link->priv; + struct net_device *dev = &lp->dev; DEBUG(1, "fmvj18x_event(0x%06x)\n", event); @@ -677,12 +660,12 @@ module_exit(exit_fmvj18x_cs); static void fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = (struct net_device *)dev_id; + local_info_t *lp = dev_id; + struct net_device *dev = &lp->dev; ioaddr_t ioaddr; - local_info_t *lp; unsigned short tx_stat, rx_stat; - if (dev == NULL) { + if (lp == NULL) { printk(KERN_NOTICE "fjn_interrupt(): irq %d for " "unknown device.\n", irq); return; @@ -693,7 +676,6 @@ static void fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } dev->interrupt = 1; - lp = (struct local_info_t *)dev->priv; ioaddr = dev->base_addr; /* avoid multiple interrupts */ @@ -710,12 +692,8 @@ static void fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) outb(tx_stat, ioaddr + TX_STATUS); outb(rx_stat, ioaddr + RX_STATUS); - if (fmvj18x_debug > 4) { - printk(KERN_DEBUG "%s: interrupt, rx_status %02x.\n", - dev->name, rx_stat); - printk(KERN_DEBUG " tx_status %02x.\n", - tx_stat); - } + DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat); + DEBUG(4, " tx_status %02x.\n", tx_stat); if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { /* there is packet(s) in rx buffer */ @@ -738,11 +716,8 @@ static void fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) mark_bh(NET_BH); /* Inform upper layers. */ } } - if (fmvj18x_debug > 4) { - printk(KERN_DEBUG "%s: exiting interrupt,\n", dev->name); - printk(KERN_DEBUG " tx_status %02x, rx_status %02x.\n", - tx_stat, rx_stat); - } + DEBUG(4, "%s: exiting interrupt,\n", dev->name); + DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat); dev->interrupt = 0; outb(D_TX_INTR, ioaddr + TX_INTR); @@ -802,15 +777,13 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned char *buf = skb->data; if (length > ETH_FRAME_LEN) { - if (fmvj18x_debug) - printk(KERN_NOTICE "%s: Attempting to send a large packet" - " (%d bytes).\n", dev->name, length); + printk(KERN_NOTICE "%s: Attempting to send a large packet" + " (%d bytes).\n", dev->name, length); return 1; } - if (fmvj18x_debug > 4) - printk(KERN_DEBUG "%s: Transmitting a packet of length %lu.\n", - dev->name, (unsigned long)skb->len); + DEBUG(4, "%s: Transmitting a packet of length %lu.\n", + dev->name, (unsigned long)skb->len); lp->stats.tx_bytes += skb->len; /* Disable both interrupts. */ @@ -864,9 +837,7 @@ static void fjn_reset(struct net_device *dev) ioaddr_t ioaddr = dev->base_addr; int i; - if (fmvj18x_debug > 4) { - printk(KERN_DEBUG "fjn_reset(%s) called.\n",dev->name); - } + DEBUG(4, "fjn_reset(%s) called.\n",dev->name); /* Power On chip and select bank 0 */ outb(BANK_0, ioaddr + CONFIG_1); @@ -885,12 +856,6 @@ static void fjn_reset(struct net_device *dev) for (i = 0; i < 6; i++) outb(dev->dev_addr[i], ioaddr + NODE_ID + i); - if (fmvj18x_debug > 4) { - printk(KERN_DEBUG "node id: "); - for (i = 0; i < 6; i++) - printk("%02X ",inb(ioaddr + NODE_ID + i)); - printk("\n"); - } /* Switch to bank 1 */ outb(BANK_1, ioaddr + CONFIG_1); @@ -948,16 +913,14 @@ static void fjn_rx(struct net_device *dev) ioaddr_t ioaddr = dev->base_addr; int boguscount = 10; /* 5 -> 10: by agy 19940922 */ - if (fmvj18x_debug > 4) - printk(KERN_DEBUG "%s: in rx_packet(), rx_status %02x.\n", - dev->name, inb(ioaddr + RX_STATUS)); + DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n", + dev->name, inb(ioaddr + RX_STATUS)); while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { u_short status = inw(ioaddr + DATAPORT); - if (fmvj18x_debug > 4) - printk(KERN_DEBUG "%s: Rxing packet mode %02x status %04x.\n", - dev->name, inb(ioaddr + RX_MODE), status); + DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n", + dev->name, inb(ioaddr + RX_MODE), status); #ifndef final_version if (status == 0) { outb(F_SKP_PKT, ioaddr + RX_SKIP); @@ -997,7 +960,8 @@ static void fjn_rx(struct net_device *dev) (pkt_len + 1) >> 1); skb->protocol = eth_type_trans(skb, dev); - if (fmvj18x_debug > 5) { +#ifdef PCMCIA_DEBUG + if (pc_debug > 5) { int i; printk(KERN_DEBUG "%s: Rxed packet of length %d: ", dev->name, pkt_len); @@ -1005,6 +969,7 @@ static void fjn_rx(struct net_device *dev) printk(" %02x", skb->data[i]); printk(".\n"); } +#endif netif_rx(skb); lp->stats.rx_packets++; @@ -1027,9 +992,9 @@ static void fjn_rx(struct net_device *dev) outb(F_SKP_PKT, ioaddr + RX_SKIP); } - if (fmvj18x_debug > 5 && i > 0) - printk(KERN_DEBUG "%s: Exint Rx packet with mode %02x after" - " %d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i); + if (i > 0) + DEBUG(5, "%s: Exint Rx packet with mode %02x after " + "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i); } */ @@ -1040,18 +1005,15 @@ static void fjn_rx(struct net_device *dev) static int fjn_config(struct net_device *dev, struct ifmap *map){ return 0; -} /* fjn_config */ +} static int fjn_open(struct net_device *dev) { struct local_info_t *lp = (struct local_info_t *)dev->priv; - dev_link_t *link; + dev_link_t *link = &lp->link; - if (fmvj18x_debug > 4) - printk(KERN_DEBUG "fjn_open('%s').\n", dev->name); + DEBUG(4, "fjn_open('%s').\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (!DEV_OK(link)) return -ENODEV; @@ -1076,23 +1038,13 @@ static int fjn_open(struct net_device *dev) static int fjn_close(struct net_device *dev) { - ioaddr_t ioaddr = dev->base_addr; struct local_info_t *lp = (struct local_info_t *)dev->priv; - dev_link_t *link; - - if (fmvj18x_debug > 4) - printk(KERN_DEBUG "fjn_open('%s').\n", dev->name); - - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; - - if (fmvj18x_debug > 2) - printk(KERN_DEBUG "%s: shutting down ethercard.\n", dev->name); + dev_link_t *link = &lp->link; + ioaddr_t ioaddr = dev->base_addr; - ((struct local_info_t *)dev->priv)->open_time = 0; + DEBUG(4, "fjn_close('%s').\n", dev->name); + lp->open_time = 0; dev->tbusy = 1; dev->start = 0; @@ -1109,7 +1061,7 @@ static int fjn_close(struct net_device *dev) /* Set the ethernet adaptor disable IRQ */ if( lp->cardtype != TDK ) - outb(INTR_OFF, ioaddr + LAN_CTRL); + outb(INTR_OFF, ioaddr + LAN_CTRL); link->open--; dev->start = 0; diff --git a/drivers/net/pcmcia/netwave_cs.c b/drivers/net/pcmcia/netwave_cs.c index 6ca0ce297..74928fd27 100644 --- a/drivers/net/pcmcia/netwave_cs.c +++ b/drivers/net/pcmcia/netwave_cs.c @@ -302,6 +302,8 @@ struct site_survey { }; typedef struct netwave_private { + dev_link_t link; + struct net_device dev; dev_node_t node; u_char *ramBase; int timeoutCounter; @@ -440,7 +442,7 @@ static dev_link_t *netwave_attach(void) client_reg_t client_reg; dev_link_t *link; struct net_device *dev; - netwave_private *priv; + netwave_private *priv; int i, ret; DEBUG(0, "netwave_attach()\n"); @@ -449,8 +451,11 @@ static dev_link_t *netwave_attach(void) netwave_flush_stale_links(); /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) return NULL; + memset(priv, 0, sizeof(*priv)); + link = &priv->link; dev = &priv->dev; + link->priv = dev->priv = priv; link->release.function = &netwave_release; link->release.data = (u_long)link; @@ -478,15 +483,7 @@ static dev_link_t *netwave_attach(void) link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - /* Allocate space for private device-specific data */ - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - - dev->priv = kmalloc(sizeof(netwave_private), GFP_KERNEL); - memset(dev->priv, 0, sizeof(netwave_private)); - /* Set the watchdog timer */ - priv = (netwave_private *) dev->priv; priv->watchdog.function = &netwave_watchdog; priv->watchdog.data = (unsigned long) dev; @@ -502,12 +499,12 @@ static dev_link_t *netwave_attach(void) dev->do_ioctl = &netwave_ioctl; ether_setup(dev); - dev->name = ((struct netwave_private *)dev->priv)->node.dev_name; + dev->name = priv->node.dev_name; dev->init = &netwave_init; dev->open = &netwave_open; dev->stop = &netwave_close; dev->tbusy = 1; - link->priv = link->irq.Instance = dev; + link->irq.Instance = dev; /* Register with Card Services */ link->next = dev_list; @@ -541,6 +538,7 @@ static dev_link_t *netwave_attach(void) */ static void netwave_detach(dev_link_t *link) { + netwave_private *priv = link->priv; dev_link_t **linkp; long flags; @@ -587,16 +585,9 @@ static void netwave_detach(dev_link_t *link) /* Unlink device structure, free pieces */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - link->dev = NULL; - if (dev->priv) - kfree(dev->priv); - kfree(link->priv); - } - kfree(link); + if (link->dev) + unregister_netdev(&priv->dev); + kfree(priv); } /* netwave_detach */ @@ -633,8 +624,8 @@ static void netwave_flush_stale_links(void) * */ static int netwave_ioctl(struct net_device *dev, /* ioctl device */ - struct ifreq *rq, /* Data passed */ - int cmd) /* Ioctl number */ + struct ifreq *rq, /* Data passed */ + int cmd) /* Ioctl number */ { unsigned long flags; int ret = 0; @@ -839,20 +830,16 @@ static int netwave_ioctl(struct net_device *dev, /* ioctl device */ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed static void netwave_pcmcia_config(dev_link_t *link) { - client_handle_t handle; + client_handle_t handle = link->handle; + netwave_private *priv = link->priv; + struct net_device *dev = &priv->dev; tuple_t tuple; cisparse_t parse; - struct net_device *dev; int i, j, last_ret, last_fn; u_char buf[64]; win_req_t req; memreq_t mem; u_char *ramBase = NULL; - /* modwin_t mod; - short iobase, *phys_addr; - */ - handle = link->handle; - dev = link->priv; DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link); @@ -969,7 +956,7 @@ failed: */ static void netwave_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; - struct net_device *dev = link->priv; + netwave_private *priv = link->priv; DEBUG(0, "netwave_release(0x%p)\n", link); @@ -986,7 +973,7 @@ static void netwave_release(u_long arg) { /* Don't bother checking to see if these succeed or not */ if (link->win) { - iounmap(((netwave_private *)dev->priv)->ramBase); + iounmap(priv->ramBase); CardServices(ReleaseWindow, link->win); } CardServices(ReleaseConfiguration, link->handle); @@ -1014,7 +1001,8 @@ static void netwave_release(u_long arg) { static int netwave_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; + netwave_private *priv = link->priv; + struct net_device *dev = &priv->dev; DEBUG(1, "netwave_event(0x%06x)\n", event); @@ -1027,7 +1015,6 @@ static int netwave_event(event_t event, int priority, link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { dev->tbusy = 1; dev->start = 0; - /* ((netwave_private *)link->priv)->block = 1; */ link->release.expires = jiffies + 5; add_timer(&link->release); } @@ -1312,24 +1299,18 @@ static void netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs) { ioaddr_t iobase; u_char *ramBase; struct net_device *dev = (struct net_device *)dev_id; - struct netwave_private *priv; + struct netwave_private *priv = dev->priv; + dev_link_t *link = &priv->link; int i; - dev_link_t *link; - - if ((dev == NULL) | (!dev->start)) - return; - priv = (netwave_private *)dev->priv; + if ((dev == NULL) | (!dev->start)) + return; if (dev->interrupt) { printk("%s: re-entering the interrupt handler.\n", dev->name); return; } dev->interrupt = 1; - - /* Find the correct dev_link_t */ - for (link = dev_list; NULL != link; link = link->next) - if (dev == link->priv) break; iobase = dev->base_addr; ramBase = priv->ramBase; @@ -1592,12 +1573,10 @@ static int netwave_rx(struct net_device *dev) { } static int netwave_open(struct net_device *dev) { - dev_link_t *link; + netwave_private *priv = dev->priv; + dev_link_t *link = &priv->link; DEBUG(1, "netwave_open: starting.\n"); - - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (!DEV_OK(link)) return -ENODEV; @@ -1612,16 +1591,11 @@ static int netwave_open(struct net_device *dev) { } static int netwave_close(struct net_device *dev) { - dev_link_t *link; - netwave_private *priv = (netwave_private *) dev->priv; + netwave_private *priv = (netwave_private *)dev->priv; + dev_link_t *link = &priv->link; DEBUG(1, "netwave_close: finishing.\n"); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; - /* If watchdog was activated, kill it ! */ del_timer(&priv->watchdog); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 2dd6a369b..2fb3772a5 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -312,61 +312,63 @@ Type Definitions ---------------------------------------------------------------------------- */ typedef struct _mace_statistics { - /* MACE_XMTFS */ - int xmtsv; - int uflo; - int lcol; - int more; - int one; - int defer; - int lcar; - int rtry; - - /* MACE_XMTRC */ - int exdef; - int xmtrc; - - /* RFS1--Receive Status (RCVSTS) */ - int oflo; - int clsn; - int fram; - int fcs; - - /* RFS2--Runt Packet Count (RNTPC) */ - int rfs_rntpc; - - /* RFS3--Receive Collision Count (RCVCC) */ - int rfs_rcvcc; - - /* MACE_IR */ - int jab; - int babl; - int cerr; - int rcvcco; - int rntpco; - int mpco; - - /* MACE_MPC */ - int mpc; - - /* MACE_RNTPC */ - int rntpc; - - /* MACE_RCVCC */ - int rcvcc; + /* MACE_XMTFS */ + int xmtsv; + int uflo; + int lcol; + int more; + int one; + int defer; + int lcar; + int rtry; + + /* MACE_XMTRC */ + int exdef; + int xmtrc; + + /* RFS1--Receive Status (RCVSTS) */ + int oflo; + int clsn; + int fram; + int fcs; + + /* RFS2--Runt Packet Count (RNTPC) */ + int rfs_rntpc; + + /* RFS3--Receive Collision Count (RCVCC) */ + int rfs_rcvcc; + + /* MACE_IR */ + int jab; + int babl; + int cerr; + int rcvcco; + int rntpco; + int mpco; + + /* MACE_MPC */ + int mpc; + + /* MACE_RNTPC */ + int rntpc; + + /* MACE_RCVCC */ + int rcvcc; } mace_statistics; typedef struct _mace_private { - dev_node_t node; - struct net_device_stats linux_stats; /* Linux statistics counters */ - mace_statistics mace_stats; /* MACE chip statistics counters */ - - /* restore_multicast_list() state variables */ - int multicast_ladrf[MACE_LADRF_LEN]; /* Logical address filter */ - int multicast_num_addrs; - - char tx_free_frames; /* Number of free transmit frame buffers */ - char tx_irq_disabled; /* MACE TX interrupt disabled */ + dev_link_t link; + struct net_device dev; + dev_node_t node; + struct net_device_stats linux_stats; /* Linux statistics counters */ + mace_statistics mace_stats; /* MACE chip statistics counters */ + + /* restore_multicast_list() state variables */ + int multicast_ladrf[MACE_LADRF_LEN]; /* Logical address filter */ + int multicast_num_addrs; + + char tx_free_frames; /* Number of free transmit frame buffers */ + char tx_irq_disabled; /* MACE TX interrupt disabled */ } mace_private; /* ---------------------------------------------------------------------------- @@ -384,9 +386,7 @@ static dev_info_t dev_info="nmclan_cs"; static dev_link_t *dev_list=NULL; static char *if_names[]={ - "Auto", - "10baseT", - "BNC", + "Auto", "10baseT", "BNC", }; #ifdef PCMCIA_DEBUG @@ -403,12 +403,8 @@ Parameters 'insmod'. ---------------------------------------------------------------------------- */ -static int if_port=0; /* default=auto */ - /* - * 0=auto - * 1=10base-T (twisted pair) - * 2=10base-2 (BNC) - */ +/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */ +static int if_port=0; /* Bit map of interrupts to choose from */ static u_int irq_mask = 0xdeb8; @@ -425,7 +421,7 @@ Function Prototypes static void nmclan_config(dev_link_t *link); static void nmclan_release(u_long arg); static int nmclan_event(event_t event, int priority, - event_callback_args_t *args); + event_callback_args_t *args); static void nmclan_reset(struct net_device *dev); static int mace_config(struct net_device *dev, struct ifmap *map); @@ -473,10 +469,11 @@ nmclan_init We never need to do anything when a nmclan device is "initialized" by the net software, because we only register already-found cards. ---------------------------------------------------------------------------- */ + static int nmclan_init(struct net_device *dev) { - return 0; -} /* nmclan_init */ + return 0; +} /* ---------------------------------------------------------------------------- nmclan_attach @@ -484,79 +481,78 @@ nmclan_attach structures for one device. The device is registered with Card Services. ---------------------------------------------------------------------------- */ + static dev_link_t *nmclan_attach(void) { - client_reg_t client_reg; - dev_link_t *link; - struct net_device *dev; - int i, ret; - - DEBUG(0, "nmclan_attach()\n"); - DEBUG(1, "%s\n", rcsid); - flush_stale_links(); - - /* Create new ethernet device */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); - link->release.function = &nmclan_release; - link->release.data = (u_long)link; - link->io.NumPorts1 = 32; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.IOAddrLines = 5; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; - if (irq_list[0] == -1) - link->irq.IRQInfo2 = irq_mask; - else - for (i = 0; i < 4; i++) - link->irq.IRQInfo2 |= 1 << irq_list[i]; - link->irq.Handler = &mace_interrupt; - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - link->conf.Present = PRESENT_OPTION; - - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - - /* Allocate private data area for this device. */ - dev->priv = kmalloc(sizeof(mace_private), GFP_KERNEL); - memset(dev->priv, 0, sizeof(mace_private)); - ((mace_private *)dev->priv)->tx_free_frames=AM2150_MAX_TX_FRAMES; - - dev->hard_start_xmit = &mace_start_xmit; - dev->set_config = &mace_config; - dev->get_stats = &mace_get_stats; - dev->set_multicast_list = &set_multicast_list; - ether_setup(dev); - dev->name = ((mace_private *)dev->priv)->node.dev_name; - dev->init = &nmclan_init; - dev->open = &mace_open; - dev->stop = &mace_close; - dev->tbusy = 0xFF; - link->priv = link->irq.Instance = dev; - - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; - client_reg.EventMask = - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.event_handler = &nmclan_event; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - ret = CardServices(RegisterClient, &link->handle, &client_reg); - if (ret != 0) { - cs_error(link->handle, RegisterClient, ret); - nmclan_detach(link); - return NULL; - } + mace_private *lp; + dev_link_t *link; + struct net_device *dev; + client_reg_t client_reg; + int i, ret; + + DEBUG(0, "nmclan_attach()\n"); + DEBUG(1, "%s\n", rcsid); + flush_stale_links(); + + /* Create new ethernet device */ + lp = kmalloc(sizeof(*lp), GFP_KERNEL); + if (!lp) return NULL; + memset(lp, 0, sizeof(*lp)); + link = &lp->link; dev = &lp->dev; + link->priv = dev->priv = link->irq.Instance = lp; + + link->release.function = &nmclan_release; + link->release.data = (u_long)link; + link->io.NumPorts1 = 32; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.IOAddrLines = 5; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->irq.Handler = &mace_interrupt; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; + + lp->tx_free_frames=AM2150_MAX_TX_FRAMES; + + dev->hard_start_xmit = &mace_start_xmit; + dev->set_config = &mace_config; + dev->get_stats = &mace_get_stats; + dev->set_multicast_list = &set_multicast_list; + ether_setup(dev); + dev->name = lp->node.dev_name; + dev->init = &nmclan_init; + dev->open = &mace_open; + dev->stop = &mace_close; + dev->tbusy = 0xFF; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &nmclan_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != 0) { + cs_error(link->handle, RegisterClient, ret); + nmclan_detach(link); + return NULL; + } - return link; + return link; } /* nmclan_attach */ /* ---------------------------------------------------------------------------- @@ -566,40 +562,36 @@ nmclan_detach structures are freed. Otherwise, the structures will be freed when the device is released. ---------------------------------------------------------------------------- */ + static void nmclan_detach(dev_link_t *link) { - dev_link_t **linkp; - - DEBUG(0, "nmclan_detach(0x%p)\n", link); - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; - - if (link->state & DEV_CONFIG) { - nmclan_release((u_long)link); - if (link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; + mace_private *lp = link->priv; + dev_link_t **linkp; + + DEBUG(0, "nmclan_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; + + if (link->state & DEV_CONFIG) { + nmclan_release((u_long)link); + if (link->state & DEV_STALE_CONFIG) { + link->state |= DEV_STALE_LINK; + return; + } } - } - if (link->handle) - CardServices(DeregisterClient, link->handle); - - /* Unlink device structure, free bits */ - *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree(dev->priv); - kfree(link->priv); - } - kfree(link); + if (link->handle) + CardServices(DeregisterClient, link->handle); + + /* Unlink device structure, free bits */ + *linkp = link->next; + if (link->dev) + unregister_netdev(&lp->dev); + kfree(lp); } /* nmclan_detach */ @@ -731,18 +723,14 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed static void nmclan_config(dev_link_t *link) { - client_handle_t handle; - struct net_device *dev; + client_handle_t handle = link->handle; + mace_private *lp = link->priv; + struct net_device *dev = &lp->dev; tuple_t tuple; cisparse_t parse; u_char buf[64]; int i, last_ret, last_fn; ioaddr_t ioaddr; - u_short *phys_addr; - - handle = link->handle; - dev = link->priv; - phys_addr = (u_short *)dev->dev_addr; DEBUG(0, "nmclan_config(0x%p)\n", link); @@ -770,7 +758,7 @@ static void nmclan_config(dev_link_t *link) printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); goto failed; } - + ioaddr = dev->base_addr; /* Read the ethernet address from the CIS. */ @@ -807,9 +795,9 @@ static void nmclan_config(dev_link_t *link) else printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); - link->dev = &((mace_private *)dev->priv)->node; + link->dev = &lp->node; link->state &= ~DEV_CONFIG_PENDING; - + printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port, hw_addr ", dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]); for (i = 0; i < 6; i++) @@ -821,7 +809,7 @@ cs_failed: failed: nmclan_release((u_long)link); return; - + } /* nmclan_config */ /* ---------------------------------------------------------------------------- @@ -862,10 +850,11 @@ static int nmclan_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; + mace_private *lp = link->priv; + struct net_device *dev = &lp->dev; DEBUG(1, "nmclan_event(0x%06x)\n", event); - + switch (event) { case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; @@ -918,20 +907,13 @@ nmclan_reset ---------------------------------------------------------------------------- */ static void nmclan_reset(struct net_device *dev) { + mace_private *lp = dev->priv; #if RESET_XILINX - dev_link_t *link; + dev_link_t *link = &lp->link; conf_reg_t reg; u_long OrigCorValue; - /* Find our client handle. */ - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) { - printk(KERN_NOTICE "nmclan_cs: bad device pointer!\n"); - return; - } - /* Save original COR value */ reg.Function = 0; reg.Action = CS_READ; @@ -953,13 +935,13 @@ static void nmclan_reset(struct net_device *dev) reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK); CardServices(AccessConfigurationRegister, link->handle, ®); /* Xilinx is now completely reset along with the MACE chip. */ - ((mace_private *)dev->priv)->tx_free_frames=AM2150_MAX_TX_FRAMES; + lp->tx_free_frames=AM2150_MAX_TX_FRAMES; #endif /* #if RESET_XILINX */ /* Xilinx is now completely reset along with the MACE chip. */ - ((mace_private *)dev->priv)->tx_free_frames=AM2150_MAX_TX_FRAMES; - + lp->tx_free_frames=AM2150_MAX_TX_FRAMES; + /* Reinitialize the MACE chip for operation. */ mace_init(dev->base_addr, dev->dev_addr); mace_write(dev->base_addr, MACE_IMR, MACE_IMR_DEFAULT); @@ -981,9 +963,8 @@ static int mace_config(struct net_device *dev, struct ifmap *map) dev->if_port = map->port; printk(KERN_INFO "%s: switched to %s port\n", dev->name, if_names[dev->if_port]); - } - else - return -EINVAL; + } else + return -EINVAL; } return 0; } /* mace_config */ @@ -995,10 +976,9 @@ mace_open static int mace_open(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; + mace_private *lp = dev->priv; + dev_link_t *link = &lp->link; - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (!DEV_OK(link)) return -ENODEV; @@ -1023,15 +1003,11 @@ mace_close static int mace_close(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; - - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; + mace_private *lp = dev->priv; + dev_link_t *link = &lp->link; DEBUG(2, "%s: shutting down ethercard.\n", dev->name); - + /* Mask off all interrupts from the MACE chip. */ outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR); @@ -1062,7 +1038,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev) { mace_private *lp = (mace_private *)dev->priv; ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; + dev_link_t *link = &lp->link; #if TIMEOUT_TX /* Transmitter timeout. */ @@ -1074,10 +1050,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); #if RESET_ON_TIMEOUT printk("resetting card\n"); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link) - CardServices(ResetCard, link->handle); + CardServices(ResetCard, link->handle); #else /* #if RESET_ON_TIMEOUT */ printk("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ @@ -1091,7 +1064,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev) DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n", dev->name, (long)skb->len); - + /* Avoid timer-based retransmission conflicts. */ if (test_and_set_bit(TBUSY_UNSPECIFIED, (void*)&dev->tbusy) != 0) { printk(KERN_NOTICE "%s: transmitter access conflict.\n", @@ -1146,7 +1119,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev) #endif /* #if (!TX_INTERRUPTABLE) */ dev_kfree_skb(skb); - + return 0; } /* mace_start_xmit */ @@ -1156,8 +1129,8 @@ mace_interrupt ---------------------------------------------------------------------------- */ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = (struct net_device *)dev_id; - mace_private *lp = (mace_private *)dev->priv; + mace_private *lp = (mace_private *)dev_id; + struct net_device *dev = &lp->dev; ioaddr_t ioaddr = dev->base_addr; int status; int IntrCnt = MACE_MAX_IR_ITERATIONS; @@ -1169,7 +1142,6 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (dev->interrupt || lp->tx_irq_disabled) { - sti(); printk( (lp->tx_irq_disabled? KERN_NOTICE "%s: Interrupt with tx_irq_disabled " @@ -1184,7 +1156,6 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } dev->interrupt = 1; - sti(); if (dev->start == 0) { DEBUG(2, "%s: interrupt from dead card\n", dev->name); @@ -1194,7 +1165,7 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) do { /* WARNING: MACE_IR is a READ/CLEAR port! */ status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR); - + DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status); if (status & MACE_IR_RCVINT) { @@ -1346,9 +1317,9 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) DEBUG(3, " receiving packet size 0x%X rx_status" " 0x%X.\n", pkt_len, rx_status); - + skb = dev_alloc_skb(pkt_len+2); - + if (skb != NULL) { skb->dev = dev; @@ -1425,7 +1396,7 @@ static void pr_mace_stats(mace_statistics *pstats) /* MACE_XMTRC */ DEBUG(2, " exdef=%-7d xmtrc=%d\n", pstats->exdef, pstats->xmtrc); - + /* RFS1--Receive Status (RCVSTS) */ DEBUG(2, " oflo=%-7d clsn=%d\n", pstats->oflo, pstats->clsn); @@ -1472,7 +1443,7 @@ update_stats static void update_stats(ioaddr_t ioaddr, struct net_device *dev) { mace_private *lp = (mace_private *)dev->priv; - + lp->mace_stats.rcvcc += mace_read(ioaddr, MACE_RCVCC); lp->mace_stats.rntpc += mace_read(ioaddr, MACE_RNTPC); lp->mace_stats.mpc += mace_read(ioaddr, MACE_MPC); @@ -1711,7 +1682,7 @@ static void restore_multicast_list(struct net_device *dev) DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name, ((mace_private *)(dev->priv))->multicast_num_addrs); - + if (dev->flags & IFF_PROMISC) { /* Promiscuous mode: receive all packets */ mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL); @@ -1768,10 +1739,10 @@ exit_nmclan_cs static void __exit exit_nmclan_cs(void) { - DEBUG(0, "nmclan_cs: unloading\n"); - unregister_pccard_driver(&dev_info); - while (dev_list != NULL) - nmclan_detach(dev_list); + DEBUG(0, "nmclan_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + nmclan_detach(dev_list); } module_init(init_nmclan_cs); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index cefdf91be..575a91271 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -11,7 +11,7 @@ Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org - pcnet_cs.c 1.106 1999/11/09 21:53:13 + pcnet_cs.c 1.110 1999/12/06 21:39:18 The network driver code is based on Donald Becker's NE2000 code: @@ -72,7 +72,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"pcnet_cs.c 1.106 1999/11/09 21:53:13 (David Hinds)"; +"pcnet_cs.c 1.110 1999/12/06 21:39:18 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -122,26 +122,21 @@ static void pcnet_config(dev_link_t *link); static void pcnet_release(u_long arg); static int pcnet_event(event_t event, int priority, event_callback_args_t *args); - static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_watchdog(u_long arg); - static void pcnet_reset_8390(struct net_device *dev); - static int set_config(struct net_device *dev, struct ifmap *map); - static int setup_shmem_window(dev_link_t *link, int start_pg, int stop_pg, int cm_offset); static int setup_dma_config(dev_link_t *link, int start_pg, int stop_pg); -static dev_info_t dev_info = "pcnet_cs"; - static dev_link_t *pcnet_attach(void); static void pcnet_detach(dev_link_t *); +static dev_info_t dev_info = "pcnet_cs"; static dev_link_t *dev_list; /*====================================================================*/ @@ -215,7 +210,8 @@ static hw_info_t hw_info[] = { { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, - { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 } + { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, + { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 } }; #define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t)) @@ -226,12 +222,13 @@ static hw_info_t dl_fast_info = { /* D-Link EtherFast */ 0x00, 0x00, 0x00, 0x00, IS_DL10019A }; typedef struct pcnet_dev_t { - struct net_device dev; + struct net_device dev; /* so &dev == &pcnet_dev_t */ + dev_link_t link; dev_node_t node; u_long flags; caddr_t base; struct timer_list watchdog; - int stale, link; + int stale, state; u_short fast_poll; } pcnet_dev_t; @@ -283,18 +280,22 @@ static int pcnet_init(struct net_device *dev) static dev_link_t *pcnet_attach(void) { - client_reg_t client_reg; - dev_link_t *link; pcnet_dev_t *info; + dev_link_t *link; struct net_device *dev; + client_reg_t client_reg; int i, ret; DEBUG(0, "pcnet_attach()\n"); flush_stale_links(); /* Create new ethernet device */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) return NULL; + memset(info, 0, sizeof(*info)); + link = &info->link; dev = &info->dev; + link->priv = info; + link->release.function = &pcnet_release; link->release.data = (u_long)link; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -308,9 +309,6 @@ static dev_link_t *pcnet_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - info = kmalloc(sizeof(struct pcnet_dev_t), GFP_KERNEL); - memset(info, 0, sizeof(struct pcnet_dev_t)); - dev = &info->dev; ethdev_init(dev); dev->name = info->node.dev_name; dev->init = &pcnet_init; @@ -318,7 +316,6 @@ static dev_link_t *pcnet_attach(void) dev->stop = &pcnet_close; dev->set_config = &set_config; dev->tbusy = 1; - link->priv = info; /* Register with Card Services */ link->next = dev_list; @@ -353,6 +350,7 @@ static dev_link_t *pcnet_attach(void) static void pcnet_detach(dev_link_t *link) { + pcnet_dev_t *info = link->priv; dev_link_t **linkp; long flags; @@ -385,15 +383,9 @@ static void pcnet_detach(dev_link_t *link) /* Unlink device structure, free bits */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree_s(dev->priv, sizeof(struct ei_device)); - kfree_s(dev, sizeof(struct pcnet_dev_t)); - } - kfree_s(link, sizeof(struct dev_link_t)); + if (link->dev) + unregister_netdev(&info->dev); + kfree(info); } /* pcnet_detach */ @@ -595,20 +587,16 @@ static int try_io_port(dev_link_t *link) static void pcnet_config(dev_link_t *link) { - client_handle_t handle; + client_handle_t handle = link->handle; + pcnet_dev_t *info = link->priv; + struct net_device *dev = &info->dev; tuple_t tuple; cisparse_t parse; - pcnet_dev_t *info; - struct net_device *dev; int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; int manfid = 0, prodid = 0, has_shmem = 0; u_short buf[64]; hw_info_t *hw_info; - handle = link->handle; - info = link->priv; - dev = &info->dev; - DEBUG(0, "pcnet_config(0x%p)\n", link); tuple.Attributes = 0; @@ -881,12 +869,10 @@ static void set_misc_reg(struct net_device *dev) static int pcnet_open(struct net_device *dev) { pcnet_dev_t *info = (pcnet_dev_t *)dev; - dev_link_t *link; + dev_link_t *link = &info->link; DEBUG(2, "pcnet_open('%s')\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; if (!DEV_OK(link)) return -ENODEV; @@ -897,7 +883,7 @@ static int pcnet_open(struct net_device *dev) request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); /* Start by assuming the link is bad */ - info->link = 1; + info->state = 1; info->watchdog.function = &ei_watchdog; info->watchdog.data = (u_long)info; info->watchdog.expires = jiffies + HZ; @@ -910,18 +896,15 @@ static int pcnet_open(struct net_device *dev) static int pcnet_close(struct net_device *dev) { - dev_link_t *link; + pcnet_dev_t *info = (pcnet_dev_t *)dev; + dev_link_t *link = &info->link; DEBUG(2, "pcnet_close('%s')\n", dev->name); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; free_irq(dev->irq, dev); link->open--; dev->start = 0; - del_timer(&((pcnet_dev_t *)dev)->watchdog); + del_timer(&info->watchdog); if (link->state & DEV_STALE_CONFIG) { link->release.expires = jiffies + HZ/20; link->state |= DEV_RELEASE_PENDING; @@ -1016,12 +999,12 @@ static void ei_watchdog(u_long arg) if (info->flags & IS_DL10019A) { int state = inb(dev->base_addr+0x1c) & 0x01; - if (state != info->link) { + if (state != info->state) { printk(KERN_INFO "%s: %s link beat\n", dev->name, (state) ? "lost" : "found"); if (!state) NS8390_init(dev, 1); - info->link = state; + info->state = state; } } diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 5c7c5e4df..4a58706f6 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -8,7 +8,7 @@ Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org - smc91c92_cs.c 1.82 1999/11/08 20:46:17 + smc91c92_cs.c 1.85 2000/01/15 02:03:14 This driver contains code written by Donald Becker (becker@cesdis.gsfc.nasa.gov), Rowan Hughes (x-csrdh@jcu.edu.au), @@ -110,6 +110,8 @@ static dev_info_t dev_info = "smc91c92_cs"; static dev_link_t *dev_list = NULL; struct smc_private { + dev_link_t link; + struct net_device dev; u_short manfid; u_short cardid; struct net_device_stats stats; @@ -336,6 +338,7 @@ static int smc91c92_init(struct net_device *dev) static dev_link_t *smc91c92_attach(void) { client_reg_t client_reg; + struct smc_private *smc; dev_link_t *link; struct net_device *dev; int i, ret; @@ -344,8 +347,11 @@ static dev_link_t *smc91c92_attach(void) flush_stale_links(); /* Create new ethernet device */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + smc = kmalloc(sizeof(struct smc_private), GFP_KERNEL); + if (!smc) return NULL; + memset(smc, 0, sizeof(struct smc_private)); + link = &smc->link; dev = &smc->dev; + link->release.function = &smc91c92_release; link->release.data = (u_long)link; link->io.NumPorts1 = 16; @@ -362,26 +368,19 @@ static dev_link_t *smc91c92_attach(void) link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - - /* Make up a SMC91-specific-data structure. */ - dev->priv = kmalloc(sizeof(struct smc_private), GFP_KERNEL); - memset(dev->priv, 0, sizeof(struct smc_private)); - + /* The SMC91c92-specific entries in the device structure. */ dev->hard_start_xmit = &smc_start_xmit; dev->get_stats = &smc91c92_get_stats; dev->set_config = &s9k_config; dev->set_multicast_list = &set_rx_mode; ether_setup(dev); - dev->name = ((struct smc_private *)dev->priv)->node.dev_name; + dev->name = smc->node.dev_name; dev->init = &smc91c92_init; dev->open = &smc91c92_open; dev->stop = &smc91c92_close; dev->tbusy = 1; - link->priv = link->irq.Instance = dev; + dev->priv = link->priv = link->irq.Instance = smc; /* Register with Card Services */ link->next = dev_list; @@ -415,6 +414,7 @@ static dev_link_t *smc91c92_attach(void) static void smc91c92_detach(dev_link_t *link) { + struct smc_private *smc = link->priv; dev_link_t **linkp; long flags; @@ -447,15 +447,9 @@ static void smc91c92_detach(dev_link_t *link) /* Unlink device structure, free bits */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree(dev->priv); - kfree(link->priv); - } - kfree(link); + if (link->dev) + unregister_netdev(&smc->dev); + kfree(smc); } /* smc91c92_detach */ @@ -509,30 +503,29 @@ static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, static int mhz_3288_power(dev_link_t *link) { - struct net_device *dev = link->priv; - struct smc_private *lp = dev->priv; + struct smc_private *smc = link->priv; u_char tmp; /* Read the ISR twice... */ - readb(lp->base+MEGAHERTZ_ISR); + readb(smc->base+MEGAHERTZ_ISR); udelay(5); - readb(lp->base+MEGAHERTZ_ISR); + readb(smc->base+MEGAHERTZ_ISR); /* Pause 200ms... */ mdelay(200); /* Now read and write the COR... */ - tmp = readb(lp->base + link->conf.ConfigBase + CISREG_COR); + tmp = readb(smc->base + link->conf.ConfigBase + CISREG_COR); udelay(5); - writeb(tmp, lp->base + link->conf.ConfigBase + CISREG_COR); + writeb(tmp, smc->base + link->conf.ConfigBase + CISREG_COR); return 0; } static int mhz_mfc_config(dev_link_t *link) { - struct net_device *dev = link->priv; - struct smc_private *lp = dev->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; tuple_t tuple; cisparse_t parse; u_char buf[255]; @@ -545,6 +538,7 @@ static int mhz_mfc_config(dev_link_t *link) link->conf.Status = CCSR_AUDIO_ENA; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; + link->io.IOAddrLines = 16; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; @@ -581,15 +575,15 @@ static int mhz_mfc_config(dev_link_t *link) i = CardServices(RequestWindow, &link->win, &req); if (i != CS_SUCCESS) return i; - lp->base = ioremap(req.Base, 0x1000); + smc->base = ioremap(req.Base, 0x1000); mem.CardOffset = mem.Page = 0; - if (lp->manfid == MANFID_MOTOROLA) + if (smc->manfid == MANFID_MOTOROLA) mem.CardOffset = link->conf.ConfigBase; i = CardServices(MapMemPage, link->win, &mem); if ((i == CS_SUCCESS) - && (lp->manfid == MANFID_MEGAHERTZ) - && (lp->cardid == PRODID_MEGAHERTZ_EM3288)) + && (smc->manfid == MANFID_MEGAHERTZ) + && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) mhz_3288_power(link); return i; @@ -598,7 +592,8 @@ static int mhz_mfc_config(dev_link_t *link) static int mhz_setup(dev_link_t *link) { client_handle_t handle = link->handle; - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; tuple_t tuple; cisparse_t parse; u_char buf[255], *station_addr; @@ -645,27 +640,28 @@ static int mhz_setup(dev_link_t *link) static void mot_config(dev_link_t *link) { - struct net_device *dev = link->priv; - struct smc_private *lp = dev->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; ioaddr_t ioaddr = dev->base_addr; ioaddr_t iouart = link->io.BasePort2; /* Set UART base address and force map with COR bit 1 */ - writeb(iouart & 0xff, lp->base + MOT_UART + CISREG_IOBASE_0); - writeb((iouart >> 8) & 0xff, lp->base + MOT_UART + CISREG_IOBASE_1); - writeb(MOT_NORMAL, lp->base + MOT_UART + CISREG_COR); + writeb(iouart & 0xff, smc->base + MOT_UART + CISREG_IOBASE_0); + writeb((iouart >> 8) & 0xff, smc->base + MOT_UART + CISREG_IOBASE_1); + writeb(MOT_NORMAL, smc->base + MOT_UART + CISREG_COR); /* Set SMC base address and force map with COR bit 1 */ - writeb(ioaddr & 0xff, lp->base + MOT_LAN + CISREG_IOBASE_0); - writeb((ioaddr >> 8) & 0xff, lp->base + MOT_LAN + CISREG_IOBASE_1); - writeb(MOT_NORMAL, lp->base + MOT_LAN + CISREG_COR); + writeb(ioaddr & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_0); + writeb((ioaddr >> 8) & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_1); + writeb(MOT_NORMAL, smc->base + MOT_LAN + CISREG_COR); /* Wait for things to settle down */ mdelay(100); } static int mot_setup(dev_link_t *link) { - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; ioaddr_t ioaddr = dev->base_addr; int i, wait, loop; unsigned int addr; @@ -699,7 +695,8 @@ static int mot_setup(dev_link_t *link) { static int smc_config(dev_link_t *link) { - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; tuple_t tuple; cisparse_t parse; u_char buf[255]; @@ -731,7 +728,8 @@ static int smc_config(dev_link_t *link) static int smc_setup(dev_link_t *link) { client_handle_t handle = link->handle; - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; tuple_t tuple; cisparse_t parse; cistpl_lan_node_id_t *node_id; @@ -774,7 +772,8 @@ static int smc_setup(dev_link_t *link) static int osi_config(dev_link_t *link) { - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; int i, j; @@ -808,7 +807,8 @@ static int osi_config(dev_link_t *link) static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) { client_handle_t handle = link->handle; - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; tuple_t tuple; u_char buf[255]; int i; @@ -862,7 +862,8 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) static int check_sig(dev_link_t *link) { - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; ioaddr_t ioaddr = dev->base_addr; int width; u_short s; @@ -920,8 +921,8 @@ if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; } static void smc91c92_config(dev_link_t *link) { client_handle_t handle = link->handle; - struct net_device *dev = link->priv; - struct smc_private *lp = dev->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; tuple_t tuple; cisparse_t parse; u_short buf[32]; @@ -943,19 +944,19 @@ static void smc91c92_config(dev_link_t *link) tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { - lp->manfid = parse.manfid.manf; - lp->cardid = parse.manfid.card; + smc->manfid = parse.manfid.manf; + smc->cardid = parse.manfid.card; } /* Configure card */ link->state |= DEV_CONFIG; - if (lp->manfid == MANFID_OSITECH) { + if (smc->manfid == MANFID_OSITECH) { i = osi_config(link); - } else if (lp->manfid == MANFID_MOTOROLA - || ((lp->manfid == MANFID_MEGAHERTZ) - && ((lp->cardid == PRODID_MEGAHERTZ_VARIOUS) - || (lp->cardid == PRODID_MEGAHERTZ_EM3288)))) { + } else if (smc->manfid == MANFID_MOTOROLA + || ((smc->manfid == MANFID_MEGAHERTZ) + && ((smc->cardid == PRODID_MEGAHERTZ_VARIOUS) + || (smc->cardid == PRODID_MEGAHERTZ_EM3288)))) { i = mhz_mfc_config(link); } else { i = smc_config(link); @@ -967,7 +968,7 @@ static void smc91c92_config(dev_link_t *link) i = CardServices(RequestConfiguration, link->handle, &link->conf); CS_EXIT_TEST(i, RequestConfiguration, config_failed); - if (lp->manfid == MANFID_MOTOROLA) + if (smc->manfid == MANFID_MOTOROLA) mot_config(link); dev->irq = link->irq.AssignedIRQ; @@ -983,10 +984,10 @@ static void smc91c92_config(dev_link_t *link) goto config_undo; } - switch (lp->manfid) { + switch (smc->manfid) { case MANFID_OSITECH: case MANFID_PSION: - i = osi_setup(link, lp->manfid, lp->cardid); break; + i = osi_setup(link, smc->manfid, smc->cardid); break; case MANFID_SMC: case MANFID_NEW_MEDIA: i = smc_setup(link); break; @@ -1004,7 +1005,7 @@ static void smc91c92_config(dev_link_t *link) goto config_undo; } - link->dev = &lp->node; + link->dev = &smc->node; link->state &= ~DEV_CONFIG_PENDING; rev = check_sig(link); @@ -1060,13 +1061,13 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */ static void smc91c92_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; DEBUG(0, "smc91c92_release(0x%p)\n", link); if (link->open) { DEBUG(1, "smc91c92_cs: release postponed, '%s' still open\n", - dev->name); + link->dev->dev_name); link->state |= DEV_STALE_CONFIG; return; } @@ -1075,8 +1076,7 @@ static void smc91c92_release(u_long arg) CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseIRQ, link->handle, &link->irq); if (link->win) { - struct smc_private *lp = dev->priv; - iounmap(lp->base); + iounmap(smc->base); CardServices(ReleaseWindow, link->win); } @@ -1097,7 +1097,8 @@ static int smc91c92_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; + struct smc_private *smc = link->priv; + struct net_device *dev = &smc->dev; DEBUG(1, "smc91c92_event(0x%06x)\n", event); @@ -1132,15 +1133,14 @@ static int smc91c92_event(event_t event, int priority, /* Fall through... */ case CS_EVENT_CARD_RESET: if (link->state & DEV_CONFIG) { - struct smc_private *lp = dev->priv; - if ((lp->manfid == MANFID_MEGAHERTZ) && - (lp->cardid == PRODID_MEGAHERTZ_EM3288)) + if ((smc->manfid == MANFID_MEGAHERTZ) && + (smc->cardid == PRODID_MEGAHERTZ_EM3288)) mhz_3288_power(link); CardServices(RequestConfiguration, link->handle, &link->conf); - if (lp->manfid == MANFID_MOTOROLA) + if (smc->manfid == MANFID_MOTOROLA) mot_config(link); - if ((lp->manfid == MANFID_OSITECH) && - (lp->cardid != PRODID_OSITECH_SEVEN)) { + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) { /* Power up the card and enable interrupts */ set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); @@ -1181,8 +1181,8 @@ static void smc_dump(struct net_device *dev) static int smc91c92_open(struct net_device *dev) { - struct smc_private *lp = (struct smc_private *)dev->priv; - dev_link_t *link; + struct smc_private *smc = dev->priv; + dev_link_t *link = &smc->link; #ifdef PCMCIA_DEBUG DEBUG(0, "%s: smc91c92_open(%p), ID/Window %4.4x.\n", @@ -1191,11 +1191,9 @@ static int smc91c92_open(struct net_device *dev) #endif /* Check that the PCMCIA card is still here. */ - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - /* Physical device present signature. */ if (!DEV_OK(link)) return -ENODEV; + /* Physical device present signature. */ if (check_sig(link) < 0) { printk("smc91c92_cs: Yikes! Bad chip signature!\n"); return -ENODEV; @@ -1204,14 +1202,14 @@ static int smc91c92_open(struct net_device *dev) MOD_INC_USE_COUNT; dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; - lp->saved_skb = 0; - lp->packets_waiting = 0; + smc->saved_skb = 0; + smc->packets_waiting = 0; smc_reset(dev); - lp->media.function = &media_check; - lp->media.data = (u_long)dev; - lp->media.expires = jiffies + HZ; - add_timer(&lp->media); + smc->media.function = &media_check; + smc->media.data = (u_long)smc; + smc->media.expires = jiffies + HZ; + add_timer(&smc->media); return 0; } /* smc91c92_open */ @@ -1220,8 +1218,9 @@ static int smc91c92_open(struct net_device *dev) static int smc91c92_close(struct net_device *dev) { + struct smc_private *smc = dev->priv; + dev_link_t *link = &smc->link; ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; DEBUG(0, "%s: smc91c92_close(), status %4.4x.\n", dev->name, inw(ioaddr + BANK_SELECT)); @@ -1241,13 +1240,8 @@ static int smc91c92_close(struct net_device *dev) SMC_SELECT_BANK( 1 ); outw(CTL_POWERDOWN, ioaddr + CONTROL ); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) break; - if (link == NULL) - return -ENODEV; - link->open--; dev->start = 0; - del_timer(&((struct smc_private *)dev->priv)->media); + del_timer(&smc->media); if (link->state & DEV_STALE_CONFIG) { link->release.expires = jiffies + HZ/20; link->state |= DEV_RELEASE_PENDING; @@ -1269,8 +1263,8 @@ static int smc91c92_close(struct net_device *dev) static void smc_hardware_send_packet( struct net_device * dev ) { - struct smc_private *lp = (struct smc_private *)dev->priv; - struct sk_buff *skb = lp->saved_skb; + struct smc_private *smc = dev->priv; + struct sk_buff *skb = smc->saved_skb; ioaddr_t ioaddr = dev->base_addr; unsigned char packet_no; @@ -1286,12 +1280,12 @@ static void smc_hardware_send_packet( struct net_device * dev ) printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation" " failed, status %#2.2x.\n", dev->name, packet_no); dev_kfree_skb (skb); - lp->saved_skb = NULL; + smc->saved_skb = NULL; dev->tbusy = 0; return; } - lp->stats.tx_bytes += skb->len; + smc->stats.tx_bytes += skb->len; /* The card should use the just-allocated buffer. */ outw( packet_no, ioaddr + PNR_ARR ); /* point to the beginning of the packet */ @@ -1332,7 +1326,7 @@ static void smc_hardware_send_packet( struct net_device * dev ) /* The chip does the rest of the work. */ outw( MC_ENQUEUE , ioaddr + MMU_CMD ); - lp->saved_skb = NULL; + smc->saved_skb = NULL; dev_kfree_skb (skb); dev->trans_start = jiffies; dev->tbusy = 0; @@ -1343,7 +1337,7 @@ static void smc_hardware_send_packet( struct net_device * dev ) static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct smc_private *lp = (struct smc_private *)dev->priv; + struct smc_private *smc = dev->priv; ioaddr_t ioaddr = dev->base_addr; unsigned short num_pages; short time_out, ir; @@ -1356,11 +1350,11 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, " "Tx_status %2.2x status %4.4x.\n", dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2)); - lp->stats.tx_errors++; + smc->stats.tx_errors++; smc_reset(dev); dev->trans_start = jiffies; dev->tbusy = 0; - lp->saved_skb = NULL; + smc->saved_skb = NULL; } DEBUG(2, "%s: smc91c92_start_xmit(length = %d) called," @@ -1372,26 +1366,26 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) return 1; } - if ( lp->saved_skb) { + if ( smc->saved_skb) { /* THIS SHOULD NEVER HAPPEN. */ - lp->stats.tx_aborted_errors++; + smc->stats.tx_aborted_errors++; printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n", dev->name); return 1; } - lp->saved_skb = skb; + smc->saved_skb = skb; num_pages = skb->len >> 8; if (num_pages > 7) { printk(KERN_ERR "%s: Far too big packet error.\n", dev->name); dev_kfree_skb (skb); - lp->saved_skb = NULL; - lp->stats.tx_dropped++; + smc->saved_skb = NULL; + smc->stats.tx_dropped++; return 0; /* Do not re-queue this packet. */ } /* A packet is now waiting. */ - lp->packets_waiting++; + smc->packets_waiting++; SMC_SELECT_BANK( 2 ); /* Paranoia, we should always be in window 2 */ @@ -1422,7 +1416,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) static void smc_tx_err( struct net_device * dev ) { - struct smc_private *lp = (struct smc_private *)dev->priv; + struct smc_private *smc = (struct smc_private *)dev->priv; ioaddr_t ioaddr = dev->base_addr; int saved_packet = inw(ioaddr + PNR_ARR) & 0xff; int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f; @@ -1436,12 +1430,12 @@ static void smc_tx_err( struct net_device * dev ) tx_status = inw(ioaddr + DATA_1); - lp->stats.tx_errors++; - if (tx_status & TS_LOSTCAR) lp->stats.tx_carrier_errors++; - if (tx_status & TS_LATCOL) lp->stats.tx_window_errors++; + smc->stats.tx_errors++; + if (tx_status & TS_LOSTCAR) smc->stats.tx_carrier_errors++; + if (tx_status & TS_LATCOL) smc->stats.tx_window_errors++; if (tx_status & TS_16COL) { - lp->stats.tx_aborted_errors++; - lp->tx_err++; + smc->stats.tx_aborted_errors++; + smc->tx_err++; } if ( tx_status & TS_SUCCESS ) { @@ -1456,7 +1450,7 @@ static void smc_tx_err( struct net_device * dev ) outw( MC_FREEPKT, ioaddr + MMU_CMD ); /* Free the packet memory. */ /* one less packet waiting for me */ - lp->packets_waiting--; + smc->packets_waiting--; outw( saved_packet, ioaddr + PNR_ARR ); return; @@ -1466,7 +1460,7 @@ static void smc_tx_err( struct net_device * dev ) static void smc_eph_irq(struct net_device *dev) { - struct smc_private *lp = dev->priv; + struct smc_private *smc = dev->priv; ioaddr_t ioaddr = dev->base_addr; unsigned short card_stats, ephs; @@ -1477,10 +1471,10 @@ static void smc_eph_irq(struct net_device *dev) /* Could be a counter roll-over warning: update stats. */ card_stats = inw( ioaddr + COUNTER ); /* single collisions */ - lp->stats.collisions += card_stats & 0xF; + smc->stats.collisions += card_stats & 0xF; card_stats >>= 4; /* multiple collisions */ - lp->stats.collisions += card_stats & 0xF; + smc->stats.collisions += card_stats & 0xF; #if 0 /* These are for when linux supports these statistics */ card_stats >>= 4; /* deferred */ card_stats >>= 4; /* excess deferred */ @@ -1500,13 +1494,13 @@ static void smc_eph_irq(struct net_device *dev) static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct net_device *dev = dev_id; - struct smc_private *lp; + struct smc_private *smc = dev_id; + struct net_device *dev = &smc->dev; ioaddr_t ioaddr; u_short saved_bank, saved_pointer, mask, status; char bogus_cnt = INTR_WORK; /* Work we are willing to do. */ - if ((dev == NULL) || !dev->start) + if ((smc == NULL) || !dev->start) return; ioaddr = dev->base_addr; @@ -1522,8 +1516,7 @@ static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) irq, ioaddr); #endif - lp = (struct smc_private *)dev->priv; - lp->watchdog = 0; + smc->watchdog = 0; saved_bank = inw(ioaddr + BANK_SELECT); if ((saved_bank & 0xff00) != 0x3300) { /* The device does not exist -- the card could be off-line, or @@ -1553,7 +1546,7 @@ static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status & IM_RCV_INT) { /* Got a packet(s). */ smc_rx(dev); - lp->last_rx = jiffies; + smc->last_rx = jiffies; } if (status & IM_TX_INT) { smc_tx_err(dev); @@ -1563,8 +1556,8 @@ static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status & IM_TX_EMPTY_INT) { outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT); mask &= ~IM_TX_EMPTY_INT; - lp->stats.tx_packets += lp->packets_waiting; - lp->packets_waiting = 0; + smc->stats.tx_packets += smc->packets_waiting; + smc->packets_waiting = 0; } if (status & IM_ALLOC_INT) { /* Clear this interrupt so it doesn't happen again */ @@ -1579,8 +1572,8 @@ static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) mark_bh( NET_BH ); } if (status & IM_RX_OVRN_INT) { - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + smc->stats.rx_errors++; + smc->stats.rx_fifo_errors++; outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT); } if (status & IM_EPH_INT) @@ -1602,25 +1595,25 @@ static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) irq_done: - if ((lp->manfid == MANFID_OSITECH) && - (lp->cardid != PRODID_OSITECH_SEVEN)) { + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) { /* Retrigger interrupt if needed */ mask_bits(0x00ff, ioaddr-0x10+OSITECH_RESET_ISR); set_bits(0x0300, ioaddr-0x10+OSITECH_RESET_ISR); } - if (lp->manfid == MANFID_MOTOROLA) { + if (smc->manfid == MANFID_MOTOROLA) { u_char cor; - cor = readb(lp->base + MOT_UART + CISREG_COR); - writeb(cor & ~COR_IREQ_ENA, lp->base + MOT_UART + CISREG_COR); - writeb(cor, lp->base + MOT_UART + CISREG_COR); - cor = readb(lp->base + MOT_LAN + CISREG_COR); - writeb(cor & ~COR_IREQ_ENA, lp->base + MOT_LAN + CISREG_COR); - writeb(cor, lp->base + MOT_LAN + CISREG_COR); + cor = readb(smc->base + MOT_UART + CISREG_COR); + writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_UART + CISREG_COR); + writeb(cor, smc->base + MOT_UART + CISREG_COR); + cor = readb(smc->base + MOT_LAN + CISREG_COR); + writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR); + writeb(cor, smc->base + MOT_LAN + CISREG_COR); } #ifdef DOES_NOT_WORK - if (lp->base != NULL) { /* Megahertz MFC's */ - readb(lp->base+MEGAHERTZ_ISR); - readb(lp->base+MEGAHERTZ_ISR); + if (smc->base != NULL) { /* Megahertz MFC's */ + readb(smc->base+MEGAHERTZ_ISR); + readb(smc->base+MEGAHERTZ_ISR); } #endif } @@ -1629,7 +1622,7 @@ irq_done: static void smc_rx(struct net_device *dev) { - struct smc_private *lp = (struct smc_private *)dev->priv; + struct smc_private *smc = (struct smc_private *)dev->priv; ioaddr_t ioaddr = dev->base_addr; int rx_status; int packet_length; /* Caution: not frame length, rather words @@ -1660,7 +1653,7 @@ static void smc_rx(struct net_device *dev) if ( skb == NULL ) { DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name); - lp->stats.rx_dropped++; + smc->stats.rx_dropped++; outw( MC_RELEASE, ioaddr + MMU_CMD ); return; } @@ -1673,18 +1666,18 @@ static void smc_rx(struct net_device *dev) skb->dev = dev; netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += skb->len; + smc->stats.rx_packets++; + smc->stats.rx_bytes += skb->len; if (rx_status & RS_MULTICAST) - lp->stats.multicast++; + smc->stats.multicast++; } else { /* error ... */ - lp->stats.rx_errors++; + smc->stats.rx_errors++; - if (rx_status & RS_ALGNERR) lp->stats.rx_frame_errors++; + if (rx_status & RS_ALGNERR) smc->stats.rx_frame_errors++; if (rx_status & (RS_TOOSHORT | RS_TOOLONG)) - lp->stats.rx_length_errors++; - if (rx_status & RS_BADCRC) lp->stats.rx_crc_errors++; + smc->stats.rx_length_errors++; + if (rx_status & RS_BADCRC) smc->stats.rx_crc_errors++; } /* Let the MMU free the memory of this packet. */ outw(MC_RELEASE, ioaddr + MMU_CMD); @@ -1696,9 +1689,9 @@ static void smc_rx(struct net_device *dev) static struct net_device_stats *smc91c92_get_stats(struct net_device *dev) { - struct smc_private *lp = (struct smc_private *)dev->priv; + struct smc_private *smc = (struct smc_private *)dev->priv; /* Nothing to update - the 91c92 is a pretty primative chip. */ - return &lp->stats; + return &smc->stats; } /*====================================================================== @@ -1801,9 +1794,9 @@ static void set_rx_mode(struct net_device *dev) static int s9k_config(struct net_device *dev, struct ifmap *map) { - struct smc_private *lp = dev->priv; + struct smc_private *smc = dev->priv; if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { - if (lp->cfg & CFG_MII_SELECT) + if (smc->cfg & CFG_MII_SELECT) return -EOPNOTSUPP; else if (map->port > 2) return -EINVAL; @@ -1827,24 +1820,24 @@ static int s9k_config(struct net_device *dev, struct ifmap *map) */ static void smc_set_xcvr(struct net_device *dev, int if_port) { - struct smc_private *lp = (struct smc_private *)dev->priv; + struct smc_private *smc = (struct smc_private *)dev->priv; ioaddr_t ioaddr = dev->base_addr; u_short saved_bank; saved_bank = inw(ioaddr + BANK_SELECT); SMC_SELECT_BANK(1); if (if_port == 2) { - outw(lp->cfg | CFG_AUI_SELECT, ioaddr + CONFIG); - if ((lp->manfid == MANFID_OSITECH) && - (lp->cardid != PRODID_OSITECH_SEVEN)) + outw(smc->cfg | CFG_AUI_SELECT, ioaddr + CONFIG); + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) set_bits(OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR); - lp->media_status = ((dev->if_port == 0) ? 0x0001 : 0x0002); + smc->media_status = ((dev->if_port == 0) ? 0x0001 : 0x0002); } else { - outw(lp->cfg, ioaddr + CONFIG); - if ((lp->manfid == MANFID_OSITECH) && - (lp->cardid != PRODID_OSITECH_SEVEN)) + outw(smc->cfg, ioaddr + CONFIG); + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) mask_bits(~OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR); - lp->media_status = ((dev->if_port == 0) ? 0x0012 : 0x4001); + smc->media_status = ((dev->if_port == 0) ? 0x0012 : 0x4001); } SMC_SELECT_BANK(saved_bank); } @@ -1852,7 +1845,7 @@ static void smc_set_xcvr(struct net_device *dev, int if_port) static void smc_reset(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - struct smc_private *lp = dev->priv; + struct smc_private *smc = dev->priv; int i; DEBUG(0, "%s: smc91c92 reset called.\n", dev->name); @@ -1875,12 +1868,12 @@ static void smc_reset(struct net_device *dev) Accept link errors, counter and Tx error interrupts. */ outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE, ioaddr + CONTROL); - lp->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT; - lp->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC | - (lp->manfid == MANFID_OSITECH ? (CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0) : 0); + smc->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT; + smc->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC | + (smc->manfid == MANFID_OSITECH ? (CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0) : 0); smc_set_xcvr(dev, dev->if_port); - if ((lp->manfid == MANFID_OSITECH) && - (lp->cardid != PRODID_OSITECH_SEVEN)) + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) outw((dev->if_port == 2 ? OSI_AUI_PWR : 0) | (inw(ioaddr-0x10+OSITECH_AUI_PWR) & 0xff00), ioaddr - 0x10 + OSITECH_AUI_PWR); @@ -1897,7 +1890,7 @@ static void smc_reset(struct net_device *dev) /* Re-enable the chip. */ SMC_SELECT_BANK(0); - outw(((lp->cfg & CFG_MII_SELECT) ? 0 : TCR_MONCSN) | + outw(((smc->cfg & CFG_MII_SELECT) ? 0 : TCR_MONCSN) | TCR_ENABLE | TCR_PAD_EN, ioaddr + TCR); set_rx_mode(dev); @@ -1915,14 +1908,13 @@ static void smc_reset(struct net_device *dev) static void media_check(u_long arg) { - struct net_device *dev = (struct net_device *)(arg); - struct smc_private *lp = (struct smc_private *)dev->priv; + struct smc_private *smc = (struct smc_private *)(arg); + struct net_device *dev = &smc->dev; ioaddr_t ioaddr = dev->base_addr; u_short i, media, saved_bank; if (dev->start == 0) goto reschedule; - lp = (struct smc_private *)dev->priv; saved_bank = inw(ioaddr + BANK_SELECT); SMC_SELECT_BANK(2); i = inw(ioaddr + INTERRUPT); @@ -1934,36 +1926,36 @@ static void media_check(u_long arg) /* Check for pending interrupt with watchdog flag set: with this, we can limp along even if the interrupt is blocked */ - if (lp->watchdog++ && ((i>>8) & i)) { - if (!lp->fast_poll) + if (smc->watchdog++ && ((i>>8) & i)) { + if (!smc->fast_poll) printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); - smc_interrupt(dev->irq, dev, NULL); - lp->fast_poll = HZ; + smc_interrupt(dev->irq, smc, NULL); + smc->fast_poll = HZ; } - if (lp->fast_poll) { - lp->fast_poll--; - lp->media.expires = jiffies + 1; - add_timer(&lp->media); + if (smc->fast_poll) { + smc->fast_poll--; + smc->media.expires = jiffies + 1; + add_timer(&smc->media); return; } - if (lp->cfg & CFG_MII_SELECT) + if (smc->cfg & CFG_MII_SELECT) goto reschedule; /* Ignore collisions unless we've had no rx's recently */ - if (jiffies - lp->last_rx > HZ) { - if (lp->tx_err || (lp->media_status & EPH_16COL)) + if (jiffies - smc->last_rx > HZ) { + if (smc->tx_err || (smc->media_status & EPH_16COL)) media |= EPH_16COL; } - lp->tx_err = 0; + smc->tx_err = 0; - if (media != lp->media_status) { - if ((media & lp->media_status & 1) && - ((lp->media_status ^ media) & EPH_LINK_OK)) + if (media != smc->media_status) { + if ((media & smc->media_status & 1) && + ((smc->media_status ^ media) & EPH_LINK_OK)) printk(KERN_INFO "%s: %s link beat\n", dev->name, - (lp->media_status & EPH_LINK_OK ? "lost" : "found")); - else if ((media & lp->media_status & 2) && - ((lp->media_status ^ media) & EPH_16COL)) + (smc->media_status & EPH_LINK_OK ? "lost" : "found")); + else if ((media & smc->media_status & 2) && + ((smc->media_status ^ media) & EPH_16COL)) printk(KERN_INFO "%s: coax cable %s\n", dev->name, (media & EPH_16COL ? "problem" : "ok")); if (dev->if_port == 0) { @@ -1981,12 +1973,12 @@ static void media_check(u_long arg) dev->name); } } - lp->media_status = media; + smc->media_status = media; } reschedule: - lp->media.expires = jiffies + HZ; - add_timer(&lp->media); + smc->media.expires = jiffies + HZ; + add_timer(&smc->media); } /*====================================================================*/ diff --git a/drivers/net/pcmcia/tulip_cb.c b/drivers/net/pcmcia/tulip_cb.c index eabffab80..ee49f58eb 100644 --- a/drivers/net/pcmcia/tulip_cb.c +++ b/drivers/net/pcmcia/tulip_cb.c @@ -39,13 +39,6 @@ static const char * const medianame[] = { "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FD", "MII 100baseT4", }; -/* Set if the PCI BIOS detects the chips on a multiport board backwards. */ -#ifdef REVERSE_PROBE_ORDER -static int reverse_probe = 1; -#else -static int reverse_probe = 0; -#endif - /* Keep the ring sizes a power of two for efficiency. Making the Tx ring too large decreases the effectiveness of channel bonding and packet priority. @@ -126,6 +119,7 @@ static int csr0 = 0x00A00000 | 0x4800; #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/delay.h> +#include <linux/init.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/bitops.h> #include <asm/io.h> @@ -262,58 +256,6 @@ them. The MII transceiver status is polled using an kernel timer. */ -static struct net_device * -tulip_probe1(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, - int irq, int chip_idx, int board_idx); - -/* This table drives the PCI probe routines. It's mostly boilerplate in all - of the drivers, and will likely be provided by some future kernel. - Note the matching code -- the first table entry matchs all 56** cards but - second only the 1234 card. -*/ -enum pci_flags_bit { - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, -}; -#define PCI_ADDR0_IO (PCI_USES_IO|PCI_ADDR0) - -struct pci_id_info { - const char *name; - u16 vendor_id, device_id, device_id_mask, flags; - int io_size, min_latency; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); -}; -#ifndef CARDBUS -static struct pci_id_info pci_tbl[] = { - { "Digital DC21040 Tulip", - 0x1011, 0x0002, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, - { "Digital DC21041 Tulip", - 0x1011, 0x0014, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, - { "Digital DS21140 Tulip", - 0x1011, 0x0009, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, - { "Digital DS21143 Tulip", - 0x1011, 0x0019, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, - { "Lite-On 82c168 PNIC", - 0x11AD, 0x0002, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, - { "Macronix 98713 PMAC", - 0x10d9, 0x0512, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, - { "Macronix 98715 PMAC", - 0x10d9, 0x0531, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, - { "Macronix 98725 PMAC", - 0x10d9, 0x0531, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, - { "ASIX AX88140", - 0x125B, 0x1400, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, - { "Lite-On LC82C115 PNIC-II", - 0x11AD, 0xc115, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, - { "ADMtek AN981 Comet", - 0x1317, 0x0981, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, - { "Compex RL100-TX", - 0x11F6, 0x9881, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, - {0}, -}; -#endif /* !CARD_BUS */ - /* This table use during operation for capabilities and media timer. */ static void tulip_timer(unsigned long data); @@ -456,7 +398,6 @@ struct mediainfo { struct tulip_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct net_device *next_module; struct tulip_rx_desc rx_ring[RX_RING_SIZE]; struct tulip_tx_desc tx_ring[TX_RING_SIZE]; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ @@ -574,107 +515,6 @@ static void outl_CSR6 (u32 newcsr6, long ioaddr, int chip_idx) restore_flags(flags); } -/* A list of all installed Tulip devices. */ -static struct net_device *root_tulip_dev = NULL; - -#ifndef CARDBUS -int tulip_probe(struct net_device *dev) -{ - int cards_found = 0; - int pci_index = 0; - unsigned char pci_bus, pci_device_fn; - - if ( ! pcibios_present()) - return -ENODEV; - - for (;pci_index < 0xff; pci_index++) { - u16 vendor, device, pci_command, new_command; - int chip_idx; - int irq; - long ioaddr; - - if (pcibios_find_class - (PCI_CLASS_NETWORK_ETHERNET << 8, - reverse_probe ? 0xfe - pci_index : pci_index, - &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL) { - if (reverse_probe) - continue; - else - break; - } - pcibios_read_config_word(pci_bus, pci_device_fn, - PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(pci_bus, pci_device_fn, - PCI_DEVICE_ID, &device); - - for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++) - if (vendor == pci_tbl[chip_idx].vendor_id - && (device & pci_tbl[chip_idx].device_id_mask) == - pci_tbl[chip_idx].device_id) - break; - if (pci_tbl[chip_idx].vendor_id == 0) - continue; - - { -#if defined(PCI_SUPPORT_VER2) - struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->base_address[0] & ~3; - irq = pdev->irq; -#elif defined(PCI_SUPPORT_VER3) - struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->resource[0].start; - irq = pdev->irq; -#else - u32 pci_ioaddr; - u8 pci_irq_line; - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - ioaddr = pci_ioaddr & ~3; - irq = pci_irq_line; -#endif - } - - if (debug > 2) - printk(KERN_INFO "Found %s at PCI I/O address %#lx.\n", - pci_tbl[chip_idx].name, ioaddr); - - pcibios_read_config_word(pci_bus, pci_device_fn, - PCI_COMMAND, &pci_command); - new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO; - if (pci_command != new_command) { - printk(KERN_INFO " The PCI BIOS has not enabled the" - " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n", - pci_bus, pci_device_fn, pci_command, new_command); - pcibios_write_config_word(pci_bus, pci_device_fn, - PCI_COMMAND, new_command); - } - - dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr, - irq, chip_idx, cards_found); - - /* Get and check the bus-master and latency values. */ - if (dev) { - u8 pci_latency; - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency < 10) { - printk(KERN_INFO " PCI latency timer (CFLT) is " - "unreasonably low at %d. Setting to 64 clocks.\n", - pci_latency); - pcibios_write_config_byte(pci_bus, pci_device_fn, - PCI_LATENCY_TIMER, 64); - } - } - dev = 0; - cards_found++; - } - - return cards_found ? 0 : -ENODEV; -} -#endif /* not CARDBUS */ - static struct net_device *tulip_probe1(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int board_idx) @@ -851,9 +691,6 @@ static struct net_device *tulip_probe1(int pci_bus, int pci_devfn, memset(tp, 0, sizeof(*tp)); dev->priv = tp; - tp->next_module = root_tulip_dev; - root_tulip_dev = dev; - tp->pci_bus = pci_bus; tp->pci_devfn = pci_devfn; tp->chip_id = chip_idx; @@ -2641,7 +2478,7 @@ static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) if (test_and_set_bit(0, (void*)&dev->interrupt)) { printk(KERN_ERR "%s: Duplicate entry of the interrupt handler by " "processor %d.\n", - dev->name, hard_smp_processor_id()); + dev->name, smp_processor_id()); dev->interrupt = 0; return; } @@ -3251,127 +3088,93 @@ static void set_rx_mode(struct net_device *dev) outl_CSR6(csr6 | 0x0000, ioaddr, tp->chip_id); } -#ifdef CARDBUS +static const struct pci_device_id tulip_pci_table[] __devinitdata = { + { 0x1011, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21040 }, + { 0x1011, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21041 }, + { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 }, + { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21142 }, + { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 }, + { 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 }, + { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, + { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 }, + { 0x125B, 0x1400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AX88140 }, + { 0x11AD, 0xc115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PNIC2 }, + { 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, + { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, + { 0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, X3201_3 }, + {0}, +}; -#include <pcmcia/driver_ops.h> +MODULE_DEVICE_TABLE(pci, tulip_pci_table); -static dev_node_t *tulip_attach(dev_locator_t *loc) +static int __devinit tulip_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct net_device *dev; - u16 dev_id; - u16 vendor_id; - u32 io; - u8 bus, devfn, irq; - - if (loc->bus != LOC_PCI) return NULL; - bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; - printk(KERN_INFO "tulip_attach(bus %d, function %d)\n", bus, devfn); - pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io); - pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id); - pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq); - pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor_id); - if (dev_id == 0x0003 && vendor_id == 0x115d) - dev = tulip_probe1(bus, devfn, NULL, io & ~3, irq, X3201_3, 0); - else - dev = tulip_probe1(bus, devfn, NULL, io & ~3, irq, DC21142, 0); + static int board_idx = 0; + + printk(KERN_INFO "tulip_attach(%s)\n", pdev->slot_name); + + pci_set_master(pdev); + dev = tulip_probe1(pdev->bus->number, pdev->devfn, NULL, + pdev->resource[0].start, pdev->irq, + id->driver_data, board_idx++); if (dev) { - dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); - strcpy(node->dev_name, dev->name); - node->major = node->minor = 0; - node->next = NULL; - MOD_INC_USE_COUNT; - return node; + pdev->driver_data = dev; + return 0; } - return NULL; + return -ENODEV; } -static void tulip_suspend(dev_node_t *node) +static void tulip_suspend(struct pci_dev *pdev) { - struct net_device *dev, *next; - printk(KERN_INFO "tulip_suspend(%s)\n", node->dev_name); - for (dev = root_tulip_dev; dev; dev = next) { - next = ((struct tulip_private *)dev->priv)->next_module; - if (strcmp(dev->name, node->dev_name) == 0) break; - } - if (dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; - if (tp->open) tulip_down(dev); - } + struct net_device *dev = pdev->driver_data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + printk(KERN_INFO "tulip_suspend(%s)\n", dev->name); + if (tp->open) tulip_down(dev); } -static void tulip_resume(dev_node_t *node) +static void tulip_resume(struct pci_dev *pdev) { - struct net_device *dev, *next; - printk(KERN_INFO "tulip_resume(%s)\n", node->dev_name); - for (dev = root_tulip_dev; dev; dev = next) { - next = ((struct tulip_private *)dev->priv)->next_module; - if (strcmp(dev->name, node->dev_name) == 0) break; - } - if (dev) { - struct tulip_private *tp = (struct tulip_private *)dev->priv; - if (tp->open) tulip_up(dev); - } + struct net_device *dev = pdev->driver_data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + printk(KERN_INFO "tulip_resume(%s)\n", dev->name); + if (tp->open) tulip_up(dev); } -static void tulip_detach(dev_node_t *node) +static void __devexit tulip_remove(struct pci_dev *pdev) { - struct net_device **devp, **next; - printk(KERN_INFO "tulip_detach(%s)\n", node->dev_name); - for (devp = &root_tulip_dev; *devp; devp = next) { - next = &((struct tulip_private *)(*devp)->priv)->next_module; - if (strcmp((*devp)->name, node->dev_name) == 0) break; - } - if (*devp) { - struct net_device *dev = *devp; - struct tulip_private *tp = dev->priv; - *devp = *next; - unregister_netdev(dev); - kfree(dev); - kfree(tp); - kfree(node); - MOD_DEC_USE_COUNT; - } + struct net_device *dev = pdev->driver_data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + + printk(KERN_INFO "tulip_detach(%s)\n", dev->name); + unregister_netdev(dev); + kfree(dev); + kfree(tp); } -struct driver_operations tulip_ops = { - "tulip_cb", tulip_attach, tulip_suspend, tulip_resume, tulip_detach +static struct pci_driver tulip_ops = { + name: "tulip_cb", + id_table: tulip_pci_table, + probe: tulip_pci_probe, + remove: tulip_remove, + suspend: tulip_suspend, + resume: tulip_resume }; -#endif /* Cardbus support */ - -#ifdef MODULE -int init_module(void) +static int __init tulip_init(void) { -#ifdef CARDBUS - reverse_probe = 0; /* Not used. */ - register_driver(&tulip_ops); + pci_register_driver(&tulip_ops); return 0; -#else - return tulip_probe(NULL); -#endif } -void cleanup_module(void) +static __exit void tulip_exit(void) { - struct net_device *next_dev; - -#ifdef CARDBUS - unregister_driver(&tulip_ops); -#endif - - /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ - while (root_tulip_dev) { - struct tulip_private *tp = (struct tulip_private *)root_tulip_dev->priv; - next_dev = tp->next_module; - unregister_netdev(root_tulip_dev); - release_region(root_tulip_dev->base_addr, - tulip_tbl[tp->chip_id].io_size); - kfree(root_tulip_dev); - root_tulip_dev = next_dev; - } + pci_unregister_driver(&tulip_ops); } -#endif /* MODULE */ +module_init(tulip_init) +module_exit(tulip_exit) + /* * Local variables: diff --git a/drivers/net/pcmcia/wavelan_cs.c b/drivers/net/pcmcia/wavelan_cs.c index 5e9c9e6e2..c1c38aa28 100644 --- a/drivers/net/pcmcia/wavelan_cs.c +++ b/drivers/net/pcmcia/wavelan_cs.c @@ -2105,7 +2105,7 @@ wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */ } /* only super-user can see encryption key */ - if(!suser()) + if(!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; @@ -2437,7 +2437,7 @@ wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */ /* ------------------ PRIVATE IOCTL ------------------ */ case SIOCSIPQTHR: - if(!suser()) + if(!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; @@ -2476,7 +2476,7 @@ wavelan_ioctl(struct net_device * dev, /* Device on wich the ioctl apply */ #ifdef HISTOGRAM case SIOCSIPHISTO: /* Verif if the user is root */ - if(!suser()) + if(!capable(CAP_NET_ADMIN)) { ret = -EPERM; } diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 0b9c4bd3a..0c4f72ae7 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -1,37 +1,44 @@ -/* [xirc2ps_cs.c wk 14.04.97] (1.31 1998/12/09 19:32:55) - * Xircom Creditcard Ethernet Adapter IIps driver +/* [xirc2ps_cs.c wk 03.11.99] (1.40 1999/11/18 00:06:03) + * Xircom CreditCard Ethernet Adapter IIps driver + * Xircom Realport 10/100 (RE-100) driver * - * This driver works for the CE2, CEM28, CEM33, CE3 and CEM56 cards. - * The CEM56 has some problems, but it works. - * The CEII card with the 14k4 modem and other old cards do not work. + * This driver originally was made by Werner Koch. Since the driver was left + * unmaintained for some time, there have been some improvements and changes + * since. These include supporting some of the "Realport" cards and develop- + * ing enhancements to support the new ones. + * It is made for CE2, CEM28, CEM33, CE33 and + * CEM56 cards. The CEM56 cards work both with their modem and ethernet + * interface. The RealPort 10/100 Modem and similar cards are supported but + * with some bugs which are being corrected as they are detected. + * + * Code revised and maintained by Allan Baker Ortegon + * al527261@prodigy.net.mx + * Written originally by Werner Koch based on David Hinds' skeleton of the + * PCMCIA driver. The code has been modified as to make the newer cards + * available. * - * Written by Werner Koch (werner.koch@guug.de), - * based on David Hinds skeleton driver. + * The latest code for the driver, information on the development project + * for the Xircom RealPort and CE cards for the PCMCIA driver, and other + * related material, can be found at the following URL, which is underway: + * + * "http://xirc2ps.linuxbox.com/index.html" * - * You can get the latest driver revision from - * "http://www.d.shuttle.de/isil/xircom/xirc2ps.html" + * Any bugs regarding this driver, please send them to: + * alanyuu@linuxbox.com * - * Please report bugs to: "xircom-bugs@isil.d.shuttle.de" - * - * A bug fix for the CEM56 to use modem and ethernet simultaneously - * was provided by Koen Van Herck (Koen.Van.Herck@xircom.com). - * - * If your card locks up you should use the option "lockup_hack=1"; - * this may solve the problem but violates a kernel timing convention - * (Thanks to David Luyer). - * - * Thanks to David Hinds for the PCMCIA package, Donald Becker for some - * advice, Xircom for providing specs and help, 4PC GmbH Duesseldorf for - * providing some hardware and last not least to all folks who helped to - * develop this driver. - * - * For those, who are willing to do alpha testing of drivers, I have setup - * the mailing list "xircom-devel@isil.d.shuttle.de" (To subscribe send a - * message containing the word "subscribe" in the subject or somewhere at - * the beginning of a line to "xircom-devel-request@isil.d.shuttle.de"). + * The driver is still evolving and there are many cards which will benefit + * from having alpha testers. If you have a particular card and would like + * to be involved in this ongoing effort, please send mail to the maintainer. + * + * Special thanks to David Hinds, to Xircom for the specifications and their + * software development kit, and all others who may have colaborated in the + * development of the driver: Koen Van Herck (Koen.Van.Herck@xircom.com), + * 4PC GmbH Duesseldorf, David Luger, et al. + * * ************************************************************************ * Copyright (c) 1997,1998 Werner Koch (dd9jn) + * Copyright (c) 1999 Allan Baker Ortegon * * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -70,7 +77,7 @@ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -388,6 +395,8 @@ static dev_link_t *dev_list = NULL; */ typedef struct local_info_t { + dev_link_t link; + struct net_device dev; dev_node_t node; struct enet_statistics stats; int card_type; @@ -472,14 +481,18 @@ get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse) static void busy_loop(u_long len) { - u_long timeout = jiffies + len; - u_long flags; - - save_flags(flags); - sti(); - while (timeout >= jiffies) - ; - restore_flags(flags); + if (in_interrupt()) { + u_long timeout = jiffies + len; + u_long flags; + save_flags(flags); + sti(); + while (timeout >= jiffies) + ; + restore_flags(flags); + } else { + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(len); + } } /*====== Functions used for debugging =================================*/ @@ -674,9 +687,13 @@ xirc2ps_attach(void) DEBUG(0, "attach()\n"); flush_stale_links(); - /* Initialize the dev_link_t structure */ - link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); - memset(link, 0, sizeof(struct dev_link_t)); + /* Allocate the device structure */ + local = kmalloc(sizeof(*local), GFP_KERNEL); + if (!local) return NULL; + memset(local, 0, sizeof(*local)); + link = &local->link; dev = &local->dev; + link->priv = dev->priv = local; + link->release.function = &xirc2ps_release; link->release.data = (u_long) link; @@ -686,13 +703,8 @@ xirc2ps_attach(void) link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - - /* Allocate space for a device structure */ - dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); - memset(dev, 0, sizeof(struct net_device)); - local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - memset(local, 0, sizeof(local_info_t)); - dev->priv = local; + link->irq.Handler = xirc2ps_interrupt; + link->irq.Instance = dev; /* Fill in card specific entries */ dev->hard_start_xmit = &do_start_xmit; @@ -706,7 +718,6 @@ xirc2ps_attach(void) dev->open = &do_open; dev->stop = &do_stop; dev->tbusy = 1; - link->priv = dev; /* Register with Card Services */ link->next = dev_list; @@ -739,6 +750,7 @@ xirc2ps_attach(void) static void xirc2ps_detach(dev_link_t * link) { + local_info_t *local = link->priv; dev_link_t **linkp; long flags; @@ -778,17 +790,11 @@ xirc2ps_detach(dev_link_t * link) if (link->handle) CardServices(DeregisterClient, link->handle); - /* Unlink device structure, free pieces */ + /* Unlink device structure, free it */ *linkp = link->next; - if (link->priv) { - struct net_device *dev = link->priv; - if (link->dev != NULL) - unregister_netdev(dev); - if (dev->priv) - kfree(dev->priv); - kfree(link->priv); - } - kfree(link); + if (link->dev) + unregister_netdev(&local->dev); + kfree(local); } /* xirc2ps_detach */ @@ -813,8 +819,7 @@ xirc2ps_detach(dev_link_t * link) static int set_card_type(dev_link_t *link, const void *s) { - struct net_device *dev = link->priv; - local_info_t *local = dev->priv; + local_info_t *local = link->priv; #ifdef PCMCIA_DEBUG unsigned cisrev = ((const unsigned char *)s)[2]; #endif @@ -907,20 +912,17 @@ has_ce2_string(dev_link_t * link) static void xirc2ps_config(dev_link_t * link) { - client_handle_t handle; + client_handle_t handle = link->handle; + local_info_t *local = link->priv; + struct net_device *dev = &local->dev; tuple_t tuple; cisparse_t parse; - struct net_device *dev; - local_info_t *local; ioaddr_t ioaddr; int err, i; u_char buf[64]; cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - handle = link->handle; - dev = link->priv; - local = dev->priv; local->dingo_ccr = 0; DEBUG(0, "config(0x%p)\n", link); @@ -1034,8 +1036,6 @@ xirc2ps_config(dev_link_t * link) for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; } - link->irq.Handler = xirc2ps_interrupt; - link->irq.Instance = dev; if (local->modem) { int pass; @@ -1124,7 +1124,7 @@ xirc2ps_config(dev_link_t * link) * the I/O windows and the interrupt mapping. */ if ((err=CardServices(RequestConfiguration, - link->handle, &link->conf))) { + link->handle, &link->conf))) { cs_error(link->handle, RequestConfiguration, err); goto config_error; } @@ -1146,7 +1146,7 @@ xirc2ps_config(dev_link_t * link) reg.Offset = CISREG_IOBASE_0; reg.Value = link->io.BasePort2 & 0xff; if ((err = CardServices(AccessConfigurationRegister, link->handle, - ®))) { + ®))) { cs_error(link->handle, AccessConfigurationRegister, err); goto config_error; } @@ -1154,7 +1154,7 @@ xirc2ps_config(dev_link_t * link) reg.Offset = CISREG_IOBASE_1; reg.Value = (link->io.BasePort2 >> 8) & 0xff; if ((err = CardServices(AccessConfigurationRegister, link->handle, - ®))) { + ®))) { cs_error(link->handle, AccessConfigurationRegister, err); goto config_error; } @@ -1213,20 +1213,19 @@ xirc2ps_config(dev_link_t * link) } #endif - writeb(0x01 , local->dingo_ccr + 0x20); - writeb(0x0c , local->dingo_ccr + 0x22); - writeb(0x00 , local->dingo_ccr + 0x24); - writeb(0x00 , local->dingo_ccr + 0x26); - writeb(0x00 , local->dingo_ccr + 0x28); + writeb(0x01, local->dingo_ccr + 0x20); + writeb(0x0c, local->dingo_ccr + 0x22); + writeb(0x00, local->dingo_ccr + 0x24); + writeb(0x00, local->dingo_ccr + 0x26); + writeb(0x00, local->dingo_ccr + 0x28); } /* The if_port symbol can be set when the module is loaded */ local->probe_port=0; if (!if_port) { - local->probe_port=1; - dev->if_port = 1; - } - else if ((if_port >= 1 && if_port <= 2) || (local->mohawk && if_port==4)) + local->probe_port = dev->if_port = 1; + } else if ((if_port >= 1 && if_port <= 2) || + (local->mohawk && if_port==4)) dev->if_port = if_port; else printk(KNOT_XIRC "invalid if_port requested\n"); @@ -1275,7 +1274,8 @@ static void xirc2ps_release(u_long arg) { dev_link_t *link = (dev_link_t *) arg; - struct net_device *dev = link->priv; + local_info_t *local = link->priv; + struct net_device *dev = &local->dev; DEBUG(0, "release(0x%p)\n", link); @@ -1322,8 +1322,8 @@ xirc2ps_event(event_t event, int priority, event_callback_args_t * args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; - local_info_t *lp = dev? dev->priv : NULL; + local_info_t *lp = link->priv; + struct net_device *dev = &lp->dev; DEBUG(0, "event(%d)\n", (int)event); @@ -1382,7 +1382,7 @@ static void xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; - local_info_t *lp; + local_info_t *lp = dev->priv; ioaddr_t ioaddr; u_char saved_page; unsigned bytes_rcvd; @@ -1401,7 +1401,6 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } dev->interrupt = 1; - lp = dev->priv; ioaddr = dev->base_addr; if (lp->mohawk) { /* must disable the interrupt */ PutByte(XIRCREG_CR, 0); @@ -1441,7 +1440,7 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* too many bytes received during this int, drop the rest of the * packets */ lp->stats.rx_dropped++; - printk(KINF_XIRC "%s: RX drop, too much done\n", dev->name); + DEBUG(2, "%s: RX drop, too much done\n", dev->name); PutWord(XIRCREG0_DO, 0x8000); /* issue cmd: skip_rx_packet */ } else if (rsr & PktRxOk) { struct sk_buff *skb; @@ -1782,8 +1781,6 @@ do_config(struct net_device *dev, struct ifmap *map) DEBUG(0, "do_config(%p)\n", dev); if (map->port != 255 && map->port != dev->if_port) { - if (local->new_mii) - return -EOPNOTSUPP; if (map->port > 4) return -EINVAL; if (!map->port) { @@ -1813,14 +1810,11 @@ static int do_open(struct net_device *dev) { local_info_t *lp = dev->priv; - dev_link_t *link; + dev_link_t *link = &lp->link; DEBUG(0, "do_open(%p)\n", dev); /* Check that the PCMCIA card is still here. */ - for (link = dev_list; link; link = link->next) - if (link->priv == dev) - break; /* Physical device present signature. */ if (!DEV_OK(link)) return -ENODEV; @@ -1858,7 +1852,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f); break; case SIOCDEVPRIVATE+2: /* Write the specified MII register */ - if (!suser()) + if (!capable(CAP_NET_ADMIN)) return -EPERM; mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16); break; @@ -2064,7 +2058,7 @@ init_mii(struct net_device *dev) local->new_mii = (mii_rd(ioaddr, 0, 2) != 0xffff); - if (local->new_mii || local->probe_port) + if (local->probe_port) control = 0x1000; /* auto neg */ else if (dev->if_port == 4) control = 0x2000; /* no auto neg, 100mbs mode */ @@ -2081,8 +2075,8 @@ init_mii(struct net_device *dev) return 0; } - if (local->new_mii || local->probe_port) { - /* according to the DP83840A specs the auto negotation process + if (local->probe_port) { + /* according to the DP83840A specs the auto negotiation process * may take up to 3.5 sec, so we use this also for our ML6692 * Fixme: Better to use a timer here! */ @@ -2094,7 +2088,7 @@ init_mii(struct net_device *dev) } if (!(status & 0x0020)) { - printk(KERN_INFO "%s: auto negotation failed;" + printk(KERN_INFO "%s: autonegotiation failed;" " using 10mbs\n", dev->name); if (!local->new_mii) { control = 0x0000; @@ -2112,7 +2106,6 @@ init_mii(struct net_device *dev) } else dev->if_port = 1; } - local->probe_port = 0; } #ifdef PCMCIA_DEBUG @@ -2140,13 +2133,11 @@ static int do_stop(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; - dev_link_t *link; + local_info_t *lp = dev->priv; + dev_link_t *link = &lp->link; DEBUG(0, "do_stop(%p)\n", dev); - for (link = dev_list; link; link = link->next) - if (link->priv == dev) - break; if (!link) return -ENODEV; |