mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-21 09:13:37 +00:00
Limit fabric search to a default 256 entries. This will all go away
soon because it's just getting harder and harder to find switches that correctly implement the GET ALL NEXT subcommands for the SNS protocol. Latch up result out pointer and set a busy flag when we're looking at the response queue. This allows for a cleaner way to make sure we don't get multiple CPUs trying to read the same response queue entries. Change how isp_handle_other_response returns values (clarity). Make PORT UNAVAILABLE the same as PORT LOGOUT (force a LIP). Do some formatting changes. MFC after: 0 days
This commit is contained in:
parent
7a0933ca5d
commit
371777b161
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=92893
|
@ -2298,6 +2298,9 @@ isp_scan_loop(struct ispsoftc *isp)
|
|||
return (0);
|
||||
}
|
||||
|
||||
#ifndef HICAP_MAX
|
||||
#define HICAP_MAX 256
|
||||
#endif
|
||||
static int
|
||||
isp_scan_fabric(struct ispsoftc *isp)
|
||||
{
|
||||
|
@ -2320,7 +2323,7 @@ isp_scan_fabric(struct ispsoftc *isp)
|
|||
first_portid = portid = fcp->isp_portid;
|
||||
fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
|
||||
|
||||
for (first_portid_seen = hicap = 0; hicap < 65535; hicap++) {
|
||||
for (first_portid_seen = hicap = 0; hicap < HICAP_MAX; hicap++) {
|
||||
mbreg_t mbs;
|
||||
sns_screq_t *rq;
|
||||
sns_ganrsp_t *rs0, *rs1;
|
||||
|
@ -3133,6 +3136,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
|
|||
} else {
|
||||
iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
|
||||
}
|
||||
isp->isp_resodx = iptr;
|
||||
|
||||
|
||||
if (optr == iptr && sema == 0) {
|
||||
|
@ -3167,9 +3171,15 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
|
|||
isr, junk, iptr, optr);
|
||||
}
|
||||
}
|
||||
isp->isp_resodx = iptr;
|
||||
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
|
||||
ISP_WRITE(isp, BIU_SEMA, 0);
|
||||
|
||||
if (isp->isp_rspbsy) {
|
||||
return;
|
||||
}
|
||||
isp->isp_rspbsy = 1;
|
||||
|
||||
while (optr != iptr) {
|
||||
ispstatusreq_t local, *sp = &local;
|
||||
isphdr_t *hp;
|
||||
|
@ -3198,19 +3208,17 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
|
|||
}
|
||||
if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
|
||||
isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
|
||||
MEMZERO(hp, QENTRY_LEN); /* PERF */
|
||||
continue;
|
||||
} else {
|
||||
/*
|
||||
* Somebody reachable via isp_handle_other_response
|
||||
* may have updated the response queue pointers for
|
||||
* us.
|
||||
* us, so we reload our goal index.
|
||||
*/
|
||||
oop = optr;
|
||||
if (!isp_handle_other_response(isp, type, hp, &optr)) {
|
||||
if (isp_handle_other_response(isp, type, hp, &optr)) {
|
||||
iptr = isp->isp_resodx;
|
||||
MEMZERO(hp, QENTRY_LEN); /* PERF */
|
||||
if (oop != optr) {
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3438,7 +3446,7 @@ isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
|
|||
}
|
||||
|
||||
isp->isp_residx = optr;
|
||||
out:
|
||||
isp->isp_rspbsy = 0;
|
||||
for (i = 0; i < ndone; i++) {
|
||||
xs = complist[i];
|
||||
if (xs) {
|
||||
|
@ -3788,7 +3796,7 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
|
|||
switch (type) {
|
||||
case RQSTYPE_STATUS_CONT:
|
||||
isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
|
||||
return (0);
|
||||
return (1);
|
||||
case RQSTYPE_ATIO:
|
||||
case RQSTYPE_CTIO:
|
||||
case RQSTYPE_ENABLE_LUN:
|
||||
|
@ -3801,7 +3809,9 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
|
|||
case RQSTYPE_CTIO3:
|
||||
isp->isp_rsltccmplt++; /* count as a response completion */
|
||||
#ifdef ISP_TARGET_MODE
|
||||
return (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp));
|
||||
if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
|
||||
return (1);
|
||||
}
|
||||
#else
|
||||
optrp = optrp;
|
||||
/* FALLTHROUGH */
|
||||
|
@ -3809,11 +3819,11 @@ isp_handle_other_response(struct ispsoftc *isp, int type,
|
|||
case RQSTYPE_REQUEST:
|
||||
default:
|
||||
if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
|
||||
isp_get_response_type(isp, hp));
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4117,18 +4127,16 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
|
|||
/*
|
||||
* No such port on the loop. Moral equivalent of SELTIMEO
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"Port Unavailable for target %d", XS_TGT(xs));
|
||||
if (XS_NOERR(xs)) {
|
||||
XS_SETERR(xs, HBA_SELTIMEOUT);
|
||||
}
|
||||
return;
|
||||
case RQCS_PORT_LOGGED_OUT:
|
||||
/*
|
||||
* It was there (maybe)- treat as a selection timeout.
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"port logout for target %d", XS_TGT(xs));
|
||||
if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"Port Unavailable for target %d", XS_TGT(xs));
|
||||
else
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"port logout for target %d", XS_TGT(xs));
|
||||
/*
|
||||
* If we're on a local loop, force a LIP (which is overkill)
|
||||
* to force a re-login of this unit.
|
||||
|
|
|
@ -409,9 +409,9 @@ typedef struct {
|
|||
isphdr_t ct_header;
|
||||
u_int16_t ct_reserved;
|
||||
u_int16_t ct_fwhandle; /* just to match CTIO */
|
||||
u_int8_t ct_lun; /* lun */
|
||||
u_int8_t ct_iid; /* initiator id */
|
||||
u_int16_t ct_rxid; /* response ID */
|
||||
u_int8_t ct_lun; /* lun */
|
||||
u_int8_t ct_iid; /* initiator id */
|
||||
u_int16_t ct_rxid; /* response ID */
|
||||
u_int16_t ct_flags;
|
||||
u_int16_t ct_status; /* isp status */
|
||||
u_int16_t ct_timeout;
|
||||
|
|
|
@ -73,7 +73,7 @@ struct ispmdvec {
|
|||
void (*dv_reset0) (struct ispsoftc *);
|
||||
void (*dv_reset1) (struct ispsoftc *);
|
||||
void (*dv_dregs) (struct ispsoftc *, const char *);
|
||||
const u_int16_t *dv_ispfw; /* ptr to f/w */
|
||||
u_int16_t *dv_ispfw; /* ptr to f/w */
|
||||
u_int16_t dv_conf1;
|
||||
u_int16_t dv_clock; /* clock frequency */
|
||||
};
|
||||
|
@ -396,6 +396,8 @@ typedef struct ispsoftc {
|
|||
volatile u_int16_t isp_reqodx; /* index of last ISP pickup */
|
||||
volatile u_int16_t isp_reqidx; /* index of next request */
|
||||
volatile u_int16_t isp_residx; /* index of next result */
|
||||
volatile u_int16_t isp_resodx; /* index of next result */
|
||||
volatile u_int16_t isp_rspbsy;
|
||||
volatile u_int16_t isp_lasthdls; /* last handle seed */
|
||||
volatile u_int16_t isp_mboxtmp[MAX_MAILBOX];
|
||||
volatile u_int16_t isp_lastmbxcmd; /* last mbox command sent */
|
||||
|
|
Loading…
Reference in a new issue