diff options
author | ps <ps@FreeBSD.org> | 2003-08-12 17:55:53 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2003-08-12 17:55:53 +0000 |
commit | 4e0802ee6605a319fd2ddcbc847b184f1b5e9680 (patch) | |
tree | ded93615eb6603f5523b6343d573e868e47b8349 /sys/dev/ciss | |
parent | a131a4bfe3692af86587ae0c330c46139f58509a (diff) | |
download | FreeBSD-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.c | 83 |
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); } |