xref: /csrg-svn/sys/vax/uba/uda.c (revision 5434)
1 /*	uda.c	4.2	82/01/17	*/
2 
3 #include "ra.h"
4 #if NUDA > 0
5 /*
6  * UDA50/RAxx disk device driver
7  *
8  * Restrictions:
9  *	Unit numbers must be less than 8.
10  *
11  * TO DO:
12  *	write dump code
13  *	test on 750
14  */
15 
16 #include "../h/param.h"
17 #include "../h/systm.h"
18 #include "../h/buf.h"
19 #include "../h/conf.h"
20 #include "../h/dir.h"
21 #include "../h/user.h"
22 #include "../h/pte.h"
23 #include "../h/map.h"
24 #include "../h/vm.h"
25 #include "../h/ubareg.h"
26 #include "../h/ubavar.h"
27 #include "../h/dk.h"
28 #include "../h/cpu.h"
29 #include "../h/cmap.h"
30 
31 int udadebug;
32 #define	printd	if(udadebug&1)printf
33 
34 /*
35  * Parameters for the communications area
36  */
37 
38 #define	NRSPL2	3
39 #define	NCMDL2	3
40 #define	NRSP	(1<<NRSPL2)
41 #define	NCMD	(1<<NCMDL2)
42 
43 #include "../h/udareg.h"
44 #include "../h/mscp.h"
45 
46 struct uda_softc {
47 	short	sc_state;	/* state of controller */
48 	short	sc_mapped;	/* Unibus map allocated for uda struct? */
49 	int	sc_ubainfo;	/* Unibus mapping info */
50 	struct uda *sc_uda;	/* Unibus address of uda struct */
51 	int	sc_ivec;	/* interrupt vector address */
52 	short	sc_credits;	/* transfer credits */
53 	short	sc_lastcmd;	/* pointer into command ring */
54 	short	sc_lastrsp;	/* pointer into response ring */
55 } uda_softc[NUDA];
56 
57 /*
58  * Controller states
59  */
60 #define	S_IDLE	0		/* hasn't been initialized */
61 #define	S_STEP1	1		/* doing step 1 init */
62 #define	S_STEP2	2		/* doing step 2 init */
63 #define	S_STEP3	3		/* doing step 3 init */
64 #define	S_SCHAR	4		/* doing "set controller characteristics" */
65 #define	S_RUN	5		/* running */
66 
67 struct uda {
68 	struct udaca	uda_ca;		/* communications area */
69 	struct mscp	uda_rsp[NRSP];	/* response packets */
70 	struct mscp	uda_cmd[NCMD];	/* command packets */
71 } uda[NUDA];
72 
73 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
74 struct size {
75 	daddr_t	nblocks;
76 	daddr_t	blkoff;
77 } ra_sizes[8] ={
78 	15884,	0,		/* A=blk 0 thru 15883 */
79 	33440,	15884,		/* B=blk 15884 thru 49323 */
80 	-1,	0,		/* C=blk 0 thru end */
81 	0,	0,		/* D reserved for RA81 */
82 	0,	0,		/* E reserved for RA81 */
83 	0,	0,		/* F reserved for RA81 */
84 	82080,	49324,		/* G=blk 49324 thru 131403 */
85 	-1,	131404,		/* H=blk 131404 thru end */
86 };
87 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
88 
89 daddr_t	radsize[NRA];			/* disk size, from ONLINE end packet */
90 
91 int	udprobe(), udslave(), udattach(), udintr();
92 struct	mscp *udgetcp();
93 struct	uba_ctlr *udminfo[NUDA];
94 struct	uba_device *uddinfo[NRA];
95 struct	uba_device *udip[NUDA][8];	/* 8 == max number of drives */
96 
97 u_short	udstd[] = { 0777550, 0 };
98 struct	uba_driver udadriver =
99  { udprobe, udslave, udattach, 0, udstd, "ra", uddinfo, "uda", udminfo, 0 };
100 struct	buf rudbuf[NRA];
101 struct	buf udutab[NRA];
102 struct	buf udwtab[NUDA];		/* I/O wait queue, per controller */
103 
104 #define	b_qsize		b_resid		/* queue size per drive, in udutab */
105 #define	b_ubinfo	b_resid		/* Unibus mapping info, per buffer */
106 
107 udprobe(reg, ctlr)
108 	caddr_t reg;
109 	int ctlr;
110 {
111 	register int br, cvec;
112 	register struct uda_softc *sc = &uda_softc[ctlr];
113 
114 #ifdef lint
115 	br = 0; cvec = br; br = cvec;
116 #endif
117 	/* SHOULD CHECK THAT IT REALLY IS A UDA */
118 	br = 0x15;
119 	cvec = sc->sc_ivec = (uba_hd[numuba].uh_lastiv -= 4);
120 	return(1);
121 }
122 
123 udslave(ui, reg)
124 	struct uba_device *ui;
125 	caddr_t reg;
126 {
127 	/*
128 	 * TOO HARD TO FIND OUT IF DISK IS THERE UNTIL
129 	 * INITIALIZED.  WE'LL FIND OUT WHEN WE FIRST
130 	 * TRY TO ACCESS IT.
131 	 */
132 	return(1);
133 }
134 
135 udattach(ui)
136 	register struct uba_device *ui;
137 {
138 
139 	if (ui->ui_dk > 0)
140 		dk_mspw[ui->ui_dk] = 1.0 / (60 * 31 * 256);	/* approx */
141 	ui->ui_flags = 0;
142 	udip[ui->ui_ctlr][ui->ui_slave] = ui;
143 	radsize[ui->ui_unit] = (daddr_t)0xffffff;	/* max possible size */
144 }
145 
146 /*
147  * Open a UDA.  Initialize the device and
148  * set the unit online.
149  */
150 udopen(dev, flag)
151 	dev_t dev;
152 	int flag;
153 {
154 	register int unit;
155 	register struct uba_device *ui;
156 	register struct uda_softc *sc;
157 	int s;
158 
159 	unit = minor(dev) >> 3;
160 	if (unit >= NRA || (ui = uddinfo[unit]) == 0 || ui->ui_alive == 0) {
161 		u.u_error = ENXIO;
162 		return;
163 	}
164 	sc = &uda_softc[ui->ui_ctlr];
165 	s = spl5();
166 	if (sc->sc_state != S_RUN) {
167 		if (sc->sc_state == S_IDLE)
168 			udinit(ui->ui_ctlr);
169 		sleep(ui->ui_mi, 0); /* wait for initialization to complete */
170 		if (sc->sc_state != S_RUN) {
171 			u.u_error = EIO;
172 			return;
173 		}
174 	}
175 	splx(s);
176 	/* SHOULD PROBABLY FORCE AN ONLINE ATTEMPT
177 	   TO SEE IF DISK IS REALLY THERE */
178 }
179 
180 /*
181  * Initialize a UDA.  Set up UBA mapping registers,
182  * initialize data structures, and start hardware
183  * initialization sequence.
184  */
185 udinit(d)
186 	int d;
187 {
188 	register struct uda_softc *sc;
189 	register struct uda *ud;
190 	struct udadevice *udaddr;
191 	struct uba_ctlr *um;
192 
193 	sc = &uda_softc[d];
194 	um = udminfo[d];
195 	um->um_tab.b_active++;
196 	ud = &uda[d];
197 	udaddr = (struct udadevice *)um->um_addr;
198 	if (sc->sc_mapped == 0) {
199 		/*
200 		 * Map the communications area and command
201 		 * and response packets into Unibus address
202 		 * space.
203 		 */
204 		sc->sc_ubainfo = uballoc(um->um_ubanum, (caddr_t)ud,
205 		    sizeof (struct uda), 0);
206 		sc->sc_uda = (struct uda *)(sc->sc_ubainfo & 0x3ffff);
207 		sc->sc_mapped = 1;
208 	}
209 
210 	/*
211 	 * Start the hardware initialization sequence.
212 	 */
213 	udaddr->udaip = 0;		/* start initialization */
214 	while ((udaddr->udasa & UDA_STEP1) == 0)
215 		;
216 	udaddr->udasa = UDA_ERR|(NCMDL2<<11)|(NRSPL2<<8)|UDA_IE|(sc->sc_ivec/4);
217 	/*
218 	 * Initialization continues in interrupt routine.
219 	 */
220 	sc->sc_state = S_STEP1;
221 	sc->sc_credits = 0;
222 }
223 
224 udstrategy(bp)
225 	register struct buf *bp;
226 {
227 	register struct uba_device *ui;
228 	register struct uba_ctlr *um;
229 	register struct buf *dp;
230 	register int unit;
231 	int xunit = minor(bp->b_dev) & 07;
232 	daddr_t sz, maxsz;
233 	int s;
234 
235 	sz = (bp->b_bcount+511) >> 9;
236 	unit = dkunit(bp);
237 	if (unit >= NRA)
238 		goto bad;
239 	ui = uddinfo[unit];
240 	um = ui->ui_mi;
241 	if (ui == 0 || ui->ui_alive == 0)
242 		goto bad;
243 	if ((maxsz = ra_sizes[xunit].nblocks) < 0)
244 		maxsz = radsize[unit] - ra_sizes[xunit].blkoff;
245 	if (bp->b_blkno < 0 || bp->b_blkno+sz > maxsz ||
246 	    ra_sizes[xunit].blkoff >= radsize[unit])
247 		goto bad;
248 	s = spl5();
249 	/*
250 	 * Link the buffer onto the drive queue
251 	 */
252 	dp = &udutab[ui->ui_unit];
253 	if (dp->b_actf == 0)
254 		dp->b_actf = bp;
255 	else
256 		dp->b_actl->av_forw = bp;
257 	dp->b_actl = bp;
258 	bp->av_forw = 0;
259 	/*
260 	 * Link the drive onto the controller queue
261 	 */
262 	if (dp->b_active == 0) {
263 		dp->b_forw = NULL;
264 		if (um->um_tab.b_actf == NULL)
265 			um->um_tab.b_actf = dp;
266 		else
267 			um->um_tab.b_actl->b_forw = dp;
268 		um->um_tab.b_actl = dp;
269 		dp->b_active = 1;
270 	}
271 	if (um->um_tab.b_active == 0) {
272 #if defined(VAX750)
273 		if (cpu == VAX_750) {
274 			if (um->um_ubinfo != 0)
275 				printf("uda: ubinfo %x\n",um->um_ubinfo);
276 			else
277 				um->um_ubinfo =
278 				uballoc(um->um_ubanum, 0, 0, UBA_NEEDBDP);
279 		}
280 #endif
281 		(void) udstart(um);
282 	}
283 	splx(s);
284 	return;
285 
286 bad:
287 	bp->b_flags |= B_ERROR;
288 	iodone(bp);
289 	return;
290 }
291 
292 udstart(um)
293 	register struct uba_ctlr *um;
294 {
295 	register struct buf *bp, *dp;
296 	register struct mscp *mp;
297 	register struct uda_softc *sc;
298 	register struct uba_device *ui;
299 	struct udadevice *udaddr;
300 	int i;
301 
302 	sc = &uda_softc[um->um_ctlr];
303 
304 loop:
305 	if ((dp = um->um_tab.b_actf) == NULL) {
306 		/*
307 		 * Release uneeded UBA resources and return
308 		 */
309 		um->um_tab.b_active = 0;
310 #if defined(VAX750)
311 		if (cpu == VAX_750) {
312 			if (um->um_ubinfo == 0)
313 				printf("uda: um_ubinfo == 0\n");
314 			else
315 				ubarelse(um->um_ubanum, &um->um_ubinfo);
316 		}
317 #endif
318 		return(0);
319 	}
320 	if ((bp = dp->b_actf) == NULL) {
321 		/*
322 		 * No more requests for this drive, remove
323 		 * from controller queue and look at next drive.
324 		 * We know we're at the head of the controller queue.
325 		 */
326 		dp->b_active = 0;
327 		um->um_tab.b_actf = dp->b_forw;
328 		goto loop;
329 	}
330 	um->um_tab.b_active++;
331 	udaddr = (struct udadevice *)um->um_addr;
332 	if ((udaddr->udasa&UDA_ERR) || sc->sc_state != S_RUN) {
333 		harderr(bp, "ra");
334 		printf("udasa %o, state %d\n", udaddr->udasa&0xffff, sc->sc_state);
335 		udinit(um->um_ctlr);
336 		/* SHOULD REQUEUE OUTSTANDING REQUESTS, LIKE UDRESET */
337 		return;
338 	}
339 	ui = uddinfo[dkunit(bp)];
340 	/*
341 	 * If no credits, can't issue any commands
342 	 * until some outstanding commands complete.
343 	 */
344 	if (sc->sc_credits < 2)
345 		return(0);
346 	if ((mp = udgetcp(um)) == NULL)
347 		return(0);
348 	sc->sc_credits--;	/* committed to issuing a command */
349 	if (ui->ui_flags == 0) {	/* not online */
350 		mp->mscp_opcode = M_OP_ONLIN;
351 		mp->mscp_unit = ui->ui_slave;
352 		dp->b_active = 2;
353 		um->um_tab.b_actf = dp->b_forw;	/* remove from controller q */
354 		printd("uda: bring unit %d online\n", ui->ui_slave);
355 		*((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
356 		i = udaddr->udaip;
357 		goto loop;
358 	}
359 	switch (cpu) {
360 	case VAX_780:
361 		i = UBA_NEEDBDP|UBA_CANTWAIT;
362 		break;
363 
364 	case VAX_750:
365 		i = um->um_ubinfo|UBA_HAVEBDP|UBA_CANTWAIT;
366 		break;
367 
368 	case VAX_7ZZ:
369 		i = UBA_CANTWAIT;
370 		break;
371 	}
372 	if ((i = ubasetup(um->um_ubanum, bp, i)) == 0) {
373 		mp->mscp_opcode = M_OP_GTUNT;
374 		mp->mscp_unit = ui->ui_slave;
375 		*((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
376 		i = udaddr->udaip;	/* initiate polling */
377 		return(1);		/* wait for interrupt */
378 	}
379 	mp->mscp_cmdref = (long)bp;	/* pointer to get back */
380 	mp->mscp_opcode = bp->b_flags&B_READ ? M_OP_READ : M_OP_WRITE;
381 	mp->mscp_unit = ui->ui_slave;
382 	mp->mscp_lbn = bp->b_blkno + ra_sizes[minor(bp->b_dev)&7].blkoff;
383 	mp->mscp_bytecnt = bp->b_bcount;
384 	mp->mscp_buffer = (i & 0x3ffff) | (((i>>28)&0xf)<<24);
385 #if defined(VAX750)
386 	if (cpu == VAX_750)
387 		i &= 0xfffffff;		/* mask off bdp */
388 #endif
389 	bp->b_ubinfo = i;		/* save mapping info */
390 	*((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
391 	i = udaddr->udaip;		/* initiate polling */
392 	if (ui->ui_dk >= 0) {
393 		dk_busy |= 1<<ui->ui_dk;
394 		dp->b_qsize++;
395 		dk_xfer[ui->ui_dk]++;
396 		dk_wds[ui->ui_dk] += bp->b_bcount>>6;
397 	}
398 
399 	/*
400 	 * Move drive to the end of the controller queue
401 	 */
402 	if (dp->b_forw != NULL) {
403 		um->um_tab.b_actf = dp->b_forw;
404 		um->um_tab.b_actl->b_forw = dp;
405 		um->um_tab.b_actl = dp;
406 		dp->b_forw = NULL;
407 	}
408 	/*
409 	 * Move buffer to I/O wait queue
410 	 */
411 	dp->b_actf = bp->av_forw;
412 	dp = &udwtab[um->um_ctlr];
413 	bp->av_forw = dp;
414 	bp->av_back = dp->av_back;
415 	dp->av_back->av_forw = bp;
416 	dp->av_back = bp;
417 	goto loop;
418 }
419 
420 /*
421  * UDA interrupt routine.
422  */
423 udintr(d)
424 	int d;
425 {
426 	register struct uba_ctlr *um = udminfo[d];
427 	register struct udadevice *udaddr = (struct udadevice *)um->um_addr;
428 	struct buf *bp;
429 	register int i;
430 	register struct uda_softc *sc = &uda_softc[d];
431 	register struct uda *ud = &uda[d];
432 	struct uda *uud;
433 	struct mscp *mp;
434 
435 	printd("udintr: state %d, udasa %o\n", sc->sc_state, udaddr->udasa);
436 	switch (sc->sc_state) {
437 	case S_IDLE:
438 		printf("uda%d: random interrupt ignored\n", d);
439 		return;
440 
441 	case S_STEP1:
442 #define	STEP1GOOD	(UDA_STEP2|UDA_IE|(NCMDL2<<3)|NRSPL2)
443 		if ((udaddr->udasa&(UDA_ERR|STEP1GOOD)) != STEP1GOOD) {
444 			sc->sc_state = S_IDLE;
445 			wakeup(um);
446 			return;
447 		}
448 		udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)|
449 		    (cpu == VAX_780 ? UDA_PI : 0);
450 		sc->sc_state = S_STEP2;
451 		return;
452 
453 	case S_STEP2:
454 #define	STEP2GOOD	(UDA_STEP3|UDA_IE|(sc->sc_ivec/4))
455 		if ((udaddr->udasa&(UDA_ERR|STEP2GOOD)) != STEP2GOOD) {
456 			sc->sc_state = S_IDLE;
457 			wakeup(um);
458 			return;
459 		}
460 		udaddr->udasa = ((int)&sc->sc_uda->uda_ca.ca_ringbase)>>16;
461 		sc->sc_state = S_STEP3;
462 		return;
463 
464 	case S_STEP3:
465 #define	STEP3GOOD	UDA_STEP4
466 		if ((udaddr->udasa&(UDA_ERR|STEP3GOOD)) != STEP3GOOD) {
467 			sc->sc_state = S_IDLE;
468 			wakeup(um);
469 			return;
470 		}
471 		udaddr->udasa = UDA_GO;
472 		sc->sc_state = S_SCHAR;
473 
474 		/*
475 		 * Initialize the data structures.
476 		 */
477 		uud = sc->sc_uda;
478 		for (i = 0; i < NRSP; i++) {
479 			ud->uda_ca.ca_rspdsc[i] = UDA_OWN|UDA_INT|
480 				(long)&uud->uda_rsp[i].mscp_cmdref;
481 			ud->uda_rsp[i].mscp_dscptr = &ud->uda_ca.ca_rspdsc[i];
482 			ud->uda_rsp[i].mscp_header.uda_msglen = sizeof (struct mscp);
483 		}
484 		for (i = 0; i < NCMD; i++) {
485 			ud->uda_ca.ca_cmddsc[i] = UDA_INT|
486 				(long)&uud->uda_cmd[i].mscp_cmdref;
487 			ud->uda_cmd[i].mscp_dscptr = &ud->uda_ca.ca_cmddsc[i];
488 			ud->uda_cmd[i].mscp_header.uda_msglen = sizeof (struct mscp);
489 		}
490 		bp = &udwtab[d];
491 		bp->av_forw = bp->av_back = bp;
492 		sc->sc_lastcmd = 0;
493 		sc->sc_lastrsp = 0;
494 		if ((mp = udgetcp(um)) == NULL) {
495 			sc->sc_state = S_IDLE;
496 			wakeup(um);
497 			return;
498 		}
499 		mp->mscp_opcode = M_OP_STCON;
500 		mp->mscp_cntflgs = M_CF_ATTN|M_CF_MISC|M_CF_THIS;
501 		*((long *)mp->mscp_dscptr) |= UDA_OWN|UDA_INT;
502 		i = udaddr->udaip;	/* initiate polling */
503 		return;
504 
505 	case S_SCHAR:
506 	case S_RUN:
507 		break;
508 
509 	default:
510 		printf("uda%d: interrupt in unknown state %d ignored\n",
511 			d, sc->sc_state);
512 		return;
513 	}
514 
515 	if (udaddr->udasa&UDA_ERR) {
516 		printf("uda%d: fatal error (%o)\n", d, udaddr->udasa&0xffff);
517 		udaddr->udaip = 0;
518 		wakeup(um);
519 	}
520 
521 	/*
522 	 * Check for a buffer purge request.
523 	 */
524 	if (ud->uda_ca.ca_bdp) {
525 		/*
526 		 * THIS IS A KLUDGE.
527 		 * Maybe we should change the entire
528 		 * UBA interface structure.
529 		 */
530 		int s = spl7();
531 
532 		i = um->um_ubinfo;
533 		printd("uda: purge bdp %d\n", ud->uda_ca.ca_bdp);
534 		um->um_ubinfo = ud->uda_ca.ca_bdp<<28;
535 		ubapurge(um);
536 		um->um_ubinfo = i;
537 		(void) splx(s);
538 		ud->uda_ca.ca_bdp = 0;
539 		udaddr->udasa = 0;	/* signal purge complete */
540 	}
541 
542 	/*
543 	 * Check for response ring transition.
544 	 */
545 	if (ud->uda_ca.ca_rspint) {
546 		ud->uda_ca.ca_rspint = 0;
547 		for (i = sc->sc_lastrsp;; i++) {
548 			i %= NRSP;
549 			if (ud->uda_ca.ca_rspdsc[i]&UDA_OWN)
550 				break;
551 			udrsp(um, ud, sc, i);
552 			ud->uda_ca.ca_rspdsc[i] |= UDA_OWN;
553 		}
554 		sc->sc_lastrsp = i;
555 	}
556 
557 	/*
558 	 * Check for command ring transition.
559 	 */
560 	if (ud->uda_ca.ca_cmdint) {
561 		printd("uda: command ring transition\n");
562 		ud->uda_ca.ca_cmdint = 0;
563 	}
564 	udstart(um);
565 }
566 
567 /*
568  * Process a response packet
569  */
570 udrsp(um, ud, sc, i)
571 	register struct uba_ctlr *um;
572 	register struct uda *ud;
573 	register struct uda_softc *sc;
574 	int i;
575 {
576 	register struct mscp *mp;
577 	struct uba_device *ui;
578 	struct buf *dp, *bp;
579 	int st;
580 
581 	mp = &ud->uda_rsp[i];
582 	mp->mscp_header.uda_msglen = sizeof (struct mscp);
583 	sc->sc_credits += mp->mscp_header.uda_credits & 0xf;
584 	if ((mp->mscp_header.uda_credits & 0xf0) > 0x10)
585 		return;
586 	/*
587 	 * If it's an error log message (datagram),
588 	 * pass it on for more extensive processing.
589 	 */
590 	if ((mp->mscp_header.uda_credits & 0xf0) == 0x10) {
591 		uderror(um, (struct mslg *)mp);
592 		return;
593 	}
594 	if (mp->mscp_unit >= 8)
595 		return;
596 	if ((ui = udip[um->um_ctlr][mp->mscp_unit]) == 0)
597 		return;
598 	st = mp->mscp_status&M_ST_MASK;
599 	switch (mp->mscp_opcode) {
600 	case M_OP_STCON|M_OP_END:
601 		if (st == M_ST_SUCC)
602 			sc->sc_state = S_RUN;
603 		else
604 			sc->sc_state = S_IDLE;
605 		um->um_tab.b_active = 0;
606 		wakeup(um);
607 		break;
608 
609 	case M_OP_ONLIN|M_OP_END:
610 		/*
611 		 * Link the drive onto the controller queue
612 		 */
613 		dp = &udutab[ui->ui_unit];
614 		dp->b_forw = NULL;
615 		if (um->um_tab.b_actf == NULL)
616 			um->um_tab.b_actf = dp;
617 		else
618 			um->um_tab.b_actl->b_forw = dp;
619 		um->um_tab.b_actl = dp;
620 		if (st == M_ST_SUCC) {
621 			ui->ui_flags = 1;	/* mark it online */
622 			radsize[ui->ui_unit] = (daddr_t)mp->mscp_untsize;
623 			printd("uda: unit %d online\n", mp->mscp_unit);
624 		} else {
625 			harderr(dp->b_actf, "ra");
626 			printf("OFFLINE\n");
627 			while (bp = dp->b_actf) {
628 				dp->b_actf = bp->av_forw;
629 				bp->b_flags |= B_ERROR;
630 				iodone(bp);
631 			}
632 		}
633 		dp->b_active = 1;
634 		break;
635 
636 	case M_OP_AVATN:
637 		printd("uda: unit %d attention\n", mp->mscp_unit);
638 		ui->ui_flags = 0;	/* it went offline and we didn't notice */
639 		break;
640 
641 	case M_OP_READ|M_OP_END:
642 	case M_OP_WRITE|M_OP_END:
643 		bp = (struct buf *)mp->mscp_cmdref;
644 		ubarelse(um->um_ubanum, &bp->b_resid);
645 		/*
646 		 * Unlink buffer from I/O wait queue.
647 		 */
648 		bp->av_back->av_forw = bp->av_forw;
649 		bp->av_forw->av_back = bp->av_back;
650 		dp = &udutab[ui->ui_unit];
651 		if (ui->ui_dk >= 0)
652 			if (--dp->b_qsize == 0)
653 				dk_busy &= ~(1<<ui->ui_dk);
654 		if (st == M_ST_OFFLN || st == M_ST_AVLBL) {
655 			ui->ui_flags = 0;	/* mark unit offline */
656 			/*
657 			 * Link the buffer onto the front of the drive queue
658 			 */
659 			if ((bp->av_forw = dp->b_actf) == 0)
660 				dp->b_actl = bp;
661 			dp->b_actf = bp;
662 			/*
663 			 * Link the drive onto the controller queue
664 			 */
665 			if (dp->b_active == 0) {
666 				dp->b_forw = NULL;
667 				if (um->um_tab.b_actf == NULL)
668 					um->um_tab.b_actf = dp;
669 				else
670 					um->um_tab.b_actl->b_forw = dp;
671 				um->um_tab.b_actl = dp;
672 				dp->b_active = 1;
673 			}
674 			return;
675 		}
676 		if (st != M_ST_SUCC) {
677 			harderr(bp, "ra");
678 			printf("status %o\n", mp->mscp_status);
679 			bp->b_flags |= B_ERROR;
680 		}
681 		bp->b_resid = bp->b_bcount - mp->mscp_bytecnt;
682 		iodone(bp);
683 		break;
684 
685 	case M_OP_GTUNT|M_OP_END:
686 		break;
687 
688 	default:
689 		printf("uda: unknown packet\n");
690 	}
691 }
692 
693 
694 /*
695  * Process an error log message
696  *
697  * For now, just log the error on the console.
698  * Only minimal decoding is done, only "useful"
699  * information is printed.  Eventually should
700  * send message to an error logger.
701  */
702 uderror(um, mp)
703 	register struct uba_ctlr *um;
704 	register struct mslg *mp;
705 {
706 	printf("uda%d:%d: %s error, ", um->um_ctlr, mp->mslg_seqnum,
707 		mp->mslg_flags&M_LF_SUCC ? "soft" : "hard");
708 	switch (mp->mslg_format) {
709 	case M_FM_CNTERR:
710 		printf("controller error, event 0%o\n", mp->mslg_event);
711 		break;
712 
713 	case M_FM_BUSADDR:
714 		printf("host memory access error, event 0%o, addr 0%o\n",
715 			mp->mslg_event, *((long *)&mp->mslg_busaddr[0]));
716 		break;
717 
718 	case M_FM_DISKTRN:
719 		printf("disk transfer error, unit %d, grp %d, cyl %d, sec %d, ",
720 			mp->mslg_unit, mp->mslg_group, mp->mslg_cylinder,
721 			mp->mslg_sector);
722 		printf("trk %d, lbn %d, retry %d, level %d\n", mp->mslg_track,
723 			mp->mslg_lbn, mp->mslg_retry, mp->mslg_level);
724 		break;
725 
726 	case M_FM_SDI:
727 		printf("SDI error, unit %d, event 0%o, cyl %d\n", mp->mslg_unit,
728 			mp->mslg_event, mp->mslg_cylinder);
729 		break;
730 
731 	case M_FM_SMLDSK:
732 		printf("small disk error, unit %d, event 0%o, cyl %d\n",
733 			mp->mslg_unit, mp->mslg_event, mp->mslg_sdecyl);
734 		break;
735 
736 	default:
737 		printf("unknown error, unit %d, format 0%o, event 0%o\n",
738 			mp->mslg_unit, mp->mslg_format, mp->mslg_event);
739 	}
740 }
741 
742 
743 /*
744  * Find an unused command packet
745  */
746 struct mscp *
747 udgetcp(um)
748 	struct uba_ctlr *um;
749 {
750 	register struct mscp *mp;
751 	register struct udaca *cp;
752 	register struct uda_softc *sc;
753 	register int i;
754 
755 	cp = &uda[um->um_ctlr].uda_ca;
756 	sc = &uda_softc[um->um_ctlr];
757 	i = sc->sc_lastcmd;
758 	if ((cp->ca_cmddsc[i] & (UDA_OWN|UDA_INT)) == UDA_INT) {
759 		cp->ca_cmddsc[i] &= ~UDA_INT;
760 		mp = &uda[um->um_ctlr].uda_cmd[i];
761 		mp->mscp_unit = mp->mscp_modifier = 0;
762 		mp->mscp_opcode = mp->mscp_flags = 0;
763 		mp->mscp_bytecnt = mp->mscp_buffer = 0;
764 		mp->mscp_errlgfl = mp->mscp_copyspd = 0;
765 		sc->sc_lastcmd = (i + 1) % NCMD;
766 		return(mp);
767 	}
768 	return(NULL);
769 }
770 
771 udread(dev)
772 	dev_t dev;
773 {
774 	register int unit = minor(dev) >> 3;
775 
776 	if (unit >= NRA)
777 		u.u_error = ENXIO;
778 	else
779 		physio(udstrategy, &rudbuf[unit], dev, B_READ, minphys);
780 }
781 
782 udwrite(dev)
783 	dev_t dev;
784 {
785 	register int unit = minor(dev) >> 3;
786 
787 	if (unit >= NRA)
788 		u.u_error = ENXIO;
789 	else
790 		physio(udstrategy, &rudbuf[unit], dev, B_WRITE, minphys);
791 }
792 
793 udreset(uban)
794 	int uban;
795 {
796 	register struct uba_ctlr *um;
797 	register struct uba_device *ui;
798 	register struct buf *bp, *dp;
799 	register int unit;
800 	struct buf *nbp;
801 	int d;
802 
803 	for (d = 0; d < NUDA; d++) {
804 		if ((um = udminfo[d]) == 0 || um->um_ubanum != uban ||
805 		    um->um_alive == 0)
806 			continue;
807 		printf(" uda%d", d);
808 		um->um_tab.b_active = 0;
809 		um->um_tab.b_actf = um->um_tab.b_actl = 0;
810 		uda_softc[d].sc_state = S_IDLE;
811 		for (unit = 0; unit < NRA; unit++) {
812 			if ((ui = uddinfo[unit]) == 0)
813 				continue;
814 			if (ui->ui_alive == 0 || ui->ui_mi != um)
815 				continue;
816 			udutab[unit].b_active = 0;
817 			udutab[unit].b_qsize = 0;
818 		}
819 		for (bp = udwtab[d].av_forw; bp != &udwtab[d]; bp = nbp) {
820 			nbp = bp->av_forw;
821 			ubarelse(uban, &bp->b_ubinfo);
822 			/*
823 			 * Link the buffer onto the drive queue
824 			 */
825 			dp = &udutab[dkunit(bp)];
826 			if (dp->b_actf == 0)
827 				dp->b_actf = bp;
828 			else
829 				dp->b_actl->av_forw = bp;
830 			dp->b_actl = bp;
831 			bp->av_forw = 0;
832 			/*
833 			 * Link the drive onto the controller queue
834 			 */
835 			if (dp->b_active == 0) {
836 				dp->b_forw = NULL;
837 				if (um->um_tab.b_actf == NULL)
838 					um->um_tab.b_actf = dp;
839 				else
840 					um->um_tab.b_actl->b_forw = dp;
841 				um->um_tab.b_actl = dp;
842 				dp->b_active = 1;
843 			}
844 		}
845 		udinit(d);
846 	}
847 }
848 
849 uddump()
850 {
851 	return(ENXIO);
852 }
853