As with cac(4). You can test now or can break later. .... Ken
Index: ic/gdt_common.c =================================================================== RCS file: /cvs/src/sys/dev/ic/gdt_common.c,v retrieving revision 1.55 diff -u -p -r1.55 gdt_common.c --- ic/gdt_common.c 12 Oct 2010 00:53:32 -0000 1.55 +++ ic/gdt_common.c 13 Oct 2010 11:09:09 -0000 @@ -61,16 +61,12 @@ int gdt_maxcmds = GDT_MAXCMDS; #define GDT_DRIVER_SUBVERSION 2 int gdt_async_event(struct gdt_softc *, int); -void gdt_chain(struct gdt_softc *); void gdt_clear_events(struct gdt_softc *); void gdt_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t); -struct scsi_xfer *gdt_dequeue(struct gdt_softc *); -void gdt_enqueue(struct gdt_softc *, struct scsi_xfer *, int); -void gdt_enqueue_ccb(struct gdt_softc *, struct gdt_ccb *); void gdt_eval_mapping(u_int32_t, int *, int *, int *); int gdt_exec_ccb(struct gdt_ccb *); -void gdt_free_ccb(struct gdt_softc *, struct gdt_ccb *); -struct gdt_ccb *gdt_get_ccb(struct gdt_softc *, int); +void gdt_ccb_free(void *, void *); +void *gdt_ccb_alloc(void *); void gdt_internal_cache_cmd(struct scsi_xfer *); int gdt_internal_cmd(struct gdt_softc *, u_int8_t, u_int16_t, u_int32_t, u_int32_t, u_int32_t); @@ -82,9 +78,7 @@ int gdt_ioctl_disk(struct gdt_softc *, s int gdt_ioctl_alarm(struct gdt_softc *, struct bioc_alarm *); int gdt_ioctl_setstate(struct gdt_softc *, struct bioc_setstate *); #endif /* NBIO > 0 */ -void gdt_raw_scsi_cmd(struct scsi_xfer *); void gdt_scsi_cmd(struct scsi_xfer *); -void gdt_start_ccbs(struct gdt_softc *); int gdt_sync_event(struct gdt_softc *, int, u_int8_t, struct scsi_xfer *); void gdt_timeout(void *); @@ -99,10 +93,6 @@ struct scsi_adapter gdt_switch = { gdt_scsi_cmd, gdtminphys, 0, 0, }; -struct scsi_adapter gdt_raw_switch = { - gdt_raw_scsi_cmd, gdtminphys, 0, 0, -}; - int gdt_cnt = 0; u_int8_t gdt_polling; u_int8_t gdt_from_wait; @@ -132,9 +122,8 @@ gdt_attach(struct gdt_softc *sc) gdt_clear_events(sc); TAILQ_INIT(&sc->sc_free_ccb); - TAILQ_INIT(&sc->sc_ccbq); - TAILQ_INIT(&sc->sc_ucmdq); - LIST_INIT(&sc->sc_queue); + mtx_init(&sc->sc_ccb_mtx, IPL_BIO); + scsi_iopool_init(&sc->sc_iopool, sc, gdt_ccb_alloc, gdt_ccb_free); /* Initialize the ccbs */ for (i = 0; i < GDT_MAXCMDS; i++) { @@ -484,26 +473,6 @@ gdt_attach(struct gdt_softc *sc) config_found(&sc->sc_dev, &saa, scsiprint); - sc->sc_raw_link = malloc(sc->sc_bus_cnt * sizeof (struct scsi_link), - M_DEVBUF, M_NOWAIT | M_ZERO); - if (sc->sc_raw_link == NULL) - panic("gdt_attach"); - - for (i = 0; i < sc->sc_bus_cnt; i++) { - /* Fill in the prototype scsi_link. */ - sc->sc_raw_link[i].adapter_softc = sc; - sc->sc_raw_link[i].adapter = &gdt_raw_switch; - sc->sc_raw_link[i].adapter_target = 7; - sc->sc_raw_link[i].openings = 4; /* XXX a guess */ - sc->sc_raw_link[i].adapter_buswidth = - (sc->sc_class & GDT_FC) ? GDT_MAXID : 16; /* XXX */ - - bzero(&saa, sizeof(saa)); - saa.saa_sc_link = &sc->sc_raw_link[i]; - - config_found(&sc->sc_dev, &saa, scsiprint); - } - gdt_polling = 0; return (0); } @@ -531,43 +500,6 @@ gdt_eval_mapping(u_int32_t size, int *cy } /* - * Insert a command into the driver queue, either at the front or at the tail. - * It's ok to overload the freelist link as these structures are never on - * the freelist at this time. - */ -void -gdt_enqueue(struct gdt_softc *sc, struct scsi_xfer *xs, int infront) -{ - if (infront || LIST_FIRST(&sc->sc_queue) == NULL) { - if (LIST_FIRST(&sc->sc_queue) == NULL) - sc->sc_queuelast = xs; - LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list); - return; - } - LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list); - sc->sc_queuelast = xs; -} - -/* - * Pull a command off the front of the driver queue. - */ -struct scsi_xfer * -gdt_dequeue(struct gdt_softc *sc) -{ - struct scsi_xfer *xs; - - xs = LIST_FIRST(&sc->sc_queue); - if (xs == NULL) - return (NULL); - LIST_REMOVE(xs, free_list); - - if (LIST_FIRST(&sc->sc_queue) == NULL) - sc->sc_queuelast = NULL; - - return (xs); -} - -/* * Start a SCSI operation on a cache device. * XXX Polled operation is not yet complete. What kind of locking do we need? */ @@ -576,18 +508,13 @@ gdt_scsi_cmd(struct scsi_xfer *xs) { struct scsi_link *link = xs->sc_link; struct gdt_softc *sc = link->adapter_softc; - u_int8_t target = link->target; struct gdt_ccb *ccb; -#if 0 - struct gdt_ucmd *ucmd; -#endif - u_int32_t blockno, blockcnt; struct scsi_rw *rw; struct scsi_rw_big *rwb; bus_dmamap_t xfer; - int error; - int s; - int polled; + u_int32_t blockno, blockcnt; + int error, s, polled; + u_int8_t target = link->target; GDT_DPRINTF(GDT_D_CMD, ("gdt_scsi_cmd ")); @@ -607,169 +534,139 @@ gdt_scsi_cmd(struct scsi_xfer *xs) return; } - /* Don't double enqueue if we came from gdt_chain. */ - if (xs != LIST_FIRST(&sc->sc_queue)) - gdt_enqueue(sc, xs, 0); + xs->error = XS_NOERROR; + ccb = xs->io; + link = xs->sc_link; + target = link->target; + polled = ISSET(xs->flags, SCSI_POLL); - while ((xs = gdt_dequeue(sc)) != NULL) { - xs->error = XS_NOERROR; - ccb = NULL; - link = xs->sc_link; - target = link->target; - polled = ISSET(xs->flags, SCSI_POLL); - - if (!gdt_polling && !(xs->flags & SCSI_POLL) && - sc->sc_test_busy(sc)) { - /* - * Put it back in front. XXX Should we instead - * set xs->error to XS_BUSY? - */ - gdt_enqueue(sc, xs, 1); - break; - } + if (!gdt_polling && !polled && sc->sc_test_busy(sc)) { + splx(s); + xs->error = XS_BUSY; + scsi_done(xs); + return; + } - switch (xs->cmd->opcode) { - case TEST_UNIT_READY: - case REQUEST_SENSE: - case INQUIRY: - case MODE_SENSE: - case START_STOP: - case READ_CAPACITY: -#if 0 - case VERIFY: -#endif - gdt_internal_cache_cmd(xs); - scsi_done(xs); - goto ready; + switch (xs->cmd->opcode) { + case TEST_UNIT_READY: + case REQUEST_SENSE: + case INQUIRY: + case MODE_SENSE: + case START_STOP: + case READ_CAPACITY: + gdt_internal_cache_cmd(xs); + scsi_done(xs); + break; - case PREVENT_ALLOW: - GDT_DPRINTF(GDT_D_CMD, ("PREVENT/ALLOW ")); - /* XXX Not yet implemented */ - xs->error = XS_NOERROR; - scsi_done(xs); - goto ready; + case PREVENT_ALLOW: + GDT_DPRINTF(GDT_D_CMD, ("PREVENT/ALLOW ")); + /* XXX Not yet implemented */ + xs->error = XS_NOERROR; + scsi_done(xs); + break; - default: - GDT_DPRINTF(GDT_D_CMD, - ("unknown opc %d ", xs->cmd->opcode)); - /* XXX Not yet implemented */ - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - goto ready; + default: + GDT_DPRINTF(GDT_D_CMD, + ("unknown opc %d ", xs->cmd->opcode)); + /* XXX Not yet implemented */ + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + break; - case READ_COMMAND: - case READ_BIG: - case WRITE_COMMAND: - case WRITE_BIG: - case SYNCHRONIZE_CACHE: - /* - * A new command chain, start from the beginning. - */ - sc->sc_cmd_off = 0; + case READ_COMMAND: + case READ_BIG: + case WRITE_COMMAND: + case WRITE_BIG: + case SYNCHRONIZE_CACHE: + /* + * A new command chain, start from the beginning. + */ + sc->sc_cmd_off = 0; - if (xs->cmd->opcode == SYNCHRONIZE_CACHE) { - blockno = blockcnt = 0; + if (xs->cmd->opcode == SYNCHRONIZE_CACHE) { + blockno = blockcnt = 0; + } else { + /* A read or write operation. */ + if (xs->cmdlen == 6) { + rw = (struct scsi_rw *)xs->cmd; + blockno = _3btol(rw->addr) & + (SRW_TOPADDR << 16 | 0xffff); + blockcnt = + rw->length ? rw->length : 0x100; } else { - /* A read or write operation. */ - if (xs->cmdlen == 6) { - rw = (struct scsi_rw *)xs->cmd; - blockno = _3btol(rw->addr) & - (SRW_TOPADDR << 16 | 0xffff); - blockcnt = - rw->length ? rw->length : 0x100; - } else { - rwb = (struct scsi_rw_big *)xs->cmd; - blockno = _4btol(rwb->addr); - blockcnt = _2btol(rwb->length); - } - if (blockno >= sc->sc_hdr[target].hd_size || - blockno + blockcnt > - sc->sc_hdr[target].hd_size) { - printf( - "%s: out of bounds %u-%u >= %u\n", - DEVNAME(sc), blockno, - blockcnt, - sc->sc_hdr[target].hd_size); - /* - * XXX Should be XS_SENSE but that - * would require setting up a faked - * sense too. - */ - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - goto ready; - } + rwb = (struct scsi_rw_big *)xs->cmd; + blockno = _4btol(rwb->addr); + blockcnt = _2btol(rwb->length); } - - ccb = gdt_get_ccb(sc, xs->flags); - /* - * We are out of commands, try again in a little while. - */ - if (ccb == NULL) { - xs->error = XS_NO_CCB; + if (blockno >= sc->sc_hdr[target].hd_size || + blockno + blockcnt > + sc->sc_hdr[target].hd_size) { + printf( + "%s: out of bounds %u-%u >= %u\n", + DEVNAME(sc), blockno, + blockcnt, + sc->sc_hdr[target].hd_size); + /* + * XXX Should be XS_SENSE but that + * would require setting up a faked + * sense too. + */ + xs->error = XS_DRIVER_STUFFUP; scsi_done(xs); - splx(s); - return; + break; } + } - ccb->gc_blockno = blockno; - ccb->gc_blockcnt = blockcnt; - ccb->gc_xs = xs; - ccb->gc_timeout = xs->timeout; - ccb->gc_service = GDT_CACHESERVICE; - gdt_ccb_set_cmd(ccb, GDT_GCF_SCSI); - - if (xs->cmd->opcode != SYNCHRONIZE_CACHE) { - xfer = ccb->gc_dmamap_xfer; - error = bus_dmamap_load(sc->sc_dmat, xfer, - xs->data, xs->datalen, NULL, - (xs->flags & SCSI_NOSLEEP) ? - BUS_DMA_NOWAIT : BUS_DMA_WAITOK); - if (error) { - printf("%s: gdt_scsi_cmd: ", - DEVNAME(sc)); - if (error == EFBIG) - printf( - "more than %d dma segs\n", - GDT_MAXOFFSETS); - else - printf("error %d " - "loading dma map\n", - error); - - gdt_free_ccb(sc, ccb); - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - goto ready; - } - bus_dmamap_sync(sc->sc_dmat, xfer, 0, - xfer->dm_mapsize, - (xs->flags & SCSI_DATA_IN) ? - BUS_DMASYNC_PREREAD : - BUS_DMASYNC_PREWRITE); - } + ccb = xs->io; - gdt_enqueue_ccb(sc, ccb); - /* XXX what if enqueue did not start a transfer? */ - if (gdt_polling || (xs->flags & SCSI_POLL)) { - if (!gdt_wait(sc, ccb, ccb->gc_timeout)) { - printf("%s: command %d timed out\n", - DEVNAME(sc), - ccb->gc_cmd_index); - xs->error = XS_NO_CCB; - scsi_done(xs); - splx(s); - return; - } + ccb->gc_blockno = blockno; + ccb->gc_blockcnt = blockcnt; + ccb->gc_xs = xs; + ccb->gc_timeout = xs->timeout; + ccb->gc_service = GDT_CACHESERVICE; + gdt_ccb_set_cmd(ccb, GDT_GCF_SCSI); + + if (xs->cmd->opcode != SYNCHRONIZE_CACHE) { + xfer = ccb->gc_dmamap_xfer; + error = bus_dmamap_load(sc->sc_dmat, xfer, + xs->data, xs->datalen, NULL, + (xs->flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK); + if (error) { + printf("%s: gdt_scsi_cmd: ", + DEVNAME(sc)); + if (error == EFBIG) + printf( + "more than %d dma segs\n", + GDT_MAXOFFSETS); + else + printf("error %d " + "loading dma map\n", + error); + + xs->error = XS_DRIVER_STUFFUP; + scsi_done(xs); + break; } + bus_dmamap_sync(sc->sc_dmat, xfer, 0, + xfer->dm_mapsize, + (xs->flags & SCSI_DATA_IN) ? + BUS_DMASYNC_PREREAD : + BUS_DMASYNC_PREWRITE); } - ready: - /* - * Don't process the queue if we are polling. - */ - if (polled) { - break; + gdt_exec_ccb(ccb); + + /* XXX what if enqueue did not start a transfer? */ + if (gdt_polling || (xs->flags & SCSI_POLL)) { + if (!gdt_wait(sc, ccb, ccb->gc_timeout)) { + printf("%s: command %d timed out\n", + DEVNAME(sc), + ccb->gc_cmd_index); + xs->error = XS_BUSY; + scsi_done(xs); + break; + } } } @@ -787,12 +684,11 @@ gdt_exec_ccb(struct gdt_ccb *ccb) u_int32_t sg_canz; bus_dmamap_t xfer; int i; -#if 1 /* XXX */ static int __level = 0; if (__level++ > 0) panic("level > 0"); -#endif + GDT_DPRINTF(GDT_D_CMD, ("gdt_exec_ccb(%p, %p) ", xs, ccb)); sc->sc_cmd_cnt = 0; @@ -884,11 +780,9 @@ gdt_exec_ccb(struct gdt_ccb *ccb) sc->sc_cmd_off + sc->sc_cmd_len + GDT_DPMEM_COMMAND_OFFSET > sc->sc_ic_all_size) { printf("%s: DPMEM overflow\n", DEVNAME(sc)); - gdt_free_ccb(sc, ccb); xs->error = XS_BUSY; -#if 1 /* XXX */ + scsi_done(xs); __level--; -#endif return (0); } @@ -897,9 +791,7 @@ gdt_exec_ccb(struct gdt_ccb *ccb) xs->error = XS_NOERROR; xs->resid = 0; -#if 1 /* XXX */ __level--; -#endif return (1); } @@ -989,43 +881,6 @@ gdt_internal_cache_cmd(struct scsi_xfer xs->error = XS_NOERROR; } -/* Start a raw SCSI operation */ -void -gdt_raw_scsi_cmd(struct scsi_xfer *xs) -{ - struct scsi_link *link = xs->sc_link; - struct gdt_softc *sc = link->adapter_softc; - struct gdt_ccb *ccb; - int s; - - GDT_DPRINTF(GDT_D_CMD, ("gdt_raw_scsi_cmd ")); - - if (xs->cmdlen > 12 /* XXX create #define */) { - GDT_DPRINTF(GDT_D_CMD, ("CDB too big %p ", xs)); - bzero(&xs->sense, sizeof(xs->sense)); - xs->sense.error_code = SSD_ERRCODE_VALID | SSD_ERRCODE_CURRENT; - xs->sense.flags = SKEY_ILLEGAL_REQUEST; - xs->sense.add_sense_code = 0x20; /* illcmd, 0x24 illfield */ - xs->error = XS_SENSE; - scsi_done(xs); - return; - } - - if ((ccb = gdt_get_ccb(sc, xs->flags)) == NULL) { - GDT_DPRINTF(GDT_D_CMD, ("no ccb available for %p ", xs)); - xs->error = XS_DRIVER_STUFFUP; - scsi_done(xs); - return; - } - - xs->error = XS_DRIVER_STUFFUP; - s = splbio(); - scsi_done(xs); - gdt_free_ccb(sc, ccb); - - splx(s); -} - void gdt_clear_events(struct gdt_softc *sc) { @@ -1085,7 +940,6 @@ gdt_intr(void *arg) { struct gdt_softc *sc = arg; struct gdt_intr_ctx ctx; - int chain = 1; int sync_val = 0; struct scsi_xfer *xs = NULL; int prev_cmd; @@ -1125,7 +979,6 @@ gdt_intr(void *arg) case GDT_SPEZINDEX: printf("%s: uninitialized or unknown service (%d %d)\n", DEVNAME(sc), ctx.info, ctx.info2); - chain = 0; goto finish; } @@ -1143,14 +996,11 @@ gdt_intr(void *arg) BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, ccb->gc_dmamap_xfer); } - gdt_free_ccb(sc, ccb); switch (prev_cmd) { case GDT_GCF_UNUSED: /* XXX Not yet implemented */ - chain = 0; goto finish; case GDT_GCF_INTERNAL: - chain = 0; goto finish; } @@ -1167,12 +1017,9 @@ gdt_intr(void *arg) break; case 2: - gdt_enqueue(sc, xs, 0); + break; } - if (chain) - gdt_chain(sc); - return (1); } @@ -1221,16 +1068,16 @@ int gdt_internal_cmd(struct gdt_softc *sc, u_int8_t service, u_int16_t opcode, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) { - int retries; struct gdt_ccb *ccb; + int retries, rslt; GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cmd(%p, %d, %d, %d, %d, %d) ", sc, service, opcode, arg1, arg2, arg3)); bzero(sc->sc_cmd, GDT_CMD_SZ); - for (retries = GDT_RETRIES; ; ) { - ccb = gdt_get_ccb(sc, SCSI_NOSLEEP); + for (retries = GDT_RETRIES; retries > 0; retries--) { + ccb = scsi_io_get(&sc->sc_iopool, SCSI_NOSLEEP); if (ccb == NULL) { printf("%s: no free command index found\n", DEVNAME(sc)); @@ -1282,7 +1129,12 @@ gdt_internal_cmd(struct gdt_softc *sc, u sc->sc_copy_cmd(sc, ccb); sc->sc_release_event(sc, ccb); DELAY(20); - if (!gdt_wait(sc, ccb, GDT_POLL_TIMEOUT)) + + gdt_exec_ccb(ccb); + rslt = gdt_wait(sc, ccb, GDT_POLL_TIMEOUT); + + scsi_io_put(&sc->sc_iopool, ccb); + if (rslt == 0) return (0); if (sc->sc_status != GDT_S_BSY || --retries == 0) break; @@ -1291,96 +1143,34 @@ gdt_internal_cmd(struct gdt_softc *sc, u return (sc->sc_status == GDT_S_OK); } -struct gdt_ccb * -gdt_get_ccb(struct gdt_softc *sc, int flags) +void * +gdt_ccb_alloc(void *xsc) { + struct gdt_softc *sc = xsc; struct gdt_ccb *ccb; - int s; - - GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p, 0x%x) ", sc, flags)); - - s = splbio(); - for (;;) { - ccb = TAILQ_FIRST(&sc->sc_free_ccb); - if (ccb != NULL) - break; - if (flags & SCSI_NOSLEEP) - goto bail_out; - tsleep(&sc->sc_free_ccb, PRIBIO, "gdt_ccb", 0); - } + GDT_DPRINTF(GDT_D_QUEUE, ("gdt_ccb_alloc(%p, 0x%x) ", sc, flags)); - TAILQ_REMOVE(&sc->sc_free_ccb, ccb, gc_chain); + mtx_enter(&sc->sc_ccb_mtx); + ccb = TAILQ_FIRST(&sc->sc_free_ccb); + if (ccb != NULL) + TAILQ_REMOVE(&sc->sc_free_ccb, ccb, gc_chain); + mtx_leave(&sc->sc_ccb_mtx); - bail_out: - splx(s); return (ccb); } void -gdt_free_ccb(struct gdt_softc *sc, struct gdt_ccb *ccb) +gdt_ccb_free(void *xsc, void *xccb) { - int s; + struct gdt_softc *sc = xsc; + struct gdt_ccb *ccb = xccb; GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p) ", sc, ccb)); - s = splbio(); - + mtx_enter(&sc->sc_ccb_mtx); TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, gc_chain); - - /* If the free list was empty, wake up potential waiters. */ - if (TAILQ_NEXT(ccb, gc_chain) == NULL) - wakeup(&sc->sc_free_ccb); - - splx(s); -} - -void -gdt_enqueue_ccb(struct gdt_softc *sc, struct gdt_ccb *ccb) -{ - GDT_DPRINTF(GDT_D_QUEUE, ("gdt_enqueue_ccb(%p, %p) ", sc, ccb)); - - timeout_set(&ccb->gc_xs->stimeout, gdt_timeout, ccb); - TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, gc_chain); - gdt_start_ccbs(sc); -} - -void -gdt_start_ccbs(struct gdt_softc *sc) -{ - struct gdt_ccb *ccb; - struct scsi_xfer *xs; - - GDT_DPRINTF(GDT_D_QUEUE, ("gdt_start_ccbs(%p) ", sc)); - - while ((ccb = TAILQ_FIRST(&sc->sc_ccbq)) != NULL) { - - xs = ccb->gc_xs; - if (ccb->gc_flags & GDT_GCF_WATCHDOG) - timeout_del(&xs->stimeout); - - if (gdt_exec_ccb(ccb) == 0) { - ccb->gc_flags |= GDT_GCF_WATCHDOG; - timeout_set(&ccb->gc_xs->stimeout, gdt_watchdog, ccb); - timeout_add_msec(&xs->stimeout, GDT_WATCH_TIMEOUT); - break; - } - TAILQ_REMOVE(&sc->sc_ccbq, ccb, gc_chain); - - if ((xs->flags & SCSI_POLL) == 0) { - timeout_set(&ccb->gc_xs->stimeout, gdt_timeout, ccb); - timeout_add_msec(&xs->stimeout, ccb->gc_timeout); - } - } -} - -void -gdt_chain(struct gdt_softc *sc) -{ - GDT_DPRINTF(GDT_D_INTR, ("gdt_chain(%p) ", sc)); - - if (LIST_FIRST(&sc->sc_queue)) - gdt_scsi_cmd(LIST_FIRST(&sc->sc_queue)); + mtx_leave(&sc->sc_ccb_mtx); } void @@ -1388,8 +1178,6 @@ gdt_timeout(void *arg) { struct gdt_ccb *ccb = arg; struct scsi_link *link = ccb->gc_xs->sc_link; - struct gdt_softc *sc = link->adapter_softc; - int s; sc_print_addr(link); printf("timed out\n"); @@ -1397,22 +1185,17 @@ gdt_timeout(void *arg) /* XXX Test for multiple timeouts */ ccb->gc_xs->error = XS_TIMEOUT; - s = splbio(); - gdt_enqueue_ccb(sc, ccb); - splx(s); + scsi_done(ccb->gc_xs); } void gdt_watchdog(void *arg) { struct gdt_ccb *ccb = arg; - struct scsi_link *link = ccb->gc_xs->sc_link; - struct gdt_softc *sc = link->adapter_softc; int s; s = splbio(); ccb->gc_flags &= ~GDT_GCF_WATCHDOG; - gdt_start_ccbs(sc); splx(s); } @@ -1514,10 +1297,8 @@ gdt_ioctl(struct device *dev, u_long cmd ucmd = (gdt_ucmd_t *)addr; s = splbio(); - TAILQ_INSERT_TAIL(&sc->sc_ucmdq, ucmd, links); ucmd->complete_flag = FALSE; splx(s); - gdt_chain(sc); if (!ucmd->complete_flag) (void)tsleep((void *)ucmd, PCATCH | PRIBIO, "gdtucw", 0); Index: ic/gdtvar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/gdtvar.h,v retrieving revision 1.17 diff -u -p -r1.17 gdtvar.h --- ic/gdtvar.h 12 Aug 2009 17:51:33 -0000 1.17 +++ ic/gdtvar.h 27 Sep 2010 09:32:51 -0000 @@ -85,7 +85,6 @@ typedef struct gdt_ucmd { } u; u_int8_t data[GDT_SCRATCH_SZ]; int complete_flag; - TAILQ_ENTRY(gdt_ucmd) links; } gdt_ucmd_t; #define GDT_IOCTL_DRVERS _IOWR('B', 34, int) /* get driver version */ @@ -293,10 +292,10 @@ struct gdt_softc { u_int16_t sc_ic_all_size; struct gdt_ccb sc_ccbs[GDT_MAXCMDS]; - TAILQ_HEAD(, gdt_ccb) sc_free_ccb, sc_ccbq; - TAILQ_HEAD(, gdt_ucmd) sc_ucmdq; - LIST_HEAD(, scsi_xfer) sc_queue; - struct scsi_xfer *sc_queuelast; + TAILQ_HEAD(, gdt_ccb) sc_free_ccb; + + struct mutex sc_ccb_mtx; + struct scsi_iopool sc_iopool; int sc_ndevs;