xref: /csrg-svn/sys/vax/datakit/kmc.c (revision 45800)
138624Skarels /*
238624Skarels  * kmc.c from 5.0 (on ihwld) hacked for 4.2
338624Skarels  * Bob Van Valzah  2/7/84
438624Skarels  */
538624Skarels 
638624Skarels /* @(#)kmc.c	1.3 */
738624Skarels /*
838624Skarels  * KMC11 microprocessor driver
938624Skarels  */
1038624Skarels 
1138624Skarels #include "kmc.h"
1238624Skarels #if NKMC > 0
1338624Skarels 
14*45800Sbostic #include "sys/param.h"
15*45800Sbostic #include "sys/ioctl.h"
16*45800Sbostic #include "sys/tty.h"
17*45800Sbostic #include "sys/kmcreg.h"
18*45800Sbostic #include "sys/buf.h"
19*45800Sbostic #include "sys/user.h"
20*45800Sbostic #include "sys/syslog.h"
21*45800Sbostic #include "../uba/ubavar.h"
22*45800Sbostic #include "sys/uio.h"
2338624Skarels 
2438624Skarels #ifdef	DATAKIT
2538624Skarels #include "dkitkmc.h"
2638624Skarels #endif
2738624Skarels #ifdef	RJE
2838624Skarels #include "vpm.h"
2938624Skarels #endif
3038624Skarels 
3138624Skarels #define ushort u_short
3238624Skarels 
3338624Skarels int	kmc_cnt = NKMC;
3438624Skarels 
3538624Skarels struct kmc {
3638624Skarels 	struct clist k_inq;
3738624Skarels 	short	k_stat;
3838624Skarels 	char	k_type;
3938624Skarels 	short	k_arg[3];
4038624Skarels 	int	(*k_rint)();
4138624Skarels 	int	(*k_init)();
4238624Skarels 	int	(*k_reset)();
4338624Skarels } kmc[NKMC];
4438624Skarels 
4538624Skarels #define	KMC11A	1
4638624Skarels #define	KMC11B	2
4738624Skarels #define	KASIZE	1024
4838624Skarels #define	KBSIZE	4096
4938624Skarels 
5038624Skarels #define	RUN	(1<<7)
5138624Skarels #define	MCLR	(1<<6)
5238624Skarels #define	CWRT	(1<<5)
5338624Skarels #define	LUB	(1<<4)
5438624Skarels #define	LUA	(1<<3)
5538624Skarels #define	ROMO	(1<<2)
5638624Skarels #define	ROMI	(1<<1)
5738624Skarels #define	STEP	(1<<0)
5838624Skarels 
5938624Skarels #define RDYO	0200
6038624Skarels #define RDYI	020
6138624Skarels #define RQI	0200
6238624Skarels #define IEI	01
6338624Skarels #define IEO	020
6438624Skarels 
6538624Skarels #define	STYPE	017
6638624Skarels #define SRUN	020
6738624Skarels #define SRINT	040
6838624Skarels #define	SOPEN	0100
6938624Skarels #define	SLOAD	0200
7038624Skarels #define	SINIT	0400
7138624Skarels #define	SRESET	01000
7238624Skarels 
7338624Skarels 
7438624Skarels struct kmcdevice {
7538624Skarels union {
7638624Skarels 	char	b[8];
7738624Skarels 	unsigned short	w[4];
7838624Skarels } un;
7938624Skarels };
8038624Skarels 
8138624Skarels #define	bsel0	un.b[0]
8238624Skarels #define	bsel1	un.b[1]
8338624Skarels #define	bsel2	un.b[2]
8438624Skarels #define	bsel3	un.b[3]
8538624Skarels #define	bsel4	un.b[4]
8638624Skarels #define	bsel5	un.b[5]
8738624Skarels #define	bsel6	un.b[6]
8838624Skarels #define	bsel7	un.b[7]
8938624Skarels #define	sel0	un.w[0]
9038624Skarels #define	sel2	un.w[1]
9138624Skarels #define	sel4	un.w[2]
9238624Skarels #define	sel6	un.w[3]
9338624Skarels 
9438624Skarels int rkmcdebug = 0;
9538624Skarels 
9638624Skarels int	kmcprobe(), kmcattach(), kmcxint();
9738624Skarels struct	uba_device *kmcdinfo[NKMC];
9838624Skarels 
9938624Skarels u_short kmcstd[] = { 0 };
10038624Skarels struct uba_driver kmcdriver =
10138624Skarels 	{ kmcprobe, 0, kmcattach, 0, kmcstd, "kmc", kmcdinfo };
10238624Skarels 
kmcprobe(reg)10338624Skarels kmcprobe(reg)
10438624Skarels caddr_t reg;
10538624Skarels {	register int br, cvec;	/* don't touch */
10638624Skarels 	register struct kmcdevice *kp = (struct kmcdevice *)reg;
10738624Skarels 	register s;
10838624Skarels 
10938624Skarels #ifdef lint
11038624Skarels 	br = 0; cvec = br; br = cvec;
11138624Skarels #endif
11238624Skarels 	s = spl7();
11338624Skarels 	kp->bsel1 = MCLR;
11438624Skarels 	splx(s);
11538624Skarels 	kp->bsel1 = ROMI;
11638624Skarels 	kp->sel4 = 0200;		/* bus request */
11738624Skarels 	kp->sel6 = 0121111;		/* mov csr4,obr */
11838624Skarels 	kp->bsel1 = ROMI|STEP;
11938624Skarels 	DELAY(50);
12038624Skarels 	kp->bsel1 = 0;
12138624Skarels 	return(1);
12238624Skarels }
12338624Skarels 
kmcattach(ui)12438624Skarels kmcattach(ui)
12538624Skarels register struct uba_device *ui;
12638624Skarels {
12738624Skarels 	switch(ui->ui_flags & 03) {
12838624Skarels #if NVPM>0
12938624Skarels 		case 0:
13038624Skarels 			vpminit(ui);
13138624Skarels 			break;
13238624Skarels #endif
13338624Skarels #if NDKITKMC>0
13438624Skarels 		case 1:
13538624Skarels 			dkkmc_attach(ui);
13638624Skarels 			break;
13738624Skarels #endif
13838624Skarels 		default:
13938624Skarels 			log(LOG_ERR, "kmc%d: no protocol %d\n", ui->ui_unit,
14038624Skarels 			    ui->ui_flags);
14138624Skarels 			break;
14238624Skarels 	}
14338624Skarels }
14438624Skarels 
14538624Skarels /*ARGSUSED*/
kmcopen(dev,flag)14638624Skarels kmcopen(dev, flag)
14738624Skarels {
14838624Skarels 	register struct kmcdevice *kp;
14938624Skarels 	register struct kmc *tp;
15038624Skarels 	register sav;
15138624Skarels 
15238624Skarels 	dev = minor(dev);
15338624Skarels 	if (dev>=kmc_cnt || (tp = &kmc[dev])->k_stat&SOPEN) {
15438624Skarels 		return (ENXIO);
15538624Skarels 	}
15638624Skarels 	tp->k_stat |= SOPEN;
15738624Skarels 	if (tp->k_type==0) {
15838624Skarels 		kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
15938624Skarels 		kp->bsel1 = ROMO;
16038624Skarels 		kp->sel4 = 0;
16138624Skarels 		sav = kp->sel6;
16238624Skarels 		kp->sel6 = ~sav;
16338624Skarels 		if (kp->sel6 != sav) {
16438624Skarels 			tp->k_type = KMC11B;
16538624Skarels 			kp->sel6 = sav;
16638624Skarels 		} else
16738624Skarels 			tp->k_type = KMC11A;
16838624Skarels 		kp->bsel1 = 0;
16938624Skarels 	}
17038624Skarels 	return (0);
17138624Skarels }
17238624Skarels 
kmcclose(dev)17338624Skarels kmcclose(dev)
17438624Skarels {
17538624Skarels 	dev = minor(dev);
17638624Skarels 	kmc[dev].k_stat &= ~SOPEN;
17738624Skarels }
17838624Skarels 
kmcread(dev,uio)17938624Skarels kmcread(dev, uio)
18038624Skarels 	dev_t dev;
18138624Skarels 	struct uio *uio;
18238624Skarels {
18338624Skarels 	register struct kmcdevice *kp;
18438624Skarels 	register ad;
18538624Skarels 	register int error = 0;
18638624Skarels 	int	dsize;
18738624Skarels 	ushort	sav;
18838624Skarels 
18938624Skarels 	dev = minor(dev);
19038624Skarels 	if (kmc[dev].k_stat&SRUN)
19138624Skarels 		return (0);
19238624Skarels 	dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
19338624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
19438624Skarels 	kp->bsel1 = 0;
19538624Skarels 	do {
19638624Skarels 		ad = uio->uio_offset;
19738624Skarels 		if (ad<dsize*2) {
19838624Skarels 			if (ad&1) {
19938624Skarels 				return (ENXIO);
20038624Skarels 			}
20138624Skarels 			ad >>= 1;
20238624Skarels 			kp->bsel1 = ROMO;
20338624Skarels 			kp->sel4 = ad;
20438624Skarels 			if ((error=ureadc(kp->bsel6, uio)) < 0)
20538624Skarels 				break;
20638624Skarels 			if ((error=ureadc(kp->bsel7, uio)) < 0)
20738624Skarels 				break;
20838624Skarels 			kp->bsel1 = 0;
20938624Skarels 		} else if (ad -= dsize*2, ad<dsize) {
21038624Skarels 			kp->bsel1 = ROMO;
21138624Skarels 			kp->sel4 = 0;
21238624Skarels 			sav = kp->sel6;
21338624Skarels 			kp->bsel1 = ROMI;
21438624Skarels 			kp->sel6 = 010000|(ad&0377);	/* mov ad,mar */
21538624Skarels 			kp->bsel1 = ROMI|STEP;
21638624Skarels 			kp->bsel1 = ROMI;
21738624Skarels 			kp->sel6 = 04000|((ad>>8)&0377);	/* mov %ad,%mar */
21838624Skarels 			kp->bsel1 = ROMI|STEP;
21938624Skarels 			kp->bsel1 = ROMI;
22038624Skarels 			kp->sel6 = 055222;	/* mov mem,csr2|mar++ */
22138624Skarels 			kp->bsel1 = ROMI|STEP;
22238624Skarels 			if ((error=ureadc(kp->bsel2, uio)) < 0)
22338624Skarels 				break;
22438624Skarels 			kp->bsel1 = ROMI;
22538624Skarels 			kp->sel6 = sav;
22638624Skarels 			kp->bsel1 = 0;
22738624Skarels 		} else
22838624Skarels 			break;
22938624Skarels 	} while (!error && uio->uio_resid);
23038624Skarels 	return (error);
23138624Skarels }
23238624Skarels 
kmcwrite(dev,uio)23338624Skarels kmcwrite(dev, uio)
23438624Skarels 	dev_t dev;
23538624Skarels 	struct uio *uio;
23638624Skarels {
23738624Skarels 	register struct kmcdevice *kp;
23838624Skarels 	register ad;
23938624Skarels 	int	dsize;
24038624Skarels 	short	ins;
24138624Skarels 	ushort	sav;
24238624Skarels 
24338624Skarels 	dev = minor(dev);
24438624Skarels 	if (kmc[dev].k_stat&SRUN)
24538624Skarels 		return (0);
24638624Skarels 	dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
24738624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
24838624Skarels 	kp->bsel1 = 0;
24938624Skarels 	while (uio->uio_resid) {
25038624Skarels 		ad = uio->uio_offset;
25138624Skarels 		if (ad<dsize*2) {
25238624Skarels 			if (ad&1) {
25338624Skarels 				return (ENXIO);
25438624Skarels 			}
25538624Skarels 			kp->bsel1 = ROMO;
25638624Skarels 			kp->sel4 = ad>>1;
25738624Skarels 			lobyte(ins) = uwritec(uio);
25838624Skarels 			hibyte(ins) = uwritec(uio);
25938624Skarels 			kp->sel6 = ins;
26038624Skarels 			kp->bsel1 |= CWRT;
26138624Skarels 			kp->bsel1 = 0;
26238624Skarels 		} else if (ad -= dsize*2, ad<dsize) {
26338624Skarels 			kp->bsel1 = ROMO;
26438624Skarels 			kp->sel4 = 0;
26538624Skarels 			sav = kp->sel6;
26638624Skarels 			kp->bsel1 = ROMI;
26738624Skarels 			kp->sel6 = 010000|(ad&0377);	/* mov ad,mar */
26838624Skarels 			kp->bsel1 = ROMI|STEP;
26938624Skarels 			kp->bsel1 = ROMI;
27038624Skarels 			kp->sel6 = 04000|((ad>>8)&0377);	/* mov %ad,%mar */
27138624Skarels 			kp->bsel1 = ROMI|STEP;
27238624Skarels 			kp->bsel1 = ROMI;
27338624Skarels 			kp->bsel2 = uwritec(uio);
27438624Skarels 			kp->sel6 = 0136440;	/* mov csr2,mem|mar++ */
27538624Skarels 			kp->bsel1 = ROMI|STEP;
27638624Skarels 			kp->bsel1 = ROMI;
27738624Skarels 			kp->sel6 = sav;
27838624Skarels 			kp->bsel1 = 0;
27938624Skarels 		} else
28038624Skarels 			break;
28138624Skarels 	}
28238624Skarels 	return (0);
28338624Skarels }
28438624Skarels 
28538624Skarels /*ARGSUSED*/
kmcioctl(dev,cmd,kk,mode)28638624Skarels kmcioctl(dev, cmd, kk, mode)
28738624Skarels 	dev_t dev;
28838624Skarels 	struct kmcntl *kk;
28938624Skarels {
29038624Skarels 	register struct kmcdevice *kp;
29138624Skarels 	register struct kmc *tp;
29238624Skarels 	short	csr[4];
29338624Skarels 	ushort	sav;
29438624Skarels 
29538624Skarels 	if (rkmcdebug) log(LOG_ERR, "kmcioctl: cmd=%d, kk->kmd=%d, kk->kcsr=0x%x, kk->kval=%d\n",
29638624Skarels 		cmd, kk->kmd, kk->kcsr, kk->kval);
29738624Skarels 	dev = minor(dev);
29838624Skarels 	if (cmd != KCSETA) {
29938624Skarels 		return (EINVAL);
30038624Skarels 	}
30138624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
30238624Skarels 	tp = &kmc[dev];
30338624Skarels 	switch (kk->kmd) {
30438624Skarels 	case KMCLR:
30538624Skarels 	case KRESET:
30638624Skarels 		spl7();
30738624Skarels 		kp->bsel1 = MCLR;
30838624Skarels 		spl0();
30938624Skarels 	case KSTOP:
31038624Skarels 		tp->k_stat &= ~SRUN;
31138624Skarels 		kp->bsel1 = 0;
31238624Skarels 		if (kk->kmd == KRESET) {
31338624Skarels 			tp->k_stat = 0;
31438624Skarels 			while(getc(&tp->k_inq) >= 0) ;
31538624Skarels 			if (tp->k_stat&SINIT)
31638624Skarels 				(*tp->k_init)(dev);
31738624Skarels 		}
31838624Skarels 		return (0);
31938624Skarels 	case KMS:
32038624Skarels 		if (tp->k_stat&SRUN)
32138624Skarels 			break;
32238624Skarels 		kp->bsel1 = ROMI|ROMO;
32338624Skarels 		sav = kp->sel6;
32438624Skarels 		kp->bsel1 = ROMI;
32538624Skarels 		kp->sel6 = kk->kval;
32638624Skarels 		kp->bsel1 = ROMI|STEP;
32738624Skarels 		kp->bsel1 = ROMI;
32838624Skarels 		kp->sel6 = sav;
32938624Skarels 		kp->bsel1 = 0;
33038624Skarels 		goto lcsr;
33138624Skarels 	case KSTEP:
33238624Skarels 		if (tp->k_stat&SRUN)
33338624Skarels 			break;
33438624Skarels 		kp->bsel1 |= STEP;
33538624Skarels 		kp->bsel1 = 0;
33638624Skarels 	case KCSR:
33738624Skarels 	lcsr:
33838624Skarels 		csr[0] = kp->sel0;
33938624Skarels 		csr[1] = kp->sel2;
34038624Skarels 		csr[2] = kp->sel4;
34138624Skarels 		csr[3] = kp->sel6;
34238624Skarels 		if (copyout((caddr_t)csr, (caddr_t)kk->kcsr, sizeof csr))
34338624Skarels 			return (EFAULT);
34438624Skarels 		return (0);
34538624Skarels 	case KWRCR:
34638624Skarels 		if (tp->k_stat&SRINT)
34738624Skarels 			break;
34838624Skarels 		kp->sel6 = kk->kval;
34938624Skarels 		return (0);
35038624Skarels 	case KRUN:
35138624Skarels 		if (tp->k_stat&SRUN)
35238624Skarels 			break;
35338624Skarels 		tp->k_stat &= ~STYPE;
35438624Skarels 		tp->k_stat |= (kk->kval&STYPE)|SRUN;
35538624Skarels 		kp->bsel1 |= RUN;
35638624Skarels 		if (tp->k_stat&SRINT) {
35738624Skarels 			spl5();
35838624Skarels 			kmcrint(dev);
35938624Skarels 			spl0();
36038624Skarels 		}
36138624Skarels 		if (tp->k_stat&SRESET)
36238624Skarels 			(*tp->k_reset)(dev);
36338624Skarels 		return (0);
36438624Skarels 	case KLU:
36538624Skarels 		kp->bsel1 = kk->kval&(LUA|LUB);
36638624Skarels 		return (0);
36738624Skarels 	}
36838624Skarels 	if (rkmcdebug) log(LOG_ERR, "kmcioctl: EIO exit, tp->k_stat=0x%x\n", tp->k_stat);
36938624Skarels 	return (EIO);
37038624Skarels }
37138624Skarels 
kmcrint(dev)37238624Skarels kmcrint(dev)
37338624Skarels {
37438624Skarels 	register struct kmcdevice *kp;
37538624Skarels 	register struct kmc *tp;
37638624Skarels 
37738624Skarels 	dev = minor(dev);
37838624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
37938624Skarels 	tp = &kmc[dev];
38038624Skarels 	kp->sel0 &= ~IEI;
38138624Skarels 	while (kp->sel2&RDYI) {
38238624Skarels 		if ((tp->k_stat&SLOAD) ||
38338624Skarels 		  q_to_b(&tp->k_inq, (char *)tp->k_arg, sizeof(tp->k_arg)) == sizeof(tp->k_arg)) {
38438624Skarels 			kp->sel2 = tp->k_arg[0]|RDYI;
38538624Skarels 			kp->sel4 = tp->k_arg[1];
38638624Skarels 			kp->sel6 = tp->k_arg[2];
38738624Skarels 			tp->k_stat &= ~SLOAD;
38838624Skarels 		} else {
38938624Skarels 			log(LOG_ERR, "Bad kmc %d load\n", dev);
39038624Skarels 		}
39138624Skarels 		if (tp->k_inq.c_cc==0) {
39238624Skarels 			kp->sel0 &= ~RQI;
39338624Skarels 			kp->sel2 &= ~RDYI;
39438624Skarels 			return;
39538624Skarels 		}
39638624Skarels 		kp->sel2 &= ~RDYI;
39738624Skarels 	}
39838624Skarels 	if ((tp->k_stat&SLOAD) || tp->k_inq.c_cc)
39938624Skarels 		kp->sel0 |= IEI|RQI;
40038624Skarels }
40138624Skarels 
kmcxint(dev)40238624Skarels kmcxint(dev)
40338624Skarels {
40438624Skarels 	register struct kmcdevice *kp;
40538624Skarels 	register struct kmc *tp;
40638624Skarels 	int p1, p2, p3, p4;
40738624Skarels 
40838624Skarels 	dev = minor(dev);
40938624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
41038624Skarels 	tp = &kmc[dev];
41138624Skarels 	kp->sel0 &= ~IEO;
41238624Skarels 	while(kp->sel2&RDYO) {
41338624Skarels 		p1 = (dev<<6)|(kp->bsel3&077);
41438624Skarels 		p2 = kp->bsel2&017;
41538624Skarels 		p3 = kp->sel4;
41638624Skarels 		p4 = kp->sel6;
41738624Skarels 		kp->sel2 &= ~RDYO;
41838624Skarels 		if (tp->k_stat&SRINT)
41938624Skarels 			(*tp->k_rint)(p1, p2, p3, p4);
42038624Skarels 	}
42138624Skarels 	kp->sel0 |= IEO;
42238624Skarels }
42338624Skarels 
kmcload(dev,p1,p2,p3)42438624Skarels kmcload(dev, p1, p2, p3)
42538624Skarels {
42638624Skarels 	register struct kmcdevice *kp;
42738624Skarels 	register struct kmc *tp;
42838624Skarels 	register unit;
42938624Skarels 	register sps;
43038624Skarels 
43138624Skarels 	dev = minor(dev);
43238624Skarels 	unit = (dev>>6)&03;
43338624Skarels 	tp = &kmc[unit];
43438624Skarels 	if (!(tp->k_stat&SRUN))
43538624Skarels 		return(-1);
43638624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[unit]->ui_addr);	/* RAV unit is suspect */
43738624Skarels 	sps = spl5();
43838624Skarels 	if (tp->k_stat&SLOAD) {
43938624Skarels 		b_to_q((char *)tp->k_arg, sizeof(tp->k_arg), &tp->k_inq);
44038624Skarels 		tp->k_stat &= ~SLOAD;
44138624Skarels 	}
44238624Skarels 	kp->sel0 |= RQI;
44338624Skarels 	tp->k_arg[0] = (p1&017)|((dev&077)<<8);
44438624Skarels 	tp->k_arg[1] = p2;
44538624Skarels 	tp->k_arg[2] = p3;
44638624Skarels 	if (tp->k_inq.c_cc)
44738624Skarels 		b_to_q((char *)tp->k_arg, sizeof(tp->k_arg), &tp->k_inq);
44838624Skarels 	else
44938624Skarels 		tp->k_stat |= SLOAD;
45038624Skarels 	kmcrint(unit);
45138624Skarels 	splx(sps);
45238624Skarels 	return(tp->k_inq.c_cc);
45338624Skarels }
45438624Skarels 
45538624Skarels kmcset(dev, type, rint)
45638624Skarels int (*rint)();
45738624Skarels {
45838624Skarels 	register struct kmcdevice *kp;
45938624Skarels 	register struct kmc *tp;
46038624Skarels 	register unit;
46138624Skarels 
46238624Skarels 	dev = minor(dev);
46338624Skarels 	unit = (dev>>6)&03;
46438624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[unit]->ui_addr);	/* RAV unit is suspect */
46538624Skarels 	tp = &kmc[unit];
46638624Skarels 	if ((tp->k_stat&(STYPE|SRUN|SOPEN))!=((type&STYPE)|SRUN))
46738624Skarels 		return (1);
46838624Skarels 	tp->k_stat |= SRINT;
46938624Skarels 	tp->k_rint = rint;
47038624Skarels 	kp->sel0 |= IEO;
47138624Skarels 	return(0);
47238624Skarels }
47338624Skarels 
kmcdclr(dev)47438624Skarels kmcdclr(dev)
47538624Skarels register dev;
47638624Skarels {
47738624Skarels 	register struct kmc *tp;
47838624Skarels 	register struct kmcdevice *kp;
47938624Skarels 
48038624Skarels 	dev = minor(dev);
48138624Skarels 	if (dev < 0 || dev >= kmc_cnt)
48238624Skarels 		return;
48338624Skarels 	tp = &kmc[dev];
48438624Skarels 	while (getc(&tp->k_inq) >= 0) ;
48538624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
48638624Skarels 	kp->sel0 = 0;
48738624Skarels 	kp->sel2 = 0;
48838624Skarels }
48938624Skarels 
kmcreset(dev)49038624Skarels kmcreset(dev)
49138624Skarels {
49238624Skarels 	register struct kmc *tp;
49338624Skarels 	register struct kmcdevice *kp;
49438624Skarels 	register s;
49538624Skarels 
49638624Skarels 	dev = minor(dev);
49738624Skarels 	tp = &kmc[dev];
49838624Skarels 	kp = ((struct kmcdevice *)kmcdinfo[dev]->ui_addr);
49938624Skarels 	s = spl7();
50038624Skarels 	kp->bsel1 = MCLR;
50138624Skarels 	splx(s);
50238624Skarels 	kp->bsel1 = 0;
50338624Skarels 	tp->k_stat = 0;
50438624Skarels 	while(getc(&tp->k_inq)>=0);
50538624Skarels }
50638624Skarels 
50738624Skarels kmcifset(dev, init)
50838624Skarels int (*init)();
50938624Skarels {
51038624Skarels 	register struct kmc *tp;
51138624Skarels 	register unit;
51238624Skarels 
51338624Skarels 	dev = minor(dev);
51438624Skarels 	unit = (dev>>6)&03;
51538624Skarels 	if (unit < 0 || unit >= kmc_cnt)
51638624Skarels 		return;
51738624Skarels 	tp = &kmc[unit];
51838624Skarels 	if (init==NULL) {
51938624Skarels 		tp->k_init = NULL;
52038624Skarels 		tp->k_stat &= ~SINIT;
52138624Skarels 	} else {
52238624Skarels 		tp->k_init = init;
52338624Skarels 		tp->k_stat |= SINIT;
52438624Skarels 	}
52538624Skarels }
52638624Skarels 
52738624Skarels kmcrfset(dev, reset)
52838624Skarels int (*reset)();
52938624Skarels {
53038624Skarels 	register struct kmc *tp;
53138624Skarels 	register unit;
53238624Skarels 
53338624Skarels 	dev = minor(dev);
53438624Skarels 	unit = (dev>>6)&03;
53538624Skarels 	if (unit < 0 || unit >= kmc_cnt)
53638624Skarels 		return;
53738624Skarels 	tp = &kmc[unit];
53838624Skarels 	if (reset==NULL) {
53938624Skarels 		tp->k_reset = NULL;
54038624Skarels 		tp->k_stat &= ~SRESET;
54138624Skarels 	} else {
54238624Skarels 		tp->k_reset = reset;
54338624Skarels 		tp->k_stat |= SRESET;
54438624Skarels 	}
54538624Skarels }
54638624Skarels #endif
547