summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
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/aic7xxx
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/aic7xxx')
-rw-r--r--sys/dev/aic7xxx/aic79xx_osm.c71
-rw-r--r--sys/dev/aic7xxx/aic7xxx_osm.c74
2 files changed, 29 insertions, 116 deletions
diff --git a/sys/dev/aic7xxx/aic79xx_osm.c b/sys/dev/aic7xxx/aic79xx_osm.c
index 3f7b818..6ef0f92 100644
--- a/sys/dev/aic7xxx/aic79xx_osm.c
+++ b/sys/dev/aic7xxx/aic79xx_osm.c
@@ -1071,6 +1071,7 @@ ahd_setup_data(struct ahd_softc *ahd, struct cam_sim *sim,
{
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_sim *sim,
}
}
- /* 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;
}
}
diff --git a/sys/dev/aic7xxx/aic7xxx_osm.c b/sys/dev/aic7xxx/aic7xxx_osm.c
index 281b00e..a51177c9 100644
--- a/sys/dev/aic7xxx/aic7xxx_osm.c
+++ b/sys/dev/aic7xxx/aic7xxx_osm.c
@@ -1138,6 +1138,7 @@ ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
{
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_sim *sim,
}
}
- /* 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;
}
}
OpenPOWER on IntegriCloud