xref: /openbsd-src/sys/dev/isa/wds.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: wds.c,v 1.28 2009/02/16 21:19:07 miod Exp $	*/
2 /*	$NetBSD: wds.c,v 1.13 1996/11/03 16:20:31 mycroft Exp $	*/
3 
4 #undef	WDSDIAG
5 #ifdef DDB
6 #define	integrate
7 #else
8 #define	integrate	static inline
9 #endif
10 
11 /*
12  * XXX
13  * sense data
14  * aborts
15  * resets
16  */
17 
18 /*
19  * Copyright (c) 1994, 1995 Julian Highfield.  All rights reserved.
20  * Portions copyright (c) 1994, 1996 Charles M. Hannum.  All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *	This product includes software developed by Julian Highfield.
33  * 4. The name of the author may not be used to endorse or promote products
34  *    derived from this software without specific prior written permission.
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
37  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
39  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
40  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
45  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46  */
47 
48 /*
49  * This driver is for the WD7000 family of SCSI controllers:
50  *   the WD7000-ASC, a bus-mastering DMA controller,
51  *   the WD7000-FASST2, an -ASC with new firmware and scatter-gather,
52  *   and the WD7000-ASE, which was custom manufactured for Apollo
53  *      workstations and seems to include an -ASC as well as floppy
54  *      and ESDI interfaces.
55  *
56  * Loosely based on Theo Deraadt's unfinished attempt says the NetBSD group
57  * so they decided to delete the copyright that file had on it.
58  */
59 
60 #include <sys/types.h>
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
64 #include <sys/errno.h>
65 #include <sys/ioctl.h>
66 #include <sys/device.h>
67 #include <sys/malloc.h>
68 #include <sys/buf.h>
69 #include <sys/proc.h>
70 #include <sys/user.h>
71 
72 #include <machine/bus.h>
73 #include <machine/intr.h>
74 
75 #include <scsi/scsi_all.h>
76 #include <scsi/scsiconf.h>
77 
78 #include <dev/isa/isavar.h>
79 #include <dev/isa/isadmavar.h>
80 #include <dev/isa/wdsreg.h>
81 
82 #ifndef DDB
83 #define Debugger() panic("should call debugger here (wds.c)")
84 #endif /* ! DDB */
85 
86 #define WDS_MBX_SIZE	16
87 
88 #define WDS_SCB_MAX	32
89 #define	SCB_HASH_SIZE	32	/* hash table size for phystokv */
90 #define	SCB_HASH_SHIFT	9
91 #define	SCB_HASH(x)	((((long)(x))>>SCB_HASH_SHIFT) & (SCB_HASH_SIZE - 1))
92 
93 #define	wds_nextmbx(wmb, mbx, mbio) \
94 	if ((wmb) == &(mbx)->mbio[WDS_MBX_SIZE - 1])	\
95 		(wmb) = &(mbx)->mbio[0];		\
96 	else						\
97 		(wmb)++;
98 
99 struct wds_mbx {
100 	struct wds_mbx_out mbo[WDS_MBX_SIZE];
101 	struct wds_mbx_in mbi[WDS_MBX_SIZE];
102 	struct wds_mbx_out *cmbo;	/* Collection Mail Box out */
103 	struct wds_mbx_out *tmbo;	/* Target Mail Box out */
104 	struct wds_mbx_in *tmbi;	/* Target Mail Box in */
105 };
106 
107 #define	KVTOPHYS(x)	vtophys((vaddr_t)(x))
108 
109 struct wds_softc {
110 	struct device sc_dev;
111 	struct isadev sc_id;
112 	void *sc_ih;
113 
114 	bus_space_tag_t sc_iot;		/* bus identifier */
115 	bus_space_handle_t sc_ioh;	/* io handle */
116 	int sc_irq, sc_drq;
117 
118 	int sc_revision;
119 
120 	struct wds_mbx sc_mbx;
121 #define	wmbx	(&sc->sc_mbx)
122 	struct wds_scb *sc_scbhash[SCB_HASH_SIZE];
123 	TAILQ_HEAD(, wds_scb) sc_free_scb, sc_waiting_scb;
124 	int sc_numscbs, sc_mbofull;
125 	int sc_scsi_dev;
126 	struct scsi_link sc_link;	/* prototype for subdevs */
127 };
128 
129 /* Define the bounce buffer length... */
130 #define BUFLEN (64*1024)
131 /* ..and how many there are. One per device! Non-FASST boards need these. */
132 #define BUFCNT 8
133 /* The macro for deciding whether the board needs a buffer. */
134 #define NEEDBUFFER(sc)	(sc->sc_revision < 0x800)
135 
136 struct wds_buf {
137 	u_char data[BUFLEN];
138 	int    busy;
139 	TAILQ_ENTRY(wds_buf) chain;
140 } wds_buffer[BUFCNT];
141 
142 TAILQ_HEAD(, wds_buf) wds_free_buffer;
143 
144 #ifdef WDSDEBUG
145 int wds_debug = WDSDEBUG;
146 #endif
147 
148 integrate void    wds_wait(bus_space_tag_t, bus_space_handle_t, int, int, int);
149 int     wds_cmd(struct wds_softc *, u_char *, int);
150 integrate void wds_finish_scbs(struct wds_softc *);
151 int     wdsintr(void *);
152 integrate void wds_reset_scb(struct wds_softc *, struct wds_scb *);
153 void    wds_free_scb(struct wds_softc *, struct wds_scb *);
154 void	wds_free_buf(struct wds_softc *, struct wds_buf *);
155 integrate void wds_init_scb(struct wds_softc *, struct wds_scb *);
156 struct	wds_scb *wds_get_scb(struct wds_softc *, int, int);
157 struct	wds_buf *wds_get_buf(struct wds_softc *, int);
158 struct	wds_scb *wds_scb_phys_kv(struct wds_softc *, u_long);
159 void	wds_queue_scb(struct wds_softc *, struct wds_scb *);
160 void	wds_collect_mbo(struct wds_softc *);
161 void	wds_start_scbs(struct wds_softc *);
162 void    wds_done(struct wds_softc *, struct wds_scb *, u_char);
163 int	wds_find(struct isa_attach_args *, struct wds_softc *);
164 void	wds_init(struct wds_softc *);
165 void	wds_inquire_setup_information(struct wds_softc *);
166 void    wdsminphys(struct buf *, struct scsi_link *);
167 int     wds_scsi_cmd(struct scsi_xfer *);
168 void	wds_sense(struct wds_softc *, struct wds_scb *);
169 int	wds_poll(struct wds_softc *, struct scsi_xfer *, int);
170 int	wds_ipoll(struct wds_softc *, struct wds_scb *, int);
171 void	wds_timeout(void *);
172 int	wdsprint(void *, const char *);
173 
174 struct scsi_adapter wds_switch = {
175 	wds_scsi_cmd,
176 	wdsminphys,
177 	0,
178 	0,
179 };
180 
181 /* the below structure is so we have a default dev struct for our link struct */
182 struct scsi_device wds_dev = {
183 	NULL,			/* Use default error handler */
184 	NULL,			/* have a queue, served by this */
185 	NULL,			/* have no async handler */
186 	NULL,			/* Use default 'done' routine */
187 };
188 
189 int	wdsprobe(struct device *, void *, void *);
190 void	wdsattach(struct device *, struct device *, void *);
191 
192 struct cfattach wds_ca = {
193 	sizeof(struct wds_softc), wdsprobe, wdsattach
194 };
195 
196 struct cfdriver wds_cd = {
197 	NULL, "wds", DV_DULL
198 };
199 
200 #define	WDS_ABORT_TIMEOUT	2000	/* time to wait for abort (mSec) */
201 
202 integrate void
203 wds_wait(iot, ioh, port, mask, val)
204 	bus_space_tag_t iot;
205 	bus_space_handle_t ioh;
206 	int port;
207 	int mask;
208 	int val;
209 {
210 	while ((bus_space_read_1(iot, ioh, port) & mask) != val)
211 		;
212 }
213 
214 /*
215  * Write a command to the board's I/O ports.
216  */
217 int
218 wds_cmd(sc, ibuf, icnt)
219 	struct wds_softc *sc;
220 	u_int8_t *ibuf;
221 	int icnt;
222 {
223 	bus_space_tag_t iot = sc->sc_iot;
224 	bus_space_handle_t ioh = sc->sc_ioh;
225 	u_int8_t c;
226 
227 	wds_wait(iot, ioh, WDS_STAT, WDSS_RDY, WDSS_RDY);
228 
229 	while (icnt--) {
230 		bus_space_write_1(iot, ioh, WDS_CMD, *ibuf++);
231 		wds_wait(iot, ioh, WDS_STAT, WDSS_RDY, WDSS_RDY);
232 		c = bus_space_read_1(iot, ioh, WDS_STAT);
233 		if (c & WDSS_REJ)
234 			return 1;
235 	}
236 
237 	return 0;
238 }
239 
240 /*
241  * Check for the presence of a WD7000 SCSI controller.
242  */
243 int
244 wdsprobe(parent, match, aux)
245 	struct device *parent;
246 	void *match, *aux;
247 {
248 	register struct isa_attach_args *ia = aux;
249 	bus_space_tag_t iot = ia->ia_iot;
250 	bus_space_handle_t ioh;
251 	int rv;
252 
253 	if (bus_space_map(iot, ia->ia_iobase, WDS_IO_PORTS, 0, &ioh))
254 		return (0);
255 
256 	/* See if there is a unit at this location. */
257 	rv = wds_find(ia, NULL);
258 
259 	bus_space_unmap(iot, ioh, WDS_IO_PORTS);
260 
261 	if (rv) {
262 		ia->ia_msize = 0;
263 		ia->ia_iosize = WDS_IO_PORTS;
264 	}
265 
266 	return (rv);
267 }
268 
269 int
270 wdsprint(aux, name)
271 	void *aux;
272 	const char *name;
273 {
274 
275 	if (name != NULL)
276 		printf("%s: scsibus ", name);
277 	return UNCONF;
278 }
279 
280 /*
281  * Attach all available units.
282  */
283 void
284 wdsattach(parent, self, aux)
285 	struct device *parent, *self;
286 	void *aux;
287 {
288 	struct isa_attach_args *ia = aux;
289 	struct wds_softc *sc = (void *)self;
290 	struct scsibus_attach_args saa;
291 	bus_space_tag_t iot = ia->ia_iot;
292 	bus_space_handle_t ioh;
293 
294 	if (bus_space_map(iot, ia->ia_iobase, WDS_IO_PORTS, 0, &ioh)) {
295 		printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
296 		return;
297 	}
298 
299 	if (!wds_find(ia, sc))
300 		panic("wdsattach: wds_find of %s failed", self->dv_xname);
301 	wds_init(sc);
302 
303 	if (sc->sc_drq != DRQUNK)
304 		isadma_cascade(sc->sc_drq);
305 
306 	TAILQ_INIT(&sc->sc_free_scb);
307 	TAILQ_INIT(&sc->sc_waiting_scb);
308 	wds_inquire_setup_information(sc);
309 
310 	/*
311 	 * fill in the prototype scsi_link.
312 	 */
313 #ifdef notyet
314 	sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
315 #endif
316 	sc->sc_link.adapter_softc = sc;
317 	sc->sc_link.adapter_target = sc->sc_scsi_dev;
318 	sc->sc_link.adapter = &wds_switch;
319 	sc->sc_link.device = &wds_dev;
320 	/* XXX */
321 	/* I don't think the -ASE can handle openings > 1. */
322 	/* It gives Vendor Error 26 whenever I try it.     */
323 	sc->sc_link.openings = 1;
324 
325 	sc->sc_ih = isa_intr_establish(ia->ia_ic, sc->sc_irq, IST_EDGE,
326 	    IPL_BIO, wdsintr, sc, sc->sc_dev.dv_xname);
327 
328 	bzero(&saa, sizeof(saa));
329 	saa.saa_sc_link = &sc->sc_link;
330 
331 	/*
332 	 * ask the adapter what subunits are present
333 	 */
334 	config_found(self, &saa, wdsprint);
335 }
336 
337 integrate void
338 wds_finish_scbs(sc)
339 	struct wds_softc *sc;
340 {
341 	struct wds_mbx_in *wmbi;
342 	struct wds_scb *scb;
343 	int i;
344 
345 	wmbi = wmbx->tmbi;
346 
347 	if (wmbi->stat == WDS_MBI_FREE) {
348 		for (i = 0; i < WDS_MBX_SIZE; i++) {
349 			if (wmbi->stat != WDS_MBI_FREE) {
350 				printf("%s: mbi not in round-robin order\n",
351 				    sc->sc_dev.dv_xname);
352 				goto AGAIN;
353 			}
354 			wds_nextmbx(wmbi, wmbx, mbi);
355 		}
356 #ifdef WDSDIAGnot
357 		printf("%s: mbi interrupt with no full mailboxes\n",
358 		    sc->sc_dev.dv_xname);
359 #endif
360 		return;
361 	}
362 
363 AGAIN:
364 	do {
365 		scb = wds_scb_phys_kv(sc, phystol(wmbi->scb_addr));
366 		if (!scb) {
367 			printf("%s: bad mbi scb pointer; skipping\n",
368 			    sc->sc_dev.dv_xname);
369 			goto next;
370 		}
371 
372 #ifdef WDSDEBUG
373 		if (wds_debug) {
374 			u_int8_t *cp = (u_int8_t *)&scb->cmd.scb;
375 			printf("op=%x %x %x %x %x %x\n",
376 			    cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
377 			printf("stat %x for mbi addr = 0x%08x, ",
378 			    wmbi->stat, wmbi);
379 			printf("scb addr = 0x%x\n", scb);
380 		}
381 #endif /* WDSDEBUG */
382 
383 		timeout_del(&scb->xs->stimeout);
384 #ifdef notyet
385 		isadma_copyfrombuf((caddr_t)scb, SCB_PHYS_SIZE,
386 		    1, scb->scb_phys);
387 #endif
388 		wds_done(sc, scb, wmbi->stat);
389 
390 	next:
391 		wmbi->stat = WDS_MBI_FREE;
392 		wds_nextmbx(wmbi, wmbx, mbi);
393 	} while (wmbi->stat != WDS_MBI_FREE);
394 
395 	wmbx->tmbi = wmbi;
396 }
397 
398 /*
399  * Process an interrupt.
400  */
401 int
402 wdsintr(arg)
403 	void *arg;
404 {
405 	struct wds_softc *sc = arg;
406 	bus_space_tag_t iot = sc->sc_iot;
407 	bus_space_handle_t ioh = sc->sc_ioh;
408 	u_char c;
409 
410 	/* Was it really an interrupt from the board? */
411 	if ((bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_IRQ) == 0)
412 		return 0;
413 
414 	/* Get the interrupt status byte. */
415 	c = bus_space_read_1(iot, ioh, WDS_IRQSTAT) & WDSI_MASK;
416 
417 	/* Acknowledge (which resets) the interrupt. */
418 	bus_space_write_1(iot, ioh, WDS_IRQACK, 0x00);
419 
420 	switch (c) {
421 	case WDSI_MSVC:
422 		wds_finish_scbs(sc);
423 		break;
424 
425 	case WDSI_MFREE:
426 		wds_start_scbs(sc);
427 		break;
428 
429 	default:
430 		printf("%s: unrecognized interrupt type %02x",
431 		    sc->sc_dev.dv_xname, c);
432 		break;
433 	}
434 
435 	return 1;
436 }
437 
438 integrate void
439 wds_reset_scb(sc, scb)
440 	struct wds_softc *sc;
441 	struct wds_scb *scb;
442 {
443 
444 	scb->flags = 0;
445 }
446 
447 /*
448  * Free the command structure, the outgoing mailbox and the data buffer.
449  */
450 void
451 wds_free_scb(sc, scb)
452 	struct wds_softc *sc;
453 	struct wds_scb *scb;
454 {
455 	int s;
456 
457 	if (scb->buf != 0) {
458 		wds_free_buf(sc, scb->buf);
459 		scb->buf = 0;
460 	}
461 
462 	s = splbio();
463 
464 #ifdef notyet
465 	if (scb->scb_phys[0].addr)
466 	        isadma_unmap((caddr_t)scb, SCB_PHYS_SIZE, 1, scb->scb_phys);
467 #endif
468 
469 	wds_reset_scb(sc, scb);
470 	TAILQ_INSERT_HEAD(&sc->sc_free_scb, scb, chain);
471 
472 	/*
473 	 * If there were none, wake anybody waiting for one to come free,
474 	 * starting with queued entries.
475 	 */
476 	if (TAILQ_NEXT(scb, chain) == NULL)
477 		wakeup(&sc->sc_free_scb);
478 
479 	splx(s);
480 }
481 
482 void
483 wds_free_buf(sc, buf)
484 	struct wds_softc *sc;
485 	struct wds_buf *buf;
486 {
487 	int s;
488 
489 	s = splbio();
490 
491 	buf->busy = 0;
492 	TAILQ_INSERT_HEAD(&wds_free_buffer, buf, chain);
493 
494 	/*
495 	 * If there were none, wake anybody waiting for one to come free,
496 	 * starting with queued entries.
497 	 */
498 	if (TAILQ_NEXT(buf, chain) == NULL)
499 		wakeup(&wds_free_buffer);
500 
501 	splx(s);
502 }
503 
504 integrate void
505 wds_init_scb(sc, scb)
506 	struct wds_softc *sc;
507 	struct wds_scb *scb;
508 {
509 	int hashnum;
510 
511 	bzero(scb, sizeof(struct wds_scb));
512 	/*
513 	 * put in the phystokv hash table
514 	 * Never gets taken out.
515 	 */
516 	scb->hashkey = KVTOPHYS(scb);
517 	hashnum = SCB_HASH(scb->hashkey);
518 	scb->nexthash = sc->sc_scbhash[hashnum];
519 	sc->sc_scbhash[hashnum] = scb;
520 	wds_reset_scb(sc, scb);
521 }
522 
523 /*
524  * Get a free scb
525  *
526  * If there are none, see if we can allocate a new one.  If so, put it in
527  * the hash table too otherwise either return an error or sleep.
528  */
529 struct wds_scb *
530 wds_get_scb(sc, flags, needbuffer)
531 	struct wds_softc *sc;
532 	int flags;
533 	int needbuffer;
534 {
535 	struct wds_scb *scb;
536 	int s;
537 #ifdef notyet
538 	int mflags, hashnum;
539 #endif
540 
541 	s = splbio();
542 
543 #ifdef notyet
544 	if (flags & SCSI_NOSLEEP)
545 		mflags = ISADMA_MAP_BOUNCE;
546 	else
547 		mflags = ISADMA_MAP_BOUNCE | ISADMA_MAP_WAITOK;
548 #endif
549 
550 	/*
551 	 * If we can and have to, sleep waiting for one to come free
552 	 * but only if we can't allocate a new one.
553 	 */
554 	for (;;) {
555 		scb = TAILQ_FIRST(&sc->sc_free_scb);
556 		if (scb) {
557 			TAILQ_REMOVE(&sc->sc_free_scb, scb, chain);
558 			break;
559 		}
560 		if (sc->sc_numscbs < WDS_SCB_MAX) {
561 			scb = (struct wds_scb *) malloc(sizeof(struct wds_scb),
562 			    M_TEMP, M_NOWAIT);
563 			if (!scb) {
564 				printf("%s: can't malloc scb\n",
565 				    sc->sc_dev.dv_xname);
566 				goto out;
567 			}
568 			wds_init_scb(sc, scb);
569 			sc->sc_numscbs++;
570 			break;
571 		}
572 		if ((flags & SCSI_NOSLEEP) != 0)
573 			goto out;
574 		tsleep(&sc->sc_free_scb, PRIBIO, "wdsscb", 0);
575 	}
576 
577 	scb->flags |= SCB_ALLOC;
578 
579 #ifdef notyet
580 	if (isadma_map((caddr_t)scb, SCB_PHYS_SIZE, scb->scb_phys,
581 	    mflags | ISADMA_MAP_CONTIG) == 1) {
582 		hashnum = SCB_HASH(scb->scb_phys[0].addr);
583 		scb->nexthash = sc->sc_scbhash[hashnum];
584 		sc->sc_scbhash[hashnum] = ccb;
585 	} else {
586 		scb->scb_phys[0].addr = 0;
587 		wds_free_scb(sc, scb);
588 		scb = 0;
589 	}
590 #else
591 	if (needbuffer) {
592 		scb->buf = wds_get_buf(sc, flags);
593 		if (scb->buf == 0) {
594 			wds_free_scb(sc, scb);
595 			scb = 0;
596 		}
597 	}
598 #endif
599 
600 
601 out:
602 	splx(s);
603 	return (scb);
604 }
605 
606 struct wds_buf *
607 wds_get_buf(sc, flags)
608 	struct wds_softc *sc;
609 	int flags;
610 {
611 	struct wds_buf *buf;
612 	int s;
613 
614 	s = splbio();
615 
616 	for (;;) {
617 		buf = TAILQ_FIRST(&wds_free_buffer);
618 		if (buf) {
619 			TAILQ_REMOVE(&wds_free_buffer, buf, chain);
620 			break;
621 		}
622 		if ((flags & SCSI_NOSLEEP) != 0)
623 			goto out;
624 		tsleep(&wds_free_buffer, PRIBIO, "wdsbuf", 0);
625 	}
626 
627 	buf->busy = 1;
628 
629 out:
630 	splx(s);
631 	return (buf);
632 }
633 
634 struct wds_scb *
635 wds_scb_phys_kv(sc, scb_phys)
636 	struct wds_softc *sc;
637 	u_long scb_phys;
638 {
639 	int hashnum = SCB_HASH(scb_phys);
640 	struct wds_scb *scb = sc->sc_scbhash[hashnum];
641 
642 	while (scb) {
643 		if (scb->hashkey == scb_phys)
644 			break;
645 		/* XXX Check to see if it matches the sense command block. */
646 		if (scb->hashkey == (scb_phys - sizeof(struct wds_cmd)))
647 			break;
648 		scb = scb->nexthash;
649 	}
650 	return scb;
651 }
652 
653 /*
654  * Queue a SCB to be sent to the controller, and send it if possible.
655  */
656 void
657 wds_queue_scb(sc, scb)
658 	struct wds_softc *sc;
659 	struct wds_scb *scb;
660 {
661 
662 	TAILQ_INSERT_TAIL(&sc->sc_waiting_scb, scb, chain);
663 	wds_start_scbs(sc);
664 }
665 
666 /*
667  * Garbage collect mailboxes that are no longer in use.
668  */
669 void
670 wds_collect_mbo(sc)
671 	struct wds_softc *sc;
672 {
673 	struct wds_mbx_out *wmbo;	/* Mail Box Out pointer */
674 #ifdef WDSDIAG
675 	struct wds_scb *scb;
676 #endif
677 
678 	wmbo = wmbx->cmbo;
679 
680 	while (sc->sc_mbofull > 0) {
681 		if (wmbo->cmd != WDS_MBO_FREE)
682 			break;
683 
684 #ifdef WDSDIAG
685 		scb = wds_scb_phys_kv(sc, phystol(wmbo->scb_addr));
686 		scb->flags &= ~SCB_SENDING;
687 #endif
688 
689 		--sc->sc_mbofull;
690 		wds_nextmbx(wmbo, wmbx, mbo);
691 	}
692 
693 	wmbx->cmbo = wmbo;
694 }
695 
696 /*
697  * Send as many SCBs as we have empty mailboxes for.
698  */
699 void
700 wds_start_scbs(sc)
701 	struct wds_softc *sc;
702 {
703 	struct wds_mbx_out *wmbo;	/* Mail Box Out pointer */
704 	struct wds_scb *scb;
705 	u_char c;
706 
707 	wmbo = wmbx->tmbo;
708 
709 	while ((scb = TAILQ_FIRST(&sc->sc_waiting_scb)) != NULL) {
710 		if (sc->sc_mbofull >= WDS_MBX_SIZE) {
711 			wds_collect_mbo(sc);
712 			if (sc->sc_mbofull >= WDS_MBX_SIZE) {
713 				c = WDSC_IRQMFREE;
714 				wds_cmd(sc, &c, sizeof c);
715 				break;
716 			}
717 		}
718 
719 		TAILQ_REMOVE(&sc->sc_waiting_scb, scb, chain);
720 #ifdef WDSDIAG
721 		scb->flags |= SCB_SENDING;
722 #endif
723 
724 		/* Link scb to mbo. */
725 #ifdef notyet
726 		isadma_copytobuf((caddr_t)scb, SCB_PHYS_SIZE,
727 		    1, scb->scb_phys);
728 		ltophys(scb->scb_phys[0].addr, wmbo->scb_addr);
729 #else
730 		if (scb->flags & SCB_SENSE)
731 			ltophys(KVTOPHYS(&scb->sense), wmbo->scb_addr);
732 		else
733 			ltophys(KVTOPHYS(&scb->cmd), wmbo->scb_addr);
734 #endif
735 		/* XXX What about aborts? */
736 		wmbo->cmd = WDS_MBO_START;
737 
738 		/* Tell the card to poll immediately. */
739 		c = WDSC_MSTART(wmbo - wmbx->mbo);
740 		wds_cmd(sc, &c, sizeof c);
741 
742 		if ((scb->flags & SCB_POLLED) == 0) {
743 			timeout_set(&scb->xs->stimeout, wds_timeout, scb);
744 			timeout_add_msec(&scb->xs->stimeout, scb->timeout);
745 		}
746 
747 		++sc->sc_mbofull;
748 		wds_nextmbx(wmbo, wmbx, mbo);
749 	}
750 
751 	wmbx->tmbo = wmbo;
752 }
753 
754 /*
755  * Process the result of a SCSI command.
756  */
757 void
758 wds_done(sc, scb, stat)
759 	struct wds_softc *sc;
760 	struct wds_scb *scb;
761 	u_int8_t stat;
762 {
763 	struct scsi_xfer *xs = scb->xs;
764 
765 	/* XXXXX */
766 
767 	/* Don't release the SCB if it was an internal command. */
768 	if (xs == 0) {
769 		scb->flags |= SCB_DONE;
770 		return;
771 	}
772 
773 	/* Sense handling. */
774 	if (xs->error == XS_SENSE) {
775 		bcopy(&scb->sense_data, &xs->sense, sizeof (struct scsi_sense_data));
776 	} else {
777 		if (xs->error == XS_NOERROR) {
778 			/* If all went well, or an error is acceptable. */
779 			if (stat == WDS_MBI_OK) {
780 				/* OK, set the result */
781 				xs->resid = 0;
782 			} else {
783 				/* Check the mailbox status. */
784 				switch (stat) {
785 				case WDS_MBI_OKERR:
786 					/* SCSI error recorded in scb, counts as WDS_MBI_OK */
787 					switch (scb->cmd.venderr) {
788 					case 0x00:
789 						printf("%s: Is this an error?\n", sc->sc_dev.dv_xname);
790 						xs->error = XS_DRIVER_STUFFUP; /* Experiment */
791 						break;
792 					case 0x01:
793 						/*printf("%s: OK, see SCSI error field.\n", sc->sc_dev.dv_xname);*/
794 						if (scb->cmd.stat == SCSI_CHECK) {
795 							/* Do sense. */
796 							wds_sense (sc, scb);
797 							return;
798 						} else if (scb->cmd.stat == SCSI_BUSY) {
799 							xs->error = XS_BUSY;
800 						}
801 						break;
802 					case 0x40:
803 						/*printf("%s: DMA underrun!\n", sc->sc_dev.dv_xname);*/
804 						/* Hits this if the target returns fewer that datalen bytes (eg my CD-ROM,
805 						which returns a short version string, or if DMA is turned off etc. */
806 						xs->resid = 0;
807 						break;
808 					default:
809 						printf("%s: VENDOR ERROR %02x, scsi %02x\n", sc->sc_dev.dv_xname, scb->cmd.venderr, scb->cmd.stat);
810 						xs->error = XS_DRIVER_STUFFUP; /* Experiment */
811 						break;
812 					}
813 					break;
814 				case WDS_MBI_ETIME:
815 					/*
816 					 * The documentation isn't clear on
817 					 * what conditions might generate this,
818 					 * but selection timeouts are the only
819 					 * one I can think of.
820 					 */
821 					xs->error = XS_SELTIMEOUT;
822 					break;
823 				case WDS_MBI_ERESET:
824 				case WDS_MBI_ETARCMD:
825 				case WDS_MBI_ERESEL:
826 				case WDS_MBI_ESEL:
827 				case WDS_MBI_EABORT:
828 				case WDS_MBI_ESRESET:
829 				case WDS_MBI_EHRESET:
830 					xs->error = XS_DRIVER_STUFFUP;
831 					break;
832 				}
833 			}
834 		} /* else sense */
835 
836 		if (NEEDBUFFER(sc) && xs->datalen) {
837 			if (xs->flags & SCSI_DATA_IN)
838 				bcopy(scb->buf->data, xs->data, xs->datalen);
839 		}
840 	} /* XS_NOERROR */
841 
842 #ifdef notyet
843 	if (scb->data_nseg) {
844 		if (xs->flags & SCSI_DATA_IN)
845 			isadma_copyfrombuf(xs->data, xs->datalen,
846 			    scb->data_nseg, scb->data_phys);
847 		isadma_unmap(xs->data, xs->datalen,
848 		    scb->data_nseg, scb->data_phys);
849 	}
850 #endif
851 	wds_free_scb(sc, scb);
852 	xs->flags |= ITSDONE;
853 	scsi_done(xs);
854 }
855 
856 int
857 wds_find(ia, sc)
858 	struct isa_attach_args *ia;
859 	struct wds_softc *sc;
860 {
861 	bus_space_tag_t iot = ia->ia_iot;
862 	bus_space_handle_t ioh;
863 	u_char c;
864 	int i;
865 
866 	/*
867 	 * Sending a command causes the CMDRDY bit to clear.
868 	 */
869 	c = bus_space_read_1(iot, ioh, WDS_STAT);
870 	for (i = 0; i < 4; i++)
871 		if ((bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_RDY) != 0) {
872 			goto ready;
873 		delay(10);
874 	}
875 	return (0);
876 
877 ready:
878 	bus_space_write_1(iot, ioh, WDS_CMD, WDSC_NOOP);
879 	if (bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_RDY)
880 		return (0);
881 
882 	bus_space_write_1(iot, ioh, WDS_HCR, WDSH_SCSIRESET|WDSH_ASCRESET);
883 	delay(10000);
884 	bus_space_write_1(iot, ioh, WDS_HCR, 0x00);
885 	delay(500000);
886 	wds_wait(iot, ioh, WDS_STAT, WDSS_RDY, WDSS_RDY);
887 	if (bus_space_read_1(iot, ioh, WDS_IRQSTAT) != 1)
888 		if (bus_space_read_1(iot, ioh, WDS_IRQSTAT) != 7)
889 			printf("%s: failed reset!!! %2x\n",
890 			    sc ? sc->sc_dev.dv_xname : "wds?",
891 			    bus_space_read_1(iot, ioh, WDS_IRQSTAT));
892 
893 	if ((bus_space_read_1(iot, ioh, WDS_STAT) & (WDSS_RDY)) != WDSS_RDY) {
894 		printf("%s: waiting for controller to become ready.",
895 		    sc ? sc->sc_dev.dv_xname : "wds?");
896 		for (i = 0; i < 20; i++) {
897 			if ((bus_space_read_1(iot, ioh, WDS_STAT) &
898 			    (WDSS_RDY)) == WDSS_RDY)
899 				break;
900 			printf(".");
901 			delay(10000);
902 		}
903 		if ((bus_space_read_1(iot, ioh, WDS_STAT) & (WDSS_RDY)) !=
904 		    WDSS_RDY) {
905 			printf(" failed\n");
906 			return (0);
907 		}
908 		printf("\n");
909 	}
910 
911 	if (sc != NULL) {
912 		/* XXX Can we do this better? */
913 		/* who are we on the scsi bus? */
914 		sc->sc_scsi_dev = 7;
915 
916 		sc->sc_iot = iot;
917 		sc->sc_ioh = ioh;
918 		sc->sc_irq = ia->ia_irq;
919 		sc->sc_drq = ia->ia_drq;
920 	}
921 
922 	return (1);
923 }
924 
925 /*
926  * Initialise the board and driver.
927  */
928 void
929 wds_init(sc)
930 	struct wds_softc *sc;
931 {
932 	bus_space_tag_t iot = sc->sc_iot;
933 	bus_space_handle_t ioh = sc->sc_ioh;
934 	struct wds_setup init;
935 	u_char c;
936 	int i;
937 #ifdef notyet
938 	struct isadma_seg mbx_phys[1];
939 #endif
940 
941 	/*
942 	 * Set up initial mail box for round-robin operation.
943 	 */
944 	for (i = 0; i < WDS_MBX_SIZE; i++) {
945 		wmbx->mbo[i].cmd = WDS_MBO_FREE;
946 		wmbx->mbi[i].stat = WDS_MBI_FREE;
947 	}
948 	wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
949 	wmbx->tmbi = &wmbx->mbi[0];
950 	sc->sc_mbofull = 0;
951 
952 	/* Clear the buffers. */
953 	TAILQ_INIT(&wds_free_buffer);
954 	for (i = 0; i < BUFCNT; i++) {
955 		wds_buffer[i].busy = 0;
956 		TAILQ_INSERT_HEAD(&wds_free_buffer, &wds_buffer[i], chain);
957 	}
958 
959 	init.opcode = WDSC_INIT;
960 	init.scsi_id = sc->sc_scsi_dev;
961 	/* Record scsi id of controller for use in scsi_attach */
962 	sc->sc_scsi_dev = init.scsi_id;
963 	init.buson_t = 48;
964 	init.busoff_t = 24;
965 	init.xx = 0;
966 #ifdef notyet
967 	if (isadma_map((caddr_t)(wmbx), sizeof(struct wds_mbx),
968 	    mbx_phys, ISADMA_MAP_CONTIG) != 1)
969 		panic("wds_init: cannot map mail box");
970 	ltophys(mbx_phys[0].addr, init.mbaddr);
971 #else
972 	ltophys(KVTOPHYS(wmbx), init.mbaddr);
973 #endif
974 	init.nomb = init.nimb = WDS_MBX_SIZE;
975 	wds_cmd(sc, (u_char *)&init, sizeof init);
976 
977 	wds_wait(iot, ioh, WDS_STAT, WDSS_INIT, WDSS_INIT);
978 
979 	c = WDSC_DISUNSOL;
980 	wds_cmd(sc, &c, sizeof c);
981 
982 	bus_space_write_1(iot, ioh, WDS_HCR, WDSH_DRQEN);
983 }
984 
985 /*
986  * Read the board's firmware revision information.
987  */
988 void
989 wds_inquire_setup_information(sc)
990 	struct wds_softc *sc;
991 {
992 	struct wds_scb *scb;
993 	u_char *j;
994 	int s;
995 
996 	if ((scb = wds_get_scb(sc, SCSI_NOSLEEP, 0)) == NULL) {
997 		printf("%s: no request slot available in getvers()!\n",
998 		    sc->sc_dev.dv_xname);
999 		return;
1000 	}
1001 	scb->xs = NULL;
1002 	scb->timeout = 40;
1003 
1004 	bzero(&scb->cmd, sizeof scb->cmd);
1005 	scb->cmd.write = 0x80;
1006 	scb->cmd.opcode = WDSX_GETFIRMREV;
1007 
1008 	/* Will poll card, await result. */
1009 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, WDS_HCR, WDSH_DRQEN);
1010 	scb->flags |= SCB_POLLED;
1011 
1012 	s = splbio();
1013 	wds_queue_scb(sc, scb);
1014 	splx(s);
1015 
1016 	if (wds_ipoll(sc, scb, scb->timeout))
1017 		goto out;
1018 
1019 	/* Print the version number. */
1020 	printf(": version %x.%02x ", scb->cmd.targ, scb->cmd.scb.opcode);
1021 	sc->sc_revision = (scb->cmd.targ << 8) | scb->cmd.scb.opcode;
1022 	/* Print out the version string. */
1023 	j = 2 + &(scb->cmd.targ);
1024 	while ((*j >= 32) && (*j < 128)) {
1025 		printf("%c", *j);
1026 		j++;
1027 	}
1028 
1029 out:
1030 	printf("\n");
1031 	wds_free_scb(sc, scb);
1032 }
1033 
1034 void
1035 wdsminphys(struct buf *bp, struct scsi_link *sl)
1036 {
1037 	if (bp->b_bcount > ((WDS_NSEG - 1) << PGSHIFT))
1038 		bp->b_bcount = ((WDS_NSEG - 1) << PGSHIFT);
1039 	minphys(bp);
1040 }
1041 
1042 /*
1043  * Send a SCSI command.
1044  */
1045 int
1046 wds_scsi_cmd(xs)
1047 	struct scsi_xfer *xs;
1048 {
1049 	struct scsi_link *sc_link = xs->sc_link;
1050 	struct wds_softc *sc = sc_link->adapter_softc;
1051 	bus_space_tag_t iot = sc->sc_iot;
1052 	bus_space_handle_t ioh = sc->sc_ioh;
1053 	struct wds_scb *scb;
1054 	struct wds_scat_gath *sg;
1055 	int seg;
1056 	u_long thiskv, thisphys, nextphys;
1057 	int bytes_this_seg, bytes_this_page, datalen, flags;
1058 	int s;
1059 #ifdef notyet
1060 	int mflags;
1061 #endif
1062 
1063 	if (xs->flags & SCSI_RESET) {
1064 		/* XXX Fix me! */
1065 		printf("%s: reset!\n", sc->sc_dev.dv_xname);
1066 		wds_init(sc);
1067 		return COMPLETE;
1068 	}
1069 
1070 	flags = xs->flags;
1071 #ifdef notyet
1072 	if (flags & SCSI_NOSLEEP)
1073 		mflags = ISADMA_MAP_BOUNCE;
1074 	else
1075 		mflags = ISADMA_MAP_BOUNCE | ISADMA_MAP_WAITOK;
1076 #endif
1077 	if ((scb = wds_get_scb(sc, flags, NEEDBUFFER(sc))) == NULL) {
1078 		return (NO_CCB);
1079 	}
1080 	scb->xs = xs;
1081 	scb->timeout = xs->timeout;
1082 
1083 	/* Zero out the command structure. */
1084 	bzero(&scb->cmd, sizeof scb->cmd);
1085 	bcopy(xs->cmd, &scb->cmd.scb, xs->cmdlen < 12 ? xs->cmdlen : 12);
1086 
1087 	/* Set up some of the command fields. */
1088 	scb->cmd.targ = (xs->sc_link->target << 5) | xs->sc_link->lun;
1089 
1090 	/* NOTE: cmd.write may be OK as 0x40 (disable direction checking)
1091 	 * on boards other than the WD-7000V-ASE. Need this for the ASE:
1092 	 */
1093 	scb->cmd.write = (xs->flags & SCSI_DATA_IN) ? 0x80 : 0x00;
1094 
1095 	if (!NEEDBUFFER(sc) && xs->datalen) {
1096 		sg = scb->scat_gath;
1097 		seg = 0;
1098 
1099 		/*
1100 		 * Set up the scatter-gather block.
1101 		 */
1102 		SC_DEBUG(sc_link, SDEV_DB4,
1103 		    ("%d @0x%x:- ", xs->datalen, xs->data));
1104 
1105 #ifdef notyet
1106 		scb->data_nseg = isadma_map(xs->data, xs->datalen,
1107 					    scb->data_phys, mflags);
1108 		for (seg = 0; seg < scb->data_nseg; seg++) {
1109 			ltophys(scb->data_phys[seg].addr,
1110 			       sg[seg].seg_addr);
1111 			ltophys(scb->data_phys[seg].length,
1112 			       sg[seg].seg_len);
1113 		}
1114 #else
1115 		datalen = xs->datalen;
1116 		thiskv = (int)xs->data;
1117 		thisphys = KVTOPHYS(xs->data);
1118 
1119 		while (datalen && seg < WDS_NSEG) {
1120 			bytes_this_seg = 0;
1121 
1122 			/* put in the base address */
1123 			ltophys(thisphys, sg->seg_addr);
1124 
1125 			SC_DEBUGN(sc_link, SDEV_DB4, ("0x%x", thisphys));
1126 
1127 			/* do it at least once */
1128 			nextphys = thisphys;
1129 			while (datalen && thisphys == nextphys) {
1130 				/*
1131 				 * This page is contiguous (physically)
1132 				 * with the last, just extend the
1133 				 * length
1134 				 */
1135 				/* check it fits on the ISA bus */
1136 				if (thisphys > 0xFFFFFF) {
1137 					printf("%s: DMA beyond"
1138 						" end of ISA\n",
1139 						sc->sc_dev.dv_xname);
1140 					goto bad;
1141 				}
1142 				/* how far to the end of the page */
1143 				nextphys = (thisphys & ~PGOFSET) + NBPG;
1144 				bytes_this_page = nextphys - thisphys;
1145 				/**** or the data ****/
1146 				bytes_this_page = min(bytes_this_page,
1147 						      datalen);
1148 				bytes_this_seg += bytes_this_page;
1149 				datalen -= bytes_this_page;
1150 
1151 				/* get more ready for the next page */
1152 				thiskv = (thiskv & ~PGOFSET) + NBPG;
1153 				if (datalen)
1154 					thisphys = KVTOPHYS(thiskv);
1155 			}
1156 			/*
1157 			 * next page isn't contiguous, finish the seg
1158 			 */
1159 			SC_DEBUGN(sc_link, SDEV_DB4,
1160 			    ("(0x%x)", bytes_this_seg));
1161 			ltophys(bytes_this_seg, sg->seg_len);
1162 			sg++;
1163 			seg++;
1164 #endif
1165 		}
1166 
1167 		SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
1168 		if (datalen) {
1169 			/*
1170 			 * there's still data, must have run out of segs!
1171 			 */
1172 			printf("%s: wds_scsi_cmd, more than %d dma segs\n",
1173 			    sc->sc_dev.dv_xname, WDS_NSEG);
1174 			goto bad;
1175 		}
1176 #ifdef notyet
1177 		if (scb->data_nseg == 0) {
1178 			printf("%s: wds_scsi_cmd, cannot map\n",
1179 			       sc->sc_dev.dv_xname);
1180 			goto bad;
1181 		} else if (flags & SCSI_DATA_OUT)
1182 			isadma_copytobuf(xs->data, xs->datalen,
1183 					 scb->data_nseg, scb->data_phys);
1184 		ltophys((unsigned)((struct wds_scb *)(scb->scb_phys[0].addr))->scat_gath,
1185 			scb->data_addr);
1186 		ltophys(scb->data_nseg * sizeof(struct wds_scat_gath),
1187 			scb->data_length);
1188 #else
1189 		scb->cmd.opcode = WDSX_SCSISG;
1190 		ltophys(KVTOPHYS(scb->scat_gath), scb->cmd.data);
1191 		ltophys(seg * sizeof(struct wds_scat_gath), scb->cmd.len);
1192 #endif
1193 	} else if (xs->datalen > 0) {
1194 		/* The board is an ASC or ASE. Do not use scatter/gather. */
1195 		if (xs->datalen > BUFLEN) {
1196 			printf("%s: wds_scsi_cmd, I/O too large for bounce buffer\n",
1197 			    sc->sc_dev.dv_xname);
1198 			goto bad;
1199 		}
1200 		if (xs->flags & SCSI_DATA_OUT)
1201 			bcopy(xs->data, scb->buf->data, xs->datalen);
1202 		else
1203 			bzero(scb->buf->data, xs->datalen);
1204 		scb->cmd.opcode = WDSX_SCSICMD;
1205 		ltophys(KVTOPHYS(scb->buf->data), scb->cmd.data);
1206 		ltophys(xs->datalen, scb->cmd.len);
1207 	} else {
1208 		scb->cmd.opcode = WDSX_SCSICMD;
1209 		ltophys(0, scb->cmd.data);
1210 		ltophys(0, scb->cmd.len);
1211 	}
1212 
1213 	scb->cmd.stat = 0x00;
1214 	scb->cmd.venderr = 0x00;
1215 	ltophys(0, scb->cmd.link);
1216 
1217 	/* XXX Do we really want to do this? */
1218 	if (flags & SCSI_POLL) {
1219 		/* Will poll card, await result. */
1220 		bus_space_write_1(iot, ioh, WDS_HCR, WDSH_DRQEN);
1221 		scb->flags |= SCB_POLLED;
1222 	} else {
1223 		/* Will send command, let interrupt routine handle result. */
1224 		bus_space_write_1(iot, ioh, WDS_HCR, WDSH_IRQEN | WDSH_DRQEN);
1225 	}
1226 
1227 	s = splbio();
1228 	wds_queue_scb(sc, scb);
1229 
1230 #ifdef notyet
1231 	if (VOLATILE_XS(xs)) {
1232 		while ((scb->xs->flags & ITSDONE) == 0) {
1233 			tsleep(scb, PRIBIO, "wdswait", 0);
1234 		}
1235 		if (scb->data_nseg) {
1236 			if (flags & SCSI_DATA_IN)
1237 				isadma_copyfrombuf(xs->data, xs->datalen,
1238 				    scb->data_nseg, scb->data_phys);
1239 			isadma_unmap(xs->data, xs->datalen,
1240 			    scb->data_nseg, scb->data_phys);
1241 		}
1242 		wds_free_scb(sc, scb);
1243 		scsi_done(xs);
1244 		splx(s);
1245 		return COMPLETE;
1246 	}
1247 #endif
1248 	splx(s);
1249 
1250 	if ((flags & SCSI_POLL) == 0)
1251 		return SUCCESSFULLY_QUEUED;
1252 
1253 	if (wds_poll(sc, xs, scb->timeout)) {
1254 		wds_timeout(scb);
1255 		if (wds_poll(sc, xs, scb->timeout))
1256 			wds_timeout(scb);
1257 	}
1258 	return COMPLETE;
1259 
1260 bad:
1261 	xs->error = XS_DRIVER_STUFFUP;
1262 	wds_free_scb(sc, scb);
1263 	return COMPLETE;
1264 }
1265 
1266 /*
1267  * Send a sense request.
1268  */
1269 void
1270 wds_sense(sc, scb)
1271 	struct wds_softc *sc;
1272 	struct wds_scb *scb;
1273 {
1274 	struct scsi_xfer *xs = scb->xs;
1275 	struct scsi_sense *ss = (void *)&scb->sense.scb;
1276 	int s;
1277 
1278 	/* XXXXX */
1279 
1280 	/* Send sense request SCSI command. */
1281 	xs->error = XS_SENSE;
1282 	scb->flags |= SCB_SENSE;
1283 
1284 	/* First, save the return values */
1285 	if (NEEDBUFFER(sc) && xs->datalen) {
1286 		if (xs->flags & SCSI_DATA_IN)
1287 			bcopy(scb->buf->data, xs->data, xs->datalen);
1288 	}
1289 
1290 	/* Next, setup a request sense command block */
1291 	bzero(ss, sizeof(*ss));
1292 	ss->opcode = REQUEST_SENSE;
1293 	ss->byte2 = xs->sc_link->lun << 5;
1294 	ss->length = sizeof(struct scsi_sense_data);
1295 
1296 	/* Set up some of the command fields. */
1297 	scb->sense.targ = scb->cmd.targ;
1298 	scb->sense.write = 0x80;
1299 	scb->sense.opcode = WDSX_SCSICMD;
1300 	ltophys(KVTOPHYS(&scb->sense_data), scb->sense.data);
1301 	ltophys(sizeof(struct scsi_sense_data), scb->sense.len);
1302 
1303 	s = splbio();
1304 	wds_queue_scb(sc, scb);
1305 	splx(s);
1306 
1307 	/*
1308 	 * There's no reason for us to poll here.  There are two cases:
1309 	 * 1) If it's a polling operation, then we're called from the interrupt
1310 	 *    handler, and we return and continue polling.
1311 	 * 2) If it's an interrupt-driven operation, then it gets completed
1312 	 *    later on when the REQUEST SENSE finishes.
1313 	 */
1314 }
1315 
1316 /*
1317  * Poll a particular unit, looking for a particular scb
1318  */
1319 int
1320 wds_poll(sc, xs, count)
1321 	struct wds_softc *sc;
1322 	struct scsi_xfer *xs;
1323 	int count;
1324 {
1325 	bus_space_tag_t iot = sc->sc_iot;
1326 	bus_space_handle_t ioh = sc->sc_ioh;
1327 	int s;
1328 
1329 	/* timeouts are in msec, so we loop in 1000 usec cycles */
1330 	while (count) {
1331 		/*
1332 		 * If we had interrupts enabled, would we
1333 		 * have got an interrupt?
1334 		 */
1335 		if (bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_IRQ) {
1336 			s = splbio();
1337 			wdsintr(sc);
1338 			splx(s);
1339 		}
1340 		if (xs->flags & ITSDONE)
1341 			return 0;
1342 		delay(1000);	/* only happens in boot so ok */
1343 		count--;
1344 	}
1345 	return 1;
1346 }
1347 
1348 /*
1349  * Poll a particular unit, looking for a particular scb
1350  */
1351 int
1352 wds_ipoll(sc, scb, count)
1353 	struct wds_softc *sc;
1354 	struct wds_scb *scb;
1355 	int count;
1356 {
1357 	bus_space_tag_t iot = sc->sc_iot;
1358 	bus_space_handle_t ioh = sc->sc_ioh;
1359 	int s;
1360 
1361 	/* timeouts are in msec, so we loop in 1000 usec cycles */
1362 	while (count) {
1363 		/*
1364 		 * If we had interrupts enabled, would we
1365 		 * have got an interrupt?
1366 		 */
1367 		if (bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_IRQ) {
1368 			s = splbio();
1369 			wdsintr(sc);
1370 			splx(s);
1371 		}
1372 		if (scb->flags & SCB_DONE)
1373 			return 0;
1374 		delay(1000);	/* only happens in boot so ok */
1375 		count--;
1376 	}
1377 	return 1;
1378 }
1379 
1380 void
1381 wds_timeout(arg)
1382 	void *arg;
1383 {
1384 	struct wds_scb *scb = arg;
1385 	struct scsi_xfer *xs;
1386 	struct scsi_link *sc_link;
1387 	struct wds_softc *sc;
1388 	int s;
1389 
1390 	s = splbio();
1391 #ifdef notyet
1392 	isadma_copyfrombuf((caddr_t)scb, SCB_PHYS_SIZE, 1, scb->scb_phys);
1393 #endif
1394 	xs = scb->xs;
1395 	sc_link = xs->sc_link;
1396 	sc = sc_link->adapter_softc;
1397 
1398 	sc_print_addr(sc_link);
1399 	printf("timed out");
1400 
1401 #ifdef WDSDIAG
1402 	/*
1403 	 * If The scb's mbx is not free, then the board has gone south?
1404 	 */
1405 	wds_collect_mbo(sc);
1406 	if (scb->flags & SCB_SENDING) {
1407 		printf("%s: not taking commands!\n", sc->sc_dev.dv_xname);
1408 		Debugger();
1409 	}
1410 #endif
1411 
1412 	/*
1413 	 * If it has been through before, then
1414 	 * a previous abort has failed, don't
1415 	 * try abort again
1416 	 */
1417 	if (scb->flags & SCB_ABORT) {
1418 		/* abort timed out */
1419 		printf(" AGAIN\n");
1420 		/* XXX Must reset! */
1421 	} else {
1422 		/* abort the operation that has timed out */
1423 		printf("\n");
1424 		scb->xs->error = XS_TIMEOUT;
1425 		scb->timeout = WDS_ABORT_TIMEOUT;
1426 		scb->flags |= SCB_ABORT;
1427 		wds_queue_scb(sc, scb);
1428 	}
1429 
1430 	splx(s);
1431 }
1432