xref: /csrg-svn/sys/vax/datakit/dksub.c (revision 43390)
138624Skarels /*
238624Skarels  * Datakit driver
338624Skarels  * Common subroutines for all drivers
438624Skarels  *	SCCSID[] = "@(#)dksub.c	1.2 Garage 84/03/27"
5*43390Smckusick  *		   "@(#)dksub.c	1.4 (Berkeley) 06/21/90"
638624Skarels  */
738624Skarels 
838624Skarels #include "datakit.h"
938624Skarels #if NDATAKIT>0
1038624Skarels 
1138624Skarels #include "param.h"
1238624Skarels #include "../machine/pte.h"
1338624Skarels #include "signal.h"
1438624Skarels #include "errno.h"
1538624Skarels #include "seg.h"
1638624Skarels #include "user.h"
1738624Skarels #include "ioctl.h"
1838624Skarels #include "tty.h"
1938624Skarels #include "syslog.h"
2038624Skarels #include "conf.h"
2138624Skarels #include "file.h"
2238624Skarels #include "inode.h"
2338624Skarels #include "systm.h"
2438624Skarels #include "proc.h"
2538624Skarels #include "mbuf.h"
2638624Skarels #include "buf.h"
2738624Skarels #include "uio.h"
2838624Skarels #include "dkit.h"
2938624Skarels #include "dk.h"
3038624Skarels #include "dkdev.h"
3138624Skarels 
3238624Skarels #define DKBUFUSE	5	/* max buffers /channel */
3338624Skarels 
3438624Skarels 
3538624Skarels extern struct dkdev dkdev[] ;
3638624Skarels 
3738624Skarels int	dksubdebug = 512;
3838624Skarels 
3938624Skarels 
4038624Skarels dkuread(chan, uio)
4138624Skarels register struct uio *uio;
4238624Skarels {
4338624Skarels 	register int len, blen ;
4438624Skarels 	register struct dkdev *tp ;
4538624Skarels 	short chanstat ;
4638624Skarels 	struct mbuf *mm ;
4738624Skarels 	int err = 0, s;
4838624Skarels 	extern wakeup() ;
4938624Skarels 	extern dkrdone() ;
5038624Skarels 
5138624Skarels 	tp = &dkdev[chan];
5238624Skarels 	MGET(mm, M_WAIT, DKMT_DATA);
5338624Skarels 	if (mm == NULL)
5438624Skarels 		return ENOBUFS;
5538624Skarels 	if (uio->uio_resid >= MLEN) {
5643388Skarels 		MCLGET(mm, M_WAIT);
5743388Skarels 		if ((mm->m_flags & M_EXT) == 0)
5838624Skarels 			goto nopages;
5943388Skarels 		blen = MCLBYTES;
6038624Skarels 	} else {
6138624Skarels nopages:
6238624Skarels 		blen = MIN(MLEN, uio->uio_resid);
6338624Skarels 	}
6438624Skarels 
6538624Skarels 	if (setjmp(&u.u_qsave)) {
6638624Skarels 		s = spl5();
6738624Skarels 		if (dk_status(chan) & DK_RCV)
6838624Skarels 			(void) dk_rabort(chan, dkrdone, (caddr_t) tp) ;
6938624Skarels 		splx(s);
7038624Skarels 		m_freem(mm);
7138624Skarels 		return EINTR ;
7238624Skarels 	}
7338624Skarels 
7438624Skarels 	while (uio->uio_resid && !err) {
7538624Skarels 		len = MIN(uio->uio_resid, blen) ;
7638624Skarels 		chanstat = dk_recv(chan, mtod(mm, caddr_t), len, tp->d_rmode, dkrdone, (caddr_t) tp) ;
7738624Skarels 		if (chanstat == 0) {
7838624Skarels 			if ((dk_status(chan) & DK_RESET) == 0)
7938624Skarels 				err = EIO ;
8038624Skarels 			break;
8138624Skarels 		}
8238624Skarels 		if ((tp->dc_state & DK_NDELAY) && (dk_status(chan) & DK_RCV)) {
8338624Skarels 			err = EWOULDBLOCK;
8438624Skarels 			break;
8538624Skarels 		}
8638624Skarels 
8738624Skarels 		s = spl5() ;
8838624Skarels 		while (dk_status(chan) & DK_RCV)
8938624Skarels 			sleep((caddr_t)(tp), TTOPRI) ;
9038624Skarels 		splx(s) ;
9138624Skarels 
9238624Skarels 		len -= tp->d_rresid ;
9338624Skarels 		if (len)
9438624Skarels 			err = uiomove(mtod(mm, caddr_t), len, UIO_READ, uio);
9538624Skarels 		if (tp->d_rdone != DKR_FULL)
9638624Skarels 			break ;
9738624Skarels 	}
9838624Skarels 	m_freem(mm) ;
9938624Skarels 	return err;
10038624Skarels }
10138624Skarels 
10238624Skarels 
10338624Skarels /*ARGSUSED*/
10438624Skarels dkrdone(tp, chan, resid, rdone, rctl)
10538624Skarels register struct dkdev *tp ;
10638624Skarels {
10738624Skarels 	tp->d_rresid = resid ;
10838624Skarels 	tp->d_rdone = rdone ;
10938624Skarels 	tp->d_rctl = rctl ;
11038624Skarels 	wakeup((caddr_t) tp) ;
11138624Skarels }
11238624Skarels 
11338624Skarels 
11438624Skarels 
11538624Skarels 
11638624Skarels dkuwrite(chan, uio) register struct uio *uio;
11738624Skarels {
11838624Skarels extern wakeup() ;
11938624Skarels extern dkwdone() ;
12038624Skarels register struct dkdev *tp ;
12138624Skarels register len ;
12238624Skarels register struct mbuf *m;
12338624Skarels register struct iovec *iov;
12438624Skarels int s, error, eob;
12538624Skarels short xc;
12638624Skarels 
12738624Skarels 	tp = &dkdev[chan] ;
12838624Skarels 	do {
12938624Skarels 		s = spl5() ;
13038624Skarels 		while (tp->d_bufct > DKBUFUSE) {
13138624Skarels 			if (tp->dc_state & DK_NDELAY) {
13238624Skarels 				splx(s);
13338624Skarels 				return EWOULDBLOCK;
13438624Skarels 			}
13538624Skarels 			tp->d_state |= DKWAIT ;
13638624Skarels 			sleep((caddr_t)(&tp->d_state), TTOPRI) ;
13738624Skarels 		}
13838624Skarels 		splx(s) ;
13938624Skarels 
14038624Skarels 		iov = uio->uio_iov;
14138624Skarels 		if (iov->iov_len) {
14238624Skarels 			MGET(m, M_WAIT, DKMT_DATA);
14338624Skarels 			if (m == NULL)
14438624Skarels 				return ENOBUFS;
14538624Skarels 			if (iov->iov_len >= MLEN) {
14643388Skarels 				MCLGET(m, M_WAIT);
14743388Skarels 				if ((m->m_flags & M_EXT) == 0)
14838624Skarels 					goto nopages;
14943388Skarels 				len = MIN(MCLBYTES, iov->iov_len);
15038624Skarels 			} else {
15138624Skarels nopages:
15238624Skarels 				len = MIN(MLEN, iov->iov_len);
15338624Skarels 			}
15438624Skarels 			error = uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
15538624Skarels 			if (error) {
15638624Skarels 				(void) m_free(m);
15738624Skarels 				return error;
15838624Skarels 			}
15938624Skarels 			m->m_len = len;
16038624Skarels 		}
16138624Skarels 		else m = NULL;
16238624Skarels 
16338624Skarels 		s = spl5();
16438624Skarels 		tp->d_bufct++;
16538624Skarels 		eob = (uio->uio_resid == 0);
16638624Skarels 		if (eob) {
16738624Skarels 			xc = tp->d_xctl;
16838624Skarels 			tp->d_xctl = 0;
16938624Skarels 		}
17038624Skarels 		else xc = 0;
17138624Skarels 		if (dk_xmit(chan, m, eob, xc, dkwdone, (caddr_t) 0) == 0) {
17238624Skarels 			tp->d_bufct-- ;
17338624Skarels 			return EIO ;
17438624Skarels 		}
17538624Skarels 		splx(s);
17638624Skarels 	} while (uio->uio_resid);
17738624Skarels 	return 0;
17838624Skarels }
17938624Skarels 
18038624Skarels /*ARGSUSED*/
18138624Skarels dkwdone(x, chan)
18238624Skarels {
18338624Skarels 	register struct dkdev *tp ;
18438624Skarels 
18538624Skarels 	tp = &dkdev[chan] ;
18638624Skarels 	if (chan > dksubdebug)
18738624Skarels 		log(LOG_ERR, "dkwdone %d: state=0%o bufct=%d\n", chan, tp->d_state,
18838624Skarels 		    tp->d_bufct);
18938624Skarels 	if (tp->d_bufct)
19038624Skarels 		tp->d_bufct-- ;
19138624Skarels 	if (tp->d_state & DKWAIT) {
19238624Skarels 		tp->d_state &= ~DKWAIT ;
19338624Skarels 		wakeup((caddr_t) &tp->d_state) ;
19438624Skarels 	}
19538624Skarels }
19638624Skarels 
19738624Skarels /* wakeup and reinitialize channel upon receipt of reconnection message */
19838624Skarels dkrsplice(chan)
19938624Skarels {
20038624Skarels 	register struct dkdev *tp ;
20138624Skarels 
20238624Skarels 	tp = &dkdev[chan] ;
20338624Skarels 	tp->d_state |= DKSPLICED ;
20438624Skarels 	wakeup((caddr_t) tp) ;
20538624Skarels 	dk_cmd(chan, DKC_XINIT) ;
20638624Skarels }
20738624Skarels 
20838624Skarels /* wait for reconnection message indicating that splice completed */
20938624Skarels dksplwait(chan)
21038624Skarels {
21138624Skarels 	register struct dkdev *tp ;
21238624Skarels 
21338624Skarels 	tp = &dkdev[chan] ;
21438624Skarels 	while ((tp->d_state & DKSPLICED) == 0)
21538624Skarels 		sleep((caddr_t) tp, TTOPRI) ;
21638624Skarels }
21738624Skarels 
21838624Skarels /* convert file desciptor to Datakit channel */
219*43390Smckusick dkgetdev(fildes, devnop)
220*43390Smckusick 	int fildes, *devnop;
22138624Skarels {
222*43390Smckusick 	struct file *fp;
223*43390Smckusick 	register struct vnode *vp ;
224*43390Smckusick 	int error;
22538624Skarels 
226*43390Smckusick 	if (error = getvnode(u.u_ofile, fildes, &fp))
227*43390Smckusick 		return error;
228*43390Smckusick 	vp = (struct vnode *)fp->f_data;
229*43390Smckusick 	if (vp->v_type != VCHR)
230*43390Smckusick 		return ENOTTY;
231*43390Smckusick 	if (dkdevtype((dev_t) vp->v_rdev)) {
232*43390Smckusick 		*devnop = minor(ip->i_rdev);
233*43390Smckusick 		return 0;
23438624Skarels 	}
235*43390Smckusick 	return EINVAL;
23638624Skarels }
23738624Skarels 
23838624Skarels /* validate device number as belonging to Datakit */
23938624Skarels dkdevtype(dev) dev_t dev;
24038624Skarels {
24138624Skarels 	extern dkopen();
24238624Skarels #if NDKTTY > 0
24338624Skarels 	extern dktopen();
24438624Skarels #endif
24538624Skarels #if NDKXQT > 0
24638624Skarels 	extern dkxopen();
24738624Skarels #endif
24838624Skarels #if NDKI > 0
24938624Skarels 	extern dkiopen();
25038624Skarels #endif
25138624Skarels 	register md = major(dev) ;
25238624Skarels 
25338624Skarels 	if ((cdevsw[md].d_open == dkopen)
25438624Skarels #if NDKTTY > 0
25538624Skarels 		|| (cdevsw[md].d_open == dktopen)
25638624Skarels #endif
25738624Skarels #if NDKI > 0
25838624Skarels 		|| (cdevsw[md].d_open == dkiopen && md > 0)
25938624Skarels #endif
26038624Skarels #if NDKXQT > 0
26138624Skarels 		|| (cdevsw[md].d_open == dkxopen)
26238624Skarels #endif
26338624Skarels 	    )
26438624Skarels 			return(1);
26538624Skarels 	else
26638624Skarels 		return(0);
26738624Skarels }
26838624Skarels 
26938624Skarels #endif
270