From 15d36dcaad5dbc36ce1fb0ca19fbafbdaade0bc8 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 12 Feb 2008 09:51:21 +0000 Subject: [PATCH] Synchronize with Feral CVS repository: - Clean up 24XX abort handling. - Remove the response queue busy stuff and just have an in_intr flag to note interrupt recursion. - Add a lower level error flag. - Clarifiy a comment; make a definition for the 'no task' RX_ID. - Change severity of f/w timeout message - Do the wait for mbox0 clearing for 2312 cards > revision 1. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@267 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla_isp/common/isp.c | 29 +++++++++-------- qla_isp/common/isp_target.c | 8 ++--- qla_isp/common/isp_target.h | 6 ++-- qla_isp/common/isp_tpublic.h | 3 +- qla_isp/common/ispvar.h | 6 ++-- qla_isp/linux/isp_linux.c | 63 ++++++++++++++++++------------------ 6 files changed, 61 insertions(+), 54 deletions(-) diff --git a/qla_isp/common/isp.c b/qla_isp/common/isp.c index 4aa5f1b54..e794f8a83 100644 --- a/qla_isp/common/isp.c +++ b/qla_isp/common/isp.c @@ -1,4 +1,4 @@ -/* $Id: isp.c,v 1.183 2007/12/05 00:42:02 mjacob Exp $ */ +/* $Id: isp.c,v 1.184 2007/12/20 18:26:18 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -688,10 +688,10 @@ isp_reset(ispsoftc_t *isp) /* * Wait for everything to finish firing up. * - * Avoid doing this on the 2312 because you can generate a PCI + * Avoid doing this on early 2312s because you can generate a PCI * parity error (chip breakage). */ - if (IS_2312(isp)) { + if (IS_2312(isp) && isp->isp_revision < 2) { USEC_DELAY(100); } else { loops = MBOX_DELAY_COUNT; @@ -1068,7 +1068,7 @@ isp_reset(ispsoftc_t *isp) isp->isp_fwrev[2] = mbs.param[3]; } - isp_prt(isp, ISP_LOGALL, + isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d", btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]); @@ -1920,6 +1920,9 @@ isp_fibre_init_2400(ispsoftc_t *isp) break; } + /* force this on for now */ + icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO; + switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) { case ICB2400_OPT2_ZIO: case ICB2400_OPT2_ZIO1: @@ -4750,6 +4753,11 @@ isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox) uint32_t iptr, optr, junk; int i, nlooked = 0, ndone = 0; + if (isp->isp_in_intr) { + isp_prt(isp, ISP_LOGERR, "recursive isp_intr!"); + return; + } + isp->isp_in_intr = 1; again: optr = isp->isp_residx; /* @@ -4772,6 +4780,7 @@ again: } if (isp->isp_mbxwrk0) { if (isp_mbox_continue(isp) == 0) { + isp->isp_in_intr = 0; return; } } @@ -4781,6 +4790,7 @@ again: "mailbox cmd (0x%x) with no waiters", mbox); } } else if (isp_parse_async(isp, mbox) < 0) { + isp->isp_in_intr = 0; return; } if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || @@ -4817,11 +4827,10 @@ again: /* * Check for ATIO Queue entries. */ - if (isp->isp_rspbsy == 0 && IS_24XX(isp)) { + if (IS_24XX(isp)) { iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP); optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP); - isp->isp_rspbsy = 1; while (optr != iptr) { uint8_t qe[QENTRY_LEN]; isphdr_t *hp; @@ -4846,7 +4855,6 @@ again: optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp)); ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr); } - isp->isp_rspbsy = 0; optr = isp->isp_residx; } #endif @@ -4932,11 +4940,6 @@ again: } isp->isp_resodx = iptr; - - if (isp->isp_rspbsy) { - goto out; - } - isp->isp_rspbsy = 1; while (optr != iptr) { uint8_t qe[QENTRY_LEN]; ispstatusreq_t *sp = (ispstatusreq_t *) qe; @@ -5292,7 +5295,6 @@ out: } isp->isp_residx = optr; - isp->isp_rspbsy = 0; for (i = 0; i < ndone; i++) { xs = complist[i]; if (xs) { @@ -5300,6 +5302,7 @@ out: isp_done(xs); } } + isp->isp_in_intr = 0; } /* diff --git a/qla_isp/common/isp_target.c b/qla_isp/common/isp_target.c index 41793ebed..969beea8d 100644 --- a/qla_isp/common/isp_target.c +++ b/qla_isp/common/isp_target.c @@ -1,4 +1,4 @@ -/* $Id: isp_target.c,v 1.72 2007/12/11 22:19:21 mjacob Exp $ */ +/* $Id: isp_target.c,v 1.73 2007/12/20 18:23:45 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -1429,7 +1429,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) case CT_TIMEOUT: if (fmsg == NULL) fmsg = "Command"; - isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); + isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); break; case CT_PANIC: @@ -1570,7 +1570,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) case CT_TIMEOUT: if (fmsg == NULL) fmsg = "command"; - isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); + isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); break; case CT_ERR: @@ -1712,7 +1712,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) if (fmsg == NULL) { fmsg = "command"; } - isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); + isp_prt(isp, ISP_LOGWARN, "Firmware timed out on %s", fmsg); break; case CT7_ERR: diff --git a/qla_isp/common/isp_target.h b/qla_isp/common/isp_target.h index d475015ac..9b69e5296 100644 --- a/qla_isp/common/isp_target.h +++ b/qla_isp/common/isp_target.h @@ -1,4 +1,4 @@ -/* $Id: isp_target.h,v 1.57 2007/12/04 22:19:15 mjacob Exp $ */ +/* $Id: isp_target.h,v 1.58 2007/12/20 18:24:40 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -786,7 +786,7 @@ typedef struct { uint8_t ct_iid_hi; /* hi 8 bits of portid */ uint8_t ct_reserved; uint32_t ct_rxid; - uint16_t ct_senselen; /* mode 0 only */ + uint16_t ct_senselen; /* mode 1 only */ uint16_t ct_flags; int32_t ct_resid; /* residual length */ uint16_t ct_oxid; @@ -947,6 +947,8 @@ typedef struct { #define ISP24XX_ABTS_RSP_LOGOUT 0x29 #define ISP24XX_ABTS_RSP_SUBCODE 0x31 +#define ISP24XX_NO_TASK 0xffffffff + /* * Debug macros */ diff --git a/qla_isp/common/isp_tpublic.h b/qla_isp/common/isp_tpublic.h index 5faab6ed6..9a20597f4 100644 --- a/qla_isp/common/isp_tpublic.h +++ b/qla_isp/common/isp_tpublic.h @@ -1,4 +1,4 @@ -/* $Id: isp_tpublic.h,v 1.39 2007/12/03 18:29:46 mjacob Exp $ */ +/* $Id: isp_tpublic.h,v 1.40 2007/12/20 18:27:06 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -288,6 +288,7 @@ typedef struct tmd_xact { #define TDFL_SENTSTATUS 0x01 /* this transaction sent status */ #define TDFL_SENTSENSE 0x02 /* this transaction sent sense data */ +#define TDFL_ERROR 0x04 /* this transaction had an error */ #define TDFL_PRIVATE 0xF0 /* private inner layer usage */ /* diff --git a/qla_isp/common/ispvar.h b/qla_isp/common/ispvar.h index daceff939..ad0ca8c5b 100644 --- a/qla_isp/common/ispvar.h +++ b/qla_isp/common/ispvar.h @@ -1,4 +1,4 @@ -/* $Id: ispvar.h,v 1.88 2007/12/11 07:17:56 mjacob Exp $ */ +/* $Id: ispvar.h,v 1.89 2007/12/20 18:26:46 mjacob Exp $ */ /*- * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -561,7 +561,8 @@ struct ispsoftc { */ volatile uint32_t : 8, - : 4, + : 3, + isp_in_intr : 1, isp_mboxbsy : 1, /* mailbox command active */ isp_state : 3, isp_nactive : 16; /* how many commands active */ @@ -569,7 +570,6 @@ struct ispsoftc { volatile uint32_t isp_reqidx; /* index of next request */ volatile uint32_t isp_residx; /* index of next result */ volatile uint32_t isp_resodx; /* index of next result */ - volatile uint32_t isp_rspbsy; volatile uint32_t isp_lasthdls; /* last handle seed */ volatile uint32_t isp_obits; /* mailbox command output */ volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE]; diff --git a/qla_isp/linux/isp_linux.c b/qla_isp/linux/isp_linux.c index 789e18b19..b75995eb4 100644 --- a/qla_isp/linux/isp_linux.c +++ b/qla_isp/linux/isp_linux.c @@ -1,4 +1,4 @@ -/* $Id: isp_linux.c,v 1.214 2007/12/12 21:14:55 mjacob Exp $ */ +/* $Id: isp_linux.c,v 1.215 2007/12/20 18:28:00 mjacob Exp $ */ /* * Copyright (c) 1997-2007 by Matthew Jacob * All rights reserved. @@ -1357,15 +1357,14 @@ isp_taction(qact_e action, void *arg) if (isp->isp_state != ISP_RUNSTATE) { isp_prt(isp, ISP_LOGINFO, "[%llx] Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid); - } else if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { + } else if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ABTS_RSP) { abts_t *abt = (abts_t *)ins->qentry; abts_rsp_t *rsp = (abts_rsp_t *)ins->qentry; uint16_t rx_id, ox_id; - isp_prt(isp, ISP_LOGINFO, "ABTS for 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts); + isp_prt(isp, ISP_LOGTINFO, "ABTS for 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts); rx_id = abt->abts_rx_id; ox_id = abt->abts_ox_id; - rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; rsp->abts_rsp_handle = rsp->abts_rsp_rxid_abts; rsp->abts_rsp_r_ctl = BA_ACC; MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc)); @@ -3253,7 +3252,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; default: if (isp_find_loopid_wwn(isp, mp->nt_channel, loopid, &ins->notify.nt_iid) == 0) { - isp_prt(isp, ISP_LOGINFO, "cannot find WWN for loopid 0x%x for notify action 0x%x", loopid, mp->nt_ncode); + isp_prt(isp, ISP_LOGTINFO, "cannot find WWN for loopid 0x%x for notify action 0x%x", loopid, mp->nt_ncode); ins->notify.nt_iid = INI_NONE; } break; @@ -3265,7 +3264,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } else { TAG_INSERT_INST(mp->nt_tagval, isp->isp_unit); } - isp_prt(isp, ISP_LOGDEBUG0, "Notify Code 0x%x iid 0x%016llx tgt 0x%016llx lun %u tag %llx", + isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x iid 0x%016llx tgt 0x%016llx lun %u tag %llx", mp->nt_ncode, (unsigned long long) mp->nt_iid, (unsigned long long) mp->nt_tgt, mp->nt_lun, mp->nt_tagval); CALL_PARENT_NOTIFY(isp, ins); @@ -3309,18 +3308,37 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) abts_t *abts = qe; abts_rsp_t *rsp = qe; int chan, i; + uint32_t sid; + + rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; + sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; if (isp->isp_osinfo.hcb == 0) { isp_prt(isp, ISP_LOGINFO, "RQSTYPE_ABTS_RCVD: with no upstream listener"); - rsp->abts_rsp_handle = rsp->abts_rsp_rxid_abts; + rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; + isp_notify_ack(isp, qe); + break; + } + if (abts->abts_rxid_task == ISP24XX_NO_TASK) { + isp_prt(isp, ISP_LOGTINFO, "ABTS from N-Port handle 0x%x Port 0x%06x has no task id (rx_id 0x%04x ox_id 0x%04x)", + abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id); + for (i = 0; i < NTGT_CMDS; i++) { + tmd_cmd_t *tmd = &isp->isp_osinfo.pool[i]; + if (tmd->cd_lflags & CDFL_BUSY) { + if (AT2_GET_TAG(tmd->cd_tagval) == abts->abts_rx_id && tmd->cd_oxid == abts->abts_ox_id) { + isp_prt(isp, ISP_LOGTINFO, "... but found tmd to to mark as aborted"); + tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP; + break; + } + } + } rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; isp_notify_ack(isp, qe); break; } ins = isp->isp_osinfo.nfreelist; if (ins == NULL) { - isp_prt(isp, ISP_LOGINFO, "out of TMD NOTIFY structs for RQSTYPE_ABTS_RCVD!"); - rsp->abts_rsp_handle = rsp->abts_rsp_rxid_abts; + isp_prt(isp, ISP_LOGTINFO, "out of TMD NOTIFY structs for RQSTYPE_ABTS_RCVD"); rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; isp_notify_ack(isp, qe); break; @@ -3333,13 +3351,8 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } } if (chan == isp->isp_nchan) { - isp_prt(isp, ISP_LOGINFO, "cannot find WWN for N-port handle 0x%x for ABTS", abts->abts_nphdl); - rsp->abts_rsp_handle = rsp->abts_rsp_rxid_abts; - rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; - isp_notify_ack(isp, qe); - ins->notify.nt_lreserved = isp->isp_osinfo.nfreelist; - isp->isp_osinfo.nfreelist = ins; - break; + isp_prt(isp, ISP_LOGTINFO, "cannot find WWN for N-port handle 0x%x for ABTS", abts->abts_nphdl); + ins->notify.nt_iid = INI_ANY; } MEMCPY(ins->qentry, qe, QENTRY_LEN); ins->qevalid = 1; @@ -3347,6 +3360,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) ins->notify.nt_tgt = FCPARAM(isp, chan)->isp_wwpn; ins->notify.nt_lun = LUN_ANY; ins->notify.nt_tagval = abts->abts_rxid_task; + FC_TAG_INSERT_INST(ins->notify.nt_tagval, isp->isp_unit); ins->notify.nt_ncode = NT_ABORT_TASK; ins->notify.nt_need_ack = 1; ins->notify.nt_channel = chan; @@ -3362,21 +3376,8 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } } } - if (ins->notify.nt_tagval == 0xffffffff) { - abts_rsp_t *rsp = (abts_rsp_t *)ins->qentry; - rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; - rsp->abts_rsp_handle = rsp->abts_rsp_rxid_abts; - rsp->abts_rsp_r_ctl = BA_RJT; - MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_rjt)); - rsp->abts_rsp_payload.ba_rjt.reason = 9; /* unable to perform request */ - rsp->abts_rsp_payload.ba_rjt.explanation = 3; /* invalid ox_id/rx_id combo */ - isp_notify_ack(isp, ins->qentry); - ins->notify.nt_lreserved = isp->isp_osinfo.nfreelist; - isp->isp_osinfo.nfreelist = ins; - } else { - isp_prt(isp, ISP_LOGINFO, "ABTS [%llx] from 0x%016llx", ins->notify.nt_tagval, ins->notify.nt_iid); - CALL_PARENT_NOTIFY(isp, ins); - } + isp_prt(isp, ISP_LOGTINFO, "ABTS [%llx] from 0x%016llx", ins->notify.nt_tagval, ins->notify.nt_iid); + CALL_PARENT_NOTIFY(isp, ins); break; } case RQSTYPE_NOTIFY: