Index: powerpc/ps3/ps3cdrom.c =================================================================== --- powerpc/ps3/ps3cdrom.c (revision 243644) +++ powerpc/ps3/ps3cdrom.c (working copy) @@ -369,9 +369,8 @@ ps3cdrom_action(struct cam_sim *sim, union ccb *cc TAILQ_REMOVE(&sc->sc_free_xferq, xp, x_queue); - err = bus_dmamap_load(sc->sc_dmatag, xp->x_dmamap, - ccb->csio.data_ptr, ccb->csio.dxfer_len, ps3cdrom_transfer, - xp, 0); + err = bus_dmamap_load_ccb(sc->sc_dmatag, xp->x_dmamap, + ccb, ps3cdrom_transfer, xp, 0); if (err && err != EINPROGRESS) { device_printf(dev, "Could not load DMA map (%d)\n", err); Index: conf/files =================================================================== --- conf/files (revision 243644) +++ conf/files (working copy) @@ -2665,6 +2665,7 @@ kern/subr_acl_posix1e.c optional ufs_acl kern/subr_autoconf.c standard kern/subr_blist.c standard kern/subr_bus.c standard +kern/subr_busdma.c standard kern/subr_bufring.c standard kern/subr_clock.c standard kern/subr_devstat.c standard Index: kern/subr_busdma.c =================================================================== --- kern/subr_busdma.c (revision 0) +++ kern/subr_busdma.c (revision 0) @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 2012 EMC Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_bus.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +int +bus_dmamap_load_ccb(bus_dma_tag_t dmat, bus_dmamap_t map, union ccb *ccb, + bus_dmamap_callback_t *callback, void *callback_arg, + int flags) +{ + struct ccb_ataio *ataio; + struct ccb_scsiio *csio; + struct ccb_hdr *ccb_h; + void *data_ptr; + uint32_t dxfer_len; + uint16_t sglist_cnt; + + ccb_h = &ccb->ccb_h; + if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) { + callback(callback_arg, NULL, 0, 0); + } + + switch (ccb_h->func_code) { + case XPT_SCSI_IO: + csio = &ccb->csio; + data_ptr = csio->data_ptr; + dxfer_len = csio->dxfer_len; + sglist_cnt = csio->sglist_cnt; + break; + case XPT_ATA_IO: + ataio = &ccb->ataio; + data_ptr = ataio->data_ptr; + dxfer_len = ataio->dxfer_len; + sglist_cnt = 0; + break; + default: + panic("bus_dmamap_load_ccb: Unsupported func code %d", + ccb_h->func_code); + } + + if ((ccb_h->flags & CAM_SCATTER_VALID) != 0) { + struct bus_dma_segment *segs; + + if ((ccb_h->flags & CAM_DATA_PHYS) != 0) + panic("bus_dmamap_load_ccb - Physical segment " + "pointers unsupported"); + + if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) + panic("bus_dmamap_load_ccb - Virtual segment " + "addresses unsupported"); + + /* Just use the segments provided */ + segs = (struct bus_dma_segment *)data_ptr; + callback(callback_arg, segs, sglist_cnt, 0); + } else if ((ccb_h->flags & CAM_DATA_PHYS) != 0) { + struct bus_dma_segment seg; + + seg.ds_addr = (bus_addr_t)(vm_offset_t)data_ptr; + seg.ds_len = dxfer_len; + callback(callback_arg, &seg, 1, 0); + } else { + return bus_dmamap_load(dmat, + map, + data_ptr, + dxfer_len, + callback, + callback_arg, + /*flags*/0); + } + return (0); +} Index: dev/mly/mlyvar.h =================================================================== --- dev/mly/mlyvar.h (revision 243644) +++ dev/mly/mlyvar.h (working copy) @@ -126,6 +126,7 @@ struct mly_command { #define MLY_CMD_MAPPED (1<<3) /* command has had its data mapped */ #define MLY_CMD_DATAIN (1<<4) /* data moves controller->system */ #define MLY_CMD_DATAOUT (1<<5) /* data moves system->controller */ +#define MLY_CMD_CCB (1<<6) /* data is ccb. */ u_int16_t mc_status; /* command completion status */ u_int8_t mc_sense; /* sense data length */ int32_t mc_resid; /* I/O residual count */ Index: dev/mly/mly.c =================================================================== --- dev/mly/mly.c (revision 243644) +++ dev/mly/mly.c (working copy) @@ -1864,9 +1864,13 @@ mly_map_command(struct mly_command *mc) /* does the command have a data buffer? */ if (mc->mc_data != NULL) { - bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap, mc->mc_data, mc->mc_length, - mly_map_command_sg, mc, 0); - + if (mc->mc_flags & MLY_CMD_CCB) + bus_dmamap_load_ccb(sc->mly_buffer_dmat, mc->mc_datamap, + mc->mc_data, mly_map_command_sg, mc, 0); + else + bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap, + mc->mc_data, mc->mc_length, + mly_map_command_sg, mc, 0); if (mc->mc_flags & MLY_CMD_DATAIN) bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREREAD); if (mc->mc_flags & MLY_CMD_DATAOUT) @@ -2251,10 +2255,12 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_ } /* build the command */ - mc->mc_data = csio->data_ptr; + mc->mc_data = csio; mc->mc_length = csio->dxfer_len; mc->mc_complete = mly_cam_complete; mc->mc_private = csio; + mc->mc_flags |= MLY_CMD_CCB; + /* XXX This code doesn't set the data direction in mc_flags. */ /* save the bus number in the ccb for later recovery XXX should be a better way */ csio->ccb_h.sim_priv.entries[0].field = bus; Index: dev/hpt27xx/osm_bsd.c =================================================================== --- dev/hpt27xx/osm_bsd.c (revision 243644) +++ dev/hpt27xx/osm_bsd.c (working copy) @@ -660,6 +660,7 @@ static void hpt_scsi_io(PVBUS_EXT vbus_ext, union case 0x2f: case 0x8f: /* VERIFY_16 */ { + int error; pCmd = ldm_alloc_cmds(vbus, vd->cmds_per_request); if(!pCmd){ KdPrint(("Failed to allocate command!")); @@ -716,42 +717,20 @@ static void hpt_scsi_io(PVBUS_EXT vbus_ext, union pCmd->target = vd; pCmd->done = os_cmddone; pCmd->buildsgl = os_buildsgl; - pCmd->psg = ext->psg; - - 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->flags.physical_sg = 1; - - for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) { - pCmd->psg[idx].addr.bus = sgList[idx].ds_addr; - pCmd->psg[idx].size = sgList[idx].ds_len; - pCmd->psg[idx].eot = (idx==ccb->csio.sglist_cnt-1)? 1 : 0; - } - - ccb->ccb_h.timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); - ldm_queue_cmd(pCmd); - } - else { - int error; - pCmd->flags.physical_sg = 1; - error = bus_dmamap_load(vbus_ext->io_dmat, - ext->dma_map, - ccb->csio.data_ptr, ccb->csio.dxfer_len, - hpt_io_dmamap_callback, pCmd, + pCmd->flags.physical_sg = 1; + error = bus_dmamap_load_ccb(vbus_ext->io_dmat, + ext->dma_map, ccb, + hpt_io_dmamap_callback, pCmd, BUS_DMA_WAITOK ); - KdPrint(("bus_dmamap_load return %d", error)); - if (error && error!=EINPROGRESS) { - os_printk("bus_dmamap_load error %d", error); - cmdext_put(ext); - ldm_free_cmds(pCmd); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - xpt_done(ccb); - } + KdPrint(("bus_dmamap_load return %d", error)); + if (error && error!=EINPROGRESS) { + os_printk("bus_dmamap_load error %d", error); + cmdext_put(ext); + ldm_free_cmds(pCmd); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(ccb); } return; } Index: dev/isci/isci_io_request.c =================================================================== --- dev/isci/isci_io_request.c (revision 243644) +++ dev/isci/isci_io_request.c (working copy) @@ -714,7 +714,6 @@ void isci_io_request_execute_scsi_io(union ccb *ccb, struct ISCI_CONTROLLER *controller) { - struct ccb_scsiio *csio = &ccb->csio; target_id_t target_id = ccb->ccb_h.target_id; struct ISCI_REQUEST *request; struct ISCI_IO_REQUEST *io_request; @@ -757,8 +756,8 @@ isci_io_request_execute_scsi_io(union ccb *ccb, panic("Unexpected CAM_DATA_PHYS flag! flags = 0x%x\n", ccb->ccb_h.flags); - error = bus_dmamap_load(io_request->parent.dma_tag, - io_request->parent.dma_map, csio->data_ptr, csio->dxfer_len, + error = bus_dmamap_load_ccb(io_request->parent.dma_tag, + io_request->parent.dma_map, ccb, isci_io_request_construct, io_request, 0x0); /* A resource shortage from BUSDMA will be automatically Index: dev/twa/tw_osl_freebsd.c =================================================================== --- dev/twa/tw_osl_freebsd.c (revision 243644) +++ dev/twa/tw_osl_freebsd.c (working copy) @@ -1473,6 +1473,10 @@ tw_osli_map_request(struct tw_osli_req_context *re twa_map_load_data_callback, req, BUS_DMA_WAITOK); mtx_unlock_spin(sc->io_lock); + } else if (req->flags & TW_OSLI_REQ_FLAGS_CCB) { + error = bus_dmamap_load_ccb(sc->dma_tag, req->dma_map, + req->data, twa_map_load_data_callback, req, + BUS_DMA_WAITOK); } else { /* * There's only one CAM I/O thread running at a time. Index: dev/twa/tw_osl.h =================================================================== --- dev/twa/tw_osl.h (revision 243644) +++ dev/twa/tw_osl.h (working copy) @@ -72,6 +72,7 @@ #define TW_OSLI_REQ_FLAGS_PASSTHRU (1<<5) /* pass through request */ #define TW_OSLI_REQ_FLAGS_SLEEPING (1<<6) /* owner sleeping on this cmd */ #define TW_OSLI_REQ_FLAGS_FAILED (1<<7) /* bus_dmamap_load() failed */ +#define TW_OSLI_REQ_FLAGS_CCB (1<<8) /* req is ccb. */ #ifdef TW_OSL_DEBUG Index: dev/twa/tw_osl_cam.c =================================================================== --- dev/twa/tw_osl_cam.c (revision 243644) +++ dev/twa/tw_osl_cam.c (working copy) @@ -261,55 +261,23 @@ tw_osli_execute_scsi(struct tw_osli_req_context *r scsi_req->cdb = csio->cdb_io.cdb_bytes; scsi_req->cdb_len = csio->cdb_len; - if (!(ccb_h->flags & CAM_DATA_PHYS)) { - /* Virtual data addresses. Need to convert them... */ - tw_osli_dbg_dprintf(3, sc, - "XPT_SCSI_IO: Single virtual address!"); - if (!(ccb_h->flags & CAM_SCATTER_VALID)) { - if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) { - tw_osli_printf(sc, "size = %d", - TW_CL_SEVERITY_ERROR_STRING, - TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, - 0x2106, - "I/O size too big", - csio->dxfer_len); - ccb_h->status = CAM_REQ_TOO_BIG; - ccb_h->status &= ~CAM_SIM_QUEUED; - xpt_done(ccb); - return(1); - } - - if ((req->length = csio->dxfer_len)) { - req->data = csio->data_ptr; - scsi_req->sgl_entries = 1; - } - } else { - tw_osli_printf(sc, "", - TW_CL_SEVERITY_ERROR_STRING, - TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, - 0x2107, - "XPT_SCSI_IO: Got SGList"); - ccb_h->status = CAM_REQ_INVALID; - ccb_h->status &= ~CAM_SIM_QUEUED; - xpt_done(ccb); - return(1); - } - } else { - /* Data addresses are physical. */ - tw_osli_printf(sc, "", + if (csio->dxfer_len > TW_CL_MAX_IO_SIZE) { + tw_osli_printf(sc, "size = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, - 0x2108, - "XPT_SCSI_IO: Physical data addresses"); - ccb_h->status = CAM_REQ_INVALID; + 0x2106, + "I/O size too big", + csio->dxfer_len); + ccb_h->status = CAM_REQ_TOO_BIG; ccb_h->status &= ~CAM_SIM_QUEUED; xpt_done(ccb); return(1); } - + req->data = csio->data_ptr; + req->length = csio->dxfer_len; + req->flags |= TW_OSLI_REQ_FLAGS_CCB; req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000); - /* * twa_map_load_data_callback will fill in the SGL, * and submit the I/O. Index: dev/hptiop/hptiop.c =================================================================== --- dev/hptiop/hptiop.c (revision 243644) +++ dev/hptiop/hptiop.c (working copy) @@ -2358,6 +2358,7 @@ static void hptiop_action(struct cam_sim *sim, uni { struct hpt_iop_hba * hba = (struct hpt_iop_hba *)cam_sim_softc(sim); struct hpt_iop_srb * srb; + int error; switch (ccb->ccb_h.func_code) { @@ -2380,54 +2381,24 @@ static void hptiop_action(struct cam_sim *sim, uni } srb->ccb = ccb; + error = bus_dmamap_load_ccb(hba->io_dmat, + srb->dma_map, + ccb, + hptiop_post_scsi_command, + srb, + 0); - if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) - hptiop_post_scsi_command(srb, NULL, 0, 0); - else if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) { - int error; - - error = bus_dmamap_load(hba->io_dmat, - srb->dma_map, - ccb->csio.data_ptr, - ccb->csio.dxfer_len, - hptiop_post_scsi_command, - srb, 0); - - if (error && error != EINPROGRESS) { - device_printf(hba->pcidev, - "%d bus_dmamap_load error %d", - hba->pciunit, error); - xpt_freeze_simq(hba->sim, 1); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; -invalid: - hptiop_free_srb(hba, srb); - xpt_done(ccb); - goto scsi_done; - } - } - else { - device_printf(hba->pcidev, - "CAM_DATA_PHYS not supported"); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - goto invalid; - } + if (error && error != EINPROGRESS) { + device_printf(hba->pcidev, + "%d bus_dmamap_load error %d", + hba->pciunit, error); + xpt_freeze_simq(hba->sim, 1); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + hptiop_free_srb(hba, srb); + xpt_done(ccb); + goto scsi_done; } - else { - struct bus_dma_segment *segs; - if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0 || - (ccb->ccb_h.flags & CAM_DATA_PHYS) != 0) { - device_printf(hba->pcidev, "SCSI cmd failed"); - ccb->ccb_h.status=CAM_PROVIDE_FAIL; - goto invalid; - } - - segs = (struct bus_dma_segment *)ccb->csio.data_ptr; - hptiop_post_scsi_command(srb, segs, - ccb->csio.sglist_cnt, 0); - } - scsi_done: hptiop_unlock_adapter(hba); return; Index: dev/buslogic/bt.c =================================================================== --- dev/buslogic/bt.c (revision 243644) +++ dev/buslogic/bt.c (working copy) @@ -1158,6 +1158,7 @@ btaction(struct cam_sim *sim, union ccb *ccb) if (ccb->ccb_h.func_code == XPT_SCSI_IO) { struct ccb_scsiio *csio; struct ccb_hdr *ccbh; + int error; csio = &ccb->csio; ccbh = &csio->ccb_h; @@ -1205,67 +1206,21 @@ btaction(struct cam_sim *sim, union ccb *ccb) * If we have any data to send with this command, * map it into bus space. */ - /* Only use S/G if there is a transfer */ - 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( - bt->buffer_dmat, - bccb->dmamap, - csio->data_ptr, - csio->dxfer_len, - btexecuteccb, - bccb, - /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain - * ordering, freeze the - * controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(bt->sim, - 1); - csio->ccb_h.status |= - 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; - btexecuteccb(bccb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccbh->flags & CAM_DATA_PHYS) != 0) - panic("btaction - Physical " - "segment pointers " - "unsupported"); - - if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) - panic("btaction - Virtual " - "segment addresses " - "unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *) - csio->data_ptr; - btexecuteccb(bccb, segs, - csio->sglist_cnt, 0); - } - } else { - btexecuteccb(bccb, NULL, 0, 0); + error = bus_dmamap_load_ccb( + bt->buffer_dmat, + bccb->dmamap, + ccb, + btexecuteccb, + bccb, + /*flags*/0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the + * controller queue until our mapping is + * returned. + */ + xpt_freeze_simq(bt->sim, 1); + csio->ccb_h.status |= CAM_RELEASE_SIMQ; } } else { hccb->opcode = INITIATOR_BUS_DEV_RESET; Index: dev/siis/siis.c =================================================================== --- dev/siis/siis.c (revision 243644) +++ dev/siis/siis.c (working copy) @@ -994,23 +994,8 @@ siis_begin_transaction(device_t dev, union ccb *cc (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) ch->aslots |= (1 << slot->slot); slot->dma.nsegs = 0; - /* If request moves data, setup and load SG list */ - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - void *buf; - bus_size_t size; - - slot->state = SIIS_SLOT_LOADING; - if (ccb->ccb_h.func_code == XPT_ATA_IO) { - buf = ccb->ataio.data_ptr; - size = ccb->ataio.dxfer_len; - } else { - buf = ccb->csio.data_ptr; - size = ccb->csio.dxfer_len; - } - bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map, - buf, size, siis_dmasetprd, slot, 0); - } else - siis_execute_transaction(slot); + bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, + ccb, siis_dmasetprd, slot, 0); } /* Locked by busdma engine. */ Index: dev/sym/sym_hipd.c =================================================================== --- dev/sym/sym_hipd.c (revision 243644) +++ dev/sym/sym_hipd.c (working copy) @@ -7875,51 +7875,15 @@ sym_setup_data_and_start(hcb_p np, struct ccb_scsi return; } - if (!(ccb_h->flags & CAM_SCATTER_VALID)) { - /* Single buffer */ - if (!(ccb_h->flags & CAM_DATA_PHYS)) { - /* Buffer is virtual */ - cp->dmamapped = (dir == CAM_DIR_IN) ? - SYM_DMA_READ : SYM_DMA_WRITE; - retv = bus_dmamap_load(np->data_dmat, cp->dmamap, - csio->data_ptr, csio->dxfer_len, - sym_execute_ccb, cp, 0); - if (retv == EINPROGRESS) { - cp->host_status = HS_WAIT; - xpt_freeze_simq(np->sim, 1); - csio->ccb_h.status |= CAM_RELEASE_SIMQ; - } - } else { - /* Buffer is physical */ - struct bus_dma_segment seg; - - seg.ds_addr = (bus_addr_t) csio->data_ptr; - sym_execute_ccb(cp, &seg, 1, 0); - } - } else { - /* Scatter/gather list */ - struct bus_dma_segment *segs; - - if ((ccb_h->flags & CAM_SG_LIST_PHYS) != 0) { - /* The SG list pointer is physical */ - sym_set_cam_status(cp->cam_ccb, CAM_REQ_INVALID); - goto out_abort; - } - - if (!(ccb_h->flags & CAM_DATA_PHYS)) { - /* SG buffer pointers are virtual */ - sym_set_cam_status(cp->cam_ccb, CAM_REQ_INVALID); - goto out_abort; - } - - /* SG buffer pointers are physical */ - segs = (struct bus_dma_segment *)csio->data_ptr; - sym_execute_ccb(cp, segs, csio->sglist_cnt, 0); + cp->dmamapped = (dir == CAM_DIR_IN) ? SYM_DMA_READ : SYM_DMA_WRITE; + retv = bus_dmamap_load_ccb(np->data_dmat, cp->dmamap, + (union ccb *)csio, sym_execute_ccb, cp, 0); + if (retv == EINPROGRESS) { + cp->host_status = HS_WAIT; + xpt_freeze_simq(np->sim, 1); + csio->ccb_h.status |= CAM_RELEASE_SIMQ; } return; -out_abort: - sym_xpt_done(np, (union ccb *) csio, cp); - sym_free_ccb(np, cp); } /* Index: dev/mfi/mfivar.h =================================================================== --- dev/mfi/mfivar.h (revision 243644) +++ dev/mfi/mfivar.h (working copy) @@ -107,6 +107,7 @@ struct mfi_command { #define MFI_ON_MFIQ_BUSY (1<<7) #define MFI_ON_MFIQ_MASK ((1<<5)|(1<<6)|(1<<7)) #define MFI_CMD_SCSI (1<<8) +#define MFI_CMD_CCB (1<<9) uint8_t retry_for_fw_reset; void (* cm_complete)(struct mfi_command *cm); void *cm_private; Index: dev/mfi/mfi.c =================================================================== --- dev/mfi/mfi.c (revision 243644) +++ dev/mfi/mfi.c (working copy) @@ -2267,8 +2267,14 @@ mfi_mapcmd(struct mfi_softc *sc, struct mfi_comman if ((cm->cm_data != NULL) && (cm->cm_frame->header.cmd != MFI_CMD_STP )) { polled = (cm->cm_flags & MFI_CMD_POLLED) ? BUS_DMA_NOWAIT : 0; - error = bus_dmamap_load(sc->mfi_buffer_dmat, cm->cm_dmamap, - cm->cm_data, cm->cm_len, mfi_data_cb, cm, polled); + if (cm->cm_flags & MFI_CMD_CCB) + error = bus_dmamap_load_ccb(sc->mfi_buffer_dmat, + cm->cm_dmamap, cm->cm_data, mfi_data_cb, cm, + polled); + else + error = bus_dmamap_load(sc->mfi_buffer_dmat, + cm->cm_dmamap, cm->cm_data, cm->cm_len, + mfi_data_cb, cm, polled); if (error == EINPROGRESS) { sc->mfi_flags |= MFI_FLAGS_QFRZN; return (0); Index: dev/mfi/mfi_cam.c =================================================================== --- dev/mfi/mfi_cam.c (revision 243644) +++ dev/mfi/mfi_cam.c (working copy) @@ -379,14 +379,14 @@ mfip_start(void *data) cm->cm_private = ccb; cm->cm_sg = &pt->sgl; cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE; - cm->cm_data = csio->data_ptr; + cm->cm_data = ccb; cm->cm_len = csio->dxfer_len; switch (ccbh->flags & CAM_DIR_MASK) { case CAM_DIR_IN: - cm->cm_flags = MFI_CMD_DATAIN; + cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_CCB; break; case CAM_DIR_OUT: - cm->cm_flags = MFI_CMD_DATAOUT; + cm->cm_flags = MFI_CMD_DATAOUT | MFI_CMD_CCB; break; case CAM_DIR_NONE: default: Index: dev/firewire/sbp.c =================================================================== --- dev/firewire/sbp.c (revision 243644) +++ dev/firewire/sbp.c (working copy) @@ -2496,10 +2496,9 @@ printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb int s, error; s = splsoftvm(); - error = bus_dmamap_load(/*dma tag*/sbp->dmat, + error = bus_dmamap_load_ccb(/*dma tag*/sbp->dmat, /*dma map*/ocb->dmamap, - ccb->csio.data_ptr, - ccb->csio.dxfer_len, + ccb, sbp_execute_ocb, ocb, /*flags*/0); Index: dev/tws/tws.h =================================================================== --- dev/tws/tws.h (revision 243644) +++ dev/tws/tws.h (working copy) @@ -137,6 +137,7 @@ enum tws_req_flags { TWS_DIR_IN = 0x2, TWS_DIR_OUT = 0x4, TWS_DIR_NONE = 0x8, + TWS_DATA_CCB = 0x16, }; enum tws_intrs { Index: dev/tws/tws_cam.c =================================================================== --- dev/tws/tws_cam.c (revision 243644) +++ dev/tws/tws_cam.c (working copy) @@ -739,39 +739,8 @@ tws_execute_scsi(struct tws_softc *sc, union ccb * else bcopy(csio->cdb_io.cdb_bytes, cmd_pkt->cmd.pkt_a.cdb, csio->cdb_len); - if (!(ccb_h->flags & CAM_DATA_PHYS)) { - /* Virtual data addresses. Need to convert them... */ - if (!(ccb_h->flags & CAM_SCATTER_VALID)) { - if (csio->dxfer_len > TWS_MAX_IO_SIZE) { - TWS_TRACE(sc, "I/O is big", csio->dxfer_len, 0); - tws_release_request(req); - ccb_h->status = CAM_REQ_TOO_BIG; - xpt_done(ccb); - return(0); - } - - req->length = csio->dxfer_len; - if (req->length) { - req->data = csio->data_ptr; - /* there is 1 sgl_entrie */ - /* cmd_pkt->cmd.pkt_a.lun_h4__sgl_entries |= 1; */ - } - } else { - TWS_TRACE_DEBUG(sc, "got sglist", ccb_h->target_id, ccb_h->target_lun); - tws_release_request(req); - ccb_h->status = CAM_REQ_INVALID; - xpt_done(ccb); - return(0); - } - } else { - /* Data addresses are physical. */ - TWS_TRACE_DEBUG(sc, "Phy data addr", ccb_h->target_id, ccb_h->target_lun); - tws_release_request(req); - ccb_h->status = CAM_REQ_INVALID; - ccb_h->status &= ~CAM_SIM_QUEUED; - xpt_done(ccb); - return(0); - } + req->data = ccb; + req->flags |= TWS_DATA_CCB; /* save ccb ptr */ req->ccb_ptr = ccb; /* @@ -961,10 +930,16 @@ tws_map_request(struct tws_softc *sc, struct tws_r * Map the data buffer into bus space and build the SG list. */ mtx_lock(&sc->io_lock); - error = bus_dmamap_load(sc->data_tag, req->dma_map, - req->data, req->length, - tws_dmamap_data_load_cbfn, req, - my_flags); + if (req->flags & TWS_DATA_CCB) + error = bus_dmamap_load_ccb(sc->data_tag, req->dma_map, + req->data, + tws_dmamap_data_load_cbfn, req, + my_flags); + else + error = bus_dmamap_load(sc->data_tag, req->dma_map, + req->data, req->length, + tws_dmamap_data_load_cbfn, req, + my_flags); mtx_unlock(&sc->io_lock); if (error == EINPROGRESS) { Index: dev/dpt/dpt_scsi.c =================================================================== --- dev/dpt/dpt_scsi.c (revision 243644) +++ dev/dpt/dpt_scsi.c (working copy) @@ -910,56 +910,22 @@ dpt_action(struct cam_sim *sim, union ccb *ccb) */ /* Only use S/G if there is a transfer */ if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { + int error; + + error = bus_dmamap_load_ccb(dpt->buffer_dmat, + dccb->dmamap, + ccb, + dptexecuteccb, + dccb, /*flags*/0); + if (error == EINPROGRESS) { /* - * We've been given a pointer - * to a single buffer. + * So as to maintain ordering, + * freeze the controller queue + * until our mapping is + * returned. */ - if ((ccbh->flags & CAM_DATA_PHYS) == 0) { - int error; - - error = - bus_dmamap_load(dpt->buffer_dmat, - dccb->dmamap, - csio->data_ptr, - csio->dxfer_len, - dptexecuteccb, - dccb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(sim, 1); - dccb->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; - dptexecuteccb(dccb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccbh->flags & CAM_DATA_PHYS) != 0) - panic("dpt_action - Physical " - "segment pointers " - "unsupported"); - - if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) - panic("dpt_action - Virtual " - "segment addresses " - "unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)csio->data_ptr; - dptexecuteccb(dccb, segs, csio->sglist_cnt, 0); + xpt_freeze_simq(sim, 1); + dccb->state |= CAM_RELEASE_SIMQ; } } else { /* Index: dev/aic7xxx/aic7xxx_osm.c =================================================================== --- dev/aic7xxx/aic7xxx_osm.c (revision 243644) +++ dev/aic7xxx/aic7xxx_osm.c (working copy) @@ -1138,6 +1138,7 @@ ahc_setup_data(struct ahc_softc *ahc, struct cam_s { struct hardware_scb *hscb; struct ccb_hdr *ccb_h; + int error; hscb = scb->hscb; ccb_h = &csio->ccb_h; @@ -1179,64 +1180,21 @@ ahc_setup_data(struct ahc_softc *ahc, struct cam_s } } - /* 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 s; - int error; - - s = splsoftvm(); - error = bus_dmamap_load(ahc->buffer_dmat, - scb->dmamap, - csio->data_ptr, - csio->dxfer_len, - ahc_execute_scb, - scb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(sim, - /*count*/1); - scb->io_ctx->ccb_h.status |= - CAM_RELEASE_SIMQ; - } - splx(s); - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - if (csio->dxfer_len > AHC_MAXTRANSFER_SIZE) - panic("ahc_setup_data - Transfer size " - "larger than can device max"); - - seg.ds_addr = - (bus_addr_t)(vm_offset_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - ahc_execute_scb(scb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccb_h->flags & CAM_DATA_PHYS) != 0) - panic("ahc_setup_data - Physical segment " - "pointers unsupported"); - - if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) - panic("ahc_setup_data - Virtual segment " - "addresses unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)csio->data_ptr; - ahc_execute_scb(scb, segs, csio->sglist_cnt, 0); - } - } else { - ahc_execute_scb(scb, NULL, 0, 0); + error = bus_dmamap_load_ccb(ahc->buffer_dmat, + scb->dmamap, + (union ccb *)csio, + ahc_execute_scb, + scb, + 0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, + * freeze the controller queue + * until our mapping is + * returned. + */ + xpt_freeze_simq(sim, /*count*/1); + scb->io_ctx->ccb_h.status |= CAM_RELEASE_SIMQ; } } Index: dev/aic7xxx/aic79xx_osm.c =================================================================== --- dev/aic7xxx/aic79xx_osm.c (revision 243644) +++ dev/aic7xxx/aic79xx_osm.c (working copy) @@ -1071,6 +1071,7 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_s { struct hardware_scb *hscb; struct ccb_hdr *ccb_h; + int error; hscb = scb->hscb; ccb_h = &csio->ccb_h; @@ -1120,64 +1121,18 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_s } } - /* 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 s; - int error; - - s = splsoftvm(); - error = bus_dmamap_load(ahd->buffer_dmat, - scb->dmamap, - csio->data_ptr, - csio->dxfer_len, - ahd_execute_scb, - scb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(sim, - /*count*/1); - scb->io_ctx->ccb_h.status |= - CAM_RELEASE_SIMQ; - } - splx(s); - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - if (csio->dxfer_len > AHD_MAXTRANSFER_SIZE) - panic("ahd_setup_data - Transfer size " - "larger than can device max"); - - seg.ds_addr = - (bus_addr_t)(vm_offset_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - ahd_execute_scb(scb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccb_h->flags & CAM_DATA_PHYS) != 0) - panic("ahd_setup_data - Physical segment " - "pointers unsupported"); - - if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) - panic("ahd_setup_data - Virtual segment " - "addresses unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)csio->data_ptr; - ahd_execute_scb(scb, segs, csio->sglist_cnt, 0); - } - } else { - ahd_execute_scb(scb, NULL, 0, 0); + error = bus_dmamap_load_ccb(ahd->buffer_dmat, + scb->dmamap, + (union ccb *)csio, + ahd_execute_scb, + scb, /*flags*/0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the controller queue + * until our mapping is returned. + */ + xpt_freeze_simq(sim, /*count*/1); + scb->io_ctx->ccb_h.status |= CAM_RELEASE_SIMQ; } } Index: dev/ahci/ahci.c =================================================================== --- dev/ahci/ahci.c (revision 243644) +++ dev/ahci/ahci.c (working copy) @@ -1667,23 +1667,8 @@ ahci_begin_transaction(device_t dev, union ccb *cc (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) ch->aslots |= (1 << slot->slot); slot->dma.nsegs = 0; - /* If request moves data, setup and load SG list */ - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - void *buf; - bus_size_t size; - - slot->state = AHCI_SLOT_LOADING; - if (ccb->ccb_h.func_code == XPT_ATA_IO) { - buf = ccb->ataio.data_ptr; - size = ccb->ataio.dxfer_len; - } else { - buf = ccb->csio.data_ptr; - size = ccb->csio.dxfer_len; - } - bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map, - buf, size, ahci_dmasetprd, slot, 0); - } else - ahci_execute_transaction(slot); + bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, ccb, + ahci_dmasetprd, slot, 0); } /* Locked by busdma engine. */ Index: dev/mvs/mvs.c =================================================================== --- dev/mvs/mvs.c (revision 243644) +++ dev/mvs/mvs.c (working copy) @@ -873,6 +873,7 @@ mvs_legacy_intr(device_t dev, int poll) } if (ccb->ccb_h.func_code == XPT_ATA_IO) { /* ATA PIO */ ccb->ataio.res.status = status; + /* XXX PIO does not support alternate data_ptr formats. */ /* Are we moving data? */ if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { /* If data read command - get them. */ @@ -1260,19 +1261,9 @@ mvs_begin_transaction(device_t dev, union ccb *ccb mvs_set_edma_mode(dev, MVS_EDMA_OFF); } if (ch->numpslots == 0 || ch->basic_dma) { - void *buf; - bus_size_t size; - slot->state = MVS_SLOT_LOADING; - if (ccb->ccb_h.func_code == XPT_ATA_IO) { - buf = ccb->ataio.data_ptr; - size = ccb->ataio.dxfer_len; - } else { - buf = ccb->csio.data_ptr; - size = ccb->csio.dxfer_len; - } - bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map, - buf, size, mvs_dmasetprd, slot, 0); + bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, + ccb, mvs_dmasetprd, slot, 0); } else mvs_legacy_execute_transaction(slot); } Index: dev/aha/aha.c =================================================================== --- dev/aha/aha.c (revision 243644) +++ dev/aha/aha.c (working copy) @@ -778,6 +778,7 @@ ahaaction(struct cam_sim *sim, union ccb *ccb) if (ccb->ccb_h.func_code == XPT_SCSI_IO) { struct ccb_scsiio *csio; struct ccb_hdr *ccbh; + int error; csio = &ccb->csio; ccbh = &csio->ccb_h; @@ -811,67 +812,22 @@ ahaaction(struct cam_sim *sim, union ccb *ccb) * If we have any data to send with this command, * map it into bus space. */ - /* Only use S/G if there is a transfer */ - 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( - aha->buffer_dmat, - accb->dmamap, - csio->data_ptr, - csio->dxfer_len, - ahaexecuteccb, - accb, - /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain - * ordering, freeze the - * controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(aha->sim, - 1); - csio->ccb_h.status |= - 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; - ahaexecuteccb(accb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccbh->flags & CAM_DATA_PHYS) != 0) - panic("ahaaction - Physical " - "segment pointers " - "unsupported"); - - if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) - panic("ahaaction - Virtual " - "segment addresses " - "unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *) - csio->data_ptr; - ahaexecuteccb(accb, segs, - csio->sglist_cnt, 0); - } - } else { - ahaexecuteccb(accb, NULL, 0, 0); + error = bus_dmamap_load_ccb( + aha->buffer_dmat, + accb->dmamap, + ccb, + ahaexecuteccb, + accb, + /*flags*/0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the + * controller queue until our mapping is + * returned. + */ + xpt_freeze_simq(aha->sim, 1); + csio->ccb_h.status |= CAM_RELEASE_SIMQ; } } else { hccb->opcode = INITIATOR_BUS_DEV_RESET; Index: dev/ahb/ahb.c =================================================================== --- dev/ahb/ahb.c (revision 243644) +++ dev/ahb/ahb.c (working copy) @@ -1056,65 +1056,19 @@ ahbaction(struct cam_sim *sim, union ccb *ccb) hecb->cdb, hecb->cdb_len); } - /* - * If we have any data to send with this command, - * map it into bus space. - */ - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - /* - * We've been given a pointer - * to a single buffer. - */ - if ((ccb->ccb_h.flags & CAM_DATA_PHYS)==0) { - int error; - - error = bus_dmamap_load( - ahb->buffer_dmat, - ecb->dmamap, - ccb->csio.data_ptr, - ccb->csio.dxfer_len, - ahbexecuteecb, - ecb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(ahb->sim, 1); - ccb->ccb_h.status |= - CAM_RELEASE_SIMQ; - } - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - seg.ds_addr = - (bus_addr_t)ccb->csio.data_ptr; - seg.ds_len = ccb->csio.dxfer_len; - ahbexecuteecb(ecb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0) - panic("ahbaction - Physical segment " - "pointers unsupported"); - - if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) - panic("btaction - Virtual segment " - "addresses unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *) - ccb->csio.data_ptr; - ahbexecuteecb(ecb, segs, ccb->csio.sglist_cnt, - 0); - } - } else { - ahbexecuteecb(ecb, NULL, 0, 0); + error = bus_dmamap_load_ccb( + ahb->buffer_dmat, + ecb->dmamap, + ccb, + ahbexecuteecb, + ecb, /*flags*/0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the controller + * queue until our mapping is returned. + */ + xpt_freeze_simq(ahb->sim, 1); + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } break; } Index: dev/hptrr/hptrr_osm_bsd.c =================================================================== --- dev/hptrr/hptrr_osm_bsd.c (revision 243644) +++ dev/hptrr/hptrr_osm_bsd.c (working copy) @@ -667,6 +667,8 @@ static void hpt_scsi_io(PVBUS_EXT vbus_ext, union case 0x13: case 0x2f: { + int error; + pCmd = ldm_alloc_cmds(vbus, vd->cmds_per_request); if(!pCmd){ KdPrint(("Failed to allocate command!")); @@ -724,40 +726,20 @@ static void hpt_scsi_io(PVBUS_EXT vbus_ext, union pCmd->buildsgl = os_buildsgl; pCmd->psg = ext->psg; - - 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->flags.physical_sg = 1; - - for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) { - pCmd->psg[idx].addr.bus = sgList[idx].ds_addr; - pCmd->psg[idx].size = sgList[idx].ds_len; - pCmd->psg[idx].eot = (idx==ccb->csio.sglist_cnt-1)? 1 : 0; - } - - ccb->ccb_h.timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); - ldm_queue_cmd(pCmd); - } - else { - int error; - pCmd->flags.physical_sg = 1; - error = bus_dmamap_load(vbus_ext->io_dmat, - ext->dma_map, - ccb->csio.data_ptr, ccb->csio.dxfer_len, - hpt_io_dmamap_callback, pCmd, - BUS_DMA_WAITOK + pCmd->flags.physical_sg = 1; + error = bus_dmamap_load_ccb(vbus_ext->io_dmat, + ext->dma_map, + ccb, + hpt_io_dmamap_callback, pCmd, + BUS_DMA_WAITOK ); - KdPrint(("bus_dmamap_load return %d", error)); - if (error && error!=EINPROGRESS) { - os_printk("bus_dmamap_load error %d", error); - cmdext_put(ext); - ldm_free_cmds(pCmd); - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - xpt_done(ccb); - } + KdPrint(("bus_dmamap_load return %d", error)); + if (error && error!=EINPROGRESS) { + os_printk("bus_dmamap_load error %d", error); + cmdext_put(ext); + ldm_free_cmds(pCmd); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(ccb); } return; } Index: dev/ciss/cissvar.h =================================================================== --- dev/ciss/cissvar.h (revision 243644) +++ dev/ciss/cissvar.h (working copy) @@ -113,6 +113,7 @@ struct ciss_request #define CISS_REQ_DATAOUT (1<<3) /* data host->adapter */ #define CISS_REQ_DATAIN (1<<4) /* data adapter->host */ #define CISS_REQ_BUSY (1<<5) /* controller has req */ +#define CISS_REQ_CCB (1<<6) /* data is ccb */ void (* cr_complete)(struct ciss_request *); void *cr_private; Index: dev/ciss/ciss.c =================================================================== --- dev/ciss/ciss.c (revision 243644) +++ dev/ciss/ciss.c (working copy) @@ -2676,9 +2676,14 @@ ciss_map_request(struct ciss_request *cr) BUS_DMASYNC_PREWRITE); if (cr->cr_data != NULL) { - error = bus_dmamap_load(sc->ciss_buffer_dmat, cr->cr_datamap, - cr->cr_data, cr->cr_length, - ciss_request_map_helper, cr, 0); + if (cr->cr_flags & CISS_REQ_CCB) + error = bus_dmamap_load_ccb(sc->ciss_buffer_dmat, + cr->cr_datamap, cr->cr_data, + ciss_request_map_helper, cr, 0); + else + error = bus_dmamap_load(sc->ciss_buffer_dmat, cr->cr_datamap, + cr->cr_data, cr->cr_length, + ciss_request_map_helper, cr, 0); if (error != 0) return (error); } else { @@ -3082,7 +3087,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb * Build the command. */ cc = cr->cr_cc; - cr->cr_data = csio->data_ptr; + cr->cr_data = csio; cr->cr_length = csio->dxfer_len; cr->cr_complete = ciss_cam_complete; cr->cr_private = csio; @@ -3109,6 +3114,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb cr->cr_flags = 0; cc->cdb.direction = CISS_CDB_DIRECTION_NONE; } + cr->cr_flags |= CISS_REQ_CCB; cc->cdb.timeout = (csio->ccb_h.timeout / 1000) + 1; if (csio->ccb_h.flags & CAM_CDB_POINTER) { bcopy(csio->cdb_io.cdb_ptr, &cc->cdb.cdb[0], csio->cdb_len); Index: dev/mps/mps.c =================================================================== --- dev/mps/mps.c (revision 243644) +++ dev/mps/mps.c (working copy) @@ -2278,6 +2278,9 @@ mps_map_command(struct mps_softc *sc, struct mps_c if (cm->cm_flags & MPS_CM_FLAGS_USE_UIO) { error = bus_dmamap_load_uio(sc->buffer_dmat, cm->cm_dmamap, &cm->cm_uio, mps_data_cb2, cm, 0); + } else if (cm->cm_flags & MPS_CM_FLAGS_USE_CCB) { + error = bus_dmamap_load_ccb(sc->buffer_dmat, cm->cm_dmamap, + cm->cm_data, mps_data_cb, cm, 0); } else if ((cm->cm_data != NULL) && (cm->cm_length != 0)) { error = bus_dmamap_load(sc->buffer_dmat, cm->cm_dmamap, cm->cm_data, cm->cm_length, mps_data_cb, cm, 0); Index: dev/mps/mps_sas.c =================================================================== --- dev/mps/mps_sas.c (revision 243644) +++ dev/mps/mps_sas.c (working copy) @@ -1755,7 +1755,8 @@ mpssas_action_scsiio(struct mpssas_softc *sassc, u } } - cm->cm_data = csio->data_ptr; + cm->cm_data = ccb; + cm->cm_flags |= MPS_CM_FLAGS_USE_CCB; cm->cm_length = csio->dxfer_len; cm->cm_sge = &req->SGL; cm->cm_sglsize = (32 - 24) * 4; Index: dev/mps/mpsvar.h =================================================================== --- dev/mps/mpsvar.h (revision 243644) +++ dev/mps/mpsvar.h (working copy) @@ -231,6 +231,7 @@ struct mps_command { #define MPS_CM_FLAGS_SMP_PASS (1 << 8) #define MPS_CM_FLAGS_CHAIN_FAILED (1 << 9) #define MPS_CM_FLAGS_ERROR_MASK MPS_CM_FLAGS_CHAIN_FAILED +#define MPS_CM_FLAGS_USE_CCB (1 << 10) u_int cm_state; #define MPS_CM_STATE_FREE 0 #define MPS_CM_STATE_BUSY 1 Index: dev/mpt/mpt_cam.c =================================================================== --- dev/mpt/mpt_cam.c (revision 243644) +++ dev/mpt/mpt_cam.c (working copy) @@ -2062,6 +2062,7 @@ mpt_start(struct cam_sim *sim, union ccb *ccb) bus_dmamap_callback_t *cb; target_id_t tgt; int raid_passthru; + int error; /* Get the pointer for the physical addapter */ mpt = ccb->ccb_h.ccb_mpt_ptr; @@ -2206,64 +2207,15 @@ mpt_start(struct cam_sim *sim, union ccb *ccb) ccb->ccb_h.target_lun, req, req->serno); } - /* - * 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) { - /* - * Virtual address that needs to translated into - * one or more physical address ranges. - */ - int error; - int s = splsoftvm(); - error = bus_dmamap_load(mpt->buffer_dmat, - req->dmap, csio->data_ptr, csio->dxfer_len, - cb, req, 0); - splx(s); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(mpt->sim, 1); - ccbh->status |= CAM_RELEASE_SIMQ; - } - } else { - /* - * We have been given a pointer to single - * physical buffer. - */ - struct bus_dma_segment seg; - seg.ds_addr = - (bus_addr_t)(vm_offset_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - (*cb)(req, &seg, 1, 0); - } - } else { - /* - * We have been given a list of addresses. - * This case could be easily supported but they are not - * currently generated by the CAM subsystem so there - * is no point in wasting the time right now. - */ - struct bus_dma_segment *segs; - if ((ccbh->flags & CAM_SG_LIST_PHYS) == 0) { - (*cb)(req, NULL, 0, EFAULT); - } else { - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)csio->data_ptr; - (*cb)(req, segs, csio->sglist_cnt, 0); - } - } - } else { - (*cb)(req, NULL, 0, 0); + error = bus_dmamap_load_ccb(mpt->buffer_dmat, req->dmap, ccb, cb, + req, 0); + if (error == EINPROGRESS) { + /* + * So as to maintain ordering, freeze the controller queue + * until our mapping is returned. + */ + xpt_freeze_simq(mpt->sim, 1); + ccbh->status |= CAM_RELEASE_SIMQ; } } @@ -4458,6 +4410,7 @@ mpt_target_start_io(struct mpt_softc *mpt, union c bus_dmamap_callback_t *cb; PTR_MSG_TARGET_ASSIST_REQUEST ta; request_t *req; + int error; KASSERT((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE, ("dxfer_len %u but direction is NONE", csio->dxfer_len)); @@ -4544,44 +4497,11 @@ mpt_target_start_io(struct mpt_softc *mpt, union c "nxtstate=%d\n", csio, csio->tag_id, csio->dxfer_len, tgt->resid, ccb->ccb_h.flags, req, req->serno, tgt->state); - if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) { - int error; - int s = splsoftvm(); - error = bus_dmamap_load(mpt->buffer_dmat, - req->dmap, csio->data_ptr, csio->dxfer_len, - cb, req, 0); - splx(s); - if (error == EINPROGRESS) { - xpt_freeze_simq(mpt->sim, 1); - ccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } - } else { - /* - * We have been given a pointer to single - * physical buffer. - */ - struct bus_dma_segment seg; - seg.ds_addr = (bus_addr_t) - (vm_offset_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - (*cb)(req, &seg, 1, 0); - } - } else { - /* - * We have been given a list of addresses. - * This case could be easily supported but they are not - * currently generated by the CAM subsystem so there - * is no point in wasting the time right now. - */ - struct bus_dma_segment *sgs; - if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) { - (*cb)(req, NULL, 0, EFAULT); - } else { - /* Just use the segments provided */ - sgs = (struct bus_dma_segment *)csio->data_ptr; - (*cb)(req, sgs, csio->sglist_cnt, 0); - } + error = bus_dmamap_load_ccb(mpt->buffer_dmat, req->dmap, ccb, + cb, req, 0); + if (error == EINPROGRESS) { + xpt_freeze_simq(mpt->sim, 1); + ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } } else { uint8_t *sp = NULL, sense[MPT_SENSE_SIZE]; Index: dev/trm/trm.c =================================================================== --- dev/trm/trm.c (revision 243644) +++ dev/trm/trm.c (working copy) @@ -559,6 +559,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb) PDCB pDCB = NULL; PSRB pSRB; struct ccb_scsiio *pcsio; + int error; pcsio = &pccb->csio; TRM_DPRINTF(" XPT_SCSI_IO \n"); @@ -614,71 +615,18 @@ trm_action(struct cam_sim *psim, union ccb *pccb) } else bcopy(pcsio->cdb_io.cdb_bytes, pSRB->CmdBlock, pcsio->cdb_len); - if ((pccb->ccb_h.flags & CAM_DIR_MASK) - != CAM_DIR_NONE) { - if ((pccb->ccb_h.flags & - CAM_SCATTER_VALID) == 0) { - if ((pccb->ccb_h.flags - & CAM_DATA_PHYS) == 0) { - int vmflags; - int error; - - vmflags = splsoftvm(); - error = bus_dmamap_load( - pACB->buffer_dmat, + error = bus_dmamap_load_ccb(pACB->buffer_dmat, pSRB->dmamap, - pcsio->data_ptr, - pcsio->dxfer_len, + pccb, trm_ExecuteSRB, pSRB, 0); - if (error == EINPROGRESS) { - xpt_freeze_simq( - pACB->psim, - 1); - pccb->ccb_h.status |= - CAM_RELEASE_SIMQ; - } - splx(vmflags); - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - seg.ds_addr = - (bus_addr_t)pcsio->data_ptr; - seg.ds_len = pcsio->dxfer_len; - trm_ExecuteSRB(pSRB, &seg, 1, - 0); - } - } else { - /* CAM_SCATTER_VALID */ - struct bus_dma_segment *segs; - - if ((pccb->ccb_h.flags & - CAM_SG_LIST_PHYS) == 0 || - (pccb->ccb_h.flags - & CAM_DATA_PHYS) != 0) { - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; - pccb->ccb_h.status = - CAM_PROVIDE_FAIL; - xpt_done(pccb); - splx(actionflags); - return; - } - - /* cam SG list is physical, - * cam data is virtual - */ - segs = (struct bus_dma_segment *) - pcsio->data_ptr; - trm_ExecuteSRB(pSRB, segs, - pcsio->sglist_cnt, 1); - } /* CAM_SCATTER_VALID */ - } else - trm_ExecuteSRB(pSRB, NULL, 0, 0); - } + if (error == EINPROGRESS) { + xpt_freeze_simq(pACB->psim, 1); + pccb->ccb_h.status |= CAM_RELEASE_SIMQ; + } break; + } case XPT_GDEV_TYPE: TRM_DPRINTF(" XPT_GDEV_TYPE \n"); pccb->ccb_h.status = CAM_REQ_INVALID; Index: dev/iir/iir.c =================================================================== --- dev/iir/iir.c (revision 243644) +++ dev/iir/iir.c (working copy) @@ -794,6 +794,7 @@ gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, { struct gdt_ccb *gccb; struct cam_sim *sim; + int error; GDT_DPRINTF(GDT_D_CMD, ("gdt_raw_cmd(%p, %p)\n", gdt, ccb)); @@ -844,51 +845,14 @@ gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, gdt_enc32(gccb->gc_cmd + GDT_CMD_UNION + GDT_RAW_SENSE_DATA, gccb->gc_scratch_busbase); - /* - * If we have any data to send with this command, - * map it into bus space. - */ - /* Only use S/G if there is a transfer */ - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - if ((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0) { - int s; - int error; - - /* vorher unlock von splcam() ??? */ - s = splsoftvm(); - error = - bus_dmamap_load(gdt->sc_buffer_dmat, - gccb->gc_dmamap, - ccb->csio.data_ptr, - ccb->csio.dxfer_len, - gdtexecuteccb, - gccb, /*flags*/0); - if (error == EINPROGRESS) { - xpt_freeze_simq(sim, 1); - gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } - splx(s); - } else { - panic("iir: CAM_DATA_PHYS not supported"); - } - } else { - struct bus_dma_segment *segs; - - if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0) - panic("iir%d: iir_action - Physical " - "segment pointers unsupported", gdt->sc_hanum); - - if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS)==0) - panic("iir%d: iir_action - Virtual " - "segment addresses unsupported", gdt->sc_hanum); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *)ccb->csio.data_ptr; - gdtexecuteccb(gccb, segs, ccb->csio.sglist_cnt, 0); - } - } else { - gdtexecuteccb(gccb, NULL, 0, 0); + error = bus_dmamap_load_ccb(gdt->sc_buffer_dmat, + gccb->gc_dmamap, + ccb, + gdtexecuteccb, + gccb, /*flags*/0); + if (error == EINPROGRESS) { + xpt_freeze_simq(sim, 1); + gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } *lock = splcam(); Index: dev/advansys/advansys.c =================================================================== --- dev/advansys/advansys.c (revision 243644) +++ dev/advansys/advansys.c (working copy) @@ -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; } Index: dev/advansys/adwcam.c =================================================================== --- dev/advansys/adwcam.c (revision 243644) +++ dev/advansys/adwcam.c (working copy) @@ -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; } Index: dev/hptmv/entry.c =================================================================== --- dev/hptmv/entry.c (revision 243644) +++ dev/hptmv/entry.c (working copy) @@ -2883,6 +2883,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 +2961,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; } Index: dev/arcmsr/arcmsr.c =================================================================== --- dev/arcmsr/arcmsr.c (revision 243644) +++ dev/arcmsr/arcmsr.c (working copy) @@ -2099,6 +2099,7 @@ static int arcmsr_iop_message_xfer(struct AdapterC (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[7] << 8 | (u_int32_t ) pccb->csio.cdb_io.cdb_bytes[8]; /* 4 bytes: Areca io control code */ + /* XXX Does not handle alternate data formats. */ if((pccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { buffer = pccb->csio.data_ptr; transfer_len = pccb->csio.dxfer_len; @@ -2489,6 +2490,7 @@ static void arcmsr_action(struct cam_sim * psim, u case XPT_SCSI_IO: { struct CommandControlBlock *srb; int target=pccb->ccb_h.target_id; + int error; if(target == 16) { /* virtual device for iop message transfer */ @@ -2503,52 +2505,13 @@ static void arcmsr_action(struct cam_sim * psim, u pccb->ccb_h.arcmsr_ccbsrb_ptr=srb; pccb->ccb_h.arcmsr_ccbacb_ptr=acb; srb->pccb=pccb; - if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if(!(pccb->ccb_h.flags & CAM_SCATTER_VALID)) { - /* Single buffer */ - if(!(pccb->ccb_h.flags & CAM_DATA_PHYS)) { - /* Buffer is virtual */ - u_int32_t error, s; - - s=splsoftvm(); - error = bus_dmamap_load(acb->dm_segs_dmat - , srb->dm_segs_dmamap - , pccb->csio.data_ptr - , pccb->csio.dxfer_len - , arcmsr_execute_srb, srb, /*flags*/0); - if(error == EINPROGRESS) { - xpt_freeze_simq(acb->psim, 1); - pccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } - splx(s); - } - else { /* Buffer is physical */ -#ifdef PAE - panic("arcmsr: CAM_DATA_PHYS not supported"); -#else - struct bus_dma_segment seg; - - seg.ds_addr = (bus_addr_t)pccb->csio.data_ptr; - seg.ds_len = pccb->csio.dxfer_len; - arcmsr_execute_srb(srb, &seg, 1, 0); -#endif - } - } else { - /* Scatter/gather list */ - struct bus_dma_segment *segs; - - if((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0 - || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0) { - pccb->ccb_h.status |= CAM_PROVIDE_FAIL; - xpt_done(pccb); - free(srb, M_DEVBUF); - return; - } - segs=(struct bus_dma_segment *)pccb->csio.data_ptr; - arcmsr_execute_srb(srb, segs, pccb->csio.sglist_cnt, 0); - } - } else { - arcmsr_execute_srb(srb, NULL, 0, 0); + error = bus_dmamap_load_ccb(acb->dm_segs_dmat + , srb->dm_segs_dmamap + , pccb + , arcmsr_execute_srb, srb, /*flags*/0); + if(error == EINPROGRESS) { + xpt_freeze_simq(acb->psim, 1); + pccb->ccb_h.status |= CAM_RELEASE_SIMQ; } break; } Index: dev/isp/isp_pci.c =================================================================== --- dev/isp/isp_pci.c (revision 243644) +++ dev/isp/isp_pci.c (working copy) @@ -1922,6 +1922,7 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsii mush_t mush, *mp; void (*eptr)(void *, bus_dma_segment_t *, int, int); void (*eptr2)(void *, bus_dma_segment_t *, int, bus_size_t, int); + int error; mp = &mush; mp->isp = isp; @@ -1942,70 +1943,17 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsii } - if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE || (csio->dxfer_len == 0)) { - (*eptr)(mp, NULL, 0, 0); - } else if ((csio->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - if ((csio->ccb_h.flags & CAM_DATA_PHYS) == 0) { - int error; - error = bus_dmamap_load(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, csio->data_ptr, csio->dxfer_len, eptr, mp, 0); -#if 0 - xpt_print(csio->ccb_h.path, "%s: bus_dmamap_load " "ptr %p len %d returned %d\n", __func__, csio->data_ptr, csio->dxfer_len, error); -#endif - - if (error == EINPROGRESS) { - bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); - mp->error = EINVAL; - isp_prt(isp, ISP_LOGERR, "deferred dma allocation not supported"); - } else if (error && mp->error == 0) { + error = bus_dmamap_load_ccb(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, + (union ccb *)csio, eptr, mp, 0); + if (error == EINPROGRESS) { + bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); + mp->error = EINVAL; + isp_prt(isp, ISP_LOGERR, "deferred dma allocation not supported"); + } else if (error && mp->error == 0) { #ifdef DIAGNOSTIC - isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); + isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); #endif - mp->error = error; - } - } else { - /* Pointer to physical buffer */ - struct bus_dma_segment seg; - seg.ds_addr = (bus_addr_t)(vm_offset_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - (*eptr)(mp, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((csio->ccb_h.flags & CAM_DATA_PHYS) != 0) { - isp_prt(isp, ISP_LOGERR, "Physical segment pointers unsupported"); - mp->error = EINVAL; - } else if ((csio->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) { - struct uio sguio; - int error; - - /* - * We're taking advantage of the fact that - * the pointer/length sizes and layout of the iovec - * structure are the same as the bus_dma_segment - * structure. This might be a little dangerous, - * but only if they change the structures, which - * seems unlikely. - */ - KASSERT((sizeof (sguio.uio_iov) == sizeof (csio->data_ptr) && - sizeof (sguio.uio_iovcnt) >= sizeof (csio->sglist_cnt) && - sizeof (sguio.uio_resid) >= sizeof (csio->dxfer_len)), ("Ken's assumption failed")); - sguio.uio_iov = (struct iovec *)csio->data_ptr; - sguio.uio_iovcnt = csio->sglist_cnt; - sguio.uio_resid = csio->dxfer_len; - sguio.uio_segflg = UIO_SYSSPACE; - - error = bus_dmamap_load_uio(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, &sguio, eptr2, mp, 0); - - if (error != 0 && mp->error == 0) { - isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); - mp->error = error; - } - } else { - /* Just use the segments provided */ - segs = (struct bus_dma_segment *) csio->data_ptr; - (*eptr)(mp, segs, csio->sglist_cnt, 0); - } + mp->error = error; } if (mp->error) { int retval = CMD_COMPLETE; Index: dev/isp/isp_sbus.c =================================================================== --- dev/isp/isp_sbus.c (revision 243644) +++ dev/isp/isp_sbus.c (working copy) @@ -635,6 +635,7 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsi { mush_t mush, *mp; void (*eptr)(void *, bus_dma_segment_t *, int, int); + int error; mp = &mush; mp->isp = isp; @@ -645,47 +646,18 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsi eptr = dma2; - if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE || (csio->dxfer_len == 0)) { - (*eptr)(mp, NULL, 0, 0); - } else if ((csio->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - if ((csio->ccb_h.flags & CAM_DATA_PHYS) == 0) { - int error; - error = bus_dmamap_load(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, csio->data_ptr, csio->dxfer_len, eptr, mp, 0); -#if 0 - xpt_print(csio->ccb_h.path, "%s: bus_dmamap_load " "ptr %p len %d returned %d\n", __func__, csio->data_ptr, csio->dxfer_len, error); -#endif - - if (error == EINPROGRESS) { - bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); - mp->error = EINVAL; - isp_prt(isp, ISP_LOGERR, "deferred dma allocation not supported"); - } else if (error && mp->error == 0) { + error = bus_dmamap_load_ccb(isp->isp_osinfo.dmat, + PISP_PCMD(csio)->dmap, (union ccb *)csio, eptr, mp, 0); + if (error == EINPROGRESS) { + bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); + mp->error = EINVAL; + isp_prt(isp, ISP_LOGERR, + "deferred dma allocation not supported"); + } else if (error && mp->error == 0) { #ifdef DIAGNOSTIC - isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); + isp_prt(isp, ISP_LOGERR, "error %d in dma mapping code", error); #endif - mp->error = error; - } - } else { - /* Pointer to physical buffer */ - struct bus_dma_segment seg; - seg.ds_addr = (bus_addr_t)(vm_offset_t)csio->data_ptr; - seg.ds_len = csio->dxfer_len; - (*eptr)(mp, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((csio->ccb_h.flags & CAM_DATA_PHYS) != 0) { - isp_prt(isp, ISP_LOGERR, "Physical segment pointers unsupported"); - mp->error = EINVAL; - } else if ((csio->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) { - isp_prt(isp, ISP_LOGERR, "Physical SG/LIST Phys segment pointers unsupported"); - mp->error = EINVAL; - } else { - /* Just use the segments provided */ - segs = (struct bus_dma_segment *) csio->data_ptr; - (*eptr)(mp, segs, csio->sglist_cnt, 0); - } + mp->error = error; } if (mp->error) { int retval = CMD_COMPLETE; Index: dev/ata/ata-dma.c =================================================================== --- dev/ata/ata-dma.c (revision 243644) +++ dev/ata/ata-dma.c (working copy) @@ -304,10 +304,15 @@ ata_dmaload(struct ata_request *request, void *add else dspa.dmatab = request->dma->sg; - if ((error = bus_dmamap_load(request->dma->data_tag, request->dma->data_map, - request->data, request->bytecount, - ch->dma.setprd, &dspa, BUS_DMA_NOWAIT)) || - (error = dspa.error)) { + if (request->ccb) + error = bus_dmamap_load_ccb(request->dma->data_tag, + request->dma->data_map, request->ccb, + ch->dma.setprd, &dspa, BUS_DMA_NOWAIT); + else + error = bus_dmamap_load(request->dma->data_tag, request->dma->data_map, + request->data, request->bytecount, + ch->dma.setprd, &dspa, BUS_DMA_NOWAIT); + if (error || (error = dspa.error)) { device_printf(request->parent, "FAILURE - load data\n"); goto error; } Index: sys/bus_dma.h =================================================================== --- sys/bus_dma.h (revision 243644) +++ sys/bus_dma.h (working copy) @@ -112,6 +112,7 @@ /* Forwards needed by prototypes below. */ struct mbuf; struct uio; +union ccb; /* * Operations performed by bus_dmamap_sync(). @@ -253,6 +254,13 @@ int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dm int flags); /* + * Like bus_dmamap_load but for cam control blocks. + */ +int bus_dmamap_load_ccb(bus_dma_tag_t dmat, bus_dmamap_t map, union ccb *ccb, + bus_dmamap_callback_t *callback, void *callback_arg, + int flags); + +/* * Perform a synchronization operation on the given map. */ void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); Index: sys/_bitset.h =================================================================== Index: sys/_numaset.h ===================================================================