diff options
Diffstat (limited to 'drivers/net/wan')
-rw-r--r-- | drivers/net/wan/cosa.c | 19 | ||||
-rw-r--r-- | drivers/net/wan/cycx_x25.c | 62 | ||||
-rw-r--r-- | drivers/net/wan/dlci.c | 67 | ||||
-rw-r--r-- | drivers/net/wan/hostess_sv11.c | 7 | ||||
-rw-r--r-- | drivers/net/wan/lapbether.c | 15 | ||||
-rw-r--r-- | drivers/net/wan/sbni.c | 73 | ||||
-rw-r--r-- | drivers/net/wan/sbni.h | 2 | ||||
-rw-r--r-- | drivers/net/wan/sdla.c | 163 | ||||
-rw-r--r-- | drivers/net/wan/sdla_chdlc.c | 3 | ||||
-rw-r--r-- | drivers/net/wan/sdla_fr.c | 137 | ||||
-rw-r--r-- | drivers/net/wan/sdla_ppp.c | 3 | ||||
-rw-r--r-- | drivers/net/wan/sdla_x25.c | 62 | ||||
-rw-r--r-- | drivers/net/wan/sealevel.c | 7 | ||||
-rw-r--r-- | drivers/net/wan/x25_asy.c | 63 | ||||
-rw-r--r-- | drivers/net/wan/z85230.c | 389 | ||||
-rw-r--r-- | drivers/net/wan/z85230.h | 6 |
16 files changed, 681 insertions, 397 deletions
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 6883aa69f..873a561ef 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -84,6 +84,7 @@ #include <linux/malloc.h> #include <linux/poll.h> #include <linux/fs.h> +#include <linux/devfs_fs_kernel.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/delay.h> @@ -359,6 +360,8 @@ static void debug_status_out(struct cosa_data *cosa, int status); /* ---------- Initialization stuff ---------- */ +static devfs_handle_t devfs_handle = NULL; + #ifdef MODULE int init_module(void) #else @@ -366,18 +369,19 @@ static int __init cosa_init(void) #endif { int i; + printk(KERN_INFO "cosa v1.06 (c) 1997-8 Jan Kasprzak <kas@fi.muni.cz>\n"); #ifdef __SMP__ printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n"); #endif if (cosa_major > 0) { - if (register_chrdev(cosa_major, "cosa", &cosa_fops)) { + if (devfs_register_chrdev(cosa_major, "cosa", &cosa_fops)) { printk(KERN_WARNING "cosa: unable to get major %d\n", cosa_major); return -EIO; } } else { - if (!(cosa_major=register_chrdev(0, "cosa", &cosa_fops))) { + if (!(cosa_major=devfs_register_chrdev(0, "cosa", &cosa_fops))) { printk(KERN_WARNING "cosa: unable to register chardev\n"); return -EIO; } @@ -386,9 +390,14 @@ static int __init cosa_init(void) cosa_cards[i].num = -1; for (i=0; io[i] != 0 && i < MAX_CARDS; i++) cosa_probe(io[i], irq[i], dma[i]); + devfs_handle = devfs_mk_dir (NULL, "cosa", 4, NULL); + devfs_register_series (devfs_handle, "%u", nr_cards, DEVFS_FL_DEFAULT, + cosa_major, 0, + S_IFCHR | S_IRUSR | S_IWUSR, 0, 0, + &cosa_fops, NULL); if (!nr_cards) { printk(KERN_WARNING "cosa: no devices found.\n"); - unregister_chrdev(cosa_major, "cosa"); + devfs_unregister_chrdev(cosa_major, "cosa"); return -ENODEV; } return 0; @@ -397,9 +406,11 @@ static int __init cosa_init(void) #ifdef MODULE void cleanup_module (void) { + int i; struct cosa_data *cosa; printk(KERN_INFO "Unloading the cosa module\n"); + devfs_unregister (devfs_handle); for (cosa=cosa_cards; nr_cards--; cosa++) { int i; /* Clean up the per-channel data */ @@ -414,7 +425,7 @@ void cleanup_module (void) free_dma(cosa->dma); release_region(cosa->datareg,is_8bit(cosa)?2:4); } - unregister_chrdev(cosa_major, "cosa"); + devfs_unregister_chrdev(cosa_major, "cosa"); } #endif diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index e11c9bcfe..e56125734 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -93,6 +93,9 @@ /* This is an extension of the 'struct net_device' we create for each network interface to keep the rest of X.25 channel-specific data. */ typedef struct x25_channel { + /* This member must be first. */ + struct net_device *slave; /* WAN slave */ + char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */ char *local_addr; /* local media address, ASCIIZ - @@ -502,12 +505,10 @@ static int if_open (struct net_device *dev) x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; - if (dev->start) + if (netif_running(dev)) return -EBUSY; /* only one open is allowed */ - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); cyclomx_mod_inc_use_count(card); return 0; @@ -521,8 +522,8 @@ static int if_close (struct net_device *dev) x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; - dev->start = 0; - + netif_stop_queue(dev); + if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING) chan_disconnect(dev); @@ -556,7 +557,7 @@ static int if_rebuild_hdr (struct sk_buff *skb) } /* Send a packet on a network interface. - * o set tbusy flag (marks start of the transmission). + * o set busy flag (marks start of the transmission). * o check link state. If link is not up, then drop the packet. * o check channel status. If it's down then initiate a call. * o pass a packet to corresponding WAN device. @@ -575,11 +576,6 @@ static int if_send (struct sk_buff *skb, struct net_device *dev) x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; - if (dev->tbusy) { - ++chan->ifstats.rx_dropped; - return -EBUSY; - } - if (!chan->svc) chan->protocol = skb->protocol; @@ -595,14 +591,14 @@ static int if_send (struct sk_buff *skb, struct net_device *dev) switch (chan->state) { case WAN_DISCONNECTED: if (chan_connect(dev)) { - dev->tbusy = 1; + netif_stop_queue(dev); return -EBUSY; } /* fall thru */ case WAN_CONNECTED: reset_timer(dev); dev->trans_start = jiffies; - dev->tbusy = 1; + netif_stop_queue(dev); if (chan_send(dev, skb)) return -EBUSY; @@ -632,8 +628,8 @@ static int if_send (struct sk_buff *skb, struct net_device *dev) skb_pull(skb, 1); /* Remove control byte */ reset_timer(dev); dev->trans_start = jiffies; - dev->tbusy = 1; - + netif_stop_queue(dev); + if (chan_send(dev, skb)) { /* prepare for future retransmissions */ skb_push(skb, 1); @@ -705,9 +701,6 @@ static void cyx_isr (cycx_t *card) cycx_poke(&card->hw, 0, &z, sizeof(z)); cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z)); card->in_isr = 0; - - if (card->buff_int_mode_unbusy) - mark_bh(NET_BH); } /* Transmit interrupt handler. @@ -724,7 +717,7 @@ static void tx_intr (cycx_t *card, TX25Cmd *cmd) /* unbusy device and then dev_tint(); */ if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) { card->buff_int_mode_unbusy = 1; - dev->tbusy = 0; + netif_wake_queue(dev); } else printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n", card->devname, lcn); @@ -1263,11 +1256,13 @@ static int x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len, void *buf) static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) { struct net_device *dev = wandev->dev; + x25_channel_t *chan; - for (; dev; dev = dev->slave) - if (((x25_channel_t*)dev->priv)->lcn == lcn) + while (dev) { + if (chan->lcn == lcn) break; - + dev = chan->slave; + } return dev; } @@ -1275,11 +1270,13 @@ static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) { struct net_device *dev = wandev->dev; + x25_channel_t *chan; - for (; dev; dev = dev->slave) - if (!strcmp(((x25_channel_t*)dev->priv)->addr, dte)) + while (dev) { + if (!strcmp(chan->addr, dte)) break; - + dev = chan->slave; + } return dev; } @@ -1357,7 +1354,7 @@ static void set_chan_state (struct net_device *dev, u8 state) case WAN_CONNECTED: string_state = "connected!"; *(u16*)dev->dev_addr = htons(chan->lcn); - dev->tbusy = 0; + netif_wake_queue(dev); reset_timer(dev); if (chan->protocol == ETH_P_X25) @@ -1384,7 +1381,7 @@ static void set_chan_state (struct net_device *dev, u8 state) if (chan->protocol == ETH_P_X25) chan_x25_send_event(dev, 2); - dev->tbusy = 0; + netif_wake_queue(dev); break; } @@ -1560,15 +1557,16 @@ static void x25_dump_devs(wan_device_t *wandev) struct net_device *dev = wandev->dev; printk(KERN_INFO "X.25 dev states\n"); - printk(KERN_INFO "name: addr: tbusy: protocol:\n"); + printk(KERN_INFO "name: addr: txoff: protocol:\n"); printk(KERN_INFO "---------------------------------------\n"); - for (; dev; dev = dev->slave) { + while(dev) { x25_channel_t *chan = dev->priv; - printk(KERN_INFO "%-5.5s %-15.15s %ld ETH_P_%s\n", - chan->name, chan->addr, dev->tbusy, + printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n", + chan->name, chan->addr, netif_queue_stopped(dev), chan->protocol == ETH_P_IP ? "IP" : "X25"); + dev = chan->slave; } } diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index a8c52f0d6..362e7a36e 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -244,43 +244,34 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev) if (!skb || !dev) return(0); - if (dev->tbusy) - return(1); - dlp = dev->priv; - if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) - printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name); - else + netif_stop_queue(dev); + + ret = dlp->slave->hard_start_xmit(skb, dlp->slave); + switch (ret) { - ret = dlp->slave->hard_start_xmit(skb, dlp->slave); - switch (ret) - { - case DLCI_RET_OK: - dlp->stats.tx_packets++; - ret = 0; - break; - + case DLCI_RET_OK: + dlp->stats.tx_packets++; + ret = 0; + break; case DLCI_RET_ERR: - dlp->stats.tx_errors++; - ret = 0; - break; - + dlp->stats.tx_errors++; + ret = 0; + break; case DLCI_RET_DROP: - dlp->stats.tx_dropped++; - ret = 1; - break; - } - - /* Alan Cox recommends always returning 0, and always freeing the packet */ - /* experience suggest a slightly more conservative approach */ - - if (!ret) - dev_kfree_skb(skb); - - dev->tbusy = 0; + dlp->stats.tx_dropped++; + ret = 1; + break; } + /* Alan Cox recommends always returning 0, and always freeing the packet */ + /* experience suggest a slightly more conservative approach */ + if (!ret) + { + dev_kfree_skb(skb); + netif_wake_queue(dev); + } return(ret); } @@ -370,19 +361,16 @@ static int dlci_open(struct net_device *dev) if (!*(short *)(dev->dev_addr)) return(-EINVAL); - if (!dlp->slave->start) + if (!netif_running(dlp->slave)) return(-ENOTCONN); - dev->flags = 0; - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - flp = dlp->slave->priv; err = (*flp->activate)(dlp->slave, dev); if (err) return(err); + netif_start_queue(dev); + return 0; } @@ -392,14 +380,13 @@ static int dlci_close(struct net_device *dev) struct frad_local *flp; int err; + netif_stop_queue(dev); + dlp = dev->priv; flp = dlp->slave->priv; err = (*flp->deactivate)(dlp->slave, dev); - dev->start = 0; - dev->tbusy = 1; - return 0; } @@ -508,7 +495,7 @@ int dlci_del(struct dlci_add *dlci) if (!master) return(-ENODEV); - if (master->start) + if (netif_running(master)) return(-EBUSY); dlp = master->priv; diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index d5c7ebd5e..6220d7fdd 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -122,7 +122,8 @@ static int hostess_open(struct net_device *d) /* * Go go go */ - d->tbusy=0; + + netif_start_queue(d); MOD_INC_USE_COUNT; return 0; } @@ -141,8 +142,8 @@ static int hostess_close(struct net_device *d) /* * Link layer down */ - d->tbusy=1; - + netif_stop_queue(d); + switch(dma) { case 0: diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index a4564afcb..1fa07475b 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -163,7 +163,7 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe dev = lapbeth_get_x25_dev(dev); - if (dev == NULL || dev->start == 0) { + if (dev == NULL || !netif_running(dev)) { kfree_skb(skb); return 0; } @@ -215,7 +215,7 @@ static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) * Just to be *really* sure not to send anything if the interface * is down, the ethernet device may have gone. */ - if (!dev->start) { + if (!netif_running(dev)) { lapbeth_check_devices(dev); kfree_skb(skb); return -ENODEV; @@ -360,9 +360,6 @@ static int lapbeth_open(struct net_device *dev) if (lapbeth_check_devices(dev)) return -ENODEV; /* oops, it's gone */ - dev->tbusy = 0; - dev->start = 1; - lapbeth = (struct lapbethdev *)dev->priv; lapbeth_callbacks.connect_confirmation = lapbeth_connected; @@ -374,12 +371,11 @@ static int lapbeth_open(struct net_device *dev) if ((err = lapb_register(lapbeth, &lapbeth_callbacks)) != LAPB_OK) { printk(KERN_ERR "lapbeth: lapb_register error - %d\n", err); - dev->tbusy = 1; - dev->start = 0; return -ENODEV; } MOD_INC_USE_COUNT; + netif_start_queue(dev); return 0; } @@ -389,9 +385,8 @@ static int lapbeth_close(struct net_device *dev) struct lapbethdev *lapbeth; int err; - dev->tbusy = 1; - dev->start = 0; - + netif_stop_queue(dev); + lapbeth = (struct lapbethdev *)dev->priv; if ((err = lapb_unregister(lapbeth)) != LAPB_OK) diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 4cf0c05a1..b161fbabc 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -59,11 +59,6 @@ #include <linux/version.h> -#if LINUX_VERSION_CODE >=0x020200 -#define v22 -#endif - - #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -74,6 +69,7 @@ #include <linux/malloc.h> #include <linux/string.h> #include <linux/errno.h> +#include <linux/spinlock.h> #include <asm/io.h> #include <asm/types.h> @@ -88,12 +84,8 @@ #include <net/arp.h> - - -#ifdef v22 #include <asm/uaccess.h> #include <linux/init.h> -#endif #include "sbni.h" @@ -523,6 +515,7 @@ static int __init sbni_probe1(struct net_device *dev, int ioaddr) dev->hard_header_cache = sbni_header_cache; dev->header_cache_update = sbni_header_cache_update; + spin_lock_init(&lp->lock); lp->m=dev; lp->me=dev; lp->next_lp=NULL; @@ -538,15 +531,15 @@ static int sbni_open(struct net_device *dev) { struct net_local* lp = (struct net_local*)dev->priv; struct timer_list* watchdog = &lp->watchdog; - + unsigned long flags; DP( printk("%s: sbni_open\n", dev->name); ) + save_flags(flags); cli(); lp->currframe = NULL; card_start(dev); - dev->start = 1; /* set timer watchdog */ init_timer(watchdog); watchdog->expires = jiffies + SBNI_TIMEOUT; @@ -555,8 +548,9 @@ static int sbni_open(struct net_device *dev) add_timer(watchdog); DP( printk("%s: sbni timer watchdog initialized\n", dev->name); ); - sti(); - + restore_flags(flags); + + netif_start_queue(dev); MOD_INC_USE_COUNT; return 0; } @@ -566,21 +560,18 @@ static int sbni_close(struct net_device *dev) int ioaddr = dev->base_addr; struct net_local* lp = (struct net_local*) dev->priv; struct timer_list* watchdog = &lp->watchdog; - - + unsigned long flags; + DP( printk("%s: sbni_close\n", dev->name); ) + netif_stop_queue(dev); + + save_flags(flags); cli(); - sbni_drop_tx_queue(dev); - - dev->tbusy = 1; - dev->start = 0; - del_timer(watchdog); - outb(0, ioaddr + CSR0); - sti(); + restore_flags(flags); MOD_DEC_USE_COUNT; return 0; @@ -590,6 +581,7 @@ static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local*)dev->priv; struct sbni_hard_header *hh=(struct sbni_hard_header *)skb->data; + unsigned long flags; #ifdef KATYUSHA struct net_local *nl; @@ -602,13 +594,6 @@ static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev) if(lp->me != dev) panic("sbni: lp->me != dev !!!\nMail to developer (xenon@granch.ru) if you noticed this error\n"); - if(dev->interrupt) - { - DP( printk("sbni_xmit_start: interrupt\n"); ) - /* May be unloading, don't stamp on */ - return 1; /* the packet buffer this time */ - } - hh->number = 1; hh->reserv = 0; @@ -623,6 +608,7 @@ static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->len - sizeof(struct sbni_hard_header), hh->crc); + spin_lock_irqsave(&lp->lock, flags); #ifdef KATYUSHA /* looking for first idle device */ for (stop=0,nl=lp; nl && !stop; nl=nl->next_lp) @@ -657,6 +643,7 @@ static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev) /* set request for transmit */ outb(inb(dev->base_addr + CSR0) | TR_REQ, dev->base_addr + CSR0); #endif + spin_unlock_irqrestore(&lp->lock, flags); return 0; } @@ -677,9 +664,6 @@ void card_start(struct net_device *dev) lp->waitack=0; skb_queue_head_init(&lp->queue); sbni_drop_tx_queue(dev); - dev->tbusy = 0; - - dev->interrupt = 0; /* Reset the card and set start parameters */ outb(PR_RES | *(char*)&lp->csr1, dev->base_addr + CSR1); outb(EN_INT, dev->base_addr + CSR0); @@ -776,8 +760,7 @@ static inline unsigned short sbni_recv(struct net_device *dev) /* * reset output active flags */ - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue(dev); /*} if */ } case PACKET_RESEND: @@ -920,17 +903,12 @@ static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs) return; } - if(dev->interrupt) - { - printk("%s: Reentering the interrupt driver!\n", dev->name); - return; - } - dev->interrupt = 1; - csr0 = inb(dev->base_addr + CSR0); DP( printk("%s: entering interrupt handler, CSR0 = %02x\n", dev->name, csr0); ) lp=dev->priv; + + spin_lock(&lp->lock); if(!lp->carrier) lp->carrier=1; @@ -971,7 +949,7 @@ static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ outb(csr0 | EN_INT, dev->base_addr + CSR0); - dev->interrupt = 0; + spin_unlock(&lp->lock); } static struct enet_statistics *sbni_get_stats(struct net_device *dev) @@ -1103,7 +1081,7 @@ static void sbni_watchdog(unsigned long arg) } sti(); outb(csr0 | RC_CHK, dev->base_addr + CSR0); - if(dev->start) + if(netif_running(dev)) { struct timer_list* watchdog = &lp->watchdog; init_timer(watchdog); @@ -1167,9 +1145,8 @@ static void sbni_drop_tx_queue(struct net_device *dev) } } lp->waitack=0; - dev->tbusy = 0; - - mark_bh(NET_BH); + netif_wake_queue(dev); + DP( printk("%s: queue dropping stoped\n",dev->name); ); } @@ -1194,7 +1171,7 @@ static int sbni_set_mac_address(struct net_device *dev, void *addr) /* struct net_local *lp = (struct net_local *)dev->priv; */ struct sockaddr *saddr = addr; - if(dev->start) + if(netif_running(dev)) { /* Only possible while card isn't started */ return -EBUSY; @@ -1400,13 +1377,11 @@ static int rxl[SBNI_MAX_NUM_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; static int baud[SBNI_MAX_NUM_CARDS] = { 0 }; static long mac[SBNI_MAX_NUM_CARDS] = { 0 }; -#ifdef v22 MODULE_PARM(io, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); MODULE_PARM(rxl, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); MODULE_PARM(baud, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); MODULE_PARM(mac, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); -#endif static int sbniautodetect = -1; diff --git a/drivers/net/wan/sbni.h b/drivers/net/wan/sbni.h index 2e34d8d34..56550d8f2 100644 --- a/drivers/net/wan/sbni.h +++ b/drivers/net/wan/sbni.h @@ -146,7 +146,7 @@ struct net_local { int carrier; - + spinlock_t lock; }; diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 29bedf8f9..64165cd0e 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -510,7 +510,7 @@ int sdla_activate(struct net_device *slave, struct net_device *master) flp->dlci[i] = abs(flp->dlci[i]); - if (slave->start && (flp->config.station == FRAD_STATION_NODE)) + if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); return(0); @@ -532,7 +532,7 @@ int sdla_deactivate(struct net_device *slave, struct net_device *master) flp->dlci[i] = -abs(flp->dlci[i]); - if (slave->start && (flp->config.station == FRAD_STATION_NODE)) + if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); return(0); @@ -565,7 +565,7 @@ int sdla_assoc(struct net_device *slave, struct net_device *master) flp->dlci[i] = -*(short *)(master->dev_addr); master->mtu = slave->mtu; - if (slave->start) { + if (netif_running(dev)) { if (flp->config.station == FRAD_STATION_CPE) sdla_reconfig(slave); else @@ -594,7 +594,7 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master) MOD_DEC_USE_COUNT; - if (slave->start) { + if (netif_running(slave)) { if (flp->config.station == FRAD_STATION_CPE) sdla_reconfig(slave); else @@ -624,7 +624,7 @@ int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) ret = SDLA_RET_OK; len = sizeof(struct dlci_conf); - if (slave->start) { + if (netif_running(slave)) { if (get) ret = sdla_cmd(slave, SDLA_READ_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, NULL, 0, &dlp->config, &len); @@ -646,7 +646,7 @@ int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) static int sdla_transmit(struct sk_buff *skb, struct net_device *dev) { struct frad_local *flp; - int ret, addr, accept; + int ret, addr, accept, i; short size; unsigned long flags; struct buf_entry *pbuf; @@ -655,90 +655,80 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev) ret = 0; accept = 1; - if (dev->tbusy) - return(1); + netif_stop_queue(dev); - if (skb == NULL) - return(0); + /* + * stupid GateD insists on setting up the multicast router thru us + * and we're ill equipped to handle a non Frame Relay packet at this + * time! + */ - if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) - printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name); - else + accept = 1; + switch (dev->type) { - /* - * stupid GateD insists on setting up the multicast router thru us - * and we're ill equipped to handle a non Frame Relay packet at this - * time! - */ - - accept = 1; - switch (dev->type) + case ARPHRD_FRAD: + if (skb->dev->type != ARPHRD_DLCI) + { + printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type); + accept = 0; + } + break; + default: + printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type); + accept = 0; + break; + } + if (accept) + { + /* this is frame specific, but till there's a PPP module, it's the default */ + switch (flp->type) { - case ARPHRD_FRAD: - if (skb->dev->type != ARPHRD_DLCI) + case SDLA_S502A: + case SDLA_S502E: + ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL); + break; + case SDLA_S508: + size = sizeof(addr); + ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size); + if (ret == SDLA_RET_OK) { - printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type); - accept = 0; + save_flags(flags); + cli(); + SDLA_WINDOW(dev, addr); + pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK)); + sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); + SDLA_WINDOW(dev, addr); + pbuf->opp_flag = 1; + restore_flags(flags); } break; - - default: - printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type); - accept = 0; - break; } - - if (accept) + switch (ret) { - /* this is frame specific, but till there's a PPP module, it's the default */ - switch (flp->type) - { - case SDLA_S502A: - case SDLA_S502E: - ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL); - break; - - case SDLA_S508: - size = sizeof(addr); - ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size); - if (ret == SDLA_RET_OK) - { - save_flags(flags); - cli(); - SDLA_WINDOW(dev, addr); - pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK)); - - sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); - - SDLA_WINDOW(dev, addr); - pbuf->opp_flag = 1; - restore_flags(flags); - } - break; - } - - switch (ret) - { - case SDLA_RET_OK: - flp->stats.tx_packets++; - ret = DLCI_RET_OK; - break; + case SDLA_RET_OK: + flp->stats.tx_packets++; + ret = DLCI_RET_OK; + break; - case SDLA_RET_CIR_OVERFLOW: - case SDLA_RET_BUF_OVERSIZE: - case SDLA_RET_NO_BUFS: - flp->stats.tx_dropped++; - ret = DLCI_RET_DROP; - break; + case SDLA_RET_CIR_OVERFLOW: + case SDLA_RET_BUF_OVERSIZE: + case SDLA_RET_NO_BUFS: + flp->stats.tx_dropped++; + ret = DLCI_RET_DROP; + break; - default: - flp->stats.tx_errors++; - ret = DLCI_RET_ERR; - break; - } + default: + flp->stats.tx_errors++; + ret = DLCI_RET_ERR; + break; } - dev->tbusy = 0; } + netif_wake_queue(dev); + for(i=0;i<CONFIG_DLCI_MAX;i++) + { + if(flp->master[i]!=NULL) + netif_wake_queue(flp->master[i]); + } return(ret); } @@ -892,7 +882,6 @@ static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs) return; } - dev->interrupt = 1; byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE); switch (byte) { @@ -925,7 +914,6 @@ static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs) /* this clears the byte, informing the Z80 we're done */ byte = 0; sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte)); - dev->interrupt = 0; } static void sdla_poll(unsigned long device) @@ -992,9 +980,8 @@ static int sdla_close(struct net_device *dev) sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); - dev->tbusy = 1; - dev->start = 0; - + netif_stop_queue(dev); + MOD_DEC_USE_COUNT; return(0); @@ -1096,10 +1083,8 @@ static int sdla_open(struct net_device *dev) sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL); } - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - + netif_start_queue(dev); + MOD_INC_USE_COUNT; return(0); @@ -1119,7 +1104,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get) if (!get) { - if (dev->start) + if (netif_running(dev)) return(-EBUSY); if(copy_from_user(&data.config, conf, sizeof(struct frad_conf))) @@ -1182,7 +1167,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get) else { /* no sense reading if the CPU isn't started */ - if (dev->start) + if (netif_running(dev)) { size = sizeof(data); if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK) @@ -1331,7 +1316,7 @@ int sdla_change_mtu(struct net_device *dev, int new_mtu) flp = dev->priv; - if (dev->start) + if (netif_running(dev)) return(-EBUSY); /* for now, you can't change the MTU! */ diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c index 3df910ea1..c0b419afa 100644 --- a/drivers/net/wan/sdla_chdlc.c +++ b/drivers/net/wan/sdla_chdlc.c @@ -74,6 +74,9 @@ typedef struct chdlc_private_area { + /* This member must be first. */ + struct net_device *slave; /* WAN slave */ + sdla_t *card; int TracingEnabled; /* For enabling Tracing */ unsigned long curr_trace_addr; /* Used for Tracing */ diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c index 0c7f7e8f0..f4431c9dc 100644 --- a/drivers/net/wan/sdla_fr.c +++ b/drivers/net/wan/sdla_fr.c @@ -167,6 +167,9 @@ */ typedef struct fr_channel { + /* This member must be first. */ + struct net_device *slave; /* WAN slave */ + char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ unsigned dlci_configured ; /* check whether configured or not */ unsigned cir_status; /* check whether CIR enabled or not */ @@ -1960,7 +1963,9 @@ goto L4; // Used to send inarp request at given interval if (card->wandev.state == WAN_CONNECTED) { int num_remaining = 0; - for (dev=card->wandev.dev;dev;dev=dev->slave) { + + dev = card->wandev.dev; + while (dev) { fr_channel_t *chan = dev->priv; if (chan->inarp == INARP_REQUEST && @@ -1972,6 +1977,7 @@ goto L4; chan->inarp_tick = jiffies; } } + dev = chan->slave; } if (!num_remaining) { // no more to process flags->imask &= ~FR_INTR_TIMER; @@ -2135,65 +2141,68 @@ static void process_route (sdla_t* card) /* Dynamic Route adding/removing */ - for (dev = card->wandev.dev; dev ; dev = dev->slave) { - if ( ((fr_channel_t*)dev->priv)->route_flag == ADD_ROUTE || - ((fr_channel_t*)dev->priv)->route_flag == REMOVE_ROUTE ) { - fs = get_fs(); + dev = card->wandev.dev; + while (dev) { + fr_channel_t *chan = dev->priv; + + if (chan->route_flag == ADD_ROUTE || + chan->route_flag == REMOVE_ROUTE ) { + fs = get_fs(); - in_dev = dev->ip_ptr; - - if( in_dev != NULL && in_dev->ifa_list != NULL) { - memset(&route, 0, sizeof(route)); - route.rt_dev = dev->name; - route.rt_flags = 0; - - ((struct sockaddr_in *) &(route.rt_dst)) -> - sin_addr.s_addr=in_dev->ifa_list->ifa_address; - ((struct sockaddr_in *) &(route.rt_dst)) -> - sin_family = AF_INET; - ((struct sockaddr_in *) &(route.rt_genmask)) -> - sin_addr.s_addr = 0xFFFFFFFF; - ((struct sockaddr_in *) &(route.rt_genmask)) -> - sin_family = AF_INET; - - switch(((fr_channel_t*)dev->priv)->route_flag) { - - case ADD_ROUTE: - set_fs(get_ds()); /* get user space block */ - err = ip_rt_ioctl( SIOCADDRT, &route); - set_fs(fs); /* restore old block */ - - if (err) { - printk(KERN_INFO "%s: Adding of route failed. Error: %d\n", card->devname,err); - printk(KERN_INFO "%s: Address: %s\n", - ((fr_channel_t*)dev->priv)->name, - in_ntoa(in_dev->ifa_list->ifa_address) ); - } - else { - ((fr_channel_t*)dev->priv)-> - route_flag = ROUTE_ADDED; - } - break; + in_dev = dev->ip_ptr; + + if( in_dev != NULL && in_dev->ifa_list != NULL) { + memset(&route, 0, sizeof(route)); + route.rt_dev = dev->name; + route.rt_flags = 0; + + ((struct sockaddr_in *) &(route.rt_dst)) -> + sin_addr.s_addr=in_dev->ifa_list->ifa_address; + ((struct sockaddr_in *) &(route.rt_dst)) -> + sin_family = AF_INET; + ((struct sockaddr_in *) &(route.rt_genmask)) -> + sin_addr.s_addr = 0xFFFFFFFF; + ((struct sockaddr_in *) &(route.rt_genmask)) -> + sin_family = AF_INET; + + switch(chan->route_flag) { + + case ADD_ROUTE: + set_fs(get_ds()); /* get user space block */ + err = ip_rt_ioctl( SIOCADDRT, &route); + set_fs(fs); /* restore old block */ + + if (err) { + printk(KERN_INFO "%s: Adding of route failed. Error: %d\n", card->devname,err); + printk(KERN_INFO "%s: Address: %s\n", + chan->name, + in_ntoa(in_dev->ifa_list->ifa_address) ); + } else { + chan->route_flag = ROUTE_ADDED; + } + break; - case REMOVE_ROUTE: - set_fs(get_ds()); /* get user space block */ - err = ip_rt_ioctl( SIOCDELRT, &route); - set_fs(fs); /* restore old block */ + case REMOVE_ROUTE: + set_fs(get_ds()); /* get user space block */ + err = ip_rt_ioctl( SIOCDELRT, &route); + set_fs(fs); /* restore old block */ + + if (err) { + printk(KERN_INFO "%s: Deleting of route failed. Error: %d\n", card->devname,err); + printk(KERN_INFO "%s: Address: %s\n", + dev->name,in_ntoa(in_dev->ifa_list->ifa_address) ); + } else { + printk(KERN_INFO "%s: Removed route.\n", + chan->name); + chan->route_flag = NO_ROUTE; + } + break; + } /* Case Statement */ + } + } /* If ADD/DELETE ROUTE */ - if (err) { - printk(KERN_INFO "%s: Deleting of route failed. Error: %d\n", card->devname,err); - printk(KERN_INFO "%s: Address: %s\n", - dev->name,in_ntoa(in_dev->ifa_list->ifa_address) ); - } else { - printk(KERN_INFO "%s: Removed route.\n", - ((fr_channel_t*)dev->priv)->name); - ((fr_channel_t*)dev->priv)->route_flag = NO_ROUTE; - } - break; - } /* Case Statement */ - } - } /* If ADD/DELETE ROUTE */ - } /* Device 'For' Loop */ + dev = chan->slave; + } /* Device 'While' Loop */ card->poll = NULL; } @@ -2568,7 +2577,8 @@ static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox) struct net_device *dev; /* Remove all routes from associated DLCI's */ - for (dev = card->wandev.dev; dev; dev = dev->slave) { + dev = card->wandev.dev; + while (dev) { fr_channel_t *chan = dev->priv; if (chan->route_flag == ROUTE_ADDED) { chan->route_flag = REMOVE_ROUTE; @@ -2578,6 +2588,8 @@ static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox) if (chan->inarp == INARP_CONFIGURED) { chan->inarp = INARP_REQUEST; } + + dev = chan->slave; } wanpipe_set_state(card, WAN_DISCONNECTED); @@ -2590,12 +2602,14 @@ static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox) int num_requests = 0; /* Remove all routes from associated DLCI's */ - for (dev = card->wandev.dev; dev; dev = dev->slave) { + dev = card->wandev.dev; + while (dev) { fr_channel_t *chan = dev->priv; if( chan->inarp == INARP_REQUEST ){ num_requests++; chan->inarp_tick = jiffies; } + dev = chan->slave; } /* Allow timer interrupts */ @@ -2731,8 +2745,8 @@ static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) } } - for (dev2 =card->wandev.dev; dev2; dev2 = dev2->slave){ - + dev2 = card->wandev.dev; + while (dev2) { chan = dev2->priv; if (chan->dlci_configured == DLCI_CONFIG_PENDING) { @@ -2741,6 +2755,7 @@ static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox) } } + dev2 = chan->slave; } return 1; } diff --git a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c index 1b900fc62..f3dcc129b 100644 --- a/drivers/net/wan/sdla_ppp.c +++ b/drivers/net/wan/sdla_ppp.c @@ -155,6 +155,9 @@ typedef struct ppp_private_area { + /* This member must be first. */ + struct net_device *slave; /* WAN slave */ + sdla_t* card; unsigned long router_start_time; /*router start time in sec */ unsigned long tick_counter; /*used for 5 second counter*/ diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c index 270c5a59f..dfb5d36a5 100644 --- a/drivers/net/wan/sdla_x25.c +++ b/drivers/net/wan/sdla_x25.c @@ -75,6 +75,9 @@ */ typedef struct x25_channel { + /* This member must be first. */ + struct net_device *slave; /* WAN slave */ + char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */ unsigned lcn; /* logical channel number */ @@ -708,11 +711,13 @@ static int if_send (struct sk_buff* skb, struct net_device* dev) return dev->tbusy; } printk(KERN_INFO "%s: Transmit time out %s!\n", - card->devname, dev->name) - ; - for( dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) - { + card->devname, dev->name); + + dev2 = card->wandev.dev; + while (dev2) { + x25_channel_t *chan2 = dev2->priv; dev2->tbusy = 0; + dev2 = chan2->slave; } } chan->tick_counter = jiffies; @@ -898,13 +903,17 @@ static void wpx_isr (sdla_t* card) if(card->buff_int_mode_unbusy) { - for(dev = card->wandev.dev; dev; dev = dev->slave) - { - if(((x25_channel_t*)dev->priv)->devtint) - { + x25_channel_t *chan; + + dev = card->wandev.dev; + while (dev) { + chan = dev->priv; + if(chan->devtint) { mark_bh(NET_BH); return; } + + dev = chan->slave; } } } @@ -1042,12 +1051,15 @@ static void rx_intr (sdla_t* card) static void tx_intr (sdla_t* card) { struct net_device *dev; + x25_channel_t *chan; /* unbusy all devices and then dev_tint(); */ - for(dev = card->wandev.dev; dev; dev = dev->slave) - { - ((x25_channel_t*)dev->priv)->devtint = dev->tbusy; + dev = card->wandev.dev; + while (dev) { + chan->devtint = dev->tbusy; dev->tbusy = 0; + + dev = chan->slave; } } @@ -1170,8 +1182,8 @@ static void poll_active (sdla_t* card) /* Fetch X.25 asynchronous events */ x25_fetch_events(card); - for (dev = card->wandev.dev; dev; dev = dev->slave) - { + dev = card->wandev.dev; + while (dev) { x25_channel_t* chan = dev->priv; struct sk_buff* skb = chan->tx_skb; @@ -1199,6 +1211,8 @@ static void poll_active (sdla_t* card) chan_disc(dev); } } + + dev = chan->slave; } } @@ -1785,8 +1799,8 @@ static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) card->devname, new_lcn, mb->data); /* Find available channel */ - for (dev = wandev->dev; dev; dev = dev->slave) - { + dev = wandev->dev; + while (dev) { chan = dev->priv; if (!chan->svc || (chan->state != WAN_DISCONNECTED)) @@ -1796,6 +1810,8 @@ static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) /* If just an '@' is specified, accept all incoming calls */ if (strcmp(chan->addr, "") == 0) break; + + dev = chan->slave; } if (dev == NULL) @@ -1912,8 +1928,14 @@ static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) card->devname, mb->cmd.cause, mb->cmd.diagn); /* down all logical channels */ - for (dev = wandev->dev; dev; dev = dev->slave) + dev = wandev->dev; + while (dev) { + x25_channel_t *chan = dev->priv; + set_chan_state(dev, WAN_DISCONNECTED); + dev = chan->slave; + } + return (cmd == X25_WRITE) ? 0 : 1; } @@ -1979,10 +2001,14 @@ static int disconnect (sdla_t* card) static struct net_device* get_dev_by_lcn (wan_device_t* wandev, unsigned lcn) { struct net_device* dev; + x25_channel_t *chan; - for (dev = wandev->dev; dev; dev = dev->slave) - if (((x25_channel_t*)dev->priv)->lcn == lcn) + dev = wandev->dev; + while (dev) { + if (chan->lcn == lcn) break; + dev = chan->slave; + } return dev; } diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 90cccf81d..8fd2ff105 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -119,7 +119,7 @@ static int sealevel_open(struct net_device *d) /* * Go go go */ - d->tbusy=0; + netif_start_queue(d); MOD_INC_USE_COUNT; return 0; } @@ -142,8 +142,9 @@ static int sealevel_close(struct net_device *d) /* * Link layer down */ - d->tbusy=1; - + + netif_stop_queue(d); + switch(unit) { case 0: diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index e50865d97..7b647d663 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -205,8 +205,7 @@ static void x25_asy_changed_mtu(struct x25_asy *sl) static inline void x25_asy_lock(struct x25_asy *sl) { - if (test_and_set_bit(0, (void *) &sl->dev->tbusy)) - printk("%s: trying to lock already locked device!\n", sl->dev->name); + netif_stop_queue(sl->dev); } @@ -214,8 +213,7 @@ static inline void x25_asy_lock(struct x25_asy *sl) static inline void x25_asy_unlock(struct x25_asy *sl) { - if (!test_and_clear_bit(0, (void *)&sl->dev->tbusy)) - printk("%s: trying to unlock already unlocked device!\n", sl->dev->name); + netif_wake_queue(sl->dev); } /* Send one completely decapsulated IP datagram to the IP layer. */ @@ -303,7 +301,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty) struct x25_asy *sl = (struct x25_asy *) tty->disc_data; /* First make sure we're connected. */ - if (!sl || sl->magic != X25_ASY_MAGIC || !sl->dev->start) + if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) return; if (sl->xleft <= 0) @@ -313,7 +311,6 @@ static void x25_asy_write_wakeup(struct tty_struct *tty) sl->tx_packets++; tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); x25_asy_unlock(sl); - mark_bh(NET_BH); return; } @@ -322,6 +319,20 @@ static void x25_asy_write_wakeup(struct tty_struct *tty) sl->xhead += actual; } +static void x25_asy_timeout(struct net_device *dev) +{ + struct x25_asy *sl = (struct x25_asy*)(dev->priv); + /* May be we must check transmitter timeout here ? + * 14 Oct 1994 Dmitry Gorodchanin. + */ + printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, + (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ? + "bad line quality" : "driver error"); + sl->xleft = 0; + sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); + x25_asy_unlock(sl); +} + /* Encapsulate an IP datagram and kick it into a TTY queue. */ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) @@ -329,7 +340,7 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) struct x25_asy *sl = (struct x25_asy*)(dev->priv); int err; - if (!dev->start) + if (!netif_running(sl->dev)) { printk("%s: xmit call when iface is down\n", dev->name); return 1; @@ -361,25 +372,6 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) * So, no queues ! * 14 Oct 1994 Dmitry Gorodchanin. */ - if (dev->tbusy) { - /* May be we must check transmitter timeout here ? - * 14 Oct 1994 Dmitry Gorodchanin. - */ -#ifdef SL_CHECK_TRANSMIT - if (jiffies - dev->trans_start < 20 * HZ) { - /* 20 sec timeout not reached */ - return 1; - } - printk("%s: transmit timed out, %s?\n", dev->name, - (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); - sl->xleft = 0; - sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - x25_asy_unlock(sl); -#else - return 1; -#endif - } if((err=lapb_data_request(sl,skb))!=LAPB_OK) { @@ -414,7 +406,7 @@ static void x25_asy_data_indication(void *token, struct sk_buff *skb) static void x25_asy_data_transmit(void *token, struct sk_buff *skb) { struct x25_asy *sl=token; - if(sl->dev->tbusy) + if (netif_queue_stopped(sl->dev)) { printk(KERN_ERR "x25_asy: tbusy drop\n"); kfree_skb(skb); @@ -514,10 +506,8 @@ static int x25_asy_open(struct net_device *dev) sl->xleft = 0; sl->flags &= (1 << SLF_INUSE); /* Clear ESCAPE & ERROR flags */ - dev->tbusy = 0; -/* dev->flags |= IFF_UP; */ - dev->start = 1; - + netif_start_queue(dev); + /* * Now attach LAPB */ @@ -551,12 +541,9 @@ static int x25_asy_close(struct net_device *dev) return -EBUSY; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); if((err=lapb_unregister(sl))!=LAPB_OK) printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err); - -/* dev->flags &= ~IFF_UP; */ return 0; } @@ -576,7 +563,7 @@ static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, { struct x25_asy *sl = (struct x25_asy *) tty->disc_data; - if (!sl || sl->magic != X25_ASY_MAGIC || !sl->dev->start) + if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) return; /* @@ -876,6 +863,8 @@ int x25_asy_init(struct net_device *dev) dev->mtu = SL_MTU; dev->hard_start_xmit = x25_asy_xmit; + dev->tx_timeout = x25_asy_timeout; + dev->watchdog_timeo = HZ*20; dev->open = x25_asy_open_dev; dev->stop = x25_asy_close; dev->get_stats = x25_asy_get_stats; @@ -914,7 +903,7 @@ cleanup_module(void) * VSV = if dev->start==0, then device * unregistered while close proc. */ - if (x25_asy_ctrls[i]->dev.start) + if (netif_running(&(x25_asy_ctrls[i]->dev))) unregister_netdev(&(x25_asy_ctrls[i]->dev)); kfree(x25_asy_ctrls[i]); diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index f6b385de5..2ff818b04 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -54,12 +54,23 @@ static spinlock_t z8530_buffer_lock = SPIN_LOCK_UNLOCKED; -/* +/** + * z8530_read_port: + * @p: port to read + * * Provided port access methods. The Comtrol SV11 requires no delays * between accesses and uses PC I/O. Some drivers may need a 5uS delay + * + * In the longer term this should become an architecture specific + * section so that this can become a generic driver interface for all + * platforms. For now we only handle PC I/O ports with or without the + * dread 5uS sanity delay. + * + * The caller must hold sufficient locks to avoid violating the horrible + * 5uS delay rule. */ -extern __inline__ int z8530_read_port(int p) +extern __inline__ int z8530_read_port(unsigned long p) { u8 r=inb(Z8530_PORT_OF(p)); if(p&Z8530_PORT_SLEEP) /* gcc should figure this out efficiently ! */ @@ -67,7 +78,23 @@ extern __inline__ int z8530_read_port(int p) return r; } -extern __inline__ void z8530_write_port(int p, u8 d) +/** + * z8530_write_port: + * @p: port to write + * @d: value to write + * + * Write a value to a port with delays if need be. Note that the + * caller must hold locks to avoid read/writes from other contexts + * violating the 5uS rule + * + * In the longer term this should become an architecture specific + * section so that this can become a generic driver interface for all + * platforms. For now we only handle PC I/O ports with or without the + * dread 5uS sanity delay. + */ + + +extern __inline__ void z8530_write_port(unsigned long p, u8 d) { outb(d,Z8530_PORT_OF(p)); if(p&Z8530_PORT_SLEEP) @@ -80,8 +107,16 @@ static void z8530_rx_done(struct z8530_channel *c); static void z8530_tx_done(struct z8530_channel *c); -/* - * Port accesses +/** + * read_zsreg: + * @c: Z8530 channel to read from (2 per chip) + * @reg: Register to read + * FIXME: Use a spinlock. + * + * Most of the Z8530 registers are indexed off the control registers. + * A read is done by writing to the control register and reading the + * register back. We do the locking needed to protect this + * operation. */ extern inline u8 read_zsreg(struct z8530_channel *c, u8 reg) @@ -97,6 +132,14 @@ extern inline u8 read_zsreg(struct z8530_channel *c, u8 reg) return r; } +/** + * read_zsdata: + * @c: The Z8530 channel to read the data port from + * + * The data port provides fast access to some things. We still + * have all the 5uS delays to worry about. + */ + extern inline u8 read_zsdata(struct z8530_channel *c) { u8 r; @@ -104,6 +147,17 @@ extern inline u8 read_zsdata(struct z8530_channel *c) return r; } +/** + * write_zsreg: + * @c: The Z8530 channel + * @reg: Register number + * @val: Value to write + * + * Write a value to an indexed register. Perform the locking needed + * to honour the irritating delay rules. We know about register 0 + * being fast to access. + */ + extern inline void write_zsreg(struct z8530_channel *c, u8 reg, u8 val) { unsigned long flags; @@ -194,8 +248,16 @@ u8 z8530_hdlc_kilostream_85230[]= EXPORT_SYMBOL(z8530_hdlc_kilostream_85230); -/* - * Flush the FIFO +/** + * z8530_flush_fifo: + * @c: Channel to flush + * + * Flush the receive FIFO. There is no specific option for this, we + * blindly read bytes and discard them. Reading when there is no data + * is harmless. The 8530 has a 4 byte FIFO, the 85230 has 8 bytes. + * + * All locking is handled for the caller. On return data may still be + * present if it arrived during the flush. */ static void z8530_flush_fifo(struct z8530_channel *c) @@ -213,7 +275,16 @@ static void z8530_flush_fifo(struct z8530_channel *c) } } -/* Sets or clears DTR/RTS on the requested line */ +/** + * z8530_rtsdtr: + * @c: The Z8530 channel to contro; + * @set: 1 to set, 0 to clear + * + * Sets or clears DTR/RTS on the requested line. All locking is handled + * for the caller. For now we assume all boards use the actual RTS/DTR + * on the chip. Apparently one or two don't. We'll scream about them + * later. + */ static void z8530_rtsdtr(struct z8530_channel *c, int set) { @@ -224,9 +295,12 @@ static void z8530_rtsdtr(struct z8530_channel *c, int set) write_zsreg(c, R5, c->regs[5]); } -/* - * Receive handler. This is much like the async one but not quite the - * same or as complex +/** + * z8530_rx: + * @c: Z8530 channel to process + * + * Receive handler for receiving in PIO mode. This is much like the + * async one but not quite the same or as complex * * Note: Its intended that this handler can easily be separated from * the main code to run realtime. That'll be needed for some machines @@ -238,9 +312,9 @@ static void z8530_rtsdtr(struct z8530_channel *c, int set) * other code - this is true in the RT case too. * * We only cover the sync cases for this. If you want 2Mbit async - * do it yourself but consider medical assistance first. - * - * This non DMA synchronous mode is portable code. + * do it yourself but consider medical assistance first. This non DMA + * synchronous mode is portable code. The DMA mode assumes PCI like + * ISA DMA */ static void z8530_rx(struct z8530_channel *c) @@ -303,8 +377,14 @@ static void z8530_rx(struct z8530_channel *c) } -/* - * Z8530 transmit interrupt handler +/** + * z8530_tx: + * @c: Z8530 channel to process + * + * Z8530 transmit interrupt handler for the PIO mode. The basic + * idea is to attempt to keep the FIFO fed. We fill as many bytes + * in as possible, its quite possible that we won't keep up with the + * data rate otherwise. */ static void z8530_tx(struct z8530_channel *c) @@ -340,6 +420,17 @@ static void z8530_tx(struct z8530_channel *c) write_zsctrl(c, RES_H_IUS); } +/** + * z8530_status: + * @chan: Z8530 channel to process + * + * A status event occured in PIO synchronous mode. There are several + * reasons the chip will bother us here. A transmit underrun means we + * failed to feed the chip fast enough and just broke a packet. A DCD + * change is a line up or down. We communicate that back to the protocol + * layer for synchronous PPP to renegotiate. + */ + static void z8530_status(struct z8530_channel *chan) { u8 status=read_zsreg(chan, R0); @@ -387,9 +478,14 @@ struct z8530_irqhandler z8530_sync= EXPORT_SYMBOL(z8530_sync); -/* +/** + * z8530_dma_rx: + * @chan: Channel to handle + * * Non bus mastering DMA interfaces for the Z8x30 devices. This - * is really pretty PC specific. + * is really pretty PC specific. The DMA mode means that most receive + * events are handled by the DMA hardware. We get a kick here only if + * a frame ended. */ static void z8530_dma_rx(struct z8530_channel *chan) @@ -417,6 +513,14 @@ static void z8530_dma_rx(struct z8530_channel *chan) } } +/** + * z8530_dma_tx: + * @chan: The Z8530 channel to handle + * + * We have received an interrupt while doing DMA transmissions. It + * shouldn't happen. Scream loudly if it does. + */ + static void z8530_dma_tx(struct z8530_channel *chan) { if(!chan->dma_tx) @@ -430,6 +534,17 @@ static void z8530_dma_tx(struct z8530_channel *chan) z8530_tx(chan); } +/** + * z8530_dma_status: + * @chan: Z8530 channel to process + * + * A status event occured on the Z8530. We receive these for two reasons + * when in DMA mode. Firstly if we finished a packet transfer we get one + * and kick the next packet out. Secondly we may see a DCD change and + * have to poke the protocol layer. + * + */ + static void z8530_dma_status(struct z8530_channel *chan) { unsigned long flags; @@ -490,8 +605,11 @@ struct z8530_irqhandler z8530_txdma_sync= EXPORT_SYMBOL(z8530_txdma_sync); -/* - * Interrupt vectors for a Z8530 that is in 'parked' mode. +/** + * z8530_rx_clear: + * @c: Z8530 channel to shut up + * + * Receive interrupt vectors for a Z8530 that is in 'parked' mode. * For machines with PCI Z85x30 cards, or level triggered interrupts * (eg the MacII) we must clear the interrupt cause or die. */ @@ -516,12 +634,30 @@ static void z8530_rx_clear(struct z8530_channel *c) write_zsctrl(c, RES_H_IUS); } +/** + * z8530_tx_clear: + * @c: Z8530 channel to shut up + * + * Transmit interrupt vectors for a Z8530 that is in 'parked' mode. + * For machines with PCI Z85x30 cards, or level triggered interrupts + * (eg the MacII) we must clear the interrupt cause or die. + */ + static void z8530_tx_clear(struct z8530_channel *c) { write_zsctrl(c, RES_Tx_P); write_zsctrl(c, RES_H_IUS); } +/** + * z8530_status_clear: + * @chan: Z8530 channel to shut up + * + * Status interrupt vectors for a Z8530 that is in 'parked' mode. + * For machines with PCI Z85x30 cards, or level triggered interrupts + * (eg the MacII) we must clear the interrupt cause or die. + */ + static void z8530_status_clear(struct z8530_channel *chan) { u8 status=read_zsreg(chan, R0); @@ -541,8 +677,17 @@ struct z8530_irqhandler z8530_nop= EXPORT_SYMBOL(z8530_nop); -/* - * A Z85[2]30 device has stuck its hand in the air for attention +/** + * z8530_interrupt: + * @irq: Interrupt number + * @dev_id: The Z8530 device that is interrupting. + * @regs: unused + * + * A Z85[2]30 device has stuck its hand in the air for attention. + * We scan both the channels on the chip for events and then call + * the channel specific call backs for each channel that has events. + * We have to use callback functions because the two channels can be + * in different modes. */ void z8530_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -612,6 +757,15 @@ static char reg_init[16]= }; +/** + * z8530_sync_open: + * @dev: The network interface we are using + * @c: The Z8530 channel to open in synchronous PIO mode + * + * Switch a Z8530 into synchronous mode without DMA assist. We + * raise the RTS/DTR and commence network operation. + */ + int z8530_sync_open(struct net_device *dev, struct z8530_channel *c) { c->sync = 1; @@ -634,9 +788,19 @@ int z8530_sync_open(struct net_device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_open); +/** + * z8530_sync_close: + * @dev: Network device to close + * @c: Z8530 channel to disassociate and move to idle + * + * Close down a Z8530 interface and switch its interrupt handlers + * to discard future events. + */ + int z8530_sync_close(struct net_device *dev, struct z8530_channel *c) { u8 chk; + c->irqs = &z8530_nop; c->max = 0; c->sync = 0; @@ -649,6 +813,16 @@ int z8530_sync_close(struct net_device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_close); +/** + * z8530_sync_dma_open: + * @dev: The network device to attach + * @c: The Z8530 channel to configure in sync DMA mode. + * + * Set up a Z85x30 device for synchronous DMA in both directions. Two + * ISA DMA channels must be available for this to work. We assume ISA + * DMA driven I/O and PC limits on access. + */ + int z8530_sync_dma_open(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; @@ -753,11 +927,21 @@ int z8530_sync_dma_open(struct net_device *dev, struct z8530_channel *c) c->irqs = &z8530_dma_sync; z8530_rtsdtr(c,1); write_zsreg(c, R3, c->regs[R3]|RxENABLE); + return 0; } EXPORT_SYMBOL(z8530_sync_dma_open); +/** + * z8530_sync_dma_close: + * @dev: Network device to detach + * @c: Z8530 channel to move into discard mode + * + * Shut down a DMA mode synchronous interface. Halt the DMA, and + * free the buffers. + */ + int z8530_sync_dma_close(struct net_device *dev, struct z8530_channel *c) { u8 chk; @@ -814,6 +998,16 @@ int z8530_sync_dma_close(struct net_device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_dma_close); +/** + * z8530_sync_txdma_open: + * @dev: The network device to attach + * @c: The Z8530 channel to configure in sync DMA mode. + * + * Set up a Z85x30 device for synchronous DMA tranmission. One + * ISA DMA channel must be available for this to work. The receive + * side is run in PIO mode, but then it has the bigger FIFO. + */ + int z8530_sync_txdma_open(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; @@ -898,15 +1092,26 @@ int z8530_sync_txdma_open(struct net_device *dev, struct z8530_channel *c) z8530_rtsdtr(c,1); printk("Rx interrupts ON\n"); write_zsreg(c, R3, c->regs[R3]|RxENABLE); + return 0; } EXPORT_SYMBOL(z8530_sync_txdma_open); - + +/** + * z8530_sync_txdma_close: + * @dev: Network device to detach + * @c: Z8530 channel to move into discard mode + * + * Shut down a DMA/PIO split mode synchronous interface. Halt the DMA, + * and free the buffers. + */ + int z8530_sync_txdma_close(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; u8 chk; + c->irqs = &z8530_nop; c->max = 0; c->sync = 0; @@ -950,21 +1155,32 @@ int z8530_sync_txdma_close(struct net_device *dev, struct z8530_channel *c) EXPORT_SYMBOL(z8530_sync_txdma_close); + /* - * Describe a Z8530 in a standard format. We must pass the I/O as - * the port offset isnt predictable. The main reason for this function - * is to try and get a common format of report. + * Name strings for Z8530 chips. SGI claim to have a 130, Zilog deny + * it exists... */ - + static char *z8530_type_name[]={ "Z8530", "Z85C30", "Z85230" }; -void z8530_describe(struct z8530_dev *dev, char *mapping, int io) +/** + * z8530_describe: + * @dev: Z8530 device to describe + * @mapping: string holding mapping type (eg "I/O" or "Mem") + * @io: the port value in question + * + * Describe a Z8530 in a standard format. We must pass the I/O as + * the port offset isnt predictable. The main reason for this function + * is to try and get a common format of report. + */ + +void z8530_describe(struct z8530_dev *dev, char *mapping, unsigned long io) { - printk(KERN_INFO "%s: %s found at %s 0x%X, IRQ %d.\n", + printk(KERN_INFO "%s: %s found at %s 0x%lX, IRQ %d.\n", dev->name, z8530_type_name[dev->type], mapping, @@ -974,8 +1190,21 @@ void z8530_describe(struct z8530_dev *dev, char *mapping, int io) EXPORT_SYMBOL(z8530_describe); -/* - * Configure up a Z8530 +/** + * z8530_init: + * @dev: Z8530 device to initialise. + * + * Configure up a Z8530/Z85C30 or Z85230 chip. We check the device + * is present, identify the type and then program it to hopefully + * keep quite and behave. This matters a lot, a Z8530 in the wrong + * state will sometimes get into stupid modes generating 10Khz + * interrupt streams and the like. + * + * We set the interrupt handler up to discard any events, in case + * we get them during reset or setp. + * + * Return 0 for success, or a negative value indicating the problem + * in errno form. */ @@ -1043,6 +1272,15 @@ int z8530_init(struct z8530_dev *dev) EXPORT_SYMBOL(z8530_init); +/** + * z8530_shutdown: + * @dev: The Z8530 chip to shutdown + * + * We set the interrupt handlers to silence any interrupts. We then + * reset the chip and wait 100uS to be sure the reset completed. Just + * in case the caller then tries to do stuff. + */ + int z8530_shutdown(struct z8530_dev *dev) { /* Reset the chip */ @@ -1055,9 +1293,15 @@ int z8530_shutdown(struct z8530_dev *dev) EXPORT_SYMBOL(z8530_shutdown); -/* - * Load a Z8530 channel up from the system data - * We use +16 to indicate the 'prime' registers +/** + * z8530_channel_load: + * @c: Z8530 channel to configure + * @rtable: Table of register, value pairs + * FIXME: ioctl to allow user uploaded tables + * + * Load a Z8530 channel up from the system data> We use +16 to + * indicate the 'prime' registers. The value 255 terminates the + * table */ int z8530_channel_load(struct z8530_channel *c, u8 *rtable) @@ -1088,8 +1332,16 @@ int z8530_channel_load(struct z8530_channel *c, u8 *rtable) EXPORT_SYMBOL(z8530_channel_load); -/* - * Higher level shovelling - transmit chains +/** + * z8530_tx_begin: + * @c: The Z8530 channel to kick + * + * This is the speed sensitive side of transmission. If we are called + * and no buffer is being transmitted we commence the next buffer. If + * nothing is queued we idle the sync. + * + * Note: We are handling this code path in the interrupt path, keep it + * fast or bad things will happen. */ static void z8530_tx_begin(struct z8530_channel *c) @@ -1102,7 +1354,7 @@ static void z8530_tx_begin(struct z8530_channel *c) c->tx_next_skb=NULL; c->tx_ptr=c->tx_next_ptr; - mark_bh(NET_BH); + netif_wake_queue(c->netdevice); if(c->tx_skb==NULL) { /* Idle on */ @@ -1176,7 +1428,15 @@ static void z8530_tx_begin(struct z8530_channel *c) } } } - + +/** + * z8530_tx_done: + * @c: The channel that completed a transmit. + * + * This is called when we complete a packet send. We wake the queue, + * start the next packet going and then free the buffer of the existing + * packet. This code is fairly timing sensitive. + */ static void z8530_tx_done(struct z8530_channel *c) { @@ -1184,7 +1444,7 @@ static void z8530_tx_done(struct z8530_channel *c) struct sk_buff *skb; spin_lock_irqsave(&z8530_buffer_lock, flags); - c->netdevice->tbusy=0; + netif_wake_queue(c->netdevice); /* Actually this can happen.*/ if(c->tx_skb==NULL) { @@ -1197,11 +1457,16 @@ static void z8530_tx_done(struct z8530_channel *c) spin_unlock_irqrestore(&z8530_buffer_lock, flags); c->stats.tx_packets++; c->stats.tx_bytes+=skb->len; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); } -/* - * Higher level shovelling - receive chains +/** + * z8530_null_rx: + * @c: The channel the packet arrived on + * @skb: The buffer + * + * We point the receive handler at this function when idle. Instead + * of syncppp processing the frames we get to throw them away. */ void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb) @@ -1211,6 +1476,17 @@ void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb) EXPORT_SYMBOL(z8530_null_rx); +/** + * z8530_rx_done: + * @c: The channel that completed a receive + * + * A new packet is complete. Our goal here is to get back into receive + * mode as fast as possible. On the Z85230 we could change to using + * ESCC mode, but on the older chips we have no choice. We flip to the + * new buffer immediately in DMA mode so that the DMA of the next + * frame can occur while we are copying the previous buffer to an sk_buff + */ + static void z8530_rx_done(struct z8530_channel *c) { struct sk_buff *skb; @@ -1265,7 +1541,7 @@ static void z8530_rx_done(struct z8530_channel *c) else /* Can't occur as we dont reenable the DMA irq until after the flip is done */ - printk("DMA flip overrun!\n"); + printk(KERN_WARNING "%s: DMA flip overrun!\n", c->netdevice->name); release_dma_lock(flags); @@ -1353,8 +1629,12 @@ static void z8530_rx_done(struct z8530_channel *c) } } -/* - * Cannot DMA over a 64K boundary on a PC +/** + * spans_boundary: + * @skb: The buffer to check + * + * Returns true if the buffer cross a DMA boundary on a PC. The poor + * thing can only DMA within a 64K block not across the edges of it. */ extern inline int spans_boundary(struct sk_buff *skb) @@ -1369,7 +1649,11 @@ extern inline int spans_boundary(struct sk_buff *skb) return 0; } -/* +/** + * z8530_queue_xmit: + * @c: The channel to use + * @skb: The packet to kick down the channel + * * Queue a packet for transmission. Because we have rather * hard to hit interrupt latencies for the Z85230 per packet * even in DMA mode we do the flip to DMA buffer if needed here @@ -1379,9 +1663,10 @@ extern inline int spans_boundary(struct sk_buff *skb) int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb) { unsigned long flags; + + netif_stop_queue(c->netdevice); if(c->tx_next_skb) { - skb->dev->tbusy=1; return 1; } @@ -1414,11 +1699,21 @@ int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb) spin_lock_irqsave(&z8530_buffer_lock, flags); z8530_tx_begin(c); spin_unlock_irqrestore(&z8530_buffer_lock, flags); + + netif_wake_queue(c->netdevice); return 0; } EXPORT_SYMBOL(z8530_queue_xmit); +/** + * z8530_get_stats: + * @c: The channel to use + * + * Get the statistics block. We keep the statistics in software as + * the chip doesn't do it for us. + */ + struct net_device_stats *z8530_get_stats(struct z8530_channel *c) { return &c->stats; diff --git a/drivers/net/wan/z85230.h b/drivers/net/wan/z85230.h index dcad711b0..8dc92a535 100644 --- a/drivers/net/wan/z85230.h +++ b/drivers/net/wan/z85230.h @@ -304,8 +304,8 @@ struct z8530_channel */ struct z8530_dev *dev; /* Z85230 chip instance we are from */ - int ctrlio; /* I/O ports */ - int dataio; + unsigned long ctrlio; /* I/O ports */ + unsigned long dataio; /* * For PC we encode this way. @@ -395,7 +395,7 @@ extern u8 z8530_dead_port[]; extern u8 z8530_hdlc_kilostream_85230[]; extern u8 z8530_hdlc_kilostream[]; extern void z8530_interrupt(int, void *, struct pt_regs *); -extern void z8530_describe(struct z8530_dev *, char *mapping,int io); +extern void z8530_describe(struct z8530_dev *, char *mapping, unsigned long io); extern int z8530_init(struct z8530_dev *); extern int z8530_shutdown(struct z8530_dev *); extern int z8530_sync_open(struct net_device *, struct z8530_channel *); |