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