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