From bd7f0fa0bb4b7b0f87227e0c4d49a4bd9b113cf0 Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 12 Feb 2013 16:57:20 +0000 Subject: 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 ) --- sys/dev/aic7xxx/aic79xx_osm.c | 71 ++++++++--------------------------------- sys/dev/aic7xxx/aic7xxx_osm.c | 74 ++++++++++--------------------------------- 2 files changed, 29 insertions(+), 116 deletions(-) (limited to 'sys/dev/aic7xxx') 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; } } -- cgit v1.1