diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2004-03-17 00:47:07 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2004-03-17 00:47:07 +0000 |
commit | 6623b2526615353b1e4394ba4c58eeacac5c4883 (patch) | |
tree | 7cb3a3670bc9a0a8ae9063508b2906a8f8d9099a /sys/dev/ic/mpt_openbsd.c | |
parent | ae7a8d837fc223764b4d9a9380aa80edfbc0d151 (diff) |
Reduce openings to avoid both usual 'EIO' problems in interrupt mode
and apparently some mpt specific problems. With this change installs
to my U320 disk work, and work *fast*.
Try to return XS_TIMEOUT for timeouts rather than XS_NOERROR.
Load on-board firmware. Currently v1.01.61 seems to work well, but
the latest 1.03.23 does not.
With these changes Marco and Milos torture chambers now report no
problems and we should be set for 3.5.
Mostly from Milos Urbanek and Marco Peereboom.
Diffstat (limited to 'sys/dev/ic/mpt_openbsd.c')
-rw-r--r-- | sys/dev/ic/mpt_openbsd.c | 88 |
1 files changed, 76 insertions, 12 deletions
diff --git a/sys/dev/ic/mpt_openbsd.c b/sys/dev/ic/mpt_openbsd.c index 8387d88e489..4bf4fd0e394 100644 --- a/sys/dev/ic/mpt_openbsd.c +++ b/sys/dev/ic/mpt_openbsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpt_openbsd.c,v 1.5 2004/03/15 09:53:33 deraadt Exp $ */ +/* $OpenBSD: mpt_openbsd.c,v 1.6 2004/03/17 00:47:06 krw Exp $ */ /* $NetBSD: mpt_netbsd.c,v 1.7 2003/07/14 15:47:11 lukem Exp $ */ /* @@ -388,13 +388,9 @@ void mpt_attach(mpt_softc_t *mpt) { struct scsi_link *lptr = &mpt->sc_link; - int maxq; mpt->bus = 0; /* XXX ?? */ - maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS(mpt)) ? - mpt->mpt_global_credits : MPT_MAX_REQUESTS(mpt); - /* Fill in the scsi_adapter. */ mpt->sc_adapter.scsi_cmd = mpt_action; mpt->sc_adapter.scsi_minphys = mpt_minphys; @@ -403,16 +399,17 @@ mpt_attach(mpt_softc_t *mpt) lptr->adapter_softc = mpt; lptr->device = &mpt_dev; lptr->adapter = &mpt->sc_adapter; - lptr->openings = maxq; lptr->flags = 0; lptr->luns = 8; if (mpt->is_fc) { lptr->adapter_buswidth = 256; lptr->adapter_target = 256; + lptr->openings = 4; /* 1024 requests / 256 targets = 4 each */ } else { lptr->adapter_buswidth = 16; lptr->adapter_target = mpt->mpt_ini_id; + lptr->openings = 16; /* 1024 requests / 16 targets = 16 each */ } #ifdef MPT_DEBUG @@ -678,8 +675,10 @@ mpt_timeout(void *arg) mpt_print_scsi_io_request((MSG_SCSI_IO_REQUEST *)req->req_vbuf); for(index = 0; index < MPT_MAX_REQUESTS(mpt); index++) - if (req == &mpt->request_pool[index]) + if (req == &mpt->request_pool[index]) { + req->debug = REQ_TIMEOUT; break; + } mpt_done(mpt, index); @@ -809,7 +808,12 @@ mpt_done(mpt_softc_t *mpt, uint32_t reply) bus_dmamap_unload(mpt->sc_dmat, req->dmap); } - if (mpt_reply == NULL) { + if (req->debug == REQ_TIMEOUT) { + xs->error = XS_TIMEOUT; + xs->status = SCSI_OK; + xs->resid = 0; + goto done; + } else if (mpt_reply == NULL) { /* * Context reply; report that the command was * successful! @@ -826,10 +830,7 @@ mpt_done(mpt_softc_t *mpt, uint32_t reply) xs->error = XS_NOERROR; xs->status = SCSI_OK; xs->resid = 0; - mpt_free_request(mpt, req); - xs->flags |= ITSDONE; - scsi_done(xs); - return; + goto done; } xs->status = mpt_reply->SCSIStatus; @@ -1501,3 +1502,66 @@ mpt_minphys(struct buf *bp) bp->b_bcount = MPT_MAX_XFER; minphys(bp); } + +/* + * Allocate DMA resources for FW image + * + * img_sz : size of image + * maxsgl : maximum number of DMA segments + */ +int +mpt_alloc_fw_mem(mpt_softc_t *mpt, uint32_t img_sz, int maxsgl) +{ + int error; + + error = bus_dmamem_alloc(mpt->sc_dmat, img_sz, PAGE_SIZE, 0, + &mpt->fw_seg, maxsgl, &mpt->fw_rseg, 0); + if (error) { + mpt_prt(mpt, "unable to allocate fw memory, error = %d\n", error); + goto fw_fail0; + } + + error = bus_dmamem_map(mpt->sc_dmat, &mpt->fw_seg, mpt->fw_rseg, img_sz, + (caddr_t *)&mpt->fw, BUS_DMA_COHERENT); + if (error) { + mpt_prt(mpt, "unable to map fw area, error = %d\n", error); + goto fw_fail1; + } + + error = bus_dmamap_create(mpt->sc_dmat, img_sz, maxsgl, img_sz, + 0, 0, &mpt->fw_dmap); + if (error) { + mpt_prt(mpt, "unable to create request DMA map, error = %d\n", + error); + goto fw_fail2; + } + + error = bus_dmamap_load(mpt->sc_dmat, mpt->fw_dmap, mpt->fw, img_sz, + NULL, 0); + if (error) { + mpt_prt(mpt, "unable to load request DMA map, error = %d\n", error); + goto fw_fail3; + } + + return(error); +fw_fail3: + bus_dmamap_unload(mpt->sc_dmat, mpt->fw_dmap); +fw_fail2: + bus_dmamap_destroy(mpt->sc_dmat, mpt->fw_dmap); +fw_fail1: + bus_dmamem_unmap(mpt->sc_dmat, (caddr_t)mpt->fw, img_sz); +fw_fail0: + bus_dmamem_free(mpt->sc_dmat, &mpt->fw_seg, mpt->fw_rseg); + + mpt->fw = NULL; + return (error); +} + +void +mpt_free_fw_mem(mpt_softc_t *mpt) +{ + bus_dmamap_unload(mpt->sc_dmat, mpt->fw_dmap); + bus_dmamap_destroy(mpt->sc_dmat, mpt->fw_dmap); + bus_dmamem_unmap(mpt->sc_dmat, (caddr_t)mpt->fw, mpt->fw_image_size); + bus_dmamem_free(mpt->sc_dmat, &mpt->fw_seg, mpt->fw_rseg); +} |