xref: /csrg-svn/sys/vax/datakit/dksub.c (revision 38624)
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