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).
This commit is contained in:
Matt Jacob 2002-04-16 19:55:35 +00:00
parent 0cde2d130e
commit 4a999c65de
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=94867
3 changed files with 112 additions and 28 deletions

View File

@ -773,7 +773,7 @@ isp_reset(struct ispsoftc *isp)
* 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 @@ isp_reset(struct ispsoftc *isp)
}
} 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 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
}
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;
}

View File

@ -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
@ -824,6 +827,18 @@ isp_get_gxn_id_response(struct ispsoftc *isp, sns_gxn_id_rsp_t *src,
ISP_IOXGET_8(isp, &src->snscb_wwn[i], dst->snscb_wwn[i]);
}
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)

View File

@ -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;