patch-2.1.115 linux/drivers/char/cyclades.c
Next file: linux/drivers/char/keyboard.c
Previous file: linux/drivers/char/console.c
Back to the patch index
Back to the overall index
- Lines: 313
- Date:
Tue Aug 4 15:00:04 1998
- Orig file:
v2.1.114/linux/drivers/char/cyclades.c
- Orig date:
Sun Jun 7 11:16:29 1998
diff -u --recursive --new-file v2.1.114/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
@@ -1,7 +1,7 @@
#define BLOCKMOVE
#define Z_WAKE
static char rcsid[] =
-"$Revision: 2.2.1.3 $$Date: 1998/06/01 12:09:10 $";
+"$Revision: 2.2.1.4 $$Date: 1998/08/04 11:02:50 $";
/*
* linux/drivers/char/cyclades.c
@@ -31,6 +31,12 @@
* void cleanup_module(void);
*
* $Log: cyclades.c,v $
+ * Revision 2.2.1.4 1998/08/04 11:02:50 ivan
+ * /proc/cyclades implementation with great collaboration of
+ * Marc Lewis <marc@blarg.net>;
+ * cyy_interrupt was changed to avoid occurence of kernel oopses
+ * during PPP operation.
+ *
* Revision 2.2.1.3 1998/06/01 12:09:10 ivan
* General code review in order to comply with 2.1 kernel standards;
* data loss prevention for slow devices revisited (cy_wait_until_sent
@@ -143,7 +149,7 @@
* Price <stevep@fa.tdktca.com> for help on this)
*
* Revision 1.36.4.21 1996/09/10 17:00:10 bentson
- * shift from cpu-bound to memcopy in cyz_polling operation
+ * shift from CPU-bound to memcopy in cyz_polling operation
*
* Revision 1.36.4.20 1996/09/09 18:30:32 Bentson
* Added support to set and report higher speeds.
@@ -557,6 +563,10 @@
#include <linux/pci.h>
#include <linux/version.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#endif
#define cy_put_user put_user
@@ -589,6 +599,8 @@
#define STD_COM_FLAGS (0)
+#define JIFFIES_DIFF(n, j) ((n) >= (j) ? (n) - (j) : ULONG_MAX - (n) + (j))
+
static DECLARE_TASK_QUEUE(tq_cyclades);
static struct tty_driver cy_serial_driver, cy_callout_driver;
@@ -748,6 +760,10 @@
static void show_status(int);
#endif
+#ifdef CONFIG_PROC_FS
+static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
+#endif
+
/* The Cyclades-Z polling cycle is defined by this variable */
static long cyz_polling_cycle = CZ_DEF_POLL;
@@ -1202,11 +1218,13 @@
TTY_FRAME;
*tty->flip.char_buf_ptr++ =
cy_readb(base_addr+(CyRDSR<<index));
+ info->idle_stats.frame_errs++;
}else if(data & CyPARITY){
*tty->flip.flag_buf_ptr++ =
TTY_PARITY;
*tty->flip.char_buf_ptr++ =
cy_readb(base_addr+(CyRDSR<<index));
+ info->idle_stats.parity_errs++;
}else if(data & CyOVERRUN){
*tty->flip.flag_buf_ptr++ =
TTY_OVERRUN;
@@ -1223,6 +1241,7 @@
*tty->flip.char_buf_ptr++ =
cy_readb(base_addr+(CyRDSR<<index));
}
+ info->idle_stats.overruns++;
/* These two conditions may imply */
/* a normal read should be done. */
/* }else if(data & CyTIMEOUT){ */
@@ -1239,6 +1258,7 @@
/* there was a software buffer
overrun and nothing could be
done about it!!! */
+ info->idle_stats.overruns++;
}
} else { /* normal character reception */
/* load # chars available from the chip */
@@ -1251,6 +1271,8 @@
info->mon.char_max = char_count;
info->mon.char_last = char_count;
#endif
+ info->idle_stats.recv_bytes += char_count;
+ info->idle_stats.recv_idle = jiffies;
while(char_count--){
if (tty->flip.count >= TTY_FLIPBUF_SIZE){
break;
@@ -1345,25 +1367,25 @@
info->x_break = 0;
}
- if (!info->xmit_cnt){
- cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
- goto txdone;
- }
- if (info->xmit_buf == 0){
- cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
- goto txdone;
- }
- if (info->tty->stopped || info->tty->hw_stopped){
- cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
- goto txdone;
- }
while (char_count-- > 0){
- if (!info->xmit_cnt){
+ if (!info->xmit_cnt){
+ cy_writeb((u_long)base_addr+(CySRER<<index),
+ cy_readb(base_addr+(CySRER<<index)) &
+ ~CyTxMpty);
+ goto txdone;
+ }
+ if (info->xmit_buf == 0){
+ cy_writeb((u_long)base_addr+(CySRER<<index),
+ cy_readb(base_addr+(CySRER<<index)) &
+ ~CyTxMpty);
goto txdone;
- }
+ }
+ if (info->tty->stopped || info->tty->hw_stopped){
+ cy_writeb((u_long)base_addr+(CySRER<<index),
+ cy_readb(base_addr+(CySRER<<index)) &
+ ~CyTxMpty);
+ goto txdone;
+ }
/* Because the Embedded Transmit Commands have
been enabled, we must check to see if the
escape character, NULL, is being sent. If it
@@ -1737,6 +1759,8 @@
info->mon.char_max = char_count;
info->mon.char_last = char_count;
#endif
+ info->idle_stats.recv_bytes += char_count;
+ info->idle_stats.recv_idle = jiffies;
if( tty == 0){
/* flush received characters */
rx_get = (rx_get + char_count) & (rx_bufsize - 1);
@@ -1952,6 +1976,10 @@
clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+ memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
+ info->idle_stats.in_use =
+ info->idle_stats.recv_idle =
+ info->idle_stats.xmit_idle = jiffies;
restore_flags(flags);
} else {
struct FIRM_ID *firm_id;
@@ -2013,6 +2041,10 @@
}
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+ memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
+ info->idle_stats.in_use =
+ info->idle_stats.recv_idle =
+ info->idle_stats.xmit_idle = jiffies;
}
#ifdef CY_DEBUG_OPEN
@@ -2787,6 +2819,10 @@
ret += c;
}
}
+
+ info->idle_stats.xmit_bytes += ret;
+ info->idle_stats.xmit_idle = jiffies;
+
if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
start_xmit(info);
}
@@ -2826,6 +2862,8 @@
info->xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= SERIAL_XMIT_SIZE - 1;
info->xmit_cnt++;
+ info->idle_stats.xmit_bytes++;
+ info->idle_stats.xmit_idle = jiffies;
restore_flags(flags);
} /* cy_put_char */
@@ -3924,10 +3962,13 @@
case CYGETCD1400VER:
ret_val = info->chip_rev;
break;
- case CYZPOLLCYCLE:
- cyz_polling_cycle = (HZ * arg) / 1000;
+ case CYZSETPOLLCYCLE:
+ cyz_polling_cycle = (arg * HZ) / 1000;
ret_val = 0;
break;
+ case CYZGETPOLLCYCLE:
+ ret_val = (cyz_polling_cycle * 1000) / HZ;
+ break;
case CYSETWAIT:
info->closing_wait = (unsigned short)arg * HZ/100;
ret_val = 0;
@@ -4876,6 +4917,65 @@
__DATE__, __TIME__);
} /* show_version */
+#ifdef CONFIG_PROC_FS
+static int
+cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
+ int *eof, void *data)
+{
+ struct cyclades_port *info;
+ int i;
+ int len=0;
+ off_t begin=0;
+ off_t pos=0;
+ int size;
+ __u32 cur_jifs = jiffies;
+
+ size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn IdleIn Overruns Ldisc\n");
+
+ pos += size;
+ len += size;
+
+ /* Output one line for each known port */
+ for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
+ info = &cy_port[i];
+
+ if (info->count)
+ size = sprintf(buf+len,
+ "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
+ info->line,
+ JIFFIES_DIFF(info->idle_stats.in_use, cur_jifs) / HZ,
+ info->idle_stats.xmit_bytes,
+ JIFFIES_DIFF(info->idle_stats.xmit_idle, cur_jifs) / HZ,
+ info->idle_stats.recv_bytes,
+ JIFFIES_DIFF(info->idle_stats.recv_idle, cur_jifs) / HZ,
+ info->idle_stats.overruns,
+ info->tty->ldisc.num);
+ else
+ size = sprintf(buf+len,
+ "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
+ info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+ len += size;
+ pos = begin + len;
+
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if (pos > offset + length)
+ goto done;
+ }
+ *eof = 1;
+done:
+ *start = buf + (offset - begin); /* Start of wanted data */
+ len -= (offset - begin); /* Start slop */
+ if (len > length)
+ len = length; /* Ending slop */
+ if (len < 0)
+ len = 0;
+ return len;
+}
+#endif
+
/* The serial driver boot-time initialization code!
Hardware I/O ports are mapped to character special devices on a
@@ -4905,6 +5005,7 @@
unsigned long mailbox;
unsigned short chip_number;
int nports;
+ struct proc_dir_entry *ent;
show_version();
@@ -5145,6 +5246,16 @@
#endif
}
+#ifdef CONFIG_PROC_FS
+ ent = create_proc_entry("cyclades", S_IFREG | S_IRUGO, 0);
+ ent->read_proc = cyclades_get_proc_info;
+#endif
+#if 0
+#ifdef CONFIG_PROC_FS
+ proc_register(&proc_root, &cyclades_proc_entry);
+#endif
+#endif
+
return 0;
} /* cy_init */
@@ -5187,6 +5298,10 @@
free_irq(cy_card[i].irq,NULL);
}
}
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry("cyclades", 0);
+#endif
+
} /* cleanup_module */
#else
/* called by linux/init/main.c to parse command line options */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov