summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2002-04-16 19:55:35 +0000
committermjacob <mjacob@FreeBSD.org>2002-04-16 19:55:35 +0000
commit3c9fbb49419cd1209b4b44133b837a7396fbfdba (patch)
tree0949e1835e6071c91c049abcdbe708fc64a0f356 /sys/dev
parente6ba3748eeca04b1fd85232061727c42c350556a (diff)
downloadFreeBSD-src-3c9fbb49419cd1209b4b44133b837a7396fbfdba.zip
FreeBSD-src-3c9fbb49419cd1209b4b44133b837a7396fbfdba.tar.gz
Scale back # of luns supported for SCC to 16384- oops- top 3 bits are a
lun address modifier of sorts. Only an HP XP-512 seems to have cared. Fix a few misplaced pointers for the new fabric goop, which has been demonstrated to work on newer Brocades and McData switches now. Put in commented out code which would run GFF_ID if the QLogic f/w allowed it. Don't whine about not being able to find a handle for a command if it was a command aborted (by us).
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/isp/isp.c119
-rw-r--r--sys/dev/isp/isp_inline.h15
-rw-r--r--sys/dev/isp/ispmbox.h6
3 files changed, 112 insertions, 28 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 83af43e..2070df7 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -773,7 +773,7 @@ again:
* of knowing how many luns we support.
*
* Expanded lun firmware gives you 32 luns for SCSI cards and
- * 65536 luns for Fibre Channel cards.
+ * 16384 luns for Fibre Channel cards.
*
* It turns out that even for QLogic 2100s with ROM 1.10 and above
* we do get a firmware attributes word returned in mailbox register 6.
@@ -796,7 +796,7 @@ again:
}
} else {
if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
- isp->isp_maxluns = 65536;
+ isp->isp_maxluns = 16384;
} else {
isp->isp_maxluns = 16;
}
@@ -1819,7 +1819,7 @@ isp_pdb_sync(struct ispsoftc *isp)
* that has, in fact, gone away. And it hangs trying to
* log it out.
*/
- if (lp->loggedin &&
+ if (lp->loggedin && lp->force_logout == 0 &&
isp_getpdb(isp, lp->loopid, &pdb) == 0) {
int nrole;
u_int64_t nwwnn, nwwpn;
@@ -1855,8 +1855,6 @@ isp_pdb_sync(struct ispsoftc *isp)
}
}
- lp->force_logout = 0;
-
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate != LOOP_SYNCING_PDB) {
return (-1);
@@ -1866,18 +1864,18 @@ isp_pdb_sync(struct ispsoftc *isp)
* Force a logout if we were logged in.
*/
if (lp->loggedin) {
- if (isp_getpdb(isp, lp->loopid, &pdb) == 0) {
+ if (lp->force_logout ||
+ isp_getpdb(isp, lp->loopid, &pdb) == 0) {
mbs.param[0] = MBOX_FABRIC_LOGOUT;
mbs.param[1] = lp->loopid << 8;
mbs.param[2] = 0;
mbs.param[3] = 0;
isp_mboxcmd(isp, &mbs, MBLOGNONE);
- lp->loggedin = 0;
isp_prt(isp, ISP_LOGINFO, plogout,
(int) (lp - fcp->portdb), lp->loopid,
lp->portid);
}
- lp->loggedin = 0;
+ lp->force_logout = lp->loggedin = 0;
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate != LOOP_SYNCING_PDB) {
return (-1);
@@ -1894,10 +1892,6 @@ isp_pdb_sync(struct ispsoftc *isp)
mbs.param[1] = loopid << 8;
mbs.param[2] = portid >> 16;
mbs.param[3] = portid & 0xffff;
- if (IS_2200(isp) || IS_23XX(isp)) {
- /* only issue a PLOGI if not logged in */
- mbs.param[1] |= 0x1;
- }
isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
if (fcp->isp_fwstate != FW_READY ||
@@ -2509,7 +2503,6 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
{
fcparam *fcp = FCPARAM(isp);
mbreg_t mbs;
- u_int8_t sc[GIDLEN]; /* XXX USE ->tport */
int i;
sns_gid_ft_req_t *rq;
sns_gid_ft_rsp_t *rs0, *rs1;
@@ -2522,7 +2515,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
FC_SCRATCH_ACQUIRE(isp);
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
- rq = (sns_gid_ft_req_t *)sc;
+ rq = (sns_gid_ft_req_t *)fcp->tport;
MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
rq->snscb_rblen = GIDLEN >> 1;
rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
@@ -2557,7 +2550,7 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
return (-1);
}
MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
- rs1 = (sns_gid_ft_rsp_t *) sc;
+ rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
if (rs1->snscb_cthdr.ct_response != FS_ACC) {
@@ -2582,6 +2575,9 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
struct lportdb lcl;
+#if 0
+ sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
+#endif
i++;
MEMZERO(&lcl, sizeof (lcl));
@@ -2628,8 +2624,8 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
isp_get_gxn_id_response(isp, gs0, gs1);
if (gs1->snscb_cthdr.ct_response != FS_ACC) {
isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
- rs1->snscb_cthdr.ct_reason,
- rs1->snscb_cthdr.ct_explanation, lcl.portid);
+ gs1->snscb_cthdr.ct_reason,
+ gs1->snscb_cthdr.ct_explanation, lcl.portid);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
@@ -2683,8 +2679,8 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
isp_get_gxn_id_response(isp, gs0, gs1);
if (gs1->snscb_cthdr.ct_response != FS_ACC) {
isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
- rs1->snscb_cthdr.ct_reason,
- rs1->snscb_cthdr.ct_explanation, lcl.portid);
+ gs1->snscb_cthdr.ct_reason,
+ gs1->snscb_cthdr.ct_explanation, lcl.portid);
if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
FC_SCRATCH_RELEASE(isp);
return (-1);
@@ -2702,13 +2698,72 @@ isp_scan_fabric(struct ispsoftc *isp, int ftype)
(((u_int64_t)gs1->snscb_wwn[7]));
/*
- * XXX: Argh! I saw some PDF which I now can't find that
- * XXX: had proposed that the bottom nibble of CONTROL
- * XXX: would have the SCSI-FCP role flags, which would
- * XXX: be *awesome*.
- *
- lcl.roles = rs1->snscb_port[i].control & 0xf;
+ * The QLogic f/w is bouncing this with a parameter error.
+ */
+#if 0
+ /*
+ * Try and get FC4 Features (FC-GS-3 only).
+ * We can use the sns_gxn_id_req_t for this request.
+ */
+ MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
+ gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
+ gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
+ gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
+ gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
+ gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
+ gq->snscb_sblen = 6;
+ gq->snscb_cmd = SNS_GFF_ID;
+ gq->snscb_portid = lcl.portid;
+ isp_put_gxn_id_request(isp, gq,
+ (sns_gxn_id_req_t *) fcp->isp_scratch);
+ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
+ mbs.param[0] = MBOX_SEND_SNS;
+ mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
+ mbs.param[2] = DMA_WD1(fcp->isp_scdma);
+ mbs.param[3] = DMA_WD0(fcp->isp_scdma);
+ /*
+ * Leave 4 and 5 alone
*/
+ mbs.param[6] = DMA_WD3(fcp->isp_scdma);
+ mbs.param[7] = DMA_WD2(fcp->isp_scdma);
+ if (isp_fabric_mbox_cmd(isp, &mbs)) {
+ if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
+ fcp->isp_loopstate = LOOP_PDB_RCVD;
+ }
+ FC_SCRATCH_RELEASE(isp);
+ return (-1);
+ }
+ if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp);
+ return (-1);
+ }
+ MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
+ fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
+ isp_get_gff_id_response(isp, fs0, fs1);
+ if (fs1->snscb_cthdr.ct_response != FS_ACC) {
+ isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
+ swrej, "GFF_ID",
+ fs1->snscb_cthdr.ct_reason,
+ fs1->snscb_cthdr.ct_explanation, lcl.portid);
+ if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
+ FC_SCRATCH_RELEASE(isp);
+ return (-1);
+ }
+ } else {
+ int index = (ftype >> 3);
+ int bshft = (ftype & 0x7) * 4;
+ int fc4_fval =
+ (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
+ if (fc4_fval & 0x1) {
+ lcl.roles |=
+ (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
+ }
+ if (fc4_fval & 0x2) {
+ lcl.roles |=
+ (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
+ }
+ }
+#endif
/*
* If we really want to know what kind of port type this is,
@@ -3602,10 +3657,18 @@ again:
}
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
+ u_int8_t ts = sp->req_completion_status & 0xff;
MEMZERO(hp, QENTRY_LEN); /* PERF */
- isp_prt(isp, ISP_LOGERR,
- "cannot find handle 0x%x in xflist",
- sp->req_handle);
+ /*
+ * Only whine if this isn't the expected fallout of
+ * aborting the command.
+ */
+ if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE ||
+ ts != RQCS_ABORTED) {
+ isp_prt(isp, ISP_LOGERR,
+ "cannot find handle 0x%x in xflist",
+ sp->req_handle);
+ }
WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
continue;
}
diff --git a/sys/dev/isp/isp_inline.h b/sys/dev/isp/isp_inline.h
index 8f9dc0e..5a1694d 100644
--- a/sys/dev/isp/isp_inline.h
+++ b/sys/dev/isp/isp_inline.h
@@ -293,6 +293,9 @@ static INLINE void
isp_get_gxn_id_response(struct ispsoftc *, sns_gxn_id_rsp_t *,
sns_gxn_id_rsp_t *);
static INLINE void
+isp_get_gff_id_response(struct ispsoftc *, sns_gff_id_rsp_t *,
+ sns_gff_id_rsp_t *);
+static INLINE void
isp_get_ga_nxt_response(struct ispsoftc *, sns_ga_nxt_rsp_t *,
sns_ga_nxt_rsp_t *);
#ifdef ISP_TARGET_MODE
@@ -825,6 +828,18 @@ isp_get_gxn_id_response(struct ispsoftc *isp, sns_gxn_id_rsp_t *src,
}
static INLINE void
+isp_get_gff_id_response(struct ispsoftc *isp, sns_gff_id_rsp_t *src,
+ sns_gff_id_rsp_t *dst)
+{
+ int i;
+ isp_get_ct_hdr(isp, &src->snscb_cthdr, &dst->snscb_cthdr);
+ for (i = 0; i < 32; i++) {
+ ISP_IOXGET_32(isp, &src->snscb_fc4_features[i],
+ dst->snscb_fc4_features[i]);
+ }
+}
+
+static INLINE void
isp_get_ga_nxt_response(struct ispsoftc *isp, sns_ga_nxt_rsp_t *src,
sns_ga_nxt_rsp_t *dst)
{
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index 1bf7648..6241f16 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -804,6 +804,7 @@ typedef struct {
#define SNS_GA_NXT 0x100
#define SNS_GPN_ID 0x112
#define SNS_GNN_ID 0x113
+#define SNS_GFF_ID 0x11F
#define SNS_GID_FT 0x171
#define SNS_RFT_ID 0x217
typedef struct {
@@ -902,6 +903,11 @@ typedef struct {
} sns_gxn_id_rsp_t;
#define SNS_GXN_ID_RESP_SIZE (sizeof (sns_gxn_id_rsp_t))
+typedef struct {
+ ct_hdr_t snscb_cthdr;
+ u_int32_t snscb_fc4_features[32];
+} sns_gff_id_rsp_t;
+#define SNS_GFF_ID_RESP_SIZE (sizeof (sns_gff_id_rsp_t))
typedef struct {
ct_hdr_t snscb_cthdr;
OpenPOWER on IntegriCloud