1 /*
2 * Copyright (c) 1992 OMRON Corporation.
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * OMRON Corporation.
8 *
9 * %sccs.include.redist.c%
10 *
11 * @(#)sc.c 8.2 (Berkeley) 12/06/93
12 */
13
14 /*
15 * sc.c -- FUJITSU MB89352 SCSI Protocole Controller (SPC) Device Driver
16 *
17 * remaked by A.Fujita, Mar-22-1992
18 * remaked again by A.Fujita, Apr-16-1992
19 */
20
21 #define DEBUG_FUNC
22
23 #include "sc.h"
24 #if NSC > 0
25
26 #include <sys/param.h>
27 #include <sys/systm.h>
28 #include <sys/buf.h>
29
30 #include <luna68k/dev/device.h>
31 #include <luna68k/dev/screg.h>
32 #include <luna68k/dev/scvar.h>
33
34 /*
35 * SC Driver Options
36 */
37
38 #define QUADBYTES /* 4 bytes access to SPC DREG Reg. */
39 #define NODISCONNECT /* not used SCSI DISCONNECT Ops. */
40 #undef XFER_ENABLE /* using interrupt for DREG access */
41
42
43 #define SCSI_IPL 2
44 #define SCSI_ID 7
45
46 extern char *hexstr();
47
48 int scinit(), scstart(), scintr();
49 void screset();
50 struct driver scdriver = {
51 scinit, "sc", scstart, (int (*)()) 0, scintr, (int (*)()) 0
52 };
53
54 struct sc_softc sc_softc[NSC];
55
56
57 #define SC_TIMEOUT 0x01400000 /* (20971520) */
58
59
60 /*
61 * for DEBUG
62 */
63
64 char *
scsi_status(stat)65 scsi_status(stat)
66 u_char stat;
67 {
68 if ((stat & 0x1e) == 0)
69 return("Good");
70 else if ((stat & 0x1e) == STS_CHECKCOND)
71 return("Check Condition");
72 else if ((stat & 0x1e) == STS_CONDMET)
73 return("Condition Met");
74 else if ((stat & 0x1e) == STS_BUSY)
75 return("Busy");
76 else if ((stat & 0x1e) == STS_INTERMED)
77 return("Intermediate status sent");
78 else if ((stat & 0x1e) == STS_EXT)
79 return("Extended status valid");
80 else
81 return("Unknown Status");
82 }
83
84 #ifdef DEBUG_FUNC
85
86 char *
scsi_command(cmd)87 scsi_command(cmd)
88 u_char cmd;
89 {
90 if (cmd == CMD_TEST_UNIT_READY)
91 return("TEST_UNIT_READY");
92 else if (cmd == CMD_REQUEST_SENSE)
93 return("REQUEST_SENSE");
94 else if (cmd == CMD_INQUIRY)
95 return("INQUIRY");
96 else if (cmd == CMD_READ)
97 return("READ");
98 else if (cmd == CMD_WRITE)
99 return("WRITE");
100 else if (cmd == CMD_READ_EXT)
101 return("READ EXT");
102 else if (cmd == CMD_WRITE_EXT)
103 return("WRITE_EXT");
104 else if (cmd == CMD_READ_CAPACITY)
105 return("READ_CAPACITY");
106 else
107 return(hexstr(cmd, 2));
108 }
109
110 char *
scsi_mesg(mesg)111 scsi_mesg(mesg)
112 u_char mesg;
113 {
114 if (mesg == MSG_CMD_COMPLETE)
115 return("Command Complete");
116 else if (mesg == MSG_EXT_MESSAGE)
117 return("Extended Message");
118 else if (mesg == MSG_SAVE_DATA_PTR)
119 return("Save Data Pointer");
120 else if (mesg == MSG_RESTORE_PTR)
121 return("Restore Pointer");
122 else if (mesg == MSG_DISCONNECT)
123 return("Disconnect");
124 else if (mesg == MSG_INIT_DETECT_ERROR)
125 return("Initiator Detected Error");
126 else if (mesg == MSG_ABORT)
127 return("Abort");
128 else if (mesg == MSG_REJECT)
129 return("Message Reject");
130 else if (mesg == MSG_NOOP)
131 return("No Operation");
132 else if (mesg == MSG_PARITY_ERROR)
133 return("Message Parity Error");
134 else if (mesg == MSG_BUS_DEVICE_RESET)
135 return("Bus Device Reset");
136 else if (mesg == MSG_IDENTIFY)
137 return("Identify");
138 else if (mesg == MSG_IDENTIFY_DR)
139 return("Identify (Disconnect)");
140 else
141 return("Unknown Message");
142 }
143
144 char *
phase_name(phase)145 phase_name(phase)
146 u_char phase;
147 {
148 if (phase == DATA_OUT_PHASE)
149 return("Data Out");
150 else if (phase == DATA_IN_PHASE)
151 return("Data In");
152 else if (phase == CMD_PHASE)
153 return("Command");
154 else if (phase == STATUS_PHASE)
155 return("Status");
156 else if (phase == BUS_FREE_PHASE)
157 return("Bus Free");
158 else if (phase == ARB_SEL_PHASE)
159 return("Arbitration/Select");
160 else if (phase == MESG_OUT_PHASE)
161 return("Message Out");
162 else if (phase == MESG_IN_PHASE)
163 return("Message In");
164 else
165 return("Unknown");
166 }
167 #endif
168
169 /*
170 * Initialize SPC & Data Structure
171 */
172
173 int
scinit(hc)174 scinit(hc)
175 register struct hp_ctlr *hc;
176 {
177 register struct sc_softc *hs = &sc_softc[hc->hp_unit];
178 register int i;
179
180 hc->hp_ipl = SCSI_IPL;
181 hs->sc_hc = hc;
182 hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
183 hs->sc_wq.dq_forw = hs->sc_wq.dq_back = &hs->sc_wq;
184
185 hs->sc_flags = 0;
186 hs->sc_phase = BUS_FREE_PHASE;
187
188 hs->sc_stat = 0;
189 hs->sc_msg[0] = 0;
190
191 screset(hc->hp_unit);
192
193 return(1);
194 }
195
196 void
screset(unit)197 screset(unit)
198 register int unit;
199 {
200 register struct sc_softc *hs = &sc_softc[unit];
201 volatile register struct scsidevice *hd =
202 (struct scsidevice *)hs->sc_hc->hp_addr;
203
204 printf("sc%d: ", unit);
205
206 /*
207 * Disable interrupts then reset the FUJI chip.
208 */
209
210 hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
211 hd->scsi_scmd = 0;
212 hd->scsi_pctl = 0;
213 hd->scsi_temp = 0;
214 hd->scsi_tch = 0;
215 hd->scsi_tcm = 0;
216 hd->scsi_tcl = 0;
217 hd->scsi_ints = 0;
218
219 /* We can use Asynchronous Transfer only */
220 printf("async");
221
222 /*
223 * Configure MB89352 with its SCSI address, all
224 * interrupts enabled & appropriate parity.
225 */
226 hd->scsi_bdid = SCSI_ID;
227 hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB|
228 SCTL_PARITY_ENAB | SCTL_RESEL_ENAB |
229 SCTL_INTR_ENAB;
230 printf(", parity");
231
232 DELAY(400);
233 hd->scsi_sctl &= ~SCTL_DISABLE;
234
235 printf(", scsi id %d\n", SCSI_ID);
236 }
237
238
239 /*
240 * SPC Arbitration/Selection routine
241 */
242
243 int
issue_select(hd,target,flags)244 issue_select(hd, target, flags)
245 volatile register struct scsidevice *hd;
246 u_char target;
247 int flags;
248 {
249 #ifndef NODISCONNECT
250 if (flags & DQ_DISCONNECT) {
251 hd->scsi_scmd = SCMD_SET_ATN;
252 }
253 #endif
254
255 hd->scsi_pctl = 0;
256 hd->scsi_temp = (1 << SCSI_ID) | (1 << target);
257
258 /* select timeout is hardcoded to 2ms */
259 hd->scsi_tch = 0;
260 hd->scsi_tcm = 32;
261 hd->scsi_tcl = 4;
262
263 hd->scsi_scmd = SCMD_SELECT;
264
265 return (1);
266 }
267
268
269 /*
270 * SPC Manual Transfer routines
271 */
272
273 /* not yet */
274
275
276 /*
277 * SPC Program Transfer routines
278 */
279
280 int
ixfer_start(hd,len,phase)281 ixfer_start(hd, len, phase)
282 volatile register struct scsidevice *hd;
283 register int len;
284 register u_char phase;
285 {
286 register int wait = 0;
287
288 hd->scsi_sdgc = 0;
289
290 hd->scsi_tch = ((len & 0xff0000) >> 16);
291 hd->scsi_tcm = ((len & 0x00ff00) >> 8);
292 hd->scsi_tcl = (len & 0x0000ff);
293 hd->scsi_pctl = phase;
294 hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
295
296 while ((hd->scsi_ssts & SSTS_BUSY) == 0) {
297 if (wait > SC_TIMEOUT) {
298 panic("ixfer_start: too long wait");
299 }
300 wait++;
301 DELAY(1);
302 }
303 }
304
305 int
ixfer_out(hd,len,buf)306 ixfer_out(hd, len, buf)
307 volatile register struct scsidevice *hd;
308 register int len;
309 register u_char *buf;
310 {
311 u_char *t = buf;
312 register int wait = 0;
313 #ifdef QUADBYTES
314 register int qwait = 0;
315 register int l_len = len >> 3;
316 register u_long * l_buf = (u_long *) buf;
317
318 for(; l_len > 0; l_len--) {
319 while ((hd->scsi_ssts & SSTS_DREG_EMPTY) == 0) {
320 if (qwait > SC_TIMEOUT) {
321 printf("ixfer_out: quad time out\n");
322 printf("ixfer_out: %d bytes sended\n",
323 (((u_char *) l_buf) - t));
324 printf("ixfer_out: TC = %d\n",
325 ( hd->scsi_tch << 16 ) |
326 ( hd->scsi_tcm << 8 ) |
327 ( hd->scsi_tcl ));
328 return(-1);
329 }
330 qwait++;
331 DELAY(1);
332 }
333 *((u_long *) &hd->scsi_dreg) = *l_buf++;
334 *((u_long *) &hd->scsi_dreg) = *l_buf++;
335 }
336
337 len &= 0x07;
338 buf = (u_char *) l_buf;
339 #endif
340 for(; len > 0; len--) {
341 while (hd->scsi_ssts & SSTS_DREG_FULL) {
342 if (wait > SC_TIMEOUT) {
343 printf("ixfer_out: time out\n");
344 printf("ixfer_out: %d bytes sended\n",
345 (buf - t));
346 return(-1);
347 }
348 wait++;
349 DELAY(1);
350 }
351 hd->scsi_dreg = *buf++;
352 }
353
354 #ifdef QUADBYTES
355 return(qwait);
356 #else
357 return(wait);
358 #endif
359 }
360
361 int
ixfer_in(hd,len,buf)362 ixfer_in(hd, len, buf)
363 volatile register struct scsidevice *hd;
364 register int len;
365 register u_char *buf;
366 {
367 u_char *t = buf;
368 register int wait = 0;
369 #ifdef QUADBYTES
370 register int qwait = 0;
371 register int l_len = len >> 3;
372 register u_long * l_buf = (u_long *) buf;
373
374 for(; l_len > 0; l_len--) {
375 while ((hd->scsi_ssts & SSTS_DREG_FULL) == 0) {
376 if (qwait > SC_TIMEOUT) {
377 printf("ixfer_in: quad time out\n");
378 printf("ixfer_in: %d bytes recieved\n",
379 (((u_char *) l_buf) - t));
380 return(-1);
381 }
382 qwait++;
383 DELAY(1);
384 }
385 *l_buf++ = *((u_long *) &hd->scsi_dreg);
386 *l_buf++ = *((u_long *) &hd->scsi_dreg);
387 }
388
389 len &= 0x07;
390 buf = (u_char *) l_buf;
391 #endif
392 for (; len > 0; len--) {
393 while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
394 if (wait > SC_TIMEOUT) {
395 printf("ixfer_in: time out\n");
396 printf("ixfer_in: %d bytes recieved\n",
397 (buf - t));
398 return(-1);
399 }
400 wait++;
401 DELAY(1);
402 }
403 *buf++ = hd->scsi_dreg;
404 }
405
406
407 #ifdef QUADBYTES
408 return(qwait);
409 #else
410 return(wait);
411 #endif
412 }
413
414
415 #ifdef XFER_ENABLE
416 /*
417 * SPC Interrupt base Transfer Routines
418 */
419
420 int
txfer_start(hd,len,phase)421 txfer_start(hd, len, phase)
422 volatile register struct scsidevice *hd;
423 register int len;
424 register u_char phase;
425 {
426 register int wait = 0;
427
428 hd->scsi_sdgc = SDGC_XFER_ENAB; /* for interrupt */
429
430 hd->scsi_tch = ((len & 0xff0000) >> 16);
431 hd->scsi_tcm = ((len & 0x00ff00) >> 8);
432 hd->scsi_tcl = (len & 0x0000ff);
433 hd->scsi_pctl = phase;
434 hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
435
436 while ((hd->scsi_ssts & SSTS_BUSY) == 0) {
437 if (wait > SC_TIMEOUT) {
438 panic("ixfer_start: too long wait");
439 }
440 wait++;
441 DELAY(1);
442 }
443 }
444
445 int
txfer_in(ctlr)446 txfer_in(ctlr)
447 register int ctlr;
448 {
449 register struct sc_softc *hs = &sc_softc[ctlr];
450 volatile register struct scsidevice *hd = (struct scsidevice *) hs->sc_hc->hp_addr;
451 register struct scsi_queue *dq = hs->sc_sq.dq_forw;
452 #ifdef QUADBYTES
453 register u_long *lp;
454
455 if (hd->scsi_ssts & SSTS_DREG_FULL) {
456 lp = (u_long *) dq->dq_xferp;
457
458 *lp++ = *((u_long *) &hd->scsi_dreg);
459 *lp++ = *((u_long *) &hd->scsi_dreg);
460
461 dq->dq_xferp = (u_char *) lp;
462 dq->dq_xfercnt -= 8;
463
464 goto xfer_done;
465 }
466 #endif
467
468 *dq->dq_xferp++ = hd->scsi_dreg;
469 dq->dq_xfercnt--;
470
471 xfer_done:
472 #ifdef DEBUGPRINT
473 if (dq->dq_xfercnt == 0) {
474 dbgprintf("txfer_in: ");
475 dbgprintf("dq->dq_bp->b_un.b_addr = 0x%s, ", hexstr(dq->dq_bp->b_un.b_addr, 8));
476 dbgprintf("dq->dq_xferp = 0x%s :", hexstr(dq->dq_xferp, 8));
477 dbgprintf("done\n");
478 }
479 #endif
480 }
481 #endif
482
483 /*
484 * SCSI Job Handler
485 */
486
487 int
scstart(ctlr)488 scstart(ctlr)
489 int ctlr;
490 {
491 register struct sc_softc *hs = &sc_softc[ctlr];
492 volatile register struct scsidevice *hd =
493 (struct scsidevice *) hs->sc_hc->hp_addr;
494 register struct scsi_queue *dq = hs->sc_sq.dq_forw;
495
496 dq->dq_imax = 0;
497 dq->dq_imin = -1;
498 dq->dq_omax = 0;
499 dq->dq_omin = -1;
500
501 hs->sc_flags = 0;
502 hs->sc_phase = ARB_SEL_PHASE;
503
504 hs->sc_stat = 0;
505 hs->sc_msg[0] = 0;
506
507 #ifdef DEBUGPRINT
508 dbgprintf("\n");
509 dbgprintf("scstart: ID = %d\n", dq->dq_slave);
510 dbgprintf("scstart: cdb[0] = %s\n", scsi_command(dq->dq_cdb->cdb[0]));
511 dbgprintf("scstart: cdb[1] = 0x%s\n", hexstr(dq->dq_cdb->cdb[1], 2));
512 dbgprintf("scstart: cdb[2] = 0x%s\n", hexstr(dq->dq_cdb->cdb[2], 2));
513 dbgprintf("scstart: cdb[3] = 0x%s\n", hexstr(dq->dq_cdb->cdb[3], 2));
514 dbgprintf("scstart: cdb[4] = 0x%s\n", hexstr(dq->dq_cdb->cdb[4], 2));
515 dbgprintf("scstart: cdb[5] = 0x%s\n", hexstr(dq->dq_cdb->cdb[5], 2));
516 if (dq->dq_cdb->cdb[0] & 0xE0) {
517 dbgprintf("scstart: cdb[6] = 0x%s\n", hexstr(dq->dq_cdb->cdb[6], 2));
518 dbgprintf("scstart: cdb[7] = 0x%s\n", hexstr(dq->dq_cdb->cdb[7], 2));
519 dbgprintf("scstart: cdb[8] = 0x%s\n", hexstr(dq->dq_cdb->cdb[8], 2));
520 dbgprintf("scstart: cdb[9] = 0x%s\n", hexstr(dq->dq_cdb->cdb[9], 2));
521 }
522 dbgprintf("scstart: bp->b_bcount = %d\n", dq->dq_bp->b_bcount);
523 dbgprintf("scstart: %s\n", phase_name(hs->sc_phase));
524 #endif
525
526 issue_select(hd, dq->dq_slave, dq->dq_flags);
527
528 return(1);
529 }
530
531 int
_scintr()532 _scintr()
533 {
534 register struct sc_softc *hs;
535 volatile register struct scsidevice *hd;
536 register int ctlr;
537
538 for (ctlr = 0; ctlr < NSC; ctlr++) {
539 hs = &sc_softc[ctlr];
540 hd = (struct scsidevice *) hs->sc_hc->hp_addr;
541
542 #ifdef XFER_ENABLE
543 if (((hd->scsi_psns & PHASE) == DATA_IN_PHASE) &&
544 (hd->scsi_serr & SERR_XFER_OUT))
545 txfer_in(ctlr);
546 #endif
547
548 if (hd->scsi_ints != 0)
549 scintr(ctlr);
550 }
551
552 return;
553 }
554
555 int
scintr(ctlr)556 scintr(ctlr)
557 register int ctlr;
558 {
559 register struct sc_softc *hs = &sc_softc[ctlr];
560 volatile register struct scsidevice *hd = (struct scsidevice *) hs->sc_hc->hp_addr;
561 register struct scsi_queue *dq = hs->sc_sq.dq_forw;
562 register u_char ints, temp;
563 register int i, slave;
564 int wait, len;
565 u_char *buf;
566
567 ints = hd->scsi_ints;
568
569 #ifdef DEBUGPRINT
570 dbgprintf("scintr: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x",
571 ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
572 if (hs->sc_phase == CMD_PHASE)
573 dbgprintf(" [%s]", scsi_command(dq->dq_cdb->cdb[0]));
574 if (hs->sc_phase & PHASE_MSG)
575 dbgprintf(" [%s]", scsi_mesg(hs->sc_msg[0]));
576 dbgprintf("\n");
577 #endif
578
579 if (ints & INTS_DISCON) {
580 if (hs->sc_msg[0] == MSG_CMD_COMPLETE) {
581 hd->scsi_ints = ints;
582
583 if (hs->sc_lock != NULL) {
584 *(hs->sc_lock) = SC_IO_COMPLETE;
585 } else {
586 (dq->dq_driver->d_intr)(dq->dq_unit, hs->sc_stat);
587 }
588
589 return;
590 #ifndef NODISCONNECT
591 } else if (hs->sc_msg[0] == MSG_DISCONNECT) {
592 #ifdef DEBUGPRINT
593 dbgprintf("scintr: DISCONNECT : ctlr = %d, slave = %d, cdb = %s\n",
594 dq->dq_ctlr, dq->dq_slave, scsi_command(dq->dq_cdb->cdb[0]));
595 #endif
596
597 hd->scsi_ints = ints;
598
599 scpend(dq);
600
601 dq = hs->sc_sq.dq_forw;
602
603 if (dq != &hs->sc_sq)
604 (dq->dq_driver->d_start)(dq->dq_unit);
605
606 return;
607 #endif
608 } else
609 goto abort;
610
611 #ifndef NODISCONNECT
612 } else if (ints & INTS_RESEL) {
613 temp = hd->scsi_temp & ~(1 << SCSI_ID);
614 for (slave = 0; temp != 1; slave++) {
615 temp >>= 1;
616 }
617
618 hd->scsi_ints = ints;
619
620 scrschdl(ctlr, slave);
621
622 dq = hs->sc_sq.dq_forw;
623 #ifdef DEBUGPRINT
624 dbgprintf("\n");
625 dbgprintf("scintr: RESELECT : ctlr = %d, slave = %d, cdb = %s\n",
626 dq->dq_ctlr, dq->dq_slave, scsi_command(dq->dq_cdb->cdb[0]));
627 #endif
628 #endif
629 } else if (ints & INTS_CMD_DONE) {
630 if (hs->sc_phase == BUS_FREE_PHASE)
631 goto abort;
632 else if (hs->sc_phase == MESG_IN_PHASE) {
633 hd->scsi_scmd = SCMD_RST_ACK;
634
635 if ((hs->sc_msg[0] == MSG_CMD_COMPLETE) ||
636 (hs->sc_msg[0] == MSG_DISCONNECT)) {
637 hd->scsi_ints = ints;
638
639 hs->sc_phase = BUS_FREE_PHASE;
640
641 return;
642 }
643 }
644 if (hs->sc_flags & SC_SEL_TIMEOUT)
645 hs->sc_flags &= ~SC_SEL_TIMEOUT;
646 } else if (ints & INTS_SRV_REQ) {
647 if (hs->sc_phase != MESG_IN_PHASE)
648 goto abort;
649 } else if (ints & INTS_TIMEOUT) {
650 if (hs->sc_phase == ARB_SEL_PHASE) {
651 if (hs->sc_flags & SC_SEL_TIMEOUT) {
652 hd->scsi_ints = ints;
653 hs->sc_flags &= ~SC_SEL_TIMEOUT;
654 /* Such SCSI Device is not conected. */
655
656 if (hs->sc_lock != NULL) {
657 *(hs->sc_lock) = SC_DEV_NOT_FOUND;
658 } else {
659 (dq->dq_driver->d_intr)(dq->dq_unit, SC_DEV_NOT_FOUND);
660 }
661
662 return;
663 } else {
664 /* wait more 250 usec */
665 hs->sc_flags |= SC_SEL_TIMEOUT;
666 hd->scsi_temp = 0;
667 hd->scsi_tch = 0;
668 hd->scsi_tcm = 0x06;
669 hd->scsi_tcl = 0x40;
670 hd->scsi_ints = ints;
671 return;
672 }
673 } else
674 goto abort;
675 } else
676 goto abort;
677
678 hd->scsi_ints = ints;
679
680 /*
681 * Next SCSI Transfer
682 */
683
684 wait = SC_TIMEOUT;
685 while ((hd->scsi_psns & PSNS_REQ) == 0) {
686 if (wait < 0) {
687 /* hd->scsi_scmd = SCMD_SET_ATN; */
688 hd->scsi_scmd = SCMD_RST;
689 DELAY(40); /* wait 25 micro sec */
690 hd->scsi_scmd = 0;
691
692 wait = SC_TIMEOUT;
693 while (wait-- > 0)
694 DELAY(1);
695
696 if (hs->sc_lock != NULL) {
697 *(hs->sc_lock) = SC_IO_TIMEOUT;
698 } else {
699 (dq->dq_driver->d_intr)(dq->dq_unit, SC_IO_TIMEOUT);
700 }
701
702 return;
703 }
704 DELAY(1);
705 wait--;
706 }
707
708 hs->sc_phase = hd->scsi_psns & PHASE;
709
710 #ifdef DEBUGPRINT
711 dbgprintf("scintr: %s\n", phase_name(hs->sc_phase));
712 #endif
713
714 if ((hs->sc_phase == DATA_OUT_PHASE) || (hs->sc_phase == DATA_IN_PHASE)) {
715 len = ( hs->sc_lock != NULL ? hs->sc_len : dq->dq_bp->b_bcount );
716 buf = ( hs->sc_lock != NULL ? hs->sc_buf : (u_char *) dq->dq_bp->b_un.b_addr );
717 } else if (hs->sc_phase == CMD_PHASE) {
718 len = ( hs->sc_lock != NULL ? hs->sc_cdblen : dq->dq_cdb->len );
719 buf = ( hs->sc_lock != NULL ? hs->sc_cdb : dq->dq_cdb->cdb );
720 } else if (hs->sc_phase == STATUS_PHASE) {
721 len = 1;
722 buf = &hs->sc_stat;
723 } else {
724 if (hs->sc_phase == MESG_OUT_PHASE) {
725 #ifndef NODISCONNECT
726 hs->sc_msg[0] = MSG_IDENTIFY_DR;
727 #else
728 hs->sc_msg[0] = MSG_IDENTIFY;
729 #endif
730 }
731 len = 1;
732 buf = hs->sc_msg;
733 }
734
735 #ifdef XFER_ENABLE
736 if ((hs->sc_lock == NULL) && (hs->sc_phase == DATA_IN_PHASE)) {
737 dq->dq_xferp = buf;
738 dq->dq_xfercnt = len;
739 txfer_start(hd, len, hs->sc_phase);
740 return;
741 }
742 #endif
743
744 ixfer_start(hd, len, hs->sc_phase);
745 if (hs->sc_phase & PHASE_IO) {
746 if ((wait = ixfer_in(hd, len, buf)) == -1) {
747 goto time_out;
748 }
749 if (dq->dq_imin == -1)
750 dq->dq_imin = wait;
751 else
752 dq->dq_imin = min(wait, dq->dq_imin);
753 dq->dq_imax = max(wait, dq->dq_imax);
754 } else {
755 if ((wait = ixfer_out(hd, len, buf)) == -1) {
756 goto time_out;
757 }
758 if (dq->dq_omin == -1)
759 dq->dq_omin = wait;
760 else
761 dq->dq_omin = min(wait, dq->dq_omin);
762 dq->dq_omax = max(wait, dq->dq_omax);
763 }
764
765 return;
766
767 time_out:
768 scabort(hs, hd);
769 printf("scintr: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Current Status\n",
770 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
771
772 if (hs->sc_lock != NULL) {
773 *(hs->sc_lock) = SC_IO_TIMEOUT;
774 } else {
775 (dq->dq_driver->d_intr)(dq->dq_unit, SC_IO_TIMEOUT);
776 }
777
778 return;
779
780 /*
781 * SCSI Abort
782 */
783 abort:
784
785 /* SCSI IO failed */
786 scabort(hs, hd);
787 hd->scsi_ints = ints;
788
789 if (hs->sc_lock != NULL) {
790 *(hs->sc_lock) = SC_IO_FAILED;
791 } else {
792 (dq->dq_driver->d_intr)(dq->dq_unit, SC_IO_FAILED);
793 }
794
795 return;
796 }
797
798 int
scabort(hs,hd)799 scabort(hs, hd)
800 register struct sc_softc *hs;
801 volatile register struct scsidevice *hd;
802 {
803 int len;
804 u_char junk;
805
806 #ifdef DEBUGPRINT
807 dbgprintall();
808 printf("\n");
809 #endif
810
811 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Current Status\n",
812 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
813
814 if (hd->scsi_ints != 0)
815 hd->scsi_ints = hd->scsi_ints;
816 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Reset INTS reg.\n",
817 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
818
819 if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
820 /* no longer connected to scsi target */
821 return;
822
823 /* get the number of bytes remaining in current xfer + fudge */
824 len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
825 printf("scabort: Current xfer count = %d\n", len);
826
827 /* for that many bus cycles, try to send an abort msg */
828 for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
829 /*
830 hd->scsi_scmd = SCMD_SET_ATN;
831 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Set ATN\n",
832 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
833 */
834 while ((hd->scsi_psns & PSNS_REQ) == 0) {
835 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Wait for REQ\n",
836 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
837 if (! (hd->scsi_ssts & SSTS_INITIATOR))
838 goto out;
839 DELAY(1);
840 }
841 /*
842 if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE) {
843 hd->scsi_scmd = SCMD_RST_ATN;
844 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Reset ATN\n",
845 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
846 }
847 */
848 hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE;
849 printf("scabort: Phase = %s\n", phase_name(hs->sc_phase));
850
851 if (hd->scsi_psns & PHASE_IO) {
852 /* one of the input phases - read & discard a byte */
853 hd->scsi_scmd = SCMD_SET_ACK;
854 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Set ACK\n",
855 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
856
857 while (hd->scsi_psns & PSNS_REQ) {
858 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Wait for REQ\n",
859 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
860 DELAY(1);
861 }
862
863 junk = hd->scsi_temp;
864 printf("scabort: TEMP = 0x%s\n", hexstr(junk, 2));
865 } else {
866 /* one of the output phases - send an abort msg */
867 hd->scsi_temp = MSG_ABORT;
868 hd->scsi_scmd = SCMD_SET_ACK;
869 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Set ACK\n",
870 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
871
872 while (hd->scsi_psns & PSNS_REQ) {
873 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Wait for REQ\n",
874 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
875 DELAY(1);
876 }
877 }
878
879 hd->scsi_scmd = SCMD_RST_ACK;
880 printf("scabort: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Reset ACK\n",
881 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
882 }
883 out:
884 /*
885 * Either the abort was successful & the bus is disconnected or
886 * the device didn't listen. If the latter, announce the problem.
887 * Either way, reset the card & the SPC.
888 */
889 if (len < 0 && hs)
890 printf("sc%d: abort failed. phase=0x%x, ssts=0x%x\n",
891 hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
892
893 while (hd->scsi_ints == 0)
894 DELAY(1);
895
896 hd->scsi_ints = hd->scsi_ints;
897
898 printf("scintr: INTS 0x%x, SSTS 0x%x, PCTL 0x%x, PSNS 0x%x Current Status\n",
899 hd->scsi_ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns);
900
901 printf("scabort: SCSI abort operation is done\n");
902 }
903
904
905 /*
906 * SPC device queue handling
907 */
908
909 int
screq(dq)910 screq(dq)
911 register struct scsi_queue *dq;
912 {
913 register struct sc_softc *hs = &sc_softc[dq->dq_ctlr];
914 register struct scsi_queue *hq = &hs->sc_sq;
915
916 insque(dq, hq->dq_back);
917
918 if (dq->dq_back == hq) {
919 #ifdef QUE_DEBUG
920 printf("screq: slave = %d, command = %s\n",
921 hq->dq_forw->dq_slave,
922 scsi_command(hq->dq_forw->dq_cdb->cdb[0]));
923 #endif
924 return(1);
925 }
926
927 return(0);
928 }
929
930 #ifndef NODISCONNECT
931 int
scpend(dq)932 scpend(dq)
933 register struct scsi_queue *dq;
934 {
935 register struct sc_softc *hs = &sc_softc[dq->dq_ctlr];
936 register struct scsi_queue *hq = &hs->sc_sq;
937 register struct scsi_queue *wq = &hs->sc_wq;
938
939 remque(dq);
940
941 insque(dq, wq->dq_back);
942 }
943
944 int
scrschdl(ctlr,slave)945 scrschdl(ctlr, slave)
946 register int ctlr;
947 register int slave;
948 {
949 register struct sc_softc *hs = &sc_softc[ctlr];
950 register struct scsi_queue *wq = &hs->sc_wq;
951 register struct scsi_queue *hq = &hs->sc_sq;
952 register struct scsi_queue *dq;
953
954 for (dq = wq->dq_forw; dq != wq; dq = dq->dq_forw) {
955 if (dq->dq_slave == slave)
956 goto found;
957 }
958
959 return(0);
960
961 found:
962 remque(dq);
963 insque(dq, hq);
964
965 return(1);
966 }
967 #endif
968
969 int
scfree(dq)970 scfree(dq)
971 register struct scsi_queue *dq;
972 {
973 register struct sc_softc *hs = &sc_softc[dq->dq_ctlr];
974 register struct scsi_queue *hq = &hs->sc_sq;
975 int status = hs->sc_stat;
976
977 remque(dq);
978
979 hs->sc_flags = 0;
980 hs->sc_phase = BUS_FREE_PHASE;
981
982 hs->sc_stat = 0;
983 hs->sc_msg[0] = 0;
984
985 if ((dq = hq->dq_forw) != hq) {
986 #ifdef QUE_DEBUG
987 printf("scfree: slave = %d, command = %s\n",
988 dq->dq_slave,
989 scsi_command(dq->dq_cdb->cdb[0]));
990 #endif
991 (dq->dq_driver->d_start)(dq->dq_unit);
992 }
993
994 return(status);
995 }
996
997 /*
998 * SCSI common interface
999 */
1000
1001 int scsi_lock[NSC];
1002
1003 int
scsi_result(unit,stat)1004 scsi_result(unit, stat)
1005 int unit, stat;
1006 {
1007 #ifdef SCSI_DEBUG
1008 printf("scsi_result: stat = %s\n", scsi_status(stat));
1009 #endif
1010 if (stat < 0)
1011 scsi_lock[unit] = stat;
1012 else
1013 scsi_lock[unit] = SC_IO_COMPLETE;
1014 }
1015
1016 struct driver scsi_driver = {
1017 (int (*)()) 0, "scsi", (int (*)()) 0, (int (*)()) 0, scsi_result, (int (*)()) 0
1018 };
1019
1020 struct scsi_queue scsi_entry[NSC];
1021
1022 int
scsi_immed_command(ctlr,slave,lun,cdb,buf,len)1023 scsi_immed_command(ctlr, slave, lun, cdb, buf, len)
1024 int ctlr, slave, lun;
1025 struct scsi_fmt_cdb *cdb;
1026 u_char *buf;
1027 unsigned len;
1028 {
1029 register struct sc_softc *hs = &sc_softc[ctlr];
1030 volatile register struct scsidevice *hd =
1031 (struct scsidevice *) hs->sc_hc->hp_addr;
1032 register struct scsi_queue *dq = &scsi_entry[ctlr];
1033 register struct buf *bp;
1034 int s, status, wait = 30;
1035
1036 #ifdef SCSI_DEBUG
1037 printf("scsi_immed_command( %d, %d, %d, cdb(%d,%s), buf, %d): Start\n",
1038 ctlr, slave, lun, cdb->len, scsi_command(cdb->cdb[0]), len);
1039 #endif
1040 bp = geteblk(len);
1041 bp->b_flags = B_BUSY;
1042
1043 s = splbio();
1044
1045 dq->dq_unit = ctlr;
1046 dq->dq_ctlr = ctlr;
1047 dq->dq_slave = slave;
1048 dq->dq_driver = &scsi_driver;
1049 dq->dq_cdb = cdb;
1050 dq->dq_bp = bp;
1051
1052 scsi_lock[ctlr] = SC_IN_PROGRESS;
1053 if (screq(dq))
1054 scstart(ctlr);
1055
1056 splx(s);
1057
1058 while (scsi_lock[ctlr] == SC_IN_PROGRESS) {
1059 if (wait < 0) {
1060 scabort(hs, hd);
1061
1062 s = splbio();
1063 status = scfree(dq);
1064 splx(s);
1065
1066 bp->b_flags = 0;
1067
1068 return(SC_IO_FAILED);
1069 }
1070
1071 DELAY(100000);
1072 wait--;
1073 }
1074
1075 s = splbio();
1076 status = scfree(dq);
1077 splx(s);
1078
1079 if (scsi_lock[ctlr] < 0)
1080 status = scsi_lock[ctlr];
1081
1082 bcopy(bp->b_un.b_addr, buf, len);
1083
1084 brelse(bp);
1085
1086 #ifdef SCSI_DEBUG
1087 printf("scsi_immed_command: Status -- 0x%x\n", status);
1088 #endif
1089 return(status);
1090 }
1091
1092 int
sc_test_unit_rdy(ctlr,slave,lun)1093 sc_test_unit_rdy(ctlr, slave, lun)
1094 int ctlr, slave, lun;
1095 {
1096 static struct scsi_fmt_cdb cdb = { 6, CMD_TEST_UNIT_READY };
1097 int stat;
1098
1099 while ((stat = scsi_immed_command(ctlr, slave, lun,
1100 &cdb, (u_char *) 0, 0)) == SC_BUSY) {
1101 DELAY(10000);
1102 }
1103
1104 return(stat);
1105 }
1106
1107 int
sc_request_sense(ctlr,slave,lun,buf,len)1108 sc_request_sense(ctlr, slave, lun, buf, len)
1109 int ctlr, slave, lun;
1110 u_char *buf;
1111 unsigned len;
1112 {
1113 register struct sc_softc *hs = &sc_softc[ctlr];
1114 volatile register struct scsidevice *hd =
1115 (struct scsidevice *) hs->sc_hc->hp_addr;
1116 static struct scsi_fmt_cdb req_cmd = { 6, CMD_REQUEST_SENSE };
1117 int s, status, lock;
1118
1119 #ifdef REQ_DEBUG
1120 printf("sc_request_sense( %d, %d, %d, buf, %d) -- Start\n",
1121 ctlr, slave, lun, len);
1122 #endif
1123
1124 req_cmd.cdb[1] = lun;
1125 req_cmd.cdb[4] = len;
1126
1127 if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
1128 return(0);
1129
1130 s = splbio();
1131
1132 hs->sc_flags = 0;
1133 hs->sc_phase = ARB_SEL_PHASE;
1134
1135 hs->sc_cdb = req_cmd.cdb;
1136 hs->sc_cdblen = req_cmd.len;
1137 hs->sc_buf = buf;
1138 hs->sc_len = len;
1139
1140 hs->sc_stat = 0;
1141 hs->sc_msg[0] = 0;
1142
1143 lock = SC_IN_PROGRESS;
1144 hs->sc_lock = &lock;
1145
1146 issue_select(hd, slave, 0);
1147
1148 spl0();
1149
1150 while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
1151 DELAY(10);
1152
1153 splbio();
1154
1155 hs->sc_flags = 0;
1156 hs->sc_phase = BUS_FREE_PHASE;
1157
1158 hs->sc_cdb = NULL;
1159 hs->sc_cdblen = 0;
1160 hs->sc_buf = NULL;
1161 hs->sc_len = 0;
1162 hs->sc_lock = NULL;
1163
1164 status = hs->sc_stat;
1165
1166 hs->sc_stat = 0;
1167 hs->sc_msg[0] = 0;
1168
1169 splx(s);
1170
1171 if (lock == SC_IO_COMPLETE) {
1172 #ifdef REQ_DEBUG
1173 printf("sc_request_sense: Status -- 0x%x\n", status);
1174 #endif
1175 return(status);
1176 } else {
1177 return(lock);
1178 }
1179 }
1180 #endif
1181