Line data Source code
1 : /* $OpenBSD: aic6360.c,v 1.29 2017/09/08 05:36:52 deraadt Exp $ */
2 : /* $NetBSD: aic6360.c,v 1.52 1996/12/10 21:27:51 thorpej Exp $ */
3 :
4 : #ifdef DDB
5 : #define integrate
6 : #else
7 : #define integrate static inline
8 : #endif
9 :
10 : /*
11 : * Copyright (c) 1994, 1995, 1996 Charles Hannum. All rights reserved.
12 : *
13 : * Redistribution and use in source and binary forms, with or without
14 : * modification, are permitted provided that the following conditions
15 : * are met:
16 : * 1. Redistributions of source code must retain the above copyright
17 : * notice, this list of conditions and the following disclaimer.
18 : * 2. Redistributions in binary form must reproduce the above copyright
19 : * notice, this list of conditions and the following disclaimer in the
20 : * documentation and/or other materials provided with the distribution.
21 : * 3. All advertising materials mentioning features or use of this software
22 : * must display the following acknowledgement:
23 : * This product includes software developed by Charles M. Hannum.
24 : * 4. The name of the author may not be used to endorse or promote products
25 : * derived from this software without specific prior written permission.
26 : *
27 : * Copyright (c) 1994 Jarle Greipsland
28 : * All rights reserved.
29 : *
30 : * Redistribution and use in source and binary forms, with or without
31 : * modification, are permitted provided that the following conditions
32 : * are met:
33 : * 1. Redistributions of source code must retain the above copyright
34 : * notice, this list of conditions and the following disclaimer.
35 : * 2. Redistributions in binary form must reproduce the above copyright
36 : * notice, this list of conditions and the following disclaimer in the
37 : * documentation and/or other materials provided with the distribution.
38 : * 3. The name of the author may not be used to endorse or promote products
39 : * derived from this software without specific prior written permission.
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 : * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 : * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
45 : * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46 : * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
47 : * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
50 : * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51 : * POSSIBILITY OF SUCH DAMAGE.
52 : */
53 :
54 : /*
55 : * Acknowledgements: Many of the algorithms used in this driver are
56 : * inspired by the work of Julian Elischer (julian@tfs.com) and
57 : * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
58 : */
59 :
60 : /* TODO list:
61 : * 1) Get the DMA stuff working.
62 : * 2) Get the iov/uio stuff working. Is this a good thing ???
63 : * 3) Get the synch stuff working.
64 : * 4) Rewrite it to use malloc for the acb structs instead of static alloc.?
65 : */
66 :
67 : /*
68 : * A few customizable items:
69 : */
70 :
71 : /* Use doubleword transfers to/from SCSI chip. Note: This requires
72 : * motherboard support. Basicly, some motherboard chipsets are able to
73 : * split a 32 bit I/O operation into two 16 bit I/O operations,
74 : * transparently to the processor. This speeds up some things, notably long
75 : * data transfers.
76 : */
77 : #define AIC_USE_DWORDS 0
78 :
79 : /* Synchronous data transfers? */
80 : #define AIC_USE_SYNCHRONOUS 0
81 : #define AIC_SYNC_REQ_ACK_OFS 8
82 :
83 : /* Wide data transfers? */
84 : #define AIC_USE_WIDE 0
85 : #define AIC_MAX_WIDTH 0
86 :
87 : /* Max attempts made to transmit a message */
88 : #define AIC_MSG_MAX_ATTEMPT 3 /* Not used now XXX */
89 :
90 : /* Use DMA (else we do programmed I/O using string instructions) (not yet!)*/
91 : #define AIC_USE_EISA_DMA 0
92 : #define AIC_USE_ISA_DMA 0
93 :
94 : /* How to behave on the (E)ISA bus when/if DMAing (on<<4) + off in us */
95 : #define EISA_BRST_TIM ((15<<4) + 1) /* 15us on, 1us off */
96 :
97 : /* Some spin loop parameters (essentially how long to wait some places)
98 : * The problem(?) is that sometimes we expect either to be able to transmit a
99 : * byte or to get a new one from the SCSI bus pretty soon. In order to avoid
100 : * returning from the interrupt just to get yanked back for the next byte we
101 : * may spin in the interrupt routine waiting for this byte to come. How long?
102 : * This is really (SCSI) device and processor dependent. Tuneable, I guess.
103 : */
104 : #define AIC_MSGIN_SPIN 1 /* Spin upto ?ms for a new msg byte */
105 : #define AIC_MSGOUT_SPIN 1
106 :
107 : /* Include debug functions? At the end of this file there are a bunch of
108 : * functions that will print out various information regarding queued SCSI
109 : * commands, driver state and chip contents. You can call them from the
110 : * kernel debugger. If you set AIC_DEBUG to 0 they are not included (the
111 : * kernel uses less memory) but you lose the debugging facilities.
112 : */
113 : #ifndef SMALL_KERNEL
114 : #define AIC_DEBUG 1
115 : #endif
116 :
117 : #define AIC_ABORT_TIMEOUT 2000 /* time to wait for abort */
118 :
119 : /* End of customizable parameters */
120 :
121 : #if AIC_USE_EISA_DMA || AIC_USE_ISA_DMA
122 : #error "I said not yet! Start paying attention... grumble"
123 : #endif
124 :
125 : #include <sys/param.h>
126 : #include <sys/systm.h>
127 : #include <sys/kernel.h>
128 : #include <sys/errno.h>
129 : #include <sys/ioctl.h>
130 : #include <sys/device.h>
131 : #include <sys/buf.h>
132 : #include <sys/queue.h>
133 :
134 : #include <machine/bus.h>
135 : #include <machine/intr.h>
136 :
137 : #include <scsi/scsi_all.h>
138 : #include <scsi/scsi_message.h>
139 : #include <scsi/scsiconf.h>
140 :
141 : #include <dev/isa/isavar.h>
142 :
143 : #include <dev/ic/aic6360reg.h>
144 : #include <dev/ic/aic6360var.h>
145 :
146 : #ifndef DDB
147 : #define db_enter() panic("should call debugger here (aic6360.c)")
148 : #endif /* ! DDB */
149 :
150 : #ifdef AIC_DEBUG
151 : int aic_debug = 0x00; /* AIC_SHOWSTART|AIC_SHOWMISC|AIC_SHOWTRACE; */
152 : #endif
153 :
154 : void aic_minphys(struct buf *, struct scsi_link *);
155 : void aic_init(struct aic_softc *);
156 : void aic_done(struct aic_softc *, struct aic_acb *);
157 : void aic_dequeue(struct aic_softc *, struct aic_acb *);
158 : void aic_scsi_cmd(struct scsi_xfer *);
159 : int aic_poll(struct aic_softc *, struct scsi_xfer *, int);
160 : integrate void aic_sched_msgout(struct aic_softc *, u_char);
161 : integrate void aic_setsync(struct aic_softc *, struct aic_tinfo *);
162 : void aic_select(struct aic_softc *, struct aic_acb *);
163 : void aic_timeout(void *);
164 : void aic_sched(struct aic_softc *);
165 : void aic_scsi_reset(struct aic_softc *);
166 : void aic_reset(struct aic_softc *);
167 : void aic_acb_free(void *, void *);
168 : void *aic_acb_alloc(void *);
169 : int aic_reselect(struct aic_softc *, int);
170 : void aic_sense(struct aic_softc *, struct aic_acb *);
171 : void aic_msgin(struct aic_softc *);
172 : void aic_abort(struct aic_softc *, struct aic_acb *);
173 : void aic_msgout(struct aic_softc *);
174 : int aic_dataout_pio(struct aic_softc *, u_char *, int);
175 : int aic_datain_pio(struct aic_softc *, u_char *, int);
176 : #ifdef AIC_DEBUG
177 : void aic_print_acb(struct aic_acb *);
178 : void aic_dump_driver(struct aic_softc *);
179 : void aic_dump6360(struct aic_softc *);
180 : void aic_show_scsi_cmd(struct aic_acb *);
181 : void aic_print_active_acb(void);
182 : #endif
183 :
184 : struct cfdriver aic_cd = {
185 : NULL, "aic", DV_DULL
186 : };
187 :
188 : struct scsi_adapter aic_switch = {
189 : aic_scsi_cmd,
190 : #ifdef notyet
191 : aic_minphys,
192 : #else
193 : scsi_minphys,
194 : #endif
195 : 0,
196 : 0,
197 : };
198 :
199 : /*
200 : * Do the real search-for-device.
201 : */
202 : int
203 0 : aic_find(bus_space_tag_t iot, bus_space_handle_t ioh)
204 : {
205 0 : char chip_id[sizeof(IDSTRING)]; /* For chips that support it */
206 : int i;
207 :
208 : /* Remove aic6360 from possible powerdown mode */
209 0 : bus_space_write_1(iot, ioh, DMACNTRL0, 0);
210 :
211 : /* Thanks to mark@aggregate.com for the new method for detecting
212 : * whether the chip is present or not. Bonus: may also work for
213 : * the AIC-6260!
214 : */
215 0 : AIC_TRACE(("aic: probing for aic-chip\n"));
216 : /*
217 : * Linux also init's the stack to 1-16 and then clears it,
218 : * 6260's don't appear to have an ID reg - mpg
219 : */
220 : /* Push the sequence 0,1,..,15 on the stack */
221 : #define STSIZE 16
222 0 : bus_space_write_1(iot, ioh, DMACNTRL1, 0); /* Reset stack pointer */
223 0 : for (i = 0; i < STSIZE; i++)
224 0 : bus_space_write_1(iot, ioh, STACK, i);
225 :
226 : /* See if we can pull out the same sequence */
227 0 : bus_space_write_1(iot, ioh, DMACNTRL1, 0);
228 0 : for (i = 0; i < STSIZE && bus_space_read_1(iot, ioh, STACK) == i; i++)
229 : ;
230 0 : if (i != STSIZE) {
231 0 : AIC_START(("STACK futzed at %d.\n", i));
232 0 : return (0);
233 : }
234 :
235 : /* See if we can pull the id string out of the ID register,
236 : * now only used for informational purposes.
237 : */
238 0 : bzero(chip_id, sizeof(chip_id));
239 0 : bus_space_read_multi_1(iot, ioh, ID, chip_id, sizeof(IDSTRING) - 1);
240 0 : AIC_START(("AIC ID: %s ", chip_id));
241 0 : AIC_START(("chip revision %d\n",
242 : (int)bus_space_read_1(iot, ioh, REV)));
243 :
244 0 : return (1);
245 0 : }
246 :
247 : /*
248 : * Attach the AIC6360, fill out some high and low level data structures
249 : */
250 : void
251 0 : aicattach(struct aic_softc *sc)
252 : {
253 0 : struct scsibus_attach_args saa;
254 0 : AIC_TRACE(("aicattach "));
255 0 : sc->sc_state = AIC_INIT;
256 :
257 0 : sc->sc_initiator = 7;
258 0 : sc->sc_freq = 20; /* XXXX assume 20 MHz. */
259 :
260 : /*
261 : * These are the bounds of the sync period, based on the frequency of
262 : * the chip's clock input and the size and offset of the sync period
263 : * register.
264 : *
265 : * For a 20MHz clock, this gives us 25, or 100nS, or 10MB/s, as a
266 : * maximum transfer rate, and 112.5, or 450nS, or 2.22MB/s, as a
267 : * minimum transfer rate.
268 : */
269 0 : sc->sc_minsync = (2 * 250) / sc->sc_freq;
270 0 : sc->sc_maxsync = (9 * 250) / sc->sc_freq;
271 :
272 0 : aic_init(sc); /* init chip and driver */
273 :
274 : /*
275 : * Fill in the prototype scsi_link
276 : */
277 0 : sc->sc_link.adapter_softc = sc;
278 0 : sc->sc_link.adapter_target = sc->sc_initiator;
279 0 : sc->sc_link.adapter = &aic_switch;
280 0 : sc->sc_link.openings = 2;
281 0 : sc->sc_link.pool = &sc->sc_iopool;
282 :
283 0 : bzero(&saa, sizeof(saa));
284 0 : saa.saa_sc_link = &sc->sc_link;
285 :
286 0 : config_found(&sc->sc_dev, &saa, scsiprint);
287 0 : }
288 :
289 : int
290 0 : aic_detach(struct device *self, int flags)
291 : {
292 0 : struct aic_softc *sc = (struct aic_softc *) self;
293 : int rv = 0;
294 :
295 0 : rv = config_detach_children(&sc->sc_dev, flags);
296 :
297 0 : return (rv);
298 : }
299 :
300 : /* Initialize AIC6360 chip itself
301 : * The following conditions should hold:
302 : * aicprobe should have succeeded, i.e. the ioh handle in aic_softc must
303 : * be valid.
304 : */
305 : void
306 0 : aic_reset(struct aic_softc *sc)
307 : {
308 0 : bus_space_tag_t iot = sc->sc_iot;
309 0 : bus_space_handle_t ioh = sc->sc_ioh;
310 :
311 : /*
312 : * Doc. recommends to clear these two registers before operations
313 : * commence
314 : */
315 0 : bus_space_write_1(iot, ioh, SCSITEST, 0);
316 0 : bus_space_write_1(iot, ioh, TEST, 0);
317 :
318 : /* Reset SCSI-FIFO and abort any transfers */
319 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH | CLRSTCNT);
320 :
321 : /* Reset DMA-FIFO */
322 0 : bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
323 0 : bus_space_write_1(iot, ioh, DMACNTRL1, 0);
324 :
325 : /* Disable all selection features */
326 0 : bus_space_write_1(iot, ioh, SCSISEQ, 0);
327 0 : bus_space_write_1(iot, ioh, SXFRCTL1, 0);
328 :
329 : /* Disable some interrupts */
330 0 : bus_space_write_1(iot, ioh, SIMODE0, 0x00);
331 : /* Clear a slew of interrupts */
332 0 : bus_space_write_1(iot, ioh, CLRSINT0, 0x7f);
333 :
334 : /* Disable some more interrupts */
335 0 : bus_space_write_1(iot, ioh, SIMODE1, 0x00);
336 : /* Clear another slew of interrupts */
337 0 : bus_space_write_1(iot, ioh, CLRSINT1, 0xef);
338 :
339 : /* Disable synchronous transfers */
340 0 : bus_space_write_1(iot, ioh, SCSIRATE, 0);
341 :
342 : /* Haven't seen ant errors (yet) */
343 0 : bus_space_write_1(iot, ioh, CLRSERR, 0x07);
344 :
345 : /* Set our SCSI-ID */
346 0 : bus_space_write_1(iot, ioh, SCSIID, sc->sc_initiator << OID_S);
347 0 : bus_space_write_1(iot, ioh, BRSTCNTRL, EISA_BRST_TIM);
348 0 : }
349 :
350 : /* Pull the SCSI RST line for 500 us */
351 : void
352 0 : aic_scsi_reset(struct aic_softc *sc)
353 : {
354 0 : bus_space_tag_t iot = sc->sc_iot;
355 0 : bus_space_handle_t ioh = sc->sc_ioh;
356 :
357 0 : bus_space_write_1(iot, ioh, SCSISEQ, SCSIRSTO);
358 0 : delay(500);
359 0 : bus_space_write_1(iot, ioh, SCSISEQ, 0);
360 0 : delay(50);
361 0 : }
362 :
363 : /*
364 : * Initialize aic SCSI driver.
365 : */
366 : void
367 0 : aic_init(struct aic_softc *sc)
368 : {
369 0 : bus_space_tag_t iot = sc->sc_iot;
370 0 : bus_space_handle_t ioh = sc->sc_ioh;
371 : struct aic_acb *acb;
372 : int r;
373 :
374 0 : aic_reset(sc);
375 0 : aic_scsi_reset(sc);
376 0 : aic_reset(sc);
377 :
378 0 : if (sc->sc_state == AIC_INIT) {
379 : /* First time through; initialize. */
380 0 : TAILQ_INIT(&sc->ready_list);
381 0 : TAILQ_INIT(&sc->nexus_list);
382 0 : TAILQ_INIT(&sc->free_list);
383 0 : mtx_init(&sc->sc_acb_mtx, IPL_BIO);
384 0 : scsi_iopool_init(&sc->sc_iopool, sc, aic_acb_alloc,
385 : aic_acb_free);
386 0 : sc->sc_nexus = NULL;
387 0 : acb = sc->sc_acb;
388 0 : bzero(acb, sizeof(sc->sc_acb));
389 0 : for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
390 0 : TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
391 0 : acb++;
392 : }
393 0 : bzero(&sc->sc_tinfo, sizeof(sc->sc_tinfo));
394 0 : } else {
395 : /* Cancel any active commands. */
396 0 : sc->sc_state = AIC_CLEANING;
397 0 : if ((acb = sc->sc_nexus) != NULL) {
398 0 : acb->xs->error = XS_DRIVER_STUFFUP;
399 0 : timeout_del(&acb->xs->stimeout);
400 0 : aic_done(sc, acb);
401 0 : }
402 0 : while ((acb = TAILQ_FIRST(&sc->nexus_list)) != NULL) {
403 0 : acb->xs->error = XS_DRIVER_STUFFUP;
404 0 : timeout_del(&acb->xs->stimeout);
405 0 : aic_done(sc, acb);
406 : }
407 : }
408 :
409 0 : sc->sc_prevphase = PH_INVALID;
410 0 : for (r = 0; r < 8; r++) {
411 0 : struct aic_tinfo *ti = &sc->sc_tinfo[r];
412 :
413 0 : ti->flags = 0;
414 : #if AIC_USE_SYNCHRONOUS
415 : ti->flags |= DO_SYNC;
416 : ti->period = sc->sc_minsync;
417 : ti->offset = AIC_SYNC_REQ_ACK_OFS;
418 : #else
419 0 : ti->period = ti->offset = 0;
420 : #endif
421 : #if AIC_USE_WIDE
422 : ti->flags |= DO_WIDE;
423 : ti->width = AIC_MAX_WIDTH;
424 : #else
425 0 : ti->width = 0;
426 : #endif
427 : }
428 :
429 0 : sc->sc_state = AIC_IDLE;
430 0 : bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
431 0 : }
432 :
433 : void
434 0 : aic_acb_free(void *xsc, void *xacb)
435 : {
436 0 : struct aic_softc *sc = xsc;
437 0 : struct aic_acb *acb = xacb;
438 :
439 0 : mtx_enter(&sc->sc_acb_mtx);
440 0 : acb->flags = 0;
441 0 : TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
442 0 : mtx_leave(&sc->sc_acb_mtx);
443 0 : }
444 :
445 : void *
446 0 : aic_acb_alloc(void *xsc)
447 : {
448 0 : struct aic_softc *sc = xsc;
449 : struct aic_acb *acb;
450 :
451 0 : mtx_enter(&sc->sc_acb_mtx);
452 0 : acb = TAILQ_FIRST(&sc->free_list);
453 0 : if (acb) {
454 0 : TAILQ_REMOVE(&sc->free_list, acb, chain);
455 0 : acb->flags |= ACB_ALLOC;
456 0 : }
457 0 : mtx_leave(&sc->sc_acb_mtx);
458 :
459 0 : return acb;
460 : }
461 :
462 : /*
463 : * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
464 : */
465 :
466 : /*
467 : * Expected sequence:
468 : * 1) Command inserted into ready list
469 : * 2) Command selected for execution
470 : * 3) Command won arbitration and has selected target device
471 : * 4) Send message out (identify message, eventually also sync.negotiations)
472 : * 5) Send command
473 : * 5a) Receive disconnect message, disconnect.
474 : * 5b) Reselected by target
475 : * 5c) Receive identify message from target.
476 : * 6) Send or receive data
477 : * 7) Receive status
478 : * 8) Receive message (command complete etc.)
479 : * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
480 : * Repeat 2-8 (no disconnects please...)
481 : */
482 :
483 : /*
484 : * Start a SCSI-command
485 : * This function is called by the higher level SCSI-driver to queue/run
486 : * SCSI-commands.
487 : */
488 : void
489 0 : aic_scsi_cmd(struct scsi_xfer *xs)
490 : {
491 0 : struct scsi_link *sc_link = xs->sc_link;
492 0 : struct aic_softc *sc = sc_link->adapter_softc;
493 : struct aic_acb *acb;
494 : int s, flags;
495 :
496 0 : AIC_TRACE(("aic_scsi_cmd "));
497 0 : AIC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
498 : sc_link->target));
499 :
500 0 : flags = xs->flags;
501 0 : acb = xs->io;
502 :
503 : /* Initialize acb */
504 0 : acb->xs = xs;
505 0 : acb->timeout = xs->timeout;
506 0 : timeout_set(&xs->stimeout, aic_timeout, acb);
507 :
508 0 : if (xs->flags & SCSI_RESET) {
509 0 : acb->flags |= ACB_RESET;
510 0 : acb->scsi_cmd_length = 0;
511 0 : acb->data_length = 0;
512 0 : } else {
513 0 : bcopy(xs->cmd, &acb->scsi_cmd, xs->cmdlen);
514 0 : acb->scsi_cmd_length = xs->cmdlen;
515 0 : acb->data_addr = xs->data;
516 0 : acb->data_length = xs->datalen;
517 : }
518 0 : acb->target_stat = 0;
519 :
520 0 : s = splbio();
521 :
522 0 : TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
523 0 : if (sc->sc_state == AIC_IDLE)
524 0 : aic_sched(sc);
525 :
526 0 : splx(s);
527 :
528 0 : if ((flags & SCSI_POLL) == 0)
529 0 : return;
530 :
531 : /* Not allowed to use interrupts, use polling instead */
532 0 : if (aic_poll(sc, xs, acb->timeout)) {
533 0 : aic_timeout(acb);
534 0 : if (aic_poll(sc, xs, acb->timeout))
535 0 : aic_timeout(acb);
536 : }
537 0 : }
538 :
539 : #ifdef notyet
540 : /*
541 : * Adjust transfer size in buffer structure
542 : */
543 : void
544 : aic_minphys(struct buf *bp, struct scsi_link *sl)
545 : {
546 :
547 : AIC_TRACE(("aic_minphys "));
548 : if (bp->b_bcount > (AIC_NSEG << PGSHIFT))
549 : bp->b_bcount = (AIC_NSEG << PGSHIFT);
550 : minphys(bp);
551 : }
552 : #endif
553 :
554 : /*
555 : * Used when interrupt driven I/O isn't allowed, e.g. during boot.
556 : */
557 : int
558 0 : aic_poll(struct aic_softc *sc, struct scsi_xfer *xs, int count)
559 : {
560 0 : bus_space_tag_t iot = sc->sc_iot;
561 0 : bus_space_handle_t ioh = sc->sc_ioh;
562 : int s;
563 :
564 0 : AIC_TRACE(("aic_poll "));
565 0 : while (count) {
566 : /*
567 : * If we had interrupts enabled, would we
568 : * have got an interrupt?
569 : */
570 0 : if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) != 0) {
571 0 : s = splbio();
572 0 : aicintr(sc);
573 0 : splx(s);
574 0 : }
575 0 : if ((xs->flags & ITSDONE) != 0)
576 0 : return 0;
577 0 : delay(1000);
578 0 : count--;
579 : }
580 0 : return 1;
581 0 : }
582 :
583 : /*
584 : * LOW LEVEL SCSI UTILITIES
585 : */
586 :
587 : integrate void
588 0 : aic_sched_msgout(struct aic_softc *sc, u_char m)
589 : {
590 0 : bus_space_tag_t iot = sc->sc_iot;
591 0 : bus_space_handle_t ioh = sc->sc_ioh;
592 :
593 0 : if (sc->sc_msgpriq == 0)
594 0 : bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase | ATNO);
595 0 : sc->sc_msgpriq |= m;
596 0 : }
597 :
598 : /*
599 : * Set synchronous transfer offset and period.
600 : */
601 : integrate void
602 0 : aic_setsync(struct aic_softc *sc, struct aic_tinfo *ti)
603 : {
604 : #if AIC_USE_SYNCHRONOUS
605 : bus_space_tag_t iot = sc->sc_iot;
606 : bus_space_handle_t ioh = sc->sc_ioh;
607 :
608 : if (ti->offset != 0)
609 : bus_space_write_1(iot, ioh, SCSIRATE,
610 : ((ti->period * sc->sc_freq) / 250 - 2) << 4 | ti->offset);
611 : else
612 : bus_space_write_1(iot, ioh, SCSIRATE, 0);
613 : #endif
614 0 : }
615 :
616 : /*
617 : * Start a selection. This is used by aic_sched() to select an idle target,
618 : * and by aic_done() to immediately reselect a target to get sense information.
619 : */
620 : void
621 0 : aic_select(struct aic_softc *sc, struct aic_acb *acb)
622 : {
623 0 : bus_space_tag_t iot = sc->sc_iot;
624 0 : bus_space_handle_t ioh = sc->sc_ioh;
625 0 : struct scsi_link *sc_link = acb->xs->sc_link;
626 0 : int target = sc_link->target;
627 0 : struct aic_tinfo *ti = &sc->sc_tinfo[target];
628 :
629 0 : bus_space_write_1(iot, ioh, SCSIID,
630 : sc->sc_initiator << OID_S | target);
631 0 : aic_setsync(sc, ti);
632 0 : bus_space_write_1(iot, ioh, SXFRCTL1, STIMO_256ms | ENSTIMER);
633 :
634 : /* Always enable reselections. */
635 0 : bus_space_write_1(iot, ioh, SIMODE0, ENSELDI | ENSELDO);
636 0 : bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST | ENSELTIMO);
637 0 : bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI | ENSELO | ENAUTOATNO);
638 :
639 0 : sc->sc_state = AIC_SELECTING;
640 0 : }
641 :
642 : int
643 0 : aic_reselect(struct aic_softc *sc, int message)
644 : {
645 : u_char selid, target, lun;
646 : struct aic_acb *acb;
647 : struct scsi_link *sc_link;
648 : struct aic_tinfo *ti;
649 :
650 : /*
651 : * The SCSI chip made a snapshot of the data bus while the reselection
652 : * was being negotiated. This enables us to determine which target did
653 : * the reselect.
654 : */
655 0 : selid = sc->sc_selid & ~(1 << sc->sc_initiator);
656 0 : if (selid & (selid - 1)) {
657 0 : printf("%s: reselect with invalid selid %02x; ",
658 0 : sc->sc_dev.dv_xname, selid);
659 0 : printf("sending DEVICE RESET\n");
660 0 : AIC_BREAK();
661 : goto reset;
662 : }
663 :
664 : /* Search wait queue for disconnected cmd
665 : * The list should be short, so I haven't bothered with
666 : * any more sophisticated structures than a simple
667 : * singly linked list.
668 : */
669 0 : target = ffs(selid) - 1;
670 0 : lun = message & 0x07;
671 0 : TAILQ_FOREACH(acb, &sc->nexus_list, chain) {
672 0 : sc_link = acb->xs->sc_link;
673 0 : if (sc_link->target == target && sc_link->lun == lun)
674 : break;
675 : }
676 0 : if (acb == NULL) {
677 0 : printf("%s: reselect from target %d lun %d with no nexus; ",
678 0 : sc->sc_dev.dv_xname, target, lun);
679 0 : printf("sending ABORT\n");
680 0 : AIC_BREAK();
681 : goto abort;
682 : }
683 :
684 : /* Make this nexus active again. */
685 0 : TAILQ_REMOVE(&sc->nexus_list, acb, chain);
686 0 : sc->sc_state = AIC_CONNECTED;
687 0 : sc->sc_nexus = acb;
688 0 : ti = &sc->sc_tinfo[target];
689 0 : ti->lubusy |= (1 << lun);
690 0 : aic_setsync(sc, ti);
691 :
692 0 : if (acb->flags & ACB_RESET)
693 0 : aic_sched_msgout(sc, SEND_DEV_RESET);
694 0 : else if (acb->flags & ACB_ABORT)
695 0 : aic_sched_msgout(sc, SEND_ABORT);
696 :
697 : /* Do an implicit RESTORE POINTERS. */
698 0 : sc->sc_dp = acb->data_addr;
699 0 : sc->sc_dleft = acb->data_length;
700 0 : sc->sc_cp = (u_char *)&acb->scsi_cmd;
701 0 : sc->sc_cleft = acb->scsi_cmd_length;
702 :
703 0 : return (0);
704 :
705 : reset:
706 0 : aic_sched_msgout(sc, SEND_DEV_RESET);
707 0 : return (1);
708 :
709 : abort:
710 0 : aic_sched_msgout(sc, SEND_ABORT);
711 0 : return (1);
712 0 : }
713 :
714 : /*
715 : * Schedule a SCSI operation. This has now been pulled out of the interrupt
716 : * handler so that we may call it from aic_scsi_cmd and aic_done. This may
717 : * save us an unnecessary interrupt just to get things going. Should only be
718 : * called when state == AIC_IDLE and at bio pl.
719 : */
720 : void
721 0 : aic_sched(struct aic_softc *sc)
722 : {
723 0 : bus_space_tag_t iot = sc->sc_iot;
724 0 : bus_space_handle_t ioh = sc->sc_ioh;
725 : struct aic_acb *acb;
726 : struct scsi_link *sc_link;
727 : struct aic_tinfo *ti;
728 :
729 : /*
730 : * Find first acb in ready queue that is for a target/lunit pair that
731 : * is not busy.
732 : */
733 0 : bus_space_write_1(iot, ioh, CLRSINT1,
734 : CLRSELTIMO | CLRBUSFREE | CLRSCSIPERR);
735 0 : TAILQ_FOREACH(acb, &sc->ready_list, chain) {
736 0 : sc_link = acb->xs->sc_link;
737 0 : ti = &sc->sc_tinfo[sc_link->target];
738 0 : if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
739 0 : AIC_MISC(("selecting %d:%d ",
740 : sc_link->target, sc_link->lun));
741 0 : TAILQ_REMOVE(&sc->ready_list, acb, chain);
742 0 : sc->sc_nexus = acb;
743 0 : aic_select(sc, acb);
744 0 : return;
745 : } else
746 0 : AIC_MISC(("%d:%d busy\n",
747 : sc_link->target, sc_link->lun));
748 : }
749 0 : AIC_MISC(("idle "));
750 : /* Nothing to start; just enable reselections and wait. */
751 0 : bus_space_write_1(iot, ioh, SIMODE0, ENSELDI);
752 0 : bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST);
753 0 : bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
754 0 : }
755 :
756 : void
757 0 : aic_sense(struct aic_softc *sc, struct aic_acb *acb)
758 : {
759 0 : struct scsi_xfer *xs = acb->xs;
760 0 : struct scsi_link *sc_link = xs->sc_link;
761 0 : struct aic_tinfo *ti = &sc->sc_tinfo[sc_link->target];
762 0 : struct scsi_sense *ss = (void *)&acb->scsi_cmd;
763 :
764 0 : AIC_MISC(("requesting sense "));
765 : /* Next, setup a request sense command block */
766 0 : bzero(ss, sizeof(*ss));
767 0 : ss->opcode = REQUEST_SENSE;
768 0 : ss->byte2 = sc_link->lun << 5;
769 0 : ss->length = sizeof(struct scsi_sense_data);
770 0 : acb->scsi_cmd_length = sizeof(*ss);
771 0 : acb->data_addr = (char *)&xs->sense;
772 0 : acb->data_length = sizeof(struct scsi_sense_data);
773 0 : acb->flags |= ACB_SENSE;
774 0 : ti->senses++;
775 0 : if (acb->flags & ACB_NEXUS)
776 0 : ti->lubusy &= ~(1 << sc_link->lun);
777 0 : if (acb == sc->sc_nexus) {
778 0 : aic_select(sc, acb);
779 0 : } else {
780 0 : aic_dequeue(sc, acb);
781 0 : TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
782 0 : if (sc->sc_state == AIC_IDLE)
783 0 : aic_sched(sc);
784 : }
785 0 : }
786 :
787 : /*
788 : * POST PROCESSING OF SCSI_CMD (usually current)
789 : */
790 : void
791 0 : aic_done(struct aic_softc *sc, struct aic_acb *acb)
792 : {
793 0 : struct scsi_xfer *xs = acb->xs;
794 0 : struct scsi_link *sc_link = xs->sc_link;
795 0 : struct aic_tinfo *ti = &sc->sc_tinfo[sc_link->target];
796 :
797 0 : AIC_TRACE(("aic_done "));
798 :
799 : /*
800 : * Now, if we've come here with no error code, i.e. we've kept the
801 : * initial XS_NOERROR, and the status code signals that we should
802 : * check sense, we'll need to set up a request sense cmd block and
803 : * push the command back into the ready queue *before* any other
804 : * commands for this target/lunit, else we lose the sense info.
805 : * We don't support chk sense conditions for the request sense cmd.
806 : */
807 0 : if (xs->error == XS_NOERROR) {
808 0 : if (acb->flags & ACB_ABORT) {
809 0 : xs->error = XS_DRIVER_STUFFUP;
810 0 : } else if (acb->flags & ACB_SENSE) {
811 0 : xs->error = XS_SENSE;
812 0 : } else if (acb->target_stat == SCSI_CHECK) {
813 : /* First, save the return values */
814 : xs->resid = acb->data_length;
815 0 : xs->status = acb->target_stat;
816 0 : aic_sense(sc, acb);
817 0 : return;
818 : } else {
819 : xs->resid = acb->data_length;
820 : }
821 : }
822 :
823 : #ifdef AIC_DEBUG
824 0 : if ((aic_debug & AIC_SHOWMISC) != 0) {
825 0 : if (xs->resid != 0)
826 0 : printf("resid=%lu ", (u_long)xs->resid);
827 0 : if (xs->error == XS_SENSE)
828 0 : printf("sense=0x%02x\n", xs->sense.error_code);
829 : else
830 0 : printf("error=%d\n", xs->error);
831 : }
832 : #endif
833 :
834 : /*
835 : * Remove the ACB from whatever queue it happens to be on.
836 : */
837 0 : if (acb->flags & ACB_NEXUS)
838 0 : ti->lubusy &= ~(1 << sc_link->lun);
839 0 : if (acb == sc->sc_nexus) {
840 0 : sc->sc_nexus = NULL;
841 0 : sc->sc_state = AIC_IDLE;
842 0 : aic_sched(sc);
843 0 : } else
844 0 : aic_dequeue(sc, acb);
845 :
846 0 : ti->cmds++;
847 0 : scsi_done(xs);
848 0 : }
849 :
850 : void
851 0 : aic_dequeue(struct aic_softc *sc, struct aic_acb *acb)
852 : {
853 :
854 0 : if (acb->flags & ACB_NEXUS) {
855 0 : TAILQ_REMOVE(&sc->nexus_list, acb, chain);
856 0 : } else {
857 0 : TAILQ_REMOVE(&sc->ready_list, acb, chain);
858 : }
859 0 : }
860 :
861 : /*
862 : * INTERRUPT/PROTOCOL ENGINE
863 : */
864 :
865 : /*
866 : * Precondition:
867 : * The SCSI bus is already in the MSGI phase and there is a message byte
868 : * on the bus, along with an asserted REQ signal.
869 : */
870 : void
871 0 : aic_msgin(struct aic_softc *sc)
872 : {
873 0 : bus_space_tag_t iot = sc->sc_iot;
874 0 : bus_space_handle_t ioh = sc->sc_ioh;
875 : u_char sstat1;
876 : int n;
877 :
878 0 : AIC_TRACE(("aic_msgin "));
879 :
880 0 : if (sc->sc_prevphase == PH_MSGIN) {
881 : /* This is a continuation of the previous message. */
882 0 : n = sc->sc_imp - sc->sc_imess;
883 0 : goto nextbyte;
884 : }
885 :
886 : /* This is a new MESSAGE IN phase. Clean up our state. */
887 0 : sc->sc_flags &= ~AIC_DROP_MSGIN;
888 :
889 : nextmsg:
890 : n = 0;
891 0 : sc->sc_imp = &sc->sc_imess[n];
892 :
893 : nextbyte:
894 : /*
895 : * Read a whole message, but don't ack the last byte. If we reject the
896 : * message, we have to assert ATN during the message transfer phase
897 : * itself.
898 : */
899 0 : for (;;) {
900 0 : for (;;) {
901 0 : sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
902 0 : if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
903 : break;
904 : /* Wait for REQINIT. XXX Need timeout. */
905 : }
906 0 : if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
907 : /*
908 : * Target left MESSAGE IN, probably because it
909 : * a) noticed our ATN signal, or
910 : * b) ran out of messages.
911 : */
912 : goto out;
913 : }
914 :
915 : /* If parity error, just dump everything on the floor. */
916 0 : if ((sstat1 & SCSIPERR) != 0) {
917 0 : sc->sc_flags |= AIC_DROP_MSGIN;
918 0 : aic_sched_msgout(sc, SEND_PARITY_ERROR);
919 0 : }
920 :
921 : /* Gather incoming message bytes if needed. */
922 0 : if ((sc->sc_flags & AIC_DROP_MSGIN) == 0) {
923 0 : if (n >= AIC_MAX_MSG_LEN) {
924 : (void) bus_space_read_1(iot, ioh, SCSIDAT);
925 0 : sc->sc_flags |= AIC_DROP_MSGIN;
926 0 : aic_sched_msgout(sc, SEND_REJECT);
927 0 : } else {
928 0 : *sc->sc_imp++ = bus_space_read_1(iot, ioh,
929 : SCSIDAT);
930 0 : n++;
931 : /*
932 : * This testing is suboptimal, but most
933 : * messages will be of the one byte variety, so
934 : * it should not affect performance
935 : * significantly.
936 : */
937 0 : if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
938 : break;
939 0 : if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
940 : break;
941 0 : if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
942 0 : n == sc->sc_imess[1] + 2)
943 : break;
944 : }
945 : } else
946 0 : (void) bus_space_read_1(iot, ioh, SCSIDAT);
947 :
948 : /*
949 : * If we reach this spot we're either:
950 : * a) in the middle of a multi-byte message, or
951 : * b) dropping bytes.
952 : */
953 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
954 : /* Ack the last byte read. */
955 0 : (void) bus_space_read_1(iot, ioh, SCSIDAT);
956 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
957 0 : while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
958 : ;
959 : }
960 :
961 0 : AIC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
962 :
963 : /* We now have a complete message. Parse it. */
964 0 : switch (sc->sc_state) {
965 : struct aic_acb *acb;
966 : struct scsi_link *sc_link;
967 : struct aic_tinfo *ti;
968 :
969 : case AIC_CONNECTED:
970 0 : AIC_ASSERT(sc->sc_nexus != NULL);
971 0 : acb = sc->sc_nexus;
972 0 : ti = &sc->sc_tinfo[acb->xs->sc_link->target];
973 :
974 0 : switch (sc->sc_imess[0]) {
975 : case MSG_CMDCOMPLETE:
976 0 : if ((long)sc->sc_dleft < 0) {
977 : sc_link = acb->xs->sc_link;
978 0 : printf("%s: %lu extra bytes from %d:%d\n",
979 0 : sc->sc_dev.dv_xname, (u_long)-sc->sc_dleft,
980 0 : sc_link->target, sc_link->lun);
981 0 : acb->data_length = 0;
982 0 : }
983 0 : acb->xs->resid = acb->data_length = sc->sc_dleft;
984 0 : sc->sc_state = AIC_CMDCOMPLETE;
985 0 : break;
986 :
987 : case MSG_PARITY_ERROR:
988 : /* Resend the last message. */
989 0 : aic_sched_msgout(sc, sc->sc_lastmsg);
990 0 : break;
991 :
992 : case MSG_MESSAGE_REJECT:
993 0 : AIC_MISC(("message rejected %02x ", sc->sc_lastmsg));
994 0 : switch (sc->sc_lastmsg) {
995 : #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
996 : case SEND_IDENTIFY:
997 : ti->flags &= ~(DO_SYNC | DO_WIDE);
998 : ti->period = ti->offset = 0;
999 : aic_setsync(sc, ti);
1000 : ti->width = 0;
1001 : break;
1002 : #endif
1003 : #if AIC_USE_SYNCHRONOUS
1004 : case SEND_SDTR:
1005 : ti->flags &= ~DO_SYNC;
1006 : ti->period = ti->offset = 0;
1007 : aic_setsync(sc, ti);
1008 : break;
1009 : #endif
1010 : #if AIC_USE_WIDE
1011 : case SEND_WDTR:
1012 : ti->flags &= ~DO_WIDE;
1013 : ti->width = 0;
1014 : break;
1015 : #endif
1016 : case SEND_INIT_DET_ERR:
1017 0 : aic_sched_msgout(sc, SEND_ABORT);
1018 0 : break;
1019 : }
1020 : break;
1021 :
1022 : case MSG_NOOP:
1023 : break;
1024 :
1025 : case MSG_DISCONNECT:
1026 0 : ti->dconns++;
1027 0 : sc->sc_state = AIC_DISCONNECT;
1028 0 : break;
1029 :
1030 : case MSG_SAVEDATAPOINTER:
1031 0 : acb->data_addr = sc->sc_dp;
1032 0 : acb->data_length = sc->sc_dleft;
1033 0 : break;
1034 :
1035 : case MSG_RESTOREPOINTERS:
1036 0 : sc->sc_dp = acb->data_addr;
1037 0 : sc->sc_dleft = acb->data_length;
1038 0 : sc->sc_cp = (u_char *)&acb->scsi_cmd;
1039 0 : sc->sc_cleft = acb->scsi_cmd_length;
1040 0 : break;
1041 :
1042 : case MSG_EXTENDED:
1043 : switch (sc->sc_imess[2]) {
1044 : #if AIC_USE_SYNCHRONOUS
1045 : case MSG_EXT_SDTR:
1046 : if (sc->sc_imess[1] != 3)
1047 : goto reject;
1048 : ti->period = sc->sc_imess[3];
1049 : ti->offset = sc->sc_imess[4];
1050 : ti->flags &= ~DO_SYNC;
1051 : if (ti->offset == 0) {
1052 : } else if (ti->period < sc->sc_minsync ||
1053 : ti->period > sc->sc_maxsync ||
1054 : ti->offset > 8) {
1055 : ti->period = ti->offset = 0;
1056 : aic_sched_msgout(sc, SEND_SDTR);
1057 : } else {
1058 : sc_print_addr(acb->xs->sc_link);
1059 : printf("sync, offset %d, ",
1060 : ti->offset);
1061 : printf("period %dnsec\n",
1062 : ti->period * 4);
1063 : }
1064 : aic_setsync(sc, ti);
1065 : break;
1066 : #endif
1067 :
1068 : #if AIC_USE_WIDE
1069 : case MSG_EXT_WDTR:
1070 : if (sc->sc_imess[1] != 2)
1071 : goto reject;
1072 : ti->width = sc->sc_imess[3];
1073 : ti->flags &= ~DO_WIDE;
1074 : if (ti->width == 0) {
1075 : } else if (ti->width > AIC_MAX_WIDTH) {
1076 : ti->width = 0;
1077 : aic_sched_msgout(sc, SEND_WDTR);
1078 : } else {
1079 : sc_print_addr(acb->xs->sc_link);
1080 : printf("wide, width %d\n",
1081 : 1 << (3 + ti->width));
1082 : }
1083 : break;
1084 : #endif
1085 :
1086 : default:
1087 0 : printf("%s: unrecognized MESSAGE EXTENDED; ",
1088 0 : sc->sc_dev.dv_xname);
1089 0 : printf("sending REJECT\n");
1090 0 : AIC_BREAK();
1091 : goto reject;
1092 : }
1093 : break;
1094 :
1095 : default:
1096 0 : printf("%s: unrecognized MESSAGE; sending REJECT\n",
1097 0 : sc->sc_dev.dv_xname);
1098 0 : AIC_BREAK();
1099 : reject:
1100 0 : aic_sched_msgout(sc, SEND_REJECT);
1101 0 : break;
1102 : }
1103 : break;
1104 :
1105 : case AIC_RESELECTED:
1106 0 : if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
1107 0 : printf("%s: reselect without IDENTIFY; ",
1108 0 : sc->sc_dev.dv_xname);
1109 0 : printf("sending DEVICE RESET\n");
1110 0 : AIC_BREAK();
1111 : goto reset;
1112 : }
1113 :
1114 0 : (void) aic_reselect(sc, sc->sc_imess[0]);
1115 0 : break;
1116 :
1117 : default:
1118 0 : printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
1119 0 : sc->sc_dev.dv_xname);
1120 0 : AIC_BREAK();
1121 : reset:
1122 0 : aic_sched_msgout(sc, SEND_DEV_RESET);
1123 0 : break;
1124 :
1125 : #ifdef notdef
1126 : abort:
1127 : aic_sched_msgout(sc, SEND_ABORT);
1128 : break;
1129 : #endif
1130 : }
1131 :
1132 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1133 : /* Ack the last message byte. */
1134 0 : (void) bus_space_read_1(iot, ioh, SCSIDAT);
1135 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1136 0 : while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
1137 : ;
1138 :
1139 : /* Go get the next message, if any. */
1140 : goto nextmsg;
1141 :
1142 : out:
1143 0 : AIC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
1144 0 : }
1145 :
1146 : /*
1147 : * Send the highest priority, scheduled message.
1148 : */
1149 : void
1150 0 : aic_msgout(struct aic_softc *sc)
1151 : {
1152 0 : bus_space_tag_t iot = sc->sc_iot;
1153 0 : bus_space_handle_t ioh = sc->sc_ioh;
1154 : #if AIC_USE_SYNCHRONOUS
1155 : struct aic_tinfo *ti;
1156 : #endif
1157 : u_char sstat1;
1158 : int n;
1159 :
1160 0 : AIC_TRACE(("aic_msgout "));
1161 :
1162 : /* Reset the FIFO. */
1163 0 : bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
1164 : /* Enable REQ/ACK protocol. */
1165 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1166 :
1167 0 : if (sc->sc_prevphase == PH_MSGOUT) {
1168 0 : if (sc->sc_omp == sc->sc_omess) {
1169 : /*
1170 : * This is a retransmission.
1171 : *
1172 : * We get here if the target stayed in MESSAGE OUT
1173 : * phase. Section 5.1.9.2 of the SCSI 2 spec indicates
1174 : * that all of the previously transmitted messages must
1175 : * be sent again, in the same order. Therefore, we
1176 : * requeue all the previously transmitted messages, and
1177 : * start again from the top. Our simple priority
1178 : * scheme keeps the messages in the right order.
1179 : */
1180 0 : AIC_MISC(("retransmitting "));
1181 0 : sc->sc_msgpriq |= sc->sc_msgoutq;
1182 : /*
1183 : * Set ATN. If we're just sending a trivial 1-byte
1184 : * message, we'll clear ATN later on anyway.
1185 : */
1186 0 : bus_space_write_1(iot, ioh, SCSISIG, PH_MSGOUT | ATNO);
1187 : } else {
1188 : /* This is a continuation of the previous message. */
1189 0 : n = sc->sc_omp - sc->sc_omess;
1190 0 : goto nextbyte;
1191 : }
1192 0 : }
1193 :
1194 : /* No messages transmitted so far. */
1195 0 : sc->sc_msgoutq = 0;
1196 0 : sc->sc_lastmsg = 0;
1197 :
1198 : nextmsg:
1199 : /* Pick up highest priority message. */
1200 0 : sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
1201 0 : sc->sc_msgpriq &= ~sc->sc_currmsg;
1202 0 : sc->sc_msgoutq |= sc->sc_currmsg;
1203 :
1204 : /* Build the outgoing message data. */
1205 0 : switch (sc->sc_currmsg) {
1206 : case SEND_IDENTIFY:
1207 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1208 0 : sc->sc_omess[0] =
1209 0 : MSG_IDENTIFY(sc->sc_nexus->xs->sc_link->lun, 1);
1210 : n = 1;
1211 0 : break;
1212 :
1213 : #if AIC_USE_SYNCHRONOUS
1214 : case SEND_SDTR:
1215 : AIC_ASSERT(sc->sc_nexus != NULL);
1216 : ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1217 : sc->sc_omess[4] = MSG_EXTENDED;
1218 : sc->sc_omess[3] = 3;
1219 : sc->sc_omess[2] = MSG_EXT_SDTR;
1220 : sc->sc_omess[1] = ti->period >> 2;
1221 : sc->sc_omess[0] = ti->offset;
1222 : n = 5;
1223 : break;
1224 : #endif
1225 :
1226 : #if AIC_USE_WIDE
1227 : case SEND_WDTR:
1228 : AIC_ASSERT(sc->sc_nexus != NULL);
1229 : ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1230 : sc->sc_omess[3] = MSG_EXTENDED;
1231 : sc->sc_omess[2] = 2;
1232 : sc->sc_omess[1] = MSG_EXT_WDTR;
1233 : sc->sc_omess[0] = ti->width;
1234 : n = 4;
1235 : break;
1236 : #endif
1237 :
1238 : case SEND_DEV_RESET:
1239 0 : sc->sc_flags |= AIC_ABORTING;
1240 0 : sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1241 : n = 1;
1242 0 : break;
1243 :
1244 : case SEND_REJECT:
1245 0 : sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1246 : n = 1;
1247 0 : break;
1248 :
1249 : case SEND_PARITY_ERROR:
1250 0 : sc->sc_omess[0] = MSG_PARITY_ERROR;
1251 : n = 1;
1252 0 : break;
1253 :
1254 : case SEND_INIT_DET_ERR:
1255 0 : sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1256 : n = 1;
1257 0 : break;
1258 :
1259 : case SEND_ABORT:
1260 0 : sc->sc_flags |= AIC_ABORTING;
1261 0 : sc->sc_omess[0] = MSG_ABORT;
1262 : n = 1;
1263 0 : break;
1264 :
1265 : default:
1266 0 : printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1267 0 : sc->sc_dev.dv_xname);
1268 0 : AIC_BREAK();
1269 0 : sc->sc_omess[0] = MSG_NOOP;
1270 : n = 1;
1271 0 : break;
1272 : }
1273 0 : sc->sc_omp = &sc->sc_omess[n];
1274 :
1275 : nextbyte:
1276 : /* Send message bytes. */
1277 0 : for (;;) {
1278 0 : for (;;) {
1279 0 : sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
1280 0 : if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
1281 : break;
1282 : /* Wait for REQINIT. XXX Need timeout. */
1283 : }
1284 0 : if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
1285 : /*
1286 : * Target left MESSAGE OUT, possibly to reject
1287 : * our message.
1288 : *
1289 : * If this is the last message being sent, then we
1290 : * deassert ATN, since either the target is going to
1291 : * ignore this message, or it's going to ask for a
1292 : * retransmission via MESSAGE PARITY ERROR (in which
1293 : * case we reassert ATN anyway).
1294 : */
1295 0 : if (sc->sc_msgpriq == 0)
1296 0 : bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
1297 : goto out;
1298 : }
1299 :
1300 : /* Clear ATN before last byte if this is the last message. */
1301 0 : if (n == 1 && sc->sc_msgpriq == 0)
1302 0 : bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
1303 : /* Send message byte. */
1304 0 : bus_space_write_1(iot, ioh, SCSIDAT, *--sc->sc_omp);
1305 0 : --n;
1306 : /* Keep track of the last message we've sent any bytes of. */
1307 0 : sc->sc_lastmsg = sc->sc_currmsg;
1308 : /* Wait for ACK to be negated. XXX Need timeout. */
1309 0 : while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
1310 : ;
1311 :
1312 0 : if (n == 0)
1313 : break;
1314 : }
1315 :
1316 : /* We get here only if the entire message has been transmitted. */
1317 0 : if (sc->sc_msgpriq != 0) {
1318 : /* There are more outgoing messages. */
1319 0 : goto nextmsg;
1320 : }
1321 :
1322 : /*
1323 : * The last message has been transmitted. We need to remember the last
1324 : * message transmitted (in case the target switches to MESSAGE IN phase
1325 : * and sends a MESSAGE REJECT), and the list of messages transmitted
1326 : * this time around (in case the target stays in MESSAGE OUT phase to
1327 : * request a retransmit).
1328 : */
1329 :
1330 : out:
1331 : /* Disable REQ/ACK protocol. */
1332 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1333 0 : }
1334 :
1335 : /* aic_dataout_pio: perform a data transfer using the FIFO datapath in the aic6360
1336 : * Precondition: The SCSI bus should be in the DOUT phase, with REQ asserted
1337 : * and ACK deasserted (i.e. waiting for a data byte).
1338 : * This new revision has been optimized (I tried) to make the common case fast,
1339 : * and the rarer cases (as a result) somewhat more complex.
1340 : */
1341 : int
1342 0 : aic_dataout_pio(struct aic_softc *sc, u_char *p, int n)
1343 : {
1344 0 : bus_space_tag_t iot = sc->sc_iot;
1345 0 : bus_space_handle_t ioh = sc->sc_ioh;
1346 : u_char dmastat = 0;
1347 : int out = 0;
1348 : #define DOUTAMOUNT 128 /* Full FIFO */
1349 :
1350 0 : AIC_MISC(("%02x%02x ", bus_space_read_1(iot, ioh, FIFOSTAT),
1351 : bus_space_read_1(iot, ioh, SSTAT2)));
1352 :
1353 : /* Clear host FIFO and counter. */
1354 0 : bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO | WRITE);
1355 : /* Enable FIFOs. */
1356 0 : bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO | WRITE);
1357 0 : bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
1358 :
1359 : /* Turn off ENREQINIT for now. */
1360 0 : bus_space_write_1(iot, ioh, SIMODE1,
1361 : ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
1362 :
1363 : /* I have tried to make the main loop as tight as possible. This
1364 : * means that some of the code following the loop is a bit more
1365 : * complex than otherwise.
1366 : */
1367 0 : while (n > 0) {
1368 0 : for (;;) {
1369 0 : dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1370 0 : if ((dmastat & (DFIFOEMP | INTSTAT)) != 0)
1371 : break;
1372 : }
1373 :
1374 0 : if ((dmastat & INTSTAT) != 0)
1375 : goto phasechange;
1376 :
1377 0 : if (n >= DOUTAMOUNT) {
1378 0 : n -= DOUTAMOUNT;
1379 0 : out += DOUTAMOUNT;
1380 :
1381 : #if AIC_USE_DWORDS
1382 : bus_space_write_multi_4(iot, ioh, DMADATALONG,
1383 : (u_int32_t *)p, DOUTAMOUNT >> 2);
1384 : #else
1385 0 : bus_space_write_multi_2(iot, ioh, DMADATA,
1386 : (u_int16_t *)p, DOUTAMOUNT >> 1);
1387 : #endif
1388 :
1389 0 : p += DOUTAMOUNT;
1390 0 : } else {
1391 : int xfer;
1392 :
1393 : xfer = n;
1394 0 : AIC_MISC(("%d> ", xfer));
1395 :
1396 : n -= xfer;
1397 0 : out += xfer;
1398 :
1399 : #if AIC_USE_DWORDS
1400 : if (xfer >= 12) {
1401 : bus_space_write_multi_4(iot, ioh, DMADATALONG,
1402 : (u_int32_t *)p, xfer >> 2);
1403 : p += xfer & ~3;
1404 : xfer &= 3;
1405 : }
1406 : #else
1407 0 : if (xfer >= 8) {
1408 0 : bus_space_write_multi_2(iot, ioh, DMADATA,
1409 : (u_int16_t *)p, xfer >> 1);
1410 0 : p += xfer & ~1;
1411 0 : xfer &= 1;
1412 0 : }
1413 : #endif
1414 :
1415 0 : if (xfer > 0) {
1416 0 : bus_space_write_1(iot, ioh, DMACNTRL0,
1417 : ENDMA | B8MODE | WRITE);
1418 0 : bus_space_write_multi_1(iot, ioh, DMADATA, p,
1419 : xfer);
1420 0 : p += xfer;
1421 0 : bus_space_write_1(iot, ioh, DMACNTRL0,
1422 : ENDMA | DWORDPIO | WRITE);
1423 0 : }
1424 : }
1425 : }
1426 :
1427 0 : if (out == 0) {
1428 0 : bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
1429 0 : for (;;) {
1430 0 : if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) !=
1431 : 0)
1432 : break;
1433 : }
1434 0 : bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1435 0 : AIC_MISC(("extra data "));
1436 : } else {
1437 : /* See the bytes off chip */
1438 0 : for (;;) {
1439 0 : dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1440 0 : if ((dmastat & INTSTAT) != 0)
1441 : goto phasechange;
1442 0 : if ((dmastat & DFIFOEMP) != 0 &&
1443 0 : (bus_space_read_1(iot, ioh, SSTAT2) & SEMPTY) != 0)
1444 : break;
1445 : }
1446 : }
1447 :
1448 : phasechange:
1449 0 : if ((dmastat & INTSTAT) != 0) {
1450 : /* Some sort of phase change. */
1451 : int amount;
1452 :
1453 : /* Stop transfers, do some accounting */
1454 0 : amount = bus_space_read_1(iot, ioh, FIFOSTAT) +
1455 0 : (bus_space_read_1(iot, ioh, SSTAT2) & 15);
1456 0 : if (amount > 0) {
1457 0 : out -= amount;
1458 0 : bus_space_write_1(iot, ioh, DMACNTRL0,
1459 : RSTFIFO | WRITE);
1460 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH);
1461 0 : AIC_MISC(("+%d ", amount));
1462 : }
1463 0 : }
1464 :
1465 : /* Turn on ENREQINIT again. */
1466 0 : bus_space_write_1(iot, ioh, SIMODE1,
1467 : ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
1468 :
1469 : /* Stop the FIFO data path. */
1470 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1471 0 : bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1472 :
1473 0 : return out;
1474 : }
1475 :
1476 : /* aic_datain_pio: perform data transfers using the FIFO datapath in the aic6360
1477 : * Precondition: The SCSI bus should be in the DIN phase, with REQ asserted
1478 : * and ACK deasserted (i.e. at least one byte is ready).
1479 : * For now, uses a pretty dumb algorithm, hangs around until all data has been
1480 : * transferred. This, is OK for fast targets, but not so smart for slow
1481 : * targets which don't disconnect or for huge transfers.
1482 : */
1483 : int
1484 0 : aic_datain_pio(struct aic_softc *sc, u_char *p, int n)
1485 : {
1486 0 : bus_space_tag_t iot = sc->sc_iot;
1487 0 : bus_space_handle_t ioh = sc->sc_ioh;
1488 : u_char dmastat;
1489 : int in = 0;
1490 : #define DINAMOUNT 128 /* Full FIFO */
1491 :
1492 0 : AIC_MISC(("%02x%02x ", bus_space_read_1(iot, ioh, FIFOSTAT),
1493 : bus_space_read_1(iot, ioh, SSTAT2)));
1494 :
1495 : /* Clear host FIFO and counter. */
1496 0 : bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
1497 : /* Enable FIFOs. */
1498 0 : bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO);
1499 0 : bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
1500 :
1501 : /* Turn off ENREQINIT for now. */
1502 0 : bus_space_write_1(iot, ioh, SIMODE1,
1503 : ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
1504 :
1505 : /* We leave this loop if one or more of the following is true:
1506 : * a) phase != PH_DATAIN && FIFOs are empty
1507 : * b) SCSIRSTI is set (a reset has occurred) or busfree is detected.
1508 : */
1509 0 : while (n > 0) {
1510 : /* Wait for fifo half full or phase mismatch */
1511 0 : for (;;) {
1512 0 : dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1513 0 : if ((dmastat & (DFIFOFULL | INTSTAT)) != 0)
1514 : break;
1515 : }
1516 :
1517 0 : if ((dmastat & DFIFOFULL) != 0) {
1518 0 : n -= DINAMOUNT;
1519 0 : in += DINAMOUNT;
1520 :
1521 : #if AIC_USE_DWORDS
1522 : bus_space_read_multi_4(iot, ioh, DMADATALONG,
1523 : (u_int32_t *)p, DINAMOUNT >> 2);
1524 : #else
1525 0 : bus_space_read_multi_2(iot, ioh, DMADATA,
1526 : (u_int16_t *)p, DINAMOUNT >> 1);
1527 : #endif
1528 :
1529 0 : p += DINAMOUNT;
1530 0 : } else {
1531 : int xfer;
1532 :
1533 0 : xfer = min(bus_space_read_1(iot, ioh, FIFOSTAT), n);
1534 0 : AIC_MISC((">%d ", xfer));
1535 :
1536 0 : n -= xfer;
1537 0 : in += xfer;
1538 :
1539 : #if AIC_USE_DWORDS
1540 : if (xfer >= 12) {
1541 : bus_space_read_multi_4(iot, ioh, DMADATALONG,
1542 : (u_int32_t *)p, xfer >> 2);
1543 : p += xfer & ~3;
1544 : xfer &= 3;
1545 : }
1546 : #else
1547 0 : if (xfer >= 8) {
1548 0 : bus_space_read_multi_2(iot, ioh, DMADATA,
1549 : (u_int16_t *)p, xfer >> 1);
1550 0 : p += xfer & ~1;
1551 0 : xfer &= 1;
1552 0 : }
1553 : #endif
1554 :
1555 0 : if (xfer > 0) {
1556 0 : bus_space_write_1(iot, ioh, DMACNTRL0,
1557 : ENDMA | B8MODE);
1558 0 : bus_space_read_multi_1(iot, ioh, DMADATA, p,
1559 : xfer);
1560 0 : p += xfer;
1561 0 : bus_space_write_1(iot, ioh, DMACNTRL0,
1562 : ENDMA | DWORDPIO);
1563 0 : }
1564 : }
1565 :
1566 0 : if ((dmastat & INTSTAT) != 0)
1567 : goto phasechange;
1568 : }
1569 :
1570 : /* Some SCSI-devices are rude enough to transfer more data than what
1571 : * was requested, e.g. 2048 bytes from a CD-ROM instead of the
1572 : * requested 512. Test for progress, i.e. real transfers. If no real
1573 : * transfers have been performed (n is probably already zero) and the
1574 : * FIFO is not empty, waste some bytes....
1575 : */
1576 0 : if (in == 0) {
1577 0 : bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
1578 0 : for (;;) {
1579 0 : if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) !=
1580 : 0)
1581 : break;
1582 : }
1583 0 : bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1584 0 : AIC_MISC(("extra data "));
1585 : }
1586 :
1587 : phasechange:
1588 : /* Turn on ENREQINIT again. */
1589 0 : bus_space_write_1(iot, ioh, SIMODE1,
1590 : ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
1591 :
1592 : /* Stop the FIFO data path. */
1593 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1594 0 : bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1595 :
1596 0 : return in;
1597 : }
1598 :
1599 : /*
1600 : * This is the workhorse routine of the driver.
1601 : * Deficiencies (for now):
1602 : * 1) always uses programmed I/O
1603 : */
1604 : int
1605 0 : aicintr(void *arg)
1606 : {
1607 0 : struct aic_softc *sc = arg;
1608 0 : bus_space_tag_t iot = sc->sc_iot;
1609 0 : bus_space_handle_t ioh = sc->sc_ioh;
1610 : u_char sstat0, sstat1;
1611 : struct aic_acb *acb;
1612 : struct scsi_link *sc_link;
1613 : struct aic_tinfo *ti;
1614 : int n;
1615 :
1616 : /*
1617 : * Clear INTEN. We enable it again before returning. This makes the
1618 : * interrupt esssentially level-triggered.
1619 : */
1620 0 : bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1621 :
1622 0 : AIC_TRACE(("aicintr "));
1623 :
1624 : loop:
1625 : /*
1626 : * First check for abnormal conditions, such as reset.
1627 : */
1628 0 : sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
1629 0 : AIC_MISC(("sstat1:0x%02x ", sstat1));
1630 :
1631 0 : if ((sstat1 & SCSIRSTI) != 0) {
1632 0 : printf("%s: SCSI bus reset\n", sc->sc_dev.dv_xname);
1633 0 : goto reset;
1634 : }
1635 :
1636 : /*
1637 : * Check for less serious errors.
1638 : */
1639 0 : if ((sstat1 & SCSIPERR) != 0) {
1640 0 : printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
1641 0 : bus_space_write_1(iot, ioh, CLRSINT1, CLRSCSIPERR);
1642 0 : if (sc->sc_prevphase == PH_MSGIN) {
1643 0 : sc->sc_flags |= AIC_DROP_MSGIN;
1644 0 : aic_sched_msgout(sc, SEND_PARITY_ERROR);
1645 0 : } else
1646 0 : aic_sched_msgout(sc, SEND_INIT_DET_ERR);
1647 : }
1648 :
1649 : /*
1650 : * If we're not already busy doing something test for the following
1651 : * conditions:
1652 : * 1) We have been reselected by something
1653 : * 2) We have selected something successfully
1654 : * 3) Our selection process has timed out
1655 : * 4) This is really a bus free interrupt just to get a new command
1656 : * going?
1657 : * 5) Spurious interrupt?
1658 : */
1659 0 : switch (sc->sc_state) {
1660 : case AIC_IDLE:
1661 : case AIC_SELECTING:
1662 0 : sstat0 = bus_space_read_1(iot, ioh, SSTAT0);
1663 0 : AIC_MISC(("sstat0:0x%02x ", sstat0));
1664 :
1665 0 : if ((sstat0 & TARGET) != 0) {
1666 : /*
1667 : * We don't currently support target mode.
1668 : */
1669 0 : printf("%s: target mode selected; going to BUS FREE\n",
1670 0 : sc->sc_dev.dv_xname);
1671 0 : bus_space_write_1(iot, ioh, SCSISIG, 0);
1672 :
1673 0 : goto sched;
1674 0 : } else if ((sstat0 & SELDI) != 0) {
1675 0 : AIC_MISC(("reselected "));
1676 :
1677 : /*
1678 : * If we're trying to select a target ourselves,
1679 : * push our command back into the ready list.
1680 : */
1681 0 : if (sc->sc_state == AIC_SELECTING) {
1682 0 : AIC_MISC(("backoff selector "));
1683 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1684 0 : acb = sc->sc_nexus;
1685 0 : sc->sc_nexus = NULL;
1686 0 : TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
1687 0 : }
1688 :
1689 : /* Save reselection ID. */
1690 0 : sc->sc_selid = bus_space_read_1(iot, ioh, SELID);
1691 :
1692 0 : sc->sc_state = AIC_RESELECTED;
1693 0 : } else if ((sstat0 & SELDO) != 0) {
1694 0 : AIC_MISC(("selected "));
1695 :
1696 : /* We have selected a target. Things to do:
1697 : * a) Determine what message(s) to send.
1698 : * b) Verify that we're still selecting the target.
1699 : * c) Mark device as busy.
1700 : */
1701 0 : if (sc->sc_state != AIC_SELECTING) {
1702 0 : printf("%s: selection out while idle; ",
1703 0 : sc->sc_dev.dv_xname);
1704 0 : printf("resetting\n");
1705 0 : AIC_BREAK();
1706 : goto reset;
1707 : }
1708 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1709 0 : acb = sc->sc_nexus;
1710 0 : sc_link = acb->xs->sc_link;
1711 0 : ti = &sc->sc_tinfo[sc_link->target];
1712 :
1713 0 : sc->sc_msgpriq = SEND_IDENTIFY;
1714 0 : if (acb->flags & ACB_RESET)
1715 0 : sc->sc_msgpriq |= SEND_DEV_RESET;
1716 0 : else if (acb->flags & ACB_ABORT)
1717 0 : sc->sc_msgpriq |= SEND_ABORT;
1718 : else {
1719 : #if AIC_USE_SYNCHRONOUS
1720 : if ((ti->flags & DO_SYNC) != 0)
1721 : sc->sc_msgpriq |= SEND_SDTR;
1722 : #endif
1723 : #if AIC_USE_WIDE
1724 : if ((ti->flags & DO_WIDE) != 0)
1725 : sc->sc_msgpriq |= SEND_WDTR;
1726 : #endif
1727 : }
1728 :
1729 0 : acb->flags |= ACB_NEXUS;
1730 0 : ti->lubusy |= (1 << sc_link->lun);
1731 :
1732 : /* Do an implicit RESTORE POINTERS. */
1733 0 : sc->sc_dp = acb->data_addr;
1734 0 : sc->sc_dleft = acb->data_length;
1735 0 : sc->sc_cp = (u_char *)&acb->scsi_cmd;
1736 0 : sc->sc_cleft = acb->scsi_cmd_length;
1737 :
1738 : /* On our first connection, schedule a timeout. */
1739 0 : if ((acb->xs->flags & SCSI_POLL) == 0)
1740 0 : timeout_add_msec(&acb->xs->stimeout, acb->timeout);
1741 :
1742 0 : sc->sc_state = AIC_CONNECTED;
1743 0 : } else if ((sstat1 & SELTO) != 0) {
1744 0 : AIC_MISC(("selection timeout "));
1745 :
1746 0 : if (sc->sc_state != AIC_SELECTING) {
1747 0 : printf("%s: selection timeout while idle; ",
1748 0 : sc->sc_dev.dv_xname);
1749 0 : printf("resetting\n");
1750 0 : AIC_BREAK();
1751 : goto reset;
1752 : }
1753 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1754 0 : acb = sc->sc_nexus;
1755 :
1756 0 : bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1757 0 : bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
1758 0 : bus_space_write_1(iot, ioh, CLRSINT1, CLRSELTIMO);
1759 0 : delay(250);
1760 :
1761 0 : acb->xs->error = XS_SELTIMEOUT;
1762 0 : goto finish;
1763 : } else {
1764 0 : if (sc->sc_state != AIC_IDLE) {
1765 0 : printf("%s: BUS FREE while not idle; ",
1766 0 : sc->sc_dev.dv_xname);
1767 0 : printf("state=%d\n", sc->sc_state);
1768 0 : AIC_BREAK();
1769 : goto out;
1770 : }
1771 :
1772 : goto sched;
1773 : }
1774 :
1775 : /*
1776 : * Turn off selection stuff, and prepare to catch bus free
1777 : * interrupts, parity errors, and phase changes.
1778 : */
1779 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRSTCNT | CLRCH);
1780 0 : bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1781 0 : bus_space_write_1(iot, ioh, SCSISEQ, ENAUTOATNP);
1782 0 : bus_space_write_1(iot, ioh, CLRSINT0, CLRSELDI | CLRSELDO);
1783 0 : bus_space_write_1(iot, ioh, CLRSINT1,
1784 : CLRBUSFREE | CLRPHASECHG);
1785 0 : bus_space_write_1(iot, ioh, SIMODE0, 0);
1786 0 : bus_space_write_1(iot, ioh, SIMODE1,
1787 : ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT |
1788 : ENPHASECHG);
1789 :
1790 0 : sc->sc_flags = 0;
1791 0 : sc->sc_prevphase = PH_INVALID;
1792 0 : goto dophase;
1793 : }
1794 :
1795 0 : if ((sstat1 & BUSFREE) != 0) {
1796 : /* We've gone to BUS FREE phase. */
1797 0 : bus_space_write_1(iot, ioh, CLRSINT1,
1798 : CLRBUSFREE | CLRPHASECHG);
1799 :
1800 0 : switch (sc->sc_state) {
1801 : case AIC_RESELECTED:
1802 : goto sched;
1803 :
1804 : case AIC_CONNECTED:
1805 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1806 0 : acb = sc->sc_nexus;
1807 :
1808 : #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
1809 : if (sc->sc_prevphase == PH_MSGOUT) {
1810 : /*
1811 : * If the target went to BUS FREE phase during
1812 : * or immediately after sending a SDTR or WDTR
1813 : * message, disable negotiation.
1814 : */
1815 : sc_link = acb->xs->sc_link;
1816 : ti = &sc->sc_tinfo[sc_link->target];
1817 : switch (sc->sc_lastmsg) {
1818 : #if AIC_USE_SYNCHRONOUS
1819 : case SEND_SDTR:
1820 : ti->flags &= ~DO_SYNC;
1821 : ti->period = ti->offset = 0;
1822 : break;
1823 : #endif
1824 : #if AIC_USE_WIDE
1825 : case SEND_WDTR:
1826 : ti->flags &= ~DO_WIDE;
1827 : ti->width = 0;
1828 : break;
1829 : #endif
1830 : }
1831 : }
1832 : #endif
1833 :
1834 0 : if ((sc->sc_flags & AIC_ABORTING) == 0) {
1835 : /*
1836 : * Section 5.1.1 of the SCSI 2 spec suggests
1837 : * issuing a REQUEST SENSE following an
1838 : * unexpected disconnect. Some devices go into
1839 : * a contingent allegiance condition when
1840 : * disconnecting, and this is necessary to
1841 : * clean up their state.
1842 : */
1843 0 : printf("%s: unexpected disconnect; ",
1844 0 : sc->sc_dev.dv_xname);
1845 0 : printf("sending REQUEST SENSE\n");
1846 0 : AIC_BREAK();
1847 0 : aic_sense(sc, acb);
1848 0 : goto out;
1849 : }
1850 :
1851 0 : acb->xs->error = XS_DRIVER_STUFFUP;
1852 0 : goto finish;
1853 :
1854 : case AIC_DISCONNECT:
1855 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1856 0 : acb = sc->sc_nexus;
1857 : #if 1 /* XXXX */
1858 0 : acb->data_addr = sc->sc_dp;
1859 0 : acb->data_length = sc->sc_dleft;
1860 : #endif
1861 0 : TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
1862 0 : sc->sc_nexus = NULL;
1863 0 : goto sched;
1864 :
1865 : case AIC_CMDCOMPLETE:
1866 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1867 0 : acb = sc->sc_nexus;
1868 0 : goto finish;
1869 : }
1870 : }
1871 :
1872 0 : bus_space_write_1(iot, ioh, CLRSINT1, CLRPHASECHG);
1873 :
1874 : dophase:
1875 0 : if ((sstat1 & REQINIT) == 0) {
1876 : /* Wait for REQINIT. */
1877 : goto out;
1878 : }
1879 :
1880 0 : sc->sc_phase = bus_space_read_1(iot, ioh, SCSISIG) & PH_MASK;
1881 0 : bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase);
1882 :
1883 0 : switch (sc->sc_phase) {
1884 : case PH_MSGOUT:
1885 0 : if (sc->sc_state != AIC_CONNECTED &&
1886 0 : sc->sc_state != AIC_RESELECTED)
1887 : break;
1888 0 : aic_msgout(sc);
1889 0 : sc->sc_prevphase = PH_MSGOUT;
1890 0 : goto loop;
1891 :
1892 : case PH_MSGIN:
1893 0 : if (sc->sc_state != AIC_CONNECTED &&
1894 0 : sc->sc_state != AIC_RESELECTED)
1895 : break;
1896 0 : aic_msgin(sc);
1897 0 : sc->sc_prevphase = PH_MSGIN;
1898 0 : goto loop;
1899 :
1900 : case PH_CMD:
1901 0 : if (sc->sc_state != AIC_CONNECTED)
1902 : break;
1903 : #ifdef AIC_DEBUG
1904 0 : if ((aic_debug & AIC_SHOWMISC) != 0) {
1905 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1906 0 : acb = sc->sc_nexus;
1907 0 : printf("cmd=0x%02x+%d ",
1908 0 : acb->scsi_cmd.opcode, acb->scsi_cmd_length-1);
1909 0 : }
1910 : #endif
1911 0 : n = aic_dataout_pio(sc, sc->sc_cp, sc->sc_cleft);
1912 0 : sc->sc_cp += n;
1913 0 : sc->sc_cleft -= n;
1914 0 : sc->sc_prevphase = PH_CMD;
1915 0 : goto loop;
1916 :
1917 : case PH_DATAOUT:
1918 0 : if (sc->sc_state != AIC_CONNECTED)
1919 : break;
1920 0 : AIC_MISC(("dataout dleft=%lu ", (u_long)sc->sc_dleft));
1921 0 : n = aic_dataout_pio(sc, sc->sc_dp, sc->sc_dleft);
1922 0 : sc->sc_dp += n;
1923 0 : sc->sc_dleft -= n;
1924 0 : sc->sc_prevphase = PH_DATAOUT;
1925 0 : goto loop;
1926 :
1927 : case PH_DATAIN:
1928 0 : if (sc->sc_state != AIC_CONNECTED)
1929 : break;
1930 0 : AIC_MISC(("datain %lu ", (u_long)sc->sc_dleft));
1931 0 : n = aic_datain_pio(sc, sc->sc_dp, sc->sc_dleft);
1932 0 : sc->sc_dp += n;
1933 0 : sc->sc_dleft -= n;
1934 0 : sc->sc_prevphase = PH_DATAIN;
1935 0 : goto loop;
1936 :
1937 : case PH_STAT:
1938 0 : if (sc->sc_state != AIC_CONNECTED)
1939 : break;
1940 0 : AIC_ASSERT(sc->sc_nexus != NULL);
1941 0 : acb = sc->sc_nexus;
1942 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1943 0 : acb->target_stat = bus_space_read_1(iot, ioh, SCSIDAT);
1944 0 : bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1945 0 : AIC_MISC(("target_stat=0x%02x ", acb->target_stat));
1946 0 : sc->sc_prevphase = PH_STAT;
1947 0 : goto loop;
1948 : }
1949 :
1950 0 : printf("%s: unexpected bus phase; resetting\n", sc->sc_dev.dv_xname);
1951 0 : AIC_BREAK();
1952 : reset:
1953 0 : aic_init(sc);
1954 0 : return 1;
1955 :
1956 : finish:
1957 0 : timeout_del(&acb->xs->stimeout);
1958 0 : aic_done(sc, acb);
1959 0 : goto out;
1960 :
1961 : sched:
1962 0 : sc->sc_state = AIC_IDLE;
1963 0 : aic_sched(sc);
1964 0 : goto out;
1965 :
1966 : out:
1967 0 : bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
1968 0 : return 1;
1969 0 : }
1970 :
1971 : void
1972 0 : aic_abort(struct aic_softc *sc, struct aic_acb *acb)
1973 : {
1974 :
1975 : /* 2 secs for the abort */
1976 0 : acb->timeout = AIC_ABORT_TIMEOUT;
1977 0 : acb->flags |= ACB_ABORT;
1978 :
1979 0 : if (acb == sc->sc_nexus) {
1980 : /*
1981 : * If we're still selecting, the message will be scheduled
1982 : * after selection is complete.
1983 : */
1984 0 : if (sc->sc_state == AIC_CONNECTED)
1985 0 : aic_sched_msgout(sc, SEND_ABORT);
1986 : } else {
1987 0 : aic_dequeue(sc, acb);
1988 0 : TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
1989 0 : if (sc->sc_state == AIC_IDLE)
1990 0 : aic_sched(sc);
1991 : }
1992 0 : }
1993 :
1994 : void
1995 0 : aic_timeout(void *arg)
1996 : {
1997 0 : struct aic_acb *acb = arg;
1998 0 : struct scsi_xfer *xs = acb->xs;
1999 0 : struct scsi_link *sc_link = xs->sc_link;
2000 0 : struct aic_softc *sc = sc_link->adapter_softc;
2001 : int s;
2002 :
2003 0 : sc_print_addr(sc_link);
2004 0 : printf("timed out");
2005 :
2006 0 : s = splbio();
2007 :
2008 0 : if (acb->flags & ACB_ABORT) {
2009 : /* abort timed out */
2010 0 : printf(" AGAIN\n");
2011 : /* XXX Must reset! */
2012 0 : } else {
2013 : /* abort the operation that has timed out */
2014 0 : printf("\n");
2015 0 : acb->xs->error = XS_TIMEOUT;
2016 0 : aic_abort(sc, acb);
2017 : }
2018 :
2019 0 : splx(s);
2020 0 : }
2021 :
2022 : #ifdef AIC_DEBUG
2023 : /*
2024 : * The following functions are mostly used for debugging purposes, either
2025 : * directly called from the driver or from the kernel debugger.
2026 : */
2027 :
2028 : void
2029 0 : aic_show_scsi_cmd(struct aic_acb *acb)
2030 : {
2031 0 : u_char *b = (u_char *)&acb->scsi_cmd;
2032 0 : struct scsi_link *sc_link = acb->xs->sc_link;
2033 : int i;
2034 :
2035 0 : sc_print_addr(sc_link);
2036 0 : if ((acb->xs->flags & SCSI_RESET) == 0) {
2037 0 : for (i = 0; i < acb->scsi_cmd_length; i++) {
2038 0 : if (i)
2039 0 : printf(",");
2040 0 : printf("%x", b[i]);
2041 : }
2042 0 : printf("\n");
2043 0 : } else
2044 0 : printf("RESET\n");
2045 0 : }
2046 :
2047 : void
2048 0 : aic_print_acb(struct aic_acb *acb)
2049 : {
2050 :
2051 0 : printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags);
2052 0 : printf(" dp=%p dleft=%d target_stat=%x\n",
2053 0 : acb->data_addr, acb->data_length, acb->target_stat);
2054 0 : aic_show_scsi_cmd(acb);
2055 0 : }
2056 :
2057 : void
2058 0 : aic_print_active_acb(void)
2059 : {
2060 : struct aic_acb *acb;
2061 0 : struct aic_softc *sc = aic_cd.cd_devs[0];
2062 :
2063 0 : printf("ready list:\n");
2064 0 : TAILQ_FOREACH(acb, &sc->ready_list, chain)
2065 0 : aic_print_acb(acb);
2066 0 : printf("nexus:\n");
2067 0 : if (sc->sc_nexus != NULL)
2068 0 : aic_print_acb(sc->sc_nexus);
2069 0 : printf("nexus list:\n");
2070 0 : TAILQ_FOREACH(acb, &sc->nexus_list, chain)
2071 0 : aic_print_acb(acb);
2072 0 : }
2073 :
2074 : void
2075 0 : aic_dump6360(struct aic_softc *sc)
2076 : {
2077 0 : bus_space_tag_t iot = sc->sc_iot;
2078 0 : bus_space_handle_t ioh = sc->sc_ioh;
2079 :
2080 0 : printf("aic6360: SCSISEQ=%x SXFRCTL0=%x SXFRCTL1=%x SCSISIG=%x\n",
2081 0 : bus_space_read_1(iot, ioh, SCSISEQ),
2082 0 : bus_space_read_1(iot, ioh, SXFRCTL0),
2083 0 : bus_space_read_1(iot, ioh, SXFRCTL1),
2084 0 : bus_space_read_1(iot, ioh, SCSISIG));
2085 0 : printf(" SSTAT0=%x SSTAT1=%x SSTAT2=%x SSTAT3=%x SSTAT4=%x\n",
2086 0 : bus_space_read_1(iot, ioh, SSTAT0),
2087 0 : bus_space_read_1(iot, ioh, SSTAT1),
2088 0 : bus_space_read_1(iot, ioh, SSTAT2),
2089 0 : bus_space_read_1(iot, ioh, SSTAT3),
2090 0 : bus_space_read_1(iot, ioh, SSTAT4));
2091 0 : printf(" SIMODE0=%x SIMODE1=%x ",
2092 0 : bus_space_read_1(iot, ioh, SIMODE0),
2093 0 : bus_space_read_1(iot, ioh, SIMODE1));
2094 0 : printf("DMACNTRL0=%x DMACNTRL1=%x DMASTAT=%x\n",
2095 0 : bus_space_read_1(iot, ioh, DMACNTRL0),
2096 0 : bus_space_read_1(iot, ioh, DMACNTRL1),
2097 0 : bus_space_read_1(iot, ioh, DMASTAT));
2098 0 : printf(" FIFOSTAT=%d SCSIBUS=0x%x\n",
2099 0 : bus_space_read_1(iot, ioh, FIFOSTAT),
2100 0 : bus_space_read_1(iot, ioh, SCSIBUS));
2101 0 : }
2102 :
2103 : void
2104 0 : aic_dump_driver(struct aic_softc *sc)
2105 : {
2106 : struct aic_tinfo *ti;
2107 : int i;
2108 :
2109 0 : printf("nexus=%p prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase);
2110 0 : printf("state=%x msgin=%x ", sc->sc_state, sc->sc_imess[0]);
2111 0 : printf("msgpriq=%x msgoutq=%x lastmsg=%x currmsg=%x\n", sc->sc_msgpriq,
2112 0 : sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
2113 0 : for (i = 0; i < 7; i++) {
2114 0 : ti = &sc->sc_tinfo[i];
2115 0 : printf("tinfo%d: %d cmds %d disconnects %d timeouts",
2116 0 : i, ti->cmds, ti->dconns, ti->touts);
2117 0 : printf(" %d senses flags=%x\n", ti->senses, ti->flags);
2118 : }
2119 0 : }
2120 : #endif
|