patch-2.0.35 linux/drivers/char/istallion.c
Next file: linux/drivers/char/lp.c
Previous file: linux/drivers/char/ftape/kernel-interface.h
Back to the patch index
Back to the overall index
- Lines: 1687
- Date:
Mon Jul 13 13:47:29 1998
- Orig file:
v2.0.34/linux/drivers/char/istallion.c
- Orig date:
Mon May 6 02:26:05 1996
diff -u --recursive --new-file v2.0.34/linux/drivers/char/istallion.c linux/drivers/char/istallion.c
@@ -3,6 +3,7 @@
/*
* istallion.c -- stallion intelligent multiport serial driver.
*
+ * Copyright (C) 1996-1998 Stallion Technologies (support@stallion.oz.au).
* Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au).
*
* This code is loosely based on the Linux serial driver, written by
@@ -73,6 +74,8 @@
#define BRD_ECPE 24
#define BRD_ECPMC 25
#define BRD_ECHPCI 26
+#define BRD_ECH64PCI 27
+#define BRD_EASYIOPCI 28
#define BRD_BRUMBY BRD_BRUMBY4
@@ -90,6 +93,12 @@
* boards can share the same shared memory address space. No interrupt
* is required for this board type.
* Another example:
+ * { BRD_ECPE, 0x5000, 0, 0x80000000, 0, 0 },
+ * This line will configure an EasyConnection 8/64 EISA in slot 5 and
+ * shared memory address of 0x80000000 (2 GByte). Multiple
+ * EasyConnection 8/64 EISA boards can share the same shared memory
+ * address space. No interrupt is required for this board type.
+ * Another example:
* { BRD_ONBOARD, 0x240, 0, 0xd0000, 0, 0 },
* This line will configure an ONboard (ISA type) at io address 240,
* and shared memory address of d0000. Multiple ONboards can share
@@ -156,8 +165,8 @@
* Define our local driver identity first. Set up stuff to deal with
* all the local structures required by a serial tty driver.
*/
-static char *stli_drvname = "Stallion Intelligent Multiport Serial Driver";
-static char *stli_drvversion = "1.1.3";
+static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver";
+static char *stli_drvversion = "5.4.4";
static char *stli_serialname = "ttyE";
static char *stli_calloutname = "cue";
@@ -281,6 +290,8 @@
"EC8/64-EI",
"EC8/64-MC",
"EC8/32-PCI",
+ "EC8/64-PCI",
+ "EasyIO-PCI",
};
/*
@@ -436,6 +447,7 @@
#define ECH_PNLSTATUS 2
#define ECH_PNL16PORT 0x20
#define ECH_PNLIDMASK 0x07
+#define ECH_PNLXPID 0x40
#define ECH_PNLINTRPEND 0x80
/*
@@ -473,9 +485,9 @@
/*
* Define the maximal baud rate, and the default baud base for ports.
*/
-#define STL_MAXBAUD 230400
+#define STL_MAXBAUD 460800
#define STL_BAUDBASE 115200
-#define STL_CLOSEDELAY 50
+#define STL_CLOSEDELAY (5 * HZ / 10)
/*****************************************************************************/
@@ -492,7 +504,7 @@
*/
static unsigned int stli_baudrates[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 230400
+ 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
};
/*****************************************************************************/
@@ -530,19 +542,16 @@
static void stli_flushbuffer(struct tty_struct *tty);
static void stli_hangup(struct tty_struct *tty);
-static int stli_initbrds(void);
static int stli_brdinit(stlibrd_t *brdp);
-static int stli_initecp(stlibrd_t *brdp);
-static int stli_initonb(stlibrd_t *brdp);
-static int stli_eisamemprobe(stlibrd_t *brdp);
-static int stli_findeisabrds(void);
-static int stli_initports(stlibrd_t *brdp);
static int stli_startbrd(stlibrd_t *brdp);
+static int stli_memopen(struct inode *ip, struct file *fp);
+static void stli_memclose(struct inode *ip, struct file *fp);
static int stli_memread(struct inode *ip, struct file *fp, char *buf, int count);
static int stli_memwrite(struct inode *ip, struct file *fp, const char *buf, int count);
static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
+static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp);
static void stli_poll(unsigned long arg);
-static int stli_hostcmd(stlibrd_t *brdp, int channr);
+static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
static int stli_initopen(stlibrd_t *brdp, stliport_t *portp);
static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
@@ -561,6 +570,7 @@
static int stli_setserial(stliport_t *portp, struct serial_struct *sp);
static int stli_getbrdstats(combrd_t *bp);
static int stli_getportstats(stliport_t *portp, comstats_t *cp);
+static int stli_portcmdstats(stliport_t *portp);
static int stli_clrportstats(stliport_t *portp, comstats_t *cp);
static int stli_getportstruct(unsigned long arg);
static int stli_getbrdstruct(unsigned long arg);
@@ -601,6 +611,13 @@
static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
+static inline int stli_initbrds(void);
+static inline int stli_initecp(stlibrd_t *brdp);
+static inline int stli_initonb(stlibrd_t *brdp);
+static inline int stli_findeisabrds(void);
+static inline int stli_eisamemprobe(stlibrd_t *brdp);
+static inline int stli_initports(stlibrd_t *brdp);
+
/*****************************************************************************/
/*
@@ -617,8 +634,8 @@
NULL,
stli_memioctl,
NULL,
- NULL,
- NULL,
+ stli_memopen,
+ stli_memclose,
NULL
};
@@ -678,7 +695,8 @@
printk("cleanup_module()\n");
#endif
- printk(KERN_INFO "Unloading %s: version %s\n", stli_drvname, stli_drvversion);
+ printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
+ stli_drvversion);
save_flags(flags);
cli();
@@ -695,12 +713,14 @@
i = tty_unregister_driver(&stli_serial);
j = tty_unregister_driver(&stli_callout);
if (i || j) {
- printk("STALLION: failed to un-register tty driver, errno=%d,%d\n", -i, -j);
+ printk("STALLION: failed to un-register tty driver, "
+ "errno=%d,%d\n", -i, -j);
restore_flags(flags);
return;
}
if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
- printk("STALLION: failed to un-register serial memory device, errno=%d\n", -i);
+ printk("STALLION: failed to un-register serial memory device, "
+ "errno=%d\n", -i);
if (stli_tmpwritebuf != (char *) NULL)
kfree_s(stli_tmpwritebuf, STLI_TXBUFSIZE);
@@ -722,10 +742,8 @@
if (brdp->memaddr >= 0x100000)
vfree(brdp->membase);
- if ((brdp->brdtype == BRD_ECP) || (brdp->brdtype == BRD_ECPE) || (brdp->brdtype == BRD_ECPMC))
- release_region(brdp->iobase, ECP_IOSIZE);
- else
- release_region(brdp->iobase, ONB_IOSIZE);
+ if (brdp->iosize > 0)
+ release_region(brdp->iobase, brdp->iosize);
kfree_s(brdp, sizeof(stlibrd_t));
stli_brds[i] = (stlibrd_t *) NULL;
}
@@ -756,7 +774,8 @@
int brdnr, portnr, rc;
#if DEBUG
- printk("stli_open(tty=%x,filp=%x): device=%x\n", (int) tty, (int) filp, tty->device);
+ printk("stli_open(tty=%x,filp=%x): device=%x\n", (int) tty,
+ (int) filp, tty->device);
#endif
minordev = MINOR(tty->device);
@@ -778,6 +797,8 @@
if (portp->devnr < 1)
return(-ENODEV);
+ MOD_INC_USE_COUNT;
+
/*
* Check if this port is in the middle of closing. If so then wait
* until it is closed then return error status based on flag settings.
@@ -842,10 +863,10 @@
return(-EBUSY);
if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
- (portp->session != current->session))
+ (portp->session != current->session))
return(-EBUSY);
if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
- (portp->pgrp != current->pgrp))
+ (portp->pgrp != current->pgrp))
return(-EBUSY);
}
portp->flags |= ASYNC_CALLOUT_ACTIVE;
@@ -892,10 +913,14 @@
save_flags(flags);
cli();
if (tty_hung_up_p(filp)) {
+ MOD_DEC_USE_COUNT;
restore_flags(flags);
return;
}
+ if ((tty->count == 1) && (portp->refcount != 1))
+ portp->refcount = 1;
if (portp->refcount-- > 1) {
+ MOD_DEC_USE_COUNT;
restore_flags(flags);
return;
}
@@ -916,10 +941,8 @@
if (tty == stli_txcooktty)
stli_flushchars(tty);
tty->closing = 1;
- if (test_bit(ST_TXBUSY, &portp->state)) {
- if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, portp->closing_wait);
- }
+ if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, portp->closing_wait);
portp->flags &= ~ASYNC_INITIALIZED;
brdp = stli_brds[portp->brdnr];
@@ -929,7 +952,8 @@
if (test_bit(ST_CMDING, &portp->state))
set_bit(ST_DOSIGS, &portp->state);
else
- stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
+ stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig,
+ sizeof(asysigs_t), 0);
}
clear_bit(ST_TXBUSY, &portp->state);
clear_bit(ST_RXSTOP, &portp->state);
@@ -940,7 +964,6 @@
stli_flushbuffer(tty);
tty->closing = 0;
- tty->driver_data = (void *) NULL;
portp->tty = (struct tty_struct *) NULL;
if (portp->openwaitcnt) {
@@ -949,8 +972,10 @@
wake_up_interruptible(&portp->open_wait);
}
- portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+ portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
+ ASYNC_CLOSING);
wake_up_interruptible(&portp->close_wait);
+ MOD_DEC_USE_COUNT;
restore_flags(flags);
}
@@ -981,23 +1006,27 @@
memset(&nt, 0, sizeof(asynotify_t));
nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK);
nt.signal = SG_DCD;
- if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, sizeof(asynotify_t), 0)) < 0)
+ if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt,
+ sizeof(asynotify_t), 0)) < 0)
return(rc);
tty = portp->tty;
if (tty == (struct tty_struct *) NULL)
return(-ENODEV);
stli_mkasyport(portp, &aport, tty->termios);
- if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)) < 0)
+ if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
+ sizeof(asyport_t), 0)) < 0)
return(rc);
set_bit(ST_GETSIGS, &portp->state);
- if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
+ if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig,
+ sizeof(asysigs_t), 1)) < 0)
return(rc);
if (clear_bit(ST_GETSIGS, &portp->state))
portp->sigs = stli_mktiocm(portp->asig.sigvalue);
stli_mkasysigs(&portp->asig, 1, 1);
- if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
+ if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
+ sizeof(asysigs_t), 0)) < 0)
return(rc);
return(0);
@@ -1021,7 +1050,8 @@
int rc;
#if DEBUG
- printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp, (int) portp, (int) arg, wait);
+ printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
+ (int) brdp, (int) portp, (int) arg, wait);
#endif
/*
@@ -1054,8 +1084,8 @@
cp->openarg = arg;
cp->open = 1;
hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- hdrp->slavereq |= portp->reqbit;
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
+ bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ portp->portidx;
*bits |= portp->portbit;
EBRDDISABLE(brdp);
@@ -1101,7 +1131,8 @@
int rc;
#if DEBUG
- printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", (int) brdp, (int) portp, (int) arg, wait);
+ printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n",
+ (int) brdp, (int) portp, (int) arg, wait);
#endif
save_flags(flags);
@@ -1129,8 +1160,8 @@
cp->closearg = arg;
cp->close = 1;
hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- hdrp->slavereq |= portp->reqbit;
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
+ bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ portp->portidx;
*bits |= portp->portbit;
EBRDDISABLE(brdp);
@@ -1173,7 +1204,9 @@
unsigned long flags;
#if DEBUG
- printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, (int) arg, size, copyback);
+ printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
+ "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
+ (int) arg, size, copyback);
#endif
save_flags(flags);
@@ -1243,7 +1276,7 @@
static void stli_delay(int len)
{
#if DEBUG
- printk("stl_delay(len=%d)\n", len);
+ printk("stli_delay(len=%d)\n", len);
#endif
if (len > 0) {
current->state = TASK_INTERRUPTIBLE;
@@ -1265,7 +1298,8 @@
int rc, doclocal;
#if DEBUG
- printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", (int) brdp, (int) portp, (int) filp);
+ printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n",
+ (int) brdp, (int) portp, (int) filp);
#endif
rc = 0;
@@ -1282,16 +1316,18 @@
save_flags(flags);
cli();
portp->openwaitcnt++;
- if (portp->refcount > 0)
+ if (! tty_hung_up_p(filp))
portp->refcount--;
for (;;) {
if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) {
stli_mkasysigs(&portp->asig, 1, 1);
- if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0)
+ if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
+ &portp->asig, sizeof(asysigs_t), 0)) < 0)
break;
}
- if (tty_hung_up_p(filp) || ((portp->flags & ASYNC_INITIALIZED) == 0)) {
+ if (tty_hung_up_p(filp) ||
+ ((portp->flags & ASYNC_INITIALIZED) == 0)) {
if (portp->flags & ASYNC_HUP_NOTIFY)
rc = -EBUSY;
else
@@ -1299,8 +1335,8 @@
break;
}
if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
- ((portp->flags & ASYNC_CLOSING) == 0) &&
- (doclocal || (portp->sigs & TIOCM_CD))) {
+ ((portp->flags & ASYNC_CLOSING) == 0) &&
+ (doclocal || (portp->sigs & TIOCM_CD))) {
break;
}
if (current->signal & ~current->blocked) {
@@ -1338,10 +1374,12 @@
unsigned long flags;
#if DEBUG
- printk("stli_write(tty=%x,from_user=%d,buf=%x,count=%d)\n", (int) tty, from_user, (int) buf, count);
+ printk("stli_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
+ (int) tty, from_user, (int) buf, count);
#endif
- if ((tty == (struct tty_struct *) NULL) || (stli_tmpwritebuf == (char *) NULL))
+ if ((tty == (struct tty_struct *) NULL) ||
+ (stli_tmpwritebuf == (char *) NULL))
return(0);
if (tty == stli_txcooktty)
stli_flushchars(tty);
@@ -1375,7 +1413,8 @@
tail = (unsigned int) ap->txq.tail;
if (tail != ((unsigned int) ap->txq.tail))
tail = (unsigned int) ap->txq.tail;
- len = (head >= tail) ? (portp->txsize - (head - tail) - 1) : (tail - head - 1);
+ len = (head >= tail) ? (portp->txsize - (head - tail) - 1) :
+ (tail - head - 1);
count = MIN(len, count);
EBRDDISABLE(brdp);
@@ -1430,8 +1469,8 @@
ap->changed.data &= ~DT_TXEMPTY;
}
hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- hdrp->slavereq |= portp->reqbit;
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
+ bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ portp->portidx;
*bits |= portp->portbit;
set_bit(ST_TXBUSY, &portp->state);
@@ -1562,8 +1601,8 @@
ap->changed.data &= ~DT_TXEMPTY;
}
hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- hdrp->slavereq |= portp->reqbit;
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
+ bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ portp->portidx;
*bits |= portp->portbit;
set_bit(ST_TXBUSY, &portp->state);
@@ -1729,12 +1768,14 @@
memcpy_fromfs(&sio, sp, sizeof(struct serial_struct));
if (!suser()) {
if ((sio.baud_base != portp->baud_base) ||
- (sio.close_delay != portp->close_delay) ||
- ((sio.flags & ~ASYNC_USR_MASK) != (portp->flags & ~ASYNC_USR_MASK)))
+ (sio.close_delay != portp->close_delay) ||
+ ((sio.flags & ~ASYNC_USR_MASK) !=
+ (portp->flags & ~ASYNC_USR_MASK)))
return(-EPERM);
}
- portp->flags = (portp->flags & ~ASYNC_USR_MASK) | (sio.flags & ASYNC_USR_MASK);
+ portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
+ (sio.flags & ASYNC_USR_MASK);
portp->baud_base = sio.baud_base;
portp->close_delay = sio.close_delay;
portp->closing_wait = sio.closing_wait;
@@ -1755,7 +1796,8 @@
int rc;
#if DEBUG
- printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", (int) tty, (int) file, cmd, (int) arg);
+ printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
+ (int) tty, (int) file, cmd, (int) arg);
#endif
if (tty == (struct tty_struct *) NULL)
@@ -1769,6 +1811,12 @@
if (brdp == (stlibrd_t *) NULL)
return(0);
+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+ (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return(-EIO);
+ }
+
rc = 0;
switch (cmd) {
@@ -1777,7 +1825,8 @@
tty_wait_until_sent(tty, 0);
if (! arg) {
val = 250;
- rc = stli_cmdwait(brdp, portp, A_BREAK, &val, sizeof(unsigned long), 0);
+ rc = stli_cmdwait(brdp, portp, A_BREAK, &val,
+ sizeof(unsigned long), 0);
}
}
break;
@@ -1785,72 +1834,98 @@
if ((rc = tty_check_change(tty)) == 0) {
tty_wait_until_sent(tty, 0);
val = (arg ? (arg * 100) : 250);
- rc = stli_cmdwait(brdp, portp, A_BREAK, &val, sizeof(unsigned long), 0);
+ rc = stli_cmdwait(brdp, portp, A_BREAK, &val,
+ sizeof(unsigned long), 0);
}
break;
case TIOCGSOFTCAR:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long))) == 0)
- put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), (unsigned long *) arg);
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(long))) == 0)
+ put_fs_long(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
+ (unsigned long *) arg);
break;
case TIOCSSOFTCAR:
- if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(long))) == 0) {
arg = get_fs_long((unsigned long *) arg);
- tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0);
+ tty->termios->c_cflag =
+ (tty->termios->c_cflag & ~CLOCAL) |
+ (arg ? CLOCAL : 0);
}
break;
case TIOCMGET:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int))) == 0) {
- if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(unsigned int))) == 0) {
+ if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
+ &portp->asig, sizeof(asysigs_t), 1)) < 0)
return(rc);
val = stli_mktiocm(portp->asig.sigvalue);
put_fs_long(val, (unsigned long *) arg);
}
break;
case TIOCMBIS:
- if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(long))) == 0) {
arg = get_fs_long((unsigned long *) arg);
- stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 1 : -1), ((arg & TIOCM_RTS) ? 1 : -1));
- rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
+ stli_mkasysigs(&portp->asig,
+ ((arg & TIOCM_DTR) ? 1 : -1),
+ ((arg & TIOCM_RTS) ? 1 : -1));
+ rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
+ &portp->asig, sizeof(asysigs_t), 0);
}
break;
case TIOCMBIC:
- if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(long))) == 0) {
arg = get_fs_long((unsigned long *) arg);
- stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 0 : -1), ((arg & TIOCM_RTS) ? 0 : -1));
- rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
+ stli_mkasysigs(&portp->asig,
+ ((arg & TIOCM_DTR) ? 0 : -1),
+ ((arg & TIOCM_RTS) ? 0 : -1));
+ rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
+ &portp->asig, sizeof(asysigs_t), 0);
}
break;
case TIOCMSET:
- if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(long))) == 0) {
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(long))) == 0) {
arg = get_fs_long((unsigned long *) arg);
- stli_mkasysigs(&portp->asig, ((arg & TIOCM_DTR) ? 1 : 0), ((arg & TIOCM_RTS) ? 1 : 0));
- rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
+ stli_mkasysigs(&portp->asig,
+ ((arg & TIOCM_DTR) ? 1 : 0),
+ ((arg & TIOCM_RTS) ? 1 : 0));
+ rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
+ &portp->asig, sizeof(asysigs_t), 0);
}
break;
case TIOCGSERIAL:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct serial_struct))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(struct serial_struct))) == 0)
stli_getserial(portp, (struct serial_struct *) arg);
break;
case TIOCSSERIAL:
- if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(struct serial_struct))) == 0)
- rc = stli_setserial(portp, (struct serial_struct *) arg);
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(struct serial_struct))) == 0)
+ rc = stli_setserial(portp, (struct serial_struct *)arg);
break;
case STL_GETPFLAG:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(unsigned long))) == 0)
put_fs_long(portp->pflag, (unsigned long *) arg);
break;
case STL_SETPFLAG:
- if ((rc = verify_area(VERIFY_READ, (void *) arg, sizeof(unsigned long))) == 0) {
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(unsigned long))) == 0) {
portp->pflag = get_fs_long((unsigned long *) arg);
stli_setport(portp);
}
break;
case COM_GETPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(comstats_t))) == 0)
rc = stli_getportstats(portp, (comstats_t *) arg);
break;
case COM_CLRPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(comstats_t))) == 0)
rc = stli_clrportstats(portp, (comstats_t *) arg);
break;
case TIOCSERCONFIG:
@@ -1898,13 +1973,15 @@
return;
tiosp = tty->termios;
- if ((tiosp->c_cflag == old->c_cflag) && (tiosp->c_iflag == old->c_iflag))
+ if ((tiosp->c_cflag == old->c_cflag) &&
+ (tiosp->c_iflag == old->c_iflag))
return;
stli_mkasyport(portp, &aport, tiosp);
stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1);
- stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0);
+ stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
+ sizeof(asysigs_t), 0);
if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
tty->hw_stopped = 0;
if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
@@ -1996,7 +2073,7 @@
memset(&actrl, 0, sizeof(asyctrl_t));
actrl.txctrl = CT_STOPFLOW;
#if 0
- stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t));
+ stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
#endif
}
@@ -2030,7 +2107,7 @@
memset(&actrl, 0, sizeof(asyctrl_t));
actrl.txctrl = CT_STARTFLOW;
#if 0
- stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t));
+ stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
#endif
}
@@ -2104,7 +2181,8 @@
set_bit(ST_DOFLUSHTX, &portp->state);
set_bit(ST_DOFLUSHRX, &portp->state);
} else {
- stli_sendcmd(brdp, portp, A_SETSIGNALSF, &portp->asig, sizeof(asysigs_t), 0);
+ stli_sendcmd(brdp, portp, A_SETSIGNALSF,
+ &portp->asig, sizeof(asysigs_t), 0);
}
}
restore_flags(flags);
@@ -2112,7 +2190,6 @@
clear_bit(ST_TXBUSY, &portp->state);
clear_bit(ST_RXSTOP, &portp->state);
set_bit(TTY_IO_ERROR, &tty->flags);
- tty->driver_data = (void *) NULL;
portp->tty = (struct tty_struct *) NULL;
portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
portp->refcount = 0;
@@ -2164,12 +2241,14 @@
ftype |= FLUSHRX;
clear_bit(ST_DOFLUSHRX, &portp->state);
}
- stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(unsigned long), 0);
+ stli_sendcmd(brdp, portp, A_FLUSH, &ftype,
+ sizeof(unsigned long), 0);
}
restore_flags(flags);
wake_up_interruptible(&tty->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup)
(tty->ldisc.write_wakeup)(tty);
}
@@ -2193,7 +2272,9 @@
unsigned long flags;
#if DEBUG
- printk("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, (int) arg, size, copyback);
+ printk("stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d,"
+ "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd,
+ (int) arg, size, copyback);
#endif
save_flags(flags);
@@ -2217,8 +2298,8 @@
cp->status = 0;
cp->cmd = cmd;
hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- hdrp->slavereq |= portp->reqbit;
- bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx;
+ bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset +
+ portp->portidx;
*bits |= portp->portbit;
set_bit(ST_CMDING, &portp->state);
EBRDDISABLE(brdp);
@@ -2307,7 +2388,8 @@
int cmd;
if (test_bit(ST_DOSIGS, &portp->state)) {
- if (test_bit(ST_DOFLUSHTX, &portp->state) && test_bit(ST_DOFLUSHRX, &portp->state))
+ if (test_bit(ST_DOFLUSHTX, &portp->state) &&
+ test_bit(ST_DOFLUSHRX, &portp->state))
cmd = A_SETSIGNALSF;
else if (test_bit(ST_DOFLUSHTX, &portp->state))
cmd = A_SETSIGNALSFTX;
@@ -2318,11 +2400,13 @@
clear_bit(ST_DOFLUSHTX, &portp->state);
clear_bit(ST_DOFLUSHRX, &portp->state);
clear_bit(ST_DOSIGS, &portp->state);
- memcpy((void *) &(cp->args[0]), (void *) &portp->asig, sizeof(asysigs_t));
+ memcpy((void *) &(cp->args[0]), (void *) &portp->asig,
+ sizeof(asysigs_t));
cp->status = 0;
cp->cmd = cmd;
set_bit(ST_CMDING, &portp->state);
- } else if (test_bit(ST_DOFLUSHTX, &portp->state) || test_bit(ST_DOFLUSHRX, &portp->state)) {
+ } else if (test_bit(ST_DOFLUSHTX, &portp->state) ||
+ test_bit(ST_DOFLUSHRX, &portp->state)) {
cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0);
cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0);
clear_bit(ST_DOFLUSHTX, &portp->state);
@@ -2342,15 +2426,17 @@
* enabled and interrupts off when called. Notice that by servicing the
* read data last we don't need to change the shared memory pointer
* during processing (which is a slow IO operation).
+ * Return value indicates if this port is still awaiting actions from
+ * the slave (like open, command, or even TX data being sent). If 0
+ * then port is still busy, otherwise no longer busy.
*/
-static inline int stli_hostcmd(stlibrd_t *brdp, int channr)
+static inline int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
{
volatile cdkasy_t *ap;
volatile cdkctrl_t *cp;
struct tty_struct *tty;
asynotify_t nt;
- stliport_t *portp;
unsigned long oldsigs;
int rc, donerx;
@@ -2358,7 +2444,6 @@
printk("stli_hostcmd(brdp=%x,channr=%d)\n", (int) brdp, channr);
#endif
- portp = brdp->ports[(channr - 1)];
ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr);
cp = &ap->ctrl;
@@ -2402,7 +2487,8 @@
if (rc > 0)
rc--;
if (portp->argp != (void *) NULL) {
- memcpy(portp->argp, (void *) &(cp->args[0]), portp->argsize);
+ memcpy(portp->argp, (void *) &(cp->args[0]),
+ portp->argsize);
portp->argp = (void *) NULL;
}
cp->status = 0;
@@ -2429,12 +2515,14 @@
oldsigs = portp->sigs;
portp->sigs = stli_mktiocm(nt.sigvalue);
clear_bit(ST_GETSIGS, &portp->state);
- if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
+ if ((portp->sigs & TIOCM_CD) &&
+ ((oldsigs & TIOCM_CD) == 0))
wake_up_interruptible(&portp->open_wait);
- if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
+ if ((oldsigs & TIOCM_CD) &&
+ ((portp->sigs & TIOCM_CD) == 0)) {
if (portp->flags & ASYNC_CHECK_CD) {
if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
- (portp->flags & ASYNC_CALLOUT_NOHUP))) {
+ (portp->flags & ASYNC_CALLOUT_NOHUP))) {
if (tty != (struct tty_struct *) NULL)
queue_task_irq_off(&portp->tqhangup, &tq_scheduler);
}
@@ -2446,7 +2534,8 @@
clear_bit(ST_TXBUSY, &portp->state);
if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
if (tty != (struct tty_struct *) NULL) {
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup) {
(tty->ldisc.write_wakeup)(tty);
EBRDENABLE(brdp);
}
@@ -2460,12 +2549,10 @@
tty->flip.count++;
*tty->flip.flag_buf_ptr++ = TTY_BREAK;
*tty->flip.char_buf_ptr++ = 0;
-#ifndef MODULE
if (portp->flags & ASYNC_SAK) {
do_SAK(tty);
EBRDENABLE(brdp);
}
-#endif
tty_schedule_flip(tty);
}
}
@@ -2490,7 +2577,74 @@
stli_read(brdp, portp);
}
- return(0);
+ return((test_bit(ST_OPENING, &portp->state) ||
+ test_bit(ST_CLOSING, &portp->state) ||
+ test_bit(ST_CMDING, &portp->state) ||
+ test_bit(ST_TXBUSY, &portp->state) ||
+ test_bit(ST_RXING, &portp->state)) ? 0 : 1);
+}
+
+/*****************************************************************************/
+
+/*
+ * Service all ports on a particular board. Assumes that the boards
+ * shared memory is enabled, and that the page pointer is pointed
+ * at the cdk header structure.
+ */
+
+static inline void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp)
+{
+ stliport_t *portp;
+ unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
+ unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
+ unsigned char *slavep;
+ int bitpos, bitat, bitsize;
+ int channr, nrdevs, slavebitchange;
+
+ bitsize = brdp->bitsize;
+ nrdevs = brdp->nrdevs;
+
+/*
+ * Check if slave wants any service. Basically we try to do as
+ * little work as possible here. There are 2 levels of service
+ * bits. So if there is nothing to do we bail early. We check
+ * 8 service bits at a time in the inner loop, so we can bypass
+ * the lot if none of them want service.
+ */
+ memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset),
+ bitsize);
+
+ memset(&slavebits[0], 0, bitsize);
+ slavebitchange = 0;
+
+ for (bitpos = 0; (bitpos < bitsize); bitpos++) {
+ if (hostbits[bitpos] == 0)
+ continue;
+ channr = bitpos * 8;
+ for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
+ if (hostbits[bitpos] & bitat) {
+ portp = brdp->ports[(channr - 1)];
+ if (stli_hostcmd(brdp, portp)) {
+ slavebitchange++;
+ slavebits[bitpos] |= bitat;
+ }
+ }
+ }
+ }
+
+/*
+ * If any of the ports are no longer busy then update them in the
+ * slave request bits. We need to do this after, since a host port
+ * service may initiate more slave requests.
+ */
+ if (slavebitchange) {
+ hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
+ slavep = ((unsigned char *) hdrp) + brdp->slaveoffset;
+ for (bitpos = 0; (bitpos < bitsize); bitpos++) {
+ if (slavebits[bitpos])
+ slavep[bitpos] &= ~slavebits[bitpos];
+ }
+ }
}
/*****************************************************************************/
@@ -2507,12 +2661,8 @@
static void stli_poll(unsigned long arg)
{
volatile cdkhdr_t *hdrp;
- unsigned char bits[(STL_MAXCHANS / 8) + 1];
- unsigned char hostreq, slavereq;
- stliport_t *portp;
stlibrd_t *brdp;
- int bitpos, bitat, bitsize;
- int brdnr, channr, nrdevs;
+ int brdnr;
stli_timerlist.expires = STLI_TIMEOUT;
add_timer(&stli_timerlist);
@@ -2529,67 +2679,8 @@
EBRDENABLE(brdp);
hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR);
- hostreq = hdrp->hostreq;
- slavereq = hdrp->slavereq;
- bitsize = brdp->bitsize;
- nrdevs = brdp->nrdevs;
-
-/*
- * Check if slave wants any service. Basically we try to do as
- * little work as possible here. There are 2 levels of service
- * bits. So if there is nothing to do we bail early. We check
- * 8 service bits at a time in the inner loop, so we can bypass
- * the lot if none of them want service.
- */
- if (hostreq) {
- memcpy(&bits[0], (((unsigned char *) hdrp) + brdp->hostoffset), bitsize);
-
- for (bitpos = 0; (bitpos < bitsize); bitpos++) {
- if (bits[bitpos] == 0)
- continue;
- channr = bitpos * 8;
- for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
- if (bits[bitpos] & bitat) {
- stli_hostcmd(brdp, channr);
- }
- }
- }
- }
-
-/*
- * Check if any of the out-standing host commands have completed.
- * It is a bit unfortunate that we need to check stuff that we
- * initiated! This ain't pretty, but it needs to be fast.
- */
- if (slavereq) {
- slavereq = 0;
- hostreq = 0;
- memcpy(&bits[0], (((unsigned char *) hdrp) + brdp->slaveoffset), bitsize);
-
- for (bitpos = 0; (bitpos < bitsize); bitpos++) {
- if (bits[bitpos] == 0)
- continue;
- channr = bitpos * 8;
- for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) {
- if (bits[bitpos] & bitat) {
- portp = brdp->ports[(channr - 1)];
- if (test_bit(ST_OPENING, &portp->state) ||
- test_bit(ST_CLOSING, &portp->state) ||
- test_bit(ST_CMDING, &portp->state) ||
- test_bit(ST_TXBUSY, &portp->state)) {
- slavereq |= portp->reqbit;
- } else {
- bits[bitpos] &= ~bitat;
- hostreq++;
- }
- }
- }
- }
- hdrp->slavereq = slavereq;
- if (hostreq)
- memcpy((((unsigned char *) hdrp) + brdp->slaveoffset), &bits[0], bitsize);
- }
-
+ if (hdrp->hostreq)
+ stli_brdpoll(brdp, hdrp);
EBRDDISABLE(brdp);
}
}
@@ -2604,7 +2695,8 @@
static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
{
#if DEBUG
- printk("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", (int) portp, (int) pp, (int) tiosp);
+ printk("stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n",
+ (int) portp, (int) pp, (int) tiosp);
#endif
memset(pp, 0, sizeof(asyport_t));
@@ -2615,7 +2707,7 @@
pp->baudout = tiosp->c_cflag & CBAUD;
if (pp->baudout & CBAUDEX) {
pp->baudout &= ~CBAUDEX;
- if ((pp->baudout < 1) || (pp->baudout > 2))
+ if ((pp->baudout < 1) || (pp->baudout > 5))
tiosp->c_cflag &= ~CBAUDEX;
else
pp->baudout += 15;
@@ -2706,7 +2798,10 @@
/*
* Transfer any persistent flags into the asyport structure.
*/
- pp->pflag = portp->pflag;
+ pp->pflag = (portp->pflag & 0xffff);
+ pp->vmin = (portp->pflag & P_RXIMIN) ? 1 : 0;
+ pp->vtime = (portp->pflag & P_RXITIME) ? 1 : 0;
+ pp->cc[1] = (portp->pflag & P_RXTHOLD) ? 1 : 0;
}
/*****************************************************************************/
@@ -2765,7 +2860,7 @@
* we need to do here is set up the appropriate per port data structures.
*/
-static int stli_initports(stlibrd_t *brdp)
+static inline int stli_initports(stlibrd_t *brdp)
{
stliport_t *portp;
int i, panelnr, panelport;
@@ -2855,11 +2950,14 @@
unsigned char val;
#if DEBUG
- printk("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
+ printk("stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
+ (int) offset);
#endif
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
val = 0;
} else {
@@ -2942,11 +3040,14 @@
unsigned char val;
#if DEBUG
- printk("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp, (int) offset, line);
+ printk("stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n",
+ (int) brdp, (int) offset, line);
#endif
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
val = 0;
} else {
@@ -2996,7 +3097,9 @@
unsigned char val;
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
val = 0;
} else {
@@ -3071,11 +3174,14 @@
void *ptr;
#if DEBUG
- printk("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
+ printk("stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
+ (int) offset);
#endif
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
} else {
ptr = brdp->membase + (offset % ONB_ATPAGESIZE);
@@ -3158,11 +3264,14 @@
unsigned char val;
#if DEBUG
- printk("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", (int) brdp, (int) offset, line);
+ printk("stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n",
+ (int) brdp, (int) offset, line);
#endif
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
val = 0;
} else {
@@ -3224,11 +3333,14 @@
unsigned char val;
#if DEBUG
- printk("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
+ printk("stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
+ (int) offset);
#endif
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
val = 0;
} else {
@@ -3282,11 +3394,14 @@
void *ptr;
#if DEBUG
- printk("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, (int) offset);
+ printk("stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp,
+ (int) offset);
#endif
if (offset > brdp->memsize) {
- printk("STALLION: shared memory pointer=%x out of range at line=%d(%d), brd=%d\n", (int) offset, line, __LINE__, brdp->brdnr);
+ printk("STALLION: shared memory pointer=%x out of range at "
+ "line=%d(%d), brd=%d\n", (int) offset, line,
+ __LINE__, brdp->brdnr);
ptr = 0;
} else {
ptr = brdp->membase + (offset % STAL_PAGESIZE);
@@ -3319,12 +3434,13 @@
* board types.
*/
-static int stli_initecp(stlibrd_t *brdp)
+static inline int stli_initecp(stlibrd_t *brdp)
{
cdkecpsig_t sig;
cdkecpsig_t *sigsp;
unsigned int status, nxtid;
- int panelnr;
+ char *name;
+ int panelnr, nrports;
#if DEBUG
printk("stli_initecp(brdp=%x)\n", (int) brdp);
@@ -3336,6 +3452,11 @@
if ((brdp->iobase == 0) || (brdp->memaddr == 0))
return(-ENODEV);
+ brdp->iosize = ECP_IOSIZE;
+ if (check_region(brdp->iobase, brdp->iosize))
+ printk("STALLION: Warning, unit %d I/O address %x conflicts "
+ "with another device\n", brdp->brdnr, brdp->iobase);
+
/*
* Based on the specific board type setup the common vars to access
* and enable shared memory. Set all board specific information now
@@ -3353,6 +3474,7 @@
brdp->getmemptr = stli_ecpgetmemptr;
brdp->intr = stli_ecpintr;
brdp->reset = stli_ecpreset;
+ name = "serial(EC8/64)";
break;
case BRD_ECPE:
@@ -3366,6 +3488,7 @@
brdp->getmemptr = stli_ecpeigetmemptr;
brdp->intr = stli_ecpintr;
brdp->reset = stli_ecpeireset;
+ name = "serial(EC8/64-EI)";
break;
case BRD_ECPMC:
@@ -3379,6 +3502,7 @@
brdp->getmemptr = stli_ecpmcgetmemptr;
brdp->intr = stli_ecpintr;
brdp->reset = stli_ecpmcreset;
+ name = "serial(EC8/64-MCA)";
break;
default:
@@ -3410,10 +3534,11 @@
EBRDDISABLE(brdp);
#if 0
- printk("%s(%d): sig-> magic=%x romver=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
+ printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n",
__FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0],
- (int) sig.panelid[1], (int) sig.panelid[2], (int) sig.panelid[3],
- (int) sig.panelid[4], (int) sig.panelid[5], (int) sig.panelid[6],
+ (int) sig.panelid[1], (int) sig.panelid[2],
+ (int) sig.panelid[3], (int) sig.panelid[4],
+ (int) sig.panelid[5], (int) sig.panelid[6],
(int) sig.panelid[7]);
#endif
@@ -3428,20 +3553,18 @@
status = sig.panelid[nxtid];
if ((status & ECH_PNLIDMASK) != nxtid)
break;
- if (status & ECH_PNL16PORT) {
- brdp->panels[panelnr] = 16;
- brdp->nrports += 16;
- nxtid += 2;
- } else {
- brdp->panels[panelnr] = 8;
- brdp->nrports += 8;
- nxtid++;
- }
+
brdp->panelids[panelnr] = status;
+ nrports = (status & ECH_PNL16PORT) ? 16 : 8;
+ if ((nrports == 16) && ((status & ECH_PNLXPID) == 0))
+ nxtid++;
+ brdp->panels[panelnr] = nrports;
+ brdp->nrports += nrports;
+ nxtid++;
brdp->nrpanels++;
}
- request_region(brdp->iobase, ECP_IOSIZE, "serial(ECP)");
+ request_region(brdp->iobase, brdp->iosize, name);
brdp->state |= BST_FOUND;
return(0);
}
@@ -3453,10 +3576,11 @@
* This handles only these board types.
*/
-static int stli_initonb(stlibrd_t *brdp)
+static inline int stli_initonb(stlibrd_t *brdp)
{
cdkonbsig_t sig;
cdkonbsig_t *sigsp;
+ char *name;
int i;
#if DEBUG
@@ -3469,6 +3593,11 @@
if ((brdp->iobase == 0) || (brdp->memaddr == 0))
return(-ENODEV);
+ brdp->iosize = ONB_IOSIZE;
+ if (check_region(brdp->iobase, brdp->iosize))
+ printk("STALLION: Warning, unit %d I/O address %x conflicts "
+ "with another device\n", brdp->brdnr, brdp->iobase);
+
/*
* Based on the specific board type setup the common vars to access
* and enable shared memory. Set all board specific information now
@@ -3494,6 +3623,7 @@
brdp->enabval = ONB_MEMENABHI;
else
brdp->enabval = ONB_MEMENABLO;
+ name = "serial(ONBoard)";
break;
case BRD_ONBOARDE:
@@ -3507,6 +3637,7 @@
brdp->getmemptr = stli_onbegetmemptr;
brdp->intr = stli_ecpintr;
brdp->reset = stli_onbereset;
+ name = "serial(ONBoard/E)";
break;
case BRD_BRUMBY4:
@@ -3522,6 +3653,7 @@
brdp->getmemptr = stli_bbygetmemptr;
brdp->intr = stli_ecpintr;
brdp->reset = stli_bbyreset;
+ name = "serial(Brumby)";
break;
case BRD_STALLION:
@@ -3535,6 +3667,7 @@
brdp->getmemptr = stli_stalgetmemptr;
brdp->intr = stli_ecpintr;
brdp->reset = stli_stalreset;
+ name = "serial(Stallion)";
break;
default:
@@ -3572,7 +3705,7 @@
#endif
if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) ||
- (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
+ (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3))
return(-ENODEV);
/*
@@ -3591,7 +3724,7 @@
}
brdp->panels[0] = brdp->nrports;
- request_region(brdp->iobase, ONB_IOSIZE, "serial(ONB/BBY)");
+ request_region(brdp->iobase, brdp->iosize, name);
brdp->state |= BST_FOUND;
return(0);
}
@@ -3626,14 +3759,16 @@
nrdevs = hdrp->nrdevs;
#if 0
- printk("%s(%d): CDK version %d.%d.%d --> nrdevs=%d memp=%x hostp=%x slavep=%x\n",
+ printk("%s(%d): CDK version %d.%d.%d --> "
+ "nrdevs=%d memp=%x hostp=%x slavep=%x\n",
__FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification,
hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp,
(int) hdrp->slavep);
#endif
if (nrdevs < (brdp->nrports + 1)) {
- printk("STALLION: slave failed to allocate memory for all devices, devices=%d\n", nrdevs);
+ printk("STALLION: slave failed to allocate memory for all "
+ "devices, devices=%d\n", nrdevs);
brdp->nrports = nrdevs - 1;
}
brdp->nrdevs = nrdevs;
@@ -3671,6 +3806,8 @@
portp->portbit = (unsigned char) (0x1 << (i % 8));
}
+ hdrp->slavereq = 0xff;
+
/*
* For each port setup a local copy of the RX and TX buffer offsets
* and sizes. We do this separate from the above, because we need to
@@ -3743,20 +3880,27 @@
case BRD_ECH:
case BRD_ECHMC:
case BRD_ECHPCI:
- printk("STALLION: %s board type not supported in this driver\n", stli_brdnames[brdp->brdtype]);
+ printk("STALLION: %s board type not supported in this driver\n",
+ stli_brdnames[brdp->brdtype]);
return(ENODEV);
default:
- printk("STALLION: unit=%d is unknown board type=%d\n", brdp->brdnr, brdp->brdtype);
+ printk("STALLION: unit=%d is unknown board type=%d\n",
+ brdp->brdnr, brdp->brdtype);
return(ENODEV);
}
if ((brdp->state & BST_FOUND) == 0) {
- printk("STALLION: %s board not found, unit=%d io=%x mem=%x\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr);
+ printk("STALLION: %s board not found, unit=%d io=%x mem=%x\n",
+ stli_brdnames[brdp->brdtype], brdp->brdnr,
+ brdp->iobase, (int) brdp->memaddr);
return(ENODEV);
}
stli_initports(brdp);
- printk("STALLION: %s found, unit=%d io=%x mem=%x nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr, brdp->nrpanels, brdp->nrports);
+ printk("STALLION: %s found, unit=%d io=%x mem=%x "
+ "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
+ brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
+ brdp->nrpanels, brdp->nrports);
return(0);
}
@@ -3767,7 +3911,7 @@
* might be. This is a bit if hack, but it is the best we can do.
*/
-static int stli_eisamemprobe(stlibrd_t *brdp)
+static inline int stli_eisamemprobe(stlibrd_t *brdp)
{
cdkecpsig_t ecpsig, *ecpsigp;
cdkonbsig_t onbsig, *onbsigp;
@@ -3820,15 +3964,19 @@
continue;
}
if (brdp->brdtype == BRD_ECPE) {
- ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp, CDK_SIGADDR, __LINE__);
+ ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp,
+ CDK_SIGADDR, __LINE__);
memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
if (ecpsig.magic == ECP_MAGIC)
foundit = 1;
} else {
- onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp, CDK_SIGADDR, __LINE__);
+ onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp,
+ CDK_SIGADDR, __LINE__);
memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t));
- if ((onbsig.magic0 == ONB_MAGIC0) && (onbsig.magic1 == ONB_MAGIC1) &&
- (onbsig.magic2 == ONB_MAGIC2) && (onbsig.magic3 == ONB_MAGIC3))
+ if ((onbsig.magic0 == ONB_MAGIC0) &&
+ (onbsig.magic1 == ONB_MAGIC1) &&
+ (onbsig.magic2 == ONB_MAGIC2) &&
+ (onbsig.magic3 == ONB_MAGIC3))
foundit = 1;
}
if (brdp->memaddr >= 0x100000)
@@ -3849,7 +3997,9 @@
if (! foundit) {
brdp->memaddr = 0;
brdp->membase = 0;
- printk("STALLION: failed to probe shared memory region for %s in EISA slot=%d\n", stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
+ printk("STALLION: failed to probe shared memory region for "
+ "%s in EISA slot=%d\n", stli_brdnames[brdp->brdtype],
+ (brdp->iobase >> 12));
return(-ENODEV);
}
return(0);
@@ -3867,7 +4017,7 @@
* do is go probing around in the usual places hoping we can find it.
*/
-static int stli_findeisabrds()
+static inline int stli_findeisabrds()
{
stlibrd_t *brdp;
unsigned int iobase, eid;
@@ -3915,7 +4065,8 @@
* info table.
*/
if (stli_nrbrds >= STL_MAXBRDS) {
- printk("STALLION: no room for more probed boards, maximum supported %d\n", STL_MAXBRDS);
+ printk("STALLION: no room for more probed boards, "
+ "maximum supported %d\n", STL_MAXBRDS);
break;
}
@@ -3925,7 +4076,8 @@
*/
brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
if (brdp == (stlibrd_t *) NULL) {
- printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlibrd_t));
+ printk("STALLION: failed to allocate memory "
+ "(size=%d)\n", sizeof(stlibrd_t));
return(-ENOMEM);
}
memset(brdp, 0, sizeof(stlibrd_t));
@@ -3956,7 +4108,7 @@
* can find.
*/
-static int stli_initbrds()
+static inline int stli_initbrds()
{
stlibrd_t *brdp, *nxtbrdp;
stlconf_t *confp;
@@ -3967,7 +4119,8 @@
#endif
if (stli_nrbrds > STL_MAXBRDS) {
- printk("STALLION: too many boards in configuration table, truncating to %d\n", STL_MAXBRDS);
+ printk("STALLION: too many boards in configuration table, "
+ "truncating to %d\n", STL_MAXBRDS);
stli_nrbrds = STL_MAXBRDS;
}
@@ -3979,7 +4132,8 @@
confp = &stli_brdconf[i];
brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
if (brdp == (stlibrd_t *) NULL) {
- printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlibrd_t));
+ printk("STALLION: failed to allocate memory "
+ "(size=%d)\n", sizeof(stlibrd_t));
return(-ENOMEM);
}
memset(brdp, 0, sizeof(stlibrd_t));
@@ -4013,7 +4167,9 @@
nxtbrdp = stli_brds[j];
if (nxtbrdp == (stlibrd_t *) NULL)
continue;
- if ((brdp->membase >= nxtbrdp->membase) && (brdp->membase <= (nxtbrdp->membase + nxtbrdp->memsize - 1))) {
+ if ((brdp->membase >= nxtbrdp->membase) &&
+ (brdp->membase <= (nxtbrdp->membase +
+ nxtbrdp->memsize - 1))) {
stli_shared++;
break;
}
@@ -4053,7 +4209,8 @@
int brdnr, size, n;
#if DEBUG
- printk("stli_memread(ip=%x,fp=%x,buf=%x,count=%d)\n", (int) ip, (int) fp, (int) buf, count);
+ printk("stli_memread(ip=%x,fp=%x,buf=%x,count=%d)\n", (int) ip,
+ (int) fp, (int) buf, count);
#endif
brdnr = MINOR(ip->i_rdev);
@@ -4103,7 +4260,8 @@
int brdnr, size, n;
#if DEBUG
- printk("stli_memwrite(ip=%x,fp=%x,buf=%x,count=%x)\n", (int) ip, (int) fp, (int) buf, count);
+ printk("stli_memwrite(ip=%x,fp=%x,buf=%x,count=%x)\n", (int) ip,
+ (int) fp, (int) buf, count);
#endif
brdnr = MINOR(ip->i_rdev);
@@ -4205,31 +4363,28 @@
* what port to get stats for (used through board control device).
*/
-static int stli_getportstats(stliport_t *portp, comstats_t *cp)
+static int stli_portcmdstats(stliport_t *portp)
{
unsigned long flags;
stlibrd_t *brdp;
int rc;
- if (portp == (stliport_t *) NULL) {
- memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
- portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
- if (portp == (stliport_t *) NULL)
- return(-ENODEV);
- }
+ memset(&stli_comstats, 0, sizeof(comstats_t));
+ if (portp == (stliport_t *) NULL)
+ return(-ENODEV);
brdp = stli_brds[portp->brdnr];
if (brdp == (stlibrd_t *) NULL)
return(-ENODEV);
if (brdp->state & BST_STARTED) {
- if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
+ if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,
+ &stli_cdkstats, sizeof(asystats_t), 1)) < 0)
return(rc);
} else {
memset(&stli_cdkstats, 0, sizeof(asystats_t));
}
- memset(&stli_comstats, 0, sizeof(comstats_t));
stli_comstats.brd = portp->brdnr;
stli_comstats.panel = portp->panelnr;
stli_comstats.port = portp->portnr;
@@ -4272,6 +4427,37 @@
stli_comstats.hwid = stli_cdkstats.hwid;
stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
+ return(0);
+}
+
+/*****************************************************************************/
+
+/*
+ * Return the port stats structure to user app. A NULL port struct
+ * pointer passed in means that we need to find out from the app
+ * what port to get stats for (used through board control device).
+ */
+
+static int stli_getportstats(stliport_t *portp, comstats_t *cp)
+{
+ stlibrd_t *brdp;
+ int rc;
+
+ if (portp == (stliport_t *) NULL) {
+ memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
+ portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
+ stli_comstats.port);
+ if (portp == (stliport_t *) NULL)
+ return(-ENODEV);
+ }
+
+ brdp = stli_brds[portp->brdnr];
+ if (brdp == (stlibrd_t *) NULL)
+ return(-ENODEV);
+
+ if ((rc = stli_portcmdstats(portp)) < 0)
+ return(rc);
+
memcpy_tofs(cp, &stli_comstats, sizeof(comstats_t));
return(0);
}
@@ -4289,7 +4475,8 @@
if (portp == (stliport_t *) NULL) {
memcpy_fromfs(&stli_comstats, cp, sizeof(comstats_t));
- portp = stli_getport(stli_comstats.brd, stli_comstats.panel, stli_comstats.port);
+ portp = stli_getport(stli_comstats.brd, stli_comstats.panel,
+ stli_comstats.port);
if (portp == (stliport_t *) NULL)
return(-ENODEV);
}
@@ -4354,6 +4541,26 @@
/*****************************************************************************/
/*
+ * Memory device open code. Need to keep track of opens and close
+ * for module handling.
+ */
+
+static int stli_memopen(struct inode *ip, struct file *fp)
+{
+ MOD_INC_USE_COUNT;
+ return(0);
+}
+
+/*****************************************************************************/
+
+static void stli_memclose(struct inode *ip, struct file *fp)
+{
+ MOD_DEC_USE_COUNT;
+}
+
+/*****************************************************************************/
+
+/*
* The "staliomem" device is also required to do some special operations on
* the board. We need to be able to send an interrupt to the board,
* reset it, and start/stop it.
@@ -4365,7 +4572,8 @@
int brdnr, rc, done;
#if DEBUG
- printk("stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip, (int) fp, cmd, (int) arg);
+ printk("stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip,
+ (int) fp, cmd, (int) arg);
#endif
/*
@@ -4376,27 +4584,34 @@
switch (cmd) {
case COM_GETPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
- rc = stli_getportstats((stliport_t *) NULL, (comstats_t *) arg);
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(comstats_t))) == 0)
+ rc = stli_getportstats((stliport_t *) NULL,
+ (comstats_t *) arg);
done++;
break;
case COM_CLRPORTSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(comstats_t))) == 0)
- rc = stli_clrportstats((stliport_t *) NULL, (comstats_t *) arg);
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(comstats_t))) == 0)
+ rc = stli_clrportstats((stliport_t *) NULL,
+ (comstats_t *) arg);
done++;
break;
case COM_GETBRDSTATS:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(combrd_t))) == 0)
rc = stli_getbrdstats((combrd_t *) arg);
done++;
break;
case COM_READPORT:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stliport_t))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(stliport_t))) == 0)
rc = stli_getportstruct(arg);
done++;
break;
case COM_READBOARD:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlibrd_t))) == 0)
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(stlibrd_t))) == 0)
rc = stli_getbrdstruct(arg);
done++;
break;
@@ -4450,7 +4665,7 @@
int stli_init()
{
- printk(KERN_INFO "%s: version %s\n", stli_drvname, stli_drvversion);
+ printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
stli_initbrds();
@@ -4459,10 +4674,12 @@
*/
stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
if (stli_tmpwritebuf == (char *) NULL)
- printk("STALLION: failed to allocate memory (size=%d)\n", STLI_TXBUFSIZE);
+ printk("STALLION: failed to allocate memory (size=%d)\n",
+ STLI_TXBUFSIZE);
stli_txcookbuf = (char *) stli_memalloc(STLI_TXBUFSIZE);
if (stli_txcookbuf == (char *) NULL)
- printk("STALLION: failed to allocate memory (size=%d)\n", STLI_TXBUFSIZE);
+ printk("STALLION: failed to allocate memory (size=%d)\n",
+ STLI_TXBUFSIZE);
/*
* Set up a character driver for the shared memory region. We need this
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov