Support EINPROGRESS and properly deal with 64bit physical addressing.

This commit is contained in:
ps 2003-08-12 17:55:53 +00:00
parent a131a4bfe3
commit 4e0802ee66

View File

@ -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);
}