summaryrefslogtreecommitdiffstats
path: root/sys/dev/ciss
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2003-08-12 17:55:53 +0000
committerps <ps@FreeBSD.org>2003-08-12 17:55:53 +0000
commit4e0802ee6605a319fd2ddcbc847b184f1b5e9680 (patch)
treeded93615eb6603f5523b6343d573e868e47b8349 /sys/dev/ciss
parenta131a4bfe3692af86587ae0c330c46139f58509a (diff)
downloadFreeBSD-src-4e0802ee6605a319fd2ddcbc847b184f1b5e9680.zip
FreeBSD-src-4e0802ee6605a319fd2ddcbc847b184f1b5e9680.tar.gz
Support EINPROGRESS and properly deal with 64bit physical addressing.
Diffstat (limited to 'sys/dev/ciss')
-rw-r--r--sys/dev/ciss/ciss.c83
1 files changed, 59 insertions, 24 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index c20ee6b..bdfabfe 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -594,10 +594,11 @@ ciss_init_pci(struct ciss_softc *sc)
*/
if (bus_dma_tag_create(NULL, /* parent */
1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- MAXBSIZE, CISS_COMMAND_SG_LENGTH, /* maxsize, nsegments */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
+ CISS_COMMAND_SG_LENGTH, /* nsegments */
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
NULL, NULL, /* lockfunc, lockarg */
@@ -740,14 +741,14 @@ ciss_init_requests(struct ciss_softc *sc)
*/
if (bus_dma_tag_create(sc->ciss_parent_dmat, /* parent */
1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
CISS_COMMAND_ALLOC_SIZE *
sc->ciss_max_requests, 1, /* maxsize, nsegments */
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- busdma_lock_mutex, &Giant, /* lockfunc, lockarg */
+ BUS_DMA_ALLOCNOW, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
&sc->ciss_command_dmat)) {
ciss_printf(sc, "can't allocate command DMA tag\n");
return(ENOMEM);
@@ -1433,12 +1434,6 @@ ciss_start(struct ciss_request *cr)
ciss_print_request(cr);
#endif
- /*
- * Post the command to the adapter.
- */
- ciss_enqueue_busy(cr);
- CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr));
-
return(0);
}
@@ -1788,6 +1783,7 @@ ciss_get_request(struct ciss_softc *sc, struct ciss_request **crp)
cr->cr_data = NULL;
cr->cr_flags = 0;
cr->cr_complete = NULL;
+ cr->cr_private = NULL;
ciss_preen_command(cr);
*crp = cr;
@@ -2004,24 +2000,35 @@ static int
ciss_map_request(struct ciss_request *cr)
{
struct ciss_softc *sc;
+ int error = 0;
debug_called(2);
sc = cr->cr_sc;
/* check that mapping is necessary */
- if ((cr->cr_flags & CISS_REQ_MAPPED) || (cr->cr_data == NULL))
+ if (cr->cr_flags & CISS_REQ_MAPPED)
return(0);
-
- bus_dmamap_load(sc->ciss_buffer_dmat, cr->cr_datamap, cr->cr_data, cr->cr_length,
- ciss_request_map_helper, CISS_FIND_COMMAND(cr), 0);
-
- if (cr->cr_flags & CISS_REQ_DATAIN)
- bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREREAD);
- if (cr->cr_flags & CISS_REQ_DATAOUT)
- bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREWRITE);
cr->cr_flags |= CISS_REQ_MAPPED;
+
+ bus_dmamap_sync(sc->ciss_command_dmat, sc->ciss_command_map,
+ 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 (error != 0)
+ return (error);
+ } else {
+ /*
+ * Post the command to the adapter.
+ */
+ ciss_enqueue_busy(cr);
+ CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr));
+ }
+
return(0);
}
@@ -2029,11 +2036,16 @@ static void
ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
struct ciss_command *cc;
+ struct ciss_request *cr;
+ struct ciss_softc *sc;
int i;
debug_called(2);
- cc = (struct ciss_command *)arg;
+ cr = (struct ciss_request *)arg;
+ sc = cr->cr_sc;
+ cc = CISS_FIND_COMMAND(cr);
+
for (i = 0; i < nseg; i++) {
cc->sg[i].address = segs[i].ds_addr;
cc->sg[i].length = segs[i].ds_len;
@@ -2042,6 +2054,17 @@ ciss_request_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
/* we leave the s/g table entirely within the command */
cc->header.sg_in_list = nseg;
cc->header.sg_total = nseg;
+
+ if (cr->cr_flags & CISS_REQ_DATAIN)
+ bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREREAD);
+ if (cr->cr_flags & CISS_REQ_DATAOUT)
+ bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_PREWRITE);
+
+ /*
+ * Post the command to the adapter.
+ */
+ ciss_enqueue_busy(cr);
+ CISS_TL_SIMPLE_POST_CMD(cr->cr_sc, CISS_FIND_COMMANDPHYS(cr));
}
/************************************************************************
@@ -2057,8 +2080,14 @@ ciss_unmap_request(struct ciss_request *cr)
sc = cr->cr_sc;
/* check that unmapping is necessary */
- if (!(cr->cr_flags & CISS_REQ_MAPPED) || (cr->cr_data == NULL))
+ if ((cr->cr_flags & CISS_REQ_MAPPED) == 0)
return;
+
+ bus_dmamap_sync(sc->ciss_command_dmat, sc->ciss_command_map,
+ BUS_DMASYNC_POSTWRITE);
+
+ if (cr->cr_data == NULL)
+ goto out;
if (cr->cr_flags & CISS_REQ_DATAIN)
bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_POSTREAD);
@@ -2066,6 +2095,7 @@ ciss_unmap_request(struct ciss_request *cr)
bus_dmamap_sync(sc->ciss_buffer_dmat, cr->cr_datamap, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->ciss_buffer_dmat, cr->cr_datamap);
+out:
cr->cr_flags &= ~CISS_REQ_MAPPED;
}
@@ -2373,8 +2403,13 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
*/
if ((error = ciss_start(cr)) != 0) {
xpt_freeze_simq(sc->ciss_cam_sim, 1);
- csio->ccb_h.status |= CAM_REQUEUE_REQ;
- ciss_release_request(cr);
+ if (error == EINPROGRESS) {
+ csio->ccb_h.status |= CAM_RELEASE_SIMQ;
+ error = 0;
+ } else {
+ csio->ccb_h.status |= CAM_REQUEUE_REQ;
+ ciss_release_request(cr);
+ }
return(error);
}
OpenPOWER on IntegriCloud