patch-2.2.15 linux/drivers/char/stallion.c
Next file: linux/drivers/char/sx.c
Previous file: linux/drivers/char/specialix.c
Back to the patch index
Back to the overall index
- Lines: 202
- Date:
Fri Apr 21 12:46:06 2000
- Orig file:
v2.2.14/drivers/char/stallion.c
- Orig date:
Sat Aug 14 02:25:40 1999
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/char/stallion.c linux/drivers/char/stallion.c
@@ -3,8 +3,8 @@
/*
* stallion.c -- stallion multiport serial driver.
*
- * Copyright (C) 1996-1999 Stallion Technologies (support@stallion.oz.au).
- * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au).
+ * Copyright (C) 1996-2000 Stallion Technologies (support@stallion.oz.au)
+ * Copyright (C) 1994-1996 Greg Ungerer.
*
* This code is loosely based on the Linux serial driver, written by
* Linus Torvalds, Theodore T'so and others.
@@ -28,6 +28,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/version.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/tty_flip.h>
@@ -47,6 +48,7 @@
#include <linux/pci.h>
#endif
+
/*****************************************************************************/
/*
@@ -127,6 +129,7 @@
#define STL_TXBUFLOW 512
#define STL_TXBUFSIZE 4096
+#define STL_IRQ_DEVID (&stl_brds[0])
/*****************************************************************************/
/*
@@ -135,7 +138,7 @@
*/
static char *stl_drvtitle = "Stallion Multiport Serial Driver";
static char *stl_drvname = "stallion";
-static char *stl_drvversion = "5.5.1";
+static char *stl_drvversion = "5.6.0";
static char *stl_serialname = "ttyE";
static char *stl_calloutname = "cue";
@@ -313,7 +316,7 @@
/*
* Define the module agruments.
*/
-MODULE_AUTHOR("Greg Ungerer");
+MODULE_AUTHOR("Stallion Technologies (support@stallion.oz.au)");
MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
MODULE_PARM(board0, "1-4s");
@@ -345,6 +348,7 @@
#define ID_BRD4 0x10
#define ID_BRD8 0x20
#define ID_BRD16 0x30
+#define ID_BRD4_422 0x40 /* 4 port EIO supporting RS422*/
#define EIO_INTRPEND 0x08
#define EIO_INTEDGE 0x00
@@ -523,6 +527,8 @@
static int stl_getbrdstats(combrd_t *bp);
static int stl_getportstats(stlport_t *portp, comstats_t *cp);
static int stl_clrportstats(stlport_t *portp, comstats_t *cp);
+static int stl_geticounters(stlport_t *portp,
+ struct serial_icounter_struct *cp);
static int stl_getportstruct(unsigned long arg);
static int stl_getbrdstruct(unsigned long arg);
static int stl_waitcarrier(stlport_t *portp, struct file *filp);
@@ -853,7 +859,7 @@
}
for (i = 0; (i < stl_numintrs); i++)
- free_irq(stl_gotintrs[i], NULL);
+ free_irq(stl_gotintrs[i], STL_IRQ_DEVID);
restore_flags(flags);
}
@@ -1599,7 +1605,8 @@
return(-ENODEV);
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
- (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
+ (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS) &&
+ (cmd != TIOCGICOUNT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
return(-EIO);
}
@@ -1671,6 +1678,13 @@
sizeof(comstats_t))) == 0)
rc = stl_clrportstats(portp, (comstats_t *) arg);
break;
+ case TIOCGICOUNT:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(struct serial_icounter_struct *))) == 0)
+ rc = stl_geticounters(portp,
+ (struct serial_icounter_struct *) arg);
+ break;
+
case TIOCSERCONFIG:
case TIOCSERGWILD:
case TIOCSERSWILD:
@@ -1869,6 +1883,7 @@
stl_flush(portp);
wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible(&tty->poll_wait);
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
@@ -2253,6 +2268,7 @@
tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible(&tty->poll_wait);
}
if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
clear_bit(ASYI_DCDCHANGE, &portp->istate);
@@ -2294,7 +2310,8 @@
break;
}
if (i >= stl_numintrs) {
- if (request_irq(irq, stl_intr, SA_INTERRUPT, name, NULL) != 0) {
+ if (request_irq(irq, stl_intr, SA_SHIRQ, name,
+ STL_IRQ_DEVID) != 0) {
printk("STALLION: failed to register interrupt "
"routine for %s irq=%d\n", name, irq);
rc = -ENODEV;
@@ -2348,6 +2365,8 @@
portp->callouttermios = stl_deftermios;
portp->tqueue.routine = stl_offintr;
portp->tqueue.data = portp;
+ portp->open_wait = 0;
+ portp->close_wait = 0;
portp->stats.brd = portp->brdnr;
portp->stats.panel = portp->panelnr;
portp->stats.port = portp->portnr;
@@ -2445,6 +2464,9 @@
case ID_BRD16:
brdp->nrports = 16;
break;
+ case ID_BRD4_422:
+ brdp->nrports = 4;
+ break;
default:
return(-ENODEV);
}
@@ -2780,7 +2802,7 @@
#if DEBUG
printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
- dev->bus->number, dev->devfn);
+ devp->bus->number, devp->devfn);
#endif
if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
@@ -3084,6 +3106,28 @@
return(0);
}
+static int stl_geticounters(stlport_t *portp,
+ struct serial_icounter_struct *icp)
+{
+ struct serial_icounter_struct icount;
+ comstats_t *s = &portp->stats;
+
+ memset(&icount, 0, sizeof(icount));
+ /*
+ * we only support a subset of the icounters - the others are handled
+ * by the uart and we don't get interrupted for them
+ */
+ icount.dcd = s->modem;
+ icount.rx = s->rxtotal;
+ icount.tx = s->txtotal;
+ icount.frame = s->rxframing;
+ icount.overrun = s->rxoverrun;
+ icount.parity = s->rxparity;
+ icount.brk = s->rxbreaks;
+
+ return (copy_to_user(icp, &icount, sizeof(icount)));
+}
+
/*****************************************************************************/
/*
@@ -4209,6 +4253,7 @@
if ((tty == (struct tty_struct *) NULL) ||
(tty->flip.char_buf_ptr == (char *) NULL) ||
((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
+ len = MIN(len, sizeof(stl_unwanted));
outb((RDSR + portp->uartaddr), ioaddr);
insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
portp->stats.rxlost += len;
@@ -5175,6 +5220,7 @@
if ((tty == (struct tty_struct *) NULL) ||
(tty->flip.char_buf_ptr == (char *) NULL) ||
((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
+ len = MIN(len, sizeof(stl_unwanted));
outb(GRXFIFO, (ioaddr + XP_ADDR));
insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
portp->stats.rxlost += len;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)