xref: /csrg-svn/sys/vax/datakit/dksub.c (revision 45800)
138624Skarels /*
238624Skarels  * Datakit driver
338624Skarels  * Common subroutines for all drivers
438624Skarels  *	SCCSID[] = "@(#)dksub.c	1.2 Garage 84/03/27"
5*45800Sbostic  *		   "@(#)dksub.c	1.7 (Berkeley) 12/16/90"
638624Skarels  */
738624Skarels 
838624Skarels #include "datakit.h"
938624Skarels #if NDATAKIT>0
1038624Skarels 
11*45800Sbostic #include "../include/pte.h"
12*45800Sbostic #include "sys/param.h"
13*45800Sbostic #include "sys/signal.h"
14*45800Sbostic #include "sys/errno.h"
15*45800Sbostic #include "sys/seg.h"
16*45800Sbostic #include "sys/user.h"
17*45800Sbostic #include "sys/ioctl.h"
18*45800Sbostic #include "sys/tty.h"
19*45800Sbostic #include "sys/syslog.h"
20*45800Sbostic #include "sys/conf.h"
21*45800Sbostic #include "sys/file.h"
22*45800Sbostic #include "sys/systm.h"
23*45800Sbostic #include "sys/proc.h"
24*45800Sbostic #include "sys/mbuf.h"
25*45800Sbostic #include "sys/buf.h"
26*45800Sbostic #include "sys/uio.h"
27*45800Sbostic #include "sys/vnode.h"
28*45800Sbostic #include "sys/specdev.h"
2938624Skarels #include "dkit.h"
3038624Skarels #include "dk.h"
3138624Skarels #include "dkdev.h"
3238624Skarels 
3338624Skarels #define DKBUFUSE	5	/* max buffers /channel */
3438624Skarels 
3538624Skarels 
3638624Skarels extern struct dkdev dkdev[] ;
3738624Skarels 
3838624Skarels int	dksubdebug = 512;
3938624Skarels 
4038624Skarels 
dkuread(chan,uio)4138624Skarels dkuread(chan, uio)
4238624Skarels register struct uio *uio;
4338624Skarels {
4438624Skarels 	register int len, blen ;
4538624Skarels 	register struct dkdev *tp ;
4638624Skarels 	short chanstat ;
4738624Skarels 	struct mbuf *mm ;
4838624Skarels 	int err = 0, s;
4938624Skarels 	extern wakeup() ;
5038624Skarels 	extern dkrdone() ;
5138624Skarels 
5238624Skarels 	tp = &dkdev[chan];
5338624Skarels 	MGET(mm, M_WAIT, DKMT_DATA);
5438624Skarels 	if (mm == NULL)
5538624Skarels 		return ENOBUFS;
5638624Skarels 	if (uio->uio_resid >= MLEN) {
5743388Skarels 		MCLGET(mm, M_WAIT);
5843388Skarels 		if ((mm->m_flags & M_EXT) == 0)
5938624Skarels 			goto nopages;
6043388Skarels 		blen = MCLBYTES;
6138624Skarels 	} else {
6238624Skarels nopages:
6338624Skarels 		blen = MIN(MLEN, uio->uio_resid);
6438624Skarels 	}
6538624Skarels 
6638624Skarels 	while (uio->uio_resid && !err) {
6738624Skarels 		len = MIN(uio->uio_resid, blen) ;
6838624Skarels 		chanstat = dk_recv(chan, mtod(mm, caddr_t), len, tp->d_rmode, dkrdone, (caddr_t) tp) ;
6938624Skarels 		if (chanstat == 0) {
7038624Skarels 			if ((dk_status(chan) & DK_RESET) == 0)
7138624Skarels 				err = EIO ;
7238624Skarels 			break;
7338624Skarels 		}
7438624Skarels 		if ((tp->dc_state & DK_NDELAY) && (dk_status(chan) & DK_RCV)) {
7538624Skarels 			err = EWOULDBLOCK;
7638624Skarels 			break;
7738624Skarels 		}
7838624Skarels 
7938624Skarels 		s = spl5() ;
8038624Skarels 		while (dk_status(chan) & DK_RCV)
8145184Skarels 			if (err = tsleep((caddr_t)(tp), TTIPRI, ttyin, 0)) {
8245184Skarels 				if (dk_status(chan) & DK_RCV)
8345184Skarels 					(void) dk_rabort(chan, dkrdone,
8445184Skarels 					    (caddr_t) tp);
8545184Skarels 				splx(s);
8645184Skarels 				goto done;
8745184Skarels 			}
8838624Skarels 		splx(s) ;
8938624Skarels 
9038624Skarels 		len -= tp->d_rresid ;
9138624Skarels 		if (len)
9238624Skarels 			err = uiomove(mtod(mm, caddr_t), len, UIO_READ, uio);
9338624Skarels 		if (tp->d_rdone != DKR_FULL)
9438624Skarels 			break ;
9538624Skarels 	}
9645184Skarels done:
9738624Skarels 	m_freem(mm) ;
9838624Skarels 	return err;
9938624Skarels }
10038624Skarels 
10138624Skarels 
10238624Skarels /*ARGSUSED*/
dkrdone(tp,chan,resid,rdone,rctl)10338624Skarels dkrdone(tp, chan, resid, rdone, rctl)
10438624Skarels register struct dkdev *tp ;
10538624Skarels {
10638624Skarels 	tp->d_rresid = resid ;
10738624Skarels 	tp->d_rdone = rdone ;
10838624Skarels 	tp->d_rctl = rctl ;
10938624Skarels 	wakeup((caddr_t) tp) ;
11038624Skarels }
11138624Skarels 
11238624Skarels 
11338624Skarels 
11438624Skarels 
dkuwrite(chan,uio)11538624Skarels dkuwrite(chan, uio) register struct uio *uio;
11638624Skarels {
11738624Skarels extern wakeup() ;
11838624Skarels extern dkwdone() ;
11938624Skarels register struct dkdev *tp ;
12038624Skarels register len ;
12138624Skarels register struct mbuf *m;
12238624Skarels register struct iovec *iov;
12338624Skarels int s, error, eob;
12438624Skarels short xc;
12538624Skarels 
12638624Skarels 	tp = &dkdev[chan] ;
12738624Skarels 	do {
12838624Skarels 		s = spl5() ;
12938624Skarels 		while (tp->d_bufct > DKBUFUSE) {
13038624Skarels 			if (tp->dc_state & DK_NDELAY) {
13138624Skarels 				splx(s);
13238624Skarels 				return EWOULDBLOCK;
13338624Skarels 			}
13438624Skarels 			tp->d_state |= DKWAIT ;
13545184Skarels 			if (error = tsleep((caddr_t)(&tp->d_state), TTOPRI,
13645184Skarels 			    ttyout, 0)) {
13745184Skarels 				splx(s);
13845184Skarels 				return (error);
13945184Skarels 			}
14038624Skarels 		}
14138624Skarels 		splx(s) ;
14238624Skarels 
14338624Skarels 		iov = uio->uio_iov;
14438624Skarels 		if (iov->iov_len) {
14538624Skarels 			MGET(m, M_WAIT, DKMT_DATA);
14638624Skarels 			if (m == NULL)
14738624Skarels 				return ENOBUFS;
14838624Skarels 			if (iov->iov_len >= MLEN) {
14943388Skarels 				MCLGET(m, M_WAIT);
15043388Skarels 				if ((m->m_flags & M_EXT) == 0)
15138624Skarels 					goto nopages;
15243388Skarels 				len = MIN(MCLBYTES, iov->iov_len);
15338624Skarels 			} else {
15438624Skarels nopages:
15538624Skarels 				len = MIN(MLEN, iov->iov_len);
15638624Skarels 			}
15738624Skarels 			error = uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
15838624Skarels 			if (error) {
15938624Skarels 				(void) m_free(m);
16038624Skarels 				return error;
16138624Skarels 			}
16238624Skarels 			m->m_len = len;
16338624Skarels 		}
16438624Skarels 		else m = NULL;
16538624Skarels 
16638624Skarels 		s = spl5();
16738624Skarels 		tp->d_bufct++;
16838624Skarels 		eob = (uio->uio_resid == 0);
16938624Skarels 		if (eob) {
17038624Skarels 			xc = tp->d_xctl;
17138624Skarels 			tp->d_xctl = 0;
17238624Skarels 		}
17338624Skarels 		else xc = 0;
17438624Skarels 		if (dk_xmit(chan, m, eob, xc, dkwdone, (caddr_t) 0) == 0) {
17538624Skarels 			tp->d_bufct-- ;
17638624Skarels 			return EIO ;
17738624Skarels 		}
17838624Skarels 		splx(s);
17938624Skarels 	} while (uio->uio_resid);
18038624Skarels 	return 0;
18138624Skarels }
18238624Skarels 
18338624Skarels /*ARGSUSED*/
dkwdone(x,chan)18438624Skarels dkwdone(x, chan)
18538624Skarels {
18638624Skarels 	register struct dkdev *tp ;
18738624Skarels 
18838624Skarels 	tp = &dkdev[chan] ;
18938624Skarels 	if (chan > dksubdebug)
19038624Skarels 		log(LOG_ERR, "dkwdone %d: state=0%o bufct=%d\n", chan, tp->d_state,
19138624Skarels 		    tp->d_bufct);
19238624Skarels 	if (tp->d_bufct)
19338624Skarels 		tp->d_bufct-- ;
19438624Skarels 	if (tp->d_state & DKWAIT) {
19538624Skarels 		tp->d_state &= ~DKWAIT ;
19638624Skarels 		wakeup((caddr_t) &tp->d_state) ;
19738624Skarels 	}
19838624Skarels }
19938624Skarels 
20038624Skarels /* wakeup and reinitialize channel upon receipt of reconnection message */
dkrsplice(chan)20138624Skarels dkrsplice(chan)
20238624Skarels {
20338624Skarels 	register struct dkdev *tp ;
20438624Skarels 
20538624Skarels 	tp = &dkdev[chan] ;
20638624Skarels 	tp->d_state |= DKSPLICED ;
20738624Skarels 	wakeup((caddr_t) tp) ;
20838624Skarels 	dk_cmd(chan, DKC_XINIT) ;
20938624Skarels }
21038624Skarels 
21138624Skarels /* wait for reconnection message indicating that splice completed */
dksplwait(chan)21238624Skarels dksplwait(chan)
21338624Skarels {
21438624Skarels 	register struct dkdev *tp ;
21545184Skarels 	int error;
21638624Skarels 
21738624Skarels 	tp = &dkdev[chan] ;
21838624Skarels 	while ((tp->d_state & DKSPLICED) == 0)
21945184Skarels 		if (error = tsleep((caddr_t) tp, TTOPRI, ttopen, 0))
22045184Skarels 			return (error);
22145184Skarels 	return (0);
22238624Skarels }
22338624Skarels 
22438624Skarels /* convert file desciptor to Datakit channel */
dkgetdev(fildes,devnop)22543390Smckusick dkgetdev(fildes, devnop)
22643390Smckusick 	int fildes, *devnop;
22738624Skarels {
22843390Smckusick 	struct file *fp;
22943390Smckusick 	register struct vnode *vp ;
23043390Smckusick 	int error;
23138624Skarels 
23243390Smckusick 	if (error = getvnode(u.u_ofile, fildes, &fp))
23343390Smckusick 		return error;
23443390Smckusick 	vp = (struct vnode *)fp->f_data;
23543390Smckusick 	if (vp->v_type != VCHR)
23643390Smckusick 		return ENOTTY;
23745199Smckusick 	if (dkdevtype(vp->v_rdev)) {
23845199Smckusick 		*devnop = minor(vp->v_rdev);
23943390Smckusick 		return 0;
24038624Skarels 	}
24143390Smckusick 	return EINVAL;
24238624Skarels }
24338624Skarels 
24438624Skarels /* validate device number as belonging to Datakit */
dkdevtype(dev)24538624Skarels dkdevtype(dev) dev_t dev;
24638624Skarels {
24738624Skarels 	extern dkopen();
24838624Skarels #if NDKTTY > 0
24938624Skarels 	extern dktopen();
25038624Skarels #endif
25138624Skarels #if NDKXQT > 0
25238624Skarels 	extern dkxopen();
25338624Skarels #endif
25438624Skarels #if NDKI > 0
25538624Skarels 	extern dkiopen();
25638624Skarels #endif
25738624Skarels 	register md = major(dev) ;
25838624Skarels 
25938624Skarels 	if ((cdevsw[md].d_open == dkopen)
26038624Skarels #if NDKTTY > 0
26138624Skarels 		|| (cdevsw[md].d_open == dktopen)
26238624Skarels #endif
26338624Skarels #if NDKI > 0
26438624Skarels 		|| (cdevsw[md].d_open == dkiopen && md > 0)
26538624Skarels #endif
26638624Skarels #if NDKXQT > 0
26738624Skarels 		|| (cdevsw[md].d_open == dkxopen)
26838624Skarels #endif
26938624Skarels 	    )
27038624Skarels 			return(1);
27138624Skarels 	else
27238624Skarels 		return(0);
27338624Skarels }
27438624Skarels 
27538624Skarels #endif
276