diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-21 22:34:01 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-21 22:34:01 +0000 |
commit | 9e30c3705aed9fbec4c3304570e4d6e707856bcb (patch) | |
tree | b19e6acb5a67af31a4e7742e05c2166dc3f1444c /drivers/net/wan | |
parent | 72919904796333a20c6a5d5c380091b42e407aa9 (diff) |
Merge with Linux 2.3.22.
Diffstat (limited to 'drivers/net/wan')
-rw-r--r-- | drivers/net/wan/cosa.c | 74 | ||||
-rw-r--r-- | drivers/net/wan/cycx_x25.c | 50 | ||||
-rw-r--r-- | drivers/net/wan/sbni.c | 20 |
3 files changed, 92 insertions, 52 deletions
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 863cd4b59..a48c5d31c 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -1,4 +1,4 @@ -/* $Id: cosa.c,v 1.26 1999/07/09 15:02:37 kas Exp $ */ +/* $Id: cosa.c,v 1.28 1999/10/11 21:06:58 kas Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <kas@fi.muni.cz> @@ -137,8 +137,7 @@ struct channel_data { struct semaphore rsem, wsem; char *rxdata; int rxsize; - wait_queue_head_t txwaitq; - wait_queue_head_t rxwaitq; + wait_queue_head_t txwaitq, rxwaitq; int tx_status, rx_status; /* SPPP/HDLC device parts */ @@ -147,6 +146,11 @@ struct channel_data { struct net_device_stats stats; }; +/* cosa->firmware_status bits */ +#define COSA_FW_RESET (1<<0) /* Is the ROM monitor active? */ +#define COSA_FW_DOWNLOAD (1<<1) /* Is the microcode downloaded? */ +#define COSA_FW_START (1<<2) /* Is the microcode running? */ + struct cosa_data { int num; /* Card number */ char name[COSA_MAX_NAME]; /* Card name - e.g "cosa0" */ @@ -606,6 +610,11 @@ static int cosa_sppp_open(struct net_device *d) struct channel_data *chan = d->priv; int err, flags; + if (!(chan->cosa->firmware_status & COSA_FW_START)) { + printk(KERN_NOTICE "%s: start the firmware first (status %d)\n", + chan->cosa->name, chan->cosa->firmware_status); + return -EPERM; + } spin_lock_irqsave(&chan->cosa->lock, flags); if (chan->usage != 0) { printk(KERN_WARNING "%s: sppp_open called with usage count %d\n", @@ -781,6 +790,11 @@ static ssize_t cosa_read(struct file *file, struct cosa_data *cosa = chan->cosa; char *kbuf; + if (!(cosa->firmware_status & COSA_FW_START)) { + printk(KERN_NOTICE "%s: start the firmware first (status %d)\n", + cosa->name, cosa->firmware_status); + return -EPERM; + } if (down_interruptible(&chan->rsem)) return -ERESTARTSYS; @@ -845,12 +859,17 @@ static int chrdev_rx_done(struct channel_data *chan) static ssize_t cosa_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { - struct channel_data *chan = (struct channel_data *)file->private_data; DECLARE_WAITQUEUE(wait, current); + struct channel_data *chan = (struct channel_data *)file->private_data; struct cosa_data *cosa = chan->cosa; unsigned int flags; char *kbuf; + if (!(cosa->firmware_status & COSA_FW_START)) { + printk(KERN_NOTICE "%s: start the firmware first (status %d)\n", + cosa->name, cosa->firmware_status); + return -EPERM; + } if (down_interruptible(&chan->wsem)) return -ERESTARTSYS; @@ -992,12 +1011,14 @@ static inline int cosa_reset(struct cosa_data *cosa) if (cosa->usage > 1) printk(KERN_INFO "cosa%d: WARNING: reset requested with cosa->usage > 1 (%d). Odd things may happen.\n", cosa->num, cosa->usage); + cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_START); if (cosa_reset_and_read_id(cosa, idstring) < 0) { printk(KERN_NOTICE "cosa%d: reset failed\n", cosa->num); return -EIO; } printk(KERN_INFO "cosa%d: resetting device: %s\n", cosa->num, idstring); + cosa->firmware_status |= COSA_FW_RESET; return 0; } @@ -1009,15 +1030,14 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d) char *code; if (cosa->usage > 1) - printk(KERN_INFO "cosa%d: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", - cosa->num, cosa->usage); -#if 0 - if (cosa->status != CARD_STATUS_RESETED && cosa->status != CARD_STATUS_DOWNLOADED) { - printk(KERN_NOTICE "cosa%d: reset the card first (status %d).\n", - cosa->num, cosa->status); + printk(KERN_INFO "%s: WARNING: download of microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", + cosa->name, cosa->usage); + if (!(cosa->firmware_status & COSA_FW_RESET)) { + printk(KERN_NOTICE "%s: reset the card first (status %d).\n", + cosa->name, cosa->firmware_status); return -EPERM; } -#endif + get_user_ret(addr, &(d->addr), -EFAULT); get_user_ret(len, &(d->len), -EFAULT); get_user_ret(code, &(d->code), -EFAULT); @@ -1027,6 +1047,9 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d) if (d->len < 0 || d->len > COSA_MAX_FIRMWARE_SIZE) return -EINVAL; + /* If something fails, force the user to reset the card */ + cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_DOWNLOAD); + if ((i=download(cosa, d->code, len, addr)) < 0) { printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n", cosa->num, i); @@ -1034,6 +1057,7 @@ static inline int cosa_download(struct cosa_data *cosa, struct cosa_download *d) } printk(KERN_INFO "cosa%d: downloading microcode - 0x%04x bytes at 0x%04x\n", cosa->num, len, addr); + cosa->firmware_status |= COSA_FW_RESET|COSA_FW_DOWNLOAD; return 0; } @@ -1048,18 +1072,19 @@ static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d) printk(KERN_INFO "cosa%d: WARNING: readmem requested with " "cosa->usage > 1 (%d). Odd things may happen.\n", cosa->num, cosa->usage); -#if 0 - if (cosa->status != CARD_STATUS_RESETED && - cosa->status != CARD_STATUS_DOWNLOADED) { - printk(KERN_NOTICE "cosa%d: reset the card first (status %d).\n", - cosa->num, cosa->status); + if (!(cosa->firmware_status & COSA_FW_RESET)) { + printk(KERN_NOTICE "%s: reset the card first (status %d).\n", + cosa->name, cosa->firmware_status); return -EPERM; } -#endif + get_user_ret(addr, &(d->addr), -EFAULT); get_user_ret(len, &(d->len), -EFAULT); get_user_ret(code, &(d->code), -EFAULT); + /* If something fails, force the user to reset the card */ + cosa->firmware_status &= ~COSA_FW_RESET; + if ((i=readmem(cosa, d->code, len, addr)) < 0) { printk(KERN_NOTICE "cosa%d: reading memory failed: %d\n", cosa->num, i); @@ -1067,6 +1092,7 @@ static inline int cosa_readmem(struct cosa_data *cosa, struct cosa_download *d) } printk(KERN_INFO "cosa%d: reading card memory - 0x%04x bytes at 0x%04x\n", cosa->num, len, addr); + cosa->firmware_status |= COSA_FW_RESET; return 0; } @@ -1078,13 +1104,14 @@ static inline int cosa_start(struct cosa_data *cosa, int address) if (cosa->usage > 1) printk(KERN_INFO "cosa%d: WARNING: start microcode requested with cosa->usage > 1 (%d). Odd things may happen.\n", cosa->num, cosa->usage); -#if 0 - if (cosa->status != CARD_STATUS_DOWNLOADED) { - printk(KERN_NOTICE "cosa%d: download the microcode first (status %d).\n", - cosa->num, cosa->status); + + if ((cosa->firmware_status & (COSA_FW_RESET|COSA_FW_DOWNLOAD)) + != (COSA_FW_RESET|COSA_FW_DOWNLOAD)) { + printk(KERN_NOTICE "%s: download the microcode and/or reset the card first (status %d).\n", + cosa->name, cosa->firmware_status); return -EPERM; } -#endif + cosa->firmware_status &= ~COSA_FW_RESET; if ((i=startmicrocode(cosa, address)) < 0) { printk(KERN_NOTICE "cosa%d: start microcode at 0x%04x failed: %d\n", cosa->num, address, i); @@ -1093,6 +1120,7 @@ static inline int cosa_start(struct cosa_data *cosa, int address) printk(KERN_INFO "cosa%d: starting microcode at 0x%04x\n", cosa->num, address); cosa->startaddr = address; + cosa->firmware_status |= COSA_FW_START; return 0; } @@ -1689,9 +1717,11 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) /* in second pass, accept first ready-to-TX channel */ if (i > cosa->nchannels) { /* Can be safely ignored */ +#ifdef DEBUG_IRQS printk(KERN_DEBUG "%s: Forcing TX " "to not-ready channel %d\n", cosa->name, cosa->txchan); +#endif break; } } diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 7e79943c0..40f76b2a5 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -11,6 +11,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/10/09 acme chan_disc renamed to chan_disconnect, +* began adding support for X.25 sockets: +* conf->protocol in new_if +* 1999/10/05 acme fixed return E... to return -E... * 1999/08/10 acme serialized access to the card thru a spinlock * in x25_exec * 1999/08/09 acme removed per channel spinlocks @@ -132,16 +136,19 @@ static int x25_configure (cycx_t *card, TX25Config *conf), x25_connect_response (cycx_t *card, x25_channel_t *chan), x25_disconnect_response (cycx_t *card, u8 link, u8 lcn); -/* Miscellaneous functions */ -static int chan_connect (struct net_device *dev), - chan_send (struct net_device *dev, struct sk_buff *skb); +/* channel functions */ +int chan_connect (struct net_device *dev), + chan_send (struct net_device *dev, struct sk_buff *skb); + +static void chan_disconnect (struct net_device *dev); +/* Miscellaneous functions */ static void set_chan_state (struct net_device *dev, u8 state), - nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble), - reset_timer (struct net_device *dev), - chan_disc (struct net_device *dev), chan_timer (unsigned long d); +static void nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble), + reset_timer (struct net_device *dev); + static u8 bps_to_speed_code (u32 bps); static u8 log2 (u32 n); @@ -334,7 +341,7 @@ static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *c strcpy(chan->name, conf->name); chan->card = card; chan->link = conf->port; - chan->protocol = ETH_P_IP; + chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP; chan->rx_skb = NULL; /* only used in svc connected thru crossover cable */ chan->local_addr = NULL; @@ -353,7 +360,7 @@ static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *c if (!chan->local_addr) { kfree(chan); - return ENOMEM; + return -ENOMEM; } } @@ -505,7 +512,7 @@ static int if_close (struct net_device *dev) dev->start = 0; if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING) - chan_disc(dev); + chan_disconnect(dev); cyclomx_close(card); return 0; @@ -763,7 +770,7 @@ static void rx_intr (cycx_t *card, TX25Cmd *cmd) dev->last_rx = jiffies; /* timestamp */ chan->rx_skb = NULL; /* dequeue packet */ - skb->protocol = htons(ETH_P_IP); + skb->protocol = htons(chan->protocol); skb->dev = dev; skb->mac.raw = skb->data; netif_rx(skb); @@ -799,6 +806,7 @@ static void connect_intr (cycx_t *card, TX25Cmd *cmd) dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n", lcn, loc, rem); + if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) { /* Invalid channel, discard packet */ printk(KERN_INFO "%s: connect not expected: remote %s!\n", @@ -824,6 +832,7 @@ static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd) cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key)); dprintk(KERN_INFO "%s: connect_confirm_intr:lcn=%d, key=%d\n", card->devname, lcn, key); + if ((dev = get_dev_by_lcn(wandev, -key)) == NULL) { /* Invalid channel, discard packet */ clear_bit(--key, (void*)&card->u.x.connection_keys); @@ -1139,10 +1148,8 @@ static int x25_place_call (cycx_t *card, x25_channel_t *chan) if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link, &d, 7 + len + 1, NULL, 0)) != 0) clear_bit(--key, (void*)&card->u.x.connection_keys); - else { + else chan->lcn = -key; - chan->protocol = ETH_P_IP; - } return err; } @@ -1229,7 +1236,7 @@ static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) * Return: 0 connected * >0 connection in progress * <0 failure */ -static int chan_connect (struct net_device *dev) +int chan_connect (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1251,7 +1258,7 @@ static int chan_connect (struct net_device *dev) /* Disconnect logical channel. * o if SVC then clear X.25 call */ -static void chan_disc (struct net_device *dev) +static void chan_disconnect (struct net_device *dev) { x25_channel_t *chan = dev->priv; @@ -1270,7 +1277,7 @@ static void chan_timer (unsigned long d) switch (chan->state) { case WAN_CONNECTED: - chan_disc(dev); + chan_disconnect(dev); break; default: printk (KERN_ERR "%s: chan_timer for svc (%s) not " @@ -1345,7 +1352,7 @@ static void set_chan_state (struct net_device *dev, u8 state) * the packet into 'complete sequence' using M-bit. * 2. When transmission is complete, an event notification should be issued * to the router. */ -static int chan_send (struct net_device *dev, struct sk_buff *skb) +int chan_send (struct net_device *dev, struct sk_buff *skb) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1473,14 +1480,15 @@ static void x25_dump_devs(wan_device_t *wandev) struct net_device *dev = wandev->dev; printk (KERN_INFO "x25 dev states\n"); - printk (KERN_INFO "name: addr: tbusy:\n"); - printk (KERN_INFO "----------------------------\n"); + printk (KERN_INFO "name: addr: tbusy: protocol:\n"); + printk (KERN_INFO "---------------------------------------\n"); for (; dev; dev = dev->slave) { x25_channel_t *chan = dev->priv; - printk (KERN_INFO "%-5.5s %-15.15s %ld\n", - chan->name, chan->addr, dev->tbusy); + printk (KERN_INFO "%-5.5s %-15.15s %ld ETH_P_%s\n", + chan->name, chan->addr, dev->tbusy, + chan->protocol == ETH_P_IP ? "IP" : "X25"); } } diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 9d5fba082..4cf0c05a1 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -1280,10 +1280,12 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EPERM; if(copy_from_user( tmpstr, ifr->ifr_data, 6)) return -EFAULT; - slave=dev_get(tmpstr); + slave = dev_get_by_name(tmpstr); if(!(slave && slave->flags & IFF_UP && dev->flags & IFF_UP)) { printk("%s: Both devices should be UP to enslave!\n",dev->name); + if (slave) + dev_put(slave); return -EINVAL; } @@ -1304,8 +1306,9 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) else { printk("%s: one of devices is already slave!\n",dev->name); - return -EBUSY; + error = -EBUSY; } + dev_put(slave); } else { @@ -1359,7 +1362,7 @@ static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) unsigned long calc_crc(char *mem, int len, unsigned initial) { - + unsigned crc, dummy_len; __asm__ ( "xorl %%eax,%%eax\n\t" "1:\n\t" @@ -1367,13 +1370,12 @@ unsigned long calc_crc(char *mem, int len, unsigned initial) "xorb %%dl,%%al\n\t" "shrl $8,%%edx\n\t" "xorl (%%edi,%%eax,4),%%edx\n\t" - "loop 1b\n\t" - "movl %%edx,%%eax" - : - : "S" (mem), "D" (&crc32tab[0]), "c" (len), "d" (initial) - : "eax", "edx", "ecx" + "loop 1b" + : "=d" (crc), "=c" (dummy_len) + : "S" (mem), "D" (&crc32tab[0]), "1" (len), "0" (initial) + : "eax" ); - /* return crc; */ + return crc; } #else |