From acd87a7687dd2f8f50e505be84b4e168a2a72953 Mon Sep 17 00:00:00 2001 From: tsutsui Date: Sun, 18 Nov 2001 13:02:30 +0000 Subject: [PATCH] Misc cleanups: - correct trm_clock_period[] value - pass BUS_DMA_{READ,WRITE,STREAMING} to bus_dmamap_load() as appropriate - make sure to call bus_dmamap_unload() even after request sense - saved srb params on request sense do not seem to be used, so remove them from struct trm_srb - handle target status more properly in trm_srb_done() and no need to handle error retry in lower driver layer - fix some comments XXX Maybe need more cleanup around TQING for MI SCSI callback.. --- sys/dev/pci/trm.c | 253 ++++++++++++++++------------------------------ 1 file changed, 88 insertions(+), 165 deletions(-) diff --git a/sys/dev/pci/trm.c b/sys/dev/pci/trm.c index 59f3ec79599c..6f980478bd1e 100644 --- a/sys/dev/pci/trm.c +++ b/sys/dev/pci/trm.c @@ -1,4 +1,4 @@ -/* $NetBSD: trm.c,v 1.4 2001/11/13 07:48:49 lukem Exp $ */ +/* $NetBSD: trm.c,v 1.5 2001/11/18 13:02:30 tsutsui Exp $ */ /* * Device Driver for Tekram DC395U/UW/F, DC315/U * PCI SCSI Bus Master Host Adapter @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: trm.c,v 1.4 2001/11/13 07:48:49 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trm.c,v 1.5 2001/11/18 13:02:30 tsutsui Exp $"); /* #define TRM_DEBUG */ @@ -96,7 +96,7 @@ struct nvram_target { #define NTC_DO_SEND_START 0x08 /* Send start command SPINUP */ #define NTC_DO_DISCONNECT 0x04 /* Enable SCSI disconnect */ #define NTC_DO_SYNC_NEGO 0x02 /* Sync negotiation */ -#define NTC_DO_PARITY_CHK 0x01 /* (it should define at NAC) Parity check enable */ +#define NTC_DO_PARITY_CHK 0x01 /* Parity check enable */ u_int8_t period; /* Target period */ u_int8_t config2; /* Target configuration byte 2 */ u_int8_t config3; /* Target configuration byte 3 */ @@ -153,16 +153,11 @@ struct trm_srb { struct trm_dcb *dcb; struct trm_sg_entry *sgentry; - struct trm_sg_entry tempsg; /* Temp sgentry when Request Sense */ - /* - * the scsipi_xfer for this cmd - */ - struct scsipi_xfer *xs; + struct scsipi_xfer *xs; /* scsipi_xfer for this cmd */ bus_dmamap_t dmap; bus_size_t sgoffset; /* Xfer buf offset */ u_int32_t buflen; /* Total xfer length */ - u_int32_t templen; /* Temp buflen when Request Sense */ u_int32_t sgaddr; /* SGList physical starting address */ u_int state; /* SRB State */ @@ -218,12 +213,10 @@ struct trm_srb { #define PARITY_ERROR 0x10 #define SRB_ERROR 0x20 int tagnum; /* Tag number */ - int retry; /* Retry Count */ int msgcnt; int cmdlen; /* SCSI command length */ u_int8_t cmd[12]; /* SCSI command */ - u_int8_t tempcmd[6]; /* Temp cmd when Request Sense */ u_int8_t msgin[6]; u_int8_t msgout[6]; @@ -270,7 +263,6 @@ struct trm_dcb { u_int8_t flag; #define ABORT_DEV_ 0x01 #define SHOW_MESSAGE_ 0x02 - u_int8_t type; /* Device Type */ }; /* @@ -372,7 +364,7 @@ static void trm_srb_done(struct trm_softc *, struct trm_dcb *, static void trm_doing_srb_done(struct trm_softc *); static void trm_scsi_reset_detect(struct trm_softc *); static void trm_reset_scsi_bus(struct trm_softc *); -static void trm_request_sense(struct trm_softc *, struct trm_dcb *, +static int trm_request_sense(struct trm_softc *, struct trm_dcb *, struct trm_srb *); static void trm_msgout_abort(struct trm_softc *, struct trm_srb *); static void trm_timeout(void *); @@ -434,7 +426,7 @@ static void *trm_scsi_phase1[] = { /* real period: */ static const u_int8_t trm_clock_period[] = { - 13, /* 52 ns 20.0 MB/sec */ + 12, /* 48 ns 20.0 MB/sec */ 18, /* 72 ns 13.3 MB/sec */ 25, /* 100 ns 10.0 MB/sec */ 31, /* 124 ns 8.0 MB/sec */ @@ -708,7 +700,7 @@ trm_scsipi_request(chan, req, arg) * Request Block for SCSI processor command doing. */ memcpy(srb->cmd, xs->cmd, xs->cmdlen); - if (xs->datalen > 0) { + if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { #ifdef TRM_DEBUG printf("xs->datalen...\n"); printf("sc->sc_dmat=%x\n", (int) sc->sc_dmat); @@ -718,8 +710,11 @@ trm_scsipi_request(chan, req, arg) #endif if ((error = bus_dmamap_load(sc->sc_dmat, srb->dmap, xs->data, xs->datalen, NULL, - (xs->xs_control & XS_CTL_NOSLEEP) ? - BUS_DMA_NOWAIT : BUS_DMA_WAITOK)) != 0) { + ((xs->xs_control & XS_CTL_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | + BUS_DMA_STREAMING | + ((xs->xs_control & XS_CTL_DATA_IN) ? + BUS_DMA_READ : BUS_DMA_WRITE))) != 0) { printf("%s: DMA transfer map unable to load, " "error = %d\n", sc->sc_dev.dv_xname, error); xs->error = XS_DRIVER_STUFFUP; @@ -754,11 +749,6 @@ trm_scsipi_request(chan, req, arg) bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, srb->sgoffset, TRM_SG_SIZE, BUS_DMASYNC_PREWRITE); - if (dcb->type != T_SEQUENTIAL) - srb->retry = 1; - else - srb->retry = 0; - srb->sgindex = 0; srb->hastat = 0; srb->tastat = 0; @@ -968,8 +958,7 @@ trm_start_scsi(sc, dcb, srb) idmsg = dcb->idmsg; if ((srb->cmd[0] == INQUIRY) || - (srb->cmd[0] == REQUEST_SENSE) || - (srb->flag & AUTO_REQSENSE)) { + (srb->cmd[0] == REQUEST_SENSE)) { if (((dcb->mode & WIDE_NEGO_ENABLE) && (dcb->mode & WIDE_NEGO_DONE) == 0) || ((dcb->mode & SYNC_NEGO_ENABLE) && @@ -1015,18 +1004,7 @@ polling: /* * Send CDB ..command block... */ - if (srb->flag & AUTO_REQSENSE) { - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, REQUEST_SENSE); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, - dcb->idmsg << SCSI_CMD_LUN_SHIFT); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 0); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 0); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, - sizeof(struct scsipi_sense_data)); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 0); - } else - bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, - srb->cmd, srb->cmdlen); + bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, srb->cmd, srb->cmdlen); if (bus_space_read_2(iot, ioh, TRM_SCSI_STATUS) & SCSIINTERRUPT) { /* @@ -1182,8 +1160,7 @@ trm_msgout_phase1(sc, srb, pstat) srb->state = SRB_ABORT_SENT; } else { if ((srb->cmd[0] == INQUIRY) || - (srb->cmd[0] == REQUEST_SENSE) || - (srb->flag & AUTO_REQSENSE)) + (srb->cmd[0] == REQUEST_SENSE)) if (dcb->mode & SYNC_NEGO_ENABLE) goto mop1; @@ -1270,24 +1247,9 @@ trm_command_phase1(sc, srb, pstat) { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - struct trm_dcb *dcb; bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRATN | DO_CLRFIFO); - if (srb->flag & AUTO_REQSENSE) { - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, REQUEST_SENSE); - dcb = sc->sc_actdcb; - /* target id */ - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, - dcb->idmsg << SCSI_CMD_LUN_SHIFT); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 0); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 0); - /* sizeof(struct scsi_sense_data) */ - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, - sizeof(struct scsipi_sense_data)); - bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 0); - } else - bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, - srb->cmd, srb->cmdlen); + bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, srb->cmd, srb->cmdlen); srb->state = SRB_COMMAND; /* it's important for atn stop */ @@ -2196,99 +2158,36 @@ trm_srb_done(sc, dcb, srb) struct scsipi_xfer *xs = srb->xs; struct scsipi_inquiry_data *ptr; struct trm_dcb *tempdcb; - int i, j, id, lun, s, tastat; + int i, j, id, lun, s; u_int8_t bval; #ifdef TRM_DEBUG printf("trm_srb_done..................\n"); #endif - if ((xs->xs_control & XS_CTL_POLL) == 0) - callout_stop(&xs->xs_callout); if (xs == NULL) return; - /* - * target status - */ - tastat = srb->tastat; + if ((xs->xs_control & XS_CTL_POLL) == 0) + callout_stop(&xs->xs_callout); - if (srb->flag & AUTO_REQSENSE) { - /* - * status of auto request sense - */ - srb->flag &= ~AUTO_REQSENSE; - srb->hastat = 0; - srb->tastat = SCSI_CHECK; - if (tastat == SCSI_CHECK) { - xs->error = XS_TIMEOUT; - goto ckc_e; - } - memcpy(srb->cmd, srb->tempcmd, sizeof(srb->tempcmd)); - - srb->buflen = srb->templen; - srb->sgentry[0].address = srb->tempsg.address; - srb->sgentry[0].length = srb->tempsg.length; - bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, srb->sgoffset, - TRM_SG_SIZE, BUS_DMASYNC_PREWRITE); - xs->status = SCSI_CHECK; - goto ckc_e; + if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT) || + srb->flag & AUTO_REQSENSE) { + bus_dmamap_sync(sc->sc_dmat, srb->dmap, 0, + srb->dmap->dm_mapsize, + ((xs->xs_control & XS_CTL_DATA_IN) || + (srb->flag & AUTO_REQSENSE)) ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, srb->dmap); } + /* * target status */ - if (tastat) - switch (tastat) { - case SCSI_CHECK: - trm_request_sense(sc, dcb, srb); - return; - case SCSI_QUEUE_FULL: - dcb->maxcmd = dcb->gosrb_cnt - 1; - trm_rewait_srb(dcb, srb); - srb->hastat = 0; - srb->tastat = 0; - goto ckc_e; - case SCSI_SEL_TIMEOUT: - srb->hastat = H_SEL_TIMEOUT; - srb->tastat = 0; - xs->error = XS_TIMEOUT; - break; - case SCSI_BUSY: - xs->error = XS_BUSY; - break; - case SCSI_RESV_CONFLICT: -#ifdef TRM_DEBUG - printf("%s: target reserved at ", sc->sc_dev.dv_xname); - printf("%s %d\n", __FILE__, __LINE__); -#endif - xs->error = XS_BUSY; - break; - default: - srb->hastat = 0; - if (srb->retry) { - srb->retry--; - srb->tastat = 0; - srb->sgindex = 0; - if (trm_start_scsi(sc, dcb, srb)) - /* - * If trm_start_scsi return 1 : - * current interrupt status is - * interrupt disreenable. It's said - * that SCSI processor has more one - * SRB need to do. - */ - trm_rewait_srb(dcb, srb); - return; - } else { -#ifdef TRM_DEBUG - printf("%s: driver stuffup at %s %d\n", - sc->sc_dev.dv_xname, __FILE__, __LINE__); -#endif - xs->error = XS_DRIVER_STUFFUP; - break; - } - } - else { + xs->status = srb->tastat; + + switch (xs->status) { + case SCSI_OK: /* * process initiator status...... * Adapter (initiator) status @@ -2304,26 +2203,67 @@ trm_srb_done(sc, dcb, srb) #endif /* Driver failed to perform operation */ xs->error = XS_DRIVER_STUFFUP; - } else { /* No error */ + } else { + /* No error */ srb->hastat = 0; - srb->tastat = 0; - xs->error = XS_NOERROR; - /* there is no error, (sense is invalid) */ + if (srb->flag & AUTO_REQSENSE) { + /* there is no error, (sense is invalid) */ + xs->error = XS_SENSE; + } else { + srb->tastat = 0; + xs->error = XS_NOERROR; + } } + break; + case SCSI_CHECK: + if ((srb->flag & AUTO_REQSENSE) != 0 || + trm_request_sense(sc, dcb, srb) != 0) { + printf("%s: request sense failed\n", + sc->sc_dev.dv_xname); + xs->error = XS_DRIVER_STUFFUP; + break; + } + xs->error = XS_SENSE; + return; + case SCSI_QUEUE_FULL: + dcb->maxcmd = dcb->gosrb_cnt - 1; + trm_rewait_srb(dcb, srb); + srb->hastat = 0; + srb->tastat = 0; + break; + case SCSI_SEL_TIMEOUT: + srb->hastat = H_SEL_TIMEOUT; + srb->tastat = 0; + xs->error = XS_TIMEOUT; + break; + case SCSI_BUSY: + xs->error = XS_BUSY; + break; + case SCSI_RESV_CONFLICT: +#ifdef TRM_DEBUG + printf("%s: target reserved at ", sc->sc_dev.dv_xname); + printf("%s %d\n", __FILE__, __LINE__); +#endif + xs->error = XS_BUSY; + break; + default: + srb->hastat = 0; +#ifdef TRM_DEBUG + printf("%s: driver stuffup at %s %d\n", + sc->sc_dev.dv_xname, __FILE__, __LINE__); +#endif + xs->error = XS_DRIVER_STUFFUP; + break; } -ckc_e: + id = srb->xs->xs_periph->periph_target; lun = srb->xs->xs_periph->periph_lun; if (sc->devscan[id][lun]) { /* * if SCSI command in "scan devices" duty + * XXX XXX XXX should not be done here! XXX XXX XXX */ - if (srb->cmd[0] == TEST_UNIT_READY) { - /* SCSI command phase: test unit ready */ -#ifdef TRM_DEBUG - printf("srb->cmd[0] == TEST_UNIT_READY....\n"); -#endif - } else if (srb->cmd[0] == INQUIRY) { + if (srb->cmd[0] == INQUIRY) { /* * SCSI command phase: inquiry scsi device data * (type,capacity,manufacture.... @@ -2333,9 +2273,7 @@ ckc_e: ptr = (struct scsipi_inquiry_data *)xs->data; bval = ptr->device & SID_TYPE; - /* - * #define T_NODEVICE 0x1f Unknown or no device type - */ + if (bval == T_NODEVICE) { NO_DEV: #ifdef TRM_DEBUG @@ -2404,7 +2342,6 @@ ckc_e: } splx(s); } else { - dcb->type = bval; if (bval == T_DIRECT || bval == T_OPTICAL) { if ((((ptr->version & 0x07) >= 2) || ((ptr->response_format & 0x0F) @@ -2419,17 +2356,9 @@ ckc_e: dcb->mode |= EN_ATN_STOP; } } - /* srb->cmd[0] == INQUIRY */ } - /* sc->devscan[id][lun] */ } exit: - if (xs->datalen > 0) { - bus_dmamap_sync(sc->sc_dmat, srb->dmap, 0, - srb->dmap->dm_mapsize, (xs->xs_control & XS_CTL_DATA_IN) ? - BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, srb->dmap); - } trm_release_srb(sc, dcb, srb); trm_wait_srb(sc); xs->xs_status |= XS_STS_DONE; @@ -2550,7 +2479,7 @@ trm_scsi_reset_detect(sc) splx(s); } -static void +static int trm_request_sense(sc, dcb, srb) struct trm_softc *sc; struct trm_dcb *dcb; @@ -2561,11 +2490,6 @@ trm_request_sense(sc, dcb, srb) int error, lun = xs->xs_periph->periph_lun; srb->flag |= AUTO_REQSENSE; - memcpy(srb->tempcmd, srb->cmd, sizeof(srb->tempcmd)); - - srb->templen = srb->buflen; - srb->tempsg.address = srb->sgentry[0].address; - srb->tempsg.length = srb->sgentry[0].length; /* Status of initiator/target */ srb->hastat = 0; @@ -2586,9 +2510,7 @@ trm_request_sense(sc, dcb, srb) if ((error = bus_dmamap_load(sc->sc_dmat, srb->dmap, &xs->sense.scsi_sense, srb->buflen, NULL, BUS_DMA_READ|BUS_DMA_NOWAIT)) != 0) { - printf("trm_request_sense: can not bus_dmamap_load()\n"); - xs->error = XS_DRIVER_STUFFUP; - return; + return error; } bus_dmamap_sync(sc->sc_dmat, srb->dmap, 0, srb->buflen, BUS_DMASYNC_PREREAD); @@ -2605,6 +2527,7 @@ trm_request_sense(sc, dcb, srb) * has more one SRB need to do. */ trm_rewait_srb(dcb, srb); + return 0; } static void