diff options
author | mjacob <mjacob@FreeBSD.org> | 2007-04-02 01:04:20 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2007-04-02 01:04:20 +0000 |
commit | 00323bff58a4642e190d904bae8a04685867f87c (patch) | |
tree | 301dc2dba02ff47c95da310a9856c01c9754f539 /sys | |
parent | 65a30c481ba0f8b44f073c893e9d5dbc5747a5d1 (diff) | |
download | FreeBSD-src-00323bff58a4642e190d904bae8a04685867f87c.zip FreeBSD-src-00323bff58a4642e190d904bae8a04685867f87c.tar.gz |
Temporarily desupport simultaneous target and initiator mode.
When the linux port changes were imported which split the
target command list to be separate from the initiator command
list and the handle format changed to encode a type in the handle
the implications to the function isp_handle_index (which only
the NetBSD/OpenBSD/FreeBSD ports use) were overlooked.
The fault is twofold: first, the index into the DMA maps
in isp_pci is wrong because a target command handle with
the type bit left in place caused a bad index (and panic)
into dma map. Secondly, the assumption of the array
of DMA maps in either PCS or SBUS attachment structures is
that there is a linear mapping between handle index and
DMA map index. This can no longer be true if there are
overlapping index spaces for initiator mode and target
mode commands.
These changes bandaid around the problem by forcing us
to not have simultaneous dual roles and doing the appropriate
masking to make sure things are indexed correctly. A longer
term fix is being devloped.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/NOTES | 8 | ||||
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 10 | ||||
-rw-r--r-- | sys/dev/isp/isp_freebsd.h | 8 | ||||
-rw-r--r-- | sys/dev/isp/isp_library.c | 14 | ||||
-rw-r--r-- | sys/dev/isp/isp_library.h | 2 | ||||
-rw-r--r-- | sys/dev/isp/isp_pci.c | 14 | ||||
-rw-r--r-- | sys/dev/isp/isp_sbus.c | 8 |
7 files changed, 44 insertions, 20 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 0bf6d64..43602d5 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1534,9 +1534,13 @@ options ADW_ALLOW_MEMIO # options ISP_TARGET_MODE=1 # -# ISP_DEFAULT_ROLES - default role (none, target, init, both) +# ISP_DEFAULT_ROLES - default role +# none=0 +# target=1 +# initiator=2 +# both=3 (not supported currently) # -options ISP_DEFAULT_ROLES=3 +options ISP_DEFAULT_ROLES=2 # Options used in dev/sym/ (Symbios SCSI driver). #options SYM_SETUP_LP_PROBE_MAP #-Low Priority Probe Map (bits) diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 8ec82e2..f422659 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -382,6 +382,14 @@ ispioctl(_DEV dev, u_long c, caddr_t addr, int flags, _IOP *td) retval = EINVAL; break; } + /* + * XXX: Current + */ + if (nr == ISP_ROLE_BOTH) { + isp_prt(isp, ISP_LOGERR, "dual roles not supported"); + retval = EINVAL; + break; + } *(int *)addr = isp->isp_role; isp->isp_role = nr; /* FALLTHROUGH */ @@ -1133,7 +1141,7 @@ isp_en_lun(ispsoftc_t *isp, union ccb *ccb) static void isp_ledone(ispsoftc_t *isp, lun_entry_t *lep) { - const char lfmt[] = "now %sabled for target mode"; + const char lfmt[] = "now %sabled for target mode\n"; union ccb *ccb; uint32_t seq; tstate_t *tptr; diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index a3f7024..e7cfb19 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -98,7 +98,7 @@ #endif #if __FreeBSD_version < 700000 -typedef void ispfwfunc(int, int, int, const void **); +typedef void ispfwfunc(int, int, int, void **); #endif #ifdef ISP_TARGET_MODE @@ -532,4 +532,10 @@ int isp_mstohz(int); #include <dev/isp/isp_library.h> +/* + * XXX: Temp + */ +#if ISP_DEFAULT_ROLES == ISP_ROLE_BOTH +#error "Dual Role Temporarily Unsupported" +#endif #endif /* _ISP_FREEBSD_H */ diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c index 98ec5d5f..2f628bf 100644 --- a/sys/dev/isp/isp_library.c +++ b/sys/dev/isp/isp_library.c @@ -1499,12 +1499,12 @@ isp_save_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep) void * isp_find_xs_tgt(ispsoftc_t *isp, uint32_t handle) { - if (handle == 0 || (handle & 0x8000) == 0 || - (handle & 0x7fff) > isp->isp_maxcmds) { + if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 || + (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) { isp_prt(isp, ISP_LOGERR, "bad handle in isp_find_xs_tgt"); return (NULL); } else { - return (isp->isp_tgtlist[(handle & 0x7fff) - 1]); + return (isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1]); } } @@ -1515,7 +1515,7 @@ isp_find_tgt_handle(ispsoftc_t *isp, void *xs) if (xs != NULL) { for (i = 0; i < isp->isp_maxcmds; i++) { if (isp->isp_tgtlist[i] == xs) { - return ((i+1) & 0x7fff); + return ((i+1) & ISP_HANDLE_MASK); } } } @@ -1525,12 +1525,12 @@ isp_find_tgt_handle(ispsoftc_t *isp, void *xs) void isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle) { - if (handle == 0 || (handle & 0x8000) == 0 || - (handle & 0x7fff) > isp->isp_maxcmds) { + if (handle == 0 || IS_TARGET_HANDLE(handle) == 0 || + (handle & ISP_HANDLE_MASK) > isp->isp_maxcmds) { isp_prt(isp, ISP_LOGERR, "bad handle in isp_destroy_tgt_handle"); } else { - isp->isp_tgtlist[(handle & 0x7fff) - 1] = NULL; + isp->isp_tgtlist[(handle & ISP_HANDLE_MASK) - 1] = NULL; } } diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h index 13b077c..a614bb6 100644 --- a/sys/dev/isp/isp_library.h +++ b/sys/dev/isp/isp_library.h @@ -128,6 +128,8 @@ extern void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *); extern void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *); extern void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *); +#define ISP_HANDLE_MASK 0x7fff + #ifdef ISP_TARGET_MODE #if defined(__NetBSD__) || defined(__OpenBSD__) #include <dev/ic/isp_target.h> diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 7b5a326..390a60f 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -1994,7 +1994,7 @@ tdma_mk(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) cto->ct_scsi_status = 0; pcs = (struct isp_pcisoftc *)isp; - dp = &pcs->dmaps[isp_handle_index(handle)]; + dp = &pcs->dmaps[isp_handle_index(handle & ISP_HANDLE_MASK)]; if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { bus_dmamap_sync(pcs->dmat, *dp, BUS_DMASYNC_PREREAD); } else { @@ -2388,7 +2388,7 @@ dma_2400(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) isp = mp->isp; rq = mp->rq; pcs = (struct isp_pcisoftc *)mp->isp; - dp = &pcs->dmaps[isp_handle_index(rq->req_handle)]; + dp = &pcs->dmaps[isp_handle_index(rq->req_handle & ISP_HANDLE_MASK)]; nxti = *mp->nxtip; if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { @@ -2494,7 +2494,7 @@ dma2_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) isp = mp->isp; rq = mp->rq; pcs = (struct isp_pcisoftc *)mp->isp; - dp = &pcs->dmaps[isp_handle_index(rq->req_handle)]; + dp = &pcs->dmaps[isp_handle_index(rq->req_handle & ISP_HANDLE_MASK)]; nxti = *mp->nxtip; if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { @@ -2628,7 +2628,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) isp = mp->isp; rq = mp->rq; pcs = (struct isp_pcisoftc *)mp->isp; - dp = &pcs->dmaps[isp_handle_index(rq->req_handle)]; + dp = &pcs->dmaps[isp_handle_index(rq->req_handle & ISP_HANDLE_MASK)]; nxti = *mp->nxtip; if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { @@ -2795,7 +2795,8 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq, if ((csio->ccb_h.flags & CAM_SCATTER_VALID) == 0) { if ((csio->ccb_h.flags & CAM_DATA_PHYS) == 0) { int error, s; - dp = &pcs->dmaps[isp_handle_index(rq->req_handle)]; + dp = &pcs->dmaps[isp_handle_index( + rq->req_handle & ISP_HANDLE_MASK)]; s = splsoftvm(); error = bus_dmamap_load(pcs->dmat, *dp, csio->data_ptr, csio->dxfer_len, eptr, mp, 0); @@ -2880,7 +2881,8 @@ static void isp_pci_dmateardown(ispsoftc_t *isp, XS_T *xs, uint32_t handle) { struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; - bus_dmamap_t *dp = &pcs->dmaps[isp_handle_index(handle)]; + bus_dmamap_t *dp; + dp = &pcs->dmaps[isp_handle_index(handle & ISP_HANDLE_MASK)]; if ((xs->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { bus_dmamap_sync(pcs->dmat, *dp, BUS_DMASYNC_POSTREAD); } else { diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c index af68ec1..c5b680c 100644 --- a/sys/dev/isp/isp_sbus.c +++ b/sys/dev/isp/isp_sbus.c @@ -624,7 +624,7 @@ dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) isp = mp->isp; rq = mp->rq; sbs = (struct isp_sbussoftc *)mp->isp; - dp = &sbs->dmaps[isp_handle_index(rq->req_handle)]; + dp = &sbs->dmaps[isp_handle_index(rq->req_handle & ISP_HANDLE_MASK)]; nxti = *mp->nxtip; if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { @@ -735,7 +735,8 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, ispreq_t *rq, if ((csio->ccb_h.flags & CAM_SCATTER_VALID) == 0) { if ((csio->ccb_h.flags & CAM_DATA_PHYS) == 0) { int error, s; - dp = &sbs->dmaps[isp_handle_index(rq->req_handle)]; + dp = &sbs->dmaps[isp_handle_index( + rq->req_handle & ISP_HANDLE_MASK)]; s = splsoftvm(); error = bus_dmamap_load(sbs->dmat, *dp, csio->data_ptr, csio->dxfer_len, eptr, mp, 0); @@ -809,7 +810,8 @@ static void isp_sbus_dmateardown(ispsoftc_t *isp, XS_T *xs, uint32_t handle) { struct isp_sbussoftc *sbs = (struct isp_sbussoftc *)isp; - bus_dmamap_t *dp = &sbs->dmaps[isp_handle_index(handle)]; + bus_dmamap_t *dp; + dp = &sbs->dmaps[isp_handle_index(handle & ISP_HANDLE_MASK)]; if ((xs->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { bus_dmamap_sync(sbs->dmat, *dp, BUS_DMASYNC_POSTREAD); } else { |