patch-2.3.22 linux/drivers/net/wan/cosa.c
Next file: linux/drivers/net/wan/cycx_x25.c
Previous file: linux/drivers/net/tokenring/tms380tr_microcode.h
Back to the patch index
Back to the overall index
- Lines: 200
- Date:
Thu Oct 14 14:29:57 1999
- Orig file:
v2.3.21/linux/drivers/net/wan/cosa.c
- Orig date:
Mon Oct 11 15:38:15 1999
diff -u --recursive --new-file v2.3.21/linux/drivers/net/wan/cosa.c linux/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 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 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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
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 @@
/* 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;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)