xref: /csrg-svn/sys/vax/datakit/dksub.c (revision 43388)
138624Skarels /*
238624Skarels  * Datakit driver
338624Skarels  * Common subroutines for all drivers
438624Skarels  *	SCCSID[] = "@(#)dksub.c	1.2 Garage 84/03/27"
5*43388Skarels  *		   "@(#)dksub.c	1.3 (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) {
56*43388Skarels 		MCLGET(mm, M_WAIT);
57*43388Skarels 		if ((mm->m_flags & M_EXT) == 0)
5838624Skarels 			goto nopages;
59*43388Skarels 		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 		u.u_error = EINTR;
7238624Skarels 		return EINTR ;
7338624Skarels 	}
7438624Skarels 
7538624Skarels 	while (uio->uio_resid && !err) {
7638624Skarels 		len = MIN(uio->uio_resid, blen) ;
7738624Skarels 		chanstat = dk_recv(chan, mtod(mm, caddr_t), len, tp->d_rmode, dkrdone, (caddr_t) tp) ;
7838624Skarels 		if (chanstat == 0) {
7938624Skarels 			if ((dk_status(chan) & DK_RESET) == 0)
8038624Skarels 				err = EIO ;
8138624Skarels 			break;
8238624Skarels 		}
8338624Skarels 		if ((tp->dc_state & DK_NDELAY) && (dk_status(chan) & DK_RCV)) {
8438624Skarels 			err = EWOULDBLOCK;
8538624Skarels 			break;
8638624Skarels 		}
8738624Skarels 
8838624Skarels 		s = spl5() ;
8938624Skarels 		while (dk_status(chan) & DK_RCV)
9038624Skarels 			sleep((caddr_t)(tp), TTOPRI) ;
9138624Skarels 		splx(s) ;
9238624Skarels 
9338624Skarels 		len -= tp->d_rresid ;
9438624Skarels 		if (len)
9538624Skarels 			err = uiomove(mtod(mm, caddr_t), len, UIO_READ, uio);
9638624Skarels 		if (tp->d_rdone != DKR_FULL)
9738624Skarels 			break ;
9838624Skarels 	}
9938624Skarels 	m_freem(mm) ;
10038624Skarels 	return err;
10138624Skarels }
10238624Skarels 
10338624Skarels 
10438624Skarels /*ARGSUSED*/
10538624Skarels dkrdone(tp, chan, resid, rdone, rctl)
10638624Skarels register struct dkdev *tp ;
10738624Skarels {
10838624Skarels 	tp->d_rresid = resid ;
10938624Skarels 	tp->d_rdone = rdone ;
11038624Skarels 	tp->d_rctl = rctl ;
11138624Skarels 	wakeup((caddr_t) tp) ;
11238624Skarels }
11338624Skarels 
11438624Skarels 
11538624Skarels 
11638624Skarels 
11738624Skarels dkuwrite(chan, uio) register struct uio *uio;
11838624Skarels {
11938624Skarels extern wakeup() ;
12038624Skarels extern dkwdone() ;
12138624Skarels register struct dkdev *tp ;
12238624Skarels register len ;
12338624Skarels register struct mbuf *m;
12438624Skarels register struct iovec *iov;
12538624Skarels int s, error, eob;
12638624Skarels short xc;
12738624Skarels 
12838624Skarels 	tp = &dkdev[chan] ;
12938624Skarels 	do {
13038624Skarels 		s = spl5() ;
13138624Skarels 		while (tp->d_bufct > DKBUFUSE) {
13238624Skarels 			if (tp->dc_state & DK_NDELAY) {
13338624Skarels 				splx(s);
13438624Skarels 				return EWOULDBLOCK;
13538624Skarels 			}
13638624Skarels 			tp->d_state |= DKWAIT ;
13738624Skarels 			sleep((caddr_t)(&tp->d_state), TTOPRI) ;
13838624Skarels 		}
13938624Skarels 		splx(s) ;
14038624Skarels 
14138624Skarels 		iov = uio->uio_iov;
14238624Skarels 		if (iov->iov_len) {
14338624Skarels 			MGET(m, M_WAIT, DKMT_DATA);
14438624Skarels 			if (m == NULL)
14538624Skarels 				return ENOBUFS;
14638624Skarels 			if (iov->iov_len >= MLEN) {
147*43388Skarels 				MCLGET(m, M_WAIT);
148*43388Skarels 				if ((m->m_flags & M_EXT) == 0)
14938624Skarels 					goto nopages;
150*43388Skarels 				len = MIN(MCLBYTES, iov->iov_len);
15138624Skarels 			} else {
15238624Skarels nopages:
15338624Skarels 				len = MIN(MLEN, iov->iov_len);
15438624Skarels 			}
15538624Skarels 			error = uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
15638624Skarels 			if (error) {
15738624Skarels 				(void) m_free(m);
15838624Skarels 				return error;
15938624Skarels 			}
16038624Skarels 			m->m_len = len;
16138624Skarels 		}
16238624Skarels 		else m = NULL;
16338624Skarels 
16438624Skarels 		s = spl5();
16538624Skarels 		tp->d_bufct++;
16638624Skarels 		eob = (uio->uio_resid == 0);
16738624Skarels 		if (eob) {
16838624Skarels 			xc = tp->d_xctl;
16938624Skarels 			tp->d_xctl = 0;
17038624Skarels 		}
17138624Skarels 		else xc = 0;
17238624Skarels 		if (dk_xmit(chan, m, eob, xc, dkwdone, (caddr_t) 0) == 0) {
17338624Skarels 			tp->d_bufct-- ;
17438624Skarels 			return EIO ;
17538624Skarels 		}
17638624Skarels 		splx(s);
17738624Skarels 	} while (uio->uio_resid);
17838624Skarels 	return 0;
17938624Skarels }
18038624Skarels 
18138624Skarels /*ARGSUSED*/
18238624Skarels dkwdone(x, chan)
18338624Skarels {
18438624Skarels 	register struct dkdev *tp ;
18538624Skarels 
18638624Skarels 	tp = &dkdev[chan] ;
18738624Skarels 	if (chan > dksubdebug)
18838624Skarels 		log(LOG_ERR, "dkwdone %d: state=0%o bufct=%d\n", chan, tp->d_state,
18938624Skarels 		    tp->d_bufct);
19038624Skarels 	if (tp->d_bufct)
19138624Skarels 		tp->d_bufct-- ;
19238624Skarels 	if (tp->d_state & DKWAIT) {
19338624Skarels 		tp->d_state &= ~DKWAIT ;
19438624Skarels 		wakeup((caddr_t) &tp->d_state) ;
19538624Skarels 	}
19638624Skarels }
19738624Skarels 
19838624Skarels /* wakeup and reinitialize channel upon receipt of reconnection message */
19938624Skarels dkrsplice(chan)
20038624Skarels {
20138624Skarels 	register struct dkdev *tp ;
20238624Skarels 
20338624Skarels 	tp = &dkdev[chan] ;
20438624Skarels 	tp->d_state |= DKSPLICED ;
20538624Skarels 	wakeup((caddr_t) tp) ;
20638624Skarels 	dk_cmd(chan, DKC_XINIT) ;
20738624Skarels }
20838624Skarels 
20938624Skarels /* wait for reconnection message indicating that splice completed */
21038624Skarels dksplwait(chan)
21138624Skarels {
21238624Skarels 	register struct dkdev *tp ;
21338624Skarels 
21438624Skarels 	tp = &dkdev[chan] ;
21538624Skarels 	while ((tp->d_state & DKSPLICED) == 0)
21638624Skarels 		sleep((caddr_t) tp, TTOPRI) ;
21738624Skarels }
21838624Skarels 
21938624Skarels /* convert file desciptor to Datakit channel */
22038624Skarels dkgetdev(fildes)
22138624Skarels {
22238624Skarels 	extern struct file *getinode();
22338624Skarels 	register struct file *fp;
22438624Skarels 	register struct inode *ip ;
22538624Skarels 
22638624Skarels 	fp = getinode(fildes) ;
22738624Skarels 	ip = (struct inode *)fp->f_data;
22838624Skarels 	if ((ip->i_mode & IFMT) != IFCHR ) {
22938624Skarels 		u.u_error = ENOTTY ;
23038624Skarels 		return(-1) ;
23138624Skarels 	}
23238624Skarels 	if (dkdevtype((dev_t) ip->i_rdev))
23338624Skarels 		return(minor(ip->i_rdev)) ;
23438624Skarels 	u.u_error = EINVAL ;
23538624Skarels 	return(-1) ;
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