From owner-p4-projects@FreeBSD.ORG Fri Sep 15 23:13:03 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2F33616A416; Fri, 15 Sep 2006 23:13:03 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E2A8016A40F for ; Fri, 15 Sep 2006 23:13:02 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 90D9B43D62 for ; Fri, 15 Sep 2006 23:12:58 +0000 (GMT) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8FNCwdD056692 for ; Fri, 15 Sep 2006 23:12:58 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8FNCw5c056689 for perforce@freebsd.org; Fri, 15 Sep 2006 23:12:58 GMT (envelope-from mjacob@freebsd.org) Date: Fri, 15 Sep 2006 23:12:58 GMT Message-Id: <200609152312.k8FNCw5c056689@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 106178 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 23:13:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=106178 Change 106178 by mjacob@newisp on 2006/09/15 23:12:52 An amazingly large amount of changes for so little net effect... Fixed REGISTER_FC4_TYPES for the 24XX. Did more new FC state engine work. Did some of the prelim spadework for multipath failover. Added an 'isp_stds' file which has structures as defined in the appropriate ANSI specs rather than derivative dribs and drabs all over the place. Removed Postion Map command support- I doubt anyone will need it ever again. Did some IOCB structure changes to try and get things ready for N-Port virtualization. Affected files ... .. //depot/projects/newisp/dev/isp/isp.c#10 edit .. //depot/projects/newisp/dev/isp/isp_freebsd.c#6 edit .. //depot/projects/newisp/dev/isp/isp_freebsd.h#4 edit .. //depot/projects/newisp/dev/isp/isp_library.c#5 edit .. //depot/projects/newisp/dev/isp/isp_library.h#5 edit .. //depot/projects/newisp/dev/isp/isp_pci.c#11 edit .. //depot/projects/newisp/dev/isp/isp_stds.h#1 add .. //depot/projects/newisp/dev/isp/isp_target.h#5 edit .. //depot/projects/newisp/dev/isp/ispmbox.h#3 edit .. //depot/projects/newisp/dev/isp/ispvar.h#3 edit Differences ... ==== //depot/projects/newisp/dev/isp/isp.c#10 (text+ko) ==== @@ -80,8 +80,6 @@ static const char topology[] = "Our PortID 0x%06x N-Port Handle %d, Connection Topology '%s'\n" " WWNN 0x%08x%08x WWPN 0x%08x%08x"; -static const char swrej[] = - "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x"; static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; static const char sc0[] = @@ -112,7 +110,6 @@ static void isp_fibre_init_2400(ispsoftc_t *); static void isp_dump_portdb(ispsoftc_t *); static void isp_mark_portdb(ispsoftc_t *, int); -static int isp_getmap(ispsoftc_t *, fcpos_map_t *); static void isp_plogx_24xx(ispsoftc_t *, uint16_t, uint32_t, int *); static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t); static void isp_port_logout(ispsoftc_t *, uint16_t, uint32_t); @@ -123,8 +120,10 @@ static int isp_pdb_sync(ispsoftc_t *); static int isp_scan_loop(ispsoftc_t *); static int isp_gid_ft_sns(ispsoftc_t *); +static int isp_gid_ft_ct_passthru(ispsoftc_t *); static int isp_scan_fabric(ispsoftc_t *); -static void isp_register_fc4_type(ispsoftc_t *); +static int isp_register_fc4_type(ispsoftc_t *); +static int isp_register_fc4_type_24xx(ispsoftc_t *); static void isp_fw_state(ispsoftc_t *); static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int); static void isp_mboxcmd(ispsoftc_t *, mbreg_t *, int); @@ -1991,36 +1990,7 @@ /* * Fibre Channel Support- get the port database for the id. - * - * Locks are held before coming here. Return 0 if success, - * else failure. */ - -static int -isp_getmap(ispsoftc_t *isp, fcpos_map_t *map) -{ - fcparam *fcp = (fcparam *) isp->isp_param; - mbreg_t mbs; - - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP; - mbs.param[2] = DMA_WD1(fcp->isp_scdma); - mbs.param[3] = DMA_WD0(fcp->isp_scdma); - mbs.param[6] = DMA_WD3(fcp->isp_scdma); - mbs.param[7] = DMA_WD2(fcp->isp_scdma); - FC_SCRATCH_ACQUIRE(isp); - MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (fcpos_map_t)); - isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); - if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { - MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t)); - map->fwmap = mbs.param[1] != 0; - FC_SCRATCH_RELEASE(isp); - return (0); - } - FC_SCRATCH_RELEASE(isp); - return (-1); -} - static void isp_dump_portdb(ispsoftc_t *isp) { @@ -2156,7 +2126,8 @@ break; case PLOGX_IOCBERR_FAILED: isp_prt(isp, ISP_LOGERR, - "PLOGX failed- reason 0x%x, last LOGIN state 0x%x", + "PLOGX(0x%x) of Port 0x%06x failed: reason 0x%x (last LOGIN" + " state 0x%x)", *log_ret, portid, parm1 & 0xff, (parm1 >> 8) & 0xff); break; case PLOGX_IOCBERR_NOFABRIC: @@ -2396,10 +2367,6 @@ isp_mark_portdb(isp, 1); /* - * XXX: Here is where we would start a 'loop dead' timeout - */ - - /* * Wait up to N microseconds for F/W to go to a ready state. */ lwfs = FW_CONFIG_WAIT; @@ -2466,7 +2433,8 @@ * If we haven't gone to 'ready' state, return. */ if (fcp->isp_fwstate != FW_READY) { - isp_prt(isp, ISP_LOGDEBUG0, "isp_fclink_test: not at FW_READY state"); + isp_prt(isp, ISP_LOGDEBUG0, + "isp_fclink_test: not at FW_READY state"); return (-1); } @@ -2536,7 +2504,7 @@ * Save the Fabric controller's port database entry. */ lp = &fcp->portdb[FL_ID]; - lp->state = FC_PORTDB_STATE_VALID; + lp->state = FC_PORTDB_STATE_PENDING_VALID; MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename); MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname); lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; @@ -2544,7 +2512,11 @@ lp->handle = pdb.handle; lp->new_portid = lp->portid; lp->new_roles = lp->roles; - isp_register_fc4_type(isp); + if (IS_24XX(isp)) { + (void) isp_register_fc4_type_24xx(isp); + } else { + (void) isp_register_fc4_type(isp); + } } else { not_on_fabric: fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL; @@ -2624,12 +2596,18 @@ fcportdb_t *lp; uint16_t dbidx; + if (fcp->isp_loopstate == LOOP_READY) { + return (0); + } + /* * Make sure we're okay for doing this right now. */ if (fcp->isp_loopstate != LOOP_PDB_RCVD && fcp->isp_loopstate != LOOP_FSCAN_DONE && fcp->isp_loopstate != LOOP_LSCAN_DONE) { + isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", + fcp->isp_loopstate); return (-1); } @@ -2638,6 +2616,8 @@ fcp->isp_topo == TOPO_N_PORT) { if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { if (isp_scan_loop(isp) != 0) { + isp_prt(isp, ISP_LOGWARN, + "isp_pdb_sync: isp_scan_loop failed"); return (-1); } } @@ -2646,6 +2626,8 @@ if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { if (fcp->isp_loopstate < LOOP_FSCAN_DONE) { if (isp_scan_fabric(isp) != 0) { + isp_prt(isp, ISP_LOGWARN, + "isp_pdb_sync: isp_scan_fabric failed"); return (-1); } } @@ -2748,9 +2730,15 @@ fcp->isp_ini_map[t] = dbidx + 1; } isp_async(isp, ISPASYNC_DEV_STAYED, lp); - lp->new_roles = 0; - lp->new_portid = 0; + if (dbidx != FL_ID) { + lp->new_roles = 0; + lp->new_portid = 0; + } break; + default: + isp_prt(isp, ISP_LOGERR, "eh? state %d for idx %d", + lp->state, dbidx); + isp_dump_portdb(isp); } } @@ -2776,6 +2764,15 @@ isp_pdb_t pdb; uint16_t dbidx, lim; + if (fcp->isp_fwstate < FW_READY || + fcp->isp_loopstate < LOOP_PDB_RCVD) { + return (-1); + } + + if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) { + return (0); + } + /* * Check our connection topology. * @@ -3074,11 +3071,11 @@ fcparam *fcp = FCPARAM(isp); union { isp_ct_pt_t plocal; - isp_ct_hdr_t clocal; + ct_hdr_t clocal; uint8_t q[QENTRY_LEN]; } un; isp_ct_pt_t *pt; - isp_ct_hdr_t *ct; + ct_hdr_t *ct; uint32_t *rp; uint8_t *scp = fcp->isp_scratch; @@ -3126,16 +3123,10 @@ ct->ct_cmd_resp = SNS_GID_FT; ct->ct_bcnt_resid = (GIDLEN - 16) >> 2; - isp_put_ct_hdr(isp, ct, (isp_ct_hdr_t *) &scp[XTXOFF]); + isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]); rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)]; ISP_IOZPUT_32(isp, FC4_SCSI, rp); - if (isp->isp_dblev & ISP_LOGDEBUG1) { - isp_print_bytes(isp, "ct hdr swizzled", - sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]); - } - MEMZERO(&scp[ZTXOFF], QENTRY_LEN); - MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; mbs.param[1] = QENTRY_LEN; @@ -3173,6 +3164,13 @@ sns_gid_ft_rsp_t *rs0, *rs1; isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric"); + if (fcp->isp_fwstate != FW_READY || + fcp->isp_loopstate < LOOP_LSCAN_DONE) { + return (-1); + } + if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) { + return (0); + } if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) { fcp->isp_loopstate = LOOP_FSCAN_DONE; isp_prt(isp, ISP_LOGDEBUG0, "FC Scan Fabric Done (no fabric)"); @@ -3193,7 +3191,7 @@ FC_SCRATCH_RELEASE(isp); return (0); } else if (r < 0) { - fcp->isp_loopstate = LOOP_LIP_RCVD; /* try again */ + fcp->isp_loopstate = LOOP_PDB_RCVD; /* try again */ FC_SCRATCH_RELEASE(isp); return (0); } @@ -3206,7 +3204,7 @@ rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF); rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF); isp_get_gid_ft_response(isp, rs0, rs1, NGENT); - if (rs1->snscb_cthdr.ct_cmd_resp != FS_ACC) { + if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) { int level; if (rs1->snscb_cthdr.ct_reason == 9 && rs1->snscb_cthdr.ct_explanation == 7) { @@ -3214,9 +3212,9 @@ } else { level = ISP_LOGWARN; } - isp_prt(isp, level, swrej, "GID_FT", - rs1->snscb_cthdr.ct_reason, - rs1->snscb_cthdr.ct_explanation, 0); + isp_prt(isp, level, "Fabric Nameserver rejected GID_FT " + "(Reason=0x%x Expl=0x%x)", rs1->snscb_cthdr.ct_reason, + rs1->snscb_cthdr.ct_explanation); FC_SCRATCH_RELEASE(isp); fcp->isp_loopstate = LOOP_FSCAN_DONE; return (0); @@ -3630,7 +3628,7 @@ return (0); } -static void +static int isp_register_fc4_type(ispsoftc_t *isp) { fcparam *fcp = isp->isp_param; @@ -3638,11 +3636,6 @@ sns_screq_t *reqp = (sns_screq_t *) local; mbreg_t mbs; - if (IS_24XX(isp)) { - isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types XXX NEED ONE FOR 24XX"); - return; - } - MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1; reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); @@ -3667,7 +3660,110 @@ isp_mboxcmd(isp, &mbs, MBLOGALL); FC_SCRATCH_RELEASE(isp); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { - isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded"); + return (0); + } else { + return (-1); + } +} + +static int +isp_register_fc4_type_24xx(ispsoftc_t *isp) +{ + mbreg_t mbs; + fcparam *fcp = FCPARAM(isp); + union { + isp_ct_pt_t plocal; + rft_id_t clocal; + uint8_t q[QENTRY_LEN]; + } un; + isp_ct_pt_t *pt; + ct_hdr_t *ct; + rft_id_t *rp; + uint8_t *scp = fcp->isp_scratch; + + FC_SCRATCH_ACQUIRE(isp); + /* + * Build a Passthrough IOCB in memory. + */ + MEMZERO(un.q, QENTRY_LEN); + pt = &un.plocal; + pt->ctp_header.rqs_entry_count = 1; + pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; + pt->ctp_handle = 0xffffffff; + pt->ctp_nphdl = NPH_SNS_ID; + pt->ctp_cmd_cnt = 1; + pt->ctp_time = 1; + pt->ctp_rsp_cnt = 1; + pt->ctp_rsp_bcnt = sizeof (ct_hdr_t); + pt->ctp_cmd_bcnt = sizeof (rft_id_t); + pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF); + pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF); + pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t); + pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF); + pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF); + pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t); + isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]); + + /* + * Build the CT header and command in memory. + * + * Note that the CT header has to end up as Big Endian format in memory. + */ + MEMZERO(&un.clocal, sizeof (un.clocal)); + ct = &un.clocal.rftid_hdr; + ct->ct_revision = CT_REVISION; + ct->ct_fcs_type = CT_FC_TYPE_FC; + ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; + ct->ct_cmd_resp = SNS_RFT_ID; + ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2; + rp = &un.clocal; + rp->rftid_portid[0] = fcp->isp_portid >> 16; + rp->rftid_portid[1] = fcp->isp_portid >> 8; + rp->rftid_portid[2] = fcp->isp_portid; + rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f); + isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]); + + MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t)); + + MEMZERO(&mbs, sizeof (mbs)); + mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; + mbs.param[1] = QENTRY_LEN; + mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF); + mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF); + mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF); + mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF); + MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN); + isp_mboxcmd(isp, &mbs, MBLOGALL); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + FC_SCRATCH_RELEASE(isp); + return (-1); + } + MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN); + pt = &un.plocal; + isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt); + if (isp->isp_dblev & ISP_LOGDEBUG1) { + isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt); + } + if (pt->ctp_status) { + FC_SCRATCH_RELEASE(isp); + isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x", + pt->ctp_status); + return (-1); + } + + isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct); + FC_SCRATCH_RELEASE(isp); + + if (ct->ct_cmd_resp == LS_RJT) { + isp_prt(isp, ISP_LOGWARN, "Register FC4 Type rejected"); + return (-1); + } else if (ct->ct_cmd_resp == LS_ACC) { + isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 Type accepted"); + return(0); + } else { + isp_prt(isp, ISP_LOGWARN, + "Register FC4 Type: %x", ct->ct_cmd_resp); + return (-1); } } @@ -3826,13 +3922,13 @@ } } if (ttype == REQFLAG_OTAG) { - ttype = 2; + ttype = FCP_CMND_TASK_ATTR_ORDERED; } else if (ttype == REQFLAG_HTAG) { - ttype = 1; + ttype = FCP_CMND_TASK_ATTR_HEAD; } else { - ttype = 0; + ttype = FCP_CMND_TASK_ATTR_SIMPLE; } - ((ispreqt7_t *)reqp)->req_task_attributes = ttype; + ((ispreqt7_t *)reqp)->req_task_attribute = ttype; } else if (IS_FC(isp)) { /* * See comment in isp_intr @@ -3879,7 +3975,7 @@ ((ispreqt7_t *)reqp)->req_nphdl = target; ((ispreqt7_t *)reqp)->req_tidlo = lp->portid; - ((ispreqt7_t *)reqp)->req_tidhi_vpidx = lp->portid >> 16; + ((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16; if (XS_LUN(xs) > 256) { ((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8; ((ispreqt7_t *)reqp)->req_lun[0] |= 0x40; @@ -4098,14 +4194,6 @@ } break; - case ISPCTL_GET_POSMAP: - - if (IS_FC(isp) && arg) { - return (isp_getmap(isp, arg)); - } - break; - - case ISPCTL_GET_PDB: if (IS_FC(isp) && arg) { int id = *((int *)arg); @@ -4344,7 +4432,7 @@ * Synchronize our view of this response queue entry. */ MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN); - isp_copy_in_hdr(isp, hp, &sp->req_header); + isp_get_hdr(isp, hp, &sp->req_header); etype = sp->req_header.rqs_entry_type; if (IS_24XX(isp) && etype == RQSTYPE_T7RQS) { @@ -4944,10 +5032,11 @@ break; case ASYNC_CHANGE_NOTIFY: - /* - * Not correct, but it will force us to rescan the loop. - */ - FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; + if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) { + FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE; + } else { + FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD; + } isp_mark_portdb(isp, 1); isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS); break; @@ -6842,7 +6931,18 @@ isp_prt(isp, ISP_LOGERR, "isp_reinit cannot restart card"); } - } + } else if (IS_FC(isp)) { + /* + * If we're in ISP_ROLE_NONE, turn off the lasers. + */ + if (!IS_24XX(isp)) { + ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS); + ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET); + ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS); + ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL); + ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS); + } + } isp->isp_nactive = 0; for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) { @@ -7520,7 +7620,7 @@ wwn = ISP2400_NVRAM_PORT_NAME(nvram_data); if (wwn) { - if ((wwn >> 60) != 2) { + if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { wwn = 0; } } @@ -7528,7 +7628,7 @@ wwn = ISP2400_NVRAM_NODE_NAME(nvram_data); if (wwn) { - if ((wwn >> 60) != 2) { + if ((wwn >> 60) != 2 && (wwn >> 60) != 5) { wwn = 0; } } ==== //depot/projects/newisp/dev/isp/isp_freebsd.c#6 (text+ko) ==== @@ -43,6 +43,8 @@ MODULE_VERSION(isp, 1); MODULE_DEPEND(isp, cam, 1, 1, 1); int isp_announced = 0; +int isp_fabric_hysteresis = 5; +int isp_loop_down_limit = 300; /* default loop down limit */ static d_ioctl_t ispioctl; static void isp_intr_enable(void *); @@ -2057,7 +2059,6 @@ isp_kthread(void *arg) { ispsoftc_t *isp = arg; - int loop_down_count = 0; int slp; @@ -2081,24 +2082,39 @@ int wasfrozen, lb; isp_prt(isp, ISP_LOGDEBUG0, "kthread: checking FC state"); - lb = isp_fc_runstate(isp, 2 * 1000000); + lb = isp_fc_runstate(isp, 250000); isp->isp_osinfo.ktmature = 1; if (lb) { + unsigned int inc = 1; + isp_prt(isp, ISP_LOGDEBUG0, "kthread: FC state %d", lb); - loop_down_count += 1; - if (loop_down_count > 20) { + if (isp->isp_osinfo.loop_down_time > 30) { + inc = 30; slp = 30 * hz; - } else if (loop_down_count > 5) { + } else if (isp->isp_osinfo.loop_down_time > 1) { slp = hz; } else { - slp = hz >> 8; + slp = 1; + } + + inc += isp->isp_osinfo.loop_down_time; + if (inc < 0xffff) { + isp->isp_osinfo.loop_down_time = inc; + } else { + isp->isp_osinfo.loop_down_time = 0xfffe; } } else { isp_prt(isp, ISP_LOGDEBUG0, "kthread: FC state OK"); - loop_down_count = 0; - slp = 60 * 60 * hz; + isp->isp_osinfo.loop_down_time = 0; + slp = 0; } + /* + * If we'd frozen the simq, unfreeze it now so that CAM + * can start sending us commands. If the FC state isn't + * okay yet, they'll hit that in isp_start which will + * freeze the queue again. + */ wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN; isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN; if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) { @@ -2116,6 +2132,17 @@ (void) tsleep(&isp->isp_osinfo.kthread_cv, PRIBIO, "ispf", slp); #endif #endif + /* + * If slp is zero, we're waking up for the first time after + * things have been okay. In this case, we set a deferral state + * for all commands and delay hysteresis seconds before starting + * the FC state evaluation. This gives the loop/fabric a chance + * to settle. + */ + if (slp == 0 && isp->isp_osinfo.hysteresis) { + (void) tsleep(&isp_fabric_hysteresis, PRIBIO, "ispT", + (isp->isp_osinfo.hysteresis * hz)); + } } } @@ -2209,10 +2236,14 @@ KASSERT((IS_FC(isp)), ("CMD_RQLATER for FC only")); /* * If we've never seen loop up and we've at least - * looked once, just fail these commands. + * looked once, just fail these commands. Also, + * if we've exceeded the loop down limit- fail them + * as well. */ - if (FCPARAM(isp)->loop_seen_once == 0 && - isp->isp_osinfo.ktmature) { + if ((FCPARAM(isp)->loop_seen_once == 0 && + isp->isp_osinfo.ktmature) || + isp->isp_osinfo.loop_down_time > + isp->isp_osinfo.loop_down_limit) { ISPLOCK_2_CAMLOCK(isp); XS_SETERR(ccb, CAM_SEL_TIMEOUT); xpt_done(ccb); @@ -3096,13 +3127,17 @@ } break; case ISPASYNC_CHANGE_NOTIFY: + { + char *msg; if (arg == ISPASYNC_CHANGE_PDB) { - isp_prt(isp, ISP_LOGINFO, - "Port Database Changed"); + msg = "Port Database Changed"; } else if (arg == ISPASYNC_CHANGE_SNS) { - isp_prt(isp, ISP_LOGINFO, - "Name Server Database Changed"); + msg = "Name Server Database Changed"; + } else { + msg = "Other Change Notify"; } + isp_prt(isp, ISP_LOGINFO, msg); + isp_freeze_loopdown(isp, msg); #if __FreeBSD_version < 500000 wakeup(&isp->isp_osinfo.kproc); #else @@ -3113,6 +3148,7 @@ #endif #endif break; + } #ifdef ISP_TARGET_MODE case ISPASYNC_TARGET_NOTIFY: { ==== //depot/projects/newisp/dev/isp/isp_freebsd.h#4 (text+ko) ==== @@ -149,7 +149,11 @@ struct cam_sim *sim2; struct cam_path *path2; struct intr_config_hook ehook; - uint8_t + uint16_t loop_down_time; + uint16_t loop_down_limit; + uint32_t + : 16, + hysteresis : 8, disabled : 1, fcbsy : 1, ktmature : 1, @@ -427,6 +431,8 @@ * driver global data */ extern int isp_announced; +extern int isp_fabric_hysteresis; +extern int isp_loop_down_limit; /* * Platform private flags ==== //depot/projects/newisp/dev/isp/isp_library.c#5 (text) ==== @@ -199,14 +199,19 @@ } fcp = FCPARAM(isp); tptr = &tval; - if (isp_control(isp, ISPCTL_FCLINK_TEST, tptr) != 0) { - isp_prt(isp, ISP_LOGINFO, "isp_fc_runstate: linktest failed"); - return (-1); - } - if (fcp->isp_fwstate != FW_READY || + if (fcp->isp_fwstate < FW_READY || fcp->isp_loopstate < LOOP_PDB_RCVD) { - isp_prt(isp, ISP_LOGINFO, "isp_fc_runstate: f/w not ready"); - return (-1); + if (isp_control(isp, ISPCTL_FCLINK_TEST, tptr) != 0) { + isp_prt(isp, ISP_LOGINFO, + "isp_fc_runstate: linktest failed"); + return (-1); + } + if (fcp->isp_fwstate != FW_READY || + fcp->isp_loopstate < LOOP_PDB_RCVD) { + isp_prt(isp, ISP_LOGINFO, + "isp_fc_runstate: f/w not ready"); + return (-1); + } } if (isp_control(isp, ISPCTL_SCAN_LOOP, NULL) != 0) { isp_prt(isp, ISP_LOGINFO, "isp_fc_runstate: scan loop fails"); @@ -247,7 +252,7 @@ * Swizzle/Copy Functions */ void -isp_copy_out_hdr(ispsoftc_t *isp, isphdr_t *hpsrc, isphdr_t *hpdst) +isp_put_hdr(ispsoftc_t *isp, isphdr_t *hpsrc, isphdr_t *hpdst) { if (ISP_IS_SBUS(isp)) { ISP_IOXPUT_8(isp, hpsrc->rqs_entry_type, @@ -271,7 +276,7 @@ } void -isp_copy_in_hdr(ispsoftc_t *isp, isphdr_t *hpsrc, isphdr_t *hpdst) +isp_get_hdr(ispsoftc_t *isp, isphdr_t *hpsrc, isphdr_t *hpdst) { if (ISP_IS_SBUS(isp)) { ISP_IOXGET_8(isp, &hpsrc->rqs_entry_type, @@ -310,7 +315,7 @@ isp_put_request(ispsoftc_t *isp, ispreq_t *rqsrc, ispreq_t *rqdst) { int i; - isp_copy_out_hdr(isp, &rqsrc->req_header, &rqdst->req_header); + isp_put_hdr(isp, &rqsrc->req_header, &rqdst->req_header); ISP_IOXPUT_32(isp, rqsrc->req_handle, &rqdst->req_handle); if (ISP_IS_SBUS(isp)) { ISP_IOXPUT_8(isp, rqsrc->req_lun_trn, &rqdst->req_target); @@ -338,23 +343,24 @@ isp_put_marker(ispsoftc_t *isp, isp_marker_t *src, isp_marker_t *dst) { int i; - isp_copy_out_hdr(isp, &src->mrk_header, &dst->mrk_header); + isp_put_hdr(isp, &src->mrk_header, &dst->mrk_header); ISP_IOXPUT_32(isp, src->mrk_handle, &dst->mrk_handle); if (ISP_IS_SBUS(isp)) { - ISP_IOXPUT_8(isp, src->_res0, &dst->mrk_target); - ISP_IOXPUT_8(isp, src->mrk_target, &dst->_res0); - ISP_IOXPUT_8(isp, src->_res1, &dst->mrk_modifier); - ISP_IOXPUT_8(isp, src->mrk_modifier, &dst->_res1); + ISP_IOXPUT_8(isp, src->mrk_reserved0, &dst->mrk_target); + ISP_IOXPUT_8(isp, src->mrk_target, &dst->mrk_reserved0); + ISP_IOXPUT_8(isp, src->mrk_reserved1, &dst->mrk_modifier); + ISP_IOXPUT_8(isp, src->mrk_modifier, &dst->mrk_reserved1); } else { - ISP_IOXPUT_8(isp, src->_res0, &dst->_res0); + ISP_IOXPUT_8(isp, src->mrk_reserved0, &dst->mrk_reserved0); ISP_IOXPUT_8(isp, src->mrk_target, &dst->mrk_target); ISP_IOXPUT_8(isp, src->mrk_modifier, &dst->mrk_modifier); - ISP_IOXPUT_8(isp, src->_res1, &dst->_res1); + ISP_IOXPUT_8(isp, src->mrk_reserved1, &dst->mrk_reserved1); } ISP_IOXPUT_16(isp, src->mrk_flags, &dst->mrk_flags); ISP_IOXPUT_16(isp, src->mrk_lun, &dst->mrk_lun); for (i = 0; i < 48; i++) { - ISP_IOXPUT_8(isp, src->_res2[i], &dst->_res2[i]); + ISP_IOXPUT_8(isp, src->mrk_reserved2[i], + &dst->mrk_reserved2[i]); } } @@ -363,270 +369,258 @@ isp_marker_24xx_t *src, isp_marker_24xx_t *dst) { int i; - isp_copy_out_hdr(isp, &src->mrk_header, &dst->mrk_header); + isp_put_hdr(isp, &src->mrk_header, &dst->mrk_header); ISP_IOXPUT_32(isp, src->mrk_handle, &dst->mrk_handle); ISP_IOXPUT_16(isp, src->mrk_nphdl, &dst->mrk_nphdl); ISP_IOXPUT_8(isp, src->mrk_modifier, &dst->mrk_modifier); - ISP_IOXPUT_8(isp, src->_res0, &dst->_res0); - ISP_IOXPUT_8(isp, src->_res1, &dst->_res1); + ISP_IOXPUT_8(isp, src->mrk_reserved0, &dst->mrk_reserved0); + ISP_IOXPUT_8(isp, src->mrk_reserved1, &dst->mrk_reserved1); ISP_IOXPUT_8(isp, src->mrk_vphdl, &dst->mrk_vphdl); - ISP_IOXPUT_8(isp, src->_res2, &dst->_res2); + ISP_IOXPUT_8(isp, src->mrk_reserved2, &dst->mrk_reserved2); for (i = 0; i < 8; i++) { ISP_IOXPUT_8(isp, src->mrk_lun[i], &dst->mrk_lun[i]); } for (i = 0; i < 40; i++) { - ISP_IOXPUT_8(isp, src->_res3[i], &dst->_res3[i]); + ISP_IOXPUT_8(isp, src->mrk_reserved3[i], + &dst->mrk_reserved3[i]); } } void -isp_put_request_t2(ispsoftc_t *isp, ispreqt2_t *tqsrc, ispreqt2_t *tqdst) +isp_put_request_t2(ispsoftc_t *isp, ispreqt2_t *src, ispreqt2_t *dst) { int i; - isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header); - ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle); - ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn); - ISP_IOXPUT_8(isp, tqsrc->req_target, &tqdst->req_target); - ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun); - ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags); - ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2); - ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time); - ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count); + isp_put_hdr(isp, &src->req_header, &dst->req_header); + ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle); + ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_lun_trn); + ISP_IOXPUT_8(isp, src->req_target, &dst->req_target); + ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun); + ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags); + ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved); + ISP_IOXPUT_16(isp, src->req_time, &dst->req_time); + ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count); for (i = 0; i < 16; i++) { - ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]); + ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]); } - ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt); + ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt); for (i = 0; i < ISP_RQDSEG_T2; i++) { - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base, - &tqdst->req_dataseg[i].ds_base); - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count, - &tqdst->req_dataseg[i].ds_count); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base, + &dst->req_dataseg[i].ds_base); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count, + &dst->req_dataseg[i].ds_count); } } void -isp_put_request_t2e(ispsoftc_t *isp, ispreqt2e_t *tqsrc, ispreqt2e_t *tqdst) +isp_put_request_t2e(ispsoftc_t *isp, ispreqt2e_t *src, ispreqt2e_t *dst) { int i; - isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header); - ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle); - ISP_IOXPUT_16(isp, tqsrc->req_target, &tqdst->req_target); - ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun); - ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags); - ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2); - ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time); - ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count); + isp_put_hdr(isp, &src->req_header, &dst->req_header); + ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle); + ISP_IOXPUT_16(isp, src->req_target, &dst->req_target); + ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun); + ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags); + ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved); + ISP_IOXPUT_16(isp, src->req_time, &dst->req_time); + ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count); for (i = 0; i < 16; i++) { - ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]); + ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]); } - ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt); + ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt); for (i = 0; i < ISP_RQDSEG_T2; i++) { - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base, - &tqdst->req_dataseg[i].ds_base); - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count, - &tqdst->req_dataseg[i].ds_count); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base, + &dst->req_dataseg[i].ds_base); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count, + &dst->req_dataseg[i].ds_count); } } void -isp_put_request_t3(ispsoftc_t *isp, ispreqt3_t *tqsrc, ispreqt3_t *tqdst) +isp_put_request_t3(ispsoftc_t *isp, ispreqt3_t *src, ispreqt3_t *dst) { int i; - isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header); - ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle); - ISP_IOXPUT_8(isp, tqsrc->req_lun_trn, &tqdst->req_lun_trn); - ISP_IOXPUT_8(isp, tqsrc->req_target, &tqdst->req_target); - ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun); - ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags); - ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2); - ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time); - ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count); + isp_put_hdr(isp, &src->req_header, &dst->req_header); + ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle); + ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_lun_trn); + ISP_IOXPUT_8(isp, src->req_target, &dst->req_target); + ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun); + ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags); + ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved); + ISP_IOXPUT_16(isp, src->req_time, &dst->req_time); + ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count); for (i = 0; i < 16; i++) { - ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]); + ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]); } - ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt); + ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt); for (i = 0; i < ISP_RQDSEG_T3; i++) { - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base, - &tqdst->req_dataseg[i].ds_base); - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_basehi, - &tqdst->req_dataseg[i].ds_basehi); - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count, - &tqdst->req_dataseg[i].ds_count); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base, + &dst->req_dataseg[i].ds_base); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_basehi, + &dst->req_dataseg[i].ds_basehi); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count, + &dst->req_dataseg[i].ds_count); } } void -isp_put_request_t3e(ispsoftc_t *isp, ispreqt3e_t *tqsrc, ispreqt3e_t *tqdst) +isp_put_request_t3e(ispsoftc_t *isp, ispreqt3e_t *src, ispreqt3e_t *dst) { int i; - isp_copy_out_hdr(isp, &tqsrc->req_header, &tqdst->req_header); - ISP_IOXPUT_32(isp, tqsrc->req_handle, &tqdst->req_handle); - ISP_IOXPUT_16(isp, tqsrc->req_target, &tqdst->req_target); - ISP_IOXPUT_16(isp, tqsrc->req_scclun, &tqdst->req_scclun); - ISP_IOXPUT_16(isp, tqsrc->req_flags, &tqdst->req_flags); - ISP_IOXPUT_16(isp, tqsrc->_res2, &tqdst->_res2); - ISP_IOXPUT_16(isp, tqsrc->req_time, &tqdst->req_time); - ISP_IOXPUT_16(isp, tqsrc->req_seg_count, &tqdst->req_seg_count); + isp_put_hdr(isp, &src->req_header, &dst->req_header); + ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle); + ISP_IOXPUT_16(isp, src->req_target, &dst->req_target); + ISP_IOXPUT_16(isp, src->req_scclun, &dst->req_scclun); + ISP_IOXPUT_16(isp, src->req_flags, &dst->req_flags); + ISP_IOXPUT_16(isp, src->req_reserved, &dst->req_reserved); + ISP_IOXPUT_16(isp, src->req_time, &dst->req_time); + ISP_IOXPUT_16(isp, src->req_seg_count, &dst->req_seg_count); for (i = 0; i < 16; i++) { - ISP_IOXPUT_8(isp, tqsrc->req_cdb[i], &tqdst->req_cdb[i]); + ISP_IOXPUT_8(isp, src->req_cdb[i], &dst->req_cdb[i]); } - ISP_IOXPUT_32(isp, tqsrc->req_totalcnt, &tqdst->req_totalcnt); + ISP_IOXPUT_32(isp, src->req_totalcnt, &dst->req_totalcnt); for (i = 0; i < ISP_RQDSEG_T3; i++) { - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_base, - &tqdst->req_dataseg[i].ds_base); - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_basehi, - &tqdst->req_dataseg[i].ds_basehi); - ISP_IOXPUT_32(isp, tqsrc->req_dataseg[i].ds_count, - &tqdst->req_dataseg[i].ds_count); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_base, + &dst->req_dataseg[i].ds_base); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_basehi, + &dst->req_dataseg[i].ds_basehi); + ISP_IOXPUT_32(isp, src->req_dataseg[i].ds_count, + &dst->req_dataseg[i].ds_count); } } void -isp_put_extended_request(ispsoftc_t *isp, ispextreq_t *xqsrc, - ispextreq_t *xqdst) +isp_put_extended_request(ispsoftc_t *isp, ispextreq_t *src, ispextreq_t *dst) { int i; - isp_copy_out_hdr(isp, &xqsrc->req_header, &xqdst->req_header); - ISP_IOXPUT_32(isp, xqsrc->req_handle, &xqdst->req_handle); + isp_put_hdr(isp, &src->req_header, &dst->req_header); + ISP_IOXPUT_32(isp, src->req_handle, &dst->req_handle); if (ISP_IS_SBUS(isp)) { - ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_target); - ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_lun_trn); + ISP_IOXPUT_8(isp, src->req_lun_trn, &dst->req_target); + ISP_IOXPUT_8(isp, src->req_target, &dst->req_lun_trn); } else { - ISP_IOXPUT_8(isp, xqsrc->req_lun_trn, &xqdst->req_lun_trn); - ISP_IOXPUT_8(isp, xqsrc->req_target, &xqdst->req_target); >>> TRUNCATED FOR MAIL (1000 lines) <<<