diff options
author | Peter Wemm <peter@FreeBSD.org> | 1996-05-04 06:09:47 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 1996-05-04 06:09:47 +0000 |
commit | 7450fe9fc2cbb874eb1d0632fd086f71ef20961d (patch) | |
tree | 74df889d984899195d330c67c2762a396cb6b3c6 | |
parent | 0a9462e35325b60cb1b2b7e71377dfa1d39b2132 (diff) |
Import v0.0.2 alpha of the Stallion drivervendor/stallion/v0_0_2_alpha
Submitted by: Greg Ungerer (gerg@stallion.oz.au)
Notes
Notes:
svn path=/vendor/stallion/dist/; revision=15590
svn path=/vendor/stallion/v0_0_2_alpha/; revision=15592; tag=vendor/stallion/v0_0_2_alpha
-rw-r--r-- | sys/i386/isa/README.stl | 34 | ||||
-rw-r--r-- | sys/i386/isa/stallion.c | 192 |
2 files changed, 158 insertions, 68 deletions
diff --git a/sys/i386/isa/README.stl b/sys/i386/isa/README.stl index 585b91bad070..312eaa063c39 100644 --- a/sys/i386/isa/README.stl +++ b/sys/i386/isa/README.stl @@ -2,8 +2,8 @@ Stallion Multiport Serial Driver Readme --------------------------------------- -Version: 0.0.1 alpha -Date: 21DEC95 +Version: 0.0.2 alpha +Date: 08JAN96 Author: Greg Ungerer (gerg@stallion.oz.au) @@ -11,8 +11,8 @@ Author: Greg Ungerer (gerg@stallion.oz.au) 1. INTRODUCTION This is a FreeBSD driver for some of the Stallion Technologies range of -multiport serial boards. This is the very first release of this driver, so -it should be considered to be of very alpha quality. +multiport serial boards. This driver is still very new, so it should be +considered to be of very alpha quality. This driver has not been developed by Stallion Technologies. I developed it in my spare time in the hope that it would be useful. As such there is no @@ -63,8 +63,9 @@ out for those some time soon... 2. INSTALLATION -This driver was developed on a FreeBSD 2.0.5 system. I have not tryed it -on a 2.1 system yet, so I don't know if it will go in painlessly or not... +This driver, as is, will work on a FreeBSD 2.1 system. It will run on +a 2.0.5 system, or -current version systems by changing a define in the +driver source. You will need to build a new kernel to use this driver. So the first thing you need is to have the full kernel source. Most people will have this @@ -81,13 +82,16 @@ Instructions to install: cp stallion.c /usr/src/sys/i386/isa cp scd1400.h /usr/src/sys/i386/ic + Note: if you are not using FreeBSD 2.1.0 then you may need to edit the + stallion.c file and change the VFREEBSD define to match your version. + 2. Add a character device switch table entry for the driver into the cdevsw table structure. This involves adding some code into the kernel conf.c file: cd /usr/src/sys/i386/i386 vi conf.c - - add the following lines (in 2.0.5 I put them at line 1019): + - add the following lines (in 2.1 I put them at line 729): /* Stallion Multiport Serial Driver */ #include "stl.h" @@ -117,13 +121,13 @@ d_ttycv_t stldevtotty; - and then inside the actual cdevsw structure definition, at the - last entry add (this is now line 1259 in the 2.0.5 conf.c): + last entry add (this is now line 1384 in the 2.1 conf.c): - { stlopen, stlclose, stlread, stlwrite, /*67*/ + { stlopen, stlclose, stlread, stlwrite, /*72*/ stlioctl, stlstop, stlreset, stldevtotty,/*stallion*/ ttselect, stlmmap, stlstrategy }, - - the line above used major number 67, but this may be different + - the line above used major number 72, but this may be different on your system. Take note of what major number you are using. - save the file and exit vi. @@ -193,7 +197,7 @@ more than 1 board then just supply the number of boards you are using as a command line parameter to mkdevnods and it will create nodes for that number of boards. By default it will create device nodes for 1 board only. -Note that if the driver is not installed at character major number 67 then +Note that if the driver is not installed at character major number 72 then you will need to edit the mkdevnods script and modify the STL_SERIALMAJOR variable to the major number you are using. @@ -223,14 +227,14 @@ under FreeBSD: 4. NOTES -Be aware that this is the first release of this driver, so there is sure to -be some bugs in it. Please email me any feedback on bugs, problems, or even -good experiences with this driver! +Be aware that this driver is still very new, so there is sure to be some bugs +in it. Please email me any feedback on bugs, problems, or even good +experiences with this driver! There is no real smart line discipline bypass code yet (like in the sio driver). I will add this for the next driver release. -I will probably also add LKM support for the next driver release. +I will probably also add LKM support some time soon. diff --git a/sys/i386/isa/stallion.c b/sys/i386/isa/stallion.c index 041a1408021e..4b4346333f8d 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); } |