138624Skarels /* 238624Skarels * Datakit driver 338624Skarels * Common subroutines for all drivers 438624Skarels * SCCSID[] = "@(#)dksub.c 1.2 Garage 84/03/27" 5*45199Smckusick * "@(#)dksub.c 1.6 (Berkeley) 09/04/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 "systm.h" 2338624Skarels #include "proc.h" 2438624Skarels #include "mbuf.h" 2538624Skarels #include "buf.h" 2638624Skarels #include "uio.h" 27*45199Smckusick #include "vnode.h" 28*45199Smckusick #include "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 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*/ 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 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*/ 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 */ 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 */ 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 */ 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; 237*45199Smckusick if (dkdevtype(vp->v_rdev)) { 238*45199Smckusick *devnop = minor(vp->v_rdev); 23943390Smckusick return 0; 24038624Skarels } 24143390Smckusick return EINVAL; 24238624Skarels } 24338624Skarels 24438624Skarels /* validate device number as belonging to Datakit */ 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