xref: /original-bsd/sys/news3400/iodev/scsi.c (revision d652179b)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: scsi.c,v 4.300 91/06/27 20:42:51 root Rel41 $ SONY
11  *
12  *	@(#)scsi.c	7.1 (Berkeley) 06/04/92
13  */
14 
15 /*
16  *	scsi.c	ver 1.1
17  */
18 
19 #include "../include/fix_machine_type.h"
20 #include "../include/param.h"
21 
22 #include "param.h"
23 #include "buf.h"
24 #include "proc.h"
25 #include "user.h"
26 
27 # include "../include/cpu.h"
28 
29 #include "../hbdev/hbvar.h"
30 #include "../hbdev/scsic.h"
31 #include "../hbdev/screg_1185.h"
32 
33 #include "../iodev/scsireg.h"
34 #include "../iodev/ioptohb.h"
35 
36 #define DEBUG_LOSSBSY_HUNG
37 
38 #ifdef DEBUG_LOSSBSY_HUNG
39 # define PROBE_MAXRETRY	100
40 #endif
41 
42 #ifndef NO_SCSI_DISCONNECT
43 int Scsi_Disconnect = IDT_DISCON;
44 #else
45 int Scsi_Disconnect = 0;
46 #endif
47 
48 # define MAXCTLR	8
49 struct sc_data sc_data[MAXCTLR];
50 struct scintsw scintsw[MAXCTLR];
51 
52 #ifdef RSENSE_MSG_DISP
53 int	rsense_msg_disp = 1;	/* RSENSE-message display flag */
54 #else
55 int	rsense_msg_disp = 0;	/* RSENSE-message display flag */
56 #endif
57 
58 int	mo_disp_format = 0;	/* MO format mode display flag */
59 
60 struct msg_list {
61 	int	ml_code;		/* message code */
62 	int	ml_msglvl;		/* message level */
63 	char	*ml_msgstr;		/* message string */
64 };
65 
66 #ifdef NO_SHRINK_RSENSE_MSG
67 struct msg_list skeylist[] = {
68 	{ 0x00,	1, "No Sense" },
69 	{ 0x01,	0, "Recoverable Error" },
70 	{ 0x02,	0, "Not Ready" },
71 	{ 0x03,	0, "Medium Error" },
72 	{ 0x04,	0, "Hardware Error" },
73 	{ 0x05, 0, "Illegal Request" },
74 	{ 0x06, 1, "Unit Attention" },
75 	{ 0x07,	1, "Data protect" },
76 	{ 0x08, 0, "Blank Check" },
77 	{ 0x09,	0, "Vendor Unique" },
78 	{ 0x0a,	0, "Copy/Compare Aborted" },
79 	{ 0x0b, 0, "Aborted Command" },
80 	{ 0x0c, 0, "Equal" },
81 	{ 0x0d, 0, "Volume Overflow" },
82 	{ 0x0e,	0, "Miscompare" },
83 	{ -1,	0, (caddr_t)0 }
84 };
85 #else /* NO_SHRINK_RSENSE_MSG */
86 struct msg_list skeylist[] = {
87 	{ 0x00,	1, NULL },
88 	{ 0x01,	0, NULL },
89 	{ 0x02,	0, NULL },
90 	{ 0x03,	0, NULL },
91 	{ 0x04,	0, NULL },
92 	{ 0x05, 0, NULL },
93 	{ 0x06, 1, NULL },
94 	{ 0x07,	1, NULL },
95 	{ 0x08, 0, NULL },
96 	{ 0x09,	0, NULL },
97 	{ 0x0a,	0, NULL },
98 	{ 0x0b, 0, NULL },
99 	{ 0x0c, 0, NULL },
100 	{ 0x0d, 0, NULL },
101 	{ 0x0e,	0, NULL },
102 	{ -1,	0, NULL }
103 };
104 #endif /* NO_SHRINK_RSENSE_MSG */
105 
106 #ifdef NO_SHRINK_RSENSE_MSG
107 struct msg_list ecodelist[] = {
108 	{ 0x00, 9, "No Additional Sense Information" },
109 /*HD*/	{ 0x01, 1, "No Index/Address Mark Found signal" },
110 	{ 0x02, 0, "No Seek Complete" },
111 	{ 0x03, 0, "Write Fault" },
112 	{ 0x04, 9, "Drive Not Ready" },
113 	{ 0x05, 0, "Drive Not Selected" },
114 /*HD*/	{ 0x06, 0, "No Track Zero" },
115 	{ 0x07, 0, "Multiple Drives Selected" },
116 	{ 0x08, 0, "Logical Unit Communication Failure" },
117 	{ 0x09, 2, "Track Following Error" },
118 /*MO*/	{ 0x0a, 1, "No Disk" },
119 /*MO*/	{ 0x0b, 1, "Load/Unload Failure" },
120 /*MO*/	{ 0x0c, 1, "Spindle Failure" },
121 /*MO*/	{ 0x0d, 1, "Focus Failure" },
122 /*MO*/	{ 0x0e, 1, "Tracking Failure" },
123 /*MO*/	{ 0x0f, 0, "Drive Initialization Failure" },
124 	{ 0x10, 1, "ID CRC or ECC error" },
125 	{ 0x11, 0, "Unrecoverd Read error" },
126 /*HD*/	{ 0x12, 0, "No Address Mark (byte sync byte) found in ID field" },
127 /*HD*/	{ 0x13, 0, "No Address Mark (byte sync byte) found in Data field" },
128 /*HD*/	{ 0x14, 0, "No record found" },
129 	{ 0x15, 1, "Seek Positioning Error" },
130 
131 /*HD*/	{ 0x17, 0, "Recovered Read data with Read retries" },
132 	{ 0x18, 0, "Recovered Read data with ECC procedure" },
133 /*HD*/	{ 0x19, 0, "Defect List error" },
134 /*HD*/	{ 0x1a, 0, "Parameter overrun" },
135 /*HD*/	{ 0x1b, 0, "Synchronous transfer error" },
136 /*HD*/	{ 0x1c, 0, "Primary Defect List not found" },
137 /*HD*/	{ 0x1d, 0, "Compare error" },
138 
139 	{ 0x20, 0, "Invalid Command Operation Code" },
140 	{ 0x21, 0, "Illegal Logical Block Address" },
141 /*HD*/	{ 0x22, 0, "Illegal function for device type" },
142 /*MO*/	{ 0x23, 0, "Illegal function for Medium Type" },
143 	{ 0x24, 0, "Illegal Field in CDB" },
144 	{ 0x25, 0, "Invalid LUN" },
145 	{ 0x26, 0, "Invalid field in Parameter List" },
146 	{ 0x27, 0, "Write Protected" },
147 	{ 0x28, 1, "Medium Changed" },
148 	{ 0x29, 1, "Power On or Reset or Bus Device Reset Occured" },
149 	{ 0x2a, 1, "Mode Select Parameters Changed" },
150 /*HD*/	{ 0x2b, 0, "Host cannot Disconnect" },
151 
152 	{ 0x31, 0, "Medium Format Corrupted" },
153 	{ 0x32, 0, "No Defect Spare Location Available" },
154 
155 /*MO*/	{ 0x38, 1, "Recovered with Automatic Reallocation" },
156 /*MO*/	{ 0x39, 0, "Automatic Reallocation Failure" },
157 /*MO*/	{ 0x3a, 1, "Defect List Update Failure" },
158 
159 /*MO*/	{ 0x3d, 0, "Defect List Not Available" },
160 
161 /*HD*/	{ 0x40, 0, "RAM failure" },
162 /*HD*/	{ 0x41, 0, "Data Path diagnostic failure" },
163 	{ 0x42, 0, "Power On Diagnostic Failure" },
164 	{ 0x43, 0, "Message Reject Error" },
165 	{ 0x44, 9, "Internal Controller Error" },
166 /*HD*/	{ 0x45, 0, "Selection/Reselection failure" },
167 
168 	{ 0x47, 0, "SCSI Interface Parity Error" },
169 	{ 0x48, 0, "Initiator Detected Error" },
170 	{ 0x49, 0, "Inappropriate/Illegal Message" },
171 
172 	{ 0x64, 1, "Illegal mode for this track" },
173 
174 	{ -1,   0, (caddr_t)0 }
175 };
176 #else /* NO_SHRINK_RSENSE_MSG */
177 struct msg_list ecodelist[] = {
178 	{ 0x00, 9, NULL },
179 /*HD*/	{ 0x01, 1, NULL },
180 	{ 0x02, 0, NULL },
181 	{ 0x03, 0, NULL },
182 	{ 0x04, 9, NULL },
183 	{ 0x05, 0, NULL },
184 /*HD*/	{ 0x06, 0, NULL },
185 	{ 0x07, 0, NULL },
186 	{ 0x08, 0, NULL },
187 	{ 0x09, 2, NULL },
188 /*MO*/	{ 0x0a, 1, NULL },
189 /*MO*/	{ 0x0b, 1, NULL },
190 /*MO*/	{ 0x0c, 1, NULL },
191 /*MO*/	{ 0x0d, 1, NULL },
192 /*MO*/	{ 0x0e, 1, NULL },
193 /*MO*/	{ 0x0f, 0, NULL },
194 	{ 0x10, 1, NULL },
195 	{ 0x11, 0, NULL },
196 /*HD*/	{ 0x12, 0, NULL },
197 /*HD*/	{ 0x13, 0, NULL },
198 /*HD*/	{ 0x14, 0, NULL },
199 	{ 0x15, 1, NULL },
200 
201 /*HD*/	{ 0x17, 0, NULL },
202 	{ 0x18, 0, NULL },
203 /*HD*/	{ 0x19, 0, NULL },
204 /*HD*/	{ 0x1a, 0, NULL },
205 /*HD*/	{ 0x1b, 0, NULL },
206 /*HD*/	{ 0x1c, 0, NULL },
207 /*HD*/	{ 0x1d, 0, NULL },
208 
209 	{ 0x20, 0, NULL },
210 	{ 0x21, 0, NULL },
211 /*HD*/	{ 0x22, 0, NULL },
212 /*MO*/	{ 0x23, 0, NULL },
213 	{ 0x24, 0, NULL },
214 	{ 0x25, 0, NULL },
215 	{ 0x26, 0, NULL },
216 	{ 0x27, 0, NULL },
217 	{ 0x28, 1, NULL },
218 	{ 0x29, 1, NULL },
219 	{ 0x2a, 1, NULL },
220 /*HD*/	{ 0x2b, 0, NULL },
221 
222 	{ 0x31, 0, NULL },
223 	{ 0x32, 0, NULL },
224 
225 /*MO*/	{ 0x38, 1, NULL },
226 /*MO*/	{ 0x39, 0, NULL },
227 /*MO*/	{ 0x3a, 1, NULL },
228 
229 /*MO*/	{ 0x3d, 0, NULL },
230 
231 /*HD*/	{ 0x40, 0, NULL },
232 /*HD*/	{ 0x41, 0, NULL },
233 	{ 0x42, 0, NULL },
234 	{ 0x43, 0, NULL },
235 	{ 0x44, 9, NULL },
236 /*HD*/	{ 0x45, 0, NULL },
237 
238 	{ 0x47, 0, NULL },
239 	{ 0x48, 0, NULL },
240 	{ 0x49, 0, NULL },
241 
242 	{ 0x64, 1, NULL },
243 
244 	{ -1,   0, NULL }
245 };
246 #endif /* NO_SHRINK_RSENSE_MSG */
247 
248 /*
249  * Init a scsi bus.
250  */
251 scop_init(scn)
252 	int	scn;
253 {
254 	static struct scsi sc;
255 	int chan;
256 
257 	for (chan = 0; chan < MAXCTLR; chan++) {
258 		bzero((caddr_t)&sc, sizeof(struct scsi));
259 		sc.sc_cdb.un_reserved[0] = SCOP_RESET;
260 		sc.sc_cdb.un_reserved[1] = SCOP_RESET;
261 
262 		if (!sc_busy(chan)) {
263 			sc_go(chan, (struct scsi *)&sc, SCSI_INTDIS);
264 
265 			chan = (chan / 8 + 1) * 8;
266 		}
267 	}
268 }
269 
270 /**************************************
271 	The multiple scsi bus is NOT suported by following routines.
272 	How about use inter like dev_t ( uper is scsi#, lower is inter )
273 	or hb_ctlr.
274 	probe() ga futatuarukara unit# ----- udauda.
275 **************************************/
276 
277 /*
278  * scprobe. probe routine for mass storage controller.
279  */
280 scprobe(im, ctlrintr, sc)
281 	struct iop/**/_ctlr *im;
282 	int (*ctlrintr)();
283 	register struct scsi *sc;
284 {
285 	register struct scintsw *sci;
286 	int s;
287 #ifdef DEBUG_LOSSBSY_HUNG
288 	int retry = 0;
289 #endif DEBUG_LOSSBSY_HUNG
290 
291 	sci = &scintsw[im->im_intr];
292 	if (sci->sci_inthandler)
293 		return (0);
294 
295 #ifdef DEBUG_LOSSBSY_HUNG
296 scprobe_loop:
297 	/* s = splsc(); */
298 	scop_inquiry(im->im_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0);
299 	/* splx(s); */
300 
301 	if (sc->sc_istatus != INST_EP) {
302 		if ((sc->sc_tstatus == TGST_BUSY) && (retry++ < PROBE_MAXRETRY)) {
303 			goto scprobe_loop;
304 		}
305 		return (0);
306 	}
307 
308 #else /* DEBUG_LOSSBSY_HUNG */
309 
310 	/* s = splsc(); */
311 	scop_inquiry(im->im_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0);
312 	/* splx(s); */
313 
314 	if (sc->sc_istatus != INST_EP)
315 		return (0);
316 
317 #endif /* DEBUG_LOSSBSY_HUNG */
318 
319 	sci->sci_inthandler = ctlrintr;
320 	sci->sci_ctlr = im->im_ctlr;
321 	return (1);
322 }
323 
324 /*
325  * ssprobe. probe routine for non-mass storage peripherals.
326  */
327 ssprobe(ii, ctlrintr, sc)
328 	struct iop/**/_device *ii;
329 	int (*ctlrintr)();
330 	register struct scsi *sc;
331 {
332 	register struct scintsw *sci;
333 	int s;
334 
335 	sci = &scintsw[ii->ii_intr];
336 	if (sci->sci_inthandler)
337 		return (0);
338 
339 	/* s = splsc(); */
340 	scop_inquiry(ii->ii_intr, sc, 0, SCSI_INTDIS, 4, (caddr_t)0);
341 	/* splx(s); */
342 
343 	if (sc->sc_istatus != INST_EP)
344 		return (0);
345 
346 	sci->sci_inthandler = ctlrintr;
347 	sci->sci_ctlr = ii->ii_unit;
348 	return (1);
349 }
350 
351 /*
352  * SCOP_TST request
353  */
354 scop_tst(intr, sc, slave, ie)
355 	register int intr;
356 	register struct scsi *sc;
357 	register int slave;
358 	register int ie;
359 {
360 	scinit(sc, slave, DEV_BSIZE);
361 
362 	/* sc_cdb */
363 	sc->sc_opcode = SCOP_TST;
364 
365 	sc_go(intr, (struct scsi *)sc, ie);
366 }
367 
368 /*
369  * SCOP_REZERO request
370  */
371 scop_rezero(intr, sc, slave, ie)
372 	register int intr;
373 	register struct scsi *sc;
374 	register int slave;
375 	register int ie;
376 {
377 	scinit(sc, slave, DEV_BSIZE);
378 
379 	/* sc_cdb */
380 	sc->sc_opcode = SCOP_REZERO;
381 
382 	sc_go(intr, (struct scsi *)sc, ie);
383 }
384 
385 /*
386  * SCOP_REWIND request
387  */
388 scop_rewind(intr, sc, slave, ie, imme)
389 	register int intr;
390 	register struct scsi *sc;
391 	register int slave;
392 	register int ie, imme;
393 {
394 	scinit(sc, slave, DEV_BSIZE);
395 
396 	/* sc_cdb */
397 	sc->sc_opcode = SCOP_REZERO;
398 	sc->sc_tucode = imme;
399 
400 	sc_go(intr, (struct scsi *)sc, ie);
401 }
402 
403 /*
404  * SCOP_RSENSE request
405  */
406 scop_rsense(intr, sc, slave, ie, count, param)
407 	register int intr;
408 	register struct scsi *sc;
409 	register int slave;
410 	register int ie;
411 	register int count;
412 	register caddr_t param;
413 {
414 	scinit(sc, slave, DEV_BSIZE);
415 
416 	sc->sc_cpoint = (u_char *)param;
417 	sc->sc_ctrnscnt = count;
418 
419 	/* sc_cdb */
420 	sc->sc_opcode = SCOP_RSENSE;
421 	sc->sc_count = count;
422 
423 	sc_go(intr, (struct scsi *)sc, ie);
424 }
425 
426 /*
427  * SCOP_RASBLK request
428  */
429 scop_rasblk(intr, sc, slave, ie, lad)
430 	register int intr;
431 	register struct scsi *sc;
432 	register int slave;
433 	register int ie;
434 	register int lad;
435 {
436 	struct sc_rab *sca = (struct sc_rab *)sc->sc_param;
437 
438 	scinit(sc, slave, DEV_BSIZE);
439 
440 	sca->sca_dllen = 4;
441 	sca->sca_dlad[0] = lad;
442 	sc->sc_cpoint = (u_char *)sca;
443 
444 	sc->sc_ctrnscnt = 8;
445 
446 	/* sc_cdb */
447 	sc->sc_opcode = SCOP_RASBLK;
448 
449 	sc_go(intr, (struct scsi *)sc, ie);
450 }
451 
452 /*
453  * SCOP_MERASE request
454  */
455 scop_merase(intr, sc, slave, ie, count)
456 	register int intr;
457 	register struct scsi *sc;
458 	register int slave;
459 	register int ie;
460 	register int count;
461 {
462 	scinit(sc, slave, DEV_BSIZE);
463 
464 	/* sc_cdb */
465 	sc->sc_opcode = SCOP_MERASE;
466 	sc->sc_mtcount3 = count;
467 
468 	sc_go(intr, (struct scsi *)sc, ie);
469 }
470 
471 /*
472  * SCOP_WFMARK request
473  */
474 scop_wfmark(intr, sc, slave, ie, count)
475 	register int intr;
476 	register struct scsi *sc;
477 	register int slave;
478 	register int ie;
479 	register int count;
480 {
481 	scinit(sc, slave, DEV_BSIZE);
482 
483 	/* sc_cdb */
484 	sc->sc_opcode = SCOP_WFMARK;
485 	count &= 0xffffff;
486 	sc->sc_tucount3 = count & 0xff;
487 	count >>= 8;
488 	sc->sc_tucount2 = count & 0xff;
489 	count >>= 8;
490 	sc->sc_tucount1 = count & 0xff;
491 
492 	sc_go(intr, (struct scsi *)sc, ie);
493 }
494 
495 /*
496  * SCOP_SPACE request
497  */
498 scop_space(intr, sc, slave, ie, count, code)
499 	register int intr;
500 	register struct scsi *sc;
501 	register int slave;
502 	register int ie;
503 	register int count;
504 	register int code;
505 {
506 	scinit(sc, slave, DEV_BSIZE);
507 
508 	/* sc_cdb */
509 	sc->sc_opcode = SCOP_SPACE;
510 	sc->sc_tucode = code;
511 	count &= 0xffffff;
512 	sc->sc_tucount3 = count & 0xff;
513 	count >>= 8;
514 	sc->sc_tucount2 = count & 0xff;
515 	count >>= 8;
516 	sc->sc_tucount1 = count & 0xff;
517 
518 	sc_go(intr, (struct scsi *)sc, ie);
519 }
520 
521 /*
522  * SCOP_INQUIRY request
523  */
524 scop_inquiry(intr, sc, slave, ie, count, param)
525 	register int intr;
526 	register struct scsi *sc;
527 	register int slave;
528 	register int ie;
529 	register int count;
530 	register caddr_t param;
531 {
532 	scinit(sc, slave, DEV_BSIZE);
533 
534 	sc->sc_cpoint = (u_char *)param;
535 	sc->sc_ctrnscnt = count;
536 
537 	/* sc_cdb */
538 	sc->sc_opcode = SCOP_INQUIRY;
539 	sc->sc_count = count;
540 
541 	sc_go(intr, (struct scsi *)sc, ie);
542 }
543 
544 /*
545  * SCOP_STST request
546  */
547 scop_stst(intr, sc, slave, ie, sw)
548 	register int intr;
549 	register struct scsi *sc;
550 	register int slave;
551 	register int ie;
552 	register int sw;
553 {
554 	scinit(sc, slave, DEV_BSIZE);
555 
556 	/* sc_cdb */
557 	sc->sc_opcode = SCOP_STST;
558 	sc->sc_switch = sw;
559 
560 	sc_go(intr, (struct scsi *)sc, ie);
561 }
562 
563 /*
564  * SCOP_RCAP request
565  */
566 scop_rcap(intr, sc, slave, ie, count, param)
567 	register int intr;
568 	register struct scsi *sc;
569 	register int slave;
570 	register int ie;
571 	register int count;
572 	register caddr_t param;
573 {
574 	scinit(sc, slave, DEV_BSIZE);
575 
576 	sc->sc_cpoint = (u_char *)param;
577 	sc->sc_ctrnscnt = count;
578 
579 	/* sc_cdb */
580 	sc->sc_opcode = SCOP_RCAP;
581 	sc->sc_pmi = OFF;
582 
583 	sc_go(intr, (struct scsi *)sc, ie);
584 }
585 
586 /*
587  * SCOP_BSSRCH request
588  */
589 scop_bssrch(intr, sc, slave, ie, count, param)
590 	register int intr;
591 	register struct scsi *sc;
592 	register int slave;
593 	register int ie;
594 	register int count;
595 	register caddr_t param;
596 {
597 	scinit(sc, slave, DEV_BSIZE);
598 
599 	sc->sc_cpoint = (u_char *)param;
600 	sc->sc_ctrnscnt = count;
601 
602 	/* sc_cdb */
603 	sc->sc_opcode = SCOP_BSSRCH;
604 	sc->sc_ladhi = *(short *)param;
605 	sc->sc_ladlo = *(short *)(param + 2);
606 
607 	sc_go(intr, (struct scsi *)sc, ie);
608 }
609 
610 /*
611  * SCOP_WSSRCH request
612  */
613 scop_wssrch(intr, sc, slave, ie, count, param)
614 	register int intr;
615 	register struct scsi *sc;
616 	register int slave;
617 	register int ie;
618 	register int count;
619 	register caddr_t param;
620 {
621 	scinit(sc, slave, DEV_BSIZE);
622 
623 	sc->sc_cpoint = (u_char *)param;
624 	sc->sc_ctrnscnt = count;
625 
626 	/* sc_cdb */
627 	sc->sc_opcode = SCOP_WSSRCH;
628 	sc->sc_ladhi = *(short *)param;
629 	sc->sc_ladlo = *(short *)(param + 2);
630 
631 	sc_go(intr, (struct scsi *)sc, ie);
632 }
633 
634 /*
635  *
636  * SCOP_EESENSE request
637  * Enable/Disable Eject Request Sense
638  * Write Once only supported.
639  *
640  */
641 scop_eesense(intr, sc, slave, ie, sw)
642 	register int intr;
643 	register struct scsi *sc;
644 	register int slave;
645 	register int ie;
646 	register int sw;
647 {
648 	scinit(sc, slave, DEV_BSIZE);
649 
650 	/* sc_cdb */
651 	sc->sc_opcode = SCOP_EESENSE;
652 	sc->sc_switch = sw;
653 
654 	sc_go(intr, (struct scsi *)sc, ie);
655 }
656 
657 /*
658  * SCOP_EJECT
659  */
660 scop_eject(intr, sc, slave, ie)
661 	register int intr;
662 	register struct scsi *sc;
663 	register int slave;
664 	register int ie;
665 {
666 	scinit(sc, slave, DEV_BSIZE);
667 
668 	/* sc_cdb */
669 	sc->sc_opcode = SCOP_EJECT;
670 
671 	sc_go(intr, (struct scsi *)sc, ie);
672 }
673 
674 /*
675  * SCOP_RBLIM request
676  */
677 scop_rblim(intr, sc, slave, ie, count, param)
678 	register int intr;
679 	register struct scsi *sc;
680 	register int slave;
681 	register int ie;
682 	register int count;
683 	register caddr_t param;
684 {
685 	scinit(sc, slave, DEV_BSIZE);
686 
687 	sc->sc_cpoint = (u_char *)param;
688 	sc->sc_ctrnscnt = count & 0xff;
689 
690 	/* sc_cdb */
691 	sc->sc_opcode = SCOP_RBLIM;
692 
693 	sc_go(intr, (struct scsi *)sc, ie);
694 }
695 
696 /*
697  * SCOP_MSENSE request
698  */
699 scop_msense(intr, sc, slave, ie, count, param)
700 	register int intr;
701 	register struct scsi *sc;
702 	register int slave;
703 	register int ie;
704 	register int count;
705 	register caddr_t param;
706 {
707 	scinit(sc, slave, DEV_BSIZE);
708 
709 	sc->sc_cpoint = (u_char *)param;
710 	sc->sc_ctrnscnt = count & 0xff;
711 
712 	/* sc_cdb */
713 	sc->sc_opcode = SCOP_MSENSE;
714 	sc->sc_lad = count >> 8;
715 	sc->sc_count = count & 0xff;
716 
717 	sc_go(intr, (struct scsi *)sc, ie);
718 }
719 
720 /*
721  * SCOP_MSELECT request
722  */
723 scop_mselect(intr, sc, slave, ie, count, param)
724 	register int intr;
725 	register struct scsi *sc;
726 	register int slave;
727 	register int ie;
728 	register int count;
729 	register caddr_t param;
730 {
731 	u_char psave[20];
732 
733 	bcopy((caddr_t)sc->sc_param, (caddr_t)psave, 20);
734 	scinit(sc, slave, DEV_BSIZE);
735 	bcopy((caddr_t)psave, (caddr_t)sc->sc_param, 20);
736 
737 	sc->sc_cpoint = (u_char *)param;
738 	sc->sc_ctrnscnt = count & 0xff;
739 
740 	/* sc_cdb */
741 	sc->sc_opcode = SCOP_MSELECT;
742 	sc->sc_lad = count >> 8;
743 	sc->sc_count = count & 0xff;
744 
745 	sc_go(intr, (struct scsi *)sc, ie);
746 }
747 
748 #ifdef SRD_MSELECT
749 /*
750  * SCOP_MSELECT request
751  */
752 scop_msense_OTHER_HD(intr, sc, slave, ie, count, param)
753 	register int intr;
754 	register struct scsi *sc;
755 	register int slave;
756 	register int ie;
757 	register int count;
758 	register caddr_t param;
759 {
760 	scinit(sc, slave, DEV_BSIZE);
761 
762 	sc->sc_cpoint = (u_char *)param;
763 	sc->sc_ctrnscnt = count;
764 
765 	/* sc_cdb */
766 	sc->sc_opcode = SCOP_MSENSE;
767 	sc->sc_count = count;
768 	sc->sc_lad = 0x3f00;
769 
770 	sc_go(intr, (struct scsi *)sc, ie);
771 }
772 
773 /*
774  * SCOP_MSELECT request
775  */
776 scop_mselect_OTHER_HD(intr, sc, slave, ie, count, param)
777 	register int intr;
778 	register struct scsi *sc;
779 	register int slave;
780 	register int ie;
781 	register int count;
782 	register caddr_t param;
783 {
784 	u_char psave[20];
785 
786 	bcopy((caddr_t)sc->sc_param, (caddr_t)psave, 20);
787 	scinit(sc, slave, DEV_BSIZE);
788 	bcopy((caddr_t)psave, (caddr_t)sc->sc_param, 20);
789 
790 	sc->sc_cpoint = (u_char *)param;
791 	sc->sc_ctrnscnt = count;
792 
793 	/* sc_cdb */
794 	sc->sc_opcode = SCOP_MSELECT;
795 	sc->sc_count = count;
796 	sc->sc_lad = 0;
797 
798 	sc_go(intr, (struct scsi *)sc, ie);
799 }
800 #endif SRD_MSELECT
801 
802 scop_erase(intr, sc, slave, ie)
803 	register int intr;
804 	register struct scsi *sc;
805 	register int slave;
806 	register int ie;
807 {
808 	scinit(sc, slave, DEV_BSIZE);
809 
810 	/* sc_cdb */
811 	sc->sc_opcode = SCOP_ERASE;
812 	sc->sc_tucode = 1;
813 
814 	sc_go(intr, (struct scsi *)sc, ie);
815 }
816 
817 /*
818  * One sector programmed I/O
819  */
820 scop_rdwr(intr, sc, slave, ie, flag, addr, lba, sectsize)
821 	int	intr;
822 	register struct scsi	*sc;
823 	int	slave;
824 	int	ie;
825 	int	flag;
826 	caddr_t	addr;
827 	int	lba;
828 	int	sectsize;
829 {
830 	scinit(sc, slave, sectsize);
831 
832 	sc->sc_cpoint = (u_char *)addr;
833 	sc->sc_ctrnscnt = sectsize;
834 
835 	/* sc_cdb */
836 	sc->sc_opcode = (flag & B_READ) ? SCOP_READ : SCOP_WRITE;
837 	sc->sc_lad = lba;
838 	sc->sc_count = 1;
839 
840 	sc_go(intr, sc, ie);
841 }
842 
843 /*
844  * Medium allow/prevent removable
845  */
846 scop_medrmv(intr, sc, slave, ie, sw)
847 	register int intr;
848 	register struct scsi *sc;
849 	register int slave;
850 	register int ie;
851 	register int sw;
852 {
853 	scinit(sc, slave, DEV_BSIZE);
854 
855 	/* sc_cdb */
856 	sc->sc_opcode = SCOP_MEDRMV;
857 	sc->sc_count = sw;
858 
859 	sc_go(intr, (struct scsi *)sc, ie);
860 }
861 
862 /*
863  * initialize struct scsi
864  */
865 scinit(sc, slave, sectsize)
866 	register struct scsi *sc;
867 	int	slave;
868 	int	sectsize;
869 {
870 	bzero((caddr_t)sc, sizeof(struct scsi));
871 
872 	sc->sc_identify = MSG_IDENT|Scsi_Disconnect|(slave & IDT_DRMASK);
873 	sc->sc_bytesec = sectsize;
874 	sc->sc_lun = slave;
875 }
876 
877 
878 /*
879  * ABORT MESSAGE
880  */
881 scms_abort(intr, sc, slave, ie)
882 	register int intr;
883 	register struct scsi *sc;
884 	register int slave;
885 	register int ie;
886 {
887 	bzero((caddr_t)sc, sizeof(struct scsi));
888 
889 	sc->sc_identify = MSG_ABORT;
890 
891 	/* sc_cdb */
892 	sc->sc_opcode = SCOP_TST;
893 	sc->sc_lun = slave;
894 
895 	sc_go(intr, (struct scsi *)sc, ie);
896 }
897 
898 sc_go(intr, sc, ie)
899 	int intr;
900 	struct scsi *sc;
901 	int ie;
902 {
903 	register struct sc_data *scdp;
904 
905 	scdp = &sc_data[intr];
906 
907 	if (sc->sc_cpoint)
908 		scdp->scd_vaddr = (char *)sc->sc_cpoint;
909 	else
910 		scdp->scd_vaddr = (char *)sc->sc_param;
911 	scdp->scd_procp = curproc;
912 	scdp->scd_scaddr = (char *)sc;
913 	scdp->scd_count = sc->sc_ctrnscnt;
914 	sc->sc_cpoint = (u_char *)ipc_phys(scdp->scd_vaddr);
915 
916 	_sc_go(intr, sc, ie);
917 
918 	if((ie & SCSI_INTEN) == 0) {
919 #ifdef mips
920 	/* if (DATAIN_PHASE_FINISHED) */
921 	MachFlushDCache(scdp->scd_scaddr, sizeof (struct scsi));
922 	if (MACH_IS_USPACE(scdp->scd_vaddr))
923 		panic("sc_go: user address is not supported");
924 	else if (MACH_IS_CACHED(scdp->scd_vaddr))
925 		MachFlushDCache(scdp->scd_vaddr, scdp->scd_count);
926 	else if (MACH_IS_MAPPED(scdp->scd_vaddr))
927 #ifdef notyet /* KU:XXX */
928 		clean_k2dcache(scdp->scd_vaddr, scdp->scd_count);
929 #else
930 		MachFlushCache(); /* Flush all caches */
931 #endif
932 #endif /* mips */
933 	}
934 }
935 
936 #ifdef CPU_SINGLE
937 _sc_go(intr, sc, ie)
938 	int intr;
939 	struct scsi *sc;
940 	int ie;
941 {
942 	register int i, s;
943 
944 	if((ie & SCSI_INTEN) == 0) {
945 		scsend(intr, ie|SCSI_NOTWAIT, sc);
946 		while (sc_busy(intr)) {
947 			splx(splscon());	/* splsc -1 */
948 #ifdef mc68030
949 			dcia();
950 #endif
951 		}
952 	} else {
953 		scsend(intr, ie, (caddr_t)sc);
954 	}
955 }
956 #endif /* CPU_SINGLE */
957 
958 screset(chan)
959 	int chan;
960 {
961 	int i, s;
962 
963 	s = splsc();
964 	printf("SCSI: screset() called ");
965 	scop_init(chan / 8);
966 	splx(s);
967 
968 	for (s = 0; s < 10; s++) {
969 		DELAY(100000 * 10);
970 	}
971 	printf("\n");
972 	iop/**/reset();
973 }
974 
975 scsisetup(bp, map, nmap)
976 	struct buf *bp;
977 	struct sc_map *map;
978 	int nmap;
979 {
980 	return (iop/**/setup(bp, map, nmap));
981 }
982 
983 
984 /*
985  * transrate skey / ecode into message display ON/OFF value
986  *	1 : display message
987  *	0 : silence
988  */
989 isdispmsg(code, list, count)
990 	register int code;
991 	register struct msg_list *list;
992 	int count;
993 {
994 	register int msglvl = 0;
995 
996 	while (list->ml_code >= 0) {
997 		if (code == list->ml_code) {
998 			msglvl = list->ml_msglvl;
999 			break;
1000 		}
1001 		list++;
1002 	}
1003 	return (count >= msglvl);
1004 }
1005 
1006 #ifdef NO_SHRINK_RSENSE_MSG
1007 /*
1008  * transrate skey / ecode into message
1009  */
1010 char *
1011 getmsg(code, list, defmsg)
1012 	int code;
1013 	struct msg_list *list;
1014 	char *defmsg;
1015 {
1016 	while (list->ml_code >= 0) {
1017 		if (code == list->ml_code)
1018 			return (list->ml_msgstr);
1019 		list++;
1020 	}
1021 	return (defmsg);
1022 }
1023 #endif /* NO_SHRINK_RSENSE_MSG */
1024 
1025 check_chan_busy(intr, sc, slave)
1026 	register int intr;
1027 	register struct scsi *sc;
1028 	register int slave;
1029 {
1030 	register struct sc_extnd *sce = (struct sc_extnd *)sc->sc_param;
1031 	int	i = 0;
1032 
1033 	if (sc->sc_istatus == INST_EP) {
1034 		switch (sc->sc_tstatus) {
1035 
1036 		case TGST_CC:
1037 			scop_rsense(intr, sc, slave, SCSI_INTDIS, 18, 0);
1038 			if (rsense_msg_disp ||
1039 			    isdispmsg(sce->sce_skey, skeylist, 0)) {
1040 #ifdef NO_SHRINK_RSENSE_MSG
1041 				if (sce->sce_advalid) {
1042 					printf("SCSI%d(block %d): %s (sense key = 0x%x)\n",
1043 					intr,
1044 					(sce->sce_infob1 << 24) +
1045 					(sce->sce_infob2 << 16) +
1046 					(sce->sce_infob3 <<  8) +
1047 					(sce->sce_infob4),
1048 					getmsg(sce->sce_skey, skeylist, "(reserved)"),
1049 					sce->sce_skey);
1050 				} else {
1051 					printf("SCSI%d(unknown block): %s (sense key = 0x%x)\n",
1052 					intr,
1053 					getmsg(sce->sce_skey, skeylist, "(reserved)"),
1054 					sce->sce_skey);
1055 				}
1056 #else /* NO_SHRINK_RSENSE_MSG */
1057 				if (sce->sce_advalid) {
1058 					printf("SCSI%d(sn %d): skey=0x%x)\n",
1059 					intr,
1060 					(sce->sce_infob1 << 24) +
1061 					(sce->sce_infob2 << 16) +
1062 					(sce->sce_infob3 <<  8) +
1063 					(sce->sce_infob4),
1064 					sce->sce_skey);
1065 				} else {
1066 					printf("SCSI%d: skey=0x%x)\n",
1067 					intr, sce->sce_skey);
1068 				}
1069 #endif /* NO_SHRINK_RSENSE_MSG */
1070 				printf("sense data = ");
1071 				for (i = 0; i < 18; i++)
1072 					printf("%x ", sc->sc_param[i]);
1073 				printf("\n");
1074 			}
1075 			break;
1076 
1077 		case TGST_GOOD:
1078 			break;
1079 
1080 		default:
1081 			printf("SCSI%d: bad target status 0x%x\n", intr, sc->sc_tstatus);
1082 			break;
1083 		}
1084 	} else {
1085 		printf("SCSI%d: bad initiator status 0x%x\n", intr, sc->sc_istatus);
1086 	}
1087 
1088 	while (i++ < 100000) {
1089 		scop_tst(intr, sc, slave, SCSI_INTDIS);
1090 		if (sc->sc_tstatus != TGST_BUSY)
1091 			break;
1092 	}
1093 	if (i > 100000)
1094 		printf("SCSI%d: still busy after rasblk.\n", intr);
1095 }
1096 
1097 /***/
1098 struct scsi_berr_bug_table {
1099 	int model;
1100 	int serial_l;
1101 	int serial_h;
1102 	int value;	/* 1:BUG, 0:NOBUG */
1103 };
1104 
1105 /***/
1106