diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2003-03-29 17:52:02 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2003-03-29 17:52:02 +0000 |
commit | 471a7e35aa8eb1431337626194e0eed0384c338c (patch) | |
tree | 8d3d00744b3df3d31fbc4ef7ee31d9feb1559b90 /sys/dev | |
parent | 9085fb972e97fd917644604f6100a04b987b2ae9 (diff) |
Another chunk of bus_dma fixes. May actually approach correctness now.
1) Actually map and sync scatter gather list that is also DMA'd.
2) Actually map and sync request sense buffer.
3) Actually POSTREAD/WRITE sync data buffer after I/O, rather than
skipping it because the I/O was successful and no chars were left to
xfer.
4) Eliminate extra fields, clarify some names, reorder fields to
clarify their use.
5) Put common scatter gather preparation logic into separate function.
6) If insertion of request sense command fails, complete active
command with XS_SENSE, but zero'd sense data.
7) Eliminate physical address arithmetic as much as possible,
centralizing remaining manipulations in code actually sending
addresses to adapter.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/iha.c | 279 | ||||
-rw-r--r-- | sys/dev/ic/iha.h | 37 |
2 files changed, 175 insertions, 141 deletions
diff --git a/sys/dev/ic/iha.c b/sys/dev/ic/iha.c index c01441e61bd..50c23095fad 100644 --- a/sys/dev/ic/iha.c +++ b/sys/dev/ic/iha.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iha.c,v 1.18 2003/03/29 02:34:17 krw Exp $ */ +/* $OpenBSD: iha.c,v 1.19 2003/03/29 17:52:01 krw Exp $ */ /*------------------------------------------------------------------------- * * Device driver for the INI-9XXXU/UW or INIC-940/950 PCI SCSI Controller. @@ -84,8 +84,9 @@ static const u_int8_t iha_rate_tbl[8] = { 62 /* 250ns, 4M */ }; +int iha_setup_sg_list(struct iha_softc *, struct iha_scsi_req_q *); u_int8_t iha_data_over_run(struct iha_scsi_req_q *); -void iha_push_sense_request(struct iha_softc *, struct iha_scsi_req_q *); +int iha_push_sense_request(struct iha_softc *, struct iha_scsi_req_q *); void iha_timeout(void *); int iha_alloc_scbs(struct iha_softc *); void iha_read_eeprom(bus_space_tag_t, bus_space_handle_t, @@ -210,6 +211,47 @@ iha_intr(arg) } /* + * iha_setup_sg_list - initialize scatter gather list of pScb from + * pScb->SCB_DataDma. + */ +int +iha_setup_sg_list(sc, pScb) + struct iha_softc *sc; + struct iha_scsi_req_q *pScb; +{ + bus_dma_segment_t *segs = pScb->SCB_DataDma->dm_segs; + int i, error, nseg = pScb->SCB_DataDma->dm_nsegs; + + if (nseg > 1) { + pScb->SCB_Flags |= FLAG_SG; + bzero(pScb->SCB_SGList, sizeof(pScb->SCB_SGList)); + + error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_SGDma, + pScb->SCB_SGList, sizeof(pScb->SCB_SGList), NULL, + (pScb->SCB_Flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK); + if (error) { + sc_print_addr(pScb->SCB_Xs->sc_link); + printf("error %d loading SG list dma map\n", error); + return (error); + } + + pScb->SCB_SGIdx = 0; + pScb->SCB_SGCount = nseg; + + for (i=0; i < nseg; i++) { + pScb->SCB_SGList[i].SG_Len = segs[i].ds_len; + pScb->SCB_SGList[i].SG_Addr = segs[i].ds_addr; + } + + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, + 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_PREWRITE); + } + + return (0); +} + +/* * iha_scsi_cmd - start execution of a SCSI command. This is called * from the generic SCSI driver via the field * sc_adapter.scsi_cmd of iha_softc. @@ -219,11 +261,9 @@ iha_scsi_cmd(xs) struct scsi_xfer *xs; { struct iha_scsi_req_q *pScb; - struct iha_sg_element *sg; struct scsi_link *sc_link = xs->sc_link; struct iha_softc *sc = sc_link->adapter_softc; - bus_dmamap_t dm; - int error, nseg, i; + int error; if ((xs->cmdlen > 12) || (sc_link->target >= IHA_MAX_TARGETS)) { xs->error = XS_DRIVER_STUFFUP; @@ -253,19 +293,19 @@ iha_scsi_cmd(xs) pScb->SCB_CDBLen = xs->cmdlen; bcopy(xs->cmd, &pScb->SCB_CDB, xs->cmdlen); - pScb->SCB_BufLen = xs->datalen; + pScb->SCB_BufCharsLeft = pScb->SCB_BufChars = xs->datalen; - if (pScb->SCB_BufLen > 0) { + if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) { #ifdef TFS if (pScb->SCB_Flags & SCSI_DATA_UIO) error = bus_dmamap_load_uio(sc->sc_dmat, - pScb->SCB_Dmamap, (struct uio *)xs->data, + pScb->SCB_DataDma, (struct uio *)xs->data, (pScb->SCB_Flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); else #endif /* TFS */ - error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_Dmamap, - xs->data, pScb->SCB_BufLen, NULL, + error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma, + xs->data, pScb->SCB_BufChars, NULL, (pScb->SCB_Flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); @@ -284,33 +324,19 @@ iha_scsi_cmd(xs) return (COMPLETE); } - dm = pScb->SCB_Dmamap; - nseg = dm->dm_nsegs; - - if (nseg > 1) { - sg = pScb->SCB_SGList; - - for (i=0; i < nseg; i++) { - sg[i].SG_Len = dm->dm_segs[i].ds_len; - sg[i].SG_Ptr = dm->dm_segs[i].ds_addr; - } - - pScb->SCB_Flags |= FLAG_SG; - pScb->SCB_SGLen = nseg; - - pScb->SCB_BufPAddr = pScb->SCB_SGPAddr; - } else - pScb->SCB_BufPAddr = dm->dm_segs[0].ds_addr; + error = iha_setup_sg_list(sc, pScb); + if (error) { + bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma); + xs->error = XS_DRIVER_STUFFUP; + return (COMPLETE); + } - bus_dmamap_sync(sc->sc_dmat, pScb->SCB_Dmamap, - 0, pScb->SCB_Dmamap->dm_mapsize, - (pScb->SCB_Flags & SCSI_DATA_IN) ? - BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma, + 0, pScb->SCB_BufChars, + (pScb->SCB_Flags & SCSI_DATA_IN) ? + BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); } - pScb->SCB_SGMax = pScb->SCB_SGLen; - pScb->SCB_Timeout = xs->timeout; - /* * Always initialize the stimeout structure as it may * contain garbage that confuses timeout_del() later on. @@ -377,25 +403,29 @@ iha_init_tulip(sc) for (i = 0, pScb = sc->HCS_Scb; i < IHA_MAX_SCB; i++, pScb++) { pScb->SCB_TagId = i; - pScb->SCB_SGPAddr = sc->sc_dmamap->dm_segs[0].ds_addr - + i*sizeof(struct iha_scsi_req_q) - + offsetof(struct iha_scsi_req_q, SCB_SGList); - - pScb->SCB_SenseLen = sizeof(struct scsi_sense_data); - pScb->SCB_SensePAddr = sc->sc_dmamap->dm_segs[0].ds_addr - + i*sizeof(struct iha_scsi_req_q) - + offsetof(struct iha_scsi_req_q, SCB_ScsiSenseData); error = bus_dmamap_create(sc->sc_dmat, (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, IHA_MAX_SG_ENTRIES, (IHA_MAX_SG_ENTRIES-1) * PAGE_SIZE, 0, - BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pScb->SCB_Dmamap); + BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &pScb->SCB_DataDma); + + if (error != 0) { + printf("%s: couldn't create SCB data DMA map, error = %d\n", + sc->sc_dev.dv_xname, error); + return (error); + } + error = bus_dmamap_create(sc->sc_dmat, + sizeof(pScb->SCB_SGList), 1, + sizeof(pScb->SCB_SGList), 0, + BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, + &pScb->SCB_SGDma); if (error != 0) { - printf("%s: couldn't create SCB DMA map, error = %d\n", + printf("%s: couldn't create SCB SG DMA map, error = %d\n", sc->sc_dev.dv_xname, error); return (error); } + TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList); } @@ -518,35 +548,28 @@ iha_append_free_scb(sc, pScb) if (pScb == sc->HCS_ActScb) sc->HCS_ActScb = NULL; - pScb->SCB_Status = STATUS_QUEUED; - pScb->SCB_HaStat = HOST_OK; - pScb->SCB_TaStat = SCSI_OK; + pScb->SCB_Status = STATUS_QUEUED; + pScb->SCB_HaStat = HOST_OK; + pScb->SCB_TaStat = SCSI_OK; pScb->SCB_NxtStat = 0; - pScb->SCB_SGIdx = 0; - pScb->SCB_SGMax = 0; pScb->SCB_Flags = 0; pScb->SCB_Target = 0; pScb->SCB_Lun = 0; - pScb->SCB_BufLen = 0; - pScb->SCB_SGLen = 0; pScb->SCB_CDBLen = 0; pScb->SCB_Ident = 0; pScb->SCB_TagMsg = 0; - pScb->SCB_Timeout = 0; - pScb->SCB_BufPAddr = 0; + + pScb->SCB_BufChars = 0; + pScb->SCB_BufCharsLeft = 0; pScb->SCB_Xs = NULL; pScb->SCB_Tcs = NULL; - bzero( pScb->SCB_CDB, sizeof(pScb->SCB_CDB)); - bzero(&pScb->SCB_ScsiSenseData, sizeof(pScb->SCB_ScsiSenseData)); - bzero( pScb->SCB_SGList, sizeof(pScb->SCB_SGList)); + bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB)); /* - * SCB_TagId, SCB_SGPAddr, SCB_SenseLen, SCB_SGList - * SCB_SensePtr are set at initialization - * and never change + * SCB_TagId is set at initialization and never changes */ TAILQ_INSERT_TAIL(&sc->HCS_FreeScb, pScb, SCB_ScbList); @@ -808,26 +831,50 @@ iha_bad_seq(sc) * SCB needing it back onto the pending * queue with a REQUEST_SENSE CDB. */ -void +int iha_push_sense_request(sc, pScb) struct iha_softc *sc; struct iha_scsi_req_q *pScb; { struct scsi_sense *sensecmd; + int error; - pScb->SCB_BufLen = pScb->SCB_SenseLen; - pScb->SCB_BufPAddr = pScb->SCB_SensePAddr; - - pScb->SCB_Flags &= SCSI_POLL; + pScb->SCB_Flags &= SCSI_POLL | SCSI_NOSLEEP; pScb->SCB_Flags |= FLAG_RSENS | SCSI_DATA_IN; + pScb->SCB_BufChars = sizeof(pScb->SCB_ScsiSenseData); + pScb->SCB_BufCharsLeft = sizeof(pScb->SCB_ScsiSenseData); + bzero(&pScb->SCB_ScsiSenseData, sizeof(pScb->SCB_ScsiSenseData)); + + error = bus_dmamap_load(sc->sc_dmat, pScb->SCB_DataDma, + &pScb->SCB_ScsiSenseData, + sizeof(pScb->SCB_ScsiSenseData), NULL, + (pScb->SCB_Flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK); + if (error) { + sc_print_addr(pScb->SCB_Xs->sc_link); + printf("error %d loading request sense buffer dma map\n", + error); + return (1); + } + + error = iha_setup_sg_list(sc, pScb); + if (error) { + bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma); + return (error); + } + + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma, + 0, pScb->SCB_BufChars, + (pScb->SCB_Flags & SCSI_DATA_IN) ? + BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + pScb->SCB_Ident &= ~MSG_IDENTIFY_DISCFLAG; pScb->SCB_TagMsg = 0; pScb->SCB_TaStat = SCSI_OK; bzero(pScb->SCB_CDB, sizeof(pScb->SCB_CDB)); - bzero(&pScb->SCB_ScsiSenseData, sizeof(pScb->SCB_ScsiSenseData)); sensecmd = (struct scsi_sense *)pScb->SCB_CDB; pScb->SCB_CDBLen = sizeof(*sensecmd); @@ -837,9 +884,11 @@ iha_push_sense_request(sc, pScb) if ((pScb->SCB_Flags & SCSI_POLL) == 0) timeout_add(&pScb->SCB_Xs->stimeout, - (pScb->SCB_Timeout/1000) * hz); + (pScb->SCB_Xs->timeout/1000) * hz); iha_push_pend_scb(sc, pScb); + + return (0); } /* @@ -872,11 +921,9 @@ iha_scsi_label: if ((pScb->SCB_Flags & FLAG_RSENS) != 0) /* Check condition on check condition*/ pScb->SCB_HaStat = HOST_BAD_PHAS; - - else { - iha_push_sense_request(sc, pScb); + else if (iha_push_sense_request(sc, pScb) == 0) + /* REQUEST SENSE ready to process */ goto iha_scsi_label; - } break; default: @@ -918,6 +965,7 @@ iha_scsi(sc, iot, ioh) struct iha_scsi_req_q *pScb; struct tcs *pTcs; u_int8_t stat; + int i; /* service pending interrupts asap */ @@ -986,7 +1034,7 @@ iha_scsi(sc, iot, ioh) } if ((pScb->SCB_Flags & SCSI_POLL) != 0) { - for (; pScb->SCB_Timeout > 0; pScb->SCB_Timeout--) { + for (i = pScb->SCB_Xs->timeout; i > 0; i--) { if (iha_wait(sc, iot, ioh, NO_OP) == -1) break; if (iha_next_state(sc, iot, ioh) == -1) @@ -1001,7 +1049,7 @@ iha_scsi(sc, iot, ioh) * * Conversely, xs->error has not been set yet */ - if (pScb->SCB_Timeout == 0) + if (i == 0) iha_timeout(pScb); else if ((pScb->SCB_CDB[0] == INQUIRY) @@ -1013,7 +1061,7 @@ iha_scsi(sc, iot, ioh) } /* - * iha_data_over_run - return HOST_OK for all SCSI opcodes where BufLen + * iha_data_over_run - return HOST_OK for all SCSI opcodes where BufCharsLeft * is an 'Allocation Length'. All other SCSI opcodes * get HOST_DO_DU as they SHOULD have xferred all the * data requested. @@ -1310,7 +1358,7 @@ iha_state_4(sc, iot, ioh) return (6); /* Both dir flags set => NO xfer was requested */ for (;;) { - if (pScb->SCB_BufLen == 0) + if (pScb->SCB_BufCharsLeft == 0) return (6); switch (sc->HCS_Phase) { @@ -1329,7 +1377,7 @@ iha_state_4(sc, iot, ioh) case PHASE_MSG_OUT: if ((sc->HCS_JSStatus0 & SPERR) != 0) { - pScb->SCB_BufLen = 0; + pScb->SCB_BufCharsLeft = 0; pScb->SCB_HaStat = HOST_SPERR; if (iha_msgout(sc, iot, ioh, MSG_INITIATOR_DET_ERR) == -1) @@ -1373,7 +1421,6 @@ iha_state_5(sc, iot, ioh) u_int16_t period; u_int8_t stat; long xcnt; /* cannot use unsigned!! see code: if (xcnt < 0) */ - int i; cnt = bus_space_read_4(iot, ioh, TUL_STCNT0) & TCNT; @@ -1422,37 +1469,38 @@ iha_state_5(sc, iot, ioh) } if (cnt == 0) { - pScb->SCB_BufLen = 0; + pScb->SCB_BufCharsLeft = 0; return (6); } /* Update active data pointer and restart the I/O at the new point */ - xcnt = pScb->SCB_BufLen - cnt; /* xcnt == bytes xferred */ - pScb->SCB_BufLen = cnt; /* cnt == bytes left */ + xcnt = pScb->SCB_BufCharsLeft - cnt; /* xcnt == bytes xferred */ + pScb->SCB_BufCharsLeft = cnt; /* cnt == bytes left */ + + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, + 0, sizeof(pScb->SCB_SGList), BUS_DMASYNC_POSTWRITE); if ((pScb->SCB_Flags & FLAG_SG) != 0) { pSg = &pScb->SCB_SGList[pScb->SCB_SGIdx]; - for (i = pScb->SCB_SGIdx; i < pScb->SCB_SGMax; pSg++, i++) { + for (; pScb->SCB_SGIdx < pScb->SCB_SGCount; pSg++, pScb->SCB_SGIdx++) { xcnt -= pSg->SG_Len; if (xcnt < 0) { xcnt += pSg->SG_Len; - pSg->SG_Ptr += xcnt; + pSg->SG_Addr += xcnt; pSg->SG_Len -= xcnt; - pScb->SCB_BufPAddr += (i - pScb->SCB_SGIdx) - * sizeof(struct iha_sg_element); - pScb->SCB_SGLen = pScb->SCB_SGMax - i; - pScb->SCB_SGIdx = i; + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, + 0, sizeof(pScb->SCB_SGList), + BUS_DMASYNC_PREWRITE); return (4); } } return (6); - } else - pScb->SCB_BufPAddr += xcnt; + } return (4); } @@ -1562,25 +1610,30 @@ iha_xfer_data(pScb, iot, ioh, direction) bus_space_handle_t ioh; int direction; { - u_int32_t xferlen; + u_int32_t xferaddr, xferlen; u_int8_t xfertype; if ((pScb->SCB_Flags & FLAG_DIR) != direction) return (6); /* wrong direction, abandon I/O */ - bus_space_write_4(iot, ioh, TUL_STCNT0, pScb->SCB_BufLen); + bus_space_write_4(iot, ioh, TUL_STCNT0, pScb->SCB_BufCharsLeft); if ((pScb->SCB_Flags & FLAG_SG) == 0) { - xferlen = pScb->SCB_BufLen; + xferaddr = pScb->SCB_DataDma->dm_segs[0].ds_addr + + (pScb->SCB_BufChars - pScb->SCB_BufCharsLeft); + xferlen = pScb->SCB_BufCharsLeft; xfertype = (direction == SCSI_DATA_IN) ? ST_X_IN : ST_X_OUT; } else { - xferlen = pScb->SCB_SGLen * sizeof(struct iha_sg_element); + xferaddr = pScb->SCB_SGDma->dm_segs[0].ds_addr + + (pScb->SCB_SGIdx * sizeof(struct iha_sg_element)); + xferlen = (pScb->SCB_SGCount - pScb->SCB_SGIdx) + * sizeof(struct iha_sg_element); xfertype = (direction == SCSI_DATA_IN) ? ST_SG_IN : ST_SG_OUT; } bus_space_write_4(iot, ioh, TUL_DXC, xferlen); - bus_space_write_4(iot, ioh, TUL_DXPA, pScb->SCB_BufPAddr); + bus_space_write_4(iot, ioh, TUL_DXPA, xferaddr); bus_space_write_1(iot, ioh, TUL_DCMD, xfertype); bus_space_write_1(iot, ioh, TUL_SCMD, @@ -2423,12 +2476,18 @@ iha_done_scb(sc, pScb) xs->status = pScb->SCB_TaStat; - if (pScb->SCB_BufLen > 0) { - bus_dmamap_sync(sc->sc_dmat, pScb->SCB_Dmamap, - 0, pScb->SCB_Dmamap->dm_mapsize, - ((pScb->SCB_Flags & SCSI_DATA_IN) ? - BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); - bus_dmamap_unload(sc->sc_dmat, pScb->SCB_Dmamap); + if ((pScb->SCB_Flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) != 0) { + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_DataDma, + 0, pScb->SCB_BufChars, + ((pScb->SCB_Flags & SCSI_DATA_IN) ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); + bus_dmamap_unload(sc->sc_dmat, pScb->SCB_DataDma); + } + if ((pScb->SCB_Flags & FLAG_SG) != 0) { + bus_dmamap_sync(sc->sc_dmat, pScb->SCB_SGDma, + 0, sizeof(pScb->SCB_SGList), + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, pScb->SCB_SGDma); } switch (pScb->SCB_HaStat) { @@ -2438,7 +2497,7 @@ iha_done_scb(sc, pScb) case SCSI_COND_MET: case SCSI_INTERM: case SCSI_INTERM_COND_MET: - xs->resid = pScb->SCB_BufLen; + xs->resid = pScb->SCB_BufCharsLeft; xs->error = XS_NOERROR; break; @@ -2625,28 +2684,6 @@ iha_alloc_scbs(sc) sc->sc_dev.dv_xname, error); return (error); } - - /* - * Create and load the DMA map used for the SCBs - */ - if ((error = bus_dmamap_create(sc->sc_dmat, - sizeof(struct iha_scsi_req_q)*IHA_MAX_SCB, - 1, sizeof(struct iha_scsi_req_q)*IHA_MAX_SCB, - 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) - != 0) { - printf("%s: unable to create control DMA map, error = %d\n", - sc->sc_dev.dv_xname, error); - return (error); - } - if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, - sc->HCS_Scb, sizeof(struct iha_scsi_req_q)*IHA_MAX_SCB, - NULL, BUS_DMA_NOWAIT)) - != 0) { - printf("%s: unable to load control DMA map, error = %d\n", - sc->sc_dev.dv_xname, error); - return (error); - } - bzero(sc->HCS_Scb, sizeof(struct iha_scsi_req_q)*IHA_MAX_SCB); return (0); diff --git a/sys/dev/ic/iha.h b/sys/dev/ic/iha.h index 44bfc6824b2..cfad53dcc33 100644 --- a/sys/dev/ic/iha.h +++ b/sys/dev/ic/iha.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iha.h,v 1.11 2002/11/14 02:31:46 krw Exp $ */ +/* $OpenBSD: iha.h,v 1.12 2003/03/29 17:52:01 krw Exp $ */ /*------------------------------------------------------------------------- * * Device driver for the INI-9XXXU/UW or INIC-940/950 PCI SCSI Controller. @@ -42,8 +42,8 @@ * Scatter-Gather Element Structure */ struct iha_sg_element { - u_int32_t SG_Ptr; /* Data Pointer */ - u_int32_t SG_Len; /* Data Length */ + u_int32_t SG_Addr; /* Physical address of segment */ + u_int32_t SG_Len; /* Length of segment */ }; /* @@ -55,22 +55,23 @@ struct iha_sg_element { struct iha_scsi_req_q { TAILQ_ENTRY(iha_scsi_req_q) SCB_ScbList; + bus_dmamap_t SCB_DataDma; /* maps xfer buffer */ + bus_dmamap_t SCB_SGDma; /* maps scatter-gather list */ + int SCB_Status; /* Current status of the SCB */ #define STATUS_QUEUED 0 /* SCB one of Free/Done/Pend */ #define STATUS_RENT 1 /* SCB allocated, not queued */ #define STATUS_SELECT 2 /* SCB being selected */ #define STATUS_BUSY 3 /* SCB I/O is active */ u_int8_t SCB_NxtStat; /* Next state function to apply */ - u_int16_t SCB_SGIdx; /* Scatter/Gather Index */ - u_int16_t SCB_SGMax; /* Scatter/Gather # valid entries */ int SCB_Flags; /* SCB Flags (xs->flags + private)*/ #define FLAG_RSENS 0x00010000 /* Request Sense sent */ #define FLAG_SG 0x00020000 /* Scatter/Gather used */ #define FLAG_DIR (SCSI_DATA_IN | SCSI_DATA_OUT) u_int8_t SCB_Target; /* Target Id */ u_int8_t SCB_Lun; /* Lun */ - u_int32_t SCB_BufPAddr; /* Data Buffer Physical Addr */ - u_int32_t SCB_BufLen; /* Data Allocation Length */ + u_int32_t SCB_BufChars; /* size of data buf */ + u_int32_t SCB_BufCharsLeft; /* Chars left to xfer to/from buf */ u_int8_t SCB_HaStat; /* Status of Host Adapter */ #define HOST_OK 0x00 /* OK - operation a success */ #define HOST_TIMED_OUT 0x01 /* Request timed out */ @@ -81,25 +82,21 @@ struct iha_scsi_req_q { #define HOST_SCSI_RST 0x1B /* SCSI bus was reset */ #define HOST_DEV_RST 0x1C /* Device was reset */ u_int8_t SCB_TaStat; /* SCSI Status Byte */ - u_int8_t SCB_SGLen; /* # of valid entries in SGList */ - u_int8_t SCB_SenseLen; /* Sense Data Allocation Length */ - u_int8_t SCB_CDBLen; /* CDB Length */ u_int8_t SCB_Ident; /* Identity Message */ u_int8_t SCB_TagMsg; /* Tag Message */ u_int8_t SCB_TagId; /* Queue Tag */ - u_int8_t SCB_CDB[12]; /* SCSI Command */ - u_int32_t SCB_SGPAddr; /* SGList Physical Address */ - u_int32_t SCB_SensePAddr; /* Sense Data PhysicalAddress */ - struct scsi_xfer *SCB_Xs; /* xs this SCB is executing */ + u_int8_t SCB_CDB[12]; /* SCSI command being executed */ + u_int8_t SCB_CDBLen; /* Length of SCSI command in CDB */ - /* Start of SG list */ - struct iha_sg_element SCB_SGList[IHA_MAX_SG_ENTRIES]; + struct scsi_xfer *SCB_Xs; /* xs this SCB is executing */ + + struct iha_sg_element SCB_SGList[IHA_MAX_SG_ENTRIES]; /* SG list */ + u_int16_t SCB_SGCount; /* # segments in list */ + u_int16_t SCB_SGIdx; /* index to current element */ - struct scsi_sense_data SCB_ScsiSenseData; - bus_dmamap_t SCB_Dmamap;/* maps xs->buf xfer buffer */ - int SCB_Timeout; /* in milliseconds */ - struct tcs *SCB_Tcs; /* tcs for SCB_Target */ + struct scsi_sense_data SCB_ScsiSenseData; /* DMA-able sense buffer */ + struct tcs *SCB_Tcs; /* tcs for SCB_Target */ }; /* |