diff options
author | kib <kib@FreeBSD.org> | 2013-02-12 16:57:20 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-02-12 16:57:20 +0000 |
commit | bd7f0fa0bb4b7b0f87227e0c4d49a4bd9b113cf0 (patch) | |
tree | e550f2c754f1edf951a8b93963ebcfc4fa0d20ce /sys/dev/hptmv/entry.c | |
parent | e0a463e76c719f11788ec107b5aa3e2da4e57c0b (diff) | |
download | FreeBSD-src-bd7f0fa0bb4b7b0f87227e0c4d49a4bd9b113cf0.zip FreeBSD-src-bd7f0fa0bb4b7b0f87227e0c4d49a4bd9b113cf0.tar.gz |
Reform the busdma API so that new types may be added without modifying
every architecture's busdma_machdep.c. It is done by unifying the
bus_dmamap_load_buffer() routines so that they may be called from MI
code. The MD busdma is then given a chance to do any final processing
in the complete() callback.
The cam changes unify the bus_dmamap_load* handling in cam drivers.
The arm and mips implementations are updated to track virtual
addresses for sync(). Previously this was done in a type specific
way. Now it is done in a generic way by recording the list of
virtuals in the map.
Submitted by: jeff (sponsored by EMC/Isilon)
Reviewed by: kan (previous version), scottl,
mjacob (isp(4), no objections for target mode changes)
Discussed with: ian (arm changes)
Tested by: marius (sparc64), mips (jmallet), isci(4) on x86 (jharris),
amd64 (Fabian Keil <freebsd-listen@fabiankeil.de>)
Diffstat (limited to 'sys/dev/hptmv/entry.c')
-rw-r--r-- | sys/dev/hptmv/entry.c | 107 |
1 files changed, 34 insertions, 73 deletions
diff --git a/sys/dev/hptmv/entry.c b/sys/dev/hptmv/entry.c index 8dfa7e2..248d655 100644 --- a/sys/dev/hptmv/entry.c +++ b/sys/dev/hptmv/entry.c @@ -2620,32 +2620,7 @@ launch_worker_thread(void) int HPTLIBAPI fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg, int logical) { - union ccb *ccb = (union ccb *)pCmd->pOrgCommand; - bus_dma_segment_t *sgList = (bus_dma_segment_t *)ccb->csio.data_ptr; - int idx; - if(logical) { - if (ccb->ccb_h.flags & CAM_DATA_PHYS) - panic("physical address unsupported"); - - if (ccb->ccb_h.flags & CAM_SCATTER_VALID) { - if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS) - panic("physical address unsupported"); - - for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) { - pSg[idx].dSgAddress = (ULONG_PTR)(UCHAR *)sgList[idx].ds_addr; - pSg[idx].wSgSize = sgList[idx].ds_len; - pSg[idx].wSgFlag = (idx==ccb->csio.sglist_cnt-1)? SG_FLAG_EOT : 0; - } - } - else { - pSg->dSgAddress = (ULONG_PTR)(UCHAR *)ccb->csio.data_ptr; - pSg->wSgSize = ccb->csio.dxfer_len; - pSg->wSgFlag = SG_FLAG_EOT; - } - return TRUE; - } - /* since we have provided physical sg, nobody will ask us to build physical sg */ HPT_ASSERT(0); return FALSE; @@ -2757,24 +2732,28 @@ hpt_io_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error) HPT_ASSERT(pCmd->cf_physical_sg); - if (error || nsegs == 0) + if (error) panic("busdma error"); HPT_ASSERT(nsegs<= MAX_SG_DESCRIPTORS); - for (idx = 0; idx < nsegs; idx++, psg++) { - psg->dSgAddress = (ULONG_PTR)(UCHAR *)segs[idx].ds_addr; - psg->wSgSize = segs[idx].ds_len; - psg->wSgFlag = (idx == nsegs-1)? SG_FLAG_EOT: 0; -/* KdPrint(("psg[%d]:add=%p,size=%x,flag=%x\n", idx, psg->dSgAddress,psg->wSgSize,psg->wSgFlag)); */ - } -/* psg[-1].wSgFlag = SG_FLAG_EOT; */ - - if (pCmd->cf_data_in) { - bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_PREREAD); - } - else if (pCmd->cf_data_out) { - bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_PREWRITE); + if (nsegs != 0) { + for (idx = 0; idx < nsegs; idx++, psg++) { + psg->dSgAddress = (ULONG_PTR)(UCHAR *)segs[idx].ds_addr; + psg->wSgSize = segs[idx].ds_len; + psg->wSgFlag = (idx == nsegs-1)? SG_FLAG_EOT: 0; + /* KdPrint(("psg[%d]:add=%p,size=%x,flag=%x\n", idx, psg->dSgAddress,psg->wSgSize,psg->wSgFlag)); */ + } + /* psg[-1].wSgFlag = SG_FLAG_EOT; */ + + if (pCmd->cf_data_in) { + bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, + BUS_DMASYNC_PREREAD); + } + else if (pCmd->cf_data_out) { + bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, + BUS_DMASYNC_PREWRITE); + } } ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz); @@ -2883,6 +2862,7 @@ OsSendCommand(_VBUS_ARG union ccb *ccb) UCHAR CdbLength; _VBUS_INST(pVDev->pVBus) PCommand pCmd = AllocateCommand(_VBUS_P0); + int error; HPT_ASSERT(pCmd); CdbLength = csio->cdb_len; @@ -2960,40 +2940,21 @@ OsSendCommand(_VBUS_ARG union ccb *ccb) break; } /*///////////////////////// */ - if (ccb->ccb_h.flags & CAM_SCATTER_VALID) { - int idx; - bus_dma_segment_t *sgList = (bus_dma_segment_t *)ccb->csio.data_ptr; - - if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS) - pCmd->cf_physical_sg = 1; - - for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) { - pCmd->pSgTable[idx].dSgAddress = (ULONG_PTR)(UCHAR *)sgList[idx].ds_addr; - pCmd->pSgTable[idx].wSgSize = sgList[idx].ds_len; - pCmd->pSgTable[idx].wSgFlag= (idx==ccb->csio.sglist_cnt-1)?SG_FLAG_EOT: 0; - } - - ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz); - pVDev->pfnSendCommand(_VBUS_P pCmd); - } - else { - int error; - pCmd->cf_physical_sg = 1; - error = bus_dmamap_load(pAdapter->io_dma_parent, - pmap->dma_map, - ccb->csio.data_ptr, ccb->csio.dxfer_len, - hpt_io_dmamap_callback, pCmd, - BUS_DMA_WAITOK - ); - KdPrint(("bus_dmamap_load return %d\n", error)); - if (error && error!=EINPROGRESS) { - hpt_printk(("bus_dmamap_load error %d\n", error)); - FreeCommand(_VBUS_P pCmd); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - dmamap_put(pmap); - pAdapter->outstandingCommands--; - xpt_done(ccb); - } + pCmd->cf_physical_sg = 1; + error = bus_dmamap_load_ccb(pAdapter->io_dma_parent, + pmap->dma_map, + ccb, + hpt_io_dmamap_callback, + pCmd, BUS_DMA_WAITOK + ); + KdPrint(("bus_dmamap_load return %d\n", error)); + if (error && error!=EINPROGRESS) { + hpt_printk(("bus_dmamap_load error %d\n", error)); + FreeCommand(_VBUS_P pCmd); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + dmamap_put(pmap); + pAdapter->outstandingCommands--; + xpt_done(ccb); } goto Command_Complished; } |