diff options
author | peter <peter@FreeBSD.org> | 1996-05-04 06:09:47 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-05-04 06:09:47 +0000 |
commit | 69bc3a9cf9fa2d75a43750a1680190c8d1b8d095 (patch) | |
tree | 74df889d984899195d330c67c2762a396cb6b3c6 /sys/i386/isa/stallion.c | |
parent | afae86dda58478de9031853ec44f2ce94fce30a0 (diff) | |
download | FreeBSD-src-69bc3a9cf9fa2d75a43750a1680190c8d1b8d095.zip FreeBSD-src-69bc3a9cf9fa2d75a43750a1680190c8d1b8d095.tar.gz |
Import v0.0.2 alpha of the Stallion driver
Submitted by: Greg Ungerer (gerg@stallion.oz.au)
Diffstat (limited to 'sys/i386/isa/stallion.c')
-rw-r--r-- | sys/i386/isa/stallion.c | 192 |
1 files changed, 139 insertions, 53 deletions
diff --git a/sys/i386/isa/stallion.c b/sys/i386/isa/stallion.c index 041a140..4b43463 100644 --- a/sys/i386/isa/stallion.c +++ b/sys/i386/isa/stallion.c @@ -45,11 +45,11 @@ #include <sys/ioctl.h> #include <sys/tty.h> #include <sys/proc.h> -#include <sys/user.h> #include <sys/conf.h> #include <sys/file.h> #include <sys/uio.h> #include <sys/syslog.h> +#include <sys/devconf.h> #include <machine/cpu.h> #include <machine/clock.h> @@ -59,6 +59,21 @@ /*****************************************************************************/ /* + * Define the version level of the kernel - so we can compile in the + * appropriate bits of code. By default this will compile for a 2.1 + * level kernel. + */ +#define VFREEBSD 210 + +#if VFREEBSD >= 220 +#define STATIC static +#else +#define STATIC +#endif + +/*****************************************************************************/ + +/* * Define different board types. At the moment I have only declared * those boards that this driver supports. But I will use the standard * "assigned" board numbers. In the future this driver will support @@ -120,7 +135,7 @@ static unsigned int stl_irqshared = 0; */ static char *stl_drvname = "stl"; static char *stl_longdrvname = "Stallion Multiport Serial Driver"; -static char *stl_drvversion = "0.0.1"; +static char *stl_drvversion = "0.0.2"; static int stl_brdprobed[STL_MAXBRDS]; static int stl_nrbrds = 0; @@ -396,20 +411,28 @@ static int stl_cd1400clkdivs[] = { /* * Declare all those functions in this driver! First up is the set of - * externally visible functions. Followed by the internal functions. - */ -int stlprobe(struct isa_device *idp); -int stlattach(struct isa_device *idp); -void stlintr(int unit); -int stlopen(dev_t dev, int flag, int mode, struct proc *p); -int stlclose(dev_t dev, int flag, int mode, struct proc *p); -int stlwrite(dev_t dev, struct uio *uiop, int flag); -int stlread(dev_t dev, struct uio *uiop, int flag); -int stlioctl(dev_t dev, int cmd, caddr_t data, int flag, - struct proc *p); -int stlstop(struct tty *tp, int rw); + * externally visible functions. + */ + +int stlprobe(struct isa_device *idp); +int stlattach(struct isa_device *idp); + +STATIC d_open_t stlopen; +STATIC d_close_t stlclose; +STATIC d_read_t stlread; +STATIC d_write_t stlwrite; +STATIC d_ioctl_t stlioctl; +STATIC d_stop_t stlstop; + +#if VFREEBSD >= 220 +STATIC d_devtotty_t stldevtotty; +#else struct tty *stldevtotty(dev_t dev); +#endif +/* + * Internal function prototypes. + */ static stlport_t *stl_dev2port(dev_t dev); static int stl_rawopen(stlport_t *portp); static int stl_rawclose(stlport_t *portp); @@ -450,6 +473,38 @@ struct isa_driver stldriver = { /*****************************************************************************/ +#if VFREEBSD >= 220 + +/* + * FreeBSD-2.2+ kernel linkage. + */ + +#define CDEV_MAJOR 70 + +static struct cdevsw stl_cdevsw = + { stlopen, stlclose, stlread, stlwrite, + stlioctl, stlstop, noreset, stldevtotty, + ttselect, nommap, NULL, "stl", NULL, -1 }; + +static stl_devsw_installed = 0; + +static void stl_drvinit(void *unused) +{ + dev_t dev; + + if (! stl_devsw_installed ) { + dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev, &stl_cdevsw, NULL); + stl_devsw_installed = 1; + } +} + +SYSINIT(sidev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,stl_drvinit,NULL) + +#endif + +/*****************************************************************************/ + /* * Probe for some type of EasyIO or EasyConnection 8/32 board at * the supplied address. All we do is check if we can find the @@ -528,7 +583,7 @@ int stlattach(struct isa_device *idp) /*****************************************************************************/ -int stlopen(dev_t dev, int flag, int mode, struct proc *p) +STATIC int stlopen(dev_t dev, int flag, int mode, struct proc *p) { struct tty *tp; stlport_t *portp; @@ -585,7 +640,7 @@ stlopen_restart: goto stlopen_end; } } else { - if (callout) { + if (portp->callout != 0) { if (flag & O_NONBLOCK) { error = EBUSY; goto stlopen_end; @@ -611,7 +666,7 @@ stlopen_restart: ((tp->t_cflag & CLOCAL) == 0) && ((flag & O_NONBLOCK) == 0)) { portp->waitopens++; - error = tsleep(&tp->t_rawq, (TTIPRI | PCATCH), "stldcd", 0); + error = tsleep(TSA_CARR_ON(tp), (TTIPRI | PCATCH), "stldcd",0); portp->waitopens--; if (error) goto stlopen_end; @@ -632,7 +687,7 @@ stlopen_restart: */ stlopen_end: splx(x); - if ((tp->t_state & TS_ISOPEN) == 0) + if (((tp->t_state & TS_ISOPEN) == 0) && (portp->waitopens == 0)) stl_rawclose(portp); return(error); @@ -640,7 +695,7 @@ stlopen_end: /*****************************************************************************/ -int stlclose(dev_t dev, int flag, int mode, struct proc *p) +STATIC int stlclose(dev_t dev, int flag, int mode, struct proc *p) { struct tty *tp; stlport_t *portp; @@ -665,7 +720,7 @@ int stlclose(dev_t dev, int flag, int mode, struct proc *p) /*****************************************************************************/ -int stlread(dev_t dev, struct uio *uiop, int flag) +STATIC int stlread(dev_t dev, struct uio *uiop, int flag) { stlport_t *portp; @@ -681,19 +736,28 @@ int stlread(dev_t dev, struct uio *uiop, int flag) /*****************************************************************************/ -int stlstop(struct tty *tp, int rw) +#if VFREEBSD >= 220 +STATIC void stlstop(struct tty *tp, int rw) +#else +STATIC int stlstop(struct tty *tp, int rw) +#endif { #if DEBUG printf("stlstop(tp=%x,rw=%x)\n", (int) tp, rw); #endif stl_flush((stlport_t *) tp, rw); + +#if VFREEBSD >= 220 + return; +#else return(0); +#endif } /*****************************************************************************/ -struct tty *stldevtotty(dev_t dev) +STATIC struct tty *stldevtotty(dev_t dev) { #if DEBUG printf("stldevtotty(dev=%x)\n", dev); @@ -703,7 +767,7 @@ struct tty *stldevtotty(dev_t dev) /*****************************************************************************/ -int stlwrite(dev_t dev, struct uio *uiop, int flag) +STATIC int stlwrite(dev_t dev, struct uio *uiop, int flag) { stlport_t *portp; @@ -719,7 +783,7 @@ int stlwrite(dev_t dev, struct uio *uiop, int flag) /*****************************************************************************/ -int stlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) +STATIC int stlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) { struct termios *newtios, *localtios; struct tty *tp; @@ -789,15 +853,14 @@ int stlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) } #endif -#if 0 /* * Carry out some pre-cmd processing work first... * Hmmm, not so sure we want this, disable for now... */ if ((cmd == TIOCSETA) || (cmd == TIOCSETAW) || (cmd == TIOCSETAF)) { newtios = (struct termios *) data; - localtios = (dev & STL_CALLOUTDEV) ? &portp->initouttios : - &portp->initintios; + localtios = (dev & STL_CALLOUTDEV) ? &portp->lockouttios : + &portp->lockintios; newtios->c_iflag = (tp->t_iflag & localtios->c_iflag) | (newtios->c_iflag & ~localtios->c_iflag); @@ -816,7 +879,6 @@ int stlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) if (localtios->c_ospeed != 0) newtios->c_ospeed = tp->t_ospeed; } -#endif /* * Call the line discipline and the common command processing to @@ -899,7 +961,7 @@ int stlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) * pointer. Return NULL if the device number is not a valid port. */ -static stlport_t *stl_dev2port(dev_t dev) +STATIC stlport_t *stl_dev2port(dev_t dev) { stlbrd_t *brdp; int brdnr, portnr; @@ -970,7 +1032,7 @@ static int stl_rawclose(stlport_t *portp) portp->brklen = 0; portp->state &= ~(ASY_ACTIVE | ASY_RTSFLOW); wakeup(&portp->callout); - wakeup(&tp->t_rawq); + wakeup(TSA_CARR_ON(tp)); return(0); } @@ -1028,6 +1090,7 @@ static void stl_start(struct tty *tp) stl_flowcontrol(portp, 1, -1); } +#if VFREEBSD == 205 /* * Check if the output cooked clist buffers are near empty, wake up * the line discipline to fill it up. @@ -1039,6 +1102,15 @@ static void stl_start(struct tty *tp) } selwakeup(&tp->t_wsel); } +#endif + +/* + * Do not transmit if we are timing out or stopped. + */ + if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { + splx(x); + return; + } /* * Copy data from the clists into the interrupt ring queue. This will @@ -1049,34 +1121,48 @@ static void stl_start(struct tty *tp) * spl protect our-selves, since we only ever update the head pointer, * and the interrupt routine only ever updates the tail pointer. */ - head = portp->tx.head; - tail = portp->tx.tail; - if (head >= tail) { - len = STL_TXBUFSIZE - (head - tail) - 1; - stlen = portp->tx.endbuf - head; - } else { - len = tail - head - 1; - stlen = len; - } + if (tp->t_outq.c_cc != 0) { + head = portp->tx.head; + tail = portp->tx.tail; + if (head >= tail) { + len = STL_TXBUFSIZE - (head - tail) - 1; + stlen = portp->tx.endbuf - head; + } else { + len = tail - head - 1; + stlen = len; + } - if (len > 0) { - stlen = MIN(len, stlen); - count = q_to_b(&tp->t_outq, head, stlen); - len -= count; - head += count; - if (head >= portp->tx.endbuf) { - head = portp->tx.buf; - if (len > 0) { - stlen = q_to_b(&tp->t_outq, head, len); - head += stlen; - count += stlen; + if (len > 0) { + stlen = MIN(len, stlen); + count = q_to_b(&tp->t_outq, head, stlen); + len -= count; + head += count; + if (head >= portp->tx.endbuf) { + head = portp->tx.buf; + if (len > 0) { + stlen = q_to_b(&tp->t_outq, head, len); + head += stlen; + count += stlen; + } } + portp->tx.head = head; + if (count > 0) + stl_startrxtx(portp, -1, 1); } - portp->tx.head = head; - if (count > 0) - stl_startrxtx(portp, -1, 1); + +/* + * If we sent something, make sure we are called again. + */ + tp->t_state |= TS_BUSY; } +#if VFREEBSD != 205 +/* + * Do any writer wakeups. + */ + ttwwakeup(tp); +#endif + splx(x); } |