diff options
| author | Matt Jacob <mjacob@FreeBSD.org> | 2005-01-29 02:42:58 +0000 |
|---|---|---|
| committer | Matt Jacob <mjacob@FreeBSD.org> | 2005-01-29 02:42:58 +0000 |
| commit | 58c53751a7228d197877b4eaf1c52c63e87220c1 (patch) | |
| tree | f9fe45f149218e5c10f36c6e910eeb0e2bb354d1 /sys/dev/isp | |
| parent | e2dbd09f4147f7da4672e1022e44320839aaee08 (diff) | |
Notes
Diffstat (limited to 'sys/dev/isp')
| -rw-r--r-- | sys/dev/isp/isp.c | 44 | ||||
| -rw-r--r-- | sys/dev/isp/isp_freebsd.c | 2 | ||||
| -rw-r--r-- | sys/dev/isp/isp_pci.c | 13 | ||||
| -rw-r--r-- | sys/dev/isp/isp_target.c | 4 | ||||
| -rw-r--r-- | sys/dev/isp/isp_target.h | 66 | ||||
| -rw-r--r-- | sys/dev/isp/ispvar.h | 2 |
6 files changed, 105 insertions, 26 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index a12c3d4472b9..9859eac3bdf8 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -1300,9 +1300,17 @@ isp_fibre_init(struct ispsoftc *isp) * * If we set ZIO, it will disable fast posting, * so we don't need to clear it in fwoptions. + * + * Depending on the role we're selecting, we + * chose fast posting or not as it still is + * a win for target mode. */ #ifndef ISP_NO_ZIO - icbp->icb_xfwoptions |= ICBXOPT_ZIO; + if (isp->isp_role == ISP_ROLE_TARGET) { + icbp->icb_fwoptions |= ICBOPT_FAST_POST; + } else { + icbp->icb_xfwoptions |= ICBXOPT_ZIO; + } #else icbp->icb_fwoptions |= ICBOPT_FAST_POST; #endif @@ -3675,6 +3683,7 @@ again: oop = optr; optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp)); nlooked++; + read_again: /* * Synchronize our view of this response queue entry. */ @@ -3700,7 +3709,10 @@ again: * may have updated the response queue pointers for * us, so we reload our goal index. */ - if (isp_handle_other_response(isp, type, hp, &optr)) { + int i = isp_handle_other_response(isp, type, hp, &optr); + if (i < 0) { + goto read_again; + } else if (i > 0) { iptr = isp->isp_resodx; MEMZERO(hp, QENTRY_LEN); /* PERF */ continue; @@ -4119,12 +4131,16 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox) int handle = (ISP_READ(isp, OUTMAILBOX2) << 16) | (ISP_READ(isp, OUTMAILBOX1)); - if (isp_target_async(isp, handle, mbox)) + if (isp_target_async(isp, handle, mbox)) { rval = -1; + } else { + /* count it as a fast posting intr */ + isp->isp_fphccmplt++; + } #else isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done"); -#endif isp->isp_fphccmplt++; /* count it as a fast posting intr */ +#endif break; } case ASYNC_LIP_F8: @@ -4282,7 +4298,7 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox) if (bus & 0x100) { int i, nh; - u_int16_t handles[5]; + u_int16_t handles[16]; for (nh = 0, i = 1; i < MAX_MAILBOX; i++) { if ((bus & (1 << i)) == 0) { @@ -4336,11 +4352,25 @@ isp_handle_other_response(struct ispsoftc *isp, int type, /* FALLTHROUGH */ case RQSTYPE_REQUEST: default: - if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) { - return (1); + USEC_DELAY(100); + if (type != isp_get_response_type(isp, hp)) { + /* + * This is questionable- we're just papering over + * something we've seen on SMP linux in target + * mode- we don't really know what's happening + * here that causes us to think we've gotten + * an entry, but that either the entry isn't + * filled out yet or our CPU read data is stale. + */ + isp_prt(isp, ISP_LOGINFO, + "unstable type in response queue"); + return (-1); } isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x", isp_get_response_type(isp, hp)); + if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) { + return (1); + } return (0); } } diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 986fc8d6cb9f..c7038abc2fe5 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -1497,7 +1497,7 @@ isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep) * Construct a tag 'id' based upon tag value (which may be 0..255) * and the handle (which we have to preserve). */ - AT_MAKE_TAGID(atiop->tag_id, aep); + AT_MAKE_TAGID(atiop->tag_id, 0, aep); if (aep->at_flags & AT_TQAE) { atiop->tag_action = aep->at_tag_type; atiop->ccb_h.status |= CAM_TAG_ACTION_VALID; diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 8fe9ba362616..be92b963ee19 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -221,6 +221,10 @@ static struct ispmdvec mdvec_2300 = { #define PCI_PRODUCT_QLOGIC_ISP2312 0x2312 #endif +#ifndef PCI_PRODUCT_QLOGIC_ISP6312 +#define PCI_PRODUCT_QLOGIC_ISP6312 0x6312 +#endif + #define PCI_QLOGIC_ISP1020 \ ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC) @@ -251,6 +255,9 @@ static struct ispmdvec mdvec_2300 = { #define PCI_QLOGIC_ISP2312 \ ((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC) +#define PCI_QLOGIC_ISP6312 \ + ((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC) + /* * Odd case for some AMI raid cards... We need to *not* attach to this. */ @@ -330,6 +337,9 @@ isp_pci_probe(device_t dev) case PCI_QLOGIC_ISP2312: device_set_desc(dev, "Qlogic ISP 2312 PCI FC-AL Adapter"); break; + case PCI_QLOGIC_ISP6312: + device_set_desc(dev, "Qlogic ISP 6312 PCI FC-AL Adapter"); + break; default: return (ENXIO); } @@ -517,7 +527,8 @@ isp_pci_attach(device_t dev) pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2300_OFF; } - if (pci_get_devid(dev) == PCI_QLOGIC_ISP2312) { + if (pci_get_devid(dev) == PCI_QLOGIC_ISP2312 || + pci_get_devid(dev) == PCI_QLOGIC_ISP6312) { mdvp = &mdvec_2300; basetype = ISP_HA_FC_2312; psize = sizeof (fcparam); diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c index d26d1e35d427..efe1d549a8d1 100644 --- a/sys/dev/isp/isp_target.c +++ b/sys/dev/isp/isp_target.c @@ -578,7 +578,7 @@ isp_got_msg(struct ispsoftc *isp, int bus, in_entry_t *inp) msg.nt_tgt = inp->in_tgt; msg.nt_lun = inp->in_lun; msg.nt_tagtype = inp->in_tag_type; - msg.nt_tagval = inp->in_tag_val; + IN_MAKE_TAGID(msg.nt_tagval, 0, inp); MEMCPY(msg.nt_msg, inp->in_msg, IN_MSGLEN); (void) isp_async(isp, ISPASYNC_TARGET_MESSAGE, &msg); } else { @@ -614,7 +614,7 @@ isp_got_msg_fc(struct ispsoftc *isp, int bus, in_fcentry_t *inp) MEMZERO(&msg, sizeof (msg)); msg.nt_bus = bus; msg.nt_iid = inp->in_iid; - msg.nt_tagval = inp->in_seqid; + IN_FC_MAKE_TAGID(msg.nt_tagval, 0, inp); msg.nt_lun = lun; if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { diff --git a/sys/dev/isp/isp_target.h b/sys/dev/isp/isp_target.h index c0bbc89fb11e..70f68c9c5409 100644 --- a/sys/dev/isp/isp_target.h +++ b/sys/dev/isp/isp_target.h @@ -244,24 +244,40 @@ typedef struct { #define AT_NOCAP 0x16 /* Requested capability not available */ #define AT_BDR_MSG 0x17 /* Bus Device Reset msg received */ #define AT_CDB 0x3D /* CDB received */ - /* * Macros to create and fetch and test concatenated handle and tag value macros */ -#define AT_MAKE_TAGID(tid, aep) \ - tid = ((aep)->at_handle << 16); \ - if ((aep)->at_flags & AT_TQAE) \ - (tid) |= ((aep)->at_tag_val + 1) +#define AT_MAKE_TAGID(tid, inst, aep) \ + tid = aep->at_handle; \ + if (aep->at_flags & AT_TQAE) { \ + tid |= (aep->at_tag_val << 16); \ + tid |= (1 << 24); \ + } \ + tid |= (inst << 25) + +#define CT_MAKE_TAGID(tid, inst, ct) \ + tid = ct->ct_fwhandle; \ + if (ct->ct_flags & CT_TQAE) { \ + tid |= (ct->ct_tag_val << 16); \ + tid |= (1 << 24); \ + } \ + tid |= (inst << 25) + +#define AT_HAS_TAG(val) ((val) & (1 << 24)) +#define AT_GET_TAG(val) (((val) >> 16) & 0xff) +#define AT_GET_INST(val) (((val) >> 25) & 0x7f) +#define AT_GET_HANDLE(val) ((val) & 0xffff) -#define CT_MAKE_TAGID(tid, ct) \ - tid = ((ct)->ct_fwhandle << 16); \ - if ((ct)->ct_flags & CT_TQAE) \ - (tid) |= ((ct)->ct_tag_val + 1) +#define IN_MAKE_TAGID(tid, inst, inp) \ + tid = inp->in_seqid; \ + tid |= (inp->in_tag_val << 16); \ + tid |= (1 << 24); \ + tid |= (inst << 25) -#define AT_HAS_TAG(val) ((val) & 0xffff) -#define AT_GET_TAG(val) AT_HAS_TAG(val) - 1 -#define AT_GET_HANDLE(val) ((val) >> 16) +#define TAG_INSERT_INST(tid, inst) \ + tid &= ~(0x1ffffff); \ + tid |= (inst << 25) /* * Accept Target I/O Entry structure, Type 2 @@ -300,6 +316,30 @@ typedef struct { #define ATIO2_EX_WRITE 0x1 #define ATIO2_EX_READ 0x2 +/* + * Macros to create and fetch and test concatenated handle and tag value macros + */ +#define AT2_MAKE_TAGID(tid, inst, aep) \ + tid = aep->at_rxid; \ + tid |= (inst << 16) + +#define CT2_MAKE_TAGID(tid, inst, ct) \ + tid = ct->ct_rxid; \ + tid |= (inst << 16) + +#define AT2_HAS_TAG(val) 1 +#define AT2_GET_TAG(val) ((val) & 0xffff) +#define AT2_GET_INST(val) ((val) >> 16) +#define AT2_GET_HANDLE AT2_GET_TAG + +#define IN_FC_MAKE_TAGID(tid, inst, inp) \ + tid = inp->in_seqid; \ + tid |= (inst << 16) + +#define FC_TAG_INSERT_INST(tid, inst) \ + tid &= ~0xffff; \ + tid |= (inst << 16) + /* * Continue Target I/O Entry structure @@ -506,7 +546,6 @@ typedef struct { #define ISP_TDQE(isp, msg, idx, arg) \ if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg) -#ifdef ISP_TARGET_FUNCTIONS /* * The functions below are for the publicly available * target mode functions that are internal to the Qlogic driver. @@ -552,5 +591,4 @@ int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t); */ int isp_target_async(struct ispsoftc *, int, int); -#endif #endif /* _ISP_TARGET_H */ diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 1e99dc9b5c4b..0810a4899068 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -54,7 +54,7 @@ #endif #define ISP_CORE_VERSION_MAJOR 2 -#define ISP_CORE_VERSION_MINOR 8 +#define ISP_CORE_VERSION_MINOR 9 /* * Vector for bus specific code to provide specific services. |
