summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-02-12 16:57:20 +0000
committerkib <kib@FreeBSD.org>2013-02-12 16:57:20 +0000
commitbd7f0fa0bb4b7b0f87227e0c4d49a4bd9b113cf0 (patch)
treee550f2c754f1edf951a8b93963ebcfc4fa0d20ce /sys/dev/isp
parente0a463e76c719f11788ec107b5aa3e2da4e57c0b (diff)
downloadFreeBSD-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/isp')
-rw-r--r--sys/dev/isp/isp_pci.c72
-rw-r--r--sys/dev/isp/isp_sbus.c50
2 files changed, 21 insertions, 101 deletions
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index e0260d4..795f432 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -1922,6 +1922,7 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, void *ff)
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_scsiio *csio, void *ff)
}
- 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;
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index 0b4f63f..9afcc8e 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -635,6 +635,7 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, void *ff)
{
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_scsiio *csio, void *ff)
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;
OpenPOWER on IntegriCloud