diff options
Diffstat (limited to 'sys/dev/sbus/isp_sbus.c')
-rw-r--r-- | sys/dev/sbus/isp_sbus.c | 120 |
1 files changed, 62 insertions, 58 deletions
diff --git a/sys/dev/sbus/isp_sbus.c b/sys/dev/sbus/isp_sbus.c index ae987f268e8..ce764d58fde 100644 --- a/sys/dev/sbus/isp_sbus.c +++ b/sys/dev/sbus/isp_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_sbus.c,v 1.1 2001/10/06 02:03:24 jason Exp $ */ +/* $OpenBSD: isp_sbus.c,v 1.2 2001/12/14 02:51:12 mjacob Exp $ */ /* $NetBSD: isp_sbus.c,v 1.46 2001/09/26 20:53:14 eeh Exp $ */ /* @@ -110,14 +110,11 @@ struct isp_sbussoftc { struct sbusdev sbus_sd; sdparam sbus_dev; bus_space_tag_t sbus_bustag; - bus_dma_tag_t sbus_dmatag; bus_space_handle_t sbus_reg; int sbus_node; int sbus_pri; struct ispmdvec sbus_mdvec; bus_dmamap_t *sbus_dmamap; - bus_dmamap_t sbus_rquest_dmamap; - bus_dmamap_t sbus_result_dmamap; int16_t sbus_poff[_NREG_BLKS]; }; @@ -167,7 +164,6 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux) printf(" for %s\n", sa->sa_name); sbc->sbus_bustag = sa->sa_bustag; - sbc->sbus_dmatag = sa->sa_dmatag; if (sa->sa_nintr != 0) sbc->sbus_pri = sa->sa_pri; sbc->sbus_mdvec = mdvec; @@ -239,7 +235,8 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux) isp->isp_bustype = ISP_BT_SBUS; isp->isp_type = ISP_HA_SCSI_UNKNOWN; isp->isp_param = &sbc->sbus_dev; - bzero(isp->isp_param, sizeof (sdparam)); + isp->isp_dmatag = sa->sa_dmatag; + MEMZERO(isp->isp_param, sizeof (sdparam)); sbc->sbus_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; sbc->sbus_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = SBUS_MBOX_REGS_OFF; @@ -306,17 +303,16 @@ isp_sbus_intr(void *arg) { u_int16_t isr, sema, mbox; struct ispsoftc *isp = arg; - struct isp_sbussoftc *sbc = arg; - bus_dmamap_sync(sbc->sbus_dmatag, sbc->sbus_result_dmamap, 0, - sbc->sbus_result_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); - if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { - sbc->sbus_isp.isp_osinfo.onintstack = 1; + isp->isp_intcnt++; + if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) { + isp->isp_intbogus++; + return (0); + } else { + isp->isp_osinfo.onintstack = 1; isp_intr(isp, isr, sema, mbox); - sbc->sbus_isp.isp_osinfo.onintstack = 0; + isp->isp_osinfo.onintstack = 0; return (1); - } else { - return (0); } } @@ -371,7 +367,6 @@ static int isp_sbus_mbxdma(struct ispsoftc *isp) { struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; - bus_dma_tag_t dmatag = sbc->sbus_dmatag; bus_dma_segment_t reqseg, rspseg; int reqrs, rsprs, i, progress; size_t n; @@ -386,7 +381,7 @@ isp_sbus_mbxdma(struct ispsoftc *isp) isp_prt(isp, ISP_LOGERR, "cannot alloc xflist array"); return (1); } - bzero(isp->isp_xflist, n); + MEMZERO(isp->isp_xflist, n); n = sizeof (bus_dmamap_t) * isp->isp_maxcmds; sbc->sbus_dmamap = (bus_dmamap_t *) malloc(n, M_DEVBUF, M_WAITOK); if (sbc->sbus_dmamap == NULL) { @@ -397,7 +392,7 @@ isp_sbus_mbxdma(struct ispsoftc *isp) } for (i = 0; i < isp->isp_maxcmds; i++) { /* Allocate a DMA handle */ - if (bus_dmamap_create(dmatag, MAXPHYS, 1, MAXPHYS, 0, + if (bus_dmamap_create(isp->isp_dmatag, MAXPHYS, 1, MAXPHYS, 0, BUS_DMA_NOWAIT, &sbc->sbus_dmamap[i]) != 0) { isp_prt(isp, ISP_LOGERR, "cmd DMA maps create error"); break; @@ -405,7 +400,8 @@ isp_sbus_mbxdma(struct ispsoftc *isp) } if (i < isp->isp_maxcmds) { while (--i >= 0) { - bus_dmamap_destroy(dmatag, sbc->sbus_dmamap[i]); + bus_dmamap_destroy(isp->isp_dmatag, + sbc->sbus_dmamap[i]); } free(isp->isp_xflist, M_DEVBUF); free(sbc->sbus_dmamap, M_DEVBUF); @@ -419,49 +415,49 @@ isp_sbus_mbxdma(struct ispsoftc *isp) */ progress = 0; len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)); - if (bus_dmamem_alloc(dmatag, len, 0, 0, &reqseg, 1, &reqrs, + if (bus_dmamem_alloc(isp->isp_dmatag, len, 0, 0, &reqseg, 1, &reqrs, BUS_DMA_NOWAIT)) { goto dmafail; } progress++; - if (bus_dmamem_map(dmatag, &reqseg, reqrs, len, + if (bus_dmamem_map(isp->isp_dmatag, &reqseg, reqrs, len, (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { goto dmafail; } progress++; - if (bus_dmamap_create(dmatag, len, 1, len, 0, BUS_DMA_NOWAIT, - &sbc->sbus_rquest_dmamap) != 0) { + if (bus_dmamap_create(isp->isp_dmatag, len, 1, len, 0, BUS_DMA_NOWAIT, + &isp->isp_rqdmap) != 0) { goto dmafail; } progress++; - if (bus_dmamap_load(dmatag, sbc->sbus_rquest_dmamap, + if (bus_dmamap_load(isp->isp_dmatag, isp->isp_rqdmap, isp->isp_rquest, len, NULL, BUS_DMA_NOWAIT) != 0) { goto dmafail; } progress++; - isp->isp_rquest_dma = sbc->sbus_rquest_dmamap->dm_segs[0].ds_addr; + isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr; len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)); - if (bus_dmamem_alloc(dmatag, len, 0, 0, &rspseg, 1, &rsprs, + if (bus_dmamem_alloc(isp->isp_dmatag, len, 0, 0, &rspseg, 1, &rsprs, BUS_DMA_NOWAIT)) { goto dmafail; } progress++; - if (bus_dmamem_map(dmatag, &rspseg, rsprs, len, + if (bus_dmamem_map(isp->isp_dmatag, &rspseg, rsprs, len, (caddr_t *)&isp->isp_result, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { goto dmafail; } progress++; - if (bus_dmamap_create(dmatag, len, 1, len, 0, BUS_DMA_NOWAIT, - &sbc->sbus_result_dmamap) != 0) { + if (bus_dmamap_create(isp->isp_dmatag, len, 1, len, 0, BUS_DMA_NOWAIT, + &isp->isp_rsdmap) != 0) { goto dmafail; } progress++; - if (bus_dmamap_load(dmatag, sbc->sbus_result_dmamap, + if (bus_dmamap_load(isp->isp_dmatag, isp->isp_rsdmap, isp->isp_result, len, NULL, BUS_DMA_NOWAIT) != 0) { goto dmafail; } - isp->isp_result_dma = sbc->sbus_result_dmamap->dm_segs[0].ds_addr; + isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr; return (0); @@ -469,35 +465,35 @@ dmafail: isp_prt(isp, ISP_LOGERR, "Mailbox DMA Setup Failure"); if (progress >= 8) { - bus_dmamap_unload(dmatag, sbc->sbus_result_dmamap); + bus_dmamap_unload(isp->isp_dmatag, isp->isp_rsdmap); } if (progress >= 7) { - bus_dmamap_destroy(dmatag, sbc->sbus_result_dmamap); + bus_dmamap_destroy(isp->isp_dmatag, isp->isp_rsdmap); } if (progress >= 6) { - bus_dmamem_unmap(dmatag, + bus_dmamem_unmap(isp->isp_dmatag, isp->isp_result, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp))); } if (progress >= 5) { - bus_dmamem_free(dmatag, &rspseg, rsprs); + bus_dmamem_free(isp->isp_dmatag, &rspseg, rsprs); } if (progress >= 4) { - bus_dmamap_unload(dmatag, sbc->sbus_rquest_dmamap); + bus_dmamap_unload(isp->isp_dmatag, isp->isp_rqdmap); } if (progress >= 3) { - bus_dmamap_destroy(dmatag, sbc->sbus_rquest_dmamap); + bus_dmamap_destroy(isp->isp_dmatag, isp->isp_rqdmap); } if (progress >= 2) { - bus_dmamem_unmap(dmatag, + bus_dmamem_unmap(isp->isp_dmatag, isp->isp_rquest, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); } if (progress >= 1) { - bus_dmamem_free(dmatag, &reqseg, reqrs); + bus_dmamem_free(isp->isp_dmatag, &reqseg, reqrs); } for (i = 0; i < isp->isp_maxcmds; i++) { - bus_dmamap_destroy(dmatag, sbc->sbus_dmamap[i]); + bus_dmamap_destroy(isp->isp_dmatag, sbc->sbus_dmamap[i]); } free(sbc->sbus_dmamap, M_DEVBUF); free(isp->isp_xflist, M_DEVBUF); @@ -513,14 +509,15 @@ dmafail: static int isp_sbus_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, - u_int16_t *iptrp, u_int16_t optr) + u_int16_t *nxtip, u_int16_t optr) { struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp; bus_dmamap_t dmap; - ispcontreq_t *crq; + ispreq_t *qep; int cansleep = (xs->flags & SCSI_NOSLEEP) == 0; int in = (xs->flags & SCSI_DATA_IN) != 0; + qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); if (xs->datalen == 0) { rq->req_seg_count = 1; goto mbxsync; @@ -531,14 +528,14 @@ isp_sbus_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, panic("%s: dma map already allocated\n", isp->isp_name); /* NOTREACHED */ } - if (bus_dmamap_load(sbc->sbus_dmatag, dmap, xs->data, xs->datalen, + if (bus_dmamap_load(isp->isp_dmatag, dmap, xs->data, xs->datalen, NULL, (cansleep ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT) | BUS_DMA_STREAMING) != 0) { XS_SETERR(xs, HBA_BOTCH); return (CMD_COMPLETE); } - bus_dmamap_sync(sbc->sbus_dmatag, dmap, 0, xs->datalen, + bus_dmamap_sync(isp->isp_dmatag, dmap, 0, xs->datalen, in? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); if (in) { @@ -548,33 +545,39 @@ isp_sbus_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq, } if (XS_CDBLEN(xs) > 12) { - crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp); - *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN(isp)); - if (*iptrp == optr) { + u_int16_t onxti; + ispcontreq_t local, *crq = &local, *cqe; + + onxti = *nxtip; + cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, onxti); + *nxtip = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp)); + if (*nxtip == optr) { isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++"); - bus_dmamap_unload(sbc->sbus_dmatag, dmap); + bus_dmamap_unload(isp->isp_dmatag, dmap); XS_SETERR(xs, HBA_BOTCH); return (CMD_EAGAIN); } rq->req_seg_count = 2; - rq->req_dataseg[0].ds_count = 0; - rq->req_dataseg[0].ds_base = 0; - bzero((void *)crq, sizeof (*crq)); + MEMZERO((void *)crq, sizeof (*crq)); crq->req_header.rqs_entry_count = 1; crq->req_header.rqs_entry_type = RQSTYPE_DATASEG; crq->req_dataseg[0].ds_count = xs->datalen; - crq->req_dataseg[0].ds_base = dmap->dm_segs[0].ds_addr; - ISP_SBUSIFY_ISPHDR(isp, &crq->req_header) + crq->req_dataseg[0].ds_base = dmap->dm_segs[0].ds_addr; + isp_put_cont_req(isp, crq, cqe); + MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN); } else { + rq->req_seg_count = 1; rq->req_dataseg[0].ds_count = xs->datalen; rq->req_dataseg[0].ds_base = dmap->dm_segs[0].ds_addr; - rq->req_seg_count = 1; } mbxsync: - ISP_SWIZZLE_REQUEST(isp, rq); - bus_dmamap_sync(sbc->sbus_dmatag, sbc->sbus_rquest_dmamap, 0, - sbc->sbus_rquest_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE); + if (XS_CDBLEN(xs) > 12) { + isp_put_extended_request(isp, + (ispextreq_t *)rq, (ispextreq_t *) qep); + } else { + isp_put_request(isp, rq, qep); + } return (CMD_QUEUED); } @@ -590,8 +593,9 @@ isp_sbus_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle) panic("%s: dma map not already allocated\n", isp->isp_name); /* NOTREACHED */ } - bus_dmamap_sync(sbc->sbus_dmatag, dmap, 0, + bus_dmamap_sync(isp->isp_dmatag, dmap, 0, xs->datalen, (xs->flags & SCSI_DATA_IN)? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sbc->sbus_dmatag, dmap); + bus_dmamap_unload(isp->isp_dmatag, dmap); } +/* %W% */ |