Move 24xx RQSTYPE_NOTIFY handling to generic code.
This code has nothing to do with specific platform. MFC after: 2 weeks
This commit is contained in:
parent
15e58d4d26
commit
5a5632c2de
@ -788,7 +788,6 @@ static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How
|
||||
static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
|
||||
static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
|
||||
static void isp_handle_platform_ctio(ispsoftc_t *, void *);
|
||||
static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
|
||||
static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
|
||||
static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
|
||||
static void isp_target_mark_aborted_early(ispsoftc_t *, int chan, tstate_t *, uint32_t);
|
||||
@ -2108,28 +2107,24 @@ mdp:
|
||||
|
||||
|
||||
static void
|
||||
isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
|
||||
isp_handle_platform_srr(ispsoftc_t *isp, isp_notify_t *notify)
|
||||
{
|
||||
in_fcentry_24xx_t *inot = inot_raw;
|
||||
in_fcentry_24xx_t *inot = notify->nt_lreserved;
|
||||
atio_private_data_t *atp;
|
||||
uint32_t tag = inot->in_rxid;
|
||||
uint32_t bus = inot->in_vpidx;
|
||||
uint32_t tag = notify->nt_tagval & 0xffffffff;
|
||||
|
||||
if (!IS_24XX(isp)) {
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_raw);
|
||||
return;
|
||||
}
|
||||
|
||||
atp = isp_find_atpd(isp, bus, tag);
|
||||
atp = isp_find_atpd(isp, notify->nt_channel, tag);
|
||||
if (atp == NULL) {
|
||||
isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag);
|
||||
isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify",
|
||||
__func__, tag);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
return;
|
||||
}
|
||||
atp->srr_notify_rcvd = 1;
|
||||
memcpy(atp->srr, inot, sizeof (atp->srr));
|
||||
isp_prt(isp, ISP_LOGTINFO /* ISP_LOGTDEBUG0 */, "SRR[0x%x] inot->in_rxid flags 0x%x srr_iu=%x reloff 0x%x", inot->in_rxid, inot->in_flags, inot->in_srr_iu,
|
||||
inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16));
|
||||
isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] flags 0x%x srr_iu %x reloff 0x%x",
|
||||
inot->in_rxid, inot->in_flags, inot->in_srr_iu,
|
||||
((uint32_t)inot->in_srr_reloff_hi << 16) | inot->in_srr_reloff_lo);
|
||||
if (atp->srr_ccb)
|
||||
isp_handle_srr_start(isp, atp);
|
||||
}
|
||||
@ -2281,127 +2276,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
|
||||
{
|
||||
uint16_t nphdl;
|
||||
uint16_t prli_options = 0;
|
||||
uint32_t portid;
|
||||
fcportdb_t *lp;
|
||||
char *msg = NULL;
|
||||
uint8_t *ptr = (uint8_t *)inot;
|
||||
uint64_t wwpn = INI_NONE, wwnn = INI_NONE;
|
||||
|
||||
nphdl = inot->in_nphdl;
|
||||
if (nphdl != NIL_HANDLE) {
|
||||
portid = inot->in_portid_hi << 16 | inot->in_portid_lo;
|
||||
} else {
|
||||
portid = PORT_ANY;
|
||||
}
|
||||
|
||||
switch (inot->in_status) {
|
||||
case IN24XX_ELS_RCVD:
|
||||
{
|
||||
char buf[16];
|
||||
int chan = ISP_GET_VPIDX(isp, inot->in_vpidx);
|
||||
|
||||
/*
|
||||
* Note that we're just getting notification that an ELS was received
|
||||
* (possibly with some associated information sent upstream). This is
|
||||
* *not* the same as being given the ELS frame to accept or reject.
|
||||
*/
|
||||
switch (inot->in_status_subcode) {
|
||||
case LOGO:
|
||||
msg = "LOGO";
|
||||
wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
|
||||
isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid);
|
||||
break;
|
||||
case PRLO:
|
||||
msg = "PRLO";
|
||||
break;
|
||||
case PLOGI:
|
||||
msg = "PLOGI";
|
||||
wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]);
|
||||
wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
|
||||
isp_add_wwn_entry(isp, chan, wwpn, wwnn,
|
||||
nphdl, portid, prli_options);
|
||||
break;
|
||||
case PRLI:
|
||||
msg = "PRLI";
|
||||
prli_options = inot->in_prli_options;
|
||||
if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID)
|
||||
wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]);
|
||||
wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]);
|
||||
isp_add_wwn_entry(isp, chan, wwpn, wwnn,
|
||||
nphdl, portid, prli_options);
|
||||
break;
|
||||
case PDISC:
|
||||
msg = "PDISC";
|
||||
break;
|
||||
case ADISC:
|
||||
msg = "ADISC";
|
||||
break;
|
||||
default:
|
||||
ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x", inot->in_status_subcode);
|
||||
msg = buf;
|
||||
break;
|
||||
}
|
||||
if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) {
|
||||
isp_prt(isp, ISP_LOGERR, "%s Chan %d ELS N-port handle %x PortID 0x%06x marked as needing a PUREX response", msg, chan, nphdl, portid);
|
||||
break;
|
||||
}
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "%s Chan %d ELS N-port handle %x PortID 0x%06x RX_ID 0x%x OX_ID 0x%x", msg, chan, nphdl, portid,
|
||||
inot->in_rxid, inot->in_oxid);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
break;
|
||||
}
|
||||
|
||||
case IN24XX_PORT_LOGOUT:
|
||||
msg = "PORT LOGOUT";
|
||||
if (isp_find_pdb_by_handle(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) {
|
||||
isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case IN24XX_PORT_CHANGED:
|
||||
if (msg == NULL)
|
||||
msg = "PORT CHANGED";
|
||||
/* FALLTHROUGH */
|
||||
case IN24XX_LIP_RESET:
|
||||
if (msg == NULL)
|
||||
msg = "LIP RESET";
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), msg, inot->in_status_subcode, nphdl);
|
||||
|
||||
/*
|
||||
* All subcodes here are irrelevant. What is relevant
|
||||
* is that we need to terminate all active commands from
|
||||
* this initiator (known by N-port handle).
|
||||
*/
|
||||
/* XXX IMPLEMENT XXX */
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
break;
|
||||
|
||||
case IN24XX_SRR_RCVD:
|
||||
#ifdef ISP_TARGET_MODE
|
||||
isp_handle_srr_notify(isp, inot);
|
||||
break;
|
||||
#else
|
||||
if (msg == NULL)
|
||||
msg = "SRR RCVD";
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case IN24XX_LINK_RESET:
|
||||
if (msg == NULL)
|
||||
msg = "LINK RESET";
|
||||
case IN24XX_LINK_FAILED:
|
||||
if (msg == NULL)
|
||||
msg = "LINK FAILED";
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), msg);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp, uint32_t rsp)
|
||||
{
|
||||
@ -4044,6 +3918,9 @@ changed:
|
||||
*/
|
||||
isp_handle_platform_target_notify_ack(isp, notify, 0);
|
||||
break;
|
||||
case NT_SRR:
|
||||
isp_handle_platform_srr(isp, notify);
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
|
||||
isp_handle_platform_target_notify_ack(isp, notify, 0);
|
||||
@ -4080,12 +3957,6 @@ changed:
|
||||
hp = va_arg(ap, isphdr_t *);
|
||||
va_end(ap);
|
||||
switch (hp->rqs_entry_type) {
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type);
|
||||
break;
|
||||
case RQSTYPE_NOTIFY:
|
||||
isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp);
|
||||
break;
|
||||
case RQSTYPE_ATIO:
|
||||
isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
|
||||
break;
|
||||
@ -4098,6 +3969,10 @@ changed:
|
||||
case RQSTYPE_CTIO:
|
||||
isp_handle_platform_ctio(isp, hp);
|
||||
break;
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x",
|
||||
__func__, hp->rqs_entry_type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
#define hdrp unp.hp
|
||||
} unp;
|
||||
uint8_t local[QENTRY_LEN];
|
||||
int bus, type, len, level, rval = 1;
|
||||
int type, len, level, rval = 1;
|
||||
|
||||
type = isp_get_response_type(isp, (isphdr_t *)vptr);
|
||||
unp.vp = vptr;
|
||||
@ -214,11 +214,9 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
|
||||
break;
|
||||
|
||||
case RQSTYPE_NOTIFY:
|
||||
bus = 0;
|
||||
if (IS_24XX(isp)) {
|
||||
isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local);
|
||||
inot_24xx = (in_fcentry_24xx_t *) local;
|
||||
isp_handle_notify_24xx(isp, inot_24xx);
|
||||
isp_handle_notify_24xx(isp, (in_fcentry_24xx_t *)local);
|
||||
break;
|
||||
}
|
||||
if (ISP_CAP_2KLOGIN(isp))
|
||||
@ -1380,51 +1378,152 @@ isp_handle_notify(ispsoftc_t *isp, in_fcentry_t *inp)
|
||||
}
|
||||
|
||||
static void
|
||||
isp_handle_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
|
||||
isp_handle_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
|
||||
{
|
||||
uint8_t ochan, chan, lochan, hichan;
|
||||
uint8_t chan;
|
||||
uint16_t nphdl, prli_options = 0;
|
||||
uint32_t portid;
|
||||
fcportdb_t *lp;
|
||||
char *msg = NULL;
|
||||
uint8_t *ptr = (uint8_t *)inot;
|
||||
uint64_t wwpn = INI_NONE, wwnn = INI_NONE;
|
||||
isp_notify_t notify;
|
||||
char buf[16];
|
||||
|
||||
/*
|
||||
* Check to see whether we got a wildcard channel.
|
||||
* If so, we have to iterate over all channels.
|
||||
*/
|
||||
ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx);
|
||||
if (chan == 0xff) {
|
||||
lochan = 0;
|
||||
hichan = isp->isp_nchan;
|
||||
nphdl = inot->in_nphdl;
|
||||
if (nphdl != NIL_HANDLE) {
|
||||
portid = inot->in_portid_hi << 16 | inot->in_portid_lo;
|
||||
} else {
|
||||
if (chan >= isp->isp_nchan) {
|
||||
char buf[64];
|
||||
ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status);
|
||||
isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx);
|
||||
return;
|
||||
}
|
||||
lochan = chan;
|
||||
hichan = chan + 1;
|
||||
portid = PORT_ANY;
|
||||
}
|
||||
isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid);
|
||||
switch (inot_24xx->in_status) {
|
||||
case IN24XX_LIP_RESET:
|
||||
case IN24XX_LINK_RESET:
|
||||
case IN24XX_PORT_LOGOUT:
|
||||
case IN24XX_PORT_CHANGED:
|
||||
case IN24XX_LINK_FAILED:
|
||||
case IN24XX_SRR_RCVD:
|
||||
|
||||
chan = ISP_GET_VPIDX(isp, inot->in_vpidx);
|
||||
if (chan >= isp->isp_nchan &&
|
||||
inot->in_status != IN24XX_LIP_RESET &&
|
||||
inot->in_status != IN24XX_LINK_RESET &&
|
||||
inot->in_status != IN24XX_LINK_FAILED) {
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: Received INOT with status %x on VP %x",
|
||||
__func__, inot->in_status, chan);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (inot->in_status) {
|
||||
case IN24XX_ELS_RCVD:
|
||||
for (chan = lochan; chan < hichan; chan++) {
|
||||
if (FCPARAM(isp, chan)->role == ISP_ROLE_NONE)
|
||||
continue;
|
||||
inot_24xx->in_reserved = 0; /* clear this for later usage */
|
||||
inot_24xx->in_vpidx = chan;
|
||||
isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx);
|
||||
{
|
||||
/*
|
||||
* Note that we're just getting notification that an ELS was
|
||||
* received (possibly with some associated information sent
|
||||
* upstream). This is *not* the same as being given the ELS
|
||||
* frame to accept or reject.
|
||||
*/
|
||||
switch (inot->in_status_subcode) {
|
||||
case LOGO:
|
||||
msg = "LOGO";
|
||||
wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
|
||||
isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid);
|
||||
break;
|
||||
case PRLO:
|
||||
msg = "PRLO";
|
||||
break;
|
||||
case PLOGI:
|
||||
msg = "PLOGI";
|
||||
wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]);
|
||||
wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
|
||||
isp_add_wwn_entry(isp, chan, wwpn, wwnn,
|
||||
nphdl, portid, prli_options);
|
||||
break;
|
||||
case PRLI:
|
||||
msg = "PRLI";
|
||||
prli_options = inot->in_prli_options;
|
||||
if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID)
|
||||
wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]);
|
||||
wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]);
|
||||
isp_add_wwn_entry(isp, chan, wwpn, wwnn,
|
||||
nphdl, portid, prli_options);
|
||||
break;
|
||||
case PDISC:
|
||||
msg = "PDISC";
|
||||
break;
|
||||
case ADISC:
|
||||
msg = "ADISC";
|
||||
break;
|
||||
default:
|
||||
ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x",
|
||||
inot->in_status_subcode);
|
||||
msg = buf;
|
||||
break;
|
||||
}
|
||||
inot_24xx->in_vpidx = ochan;
|
||||
if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) {
|
||||
isp_prt(isp, ISP_LOGERR, "%s Chan %d ELS N-port handle %x"
|
||||
" PortID 0x%06x marked as needing a PUREX response",
|
||||
msg, chan, nphdl, portid);
|
||||
break;
|
||||
}
|
||||
isp_prt(isp, ISP_LOGTDEBUG0, "%s Chan %d ELS N-port handle %x"
|
||||
" PortID 0x%06x RX_ID 0x%x OX_ID 0x%x", msg, chan, nphdl,
|
||||
portid, inot->in_rxid, inot->in_oxid);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
break;
|
||||
}
|
||||
|
||||
case IN24XX_PORT_LOGOUT:
|
||||
msg = "PORT LOGOUT";
|
||||
if (isp_find_pdb_by_handle(isp, chan, nphdl, &lp))
|
||||
isp_del_wwn_entry(isp, chan, lp->port_wwn, nphdl, lp->portid);
|
||||
/* FALLTHROUGH */
|
||||
case IN24XX_PORT_CHANGED:
|
||||
if (msg == NULL)
|
||||
msg = "PORT CHANGED";
|
||||
/* FALLTHROUGH */
|
||||
case IN24XX_LIP_RESET:
|
||||
if (msg == NULL)
|
||||
msg = "LIP RESET";
|
||||
isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for "
|
||||
"N-port handle 0x%x",
|
||||
chan, msg, inot->in_status_subcode, nphdl);
|
||||
|
||||
/*
|
||||
* All subcodes here are irrelevant. What is relevant
|
||||
* is that we need to terminate all active commands from
|
||||
* this initiator (known by N-port handle).
|
||||
*/
|
||||
/* XXX IMPLEMENT XXX */
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
break;
|
||||
|
||||
case IN24XX_SRR_RCVD:
|
||||
#ifdef ISP_TARGET_MODE
|
||||
ISP_MEMZERO(¬ify, sizeof (isp_notify_t));
|
||||
notify.nt_hba = isp;
|
||||
notify.nt_wwn = INI_ANY;
|
||||
notify.nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
|
||||
notify.nt_nphdl = nphdl;
|
||||
notify.nt_sid = portid;
|
||||
notify.nt_did = PORT_ANY;
|
||||
notify.nt_lun = LUN_ANY;
|
||||
notify.nt_tagval = inot->in_rxid;
|
||||
notify.nt_tagval |= ((uint64_t)inot->in_srr_rxid << 32);
|
||||
notify.nt_need_ack = 1;
|
||||
notify.nt_channel = chan;
|
||||
notify.nt_lreserved = inot;
|
||||
notify.nt_ncode = NT_SRR;
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
#else
|
||||
if (msg == NULL)
|
||||
msg = "SRR RCVD";
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
case IN24XX_LINK_RESET:
|
||||
if (msg == NULL)
|
||||
msg = "LINK RESET";
|
||||
case IN24XX_LINK_FAILED:
|
||||
if (msg == NULL)
|
||||
msg = "LINK FAILED";
|
||||
default:
|
||||
isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d",
|
||||
__func__, inot_24xx->in_status, chan);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx);
|
||||
isp_prt(isp, ISP_LOGWARN, "Chan %d %s", chan, msg);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ typedef enum {
|
||||
NT_CHANGED,
|
||||
NT_HBA_RESET,
|
||||
NT_QUERY_TASK_SET,
|
||||
NT_QUERY_ASYNC_EVENT
|
||||
NT_QUERY_ASYNC_EVENT,
|
||||
NT_SRR /* Sequence Retransmission Request */
|
||||
} isp_ncode_t;
|
||||
|
||||
typedef struct isp_notify {
|
||||
|
Loading…
x
Reference in New Issue
Block a user