xref: /netbsd-src/sys/arch/sgimips/stand/common/iris_scsi.c (revision 100a3398b8d3c64e571cff36b46c23431b410e09)
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