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/advansys | |
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/advansys')
-rw-r--r-- | sys/dev/advansys/advansys.c | 64 | ||||
-rw-r--r-- | sys/dev/advansys/adwcam.c | 73 |
2 files changed, 25 insertions, 112 deletions
diff --git a/sys/dev/advansys/advansys.c b/sys/dev/advansys/advansys.c index d804b6d..c9ccb67 100644 --- a/sys/dev/advansys/advansys.c +++ b/sys/dev/advansys/advansys.c @@ -207,6 +207,7 @@ adv_action(struct cam_sim *sim, union ccb *ccb) struct ccb_hdr *ccb_h; struct ccb_scsiio *csio; struct adv_ccb_info *cinfo; + int error; ccb_h = &ccb->ccb_h; csio = &ccb->csio; @@ -217,58 +218,17 @@ adv_action(struct cam_sim *sim, union ccb *ccb) ccb_h->ccb_cinfo_ptr = cinfo; cinfo->ccb = ccb; - /* Only use S/G if there is a transfer */ - if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { - /* - * We've been given a pointer - * to a single buffer - */ - if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { - int error; - - error = - bus_dmamap_load(adv->buffer_dmat, - cinfo->dmamap, - csio->data_ptr, - csio->dxfer_len, - adv_execute_ccb, - csio, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - adv_set_state(adv, - ADV_BUSDMA_BLOCK); - } - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - seg.ds_addr = - (bus_addr_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - adv_execute_ccb(csio, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - if ((ccb_h->flags & CAM_DATA_PHYS) != 0) - panic("adv_setup_data - Physical " - "segment pointers unsupported"); - - if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) - panic("adv_setup_data - Virtual " - "segment addresses unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)csio->data_ptr; - adv_execute_ccb(ccb, segs, csio->sglist_cnt, 0); - } - } else { - adv_execute_ccb(ccb, NULL, 0, 0); + error = bus_dmamap_load_ccb(adv->buffer_dmat, + cinfo->dmamap, + ccb, + adv_execute_ccb, + csio, /*flags*/0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the controller + * queue until our mapping is returned. + */ + adv_set_state(adv, ADV_BUSDMA_BLOCK); } break; } diff --git a/sys/dev/advansys/adwcam.c b/sys/dev/advansys/adwcam.c index defc7c7..de1f413 100644 --- a/sys/dev/advansys/adwcam.c +++ b/sys/dev/advansys/adwcam.c @@ -353,6 +353,7 @@ adw_action(struct cam_sim *sim, union ccb *ccb) struct ccb_scsiio *csio; struct ccb_hdr *ccbh; struct acb *acb; + int error; csio = &ccb->csio; ccbh = &ccb->ccb_h; @@ -427,66 +428,18 @@ adw_action(struct cam_sim *sim, union ccb *ccb) acb->queue.cdb, csio->cdb_len); } - /* - * If we have any data to send with this command, - * map it into bus space. - */ - if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { - /* - * We've been given a pointer - * to a single buffer. - */ - if ((ccbh->flags & CAM_DATA_PHYS) == 0) { - int error; - - error = - bus_dmamap_load(adw->buffer_dmat, - acb->dmamap, - csio->data_ptr, - csio->dxfer_len, - adwexecuteacb, - acb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(sim, 1); - acb->state |= CAM_RELEASE_SIMQ; - } - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - seg.ds_addr = - (bus_addr_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - adwexecuteacb(acb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccbh->flags & CAM_DATA_PHYS) != 0) - panic("adw_action - Physical " - "segment pointers " - "unsupported"); - - if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) - panic("adw_action - Virtual " - "segment addresses " - "unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)csio->data_ptr; - adwexecuteacb(acb, segs, csio->sglist_cnt, - (csio->sglist_cnt < ADW_SGSIZE) - ? 0 : EFBIG); - } - } else { - adwexecuteacb(acb, NULL, 0, 0); + error = bus_dmamap_load_ccb(adw->buffer_dmat, + acb->dmamap, + ccb, + adwexecuteacb, + acb, /*flags*/0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the controller + * queue until our mapping is returned. + */ + xpt_freeze_simq(sim, 1); + acb->state |= CAM_RELEASE_SIMQ; } break; } |