1*38624Skarels 2*38624Skarels /* 3*38624Skarels * Datakit driver 4*38624Skarels * Common subroutines for all drivers 5*38624Skarels * SCCSID[] = "@(#)dksub.c 1.2 Garage 84/03/27" 6*38624Skarels */ 7*38624Skarels 8*38624Skarels #include "datakit.h" 9*38624Skarels #if NDATAKIT>0 10*38624Skarels 11*38624Skarels #include "param.h" 12*38624Skarels #include "../machine/pte.h" 13*38624Skarels #include "signal.h" 14*38624Skarels #include "errno.h" 15*38624Skarels #include "seg.h" 16*38624Skarels #include "dir.h" 17*38624Skarels #include "user.h" 18*38624Skarels #include "ioctl.h" 19*38624Skarels #include "tty.h" 20*38624Skarels #include "syslog.h" 21*38624Skarels #include "conf.h" 22*38624Skarels #include "file.h" 23*38624Skarels #include "inode.h" 24*38624Skarels #include "systm.h" 25*38624Skarels #include "proc.h" 26*38624Skarels #include "mbuf.h" 27*38624Skarels #include "buf.h" 28*38624Skarels #include "uio.h" 29*38624Skarels #include "dkit.h" 30*38624Skarels #include "dk.h" 31*38624Skarels #include "dkdev.h" 32*38624Skarels 33*38624Skarels #define DKBUFUSE 5 /* max buffers /channel */ 34*38624Skarels 35*38624Skarels 36*38624Skarels extern struct dkdev dkdev[] ; 37*38624Skarels 38*38624Skarels int dksubdebug = 512; 39*38624Skarels 40*38624Skarels 41*38624Skarels dkuread(chan, uio) 42*38624Skarels register struct uio *uio; 43*38624Skarels { 44*38624Skarels register int len, blen ; 45*38624Skarels register struct dkdev *tp ; 46*38624Skarels short chanstat ; 47*38624Skarels struct mbuf *mm ; 48*38624Skarels int err = 0, s; 49*38624Skarels extern wakeup() ; 50*38624Skarels extern dkrdone() ; 51*38624Skarels 52*38624Skarels tp = &dkdev[chan]; 53*38624Skarels MGET(mm, M_WAIT, DKMT_DATA); 54*38624Skarels if (mm == NULL) 55*38624Skarels return ENOBUFS; 56*38624Skarels if (uio->uio_resid >= MLEN) { 57*38624Skarels register struct mbuf *p; 58*38624Skarels MCLALLOC(p, 1); 59*38624Skarels if (p == 0) 60*38624Skarels goto nopages; 61*38624Skarels mm->m_off = (int)p - (int)mm; 62*38624Skarels blen = CLBYTES; 63*38624Skarels } else { 64*38624Skarels nopages: 65*38624Skarels blen = MIN(MLEN, uio->uio_resid); 66*38624Skarels } 67*38624Skarels 68*38624Skarels if (setjmp(&u.u_qsave)) { 69*38624Skarels s = spl5(); 70*38624Skarels if (dk_status(chan) & DK_RCV) 71*38624Skarels (void) dk_rabort(chan, dkrdone, (caddr_t) tp) ; 72*38624Skarels splx(s); 73*38624Skarels m_freem(mm); 74*38624Skarels u.u_error = EINTR; 75*38624Skarels return EINTR ; 76*38624Skarels } 77*38624Skarels 78*38624Skarels while (uio->uio_resid && !err) { 79*38624Skarels len = MIN(uio->uio_resid, blen) ; 80*38624Skarels chanstat = dk_recv(chan, mtod(mm, caddr_t), len, tp->d_rmode, dkrdone, (caddr_t) tp) ; 81*38624Skarels if (chanstat == 0) { 82*38624Skarels if ((dk_status(chan) & DK_RESET) == 0) 83*38624Skarels err = EIO ; 84*38624Skarels break; 85*38624Skarels } 86*38624Skarels if ((tp->dc_state & DK_NDELAY) && (dk_status(chan) & DK_RCV)) { 87*38624Skarels err = EWOULDBLOCK; 88*38624Skarels break; 89*38624Skarels } 90*38624Skarels 91*38624Skarels s = spl5() ; 92*38624Skarels while (dk_status(chan) & DK_RCV) 93*38624Skarels sleep((caddr_t)(tp), TTOPRI) ; 94*38624Skarels splx(s) ; 95*38624Skarels 96*38624Skarels len -= tp->d_rresid ; 97*38624Skarels if (len) 98*38624Skarels err = uiomove(mtod(mm, caddr_t), len, UIO_READ, uio); 99*38624Skarels if (tp->d_rdone != DKR_FULL) 100*38624Skarels break ; 101*38624Skarels } 102*38624Skarels m_freem(mm) ; 103*38624Skarels return err; 104*38624Skarels } 105*38624Skarels 106*38624Skarels 107*38624Skarels /*ARGSUSED*/ 108*38624Skarels dkrdone(tp, chan, resid, rdone, rctl) 109*38624Skarels register struct dkdev *tp ; 110*38624Skarels { 111*38624Skarels tp->d_rresid = resid ; 112*38624Skarels tp->d_rdone = rdone ; 113*38624Skarels tp->d_rctl = rctl ; 114*38624Skarels wakeup((caddr_t) tp) ; 115*38624Skarels } 116*38624Skarels 117*38624Skarels 118*38624Skarels 119*38624Skarels 120*38624Skarels dkuwrite(chan, uio) register struct uio *uio; 121*38624Skarels { 122*38624Skarels extern wakeup() ; 123*38624Skarels extern dkwdone() ; 124*38624Skarels register struct dkdev *tp ; 125*38624Skarels register len ; 126*38624Skarels register struct mbuf *m; 127*38624Skarels register struct iovec *iov; 128*38624Skarels int s, error, eob; 129*38624Skarels short xc; 130*38624Skarels 131*38624Skarels tp = &dkdev[chan] ; 132*38624Skarels do { 133*38624Skarels s = spl5() ; 134*38624Skarels while (tp->d_bufct > DKBUFUSE) { 135*38624Skarels if (tp->dc_state & DK_NDELAY) { 136*38624Skarels splx(s); 137*38624Skarels return EWOULDBLOCK; 138*38624Skarels } 139*38624Skarels tp->d_state |= DKWAIT ; 140*38624Skarels sleep((caddr_t)(&tp->d_state), TTOPRI) ; 141*38624Skarels } 142*38624Skarels splx(s) ; 143*38624Skarels 144*38624Skarels iov = uio->uio_iov; 145*38624Skarels if (iov->iov_len) { 146*38624Skarels MGET(m, M_WAIT, DKMT_DATA); 147*38624Skarels if (m == NULL) 148*38624Skarels return ENOBUFS; 149*38624Skarels if (iov->iov_len >= MLEN) { 150*38624Skarels register struct mbuf *p; 151*38624Skarels MCLALLOC(p, 1); 152*38624Skarels if (p == 0) 153*38624Skarels goto nopages; 154*38624Skarels m->m_off = (int)p - (int)m; 155*38624Skarels len = MIN(CLBYTES, iov->iov_len); 156*38624Skarels } else { 157*38624Skarels nopages: 158*38624Skarels len = MIN(MLEN, iov->iov_len); 159*38624Skarels } 160*38624Skarels error = uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio); 161*38624Skarels if (error) { 162*38624Skarels (void) m_free(m); 163*38624Skarels return error; 164*38624Skarels } 165*38624Skarels m->m_len = len; 166*38624Skarels } 167*38624Skarels else m = NULL; 168*38624Skarels 169*38624Skarels s = spl5(); 170*38624Skarels tp->d_bufct++; 171*38624Skarels eob = (uio->uio_resid == 0); 172*38624Skarels if (eob) { 173*38624Skarels xc = tp->d_xctl; 174*38624Skarels tp->d_xctl = 0; 175*38624Skarels } 176*38624Skarels else xc = 0; 177*38624Skarels if (dk_xmit(chan, m, eob, xc, dkwdone, (caddr_t) 0) == 0) { 178*38624Skarels tp->d_bufct-- ; 179*38624Skarels return EIO ; 180*38624Skarels } 181*38624Skarels splx(s); 182*38624Skarels } while (uio->uio_resid); 183*38624Skarels return 0; 184*38624Skarels } 185*38624Skarels 186*38624Skarels /*ARGSUSED*/ 187*38624Skarels dkwdone(x, chan) 188*38624Skarels { 189*38624Skarels register struct dkdev *tp ; 190*38624Skarels 191*38624Skarels tp = &dkdev[chan] ; 192*38624Skarels if (chan > dksubdebug) 193*38624Skarels log(LOG_ERR, "dkwdone %d: state=0%o bufct=%d\n", chan, tp->d_state, 194*38624Skarels tp->d_bufct); 195*38624Skarels if (tp->d_bufct) 196*38624Skarels tp->d_bufct-- ; 197*38624Skarels if (tp->d_state & DKWAIT) { 198*38624Skarels tp->d_state &= ~DKWAIT ; 199*38624Skarels wakeup((caddr_t) &tp->d_state) ; 200*38624Skarels } 201*38624Skarels } 202*38624Skarels 203*38624Skarels /* wakeup and reinitialize channel upon receipt of reconnection message */ 204*38624Skarels dkrsplice(chan) 205*38624Skarels { 206*38624Skarels register struct dkdev *tp ; 207*38624Skarels 208*38624Skarels tp = &dkdev[chan] ; 209*38624Skarels tp->d_state |= DKSPLICED ; 210*38624Skarels wakeup((caddr_t) tp) ; 211*38624Skarels dk_cmd(chan, DKC_XINIT) ; 212*38624Skarels } 213*38624Skarels 214*38624Skarels /* wait for reconnection message indicating that splice completed */ 215*38624Skarels dksplwait(chan) 216*38624Skarels { 217*38624Skarels register struct dkdev *tp ; 218*38624Skarels 219*38624Skarels tp = &dkdev[chan] ; 220*38624Skarels while ((tp->d_state & DKSPLICED) == 0) 221*38624Skarels sleep((caddr_t) tp, TTOPRI) ; 222*38624Skarels } 223*38624Skarels 224*38624Skarels /* convert file desciptor to Datakit channel */ 225*38624Skarels dkgetdev(fildes) 226*38624Skarels { 227*38624Skarels extern struct file *getinode(); 228*38624Skarels register struct file *fp; 229*38624Skarels register struct inode *ip ; 230*38624Skarels 231*38624Skarels fp = getinode(fildes) ; 232*38624Skarels ip = (struct inode *)fp->f_data; 233*38624Skarels if ((ip->i_mode & IFMT) != IFCHR ) { 234*38624Skarels u.u_error = ENOTTY ; 235*38624Skarels return(-1) ; 236*38624Skarels } 237*38624Skarels if (dkdevtype((dev_t) ip->i_rdev)) 238*38624Skarels return(minor(ip->i_rdev)) ; 239*38624Skarels u.u_error = EINVAL ; 240*38624Skarels return(-1) ; 241*38624Skarels } 242*38624Skarels 243*38624Skarels /* validate device number as belonging to Datakit */ 244*38624Skarels dkdevtype(dev) dev_t dev; 245*38624Skarels { 246*38624Skarels extern dkopen(); 247*38624Skarels #if NDKTTY > 0 248*38624Skarels extern dktopen(); 249*38624Skarels #endif 250*38624Skarels #if NDKXQT > 0 251*38624Skarels extern dkxopen(); 252*38624Skarels #endif 253*38624Skarels #if NDKI > 0 254*38624Skarels extern dkiopen(); 255*38624Skarels #endif 256*38624Skarels register md = major(dev) ; 257*38624Skarels 258*38624Skarels if ((cdevsw[md].d_open == dkopen) 259*38624Skarels #if NDKTTY > 0 260*38624Skarels || (cdevsw[md].d_open == dktopen) 261*38624Skarels #endif 262*38624Skarels #if NDKI > 0 263*38624Skarels || (cdevsw[md].d_open == dkiopen && md > 0) 264*38624Skarels #endif 265*38624Skarels #if NDKXQT > 0 266*38624Skarels || (cdevsw[md].d_open == dkxopen) 267*38624Skarels #endif 268*38624Skarels ) 269*38624Skarels return(1); 270*38624Skarels else 271*38624Skarels return(0); 272*38624Skarels } 273*38624Skarels 274*38624Skarels #endif 275