summaryrefslogtreecommitdiff
path: root/sys/dev/isp
diff options
context:
space:
mode:
authorMatt Jacob <mjacob@FreeBSD.org>2005-01-29 02:42:58 +0000
committerMatt Jacob <mjacob@FreeBSD.org>2005-01-29 02:42:58 +0000
commit58c53751a7228d197877b4eaf1c52c63e87220c1 (patch)
treef9fe45f149218e5c10f36c6e910eeb0e2bb354d1 /sys/dev/isp
parente2dbd09f4147f7da4672e1022e44320839aaee08 (diff)
Notes
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp.c44
-rw-r--r--sys/dev/isp/isp_freebsd.c2
-rw-r--r--sys/dev/isp/isp_pci.c13
-rw-r--r--sys/dev/isp/isp_target.c4
-rw-r--r--sys/dev/isp/isp_target.h66
-rw-r--r--sys/dev/isp/ispvar.h2
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.