xref: /csrg-svn/sys/vax/datakit/kmc.c (revision 38624)
1*38624Skarels /*
2*38624Skarels  * kmc.c from 5.0 (on ihwld) hacked for 4.2
3*38624Skarels  * Bob Van Valzah  2/7/84
4*38624Skarels  */
5*38624Skarels 
6*38624Skarels /* @(#)kmc.c	1.3 */
7*38624Skarels /*
8*38624Skarels  * KMC11 microprocessor driver
9*38624Skarels  */
10*38624Skarels 
11*38624Skarels #include "kmc.h"
12*38624Skarels #if NKMC > 0
13*38624Skarels 
14*38624Skarels #include "syslog.h"
15*38624Skarels #include "param.h"
16*38624Skarels #include "ioctl.h"
17*38624Skarels #include "tty.h"
18*38624Skarels #include "kmcreg.h"
19*38624Skarels #include "buf.h"
20*38624Skarels #include "dir.h"
21*38624Skarels #include "user.h"
22*38624Skarels #include "../vaxuba/ubavar.h"
23*38624Skarels #include "uio.h"
24*38624Skarels 
25*38624Skarels #ifdef	DATAKIT
26*38624Skarels #include "dkitkmc.h"
27*38624Skarels #endif
28*38624Skarels #ifdef	RJE
29*38624Skarels #include "vpm.h"
30*38624Skarels #endif
31*38624Skarels 
32*38624Skarels #define ushort u_short
33*38624Skarels 
34*38624Skarels int	kmc_cnt = NKMC;
35*38624Skarels 
36*38624Skarels struct kmc {
37*38624Skarels 	struct clist k_inq;
38*38624Skarels 	short	k_stat;
39*38624Skarels 	char	k_type;
40*38624Skarels 	short	k_arg[3];
41*38624Skarels 	int	(*k_rint)();
42*38624Skarels 	int	(*k_init)();
43*38624Skarels 	int	(*k_reset)();
44*38624Skarels } kmc[NKMC];
45*38624Skarels 
46*38624Skarels #define	KMC11A	1
47*38624Skarels #define	KMC11B	2
48*38624Skarels #define	KASIZE	1024
49*38624Skarels #define	KBSIZE	4096
50*38624Skarels 
51*38624Skarels #define	RUN	(1<<7)
52*38624Skarels #define	MCLR	(1<<6)
53*38624Skarels #define	CWRT	(1<<5)
54*38624Skarels #define	LUB	(1<<4)
55*38624Skarels #define	LUA	(1<<3)
56*38624Skarels #define	ROMO	(1<<2)
57*38624Skarels #define	ROMI	(1<<1)
58*38624Skarels #define	STEP	(1<<0)
59*38624Skarels 
60*38624Skarels #define RDYO	0200
61*38624Skarels #define RDYI	020
62*38624Skarels #define RQI	0200
63*38624Skarels #define IEI	01
64*38624Skarels #define IEO	020
65*38624Skarels 
66*38624Skarels #define	STYPE	017
67*38624Skarels #define SRUN	020
68*38624Skarels #define SRINT	040
69*38624Skarels #define	SOPEN	0100
70*38624Skarels #define	SLOAD	0200
71*38624Skarels #define	SINIT	0400
72*38624Skarels #define	SRESET	01000
73*38624Skarels 
74*38624Skarels 
75*38624Skarels struct kmcdevice {
76*38624Skarels union {
77*38624Skarels 	char	b[8];
78*38624Skarels 	unsigned short	w[4];
79*38624Skarels } un;
80*38624Skarels };
81*38624Skarels 
82*38624Skarels #define	bsel0	un.b[0]
83*38624Skarels #define	bsel1	un.b[1]
84*38624Skarels #define	bsel2	un.b[2]
85*38624Skarels #define	bsel3	un.b[3]
86*38624Skarels #define	bsel4	un.b[4]
87*38624Skarels #define	bsel5	un.b[5]
88*38624Skarels #define	bsel6	un.b[6]
89*38624Skarels #define	bsel7	un.b[7]
90*38624Skarels #define	sel0	un.w[0]
91*38624Skarels #define	sel2	un.w[1]
92*38624Skarels #define	sel4	un.w[2]
93*38624Skarels #define	sel6	un.w[3]
94*38624Skarels 
95*38624Skarels int rkmcdebug = 0;
96*38624Skarels 
97*38624Skarels int	kmcprobe(), kmcattach(), kmcxint();
98*38624Skarels struct	uba_device *kmcdinfo[NKMC];
99*38624Skarels 
100*38624Skarels u_short kmcstd[] = { 0 };
101*38624Skarels struct uba_driver kmcdriver =
102*38624Skarels 	{ kmcprobe, 0, kmcattach, 0, kmcstd, "kmc", kmcdinfo };
103*38624Skarels 
104*38624Skarels kmcprobe(reg)
105*38624Skarels caddr_t reg;
106*38624Skarels {	register int br, cvec;	/* don't touch */
107*38624Skarels 	register struct kmcdevice *kp = (struct kmcdevice *)reg;
108*38624Skarels 	register s;
109*38624Skarels 
110*38624Skarels #ifdef lint
111*38624Skarels 	br = 0; cvec = br; br = cvec;
112*38624Skarels #endif
113*38624Skarels 	s = spl7();
114*38624Skarels 	kp->bsel1 = MCLR;
115*38624Skarels 	splx(s);
116*38624Skarels 	kp->bsel1 = ROMI;
117*38624Skarels 	kp->sel4 = 0200;		/* bus request */
118*38624Skarels 	kp->sel6 = 0121111;		/* mov csr4,obr */
119*38624Skarels 	kp->bsel1 = ROMI|STEP;
120*38624Skarels 	DELAY(50);
121*38624Skarels 	kp->bsel1 = 0;
122*38624Skarels 	return(1);
123*38624Skarels }
124*38624Skarels 
125*38624Skarels kmcattach(ui)
126*38624Skarels register struct uba_device *ui;
127*38624Skarels {
128*38624Skarels 	switch(ui->ui_flags & 03) {
129*38624Skarels #if NVPM>0
130*38624Skarels 		case 0:
131*38624Skarels 			vpminit(ui);
132*38624Skarels 			break;
133*38624Skarels #endif
134*38624Skarels #if NDKITKMC>0
135*38624Skarels 		case 1:
136*38624Skarels 			dkkmc_attach(ui);
137*38624Skarels 			break;
138*38624Skarels #endif
139*38624Skarels 		default:
140*38624Skarels 			log(LOG_ERR, "kmc%d: no protocol %d\n", ui->ui_unit,
141*38624Skarels 			    ui->ui_flags);
142*38624Skarels 			break;
143*38624Skarels 	}
144*38624Skarels }
145*38624Skarels 
146*38624Skarels /*ARGSUSED*/
147*38624Skarels kmcopen(dev, flag)
148*38624Skarels {
149*38624Skarels 	register struct kmcdevice *kp;
150*38624Skarels 	register struct kmc *tp;
151*38624Skarels 	register sav;
152*38624Skarels 
153*38624Skarels 	dev = minor(dev);
154*38624Skarels 	if (dev>=kmc_cnt || (tp = &kmc[dev])->k_stat&SOPEN) {
155*38624Skarels 		return (ENXIO);
156*38624Skarels 	}
157*38624Skarels 	tp->k_stat |= SOPEN;
158*38624Skarels 	if (tp->k_type==0) {
159*38624Skarels 		kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
160*38624Skarels 		kp->bsel1 = ROMO;
161*38624Skarels 		kp->sel4 = 0;
162*38624Skarels 		sav = kp->sel6;
163*38624Skarels 		kp->sel6 = ~sav;
164*38624Skarels 		if (kp->sel6 != sav) {
165*38624Skarels 			tp->k_type = KMC11B;
166*38624Skarels 			kp->sel6 = sav;
167*38624Skarels 		} else
168*38624Skarels 			tp->k_type = KMC11A;
169*38624Skarels 		kp->bsel1 = 0;
170*38624Skarels 	}
171*38624Skarels 	return (0);
172*38624Skarels }
173*38624Skarels 
174*38624Skarels kmcclose(dev)
175*38624Skarels {
176*38624Skarels 	dev = minor(dev);
177*38624Skarels 	kmc[dev].k_stat &= ~SOPEN;
178*38624Skarels }
179*38624Skarels 
180*38624Skarels kmcread(dev, uio)
181*38624Skarels 	dev_t dev;
182*38624Skarels 	struct uio *uio;
183*38624Skarels {
184*38624Skarels 	register struct kmcdevice *kp;
185*38624Skarels 	register ad;
186*38624Skarels 	register int error = 0;
187*38624Skarels 	int	dsize;
188*38624Skarels 	ushort	sav;
189*38624Skarels 
190*38624Skarels 	dev = minor(dev);
191*38624Skarels 	if (kmc[dev].k_stat&SRUN)
192*38624Skarels 		return (0);
193*38624Skarels 	dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
194*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
195*38624Skarels 	kp->bsel1 = 0;
196*38624Skarels 	do {
197*38624Skarels 		ad = uio->uio_offset;
198*38624Skarels 		if (ad<dsize*2) {
199*38624Skarels 			if (ad&1) {
200*38624Skarels 				return (ENXIO);
201*38624Skarels 			}
202*38624Skarels 			ad >>= 1;
203*38624Skarels 			kp->bsel1 = ROMO;
204*38624Skarels 			kp->sel4 = ad;
205*38624Skarels 			if ((error=ureadc(kp->bsel6, uio)) < 0)
206*38624Skarels 				break;
207*38624Skarels 			if ((error=ureadc(kp->bsel7, uio)) < 0)
208*38624Skarels 				break;
209*38624Skarels 			kp->bsel1 = 0;
210*38624Skarels 		} else if (ad -= dsize*2, ad<dsize) {
211*38624Skarels 			kp->bsel1 = ROMO;
212*38624Skarels 			kp->sel4 = 0;
213*38624Skarels 			sav = kp->sel6;
214*38624Skarels 			kp->bsel1 = ROMI;
215*38624Skarels 			kp->sel6 = 010000|(ad&0377);	/* mov ad,mar */
216*38624Skarels 			kp->bsel1 = ROMI|STEP;
217*38624Skarels 			kp->bsel1 = ROMI;
218*38624Skarels 			kp->sel6 = 04000|((ad>>8)&0377);	/* mov %ad,%mar */
219*38624Skarels 			kp->bsel1 = ROMI|STEP;
220*38624Skarels 			kp->bsel1 = ROMI;
221*38624Skarels 			kp->sel6 = 055222;	/* mov mem,csr2|mar++ */
222*38624Skarels 			kp->bsel1 = ROMI|STEP;
223*38624Skarels 			if ((error=ureadc(kp->bsel2, uio)) < 0)
224*38624Skarels 				break;
225*38624Skarels 			kp->bsel1 = ROMI;
226*38624Skarels 			kp->sel6 = sav;
227*38624Skarels 			kp->bsel1 = 0;
228*38624Skarels 		} else
229*38624Skarels 			break;
230*38624Skarels 	} while (!error && uio->uio_resid);
231*38624Skarels 	return (error);
232*38624Skarels }
233*38624Skarels 
234*38624Skarels kmcwrite(dev, uio)
235*38624Skarels 	dev_t dev;
236*38624Skarels 	struct uio *uio;
237*38624Skarels {
238*38624Skarels 	register struct kmcdevice *kp;
239*38624Skarels 	register ad;
240*38624Skarels 	int	dsize;
241*38624Skarels 	short	ins;
242*38624Skarels 	ushort	sav;
243*38624Skarels 
244*38624Skarels 	dev = minor(dev);
245*38624Skarels 	if (kmc[dev].k_stat&SRUN)
246*38624Skarels 		return (0);
247*38624Skarels 	dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
248*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
249*38624Skarels 	kp->bsel1 = 0;
250*38624Skarels 	while (uio->uio_resid) {
251*38624Skarels 		ad = uio->uio_offset;
252*38624Skarels 		if (ad<dsize*2) {
253*38624Skarels 			if (ad&1) {
254*38624Skarels 				return (ENXIO);
255*38624Skarels 			}
256*38624Skarels 			kp->bsel1 = ROMO;
257*38624Skarels 			kp->sel4 = ad>>1;
258*38624Skarels 			lobyte(ins) = uwritec(uio);
259*38624Skarels 			hibyte(ins) = uwritec(uio);
260*38624Skarels 			kp->sel6 = ins;
261*38624Skarels 			kp->bsel1 |= CWRT;
262*38624Skarels 			kp->bsel1 = 0;
263*38624Skarels 		} else if (ad -= dsize*2, ad<dsize) {
264*38624Skarels 			kp->bsel1 = ROMO;
265*38624Skarels 			kp->sel4 = 0;
266*38624Skarels 			sav = kp->sel6;
267*38624Skarels 			kp->bsel1 = ROMI;
268*38624Skarels 			kp->sel6 = 010000|(ad&0377);	/* mov ad,mar */
269*38624Skarels 			kp->bsel1 = ROMI|STEP;
270*38624Skarels 			kp->bsel1 = ROMI;
271*38624Skarels 			kp->sel6 = 04000|((ad>>8)&0377);	/* mov %ad,%mar */
272*38624Skarels 			kp->bsel1 = ROMI|STEP;
273*38624Skarels 			kp->bsel1 = ROMI;
274*38624Skarels 			kp->bsel2 = uwritec(uio);
275*38624Skarels 			kp->sel6 = 0136440;	/* mov csr2,mem|mar++ */
276*38624Skarels 			kp->bsel1 = ROMI|STEP;
277*38624Skarels 			kp->bsel1 = ROMI;
278*38624Skarels 			kp->sel6 = sav;
279*38624Skarels 			kp->bsel1 = 0;
280*38624Skarels 		} else
281*38624Skarels 			break;
282*38624Skarels 	}
283*38624Skarels 	return (0);
284*38624Skarels }
285*38624Skarels 
286*38624Skarels /*ARGSUSED*/
287*38624Skarels kmcioctl(dev, cmd, kk, mode)
288*38624Skarels 	dev_t dev;
289*38624Skarels 	struct kmcntl *kk;
290*38624Skarels {
291*38624Skarels 	register struct kmcdevice *kp;
292*38624Skarels 	register struct kmc *tp;
293*38624Skarels 	short	csr[4];
294*38624Skarels 	ushort	sav;
295*38624Skarels 
296*38624Skarels 	if (rkmcdebug) log(LOG_ERR, "kmcioctl: cmd=%d, kk->kmd=%d, kk->kcsr=0x%x, kk->kval=%d\n",
297*38624Skarels 		cmd, kk->kmd, kk->kcsr, kk->kval);
298*38624Skarels 	dev = minor(dev);
299*38624Skarels 	if (cmd != KCSETA) {
300*38624Skarels 		return (EINVAL);
301*38624Skarels 	}
302*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
303*38624Skarels 	tp = &kmc[dev];
304*38624Skarels 	switch (kk->kmd) {
305*38624Skarels 	case KMCLR:
306*38624Skarels 	case KRESET:
307*38624Skarels 		spl7();
308*38624Skarels 		kp->bsel1 = MCLR;
309*38624Skarels 		spl0();
310*38624Skarels 	case KSTOP:
311*38624Skarels 		tp->k_stat &= ~SRUN;
312*38624Skarels 		kp->bsel1 = 0;
313*38624Skarels 		if (kk->kmd == KRESET) {
314*38624Skarels 			tp->k_stat = 0;
315*38624Skarels 			while(getc(&tp->k_inq) >= 0) ;
316*38624Skarels 			if (tp->k_stat&SINIT)
317*38624Skarels 				(*tp->k_init)(dev);
318*38624Skarels 		}
319*38624Skarels 		return (0);
320*38624Skarels 	case KMS:
321*38624Skarels 		if (tp->k_stat&SRUN)
322*38624Skarels 			break;
323*38624Skarels 		kp->bsel1 = ROMI|ROMO;
324*38624Skarels 		sav = kp->sel6;
325*38624Skarels 		kp->bsel1 = ROMI;
326*38624Skarels 		kp->sel6 = kk->kval;
327*38624Skarels 		kp->bsel1 = ROMI|STEP;
328*38624Skarels 		kp->bsel1 = ROMI;
329*38624Skarels 		kp->sel6 = sav;
330*38624Skarels 		kp->bsel1 = 0;
331*38624Skarels 		goto lcsr;
332*38624Skarels 	case KSTEP:
333*38624Skarels 		if (tp->k_stat&SRUN)
334*38624Skarels 			break;
335*38624Skarels 		kp->bsel1 |= STEP;
336*38624Skarels 		kp->bsel1 = 0;
337*38624Skarels 	case KCSR:
338*38624Skarels 	lcsr:
339*38624Skarels 		csr[0] = kp->sel0;
340*38624Skarels 		csr[1] = kp->sel2;
341*38624Skarels 		csr[2] = kp->sel4;
342*38624Skarels 		csr[3] = kp->sel6;
343*38624Skarels 		if (copyout((caddr_t)csr, (caddr_t)kk->kcsr, sizeof csr))
344*38624Skarels 			return (EFAULT);
345*38624Skarels 		return (0);
346*38624Skarels 	case KWRCR:
347*38624Skarels 		if (tp->k_stat&SRINT)
348*38624Skarels 			break;
349*38624Skarels 		kp->sel6 = kk->kval;
350*38624Skarels 		return (0);
351*38624Skarels 	case KRUN:
352*38624Skarels 		if (tp->k_stat&SRUN)
353*38624Skarels 			break;
354*38624Skarels 		tp->k_stat &= ~STYPE;
355*38624Skarels 		tp->k_stat |= (kk->kval&STYPE)|SRUN;
356*38624Skarels 		kp->bsel1 |= RUN;
357*38624Skarels 		if (tp->k_stat&SRINT) {
358*38624Skarels 			spl5();
359*38624Skarels 			kmcrint(dev);
360*38624Skarels 			spl0();
361*38624Skarels 		}
362*38624Skarels 		if (tp->k_stat&SRESET)
363*38624Skarels 			(*tp->k_reset)(dev);
364*38624Skarels 		return (0);
365*38624Skarels 	case KLU:
366*38624Skarels 		kp->bsel1 = kk->kval&(LUA|LUB);
367*38624Skarels 		return (0);
368*38624Skarels 	}
369*38624Skarels 	if (rkmcdebug) log(LOG_ERR, "kmcioctl: EIO exit, tp->k_stat=0x%x\n", tp->k_stat);
370*38624Skarels 	return (EIO);
371*38624Skarels }
372*38624Skarels 
373*38624Skarels kmcrint(dev)
374*38624Skarels {
375*38624Skarels 	register struct kmcdevice *kp;
376*38624Skarels 	register struct kmc *tp;
377*38624Skarels 
378*38624Skarels 	dev = minor(dev);
379*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
380*38624Skarels 	tp = &kmc[dev];
381*38624Skarels 	kp->sel0 &= ~IEI;
382*38624Skarels 	while (kp->sel2&RDYI) {
383*38624Skarels 		if ((tp->k_stat&SLOAD) ||
384*38624Skarels 		  q_to_b(&tp->k_inq, (char *)tp->k_arg, sizeof(tp->k_arg)) == sizeof(tp->k_arg)) {
385*38624Skarels 			kp->sel2 = tp->k_arg[0]|RDYI;
386*38624Skarels 			kp->sel4 = tp->k_arg[1];
387*38624Skarels 			kp->sel6 = tp->k_arg[2];
388*38624Skarels 			tp->k_stat &= ~SLOAD;
389*38624Skarels 		} else {
390*38624Skarels 			log(LOG_ERR, "Bad kmc %d load\n", dev);
391*38624Skarels 		}
392*38624Skarels 		if (tp->k_inq.c_cc==0) {
393*38624Skarels 			kp->sel0 &= ~RQI;
394*38624Skarels 			kp->sel2 &= ~RDYI;
395*38624Skarels 			return;
396*38624Skarels 		}
397*38624Skarels 		kp->sel2 &= ~RDYI;
398*38624Skarels 	}
399*38624Skarels 	if ((tp->k_stat&SLOAD) || tp->k_inq.c_cc)
400*38624Skarels 		kp->sel0 |= IEI|RQI;
401*38624Skarels }
402*38624Skarels 
403*38624Skarels kmcxint(dev)
404*38624Skarels {
405*38624Skarels 	register struct kmcdevice *kp;
406*38624Skarels 	register struct kmc *tp;
407*38624Skarels 	int p1, p2, p3, p4;
408*38624Skarels 
409*38624Skarels 	dev = minor(dev);
410*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
411*38624Skarels 	tp = &kmc[dev];
412*38624Skarels 	kp->sel0 &= ~IEO;
413*38624Skarels 	while(kp->sel2&RDYO) {
414*38624Skarels 		p1 = (dev<<6)|(kp->bsel3&077);
415*38624Skarels 		p2 = kp->bsel2&017;
416*38624Skarels 		p3 = kp->sel4;
417*38624Skarels 		p4 = kp->sel6;
418*38624Skarels 		kp->sel2 &= ~RDYO;
419*38624Skarels 		if (tp->k_stat&SRINT)
420*38624Skarels 			(*tp->k_rint)(p1, p2, p3, p4);
421*38624Skarels 	}
422*38624Skarels 	kp->sel0 |= IEO;
423*38624Skarels }
424*38624Skarels 
425*38624Skarels kmcload(dev, p1, p2, p3)
426*38624Skarels {
427*38624Skarels 	register struct kmcdevice *kp;
428*38624Skarels 	register struct kmc *tp;
429*38624Skarels 	register unit;
430*38624Skarels 	register sps;
431*38624Skarels 
432*38624Skarels 	dev = minor(dev);
433*38624Skarels 	unit = (dev>>6)&03;
434*38624Skarels 	tp = &kmc[unit];
435*38624Skarels 	if (!(tp->k_stat&SRUN))
436*38624Skarels 		return(-1);
437*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[unit]->ui_addr);	/* RAV unit is suspect */
438*38624Skarels 	sps = spl5();
439*38624Skarels 	if (tp->k_stat&SLOAD) {
440*38624Skarels 		b_to_q((char *)tp->k_arg, sizeof(tp->k_arg), &tp->k_inq);
441*38624Skarels 		tp->k_stat &= ~SLOAD;
442*38624Skarels 	}
443*38624Skarels 	kp->sel0 |= RQI;
444*38624Skarels 	tp->k_arg[0] = (p1&017)|((dev&077)<<8);
445*38624Skarels 	tp->k_arg[1] = p2;
446*38624Skarels 	tp->k_arg[2] = p3;
447*38624Skarels 	if (tp->k_inq.c_cc)
448*38624Skarels 		b_to_q((char *)tp->k_arg, sizeof(tp->k_arg), &tp->k_inq);
449*38624Skarels 	else
450*38624Skarels 		tp->k_stat |= SLOAD;
451*38624Skarels 	kmcrint(unit);
452*38624Skarels 	splx(sps);
453*38624Skarels 	return(tp->k_inq.c_cc);
454*38624Skarels }
455*38624Skarels 
456*38624Skarels kmcset(dev, type, rint)
457*38624Skarels int (*rint)();
458*38624Skarels {
459*38624Skarels 	register struct kmcdevice *kp;
460*38624Skarels 	register struct kmc *tp;
461*38624Skarels 	register unit;
462*38624Skarels 
463*38624Skarels 	dev = minor(dev);
464*38624Skarels 	unit = (dev>>6)&03;
465*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[unit]->ui_addr);	/* RAV unit is suspect */
466*38624Skarels 	tp = &kmc[unit];
467*38624Skarels 	if ((tp->k_stat&(STYPE|SRUN|SOPEN))!=((type&STYPE)|SRUN))
468*38624Skarels 		return (1);
469*38624Skarels 	tp->k_stat |= SRINT;
470*38624Skarels 	tp->k_rint = rint;
471*38624Skarels 	kp->sel0 |= IEO;
472*38624Skarels 	return(0);
473*38624Skarels }
474*38624Skarels 
475*38624Skarels kmcdclr(dev)
476*38624Skarels register dev;
477*38624Skarels {
478*38624Skarels 	register struct kmc *tp;
479*38624Skarels 	register struct kmcdevice *kp;
480*38624Skarels 
481*38624Skarels 	dev = minor(dev);
482*38624Skarels 	if (dev < 0 || dev >= kmc_cnt)
483*38624Skarels 		return;
484*38624Skarels 	tp = &kmc[dev];
485*38624Skarels 	while (getc(&tp->k_inq) >= 0) ;
486*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
487*38624Skarels 	kp->sel0 = 0;
488*38624Skarels 	kp->sel2 = 0;
489*38624Skarels }
490*38624Skarels 
491*38624Skarels kmcreset(dev)
492*38624Skarels {
493*38624Skarels 	register struct kmc *tp;
494*38624Skarels 	register struct kmcdevice *kp;
495*38624Skarels 	register s;
496*38624Skarels 
497*38624Skarels 	dev = minor(dev);
498*38624Skarels 	tp = &kmc[dev];
499*38624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
500*38624Skarels 	s = spl7();
501*38624Skarels 	kp->bsel1 = MCLR;
502*38624Skarels 	splx(s);
503*38624Skarels 	kp->bsel1 = 0;
504*38624Skarels 	tp->k_stat = 0;
505*38624Skarels 	while(getc(&tp->k_inq)>=0);
506*38624Skarels }
507*38624Skarels 
508*38624Skarels kmcifset(dev, init)
509*38624Skarels int (*init)();
510*38624Skarels {
511*38624Skarels 	register struct kmc *tp;
512*38624Skarels 	register unit;
513*38624Skarels 
514*38624Skarels 	dev = minor(dev);
515*38624Skarels 	unit = (dev>>6)&03;
516*38624Skarels 	if (unit < 0 || unit >= kmc_cnt)
517*38624Skarels 		return;
518*38624Skarels 	tp = &kmc[unit];
519*38624Skarels 	if (init==NULL) {
520*38624Skarels 		tp->k_init = NULL;
521*38624Skarels 		tp->k_stat &= ~SINIT;
522*38624Skarels 	} else {
523*38624Skarels 		tp->k_init = init;
524*38624Skarels 		tp->k_stat |= SINIT;
525*38624Skarels 	}
526*38624Skarels }
527*38624Skarels 
528*38624Skarels kmcrfset(dev, reset)
529*38624Skarels int (*reset)();
530*38624Skarels {
531*38624Skarels 	register struct kmc *tp;
532*38624Skarels 	register unit;
533*38624Skarels 
534*38624Skarels 	dev = minor(dev);
535*38624Skarels 	unit = (dev>>6)&03;
536*38624Skarels 	if (unit < 0 || unit >= kmc_cnt)
537*38624Skarels 		return;
538*38624Skarels 	tp = &kmc[unit];
539*38624Skarels 	if (reset==NULL) {
540*38624Skarels 		tp->k_reset = NULL;
541*38624Skarels 		tp->k_stat &= ~SRESET;
542*38624Skarels 	} else {
543*38624Skarels 		tp->k_reset = reset;
544*38624Skarels 		tp->k_stat |= SRESET;
545*38624Skarels 	}
546*38624Skarels }
547*38624Skarels #endif
548