1 /* $NetBSD: iris_scsi.c,v 1.2 2024/02/09 22:08:33 andvar Exp $ */
2
3 /*
4 * Copyright (c) 2018 Naruaki Etomi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 * Silicon Graphics "IRIS" series MIPS processors machine bootloader.
30 * WD33C93 SCSI bus driver for standalone programs.
31 */
32
33 #include <sys/cdefs.h>
34 #include <lib/libsa/stand.h>
35
36 #ifndef INDIGO_R3K_MODE
37 #include <dev/arcbios/arcbios.h>
38 #endif
39
40 #include "iris_machdep.h"
41 #include "iris_scsivar.h"
42 #include "iris_scsireg.h"
43 #include "iris_scsicmd.h"
44 #include <dev/scsipi/scsi_message.h>
45
46 #define SBIC_WAIT(regs, until, timeo) wd33c93_wait(regs, until, timeo)
47
48 /*
49 * Timeouts
50 */
51 int wd33c93_cmd_wait = SBIC_CMD_WAIT;
52 int wd33c93_data_wait = SBIC_DATA_WAIT;
53 int wd33c93_init_wait = SBIC_INIT_WAIT;
54
55 #define STATUS_UNKNOWN 0xff
56
57 void wd33c93_reset(struct wd33c93_softc *);
58 int wd33c93_wait(struct wd33c93_softc *, uint8_t, int);
59 uint8_t wd33c93_selectbus(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
60 size_t *);
61 void wd33c93_setsync(struct wd33c93_softc *);
62 int wd33c93_nextstate(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
63 size_t *, uint8_t, uint8_t);
64 size_t wd33c93_xfout(struct wd33c93_softc *, void *, size_t *);
65 int wd33c93_intr(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
66 size_t *);
67 size_t wd33c93_xfin(struct wd33c93_softc *, void *, size_t *);
68 void wd33c93_xferdone(struct wd33c93_softc *);
69 int wd33c93_abort(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
70 size_t *);
71 int wd33c93_poll(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
72 size_t *);
73 void wd33c93_timeout(struct wd33c93_softc *, uint8_t *, size_t, uint8_t *,
74 size_t *);
75 int wd33c93_msgin_phase(struct wd33c93_softc *);
76 void wd33c93_scsistart(struct wd33c93_softc *);
77 void wd33c93_scsidone(struct wd33c93_softc *);
78 void wd33c93_error(struct wd33c93_softc *);
79
80 /*
81 * Initialize SPC & Data Structure
82 */
83 void
wd33c93_init(void * aaddr,void * daddr)84 wd33c93_init(void *aaddr, void *daddr)
85 {
86 struct wd33c93_softc *sc;
87
88 sc = &wd33c93_softc[scsi_ctlr];
89
90 sc->sc_asr_regh = aaddr;
91 sc->sc_data_regh = daddr;
92 sc->sc_target = scsi_id;
93
94 sc->sc_flags = 0;
95 sc->sc_state = SBIC_IDLE;
96
97 wd33c93_reset(sc);
98 }
99
100 void
wd33c93_reset(struct wd33c93_softc * sc)101 wd33c93_reset(struct wd33c93_softc *sc)
102 {
103 u_int my_id;
104 uint8_t csr;
105
106 SET_SBIC_cmd(sc, SBIC_CMD_ABORT);
107 WAIT_CIP(sc);
108
109 my_id = sc->sc_target & SBIC_ID_MASK;
110
111 /* Set Clock == 20.0 MHz */
112 my_id |= SBIC_ID_FS_8_10;
113 sc->sc_syncperiods = 2 * 2 * 1250 / SCSI_CLKFREQ;
114
115 SET_SBIC_myid(sc, my_id);
116
117 /* Reset the chip */
118 SET_SBIC_cmd(sc, SBIC_CMD_RESET);
119 DELAY(25);
120 SBIC_WAIT(sc, SBIC_ASR_INT, 0);
121
122 /* PIO mode */
123 SBIC_TC_PUT(sc, 0);
124 SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
125
126 /* clears interrupt also */
127 GET_SBIC_csr(sc, csr);
128 __USE(csr);
129
130 SET_SBIC_rselid(sc, SBIC_RID_ER);
131 SET_SBIC_syn(sc, 0);
132
133 sc->sc_flags = 0;
134 sc->sc_state = SBIC_IDLE;
135 }
136
137 int
wd33c93_wait(struct wd33c93_softc * sc,uint8_t until,int timeo)138 wd33c93_wait(struct wd33c93_softc *sc, uint8_t until, int timeo)
139 {
140 uint8_t val;
141
142 if (timeo == 0)
143 /* some large value.. */
144 timeo = 1000000;
145
146 GET_SBIC_asr(sc, val);
147
148 while ((val & until) == 0) {
149 if (timeo-- == 0) {
150 return val;
151 break;
152 }
153 DELAY(1);
154 GET_SBIC_asr(sc, val);
155 }
156 return val;
157 }
158
159 /* SCSI command entry point */
160 int
wd33c93_go(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp)161 wd33c93_go(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen, uint8_t *buf,
162 size_t *lenp)
163 {
164 int i;
165 uint8_t csr, asr;
166
167 wd33c93_scsistart(sc);
168
169 sc->sc_status = STATUS_UNKNOWN;
170 sc->sc_flags = 0;
171 /* select the SCSI bus (it's an error if bus isn't free) */
172 if ((csr = wd33c93_selectbus(sc, cbuf, clen, buf, lenp)) == 0)
173 /* Not done: needs to be rescheduled */
174 return 1;
175
176 /*
177 * Lets cycle a while then let the interrupt handler take over.
178 */
179 GET_SBIC_asr(sc, asr);
180 do {
181 /* Handle the new phase */
182 i = wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
183 WAIT_CIP(sc); /* XXX */
184 if (sc->sc_state == SBIC_CONNECTED) {
185 GET_SBIC_asr(sc, asr);
186
187 if ((asr & SBIC_ASR_LCI) != 0)
188 DELAY(5000);
189
190 if ((asr & SBIC_ASR_INT) != 0)
191 GET_SBIC_csr(sc, csr);
192 }
193
194 } while (sc->sc_state == SBIC_CONNECTED &&
195 (asr & (SBIC_ASR_INT|SBIC_ASR_LCI)) != 0);
196
197 if (i == SBIC_STATE_DONE) {
198 if (sc->sc_status == STATUS_UNKNOWN) {
199 printf("wd33c93_go: stat == UNKNOWN\n");
200 return 1;
201 }
202 }
203
204 if (wd33c93_poll(sc, cbuf, clen, buf, lenp)) {
205 wd33c93_timeout(sc, cbuf, clen, buf, lenp);
206 if (wd33c93_poll(sc, cbuf, clen, buf, lenp)) {
207 wd33c93_timeout(sc, cbuf, clen, buf, lenp);
208 }
209 }
210 return 0;
211 }
212
213 /*
214 * select the bus, return when selected or error.
215 *
216 * Returns the current CSR following selection and optionally MSG out phase.
217 * i.e. the returned CSR *should* indicate CMD phase...
218 * If the return value is 0, some error happened.
219 */
220 uint8_t
wd33c93_selectbus(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp)221 wd33c93_selectbus(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
222 uint8_t *buf, size_t *lenp)
223 {
224 uint8_t asr, csr, id, lun, target;
225 static int i = 0;
226
227 sc->sc_state = SBIC_SELECTING;
228
229 target = sc->sc_target;
230 lun = SCSI_LUN;
231
232 /*
233 * issue select
234 */
235 SBIC_TC_PUT(sc, 0);
236 SET_SBIC_selid(sc, target);
237 SET_SBIC_timeo(sc, SBIC_TIMEOUT(250, SCSI_CLKFREQ));
238
239 GET_SBIC_asr(sc, asr);
240
241 if ((asr & (SBIC_ASR_INT|SBIC_ASR_BSY)) != 0) {
242 return 0;
243 }
244
245 SET_SBIC_cmd(sc, SBIC_CMD_SEL_ATN);
246 WAIT_CIP(sc);
247
248 /*
249 * wait for select (merged from separate function may need
250 * cleanup)
251 */
252 do {
253 asr = SBIC_WAIT(sc, SBIC_ASR_INT | SBIC_ASR_LCI, 0);
254
255 if ((asr & SBIC_ASR_LCI) != 0) {
256 return 0;
257 }
258
259 /* Clear interrupt */
260 GET_SBIC_csr(sc, csr);
261
262 /* Reselected from under our feet? */
263 if (csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY) {
264 /*
265 * We need to handle this now so we don't lock up later
266 */
267 wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
268 return 0;
269 }
270 /* Whoops! */
271 if (csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN) {
272 return 0;
273 }
274 } while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) &&
275 csr != (SBIC_CSR_MIS_2 | CMD_PHASE) &&
276 csr != SBIC_CSR_SEL_TIMEO);
277
278 /* Anyone at home? */
279 if (csr == SBIC_CSR_SEL_TIMEO) {
280 return 0;
281 }
282
283 /* Assume we're now selected */
284 GET_SBIC_selid(sc, id);
285
286 if (id != target) {
287 /* Something went wrong - wrong target was select */
288 printf("wd33c93_selectbus: wrong target selected WANTED %d GOT %d \n",
289 target, id);
290 printf("Boot failed! Halting...\n");
291 reboot();
292 }
293
294 sc->sc_flags |= SBICF_SELECTED;
295 sc->sc_state = SBIC_CONNECTED;
296
297 /* setup correct sync mode for this target */
298 wd33c93_setsync(sc);
299 SET_SBIC_rselid(sc, SBIC_RID_ER);
300
301 /*
302 * We only really need to do anything when the target goes to MSG out
303 * If the device ignored ATN, it's probably old and brain-dead,
304 * but we'll try to support it anyhow.
305 * If it doesn't support message out, it definitely doesn't
306 * support synchronous transfers, so no point in even asking...
307 */
308
309 if (csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE)) {
310 if (i < 6) {
311 SEND_BYTE(sc, MSG_IDENTIFY(lun, 0));
312 DELAY(200000);
313 i++;
314 } else {
315 /*
316 * setup scsi message sync message request
317 */
318 sc->sc_omsg[0] = MSG_IDENTIFY(lun, 0);
319 sc->sc_omsg[1] = MSG_EXTENDED;
320 sc->sc_omsg[2] = MSG_EXT_SDTR_LEN;
321 sc->sc_omsg[3] = MSG_EXT_SDTR;
322 sc->sc_omsg[4] = sc->sc_syncperiods;
323 sc->sc_omsg[5] = SBIC_SYN_93AB_MAX_OFFSET;
324
325 size_t foo = 6;
326 size_t *bar;
327 bar = &foo;
328
329 wd33c93_xfout(sc, sc->sc_omsg, bar);
330 sc->sc_flags |= SBICF_SYNCNEGO;
331 }
332
333 SBIC_WAIT(sc, SBIC_ASR_INT , 0);
334 GET_SBIC_csr(sc, csr);
335 }
336 return csr;
337 }
338
339 /*
340 * Setup sync mode for given target
341 */
342 void
wd33c93_setsync(struct wd33c93_softc * sc)343 wd33c93_setsync(struct wd33c93_softc *sc)
344 {
345 uint8_t syncreg;
346
347 syncreg = SBIC_SYN(0, 0, 0);
348
349 SET_SBIC_syn(sc, syncreg);
350 }
351
352 /*
353 * wd33c93_nextstate()
354 * return:
355 * SBIC_STATE_DONE == done
356 * SBIC_STATE_RUNNING == working
357 * SBIC_STATE_DISCONNECT == disconnected
358 * SBIC_STATE_ERROR == error
359 */
360 int
wd33c93_nextstate(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp,uint8_t csr,uint8_t asr)361 wd33c93_nextstate(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
362 uint8_t *buf, size_t *lenp, uint8_t csr, uint8_t asr)
363 {
364 size_t *clenp;
365 size_t resid;
366
367 switch (csr) {
368 case SBIC_CSR_XFERRED | CMD_PHASE:
369 case SBIC_CSR_MIS | CMD_PHASE:
370 case SBIC_CSR_MIS_1 | CMD_PHASE:
371 case SBIC_CSR_MIS_2 | CMD_PHASE:
372 clenp = &clen;
373
374 if (wd33c93_xfout(sc, cbuf, clenp))
375 goto abort;
376 break;
377
378 case SBIC_CSR_XFERRED | STATUS_PHASE:
379 case SBIC_CSR_MIS | STATUS_PHASE:
380 case SBIC_CSR_MIS_1 | STATUS_PHASE:
381 case SBIC_CSR_MIS_2 | STATUS_PHASE:
382 SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
383
384 /*
385 * this should be the normal i/o completion case.
386 * get the status & cmd complete msg then let the
387 * device driver look at what happened.
388 */
389 wd33c93_xferdone(sc);
390 wd33c93_scsidone(sc);
391
392 return SBIC_STATE_DONE;
393
394 case SBIC_CSR_XFERRED | DATA_IN_PHASE:
395 case SBIC_CSR_MIS | DATA_IN_PHASE:
396 case SBIC_CSR_MIS_1 | DATA_IN_PHASE:
397 case SBIC_CSR_MIS_2 | DATA_IN_PHASE:
398 case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
399 case SBIC_CSR_MIS | DATA_OUT_PHASE:
400 case SBIC_CSR_MIS_1 | DATA_OUT_PHASE:
401 case SBIC_CSR_MIS_2 | DATA_OUT_PHASE:
402 /*
403 * Should we transfer using PIO or DMA ?
404 */
405 /* Perform transfer using PIO */
406 if (SBIC_PHASE(csr) == DATA_IN_PHASE){
407 /* data in */
408 resid = wd33c93_xfin(sc, buf, lenp);
409 *lenp = resid;
410 wd33c93_intr(sc, cbuf, clen, buf, lenp);
411 } else { /* data out */
412 resid = wd33c93_xfout(sc, buf, lenp);
413 *lenp = resid;
414 }
415 break;
416
417 case SBIC_CSR_XFERRED | MESG_IN_PHASE:
418 case SBIC_CSR_MIS | MESG_IN_PHASE:
419 case SBIC_CSR_MIS_1 | MESG_IN_PHASE:
420 case SBIC_CSR_MIS_2 | MESG_IN_PHASE:
421 /* Handle a single message in... */
422 return wd33c93_msgin_phase(sc);
423
424 case SBIC_CSR_MSGIN_W_ACK:
425 /*
426 * We should never see this since it's handled in
427 * 'wd33c93_msgin_phase()' but just for the sake of paranoia...
428 */
429 SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
430 break;
431
432 case SBIC_CSR_XFERRED | MESG_OUT_PHASE:
433 case SBIC_CSR_MIS | MESG_OUT_PHASE:
434 case SBIC_CSR_MIS_1 | MESG_OUT_PHASE:
435 case SBIC_CSR_MIS_2 | MESG_OUT_PHASE:
436 /*
437 * Message out phase. ATN signal has been asserted
438 */
439 return SBIC_STATE_RUNNING;
440
441 case SBIC_CSR_DISC:
442 case SBIC_CSR_DISC_1:
443 sc->sc_state = SBIC_IDLE;
444 sc->sc_flags = 0;
445
446 return SBIC_STATE_DISCONNECT;
447
448 case SBIC_CSR_RSLT_NI:
449 case SBIC_CSR_RSLT_IFY:
450 {
451 sc->sc_state = SBIC_RESELECTED;
452
453 if (csr == SBIC_CSR_RSLT_IFY)
454 SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
455 break;
456 }
457
458 default:
459 abort:
460 /* Something unexpected happend -- deal with it. */
461 printf("wd33c93_nextstate:abort\n");
462 printf("Boot failed! Halting...\n");
463 reboot();
464 }
465 return SBIC_STATE_RUNNING;
466 }
467
468 /*
469 * Information Transfer *to* a SCSI Target.
470 *
471 * Note: Don't expect there to be an interrupt immediately after all
472 * the data is transferred out. The WD spec sheet says that the Transfer-
473 * Info command for non-MSG_IN phases only completes when the target
474 * next asserts 'REQ'. That is, when the SCSI bus changes to a new state.
475 *
476 * This can have a nasty effect on commands which take a relatively long
477 * time to complete, for example a START/STOP unit command may remain in
478 * CMD phase until the disk has spun up. Only then will the target change
479 * to STATUS phase. This is really only a problem for immediate commands
480 * since we don't allow disconnection for them (yet).
481 */
482 size_t
wd33c93_xfout(struct wd33c93_softc * sc,void * bp,size_t * lenp)483 wd33c93_xfout(struct wd33c93_softc *sc, void *bp, size_t *lenp)
484 {
485
486 int wait = wd33c93_data_wait;
487 uint8_t asr, *buf = bp;
488 size_t len = *lenp;
489
490 /*
491 * sigh.. WD-PROTO strikes again.. sending the command in one go
492 * causes the chip to lock up if talking to certain (misbehaving?)
493 * targets. Anyway, this procedure should work for all targets, but
494 * it's slightly slower due to the overhead
495 */
496
497 SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
498 SBIC_TC_PUT(sc, (unsigned int)len);
499
500 WAIT_CIP(sc);
501 SET_SBIC_cmd(sc, SBIC_CMD_XFER_INFO);
502
503 /*
504 * Loop for each byte transferred
505 */
506 do {
507 GET_SBIC_asr(sc, asr);
508
509 if ((asr & SBIC_ASR_DBR) != 0) {
510 if (len != 0) {
511 SET_SBIC_data(sc, *buf);
512 buf++;
513 len--;
514 } else {
515 SET_SBIC_data(sc, 0);
516 }
517 wait = wd33c93_data_wait;
518 }
519 } while (len != 0 && (asr & SBIC_ASR_INT) == 0 && wait-- > 0);
520
521 /*
522 * Normally, an interrupt will be pending when this routing returns.
523 */
524 return len;
525 }
526
527 int
wd33c93_intr(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp)528 wd33c93_intr(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
529 uint8_t *buf, size_t *lenp)
530 {
531 uint8_t asr, csr;
532
533 /*
534 * pending interrupt?
535 */
536 GET_SBIC_asr(sc, asr);
537 if ((asr & SBIC_ASR_INT) == 0)
538 return 0;
539
540 GET_SBIC_csr(sc, csr);
541
542 do {
543
544 (void)wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr, asr);
545 WAIT_CIP(sc);
546 if (sc->sc_state == SBIC_CONNECTED) {
547 GET_SBIC_asr(sc, asr);
548
549 if ((asr & SBIC_ASR_INT) != 0)
550 GET_SBIC_csr(sc, csr);
551 }
552 } while (sc->sc_state == SBIC_CONNECTED &&
553 (asr & (SBIC_ASR_INT|SBIC_ASR_LCI)) != 0);
554
555 return 1;
556 }
557
558 /*
559 * Information Transfer *from* a Scsi Target
560 * returns # bytes left to read
561 */
562 size_t
wd33c93_xfin(struct wd33c93_softc * sc,void * bp,size_t * lenp)563 wd33c93_xfin(struct wd33c93_softc *sc, void *bp, size_t *lenp)
564 {
565 size_t len = *lenp;
566
567 int wait = wd33c93_data_wait;
568 uint8_t *buf = bp;
569 uint8_t asr;
570
571 SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
572 SBIC_TC_PUT(sc, (unsigned int)len);
573
574 WAIT_CIP(sc);
575 SET_SBIC_cmd(sc, SBIC_CMD_XFER_INFO);
576
577 /*
578 * Loop for each byte transferred
579 */
580 do {
581 GET_SBIC_asr(sc, asr);
582
583 if ((asr & SBIC_ASR_DBR) != 0) {
584 if (len != 0) {
585 GET_SBIC_data(sc, *buf);
586 buf++;
587 len--;
588 } else {
589 uint8_t foo;
590 GET_SBIC_data(sc, foo);
591 __USE(foo);
592 }
593 wait = wd33c93_data_wait;
594 }
595
596 } while ((asr & SBIC_ASR_INT) == 0 && wait-- > 0);
597
598 SBIC_TC_PUT(sc, 0);
599
600 /*
601 * this leaves with one csr to be read
602 */
603 return len;
604 }
605
606 /*
607 * Finish SCSI xfer command: After the completion interrupt from
608 * a read/write operation, sequence through the final phases in
609 * programmed i/o.
610 */
611 void
wd33c93_xferdone(struct wd33c93_softc * sc)612 wd33c93_xferdone(struct wd33c93_softc *sc)
613 {
614 uint8_t phase, csr;
615
616 /*
617 * have the wd33c93 complete on its own
618 */
619 SBIC_TC_PUT(sc, 0);
620 SET_SBIC_cmd_phase(sc, 0x46);
621 SET_SBIC_cmd(sc, SBIC_CMD_SEL_ATN_XFER);
622
623 do {
624 SBIC_WAIT(sc, SBIC_ASR_INT, 0);
625 GET_SBIC_csr(sc, csr);
626 } while ((csr != SBIC_CSR_DISC) &&
627 (csr != SBIC_CSR_DISC_1) &&
628 (csr != SBIC_CSR_S_XFERRED));
629
630 sc->sc_flags &= ~SBICF_SELECTED;
631 sc->sc_state = SBIC_DISCONNECT;
632
633 GET_SBIC_cmd_phase(sc, phase);
634
635 if (phase == 0x60)
636 GET_SBIC_tlun(sc, sc->sc_status);
637 else
638 wd33c93_error(sc);
639 }
640
641 int
wd33c93_abort(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp)642 wd33c93_abort(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
643 uint8_t *buf, size_t *lenp)
644 {
645 uint8_t csr, asr;
646
647 GET_SBIC_asr(sc, asr);
648 GET_SBIC_csr(sc, csr);
649
650 /*
651 * Clean up chip itself
652 */
653 wd33c93_timeout(sc, cbuf, clen, buf, lenp);
654
655 while ((asr & SBIC_ASR_DBR) != 0) {
656 /*
657 * wd33c93 is jammed w/data. need to clear it
658 * But we don't know what direction it needs to go
659 */
660 GET_SBIC_data(sc, asr);
661 GET_SBIC_asr(sc, asr);
662 if ((asr & SBIC_ASR_DBR) != 0)
663 /* Not the read direction */
664 SET_SBIC_data(sc, asr);
665 GET_SBIC_asr(sc, asr);
666 }
667
668 WAIT_CIP(sc);
669 SET_SBIC_cmd(sc, SBIC_CMD_ABORT);
670 WAIT_CIP(sc);
671
672 GET_SBIC_asr(sc, asr);
673
674 if ((asr & (SBIC_ASR_BSY|SBIC_ASR_LCI)) != 0) {
675 /*
676 * ok, get more drastic..
677 */
678 wd33c93_reset(sc);
679 } else {
680 SET_SBIC_cmd(sc, SBIC_CMD_DISC);
681 WAIT_CIP(sc);
682
683 do {
684 SBIC_WAIT(sc, SBIC_ASR_INT, 0);
685 GET_SBIC_asr(sc, asr);
686 GET_SBIC_csr(sc, csr);
687 } while ((csr != SBIC_CSR_DISC) &&
688 (csr != SBIC_CSR_DISC_1) &&
689 (csr != SBIC_CSR_CMD_INVALID));
690
691 sc->sc_state = SBIC_ERROR;
692 sc->sc_flags = 0;
693 }
694 return SBIC_STATE_ERROR;
695 }
696
697 void
wd33c93_timeout(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp)698 wd33c93_timeout(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
699 uint8_t *buf, size_t *lenp)
700 {
701 uint8_t asr;
702
703 GET_SBIC_asr(sc, asr);
704
705 if ((asr & SBIC_ASR_INT) != 0) {
706 /* We need to service a missed IRQ */
707 wd33c93_intr(sc, cbuf, clen, buf, lenp);
708 } else {
709 wd33c93_abort(sc, cbuf, clen, buf, lenp);
710 }
711 }
712
713 /*
714 * Complete current command using polled I/O.Used when interrupt driven
715 * I/O is not allowed (ie. during boot and shutdown)
716 *
717 * Polled I/O is very processor intensive
718 */
719 int
wd33c93_poll(struct wd33c93_softc * sc,uint8_t * cbuf,size_t clen,uint8_t * buf,size_t * lenp)720 wd33c93_poll(struct wd33c93_softc *sc, uint8_t *cbuf, size_t clen,
721 uint8_t *buf, size_t *lenp)
722 {
723 uint8_t asr, csr = 0;
724 int count;
725
726 SBIC_WAIT(sc, SBIC_ASR_INT, wd33c93_cmd_wait);
727 for (count = SBIC_ABORT_TIMEOUT; count;) {
728 GET_SBIC_asr(sc, asr);
729 if ((asr & SBIC_ASR_LCI) != 0)
730 DELAY(5000);
731
732 if ((asr & SBIC_ASR_INT) != 0) {
733 GET_SBIC_csr(sc, csr);
734 (void)wd33c93_nextstate(sc, cbuf, clen, buf, lenp, csr,
735 asr);
736 WAIT_CIP(sc);
737 } else {
738 DELAY(5000);
739 count--;
740 }
741
742 if ((sc->xs_status & XS_STS_DONE) != 0)
743 return 0;
744 }
745 return 1;
746 }
747
748 static inline int
__verify_msg_format(uint8_t * p,int len)749 __verify_msg_format(uint8_t *p, int len)
750 {
751
752 if (len == 1 && MSG_IS1BYTE(p[0]))
753 return 1;
754 if (len == 2 && MSG_IS2BYTE(p[0]))
755 return 1;
756 if (len >= 3 && MSG_ISEXTENDED(p[0]) &&
757 len == p[1] + 2)
758 return 1;
759 return 0;
760 }
761
762 /*
763 * Handle message_in phase
764 */
765 int
wd33c93_msgin_phase(struct wd33c93_softc * sc)766 wd33c93_msgin_phase(struct wd33c93_softc *sc)
767 {
768 int len;
769 uint8_t asr, csr, *msg;
770
771 GET_SBIC_asr(sc, asr);
772 __USE(asr);
773
774 GET_SBIC_selid(sc, csr);
775 SET_SBIC_selid(sc, csr | SBIC_SID_FROM_SCSI);
776
777 SBIC_TC_PUT(sc, 0);
778
779 SET_SBIC_control(sc, SBIC_CTL_EDI | SBIC_CTL_IDI);
780
781 msg = sc->sc_imsg;
782 len = 0;
783
784 do {
785 /* Fetch the next byte of the message */
786 RECV_BYTE(sc, *msg++);
787 len++;
788
789 /*
790 * get the command completion interrupt, or we
791 * can't send a new command (LCI)
792 */
793 SBIC_WAIT(sc, SBIC_ASR_INT, 0);
794 GET_SBIC_csr(sc, csr);
795
796 if (__verify_msg_format(sc->sc_imsg, len))
797 /* Complete message received */
798 break;
799
800 /*
801 * Clear ACK, and wait for the interrupt
802 * for the next byte or phase change
803 */
804 SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
805 SBIC_WAIT(sc, SBIC_ASR_INT, 0);
806
807 GET_SBIC_csr(sc, csr);
808 } while (len < SBIC_MAX_MSGLEN);
809
810 /*
811 * Clear ACK, and wait for the interrupt
812 * for the phase change
813 */
814 SET_SBIC_cmd(sc, SBIC_CMD_CLR_ACK);
815 SBIC_WAIT(sc, SBIC_ASR_INT, 0);
816
817 /* Should still have one CSR to read */
818 return SBIC_STATE_RUNNING;
819 }
820
821 void
wd33c93_scsistart(struct wd33c93_softc * sc)822 wd33c93_scsistart(struct wd33c93_softc *sc)
823 {
824
825 sc->xs_status = 0;
826 }
827
828 void
wd33c93_scsidone(struct wd33c93_softc * sc)829 wd33c93_scsidone(struct wd33c93_softc *sc)
830 {
831
832 sc->xs_status = XS_STS_DONE;
833 }
834
835 void
wd33c93_error(struct wd33c93_softc * sc)836 wd33c93_error(struct wd33c93_softc *sc)
837 {
838 }
839