adw.c revision 1.6 1 /* $NetBSD: adw.c,v 1.6 1998/12/09 08:47:18 thorpej Exp $ */
2
3 /*
4 * Generic driver for the Advanced Systems Inc. SCSI controllers
5 *
6 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * All rights reserved.
8 *
9 * Author: Baldassare Dante Profeta <dante (at) mclink.it>
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/errno.h>
45 #include <sys/ioctl.h>
46 #include <sys/device.h>
47 #include <sys/malloc.h>
48 #include <sys/buf.h>
49 #include <sys/proc.h>
50 #include <sys/user.h>
51
52 #include <machine/bus.h>
53 #include <machine/intr.h>
54
55 #include <vm/vm.h>
56 #include <vm/vm_param.h>
57 #include <vm/pmap.h>
58
59 #include <dev/scsipi/scsi_all.h>
60 #include <dev/scsipi/scsipi_all.h>
61 #include <dev/scsipi/scsiconf.h>
62
63 #include <dev/ic/adwlib.h>
64 #include <dev/ic/adw.h>
65
66 #ifndef DDB
67 #define Debugger() panic("should call debugger here (adv.c)")
68 #endif /* ! DDB */
69
70 /******************************************************************************/
71
72
73 static int adw_alloc_ccbs __P((ADW_SOFTC *));
74 static int adw_create_ccbs __P((ADW_SOFTC *, ADW_CCB *, int));
75 static void adw_free_ccb __P((ADW_SOFTC *, ADW_CCB *));
76 static void adw_reset_ccb __P((ADW_CCB *));
77 static int adw_init_ccb __P((ADW_SOFTC *, ADW_CCB *));
78 static ADW_CCB *adw_get_ccb __P((ADW_SOFTC *, int));
79 static void adw_queue_ccb __P((ADW_SOFTC *, ADW_CCB *));
80 static void adw_start_ccbs __P((ADW_SOFTC *));
81
82 static int adw_scsi_cmd __P((struct scsipi_xfer *));
83 static int adw_build_req __P((struct scsipi_xfer *, ADW_CCB *));
84 static void adw_build_sglist __P((ADW_CCB *, ADW_SCSI_REQ_Q *));
85 static void adwminphys __P((struct buf *));
86 static void adw_wide_isr_callback __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *));
87
88 static int adw_poll __P((ADW_SOFTC *, struct scsipi_xfer *, int));
89 static void adw_timeout __P((void *));
90 static void adw_watchdog __P((void *));
91
92
93 /******************************************************************************/
94
95
96 /* the below structure is so we have a default dev struct for out link struct */
97 struct scsipi_device adw_dev =
98 {
99 NULL, /* Use default error handler */
100 NULL, /* have a queue, served by this */
101 NULL, /* have no async handler */
102 NULL, /* Use default 'done' routine */
103 };
104
105
106 #define ADW_ABORT_TIMEOUT 10000 /* time to wait for abort (mSec) */
107 #define ADW_WATCH_TIMEOUT 10000 /* time to wait for watchdog (mSec) */
108
109
110 /******************************************************************************/
111 /* Control Blocks routines */
112 /******************************************************************************/
113
114
115 static int
116 adw_alloc_ccbs(sc)
117 ADW_SOFTC *sc;
118 {
119 bus_dma_segment_t seg;
120 int error, rseg;
121
122 /*
123 * Allocate the control blocks.
124 */
125 if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adw_control),
126 NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
127 printf("%s: unable to allocate control structures,"
128 " error = %d\n", sc->sc_dev.dv_xname, error);
129 return (error);
130 }
131 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
132 sizeof(struct adw_control), (caddr_t *) & sc->sc_control,
133 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
134 printf("%s: unable to map control structures, error = %d\n",
135 sc->sc_dev.dv_xname, error);
136 return (error);
137 }
138 /*
139 * Create and load the DMA map used for the control blocks.
140 */
141 if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adw_control),
142 1, sizeof(struct adw_control), 0, BUS_DMA_NOWAIT,
143 &sc->sc_dmamap_control)) != 0) {
144 printf("%s: unable to create control DMA map, error = %d\n",
145 sc->sc_dev.dv_xname, error);
146 return (error);
147 }
148 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
149 sc->sc_control, sizeof(struct adw_control), NULL,
150 BUS_DMA_NOWAIT)) != 0) {
151 printf("%s: unable to load control DMA map, error = %d\n",
152 sc->sc_dev.dv_xname, error);
153 return (error);
154 }
155 return (0);
156 }
157
158
159 /*
160 * Create a set of ccbs and add them to the free list. Called once
161 * by adw_init(). We return the number of CCBs successfully created.
162 */
163 static int
164 adw_create_ccbs(sc, ccbstore, count)
165 ADW_SOFTC *sc;
166 ADW_CCB *ccbstore;
167 int count;
168 {
169 ADW_CCB *ccb;
170 int i, error;
171
172 bzero(ccbstore, sizeof(ADW_CCB) * count);
173 for (i = 0; i < count; i++) {
174 ccb = &ccbstore[i];
175 if ((error = adw_init_ccb(sc, ccb)) != 0) {
176 printf("%s: unable to initialize ccb, error = %d\n",
177 sc->sc_dev.dv_xname, error);
178 return (i);
179 }
180 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
181 }
182
183 return (i);
184 }
185
186
187 /*
188 * A ccb is put onto the free list.
189 */
190 static void
191 adw_free_ccb(sc, ccb)
192 ADW_SOFTC *sc;
193 ADW_CCB *ccb;
194 {
195 int s;
196
197 s = splbio();
198
199 adw_reset_ccb(ccb);
200 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
201
202 /*
203 * If there were none, wake anybody waiting for one to come free,
204 * starting with queued entries.
205 */
206 if (ccb->chain.tqe_next == 0)
207 wakeup(&sc->sc_free_ccb);
208
209 splx(s);
210 }
211
212
213 static void
214 adw_reset_ccb(ccb)
215 ADW_CCB *ccb;
216 {
217
218 ccb->flags = 0;
219 }
220
221
222 static int
223 adw_init_ccb(sc, ccb)
224 ADW_SOFTC *sc;
225 ADW_CCB *ccb;
226 {
227 int error;
228
229 /*
230 * Create the DMA map for this CCB.
231 */
232 error = bus_dmamap_create(sc->sc_dmat,
233 (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
234 ADW_MAX_SG_LIST, (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
235 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
236 if (error) {
237 printf("%s: unable to create DMA map, error = %d\n",
238 sc->sc_dev.dv_xname, error);
239 return (error);
240 }
241 adw_reset_ccb(ccb);
242 return (0);
243 }
244
245
246 /*
247 * Get a free ccb
248 *
249 * If there are none, see if we can allocate a new one
250 */
251 static ADW_CCB *
252 adw_get_ccb(sc, flags)
253 ADW_SOFTC *sc;
254 int flags;
255 {
256 ADW_CCB *ccb = 0;
257 int s;
258
259 s = splbio();
260
261 /*
262 * If we can and have to, sleep waiting for one to come free
263 * but only if we can't allocate a new one.
264 */
265 for (;;) {
266 ccb = sc->sc_free_ccb.tqh_first;
267 if (ccb) {
268 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
269 break;
270 }
271 if ((flags & SCSI_NOSLEEP) != 0)
272 goto out;
273
274 tsleep(&sc->sc_free_ccb, PRIBIO, "adwccb", 0);
275 }
276
277 ccb->flags |= CCB_ALLOC;
278
279 out:
280 splx(s);
281 return (ccb);
282 }
283
284
285 /*
286 * Queue a CCB to be sent to the controller, and send it if possible.
287 */
288 static void
289 adw_queue_ccb(sc, ccb)
290 ADW_SOFTC *sc;
291 ADW_CCB *ccb;
292 {
293
294 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
295
296 adw_start_ccbs(sc);
297 }
298
299
300 static void
301 adw_start_ccbs(sc)
302 ADW_SOFTC *sc;
303 {
304 ADW_CCB *ccb;
305
306 while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
307 if (ccb->flags & CCB_WATCHDOG)
308 untimeout(adw_watchdog, ccb);
309
310 if (AdvExeScsiQueue(sc, &ccb->scsiq) == ADW_BUSY) {
311 ccb->flags |= CCB_WATCHDOG;
312 timeout(adw_watchdog, ccb,
313 (ADW_WATCH_TIMEOUT * hz) / 1000);
314 break;
315 }
316 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
317
318 if ((ccb->xs->flags & SCSI_POLL) == 0)
319 timeout(adw_timeout, ccb, (ccb->timeout * hz) / 1000);
320 }
321 }
322
323
324 /******************************************************************************/
325 /* SCSI layer interfacing routines */
326 /******************************************************************************/
327
328
329 int
330 adw_init(sc)
331 ADW_SOFTC *sc;
332 {
333 u_int16_t warn_code;
334
335
336 sc->cfg.lib_version = (ADW_LIB_VERSION_MAJOR << 8) |
337 ADW_LIB_VERSION_MINOR;
338 sc->cfg.chip_version =
339 ADW_GET_CHIP_VERSION(sc->sc_iot, sc->sc_ioh, sc->bus_type);
340
341 /*
342 * Reset the chip to start and allow register writes.
343 */
344 if (ADW_FIND_SIGNATURE(sc->sc_iot, sc->sc_ioh) == 0) {
345 panic("adw_init: adw_find_signature failed");
346 } else {
347 AdvResetChip(sc->sc_iot, sc->sc_ioh);
348
349 warn_code = AdvInitFromEEP(sc);
350 if (warn_code & ASC_WARN_EEPROM_CHKSUM)
351 printf("%s: Bad checksum found. "
352 "Setting default values\n",
353 sc->sc_dev.dv_xname);
354 if (warn_code & ASC_WARN_EEPROM_TERMINATION)
355 printf("%s: Bad bus termination setting."
356 "Using automatic termination.\n",
357 sc->sc_dev.dv_xname);
358
359 /*
360 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
361 * Resets should be performed.
362 */
363 if (sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
364 AdvResetSCSIBus(sc);
365 }
366
367 sc->isr_callback = (ulong) adw_wide_isr_callback;
368
369 return (0);
370 }
371
372
373 void
374 adw_attach(sc)
375 ADW_SOFTC *sc;
376 {
377 int i, error;
378
379
380 /*
381 * Initialize the ASC3550.
382 */
383 switch (AdvInitAsc3550Driver(sc)) {
384 case ASC_IERR_MCODE_CHKSUM:
385 panic("%s: Microcode checksum error",
386 sc->sc_dev.dv_xname);
387 break;
388
389 case ASC_IERR_ILLEGAL_CONNECTION:
390 panic("%s: All three connectors are in use",
391 sc->sc_dev.dv_xname);
392 break;
393
394 case ASC_IERR_REVERSED_CABLE:
395 panic("%s: Cable is reversed",
396 sc->sc_dev.dv_xname);
397 break;
398
399 case ASC_IERR_SINGLE_END_DEVICE:
400 panic("%s: single-ended device is attached to"
401 " one of the connectors",
402 sc->sc_dev.dv_xname);
403 break;
404 }
405
406 /*
407 * Fill in the adapter.
408 */
409 sc->sc_adapter.scsipi_cmd = adw_scsi_cmd;
410 sc->sc_adapter.scsipi_minphys = adwminphys;
411
412 /*
413 * fill in the prototype scsipi_link.
414 */
415 sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
416 sc->sc_link.adapter_softc = sc;
417 sc->sc_link.scsipi_scsi.adapter_target = sc->chip_scsi_id;
418 sc->sc_link.adapter = &sc->sc_adapter;
419 sc->sc_link.device = &adw_dev;
420 sc->sc_link.openings = 4;
421 sc->sc_link.scsipi_scsi.max_target = ADW_MAX_TID;
422 sc->sc_link.scsipi_scsi.max_lun = 7;
423 sc->sc_link.type = BUS_SCSI;
424
425
426 TAILQ_INIT(&sc->sc_free_ccb);
427 TAILQ_INIT(&sc->sc_waiting_ccb);
428 TAILQ_INIT(&sc->sc_queue);
429
430
431 /*
432 * Allocate the Control Blocks.
433 */
434 error = adw_alloc_ccbs(sc);
435 if (error)
436 return; /* (error) */ ;
437
438 /*
439 * Create and initialize the Control Blocks.
440 */
441 i = adw_create_ccbs(sc, sc->sc_control->ccbs, ADW_MAX_CCB);
442 if (i == 0) {
443 printf("%s: unable to create control blocks\n",
444 sc->sc_dev.dv_xname);
445 return; /* (ENOMEM) */ ;
446 } else if (i != ADW_MAX_CCB) {
447 printf("%s: WARNING: only %d of %d control blocks"
448 " created\n",
449 sc->sc_dev.dv_xname, i, ADW_MAX_CCB);
450 }
451 config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
452 }
453
454
455 static void
456 adwminphys(bp)
457 struct buf *bp;
458 {
459
460 if (bp->b_bcount > ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE))
461 bp->b_bcount = ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE);
462 minphys(bp);
463 }
464
465
466 /*
467 * start a scsi operation given the command and the data address.
468 * Also needs the unit, target and lu.
469 */
470 static int
471 adw_scsi_cmd(xs)
472 struct scsipi_xfer *xs;
473 {
474 struct scsipi_link *sc_link = xs->sc_link;
475 ADW_SOFTC *sc = sc_link->adapter_softc;
476 ADW_CCB *ccb;
477 int s, fromqueue = 1, dontqueue = 0;
478
479 s = splbio(); /* protect the queue */
480
481 /*
482 * If we're running the queue from adw_done(), we've been
483 * called with the first queue entry as our argument.
484 */
485 if (xs == TAILQ_FIRST(&sc->sc_queue)) {
486 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
487 fromqueue = 1;
488 } else {
489
490 /* Polled requests can't be queued for later. */
491 dontqueue = xs->flags & SCSI_POLL;
492
493 /*
494 * If there are jobs in the queue, run them first.
495 */
496 if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
497 /*
498 * If we can't queue, we have to abort, since
499 * we have to preserve order.
500 */
501 if (dontqueue) {
502 splx(s);
503 xs->error = XS_DRIVER_STUFFUP;
504 return (TRY_AGAIN_LATER);
505 }
506 /*
507 * Swap with the first queue entry.
508 */
509 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
510 xs = TAILQ_FIRST(&sc->sc_queue);
511 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
512 fromqueue = 1;
513 }
514 }
515
516
517 /*
518 * get a ccb to use. If the transfer
519 * is from a buf (possibly from interrupt time)
520 * then we can't allow it to sleep
521 */
522
523 if ((ccb = adw_get_ccb(sc, xs->flags)) == NULL) {
524 /*
525 * If we can't queue, we lose.
526 */
527 if (dontqueue) {
528 splx(s);
529 xs->error = XS_DRIVER_STUFFUP;
530 return (TRY_AGAIN_LATER);
531 }
532 /*
533 * Stuff ourselves into the queue, in front
534 * if we came off in the first place.
535 */
536 if (fromqueue)
537 TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
538 else
539 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
540 splx(s);
541 return (SUCCESSFULLY_QUEUED);
542 }
543 splx(s); /* done playing with the queue */
544
545 ccb->xs = xs;
546 ccb->timeout = xs->timeout;
547
548 if (adw_build_req(xs, ccb)) {
549 s = splbio();
550 adw_queue_ccb(sc, ccb);
551 splx(s);
552
553 /*
554 * Usually return SUCCESSFULLY QUEUED
555 */
556 if ((xs->flags & SCSI_POLL) == 0)
557 return (SUCCESSFULLY_QUEUED);
558
559 /*
560 * If we can't use interrupts, poll on completion
561 */
562 if (adw_poll(sc, xs, ccb->timeout)) {
563 adw_timeout(ccb);
564 if (adw_poll(sc, xs, ccb->timeout))
565 adw_timeout(ccb);
566 }
567 }
568 return (COMPLETE);
569 }
570
571
572 /*
573 * Build a request structure for the Wide Boards.
574 */
575 static int
576 adw_build_req(xs, ccb)
577 struct scsipi_xfer *xs;
578 ADW_CCB *ccb;
579 {
580 struct scsipi_link *sc_link = xs->sc_link;
581 ADW_SOFTC *sc = sc_link->adapter_softc;
582 bus_dma_tag_t dmat = sc->sc_dmat;
583 ADW_SCSI_REQ_Q *scsiqp;
584 int error;
585
586 scsiqp = &ccb->scsiq;
587 bzero(scsiqp, sizeof(ADW_SCSI_REQ_Q));
588
589 /*
590 * Set the ADW_SCSI_REQ_Q 'ccb_ptr' to point to the CCB structure.
591 */
592 scsiqp->ccb_ptr = (ulong) ccb;
593
594
595 /*
596 * Build the ADW_SCSI_REQ_Q request.
597 */
598
599 /*
600 * Set CDB length and copy it to the request structure.
601 */
602 bcopy(xs->cmd, &scsiqp->cdb, scsiqp->cdb_len = xs->cmdlen);
603
604 scsiqp->target_id = sc_link->scsipi_scsi.target;
605 scsiqp->target_lun = sc_link->scsipi_scsi.lun;
606
607 scsiqp->vsense_addr = (ulong) & ccb->scsi_sense;
608 scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
609 ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense);
610 scsiqp->sense_len = sizeof(struct scsipi_sense_data);
611
612 /*
613 * Build ADW_SCSI_REQ_Q for a scatter-gather buffer command.
614 */
615 if (xs->datalen) {
616 /*
617 * Map the DMA transfer.
618 */
619 #ifdef TFS
620 if (xs->flags & SCSI_DATA_UIO) {
621 error = bus_dmamap_load_uio(dmat,
622 ccb->dmamap_xfer, (struct uio *) xs->data,
623 (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
624 BUS_DMA_WAITOK);
625 } else
626 #endif /* TFS */
627 {
628 error = bus_dmamap_load(dmat,
629 ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
630 (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
631 BUS_DMA_WAITOK);
632 }
633
634 if (error) {
635 if (error == EFBIG) {
636 printf("%s: adw_scsi_cmd, more than %d dma"
637 " segments\n",
638 sc->sc_dev.dv_xname, ADW_MAX_SG_LIST);
639 } else {
640 printf("%s: adw_scsi_cmd, error %d loading"
641 " dma map\n",
642 sc->sc_dev.dv_xname, error);
643 }
644
645 xs->error = XS_DRIVER_STUFFUP;
646 adw_free_ccb(sc, ccb);
647 return (0);
648 }
649 bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
650 ccb->dmamap_xfer->dm_mapsize,
651 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
652 BUS_DMASYNC_PREWRITE);
653
654 /*
655 * Build scatter-gather list.
656 */
657 scsiqp->data_cnt = xs->datalen;
658 scsiqp->vdata_addr = (ulong) xs->data;
659 scsiqp->data_addr = ccb->dmamap_xfer->dm_segs[0].ds_addr;
660 scsiqp->sg_list_ptr = &ccb->sg_block[0];
661 bzero(scsiqp->sg_list_ptr,
662 sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK);
663 adw_build_sglist(ccb, scsiqp);
664 } else {
665 /*
666 * No data xfer, use non S/G values.
667 */
668 scsiqp->data_cnt = 0;
669 scsiqp->vdata_addr = 0;
670 scsiqp->data_addr = 0;
671 scsiqp->sg_list_ptr = NULL;
672 }
673
674 return (1);
675 }
676
677
678 /*
679 * Build scatter-gather list for Wide Boards.
680 */
681 static void
682 adw_build_sglist(ccb, scsiqp)
683 ADW_CCB *ccb;
684 ADW_SCSI_REQ_Q *scsiqp;
685 {
686 struct scsipi_xfer *xs = ccb->xs;
687 ADW_SOFTC *sc = xs->sc_link->adapter_softc;
688 ADW_SG_BLOCK *sg_block = scsiqp->sg_list_ptr;
689 ulong sg_block_next_addr; /* block and its next */
690 ulong sg_block_physical_addr;
691 int sg_block_index, i; /* how many SG entries */
692 bus_dma_segment_t *sg_list = &ccb->dmamap_xfer->dm_segs[0];
693 int sg_elem_cnt = ccb->dmamap_xfer->dm_nsegs;
694
695
696 sg_block_next_addr = (ulong) sg_block; /* allow math operation */
697 sg_block_physical_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
698 ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, sg_block[0]);
699 scsiqp->sg_real_addr = sg_block_physical_addr;
700
701 /*
702 * If there are more than NO_OF_SG_PER_BLOCK dma segments (hw sg-list)
703 * then split the request into multiple sg-list blocks.
704 */
705
706 sg_block_index = 0;
707 do {
708 sg_block->first_entry_no = sg_block_index;
709 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
710 sg_block->sg_list[i].sg_addr = sg_list->ds_addr;
711 sg_block->sg_list[i].sg_count = sg_list->ds_len;
712
713 if (--sg_elem_cnt == 0) {
714 /* last entry, get out */
715 scsiqp->sg_entry_cnt = sg_block_index + i + 1;
716 sg_block->last_entry_no = sg_block_index + i;
717 sg_block->sg_ptr = NULL; /* next link = NULL */
718 return;
719 }
720 sg_list++;
721 }
722 sg_block_next_addr += sizeof(ADW_SG_BLOCK);
723 sg_block_physical_addr += sizeof(ADW_SG_BLOCK);
724
725 sg_block_index += NO_OF_SG_PER_BLOCK;
726 sg_block->sg_ptr = (ADW_SG_BLOCK *) sg_block_physical_addr;
727 sg_block->last_entry_no = sg_block_index - 1;
728 sg_block = (ADW_SG_BLOCK *) sg_block_next_addr; /* virt. addr */
729 }
730 while (1);
731 }
732
733
734 int
735 adw_intr(arg)
736 void *arg;
737 {
738 ADW_SOFTC *sc = arg;
739 struct scsipi_xfer *xs;
740
741
742 AdvISR(sc);
743
744 /*
745 * If there are queue entries in the software queue, try to
746 * run the first one. We should be more or less guaranteed
747 * to succeed, since we just freed a CCB.
748 *
749 * NOTE: adw_scsi_cmd() relies on our calling it with
750 * the first entry in the queue.
751 */
752 if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
753 (void) adw_scsi_cmd(xs);
754
755 return (1);
756 }
757
758
759 /*
760 * Poll a particular unit, looking for a particular xs
761 */
762 static int
763 adw_poll(sc, xs, count)
764 ADW_SOFTC *sc;
765 struct scsipi_xfer *xs;
766 int count;
767 {
768
769 /* timeouts are in msec, so we loop in 1000 usec cycles */
770 while (count) {
771 adw_intr(sc);
772 if (xs->flags & ITSDONE)
773 return (0);
774 delay(1000); /* only happens in boot so ok */
775 count--;
776 }
777 return (1);
778 }
779
780
781 static void
782 adw_timeout(arg)
783 void *arg;
784 {
785 ADW_CCB *ccb = arg;
786 struct scsipi_xfer *xs = ccb->xs;
787 struct scsipi_link *sc_link = xs->sc_link;
788 ADW_SOFTC *sc = sc_link->adapter_softc;
789 int s;
790
791 scsi_print_addr(sc_link);
792 printf("timed out");
793
794 s = splbio();
795
796 /*
797 * If it has been through before, then a previous abort has failed,
798 * don't try abort again, reset the bus instead.
799 */
800 if (ccb->flags & CCB_ABORT) {
801 /* abort timed out */
802 printf(" AGAIN. Resetting Bus\n");
803 /* Lets try resetting the bus! */
804 AdvResetSCSIBus(sc);
805 ccb->timeout = ADW_ABORT_TIMEOUT;
806 adw_queue_ccb(sc, ccb);
807 } else {
808 /* abort the operation that has timed out */
809 printf("\n");
810 ADW_ABORT_CCB(sc, ccb);
811 xs->error = XS_TIMEOUT;
812 ccb->timeout = ADW_ABORT_TIMEOUT;
813 ccb->flags |= CCB_ABORT;
814 adw_queue_ccb(sc, ccb);
815 }
816
817 splx(s);
818 }
819
820
821 static void
822 adw_watchdog(arg)
823 void *arg;
824 {
825 ADW_CCB *ccb = arg;
826 struct scsipi_xfer *xs = ccb->xs;
827 struct scsipi_link *sc_link = xs->sc_link;
828 ADW_SOFTC *sc = sc_link->adapter_softc;
829 int s;
830
831 s = splbio();
832
833 ccb->flags &= ~CCB_WATCHDOG;
834 adw_start_ccbs(sc);
835
836 splx(s);
837 }
838
839
840 /******************************************************************************/
841 /* NARROW and WIDE boards Interrupt callbacks */
842 /******************************************************************************/
843
844
845 /*
846 * adw_wide_isr_callback() - Second Level Interrupt Handler called by AdvISR()
847 *
848 * Interrupt callback function for the Wide SCSI Adv Library.
849 */
850 static void
851 adw_wide_isr_callback(sc, scsiq)
852 ADW_SOFTC *sc;
853 ADW_SCSI_REQ_Q *scsiq;
854 {
855 bus_dma_tag_t dmat = sc->sc_dmat;
856 ADW_CCB *ccb = (ADW_CCB *) scsiq->ccb_ptr;
857 struct scsipi_xfer *xs = ccb->xs;
858 struct scsipi_sense_data *s1, *s2;
859 //int underrun = ASC_FALSE;
860
861
862 untimeout(adw_timeout, ccb);
863
864 /*
865 * If we were a data transfer, unload the map that described
866 * the data buffer.
867 */
868 if (xs->datalen) {
869 bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
870 ccb->dmamap_xfer->dm_mapsize,
871 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
872 BUS_DMASYNC_POSTWRITE);
873 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
874 }
875 if ((ccb->flags & CCB_ALLOC) == 0) {
876 printf("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
877 Debugger();
878 return;
879 }
880 /*
881 * Check for an underrun condition.
882 */
883 /*
884 * if (xs->request_bufflen != 0 && scsiqp->data_cnt != 0) {
885 * ASC_DBG1(1, "adw_isr_callback: underrun condition %lu bytes\n",
886 * scsiqp->data_cnt); underrun = ASC_TRUE; }
887 */
888 /*
889 * 'done_status' contains the command's ending status.
890 */
891 switch (scsiq->done_status) {
892 case QD_NO_ERROR:
893 switch (scsiq->host_status) {
894 case QHSTA_NO_ERROR:
895 xs->error = XS_NOERROR;
896 xs->resid = 0;
897 break;
898 default:
899 /* QHSTA error occurred. */
900 xs->error = XS_DRIVER_STUFFUP;
901 break;
902 }
903 /*
904 * If there was an underrun without any other error,
905 * set DID_ERROR to indicate the underrun error.
906 *
907 * Note: There is no way yet to indicate the number
908 * of underrun bytes.
909 */
910 /*
911 * if (xs->error == XS_NOERROR && underrun == ASC_TRUE) {
912 * scp->result = HOST_BYTE(DID_UNDERRUN); }
913 */ break;
914
915 case QD_WITH_ERROR:
916 switch (scsiq->host_status) {
917 case QHSTA_NO_ERROR:
918 if (scsiq->scsi_status == SS_CHK_CONDITION) {
919 s1 = &ccb->scsi_sense;
920 s2 = &xs->sense.scsi_sense;
921 *s2 = *s1;
922 xs->error = XS_SENSE;
923 } else {
924 xs->error = XS_DRIVER_STUFFUP;
925 }
926 break;
927
928 default:
929 /* Some other QHSTA error occurred. */
930 xs->error = XS_DRIVER_STUFFUP;
931 break;
932 }
933 break;
934
935 case QD_ABORTED_BY_HOST:
936 default:
937 xs->error = XS_DRIVER_STUFFUP;
938 break;
939 }
940
941
942 adw_free_ccb(sc, ccb);
943 xs->flags |= ITSDONE;
944 scsipi_done(xs);
945 }
946