update identifier from Utah
[unix-history] / usr / src / sys / hp300 / dev / scsi.c
CommitLineData
60f56dfc
KM
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Van Jacobson of Lawrence Berkeley Laboratory.
7 *
8 * %sccs.include.redist.c%
9 *
10 * @(#)scsi.c 7.1 (Berkeley) %G%
11 */
12
13/*
14 * HP9000/3xx 98658 SCSI host adaptor driver.
15 */
16#include "scsi.h"
17#if NSCSI > 0
18
19#ifndef lint
20static char rcsid[] = "$Header: scsi.c,v 1.3 90/01/06 04:56:50 van Exp $";
21#endif
22
23#include "param.h"
24#include "systm.h"
25#include "buf.h"
26#include "device.h"
27#include "scsivar.h"
28#include "scsireg.h"
29#include "dmavar.h"
30
31#include "machine/cpu.h"
32#include "machine/isr.h"
33
34extern void isrlink();
35extern void printf();
36extern void _insque();
37extern void _remque();
38extern void bzero();
39
40int scsiinit(), scsigo(), scsiintr(), scsixfer();
41void scsistart(), scsidone(), scsifree(), scsireset();
42struct driver scsidriver = {
43 scsiinit, "scsi", (int (*)())scsistart, scsigo, scsiintr,
44 (int (*)())scsidone,
45};
46
47struct scsi_softc scsi_softc[NSCSI];
48struct isr scsi_isr[NSCSI];
49
50int scsi_cmd_wait = 512; /* microsec wait per step of 'immediate' cmds */
51int scsi_data_wait = 512; /* wait per data in/out step */
52int scsi_nosync = 1; /* inhibit sync xfers if 1 */
53
54#ifdef DEBUG
55int scsi_debug = 0;
56#define WAITHIST
57#endif
58
59#ifdef WAITHIST
60#define MAXWAIT 2048
61u_int ixstart_wait[MAXWAIT+2];
62u_int ixin_wait[MAXWAIT+2];
63u_int ixout_wait[MAXWAIT+2];
64u_int mxin_wait[MAXWAIT+2];
65u_int cxin_wait[MAXWAIT+2];
66u_int fxfr_wait[MAXWAIT+2];
67u_int sgo_wait[MAXWAIT+2];
68#define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]);
69#else
70#define HIST(h,w)
71#endif
72
73#define b_cylin b_resid
74
75static void
76scsiabort(hs, hd, where)
77 register struct scsi_softc *hs;
78 volatile register struct scsidevice *hd;
79 char *where;
80{
81 int len;
82 u_char junk;
83
84 printf("scsi%d: abort from %s: phase=0x%x, ssts=0x%x, ints=0x%x\n",
85 hs->sc_hc->hp_unit, where, hd->scsi_psns, hd->scsi_ssts,
86 hd->scsi_ints);
87
88 hd->scsi_ints = hd->scsi_ints;
89 hd->scsi_csr = 0;
90 if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
91 /* no longer connected to scsi target */
92 return;
93
94 /* get the number of bytes remaining in current xfer + fudge */
95 len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
96
97 /* for that many bus cycles, try to send an abort msg */
98 for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
99 hd->scsi_scmd = SCMD_SET_ATN;
100 while ((hd->scsi_psns & PSNS_REQ) == 0) {
101 if (! (hd->scsi_ssts & SSTS_INITIATOR))
102 goto out;
103 DELAY(1);
104 }
105 if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
106 hd->scsi_scmd = SCMD_RST_ATN;
107 hd->scsi_pctl = hd->scsi_psns & PHASE;
108 if (hd->scsi_psns & PHASE_IO) {
109 /* one of the input phases - read & discard a byte */
110 hd->scsi_scmd = SCMD_SET_ACK;
111 if (hd->scsi_tmod == 0)
112 while (hd->scsi_psns & PSNS_REQ)
113 DELAY(1);
114 junk = hd->scsi_temp;
115 } else {
116 /* one of the output phases - send an abort msg */
117 hd->scsi_temp = MSG_ABORT;
118 hd->scsi_scmd = SCMD_SET_ACK;
119 if (hd->scsi_tmod == 0)
120 while (hd->scsi_psns & PSNS_REQ)
121 DELAY(1);
122 }
123 hd->scsi_scmd = SCMD_RST_ACK;
124 }
125out:
126 /*
127 * Either the abort was successful & the bus is disconnected or
128 * the device didn't listen. If the latter, announce the problem.
129 * Either way, reset the card & the SPC.
130 */
131 if (len < 0 && hs)
132 printf("scsi%d: abort failed. phase=0x%x, ssts=0x%x\n",
133 hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
134
135 if (! ((junk = hd->scsi_ints) & INTS_RESEL)) {
136 hd->scsi_sctl |= SCTL_CTRLRST;
137 DELAY(1);
138 hd->scsi_sctl &=~ SCTL_CTRLRST;
139 hd->scsi_hconf = 0;
140 hd->scsi_ints = hd->scsi_ints;
141 }
142}
143
144int
145scsiinit(hc)
146 register struct hp_ctlr *hc;
147{
148 register struct scsi_softc *hs = &scsi_softc[hc->hp_unit];
149 register struct scsidevice *hd = (struct scsidevice *)hc->hp_addr;
150
151 if ((hd->scsi_id & ID_MASK) != SCSI_ID)
152 return(0);
153 hc->hp_ipl = SCSI_IPL(hd->scsi_csr);
154 hs->sc_hc = hc;
155 hs->sc_dq.dq_unit = hc->hp_unit;
156 hs->sc_dq.dq_driver = &scsidriver;
157 hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
158 scsi_isr[hc->hp_unit].isr_intr = scsiintr;
159 scsi_isr[hc->hp_unit].isr_ipl = hc->hp_ipl;
160 scsi_isr[hc->hp_unit].isr_arg = hc->hp_unit;
161 isrlink(&scsi_isr[hc->hp_unit]);
162 scsireset(hc->hp_unit);
163 return(1);
164}
165
166void
167scsireset(unit)
168 register int unit;
169{
170 register struct scsi_softc *hs = &scsi_softc[unit];
171 volatile register struct scsidevice *hd =
172 (struct scsidevice *)hs->sc_hc->hp_addr;
173 u_int i;
174
175 if (hs->sc_flags & SCSI_ALIVE)
176 scsiabort(hs, hd, "reset");
177
178 printf("scsi%d: ", unit);
179
180 hd->scsi_id = 0xFF;
181 DELAY(100);
182 /*
183 * Disable interrupts then reset the FUJI chip.
184 */
185 hd->scsi_csr = 0;
186 hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
187 hd->scsi_scmd = 0;
188 hd->scsi_tmod = 0;
189 hd->scsi_pctl = 0;
190 hd->scsi_temp = 0;
191 hd->scsi_tch = 0;
192 hd->scsi_tcm = 0;
193 hd->scsi_tcl = 0;
194 hd->scsi_ints = 0;
195
196 if ((hd->scsi_id & ID_WORD_DMA) == 0) {
197 hs->sc_flags |= SCSI_DMA32;
198 printf("32 bit dma, ");
199 }
200
201 /* Determine Max Synchronous Transfer Rate */
202 if (scsi_nosync)
203 i = 3;
204 else
205 i = SCSI_SYNC_XFER(hd->scsi_hconf);
206 switch (i) {
207 case 0:
208 hs->sc_sync = TMOD_SYNC | 0x3e; /* 250 nsecs */
209 printf("250ns sync");
210 break;
211 case 1:
212 hs->sc_sync = TMOD_SYNC | 0x5e; /* 375 nsecs */
213 printf("375ns sync");
214 break;
215 case 2:
216 hs->sc_sync = TMOD_SYNC | 0x7d; /* 500 nsecs */
217 printf("500ns sync");
218 break;
219 case 3:
220 hs->sc_sync = 0;
221 printf("async");
222 break;
223 }
224
225 /*
226 * Configure the FUJI chip with its SCSI address, all
227 * interrupts enabled & appropriate parity.
228 */
229 i = (~hd->scsi_hconf) & 0x7;
230 hs->sc_scsi_addr = 1 << i;
231 hd->scsi_bdid = i;
232 if (hd->scsi_hconf & HCONF_PARITY)
233 hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB |
234 SCTL_SEL_ENAB | SCTL_RESEL_ENAB |
235 SCTL_INTR_ENAB | SCTL_PARITY_ENAB;
236 else {
237 hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB |
238 SCTL_SEL_ENAB | SCTL_RESEL_ENAB |
239 SCTL_INTR_ENAB;
240 printf(", no parity");
241 }
242 hd->scsi_sctl &=~ SCTL_DISABLE;
243
244 printf(", scsi id %d\n", i);
245 hs->sc_flags |= SCSI_ALIVE;
246}
247
248static void
249scsierror(hs, hd, ints)
250 register struct scsi_softc *hs;
251 volatile register struct scsidevice *hd;
252 u_char ints;
253{
254 int unit = hs->sc_hc->hp_unit;
255 char *sep = "";
256
257 printf("scsi%d: ", unit);
258 if (ints & INTS_RST) {
259 DELAY(100);
260 if (hd->scsi_hconf & HCONF_SD)
261 printf("spurious RST interrupt");
262 else
263 printf("hardware error - check fuse");
264 sep = ", ";
265 }
266 if ((ints & INTS_HARD_ERR) || hd->scsi_serr) {
267 if (hd->scsi_serr & SERR_SCSI_PAR) {
268 printf("%sparity err", sep);
269 sep = ", ";
270 }
271 if (hd->scsi_serr & SERR_SPC_PAR) {
272 printf("%sSPC parity err", sep);
273 sep = ", ";
274 }
275 if (hd->scsi_serr & SERR_TC_PAR) {
276 printf("%sTC parity err", sep);
277 sep = ", ";
278 }
279 if (hd->scsi_serr & SERR_PHASE_ERR) {
280 printf("%sphase err", sep);
281 sep = ", ";
282 }
283 if (hd->scsi_serr & SERR_SHORT_XFR) {
284 printf("%ssync short transfer err", sep);
285 sep = ", ";
286 }
287 if (hd->scsi_serr & SERR_OFFSET) {
288 printf("%ssync offset error", sep);
289 sep = ", ";
290 }
291 }
292 if (ints & INTS_TIMEOUT)
293 printf("%sSPC select timeout error", sep);
294 if (ints & INTS_SRV_REQ)
295 printf("%sspurious SRV_REQ interrupt", sep);
296 if (ints & INTS_CMD_DONE)
297 printf("%sspurious CMD_DONE interrupt", sep);
298 if (ints & INTS_DISCON)
299 printf("%sspurious disconnect interrupt", sep);
300 if (ints & INTS_RESEL)
301 printf("%sspurious reselect interrupt", sep);
302 if (ints & INTS_SEL)
303 printf("%sspurious select interrupt", sep);
304 printf("\n");
305}
306
307static int
308issue_select(hd, target, our_addr)
309 volatile register struct scsidevice *hd;
310 u_char target, our_addr;
311{
312 if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
313 return (1);
314
315 if (hd->scsi_ints & INTS_DISCON)
316 hd->scsi_ints = INTS_DISCON;
317
318 hd->scsi_pctl = 0;
319 hd->scsi_temp = (1 << target) | our_addr;
320 /* select timeout is hardcoded to 2ms */
321 hd->scsi_tch = 0;
322 hd->scsi_tcm = 32;
323 hd->scsi_tcl = 4;
324
325 hd->scsi_scmd = SCMD_SELECT;
326 return (0);
327}
328
329static int
330wait_for_select(hd)
331 volatile register struct scsidevice *hd;
332{
333 u_char ints;
334
335 while ((ints = hd->scsi_ints) == 0)
336 DELAY(1);
337 hd->scsi_ints = ints;
338 return (!(hd->scsi_ssts & SSTS_INITIATOR));
339}
340
341static int
342ixfer_start(hd, len, phase, wait)
343 volatile register struct scsidevice *hd;
344 int len;
345 u_char phase;
346 register int wait;
347{
348
349 hd->scsi_tch = len >> 16;
350 hd->scsi_tcm = len >> 8;
351 hd->scsi_tcl = len;
352 hd->scsi_pctl = phase;
353 hd->scsi_tmod = 0; /*XXX*/
354 hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
355
356 /* wait for xfer to start or svc_req interrupt */
357 while ((hd->scsi_ssts & SSTS_BUSY) == 0) {
358 if (hd->scsi_ints || --wait < 0) {
359#ifdef DEBUG
360 if (scsi_debug)
361 printf("ixfer_start fail: i%x, w%d\n",
362 hd->scsi_ints, wait);
363#endif
364 HIST(ixstart_wait, wait)
365 return (0);
366 }
367 DELAY(1);
368 }
369 HIST(ixstart_wait, wait)
370 return (1);
371}
372
373static int
374ixfer_out(hd, len, buf)
375 volatile register struct scsidevice *hd;
376 int len;
377 register u_char *buf;
378{
379 register int wait = scsi_data_wait;
380
381 for (; len > 0; --len) {
382 while (hd->scsi_ssts & SSTS_DREG_FULL) {
383 if (hd->scsi_ints || --wait < 0) {
384#ifdef DEBUG
385 if (scsi_debug)
386 printf("ixfer_out fail: l%d i%x w%d\n",
387 len, hd->scsi_ints, wait);
388#endif
389 HIST(ixout_wait, wait)
390 return (len);
391 }
392 DELAY(1);
393 }
394 hd->scsi_dreg = *buf++;
395 }
396 HIST(ixout_wait, wait)
397 return (0);
398}
399
400static void
401ixfer_in(hd, len, buf)
402 volatile register struct scsidevice *hd;
403 int len;
404 register u_char *buf;
405{
406 register int wait = scsi_data_wait;
407
408 for (; len > 0; --len) {
409 while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
410 if (hd->scsi_ints || --wait < 0) {
411 while (! (hd->scsi_ssts & SSTS_DREG_EMPTY)) {
412 *buf++ = hd->scsi_dreg;
413 --len;
414 }
415#ifdef DEBUG
416 if (scsi_debug)
417 printf("ixfer_in fail: l%d i%x w%d\n",
418 len, hd->scsi_ints, wait);
419#endif
420 HIST(ixin_wait, wait)
421 return;
422 }
423 DELAY(1);
424 }
425 *buf++ = hd->scsi_dreg;
426 }
427 HIST(ixin_wait, wait)
428}
429
430static int
431mxfer_in(hd, len, buf, phase)
432 volatile register struct scsidevice *hd;
433 register int len;
434 register u_char *buf;
435 register u_char phase;
436{
437 register int wait = scsi_cmd_wait;
438 register int i;
439
440 hd->scsi_tmod = 0;
441 for (i = 0; i < len; ++i) {
442 /*
443 * wait for the request line (which says the target
444 * wants to give us data). If the phase changes while
445 * we're waiting, we're done.
446 */
447 while ((hd->scsi_psns & PSNS_REQ) == 0) {
448 if (--wait < 0) {
449 HIST(mxin_wait, wait)
450 return (-1);
451 }
452 if ((hd->scsi_psns & PHASE) != phase ||
453 (hd->scsi_ssts & SSTS_INITIATOR) == 0)
454 goto out;
455
456 DELAY(1);
457 }
458 /*
459 * set ack (which says we're ready for the data, wait for
460 * req to go away (target says data is available), grab the
461 * data, then reset ack (say we've got the data).
462 */
463 hd->scsi_pctl = phase;
464 hd->scsi_scmd = SCMD_SET_ACK;
465 while (hd->scsi_psns & PSNS_REQ) {
466 if (--wait < 0) {
467 HIST(mxin_wait, wait)
468 return (-2);
469 }
470 DELAY(1);
471 }
472 *buf++ = hd->scsi_temp;
473 hd->scsi_scmd = SCMD_RST_ACK;
474 if (hd->scsi_psns & PSNS_ATN)
475 hd->scsi_scmd = SCMD_RST_ATN;
476 }
477out:
478 HIST(mxin_wait, wait)
479 return (i);
480}
481
482/*
483 * SCSI 'immediate' command: issue a command to some SCSI device
484 * and get back an 'immediate' response (i.e., do programmed xfer
485 * to get the response data). 'cbuf' is a buffer containing a scsi
486 * command of length clen bytes. 'buf' is a buffer of length 'len'
487 * bytes for data. The transfer direction is determined by the device
488 * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the
489 * command must supply no data. 'xferphase' is the bus phase the
490 * caller expects to happen after the command is issued. It should
491 * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE.
492 */
493static int
494scsiicmd(hs, target, cbuf, clen, buf, len, xferphase)
495 struct scsi_softc *hs;
496 int target;
497 u_char *cbuf;
498 int clen;
499 u_char *buf;
500 int len;
501 u_char xferphase;
502{
503 volatile register struct scsidevice *hd =
504 (struct scsidevice *)hs->sc_hc->hp_addr;
505 u_char phase, ints;
506 register int wait;
507
508 /* select the SCSI bus (it's an error if bus isn't free) */
509 if (issue_select(hd, target, hs->sc_scsi_addr))
510 return (-1);
511 if (wait_for_select(hd))
512 return (-1);
513 /*
514 * Wait for a phase change (or error) then let the device
515 * sequence us through the various SCSI phases.
516 */
517 hs->sc_stat[0] = 0xff;
518 hs->sc_msg[0] = 0xff;
519 phase = CMD_PHASE;
520 while (1) {
521 wait = scsi_cmd_wait;
522 switch (phase) {
523
524 case CMD_PHASE:
525 if (ixfer_start(hd, clen, phase, wait))
526 if (ixfer_out(hd, clen, cbuf))
527 goto abort;
528 phase = xferphase;
529 break;
530
531 case DATA_IN_PHASE:
532 if (len <= 0)
533 goto abort;
534 wait = scsi_data_wait;
535 if (ixfer_start(hd, len, phase, wait) ||
536 !(hd->scsi_ssts & SSTS_DREG_EMPTY))
537 ixfer_in(hd, len, buf);
538 phase = STATUS_PHASE;
539 break;
540
541 case DATA_OUT_PHASE:
542 if (len <= 0)
543 goto abort;
544 wait = scsi_data_wait;
545 if (ixfer_start(hd, len, phase, wait)) {
546 if (ixfer_out(hd, len, buf))
547 goto abort;
548 }
549 phase = STATUS_PHASE;
550 break;
551
552 case STATUS_PHASE:
553 wait = scsi_data_wait;
554 if (ixfer_start(hd, sizeof(hs->sc_stat), phase, wait) ||
555 !(hd->scsi_ssts & SSTS_DREG_EMPTY))
556 ixfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat);
557 phase = MESG_IN_PHASE;
558 break;
559
560 case MESG_IN_PHASE:
561 if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait) ||
562 !(hd->scsi_ssts & SSTS_DREG_EMPTY)) {
563 ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg);
564 hd->scsi_scmd = SCMD_RST_ACK;
565 }
566 phase = BUS_FREE_PHASE;
567 break;
568
569 case BUS_FREE_PHASE:
570 goto out;
571
572 default:
573 printf("scsi%d: unexpected phase %d in icmd from %d\n",
574 hs->sc_hc->hp_unit, phase, target);
575 goto abort;
576 }
577 /* wait for last command to complete */
578 while ((ints = hd->scsi_ints) == 0) {
579 if (--wait < 0) {
580 HIST(cxin_wait, wait)
581 goto abort;
582 }
583 DELAY(1);
584 }
585 HIST(cxin_wait, wait)
586 hd->scsi_ints = ints;
587 if (ints & INTS_SRV_REQ)
588 phase = hd->scsi_psns & PHASE;
589 else if (ints & INTS_DISCON)
590 goto out;
591 else if ((ints & INTS_CMD_DONE) == 0) {
592 scsierror(hs, hd, ints);
593 goto abort;
594 }
595 }
596abort:
597 scsiabort(hs, hd, "icmd");
598out:
599 return (hs->sc_stat[0]);
600}
601
602/*
603 * Finish SCSI xfer command: After the completion interrupt from
604 * a read/write operation, sequence through the final phases in
605 * programmed i/o. This routine is a lot like scsiicmd except we
606 * skip (and don't allow) the select, cmd out and data in/out phases.
607 */
608static void
609finishxfer(hs, hd, target)
610 struct scsi_softc *hs;
611 volatile register struct scsidevice *hd;
612 int target;
613{
614 u_char phase, ints;
615
616 /*
617 * We specified padding xfer so we ended with either a phase
618 * change interrupt (normal case) or an error interrupt (handled
619 * elsewhere). Reset the board dma logic then try to get the
620 * completion status & command done msg. The reset confuses
621 * the SPC REQ/ACK logic so we have to do any status/msg input
622 * operations via 'manual xfer'.
623 */
624 if (hd->scsi_ssts & SSTS_BUSY) {
625 int wait = scsi_cmd_wait;
626
627 /* wait for dma operation to finish */
628 while (hd->scsi_ssts & SSTS_BUSY) {
629 if (--wait < 0) {
630#ifdef DEBUG
631 if (scsi_debug)
632 printf("finishxfer fail: ssts %x\n",
633 hd->scsi_ssts);
634#endif
635 HIST(fxfr_wait, wait)
636 goto abort;
637 }
638 }
639 HIST(fxfr_wait, wait)
640 }
641 hd->scsi_scmd |= SCMD_PROG_XFR;
642 hd->scsi_sctl |= SCTL_CTRLRST;
643 DELAY(1);
644 hd->scsi_sctl &=~ SCTL_CTRLRST;
645 hd->scsi_hconf = 0;
646 hs->sc_stat[0] = 0xff;
647 hs->sc_msg[0] = 0xff;
648 hd->scsi_csr = 0;
649 hd->scsi_ints = ints = hd->scsi_ints;
650 while (1) {
651 phase = hd->scsi_psns & PHASE;
652 switch (phase) {
653
654 case STATUS_PHASE:
655 if (mxfer_in(hd, sizeof(hs->sc_stat), hs->sc_stat,
656 phase) <= 0)
657 goto abort;
658 break;
659
660 case MESG_IN_PHASE:
661 if (mxfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg,
662 phase) < 0)
663 goto abort;
664 break;
665
666 case BUS_FREE_PHASE:
667 return;
668
669 default:
670 printf("scsi%d: unexpected phase %d in finishxfer from %d\n",
671 hs->sc_hc->hp_unit, phase, target);
672 goto abort;
673 }
674 if (ints = hd->scsi_ints) {
675 hd->scsi_ints = ints;
676 if (ints & INTS_DISCON)
677 return;
678 else if (ints & ~(INTS_SRV_REQ|INTS_CMD_DONE)) {
679 scsierror(hs, hd, ints);
680 break;
681 }
682 }
683 if ((hd->scsi_ssts & SSTS_INITIATOR) == 0)
684 return;
685 }
686abort:
687 scsiabort(hs, hd, "finishxfer");
688 hs->sc_stat[0] = 0xfe;
689}
690
691int
692scsi_test_unit_rdy(ctlr, slave, unit)
693 int ctlr, slave, unit;
694{
695 register struct scsi_softc *hs = &scsi_softc[ctlr];
696 static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
697
698 cdb.lun = unit;
699 return (scsiicmd(hs, slave, &cdb, sizeof(cdb), (u_char *)0, 0,
700 STATUS_PHASE));
701}
702
703int
704scsi_request_sense(ctlr, slave, unit, buf, len)
705 int ctlr, slave, unit;
706 u_char *buf;
707 unsigned len;
708{
709 register struct scsi_softc *hs = &scsi_softc[ctlr];
710 static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE };
711
712 cdb.lun = unit;
713 cdb.len = len;
714 return (scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE));
715}
716
717int
718scsi_immed_command(ctlr, slave, unit, cdb, buf, len, rd)
719 int ctlr, slave, unit;
720 struct scsi_fmt_cdb *cdb;
721 u_char *buf;
722 unsigned len;
723{
724 register struct scsi_softc *hs = &scsi_softc[ctlr];
725
726 cdb->cdb[1] |= unit << 5;
727 return (scsiicmd(hs, slave, cdb->cdb, cdb->len, buf, len,
728 rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE));
729}
730
731/*
732 * The following routines are test-and-transfer i/o versions of read/write
733 * for things like reading disk labels and writing core dumps. The
734 * routine scsigo should be used for normal data transfers, NOT these
735 * routines.
736 */
737int
738scsi_tt_read(ctlr, slave, unit, buf, len, blk, bshift)
739 int ctlr, slave, unit;
740 u_char *buf;
741 u_int len;
742 daddr_t blk;
743 int bshift;
744{
745 register struct scsi_softc *hs = &scsi_softc[ctlr];
746 struct scsi_cdb10 cdb;
747 int stat;
748 int old_wait = scsi_data_wait;
749
750 scsi_data_wait = 300000;
751 bzero(&cdb, sizeof(cdb));
752 cdb.cmd = CMD_READ_EXT;
753 cdb.lun = unit;
754 blk >>= bshift;
755 cdb.lbah = blk >> 24;
756 cdb.lbahm = blk >> 16;
757 cdb.lbalm = blk >> 8;
758 cdb.lbal = blk;
759 cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
760 cdb.lenl = len >> (DEV_BSHIFT + bshift);
761 stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE);
762 scsi_data_wait = old_wait;
763 return (stat);
764}
765
766int
767scsi_tt_write(ctlr, slave, unit, buf, len, blk, bshift)
768 int ctlr, slave, unit;
769 u_char *buf;
770 u_int len;
771 daddr_t blk;
772 int bshift;
773{
774 register struct scsi_softc *hs = &scsi_softc[ctlr];
775 struct scsi_cdb10 cdb;
776 int stat;
777 int old_wait = scsi_data_wait;
778
779 scsi_data_wait = 300000;
780
781 bzero(&cdb, sizeof(cdb));
782 cdb.cmd = CMD_WRITE_EXT;
783 cdb.lun = unit;
784 blk >>= bshift;
785 cdb.lbah = blk >> 24;
786 cdb.lbahm = blk >> 16;
787 cdb.lbalm = blk >> 8;
788 cdb.lbal = blk;
789 cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
790 cdb.lenl = len >> (DEV_BSHIFT + bshift);
791 stat = scsiicmd(hs, slave, &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE);
792 scsi_data_wait = old_wait;
793 return (stat);
794}
795
796
797int
798scsireq(dq)
799 register struct devqueue *dq;
800{
801 register struct devqueue *hq;
802
803 hq = &scsi_softc[dq->dq_ctlr].sc_sq;
804 insque(dq, hq->dq_back);
805 if (dq->dq_back == hq)
806 return(1);
807 return(0);
808}
809
810int
811scsiustart(unit)
812 int unit;
813{
814 register struct scsi_softc *hs = &scsi_softc[unit];
815
816 hs->sc_dq.dq_ctlr = DMA0 | DMA1;
817 if (dmareq(&hs->sc_dq))
818 return(1);
819 return(0);
820}
821
822void
823scsistart(unit)
824 int unit;
825{
826 register struct devqueue *dq;
827
828 dq = scsi_softc[unit].sc_sq.dq_forw;
829 (dq->dq_driver->d_go)(dq->dq_unit);
830}
831
832int
833scsigo(ctlr, slave, unit, bp, cdb, pad)
834 int ctlr, slave, unit;
835 struct buf *bp;
836 struct scsi_fmt_cdb *cdb;
837 int pad;
838{
839 register struct scsi_softc *hs = &scsi_softc[ctlr];
840 volatile register struct scsidevice *hd =
841 (struct scsidevice *)hs->sc_hc->hp_addr;
842 int i, dmaflags;
843 u_char phase, ints, cmd;
844
845 cdb->cdb[1] |= unit << 5;
846
847 /* select the SCSI bus (it's an error if bus isn't free) */
848 if (issue_select(hd, slave, hs->sc_scsi_addr) || wait_for_select(hd)) {
849 dmafree(&hs->sc_dq);
850 return (1);
851 }
852 /*
853 * Wait for a phase change (or error) then let the device
854 * sequence us through command phase (we may have to take
855 * a msg in/out before doing the command). If the disk has
856 * to do a seek, it may be a long time until we get a change
857 * to data phase so, in the absense of an explicit phase
858 * change, we assume data phase will be coming up and tell
859 * the SPC to start a transfer whenever it does. We'll get
860 * a service required interrupt later if this assumption is
861 * wrong. Otherwise we'll get a service required int when
862 * the transfer changes to status phase.
863 */
864 phase = CMD_PHASE;
865 while (1) {
866 register int wait = scsi_cmd_wait;
867
868 switch (phase) {
869
870 case CMD_PHASE:
871 if (ixfer_start(hd, cdb->len, phase, wait))
872 if (ixfer_out(hd, cdb->len, cdb->cdb))
873 goto abort;
874 break;
875
876 case MESG_IN_PHASE:
877 if (ixfer_start(hd, sizeof(hs->sc_msg), phase, wait)||
878 !(hd->scsi_ssts & SSTS_DREG_EMPTY)) {
879 ixfer_in(hd, sizeof(hs->sc_msg), hs->sc_msg);
880 hd->scsi_scmd = SCMD_RST_ACK;
881 }
882 phase = BUS_FREE_PHASE;
883 break;
884
885 case DATA_IN_PHASE:
886 case DATA_OUT_PHASE:
887 goto out;
888
889 default:
890 printf("scsi%d: unexpected phase %d in go from %d\n",
891 hs->sc_hc->hp_unit, phase, slave);
892 goto abort;
893 }
894 while ((ints = hd->scsi_ints) == 0) {
895 if (--wait < 0) {
896 HIST(sgo_wait, wait)
897 goto abort;
898 }
899 DELAY(1);
900 }
901 HIST(sgo_wait, wait)
902 hd->scsi_ints = ints;
903 if (ints & INTS_SRV_REQ)
904 phase = hd->scsi_psns & PHASE;
905 else if (ints & INTS_CMD_DONE)
906 goto out;
907 else {
908 scsierror(hs, hd, ints);
909 goto abort;
910 }
911 }
912out:
913 /*
914 * Reset the card dma logic, setup the dma channel then
915 * get the dio part of the card set for a dma xfer.
916 */
917 hd->scsi_hconf = 0;
918 cmd = CSR_IE | (CSR_DE0 << hs->sc_dq.dq_ctlr);
919 dmaflags = DMAGO_NOINT;
920 if (bp->b_flags & B_READ)
921 dmaflags |= DMAGO_READ;
922 if ((hs->sc_flags & SCSI_DMA32) &&
923 ((int)bp->b_un.b_addr & 3) == 0 && (bp->b_bcount & 3) == 0) {
924 cmd |= CSR_DMA32;
925 dmaflags |= DMAGO_LWORD;
926 } else
927 dmaflags |= DMAGO_WORD;
928 dmago(hs->sc_dq.dq_ctlr, bp->b_un.b_addr, bp->b_bcount, dmaflags);
929
930 if (bp->b_flags & B_READ) {
931 cmd |= CSR_DMAIN;
932 phase = DATA_IN_PHASE;
933 } else
934 phase = DATA_OUT_PHASE;
935 hd->scsi_csr = cmd;
936 /*
937 * Setup the SPC for the transfer. We don't want to take
938 * first a command complete then a service required interrupt
939 * at the end of the transfer so we try to disable the cmd
940 * complete by setting the transfer counter to more bytes
941 * than we expect. (XXX - This strategy may have to be
942 * modified to deal with devices that return variable length
943 * blocks, e.g., some tape drives.)
944 */
945 cmd = SCMD_XFR;
946 i = (unsigned)bp->b_bcount;
947 if (pad) {
948 cmd |= SCMD_PAD;
949 /*
950 * XXX - If we don't do this, the last 2 or 4 bytes
951 * (depending on word/lword DMA) of a read get trashed.
952 * It looks like it is necessary for the DMA to complete
953 * before the SPC goes into "pad mode"??? Note: if we
954 * also do this on a write, the request never completes.
955 */
956 if (bp->b_flags & B_READ)
957 i += 2;
958#ifdef DEBUG
959 hs->sc_flags |= SCSI_PAD;
960 if (i & 1)
961 printf("scsi%d: odd byte count: %d bytes @ %d\n",
962 ctlr, i, bp->b_cylin);
963#endif
964 } else
965 i += 4;
966 hd->scsi_tch = i >> 16;
967 hd->scsi_tcm = i >> 8;
968 hd->scsi_tcl = i;
969 hd->scsi_pctl = phase;
970 hd->scsi_tmod = 0;
971 hd->scsi_scmd = cmd;
972 hs->sc_flags |= SCSI_IO;
973 return (0);
974abort:
975 scsiabort(hs, hd, "go");
976 dmafree(&hs->sc_dq);
977 return (1);
978}
979
980void
981scsidone(unit)
982 register int unit;
983{
984 volatile register struct scsidevice *hd =
985 (struct scsidevice *)scsi_softc[unit].sc_hc->hp_addr;
986
987 /* dma operation is done -- turn off card dma */
988 hd->scsi_csr &=~ (CSR_DE1|CSR_DE0);
989}
990
991int
992scsiintr(unit)
993 register int unit;
994{
995 register struct scsi_softc *hs = &scsi_softc[unit];
996 volatile register struct scsidevice *hd =
997 (struct scsidevice *)hs->sc_hc->hp_addr;
998 register u_char ints;
999 register struct devqueue *dq;
1000
1001 if ((hd->scsi_csr & (CSR_IE|CSR_IR)) != (CSR_IE|CSR_IR))
1002 return (0);
1003
1004 ints = hd->scsi_ints;
1005 if ((ints & INTS_SRV_REQ) && (hs->sc_flags & SCSI_IO)) {
1006 /*
1007 * this should be the normal i/o completion case.
1008 * get the status & cmd complete msg then let the
1009 * device driver look at what happened.
1010 */
1011#ifdef DEBUG
1012 int len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) |
1013 hd->scsi_tcl;
1014 if (!(hs->sc_flags & SCSI_PAD))
1015 len -= 4;
1016 if (len)
1017 printf("scsi%d: transfer length error %d\n", unit, len);
1018 hs->sc_flags &=~ SCSI_PAD;
1019#endif
1020 dq = hs->sc_sq.dq_forw;
1021 finishxfer(hs, hd, dq->dq_unit);
1022 hs->sc_flags &=~ SCSI_IO;
1023 dmafree(&hs->sc_dq);
1024 (dq->dq_driver->d_intr)(dq->dq_unit, hs->sc_stat[0]);
1025 } else {
1026 /* Something unexpected happened -- deal with it. */
1027 hd->scsi_ints = ints;
1028 hd->scsi_csr = 0;
1029 scsierror(hs, hd, ints);
1030 scsiabort(hs, hd, "intr");
1031 if (hs->sc_flags & SCSI_IO) {
1032 hs->sc_flags &=~ SCSI_IO;
1033 dmafree(&hs->sc_dq);
1034 dq = hs->sc_sq.dq_forw;
1035 (dq->dq_driver->d_intr)(dq->dq_unit, -1);
1036 }
1037 }
1038 return(1);
1039}
1040
1041void
1042scsifree(dq)
1043 register struct devqueue *dq;
1044{
1045 register struct devqueue *hq;
1046
1047 hq = &scsi_softc[dq->dq_ctlr].sc_sq;
1048 remque(dq);
1049 if ((dq = hq->dq_forw) != hq)
1050 (dq->dq_driver->d_start)(dq->dq_unit);
1051}
1052#endif