File:  [DragonFly] / src / sys / dev / disk / isp / isp.c
Revision 1.4: download - view: text, annotated - select for diffs
Fri Feb 13 01:04:15 2004 UTC (10 years, 2 months ago) by joerg
Branches: MAIN
CVS tags: HEAD, DragonFly_Stable, DragonFly_Snap29Sep2004, DragonFly_Snap13Sep2004, DragonFly_RELEASE_1_8_Slip, DragonFly_RELEASE_1_8, DragonFly_RELEASE_1_6_Slip, DragonFly_RELEASE_1_6, DragonFly_RELEASE_1_4_Slip, DragonFly_RELEASE_1_4, DragonFly_RELEASE_1_2_Slip, DragonFly_RELEASE_1_2, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
Add __DragonFly__

    1: /* $FreeBSD: src/sys/dev/isp/isp.c,v 1.41.2.23 2002/10/11 17:34:28 mjacob Exp $ */
    2: /* $DragonFly: src/sys/dev/disk/isp/isp.c,v 1.4 2004/02/13 01:04:15 joerg Exp $ */
    3: /*
    4:  * Machine and OS Independent (well, as best as possible)
    5:  * code for the Qlogic ISP SCSI adapters.
    6:  *
    7:  * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob
    8:  * Feral Software
    9:  * All rights reserved.
   10:  *
   11:  * Redistribution and use in source and binary forms, with or without
   12:  * modification, are permitted provided that the following conditions
   13:  * are met:
   14:  * 1. Redistributions of source code must retain the above copyright
   15:  *    notice immediately at the beginning of the file, without modification,
   16:  *    this list of conditions, and the following disclaimer.
   17:  * 2. The name of the author may not be used to endorse or promote products
   18:  *    derived from this software without specific prior written permission.
   19:  *
   20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   24:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30:  * SUCH DAMAGE.
   31:  */
   32: 
   33: /*
   34:  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
   35:  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
   36:  * ideas dredged from the Solaris driver.
   37:  */
   38: 
   39: /*
   40:  * Include header file appropriate for platform we're building on.
   41:  */
   42: 
   43: #ifdef	__NetBSD__
   44: #include <dev/ic/isp_netbsd.h>
   45: #endif
   46: #if defined(__DragonFly__) || defined(__FreeBSD__)
   47: #include "isp_freebsd.h"
   48: #endif
   49: #ifdef	__OpenBSD__
   50: #include <dev/ic/isp_openbsd.h>
   51: #endif
   52: #ifdef	__linux__
   53: #include "isp_linux.h"
   54: #endif
   55: #ifdef	__svr4__
   56: #include "isp_solaris.h"
   57: #endif
   58: 
   59: /*
   60:  * General defines
   61:  */
   62: 
   63: #define	MBOX_DELAY_COUNT	1000000 / 100
   64: 
   65: /*
   66:  * Local static data
   67:  */
   68: static const char portshift[] =
   69:     "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
   70: static const char portdup[] =
   71:     "Target %d duplicates Target %d- killing off both";
   72: static const char retained[] =
   73:     "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
   74: static const char lretained[] =
   75:     "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
   76: static const char plogout[] =
   77:     "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
   78: static const char plogierr[] =
   79:     "Command Error in PLOGI for Port 0x%x (0x%x)";
   80: static const char nopdb[] =
   81:     "Could not get PDB for Device @ Port 0x%x";
   82: static const char pdbmfail1[] =
   83:     "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
   84: static const char pdbmfail2[] =
   85:     "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
   86: static const char ldumped[] =
   87:     "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
   88: static const char notresp[] =
   89:   "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
   90: static const char xact1[] =
   91:     "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
   92: static const char xact2[] =
   93:     "HBA attempted queued transaction to target routine %d on target %d bus %d";
   94: static const char xact3[] =
   95:     "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
   96: static const char pskip[] =
   97:     "SCSI phase skipped for target %d.%d.%d";
   98: static const char topology[] =
   99:     "Loop ID %d, AL_PA 0x%x, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
  100: static const char swrej[] =
  101:     "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
  102: static const char finmsg[] =
  103:     "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
  104: static const char sc0[] =
  105:     "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
  106: static const char sc1[] =
  107:     "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
  108: static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
  109: static const char sc3[] = "Generated";
  110: static const char sc4[] = "NVRAM";
  111: static const char bun[] =
  112:     "bad underrun for %d.%d (count %d, resid %d, status %s)";
  113: 
  114: /*
  115:  * Local function prototypes.
  116:  */
  117: static int isp_parse_async(struct ispsoftc *, u_int16_t);
  118: static int isp_handle_other_response(struct ispsoftc *, int, isphdr_t *,
  119:     u_int16_t *);
  120: static void
  121: isp_parse_status(struct ispsoftc *, ispstatusreq_t *, XS_T *);
  122: static void isp_fastpost_complete(struct ispsoftc *, u_int16_t);
  123: static int isp_mbox_continue(struct ispsoftc *);
  124: static void isp_scsi_init(struct ispsoftc *);
  125: static void isp_scsi_channel_init(struct ispsoftc *, int);
  126: static void isp_fibre_init(struct ispsoftc *);
  127: static void isp_mark_getpdb_all(struct ispsoftc *);
  128: static int isp_getmap(struct ispsoftc *, fcpos_map_t *);
  129: static int isp_getpdb(struct ispsoftc *, int, isp_pdb_t *);
  130: static u_int64_t isp_get_portname(struct ispsoftc *, int, int);
  131: static int isp_fclink_test(struct ispsoftc *, int);
  132: static char *isp2100_fw_statename(int);
  133: static int isp_pdb_sync(struct ispsoftc *);
  134: static int isp_scan_loop(struct ispsoftc *);
  135: static int isp_fabric_mbox_cmd(struct ispsoftc *, mbreg_t *);
  136: static int isp_scan_fabric(struct ispsoftc *, int);
  137: static void isp_register_fc4_type(struct ispsoftc *);
  138: static void isp_fw_state(struct ispsoftc *);
  139: static void isp_mboxcmd_qnw(struct ispsoftc *, mbreg_t *, int);
  140: static void isp_mboxcmd(struct ispsoftc *, mbreg_t *, int);
  141: 
  142: static void isp_update(struct ispsoftc *);
  143: static void isp_update_bus(struct ispsoftc *, int);
  144: static void isp_setdfltparm(struct ispsoftc *, int);
  145: static int isp_read_nvram(struct ispsoftc *);
  146: static void isp_rdnvram_word(struct ispsoftc *, int, u_int16_t *);
  147: static void isp_parse_nvram_1020(struct ispsoftc *, u_int8_t *);
  148: static void isp_parse_nvram_1080(struct ispsoftc *, int, u_int8_t *);
  149: static void isp_parse_nvram_12160(struct ispsoftc *, int, u_int8_t *);
  150: static void isp_parse_nvram_2100(struct ispsoftc *, u_int8_t *);
  151: 
  152: /*
  153:  * Reset Hardware.
  154:  *
  155:  * Hit the chip over the head, download new f/w if available and set it running.
  156:  *
  157:  * Locking done elsewhere.
  158:  */
  159: 
  160: void
  161: isp_reset(struct ispsoftc *isp)
  162: {
  163: 	mbreg_t mbs;
  164: 	u_int16_t code_org;
  165: 	int loops, i, dodnld = 1;
  166: 	char *btype = "????";
  167: 
  168: 	isp->isp_state = ISP_NILSTATE;
  169: 
  170: 	/*
  171: 	 * Basic types (SCSI, FibreChannel and PCI or SBus)
  172: 	 * have been set in the MD code. We figure out more
  173: 	 * here. Possibly more refined types based upon PCI
  174: 	 * identification. Chip revision has been gathered.
  175: 	 *
  176: 	 * After we've fired this chip up, zero out the conf1 register
  177: 	 * for SCSI adapters and do other settings for the 2100.
  178: 	 */
  179: 
  180: 	/*
  181: 	 * Get the current running firmware revision out of the
  182: 	 * chip before we hit it over the head (if this is our
  183: 	 * first time through). Note that we store this as the
  184: 	 * 'ROM' firmware revision- which it may not be. In any
  185: 	 * case, we don't really use this yet, but we may in
  186: 	 * the future.
  187: 	 */
  188: 	if (isp->isp_touched == 0) {
  189: 		/*
  190: 		 * First see whether or not we're sitting in the ISP PROM.
  191: 		 * If we've just been reset, we'll have the string "ISP   "
  192: 		 * spread through outgoing mailbox registers 1-3. We do
  193: 		 * this for PCI cards because otherwise we really don't
  194: 		 * know what state the card is in and we could hang if
  195: 		 * we try this command otherwise.
  196: 		 *
  197: 		 * For SBus cards, we just do this because they almost
  198: 		 * certainly will be running firmware by now.
  199: 		 */
  200: 		if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
  201: 		    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
  202: 		    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
  203: 			/*
  204: 			 * Just in case it was paused...
  205: 			 */
  206: 			ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
  207: 			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
  208: 			isp_mboxcmd(isp, &mbs, MBLOGNONE);
  209: 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
  210: 				isp->isp_romfw_rev[0] = mbs.param[1];
  211: 				isp->isp_romfw_rev[1] = mbs.param[2];
  212: 				isp->isp_romfw_rev[2] = mbs.param[3];
  213: 			}
  214: 		}
  215: 		isp->isp_touched = 1;
  216: 	}
  217: 
  218: 	DISABLE_INTS(isp);
  219: 
  220: 	/*
  221: 	 * Set up default request/response queue in-pointer/out-pointer
  222: 	 * register indices.
  223: 	 */
  224: 	if (IS_23XX(isp)) {
  225: 		isp->isp_rqstinrp = BIU_REQINP;
  226: 		isp->isp_rqstoutrp = BIU_REQOUTP;
  227: 		isp->isp_respinrp = BIU_RSPINP;
  228: 		isp->isp_respoutrp = BIU_RSPOUTP;
  229: 	} else {
  230: 		isp->isp_rqstinrp = INMAILBOX4;
  231: 		isp->isp_rqstoutrp = OUTMAILBOX4;
  232: 		isp->isp_respinrp = OUTMAILBOX5;
  233: 		isp->isp_respoutrp = INMAILBOX5;
  234: 	}
  235: 
  236: 	/*
  237: 	 * Put the board into PAUSE mode (so we can read the SXP registers
  238: 	 * or write FPM/FBM registers).
  239: 	 */
  240: 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
  241: 
  242: 	if (IS_FC(isp)) {
  243: 		switch (isp->isp_type) {
  244: 		case ISP_HA_FC_2100:
  245: 			btype = "2100";
  246: 			break;
  247: 		case ISP_HA_FC_2200:
  248: 			btype = "2200";
  249: 			break;
  250: 		case ISP_HA_FC_2300:
  251: 			btype = "2300";
  252: 			break;
  253: 		case ISP_HA_FC_2312:
  254: 			btype = "2312";
  255: 			break;
  256: 		default:
  257: 			break;
  258: 		}
  259: 		/*
  260: 		 * While we're paused, reset the FPM module and FBM fifos.
  261: 		 */
  262: 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
  263: 		ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
  264: 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
  265: 		ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
  266: 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
  267: 	} else if (IS_1240(isp)) {
  268: 		sdparam *sdp = isp->isp_param;
  269: 		btype = "1240";
  270: 		isp->isp_clock = 60;
  271: 		sdp->isp_ultramode = 1;
  272: 		sdp++;
  273: 		sdp->isp_ultramode = 1;
  274: 		/*
  275: 		 * XXX: Should probably do some bus sensing.
  276: 		 */
  277: 	} else if (IS_ULTRA2(isp)) {
  278: 		static const char m[] = "bus %d is in %s Mode";
  279: 		u_int16_t l;
  280: 		sdparam *sdp = isp->isp_param;
  281: 
  282: 		isp->isp_clock = 100;
  283: 
  284: 		if (IS_1280(isp))
  285: 			btype = "1280";
  286: 		else if (IS_1080(isp))
  287: 			btype = "1080";
  288: 		else if (IS_10160(isp))
  289: 			btype = "10160";
  290: 		else if (IS_12160(isp))
  291: 			btype = "12160";
  292: 		else
  293: 			btype = "<UNKLVD>";
  294: 
  295: 		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
  296: 		switch (l) {
  297: 		case ISP1080_LVD_MODE:
  298: 			sdp->isp_lvdmode = 1;
  299: 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
  300: 			break;
  301: 		case ISP1080_HVD_MODE:
  302: 			sdp->isp_diffmode = 1;
  303: 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
  304: 			break;
  305: 		case ISP1080_SE_MODE:
  306: 			sdp->isp_ultramode = 1;
  307: 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
  308: 			break;
  309: 		default:
  310: 			isp_prt(isp, ISP_LOGERR,
  311: 			    "unknown mode on bus %d (0x%x)", 0, l);
  312: 			break;
  313: 		}
  314: 
  315: 		if (IS_DUALBUS(isp)) {
  316: 			sdp++;
  317: 			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
  318: 			l &= ISP1080_MODE_MASK;
  319: 			switch(l) {
  320: 			case ISP1080_LVD_MODE:
  321: 				sdp->isp_lvdmode = 1;
  322: 				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
  323: 				break;
  324: 			case ISP1080_HVD_MODE:
  325: 				sdp->isp_diffmode = 1;
  326: 				isp_prt(isp, ISP_LOGCONFIG,
  327: 				    m, 1, "Differential");
  328: 				break;
  329: 			case ISP1080_SE_MODE:
  330: 				sdp->isp_ultramode = 1;
  331: 				isp_prt(isp, ISP_LOGCONFIG,
  332: 				    m, 1, "Single-Ended");
  333: 				break;
  334: 			default:
  335: 				isp_prt(isp, ISP_LOGERR,
  336: 				    "unknown mode on bus %d (0x%x)", 1, l);
  337: 				break;
  338: 			}
  339: 		}
  340: 	} else {
  341: 		sdparam *sdp = isp->isp_param;
  342: 		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
  343: 		switch (i) {
  344: 		default:
  345: 			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
  346: 			/* FALLTHROUGH */
  347: 		case 1:
  348: 			btype = "1020";
  349: 			isp->isp_type = ISP_HA_SCSI_1020;
  350: 			isp->isp_clock = 40;
  351: 			break;
  352: 		case 2:
  353: 			/*
  354: 			 * Some 1020A chips are Ultra Capable, but don't
  355: 			 * run the clock rate up for that unless told to
  356: 			 * do so by the Ultra Capable bits being set.
  357: 			 */
  358: 			btype = "1020A";
  359: 			isp->isp_type = ISP_HA_SCSI_1020A;
  360: 			isp->isp_clock = 40;
  361: 			break;
  362: 		case 3:
  363: 			btype = "1040";
  364: 			isp->isp_type = ISP_HA_SCSI_1040;
  365: 			isp->isp_clock = 60;
  366: 			break;
  367: 		case 4:
  368: 			btype = "1040A";
  369: 			isp->isp_type = ISP_HA_SCSI_1040A;
  370: 			isp->isp_clock = 60;
  371: 			break;
  372: 		case 5:
  373: 			btype = "1040B";
  374: 			isp->isp_type = ISP_HA_SCSI_1040B;
  375: 			isp->isp_clock = 60;
  376: 			break;
  377: 		case 6:
  378: 			btype = "1040C";
  379: 			isp->isp_type = ISP_HA_SCSI_1040C;
  380: 			isp->isp_clock = 60;
  381:                         break;
  382: 		}
  383: 		/*
  384: 		 * Now, while we're at it, gather info about ultra
  385: 		 * and/or differential mode.
  386: 		 */
  387: 		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
  388: 			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
  389: 			sdp->isp_diffmode = 1;
  390: 		} else {
  391: 			sdp->isp_diffmode = 0;
  392: 		}
  393: 		i = ISP_READ(isp, RISC_PSR);
  394: 		if (isp->isp_bustype == ISP_BT_SBUS) {
  395: 			i &= RISC_PSR_SBUS_ULTRA;
  396: 		} else {
  397: 			i &= RISC_PSR_PCI_ULTRA;
  398: 		}
  399: 		if (i != 0) {
  400: 			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
  401: 			sdp->isp_ultramode = 1;
  402: 			/*
  403: 			 * If we're in Ultra Mode, we have to be 60Mhz clock-
  404: 			 * even for the SBus version.
  405: 			 */
  406: 			isp->isp_clock = 60;
  407: 		} else {
  408: 			sdp->isp_ultramode = 0;
  409: 			/*
  410: 			 * Clock is known. Gronk.
  411: 			 */
  412: 		}
  413: 
  414: 		/*
  415: 		 * Machine dependent clock (if set) overrides
  416: 		 * our generic determinations.
  417: 		 */
  418: 		if (isp->isp_mdvec->dv_clock) {
  419: 			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
  420: 				isp->isp_clock = isp->isp_mdvec->dv_clock;
  421: 			}
  422: 		}
  423: 
  424: 	}
  425: 
  426: 	/*
  427: 	 * Clear instrumentation
  428: 	 */
  429: 	isp->isp_intcnt = isp->isp_intbogus = 0;
  430: 
  431: 	/*
  432: 	 * Do MD specific pre initialization
  433: 	 */
  434: 	ISP_RESET0(isp);
  435: 
  436: again:
  437: 
  438: 	/*
  439: 	 * Hit the chip over the head with hammer,
  440: 	 * and give the ISP a chance to recover.
  441: 	 */
  442: 
  443: 	if (IS_SCSI(isp)) {
  444: 		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
  445: 		/*
  446: 		 * A slight delay...
  447: 		 */
  448: 		USEC_DELAY(100);
  449: 
  450: 		/*
  451: 		 * Clear data && control DMA engines.
  452: 		 */
  453: 		ISP_WRITE(isp, CDMA_CONTROL,
  454: 		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
  455: 		ISP_WRITE(isp, DDMA_CONTROL,
  456: 		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
  457: 
  458: 
  459: 	} else {
  460: 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
  461: 		/*
  462: 		 * A slight delay...
  463: 		 */
  464: 		USEC_DELAY(100);
  465: 
  466: 		/*
  467: 		 * Clear data && control DMA engines.
  468: 		 */
  469: 		ISP_WRITE(isp, CDMA2100_CONTROL,
  470: 			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  471: 		ISP_WRITE(isp, TDMA2100_CONTROL,
  472: 			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  473: 		ISP_WRITE(isp, RDMA2100_CONTROL,
  474: 			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
  475: 	}
  476: 
  477: 	/*
  478: 	 * Wait for ISP to be ready to go...
  479: 	 */
  480: 	loops = MBOX_DELAY_COUNT;
  481: 	for (;;) {
  482: 		if (IS_SCSI(isp)) {
  483: 			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
  484: 				break;
  485: 		} else {
  486: 			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
  487: 				break;
  488: 		}
  489: 		USEC_DELAY(100);
  490: 		if (--loops < 0) {
  491: 			ISP_DUMPREGS(isp, "chip reset timed out");
  492: 			return;
  493: 		}
  494: 	}
  495: 
  496: 	/*
  497: 	 * After we've fired this chip up, zero out the conf1 register
  498: 	 * for SCSI adapters and other settings for the 2100.
  499: 	 */
  500: 
  501: 	if (IS_SCSI(isp)) {
  502: 		ISP_WRITE(isp, BIU_CONF1, 0);
  503: 	} else {
  504: 		ISP_WRITE(isp, BIU2100_CSR, 0);
  505: 	}
  506: 
  507: 	/*
  508: 	 * Reset RISC Processor
  509: 	 */
  510: 	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
  511: 	USEC_DELAY(100);
  512: 	/* Clear semaphore register (just to be sure) */
  513: 	ISP_WRITE(isp, BIU_SEMA, 0);
  514: 
  515: 	/*
  516: 	 * Establish some initial burst rate stuff.
  517: 	 * (only for the 1XX0 boards). This really should
  518: 	 * be done later after fetching from NVRAM.
  519: 	 */
  520: 	if (IS_SCSI(isp)) {
  521: 		u_int16_t tmp = isp->isp_mdvec->dv_conf1;
  522: 		/*
  523: 		 * Busted FIFO. Turn off all but burst enables.
  524: 		 */
  525: 		if (isp->isp_type == ISP_HA_SCSI_1040A) {
  526: 			tmp &= BIU_BURST_ENABLE;
  527: 		}
  528: 		ISP_SETBITS(isp, BIU_CONF1, tmp);
  529: 		if (tmp & BIU_BURST_ENABLE) {
  530: 			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
  531: 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
  532: 		}
  533: #ifdef	PTI_CARDS
  534: 		if (((sdparam *) isp->isp_param)->isp_ultramode) {
  535: 			while (ISP_READ(isp, RISC_MTR) != 0x1313) {
  536: 				ISP_WRITE(isp, RISC_MTR, 0x1313);
  537: 				ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
  538: 			}
  539: 		} else {
  540: 			ISP_WRITE(isp, RISC_MTR, 0x1212);
  541: 		}
  542: 		/*
  543: 		 * PTI specific register
  544: 		 */
  545: 		ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
  546: #else
  547: 		ISP_WRITE(isp, RISC_MTR, 0x1212);
  548: #endif
  549: 	} else {
  550: 		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
  551: 		if (IS_2200(isp) || IS_23XX(isp)) {
  552: 			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
  553: 		}
  554: 	}
  555: 
  556: 	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
  557: 
  558: 	/*
  559: 	 * Do MD specific post initialization
  560: 	 */
  561: 	ISP_RESET1(isp);
  562: 
  563: 	/*
  564: 	 * Wait for everything to finish firing up.
  565: 	 *
  566: 	 * Avoid doing this on the 2312 because you can generate a PCI
  567: 	 * parity error (chip breakage).
  568: 	 */
  569: 	if (IS_23XX(isp)) {
  570: 		USEC_DELAY(5);
  571: 	} else {
  572: 		loops = MBOX_DELAY_COUNT;
  573: 		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
  574: 			USEC_DELAY(100);
  575: 			if (--loops < 0) {
  576: 				isp_prt(isp, ISP_LOGERR,
  577: 				    "MBOX_BUSY never cleared on reset");
  578: 				return;
  579: 			}
  580: 		}
  581: 	}
  582: 
  583: 	/*
  584: 	 * Up until this point we've done everything by just reading or
  585: 	 * setting registers. From this point on we rely on at least *some*
  586: 	 * kind of firmware running in the card.
  587: 	 */
  588: 
  589: 	/*
  590: 	 * Do some sanity checking.
  591: 	 */
  592: 	mbs.param[0] = MBOX_NO_OP;
  593: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  594: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  595: 		return;
  596: 	}
  597: 
  598: 	if (IS_SCSI(isp)) {
  599: 		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
  600: 		mbs.param[1] = 0xdead;
  601: 		mbs.param[2] = 0xbeef;
  602: 		mbs.param[3] = 0xffff;
  603: 		mbs.param[4] = 0x1111;
  604: 		mbs.param[5] = 0xa5a5;
  605: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
  606: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  607: 			return;
  608: 		}
  609: 		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
  610: 		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
  611: 		    mbs.param[5] != 0xa5a5) {
  612: 			isp_prt(isp, ISP_LOGERR,
  613: 			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
  614: 			    mbs.param[1], mbs.param[2], mbs.param[3],
  615: 			    mbs.param[4], mbs.param[5]);
  616: 			return;
  617: 		}
  618: 
  619: 	}
  620: 
  621: 	/*
  622: 	 * Download new Firmware, unless requested not to do so.
  623: 	 * This is made slightly trickier in some cases where the
  624: 	 * firmware of the ROM revision is newer than the revision
  625: 	 * compiled into the driver. So, where we used to compare
  626: 	 * versions of our f/w and the ROM f/w, now we just see
  627: 	 * whether we have f/w at all and whether a config flag
  628: 	 * has disabled our download.
  629: 	 */
  630: 	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
  631: 	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
  632: 		dodnld = 0;
  633: 	}
  634: 
  635: 	if (IS_23XX(isp))
  636: 		code_org = ISP_CODE_ORG_2300;
  637: 	else
  638: 		code_org = ISP_CODE_ORG;
  639: 
  640: 	if (dodnld) {
  641: 		isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1];
  642: 		isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1;
  643: 		isp->isp_mbxwrk1 = code_org + 1;
  644: 		mbs.param[0] = MBOX_WRITE_RAM_WORD;
  645: 		mbs.param[1] = code_org;
  646: 		mbs.param[2] = isp->isp_mdvec->dv_ispfw[0];
  647: 		isp_mboxcmd(isp, &mbs, MBLOGNONE);
  648: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  649: 			isp_prt(isp, ISP_LOGERR,
  650: 			    "F/W download failed at word %d",
  651: 			    isp->isp_mbxwrk1 - code_org);
  652: 			dodnld = 0;
  653: 			goto again;
  654: 		}
  655: 		/*
  656: 		 * Verify that it downloaded correctly.
  657: 		 */
  658: 		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
  659: 		mbs.param[1] = code_org;
  660: 		isp_mboxcmd(isp, &mbs, MBLOGNONE);
  661: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  662: 			isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
  663: 			return;
  664: 		}
  665: 		isp->isp_loaded_fw = 1;
  666: 	} else {
  667: 		isp->isp_loaded_fw = 0;
  668: 		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
  669: 	}
  670: 
  671: 	/*
  672: 	 * Now start it rolling.
  673: 	 *
  674: 	 * If we didn't actually download f/w,
  675: 	 * we still need to (re)start it.
  676: 	 */
  677: 
  678: 
  679: 	mbs.param[0] = MBOX_EXEC_FIRMWARE;
  680: 	mbs.param[1] = code_org;
  681: 	isp_mboxcmd(isp, &mbs, MBLOGNONE);
  682: 	/*
  683: 	 * Give it a chance to start.
  684: 	 */
  685: 	USEC_DELAY(500);
  686: 
  687: 	if (IS_SCSI(isp)) {
  688: 		/*
  689: 		 * Set CLOCK RATE, but only if asked to.
  690: 		 */
  691: 		if (isp->isp_clock) {
  692: 			mbs.param[0] = MBOX_SET_CLOCK_RATE;
  693: 			mbs.param[1] = isp->isp_clock;
  694: 			isp_mboxcmd(isp, &mbs, MBLOGALL);
  695: 			/* we will try not to care if this fails */
  696: 		}
  697: 	}
  698: 
  699: 	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
  700: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  701: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  702: 		return;
  703: 	}
  704: 
  705: 	/*
  706: 	 * The SBus firmware that we are using apparently does not return
  707: 	 * major, minor, micro revisions in the mailbox registers, which
  708: 	 * is really, really, annoying.
  709: 	 */
  710: 	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
  711: 		if (dodnld) {
  712: #ifdef	ISP_TARGET_MODE
  713: 			isp->isp_fwrev[0] = 7;
  714: 			isp->isp_fwrev[1] = 55;
  715: #else
  716: 			isp->isp_fwrev[0] = 1;
  717: 			isp->isp_fwrev[1] = 37;
  718: #endif
  719: 			isp->isp_fwrev[2] = 0;
  720: 		} 
  721: 	} else {
  722: 		isp->isp_fwrev[0] = mbs.param[1];
  723: 		isp->isp_fwrev[1] = mbs.param[2];
  724: 		isp->isp_fwrev[2] = mbs.param[3];
  725: 	}
  726: 	isp_prt(isp, ISP_LOGCONFIG,
  727: 	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
  728: 	    btype, isp->isp_revision, dodnld? "loaded" : "resident",
  729: 	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
  730: 
  731: 	if (IS_FC(isp)) {
  732: 		/*
  733: 		 * We do not believe firmware attributes for 2100 code less
  734: 		 * than 1.17.0, unless it's the firmware we specifically
  735: 		 * are loading.
  736: 		 *
  737: 		 * Note that all 22XX and 23XX f/w is greater than 1.X.0.
  738: 		 */
  739: 		if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
  740: #ifdef	USE_SMALLER_2100_FIRMWARE
  741: 			FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
  742: #else
  743: 			FCPARAM(isp)->isp_fwattr = 0;
  744: #endif
  745: 		} else {
  746: 			FCPARAM(isp)->isp_fwattr = mbs.param[6];
  747: 			isp_prt(isp, ISP_LOGDEBUG0,
  748: 			    "Firmware Attributes = 0x%x", mbs.param[6]);
  749: 		}
  750: 		if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
  751: 			isp_prt(isp, ISP_LOGCONFIG,
  752: 			    "Installed in 64-Bit PCI slot");
  753: 		}
  754: 	}
  755: 
  756: 	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
  757: 	    isp->isp_romfw_rev[2]) {
  758: 		isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
  759: 		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
  760: 		    isp->isp_romfw_rev[2]);
  761: 	}
  762: 
  763: 	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
  764: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  765: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  766: 		return;
  767: 	}
  768: 	isp->isp_maxcmds = mbs.param[2];
  769: 	isp_prt(isp, ISP_LOGINFO,
  770: 	    "%d max I/O commands supported", mbs.param[2]);
  771: 	isp_fw_state(isp);
  772: 
  773: 	/*
  774: 	 * Set up DMA for the request and result mailboxes.
  775: 	 */
  776: 	if (ISP_MBOXDMASETUP(isp) != 0) {
  777: 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
  778: 		return;
  779: 	}
  780: 	isp->isp_state = ISP_RESETSTATE;
  781: 
  782: 	/*
  783: 	 * Okay- now that we have new firmware running, we now (re)set our
  784: 	 * notion of how many luns we support. This is somewhat tricky because
  785: 	 * if we haven't loaded firmware, we sometimes do not have an easy way
  786: 	 * of knowing how many luns we support.
  787: 	 *
  788: 	 * Expanded lun firmware gives you 32 luns for SCSI cards and
  789: 	 * 16384 luns for Fibre Channel cards.
  790: 	 *
  791: 	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
  792: 	 * we do get a firmware attributes word returned in mailbox register 6.
  793: 	 *
  794: 	 * Because the lun is in a a different position in the Request Queue
  795: 	 * Entry structure for Fibre Channel with expanded lun firmware, we
  796: 	 * can only support one lun (lun zero) when we don't know what kind
  797: 	 * of firmware we're running.
  798: 	 *
  799: 	 * Note that we only do this once (the first time thru isp_reset)
  800: 	 * because we may be called again after firmware has been loaded once
  801: 	 * and released.
  802: 	 */
  803: 	if (IS_SCSI(isp)) {
  804: 		if (dodnld) {
  805: 			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
  806: 				isp->isp_maxluns = 32;
  807: 			} else {
  808: 				isp->isp_maxluns = 8;
  809: 			}
  810: 		} else {
  811: 			isp->isp_maxluns = 8;
  812: 		}
  813: 	} else {
  814: 		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
  815: 			isp->isp_maxluns = 16384;
  816: 		} else {
  817: 			isp->isp_maxluns = 16;
  818: 		}
  819: 	}
  820: }
  821: 
  822: /*
  823:  * Initialize Parameters of Hardware to a known state.
  824:  *
  825:  * Locks are held before coming here.
  826:  */
  827: 
  828: void
  829: isp_init(struct ispsoftc *isp)
  830: {
  831: 	/*
  832: 	 * Must do this first to get defaults established.
  833: 	 */
  834: 	isp_setdfltparm(isp, 0);
  835: 	if (IS_DUALBUS(isp)) {
  836: 		isp_setdfltparm(isp, 1);
  837: 	}
  838: 	if (IS_FC(isp)) {
  839: 		isp_fibre_init(isp);
  840: 	} else {
  841: 		isp_scsi_init(isp);
  842: 	}
  843: }
  844: 
  845: static void
  846: isp_scsi_init(struct ispsoftc *isp)
  847: {
  848: 	sdparam *sdp_chan0, *sdp_chan1;
  849: 	mbreg_t mbs;
  850: 
  851: 	sdp_chan0 = isp->isp_param;
  852: 	sdp_chan1 = sdp_chan0;
  853: 	if (IS_DUALBUS(isp)) {
  854: 		sdp_chan1++;
  855: 	}
  856: 
  857: 	/*
  858: 	 * If we have no role (neither target nor initiator), return.
  859: 	 */
  860: 	if (isp->isp_role == ISP_ROLE_NONE) {
  861: 		return;
  862: 	}
  863: 
  864: 	/* First do overall per-card settings. */
  865: 
  866: 	/*
  867: 	 * If we have fast memory timing enabled, turn it on.
  868: 	 */
  869: 	if (sdp_chan0->isp_fast_mttr) {
  870: 		ISP_WRITE(isp, RISC_MTR, 0x1313);
  871: 	}
  872: 
  873: 	/*
  874: 	 * Set Retry Delay and Count.
  875: 	 * You set both channels at the same time.
  876: 	 */
  877: 	mbs.param[0] = MBOX_SET_RETRY_COUNT;
  878: 	mbs.param[1] = sdp_chan0->isp_retry_count;
  879: 	mbs.param[2] = sdp_chan0->isp_retry_delay;
  880: 	mbs.param[6] = sdp_chan1->isp_retry_count;
  881: 	mbs.param[7] = sdp_chan1->isp_retry_delay;
  882: 
  883: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  884: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  885: 		return;
  886: 	}
  887: 
  888: 	/*
  889: 	 * Set ASYNC DATA SETUP time. This is very important.
  890: 	 */
  891: 	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
  892: 	mbs.param[1] = sdp_chan0->isp_async_data_setup;
  893: 	mbs.param[2] = sdp_chan1->isp_async_data_setup;
  894: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  895: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  896: 		return;
  897: 	}
  898: 
  899: 	/*
  900: 	 * Set ACTIVE Negation State.
  901: 	 */
  902: 	mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
  903: 	mbs.param[1] =
  904: 	    (sdp_chan0->isp_req_ack_active_neg << 4) |
  905: 	    (sdp_chan0->isp_data_line_active_neg << 5);
  906: 	mbs.param[2] =
  907: 	    (sdp_chan1->isp_req_ack_active_neg << 4) |
  908: 	    (sdp_chan1->isp_data_line_active_neg << 5);
  909: 
  910: 	isp_mboxcmd(isp, &mbs, MBLOGNONE);
  911: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  912: 		isp_prt(isp, ISP_LOGERR,
  913: 		    "failed to set active negation state (%d,%d), (%d,%d)",
  914: 		    sdp_chan0->isp_req_ack_active_neg,
  915: 		    sdp_chan0->isp_data_line_active_neg,
  916: 		    sdp_chan1->isp_req_ack_active_neg,
  917: 		    sdp_chan1->isp_data_line_active_neg);
  918: 		/*
  919: 		 * But don't return.
  920: 		 */
  921: 	}
  922: 
  923: 	/*
  924: 	 * Set the Tag Aging limit
  925: 	 */
  926: 	mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
  927: 	mbs.param[1] = sdp_chan0->isp_tag_aging;
  928: 	mbs.param[2] = sdp_chan1->isp_tag_aging;
  929: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  930: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  931: 		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
  932: 		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
  933: 		return;
  934: 	}
  935: 
  936: 	/*
  937: 	 * Set selection timeout.
  938: 	 */
  939: 	mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
  940: 	mbs.param[1] = sdp_chan0->isp_selection_timeout;
  941: 	mbs.param[2] = sdp_chan1->isp_selection_timeout;
  942: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
  943: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  944: 		return;
  945: 	}
  946: 
  947: 	/* now do per-channel settings */
  948: 	isp_scsi_channel_init(isp, 0);
  949: 	if (IS_DUALBUS(isp))
  950: 		isp_scsi_channel_init(isp, 1);
  951: 
  952: 	/*
  953: 	 * Now enable request/response queues
  954: 	 */
  955: 
  956: 	if (IS_ULTRA2(isp) || IS_1240(isp)) {
  957: 		mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
  958: 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
  959: 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
  960: 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
  961: 		mbs.param[4] = 0;
  962: 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
  963: 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
  964: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
  965: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  966: 			return;
  967: 		}
  968: 		isp->isp_residx = mbs.param[5];
  969: 
  970: 		mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
  971: 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
  972: 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  973: 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  974: 		mbs.param[5] = 0;
  975: 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
  976: 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
  977: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
  978: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  979: 			return;
  980: 		}
  981: 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
  982: 	} else {
  983: 		mbs.param[0] = MBOX_INIT_RES_QUEUE;
  984: 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
  985: 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
  986: 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
  987: 		mbs.param[4] = 0;
  988: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
  989: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
  990: 			return;
  991: 		}
  992: 		isp->isp_residx = mbs.param[5];
  993: 
  994: 		mbs.param[0] = MBOX_INIT_REQ_QUEUE;
  995: 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
  996: 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
  997: 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
  998: 		mbs.param[5] = 0;
  999: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 1000: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1001: 			return;
 1002: 		}
 1003: 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 1004: 	}
 1005: 
 1006: 	/*
 1007: 	 * Turn on Fast Posting, LVD transitions
 1008: 	 *
 1009: 	 * Ultra2 F/W always has had fast posting (and LVD transitions)
 1010: 	 *
 1011: 	 * Ultra and older (i.e., SBus) cards may not. It's just safer
 1012: 	 * to assume not for them.
 1013: 	 */
 1014: 
 1015: 	mbs.param[0] = MBOX_SET_FW_FEATURES;
 1016: 	mbs.param[1] = 0;
 1017: 	if (IS_ULTRA2(isp))
 1018: 		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
 1019: #ifndef	ISP_NO_RIO
 1020: 	if (IS_ULTRA2(isp) || IS_1240(isp))
 1021: 		mbs.param[1] |= FW_FEATURE_RIO_16BIT;
 1022: #else
 1023: #ifndef	ISP_NO_FASTPOST
 1024: 	if (IS_ULTRA2(isp) || IS_1240(isp))
 1025: 		mbs.param[1] |= FW_FEATURE_FAST_POST;
 1026: #endif
 1027: #endif
 1028: 	if (mbs.param[1] != 0) {
 1029: 		u_int16_t sfeat = mbs.param[1];
 1030: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 1031: 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1032: 			isp_prt(isp, ISP_LOGINFO,
 1033: 			    "Enabled FW features (0x%x)", sfeat);
 1034: 		}
 1035: 	}
 1036: 
 1037: 	/*
 1038: 	 * Let the outer layers decide whether to issue a SCSI bus reset.
 1039: 	 */
 1040: 	isp->isp_state = ISP_INITSTATE;
 1041: }
 1042: 
 1043: static void
 1044: isp_scsi_channel_init(struct ispsoftc *isp, int channel)
 1045: {
 1046: 	sdparam *sdp;
 1047: 	mbreg_t mbs;
 1048: 	int tgt;
 1049: 
 1050: 	sdp = isp->isp_param;
 1051: 	sdp += channel;
 1052: 
 1053: 	/*
 1054: 	 * Set (possibly new) Initiator ID.
 1055: 	 */
 1056: 	mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
 1057: 	mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
 1058: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
 1059: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1060: 		return;
 1061: 	}
 1062: 	isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
 1063: 	    sdp->isp_initiator_id, channel);
 1064: 
 1065: 
 1066: 	/*
 1067: 	 * Set current per-target parameters to an initial safe minimum.
 1068: 	 */
 1069: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 1070: 		int lun;
 1071: 		u_int16_t sdf;
 1072: 
 1073: 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
 1074: 			continue;
 1075: 		}
 1076: #ifndef	ISP_TARGET_MODE
 1077: 		sdf = sdp->isp_devparam[tgt].goal_flags;
 1078: 		sdf &= DPARM_SAFE_DFLT;
 1079: 		/*
 1080: 		 * It is not quite clear when this changed over so that
 1081: 		 * we could force narrow and async for 1000/1020 cards,
 1082: 		 * but assume that this is only the case for loaded
 1083: 		 * firmware.
 1084: 		 */
 1085: 		if (isp->isp_loaded_fw) {
 1086: 			sdf |= DPARM_NARROW | DPARM_ASYNC;
 1087: 		}
 1088: #else
 1089: 		/*
 1090: 		 * The !$*!)$!$)* f/w uses the same index into some
 1091: 		 * internal table to decide how to respond to negotiations,
 1092: 		 * so if we've said "let's be safe" for ID X, and ID X
 1093: 		 * selects *us*, the negotiations will back to 'safe'
 1094: 		 * (as in narrow/async). What the f/w *should* do is
 1095: 		 * use the initiator id settings to decide how to respond.
 1096: 		 */
 1097: 		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
 1098: #endif
 1099: 		mbs.param[0] = MBOX_SET_TARGET_PARAMS;
 1100: 		mbs.param[1] = (channel << 15) | (tgt << 8);
 1101: 		mbs.param[2] = sdf;
 1102: 		if ((sdf & DPARM_SYNC) == 0) {
 1103: 			mbs.param[3] = 0;
 1104: 		} else {
 1105: 			mbs.param[3] =
 1106: 			    (sdp->isp_devparam[tgt].goal_offset << 8) |
 1107: 			    (sdp->isp_devparam[tgt].goal_period);
 1108: 		}
 1109: 		isp_prt(isp, ISP_LOGDEBUG0,
 1110: 		    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
 1111: 		    channel, tgt, mbs.param[2], mbs.param[3] >> 8,
 1112: 		    mbs.param[3] & 0xff);
 1113: 		isp_mboxcmd(isp, &mbs, MBLOGNONE);
 1114: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1115: 			sdf = DPARM_SAFE_DFLT;
 1116: 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
 1117: 			mbs.param[1] = (tgt << 8) | (channel << 15);
 1118: 			mbs.param[2] = sdf;
 1119: 			mbs.param[3] = 0;
 1120: 			isp_mboxcmd(isp, &mbs, MBLOGALL);
 1121: 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1122: 				continue;
 1123: 			}
 1124: 		}
 1125: 
 1126: 		/*
 1127: 		 * We don't update any information directly from the f/w
 1128: 		 * because we need to run at least one command to cause a
 1129: 		 * new state to be latched up. So, we just assume that we
 1130: 		 * converge to the values we just had set.
 1131: 		 *
 1132: 		 * Ensure that we don't believe tagged queuing is enabled yet.
 1133: 		 * It turns out that sometimes the ISP just ignores our
 1134: 		 * attempts to set parameters for devices that it hasn't
 1135: 		 * seen yet.
 1136: 		 */
 1137: 		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
 1138: 		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
 1139: 			mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
 1140: 			mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
 1141: 			mbs.param[2] = sdp->isp_max_queue_depth;
 1142: 			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
 1143: 			isp_mboxcmd(isp, &mbs, MBLOGALL);
 1144: 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1145: 				break;
 1146: 			}
 1147: 		}
 1148: 	}
 1149: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 1150: 		if (sdp->isp_devparam[tgt].dev_refresh) {
 1151: 			isp->isp_sendmarker |= (1 << channel);
 1152: 			isp->isp_update |= (1 << channel);
 1153: 			break;
 1154: 		}
 1155: 	}
 1156: }
 1157: 
 1158: /*
 1159:  * Fibre Channel specific initialization.
 1160:  *
 1161:  * Locks are held before coming here.
 1162:  */
 1163: static void
 1164: isp_fibre_init(struct ispsoftc *isp)
 1165: {
 1166: 	fcparam *fcp;
 1167: 	isp_icb_t local, *icbp = &local;
 1168: 	mbreg_t mbs;
 1169: 	int loopid;
 1170: 	u_int64_t nwwn, pwwn;
 1171: 
 1172: 	fcp = isp->isp_param;
 1173: 
 1174: 	/*
 1175: 	 * Do this *before* initializing the firmware.
 1176: 	 */
 1177: 	isp_mark_getpdb_all(isp);
 1178: 	fcp->isp_fwstate = FW_CONFIG_WAIT;
 1179: 	fcp->isp_loopstate = LOOP_NIL;
 1180: 
 1181: 	/*
 1182: 	 * If we have no role (neither target nor initiator), return.
 1183: 	 */
 1184: 	if (isp->isp_role == ISP_ROLE_NONE) {
 1185: 		return;
 1186: 	}
 1187: 
 1188: 	loopid = fcp->isp_loopid;
 1189: 	MEMZERO(icbp, sizeof (*icbp));
 1190: 	icbp->icb_version = ICB_VERSION1;
 1191: 
 1192: 	/*
 1193: 	 * Firmware Options are either retrieved from NVRAM or
 1194: 	 * are patched elsewhere. We check them for sanity here
 1195: 	 * and make changes based on board revision, but otherwise
 1196: 	 * let others decide policy.
 1197: 	 */
 1198: 
 1199: 	/*
 1200: 	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
 1201: 	 */
 1202: 	if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
 1203: 		fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
 1204: 	}
 1205: 
 1206: 	/*
 1207: 	 * We have to use FULL LOGIN even though it resets the loop too much
 1208: 	 * because otherwise port database entries don't get updated after
 1209: 	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
 1210: 	 */
 1211: 	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
 1212: 		fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
 1213: 	}
 1214: 
 1215: 	/*
 1216: 	 * Insist on Port Database Update Async notifications
 1217: 	 */
 1218: 	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
 1219: 
 1220: 	/*
 1221: 	 * Make sure that target role reflects into fwoptions.
 1222: 	 */
 1223: 	if (isp->isp_role & ISP_ROLE_TARGET) {
 1224: 		fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
 1225: 	} else {
 1226: 		fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
 1227: 	}
 1228: 
 1229: 	/*
 1230: 	 * Propagate all of this into the ICB structure.
 1231: 	 */
 1232: 	icbp->icb_fwoptions = fcp->isp_fwoptions;
 1233: 	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
 1234: 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
 1235: 	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
 1236: 		isp_prt(isp, ISP_LOGERR,
 1237: 		    "bad frame length (%d) from NVRAM- using %d",
 1238: 		    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
 1239: 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
 1240: 	}
 1241: 	icbp->icb_maxalloc = fcp->isp_maxalloc;
 1242: 	if (icbp->icb_maxalloc < 1) {
 1243: 		isp_prt(isp, ISP_LOGERR,
 1244: 		    "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
 1245: 		icbp->icb_maxalloc = 16;
 1246: 	}
 1247: 	icbp->icb_execthrottle = fcp->isp_execthrottle;
 1248: 	if (icbp->icb_execthrottle < 1) {
 1249: 		isp_prt(isp, ISP_LOGERR,
 1250: 		    "bad execution throttle of %d- using 16",
 1251: 		    fcp->isp_execthrottle);
 1252: 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
 1253: 	}
 1254: 	icbp->icb_retry_delay = fcp->isp_retry_delay;
 1255: 	icbp->icb_retry_count = fcp->isp_retry_count;
 1256: 	icbp->icb_hardaddr = loopid;
 1257: 	/*
 1258: 	 * Right now we just set extended options to prefer point-to-point
 1259: 	 * over loop based upon some soft config options.
 1260: 	 * 
 1261: 	 * NB: for the 2300, ICBOPT_EXTENDED is required.
 1262: 	 */
 1263: 	if (IS_2200(isp) || IS_23XX(isp)) {
 1264: 		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
 1265: 		/*
 1266: 		 * Prefer or force Point-To-Point instead Loop?
 1267: 		 */
 1268: 		switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
 1269: 		case ISP_CFG_NPORT:
 1270: 			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
 1271: 			break;
 1272: 		case ISP_CFG_NPORT_ONLY:
 1273: 			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
 1274: 			break;
 1275: 		case ISP_CFG_LPORT_ONLY:
 1276: 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
 1277: 			break;
 1278: 		default:
 1279: 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
 1280: 			break;
 1281: 		}
 1282: 		if (IS_23XX(isp)) {
 1283: 			/*
 1284: 			 * QLogic recommends that FAST Posting be turned
 1285: 			 * off for 23XX cards and instead allow the HBA
 1286: 			 * to write response queue entries and interrupt
 1287: 			 * after a delay (ZIO).
 1288: 			 *
 1289: 			 * If we set ZIO, it will disable fast posting,
 1290: 			 * so we don't need to clear it in fwoptions.
 1291: 			 */
 1292: 			icbp->icb_xfwoptions |= ICBXOPT_ZIO;
 1293: 
 1294: 			if (isp->isp_confopts & ISP_CFG_ONEGB) {
 1295: 				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
 1296: 			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
 1297: 				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
 1298: 			} else {
 1299: 				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
 1300: 			}
 1301: 		}
 1302: 	}
 1303: 
 1304: #ifndef	ISP_NO_RIO_FC
 1305: 	/*
 1306: 	 * RIO seems to be enabled in 2100s for fw >= 1.17.0.
 1307: 	 *
 1308: 	 * I've had some questionable problems with RIO on 2200.
 1309: 	 * More specifically, on a 2204 I had problems with RIO
 1310: 	 * on a Linux system where I was dropping commands right
 1311: 	 * and left. It's not clear to me what the actual problem
 1312: 	 * was.
 1313: 	 *
 1314: 	 * 23XX Cards do not support RIO. Instead they support ZIO.
 1315: 	 */
 1316: #if	0
 1317: 	if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
 1318: 		icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
 1319: 		icbp->icb_racctimer = 4;
 1320: 		icbp->icb_idelaytimer = 8;
 1321: 	}
 1322: #endif
 1323: #endif
 1324: 
 1325: 	/*
 1326: 	 * For 22XX > 2.1.26 && 23XX, set someoptions.
 1327: 	 * XXX: Probably okay for newer 2100 f/w too.
 1328: 	 */
 1329: 	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
 1330: 		/*
 1331: 		 * Turn on LIP F8 async event (1)
 1332: 		 * Turn on generate AE 8013 on all LIP Resets (2)
 1333: 		 * Disable LIP F7 switching (8)
 1334: 		 */
 1335: 		mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
 1336: 		mbs.param[1] = 0xb;
 1337: 		mbs.param[2] = 0;
 1338: 		mbs.param[3] = 0;
 1339: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 1340: 	}
 1341: 	icbp->icb_logintime = 30;	/* 30 second login timeout */
 1342: 
 1343: 	if (IS_23XX(isp)) {
 1344: 		ISP_WRITE(isp, isp->isp_rqstinrp, 0);
 1345:         	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
 1346:         	ISP_WRITE(isp, isp->isp_respinrp, 0);
 1347: 		ISP_WRITE(isp, isp->isp_respoutrp, 0);
 1348: 	}
 1349: 
 1350: 	nwwn = ISP_NODEWWN(isp);
 1351: 	pwwn = ISP_PORTWWN(isp);
 1352: 	if (nwwn && pwwn) {
 1353: 		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
 1354: 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
 1355: 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
 1356: 		isp_prt(isp, ISP_LOGDEBUG1,
 1357: 		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
 1358: 		    ((u_int32_t) (nwwn >> 32)),
 1359: 		    ((u_int32_t) (nwwn & 0xffffffff)),
 1360: 		    ((u_int32_t) (pwwn >> 32)),
 1361: 		    ((u_int32_t) (pwwn & 0xffffffff)));
 1362: 	} else {
 1363: 		isp_prt(isp, ISP_LOGDEBUG1, "Not using any WWNs");
 1364: 		icbp->icb_fwoptions &= ~(ICBOPT_BOTH_WWNS|ICBOPT_FULL_LOGIN);
 1365: 	}
 1366: 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
 1367: 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
 1368: 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
 1369: 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
 1370: 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
 1371: 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
 1372: 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
 1373: 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
 1374: 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
 1375: 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
 1376: 	isp_prt(isp, ISP_LOGDEBUG0,
 1377: 	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
 1378: 	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
 1379: 
 1380: 	FC_SCRATCH_ACQUIRE(isp);
 1381: 	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
 1382: 
 1383: 	/*
 1384: 	 * Init the firmware
 1385: 	 */
 1386: 	mbs.param[0] = MBOX_INIT_FIRMWARE;
 1387: 	mbs.param[1] = 0;
 1388: 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 1389: 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 1390: 	mbs.param[4] = 0;
 1391: 	mbs.param[5] = 0;
 1392: 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 1393: 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 1394: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
 1395: 	FC_SCRATCH_RELEASE(isp);
 1396: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1397: 		return;
 1398: 	}
 1399: 	isp->isp_reqidx = isp->isp_reqodx = 0;
 1400: 	isp->isp_residx = 0;
 1401: 	isp->isp_sendmarker = 1;
 1402: 
 1403: 	/*
 1404: 	 * Whatever happens, we're now committed to being here.
 1405: 	 */
 1406: 	isp->isp_state = ISP_INITSTATE;
 1407: }
 1408: 
 1409: /*
 1410:  * Fibre Channel Support- get the port database for the id.
 1411:  *
 1412:  * Locks are held before coming here. Return 0 if success,
 1413:  * else failure.
 1414:  */
 1415: 
 1416: static int
 1417: isp_getmap(struct ispsoftc *isp, fcpos_map_t *map)
 1418: {
 1419: 	fcparam *fcp = (fcparam *) isp->isp_param;
 1420: 	mbreg_t mbs;
 1421: 
 1422: 	mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP;
 1423: 	mbs.param[1] = 0;
 1424: 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 1425: 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 1426: 	/*
 1427: 	 * Unneeded. For the 2100, except for initializing f/w, registers
 1428: 	 * 4/5 have to not be written to.
 1429: 	 *	mbs.param[4] = 0;
 1430: 	 *	mbs.param[5] = 0;
 1431: 	 *
 1432: 	 */
 1433: 	mbs.param[6] = 0;
 1434: 	mbs.param[7] = 0;
 1435: 	FC_SCRATCH_ACQUIRE(isp);
 1436: 	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
 1437: 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1438: 		MEMCPY(map, fcp->isp_scratch, sizeof (fcpos_map_t));
 1439: 		map->fwmap = mbs.param[1] != 0;
 1440: 		FC_SCRATCH_RELEASE(isp);
 1441: 		return (0);
 1442: 	}
 1443: 	FC_SCRATCH_RELEASE(isp);
 1444: 	return (-1);
 1445: }
 1446: 
 1447: static void
 1448: isp_mark_getpdb_all(struct ispsoftc *isp)
 1449: {
 1450: 	fcparam *fcp = (fcparam *) isp->isp_param;
 1451: 	int i;
 1452: 	for (i = 0; i < MAX_FC_TARG; i++) {
 1453: 		fcp->portdb[i].valid = fcp->portdb[i].fabric_dev = 0;
 1454: 	}
 1455: }
 1456: 
 1457: static int
 1458: isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp)
 1459: {
 1460: 	fcparam *fcp = (fcparam *) isp->isp_param;
 1461: 	mbreg_t mbs;
 1462: 
 1463: 	mbs.param[0] = MBOX_GET_PORT_DB;
 1464: 	mbs.param[1] = id << 8;
 1465: 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 1466: 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 1467: 	/*
 1468: 	 * Unneeded. For the 2100, except for initializing f/w, registers
 1469: 	 * 4/5 have to not be written to.
 1470: 	 *	mbs.param[4] = 0;
 1471: 	 *	mbs.param[5] = 0;
 1472: 	 *
 1473: 	 */
 1474: 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 1475: 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 1476: 	FC_SCRATCH_ACQUIRE(isp);
 1477: 	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
 1478: 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1479: 		isp_get_pdb(isp, (isp_pdb_t *)fcp->isp_scratch, pdbp);
 1480: 		FC_SCRATCH_RELEASE(isp);
 1481: 		return (0);
 1482: 	}
 1483: 	FC_SCRATCH_RELEASE(isp);
 1484: 	return (-1);
 1485: }
 1486: 
 1487: static u_int64_t
 1488: isp_get_portname(struct ispsoftc *isp, int loopid, int nodename)
 1489: {
 1490: 	u_int64_t wwn = 0;
 1491: 	mbreg_t mbs;
 1492: 
 1493: 	mbs.param[0] = MBOX_GET_PORT_NAME;
 1494: 	mbs.param[1] = loopid << 8;
 1495: 	if (nodename)
 1496: 		mbs.param[1] |= 1;
 1497: 	isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR);
 1498: 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1499: 		wwn =
 1500: 		    (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
 1501: 		    (((u_int64_t)(mbs.param[2] >> 8))	<< 48) |
 1502: 		    (((u_int64_t)(mbs.param[3] & 0xff))	<< 40) |
 1503: 		    (((u_int64_t)(mbs.param[3] >> 8))	<< 32) |
 1504: 		    (((u_int64_t)(mbs.param[6] & 0xff))	<< 24) |
 1505: 		    (((u_int64_t)(mbs.param[6] >> 8))	<< 16) |
 1506: 		    (((u_int64_t)(mbs.param[7] & 0xff))	<<  8) |
 1507: 		    (((u_int64_t)(mbs.param[7] >> 8)));
 1508: 	}
 1509: 	return (wwn);
 1510: }
 1511: 
 1512: /*
 1513:  * Make sure we have good FC link and know our Loop ID.
 1514:  */
 1515: 
 1516: static int
 1517: isp_fclink_test(struct ispsoftc *isp, int usdelay)
 1518: {
 1519: 	static char *toponames[] = {
 1520: 		"Private Loop",
 1521: 		"FL Port",
 1522: 		"N-Port to N-Port",
 1523: 		"F Port",
 1524: 		"F Port (no FLOGI_ACC response)"
 1525: 	};
 1526: 	mbreg_t mbs;
 1527: 	int count, check_for_fabric;
 1528: 	u_int8_t lwfs;
 1529: 	fcparam *fcp;
 1530: 	struct lportdb *lp;
 1531: 	isp_pdb_t pdb;
 1532: 
 1533: 	fcp = isp->isp_param;
 1534: 
 1535: 	/*
 1536: 	 * XXX: Here is where we would start a 'loop dead' timeout
 1537: 	 */
 1538: 
 1539: 	/*
 1540: 	 * Wait up to N microseconds for F/W to go to a ready state.
 1541: 	 */
 1542: 	lwfs = FW_CONFIG_WAIT;
 1543: 	count = 0;
 1544: 	while (count < usdelay) {
 1545: 		u_int64_t enano;
 1546: 		u_int32_t wrk;
 1547: 		NANOTIME_T hra, hrb;
 1548: 
 1549: 		GET_NANOTIME(&hra);
 1550: 		isp_fw_state(isp);
 1551: 		if (lwfs != fcp->isp_fwstate) {
 1552: 			isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",
 1553: 			    isp2100_fw_statename((int)lwfs),
 1554: 			    isp2100_fw_statename((int)fcp->isp_fwstate));
 1555: 			lwfs = fcp->isp_fwstate;
 1556: 		}
 1557: 		if (fcp->isp_fwstate == FW_READY) {
 1558: 			break;
 1559: 		}
 1560: 		GET_NANOTIME(&hrb);
 1561: 
 1562: 		/*
 1563: 		 * Get the elapsed time in nanoseconds.
 1564: 		 * Always guaranteed to be non-zero.
 1565: 		 */
 1566: 		enano = NANOTIME_SUB(&hrb, &hra);
 1567: 
 1568: 		isp_prt(isp, ISP_LOGDEBUG1,
 1569: 		    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
 1570: 		    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
 1571: 		    (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));
 1572: 
 1573: 		/*
 1574: 		 * If the elapsed time is less than 1 millisecond,
 1575: 		 * delay a period of time up to that millisecond of
 1576: 		 * waiting.
 1577: 		 *
 1578: 		 * This peculiar code is an attempt to try and avoid
 1579: 		 * invoking u_int64_t math support functions for some
 1580: 		 * platforms where linkage is a problem.
 1581: 		 */
 1582: 		if (enano < (1000 * 1000)) {
 1583: 			count += 1000;
 1584: 			enano = (1000 * 1000) - enano;
 1585: 			while (enano > (u_int64_t) 4000000000U) {
 1586: 				USEC_SLEEP(isp, 4000000);
 1587: 				enano -= (u_int64_t) 4000000000U;
 1588: 			}
 1589: 			wrk = enano;
 1590: 			wrk /= 1000;
 1591: 			USEC_SLEEP(isp, wrk);
 1592: 		} else {
 1593: 			while (enano > (u_int64_t) 4000000000U) {
 1594: 				count += 4000000;
 1595: 				enano -= (u_int64_t) 4000000000U;
 1596: 			}
 1597: 			wrk = enano;
 1598: 			count += (wrk / 1000);
 1599: 		}
 1600: 	}
 1601: 
 1602: 	/*
 1603: 	 * If we haven't gone to 'ready' state, return.
 1604: 	 */
 1605: 	if (fcp->isp_fwstate != FW_READY) {
 1606: 		return (-1);
 1607: 	}
 1608: 
 1609: 	/*
 1610: 	 * Get our Loop ID (if possible). We really need to have it.
 1611: 	 */
 1612: 	mbs.param[0] = MBOX_GET_LOOP_ID;
 1613: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
 1614: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 1615: 		return (-1);
 1616: 	}
 1617: 	fcp->isp_loopid = mbs.param[1];
 1618: 	if (IS_2200(isp) || IS_23XX(isp)) {
 1619: 		int topo = (int) mbs.param[6];
 1620: 		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
 1621: 			topo = TOPO_PTP_STUB;
 1622: 		fcp->isp_topo = topo;
 1623: 	} else {
 1624: 		fcp->isp_topo = TOPO_NL_PORT;
 1625: 	}
 1626: 	fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;
 1627: 
 1628: 	/*
 1629: 	 * Check to see if we're on a fabric by trying to see if we
 1630: 	 * can talk to the fabric name server. This can be a bit
 1631: 	 * tricky because if we're a 2100, we should check always
 1632: 	 * (in case we're connected to an server doing aliasing).
 1633: 	 */
 1634: 	fcp->isp_onfabric = 0;
 1635: 
 1636: 	if (IS_2100(isp)) {
 1637: 		/*
 1638: 		 * Don't bother with fabric if we are using really old
 1639: 		 * 2100 firmware. It's just not worth it.
 1640: 		 */
 1641: 		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
 1642: 			check_for_fabric = 1;
 1643: 		} else {
 1644: 			check_for_fabric = 0;
 1645: 		}
 1646: 	} else if (fcp->isp_topo == TOPO_FL_PORT ||
 1647: 	    fcp->isp_topo == TOPO_F_PORT) {
 1648: 		check_for_fabric = 1;
 1649: 	} else
 1650: 		check_for_fabric = 0;
 1651: 
 1652: 	if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
 1653: 		int loopid = FL_PORT_ID;
 1654: 		if (IS_2100(isp)) {
 1655: 			fcp->isp_topo = TOPO_FL_PORT;
 1656: 		}
 1657: 
 1658: 		if (BITS2WORD(pdb.pdb_portid_bits) == 0) {
 1659: 			/*
 1660: 			 * Crock.
 1661: 			 */
 1662: 			fcp->isp_topo = TOPO_NL_PORT;
 1663: 			goto not_on_fabric;
 1664: 		}
 1665: 		fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);
 1666: 
 1667: 		/*
 1668: 		 * Save the Fabric controller's port database entry.
 1669: 		 */
 1670: 		lp = &fcp->portdb[loopid];
 1671: 		lp->node_wwn =
 1672: 		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
 1673: 		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
 1674: 		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
 1675: 		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
 1676: 		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
 1677: 		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
 1678: 		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
 1679: 		    (((u_int64_t)pdb.pdb_nodename[7]));
 1680: 		lp->port_wwn =
 1681: 		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
 1682: 		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
 1683: 		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
 1684: 		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
 1685: 		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
 1686: 		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
 1687: 		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
 1688: 		    (((u_int64_t)pdb.pdb_portname[7]));
 1689: 		lp->roles =
 1690: 		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 1691: 		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
 1692: 		lp->loopid = pdb.pdb_loopid;
 1693: 		lp->loggedin = lp->valid = 1;
 1694: 		fcp->isp_onfabric = 1;
 1695: 		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
 1696: 		isp_register_fc4_type(isp);
 1697: 	} else {
 1698: not_on_fabric:
 1699: 		fcp->isp_onfabric = 0;
 1700: 		fcp->portdb[FL_PORT_ID].valid = 0;
 1701: 	}
 1702: 
 1703: 	fcp->isp_gbspeed = 1;
 1704: 	if (IS_23XX(isp)) {
 1705: 		mbs.param[0] = MBOX_GET_SET_DATA_RATE;
 1706: 		mbs.param[1] = MBGSD_GET_RATE;
 1707: 		/* mbs.param[2] undefined if we're just getting rate */
 1708: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 1709: 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 1710: 			if (mbs.param[1] == MBGSD_TWOGB) {
 1711: 				isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
 1712: 				fcp->isp_gbspeed = 2;
 1713: 			}
 1714: 		}
 1715: 	}
 1716: 
 1717: 	isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,
 1718: 	    fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);
 1719: 
 1720: 	/*
 1721: 	 * Announce ourselves, too. This involves synthesizing an entry.
 1722: 	 */
 1723: 	if (fcp->isp_iid_set == 0) {
 1724: 		fcp->isp_iid_set = 1;
 1725: 		fcp->isp_iid = fcp->isp_loopid;
 1726: 		lp = &fcp->portdb[fcp->isp_iid];
 1727: 	} else {
 1728: 		lp = &fcp->portdb[fcp->isp_iid];
 1729: 		if (fcp->isp_portid != lp->portid ||
 1730: 		    fcp->isp_loopid != lp->loopid ||
 1731: 		    fcp->isp_nodewwn != ISP_NODEWWN(isp) ||
 1732: 		    fcp->isp_portwwn != ISP_PORTWWN(isp)) {
 1733: 			lp->valid = 0;
 1734: 			count = fcp->isp_iid;
 1735: 			(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
 1736: 		}
 1737: 	}
 1738: 	lp->loopid = fcp->isp_loopid;
 1739: 	lp->portid = fcp->isp_portid;
 1740: 	lp->node_wwn = ISP_NODEWWN(isp);
 1741: 	lp->port_wwn = ISP_PORTWWN(isp);
 1742: 	switch (isp->isp_role) {
 1743: 	case ISP_ROLE_NONE:
 1744: 		lp->roles = 0;
 1745: 		break;
 1746: 	case ISP_ROLE_TARGET:
 1747: 		lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;
 1748: 		break;
 1749: 	case ISP_ROLE_INITIATOR:
 1750: 		lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;
 1751: 		break;
 1752: 	case ISP_ROLE_BOTH:
 1753: 		lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;
 1754: 		break;
 1755: 	}
 1756: 	lp->loggedin = lp->valid = 1;
 1757: 	count = fcp->isp_iid;
 1758: 	(void) isp_async(isp, ISPASYNC_PROMENADE, &count);
 1759: 	return (0);
 1760: }
 1761: 
 1762: static char *
 1763: isp2100_fw_statename(int state)
 1764: {
 1765: 	switch(state) {
 1766: 	case FW_CONFIG_WAIT:	return "Config Wait";
 1767: 	case FW_WAIT_AL_PA:	return "Waiting for AL_PA";
 1768: 	case FW_WAIT_LOGIN:	return "Wait Login";
 1769: 	case FW_READY:		return "Ready";
 1770: 	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";
 1771: 	case FW_ERROR:		return "Error";
 1772: 	case FW_REINIT:		return "Re-Init";
 1773: 	case FW_NON_PART:	return "Nonparticipating";
 1774: 	default:		return "?????";
 1775: 	}
 1776: }
 1777: 
 1778: /*
 1779:  * Synchronize our soft copy of the port database with what the f/w thinks
 1780:  * (with a view toward possibly for a specific target....)
 1781:  */
 1782: 
 1783: static int
 1784: isp_pdb_sync(struct ispsoftc *isp)
 1785: {
 1786: 	struct lportdb *lp;
 1787: 	fcparam *fcp = isp->isp_param;
 1788: 	isp_pdb_t pdb;
 1789: 	int loopid, base, lim;
 1790: 
 1791: 	/*
 1792: 	 * Make sure we're okay for doing this right now.
 1793: 	 */
 1794: 	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
 1795: 	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
 1796: 	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
 1797: 		return (-1);
 1798: 	}
 1799: 
 1800: 	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||
 1801: 	    fcp->isp_topo == TOPO_N_PORT) {
 1802: 		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
 1803: 			if (isp_scan_loop(isp) != 0) {
 1804: 				return (-1);
 1805: 			}
 1806: 		}
 1807: 	}
 1808: 	fcp->isp_loopstate = LOOP_SYNCING_PDB;
 1809: 
 1810: 	/*
 1811: 	 * If we get this far, we've settled our differences with the f/w
 1812: 	 * (for local loop device) and we can say that the loop state is ready.
 1813: 	 */
 1814: 
 1815: 	if (fcp->isp_topo == TOPO_NL_PORT) {
 1816: 		fcp->loop_seen_once = 1;
 1817: 		fcp->isp_loopstate = LOOP_READY;
 1818: 		return (0);
 1819: 	}
 1820: 
 1821: 	/*
 1822: 	 * Find all Fabric Entities that didn't make it from one scan to the
 1823: 	 * next and let the world know they went away. Scan the whole database.
 1824: 	 */
 1825: 	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
 1826: 		if (lp->was_fabric_dev && lp->fabric_dev == 0) {
 1827: 			loopid = lp - fcp->portdb;
 1828: 			lp->valid = 0;	/* should already be set */
 1829: 			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
 1830: 			MEMZERO((void *) lp, sizeof (*lp));
 1831: 			continue;
 1832: 		}
 1833: 		lp->was_fabric_dev = lp->fabric_dev;
 1834: 	}
 1835: 
 1836: 	if (fcp->isp_topo == TOPO_FL_PORT)
 1837: 		base = FC_SNS_ID+1;
 1838: 	else
 1839: 		base = 0;
 1840: 
 1841: 	if (fcp->isp_topo == TOPO_N_PORT)
 1842: 		lim = 1;
 1843: 	else
 1844: 		lim = MAX_FC_TARG;
 1845: 
 1846: 	/*
 1847: 	 * Now log in any fabric devices that the outer layer has
 1848: 	 * left for us to see. This seems the most sane policy
 1849: 	 * for the moment.
 1850: 	 */
 1851: 	for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {
 1852: 		u_int32_t portid;
 1853: 		mbreg_t mbs;
 1854: 
 1855: 		loopid = lp - fcp->portdb;
 1856: 		if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {
 1857: 			continue;
 1858: 		}
 1859: 
 1860: 		/*
 1861: 		 * Anything here?
 1862: 		 */
 1863: 		if (lp->port_wwn == 0) {
 1864: 			continue;
 1865: 		}
 1866: 
 1867: 		/*
 1868: 		 * Don't try to log into yourself.
 1869: 		 */
 1870: 		if ((portid = lp->portid) == fcp->isp_portid) {
 1871: 			continue;
 1872: 		}
 1873: 
 1874: 
 1875: 		/*
 1876: 		 * If we'd been logged in- see if we still are and we haven't
 1877: 		 * changed. If so, no need to log ourselves out, etc..
 1878: 		 *
 1879: 		 * Unfortunately, our charming Qlogic f/w has decided to
 1880: 		 * return a valid port database entry for a fabric device
 1881: 		 * that has, in fact, gone away. And it hangs trying to
 1882: 		 * log it out.
 1883: 		 */
 1884: 		if (lp->loggedin && lp->force_logout == 0 &&
 1885: 		    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
 1886: 			int nrole;
 1887: 			u_int64_t nwwnn, nwwpn;
 1888: 			nwwnn =
 1889: 			    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
 1890: 			    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
 1891: 			    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
 1892: 			    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
 1893: 			    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
 1894: 			    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
 1895: 			    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
 1896: 			    (((u_int64_t)pdb.pdb_nodename[7]));
 1897: 			nwwpn =
 1898: 			    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
 1899: 			    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
 1900: 			    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
 1901: 			    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
 1902: 			    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
 1903: 			    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
 1904: 			    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
 1905: 			    (((u_int64_t)pdb.pdb_portname[7]));
 1906: 			nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
 1907: 			    SVC3_ROLE_SHIFT;
 1908: 			if (pdb.pdb_loopid == lp->loopid && lp->portid ==
 1909: 			    (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
 1910: 			    nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
 1911: 			    lp->roles == nrole && lp->force_logout == 0) {
 1912: 				lp->loggedin = lp->valid = 1;
 1913: 				isp_prt(isp, ISP_LOGCONFIG, lretained,
 1914: 				    (int) (lp - fcp->portdb),
 1915: 				    (int) lp->loopid, lp->portid);
 1916: 				continue;
 1917: 			}
 1918: 		}
 1919: 
 1920: 		if (fcp->isp_fwstate != FW_READY ||
 1921: 		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
 1922: 			return (-1);
 1923: 		}
 1924: 
 1925: 		/*
 1926: 		 * Force a logout if we were logged in.
 1927: 		 */
 1928: 		if (lp->loggedin) {
 1929: 			if (lp->force_logout ||
 1930: 			    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
 1931: 				mbs.param[0] = MBOX_FABRIC_LOGOUT;
 1932: 				mbs.param[1] = lp->loopid << 8;
 1933: 				mbs.param[2] = 0;
 1934: 				mbs.param[3] = 0;
 1935: 				isp_mboxcmd(isp, &mbs, MBLOGNONE);
 1936: 				isp_prt(isp, ISP_LOGINFO, plogout,
 1937: 				    (int) (lp - fcp->portdb), lp->loopid,
 1938: 				    lp->portid);
 1939: 			}
 1940: 			lp->force_logout = lp->loggedin = 0;
 1941: 			if (fcp->isp_fwstate != FW_READY ||
 1942: 			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
 1943: 				return (-1);
 1944: 			}
 1945: 		}
 1946: 
 1947: 		/*
 1948: 		 * And log in....
 1949: 		 */
 1950: 		loopid = lp - fcp->portdb;
 1951: 		lp->loopid = FL_PORT_ID;
 1952: 		do {
 1953: 			mbs.param[0] = MBOX_FABRIC_LOGIN;
 1954: 			mbs.param[1] = loopid << 8;
 1955: 			mbs.param[2] = portid >> 16;
 1956: 			mbs.param[3] = portid & 0xffff;
 1957: 			isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |
 1958: 			    MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));
 1959: 			if (fcp->isp_fwstate != FW_READY ||
 1960: 			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
 1961: 				return (-1);
 1962: 			}
 1963: 			switch (mbs.param[0]) {
 1964: 			case MBOX_LOOP_ID_USED:
 1965: 				/*
 1966: 				 * Try the next available loop id.
 1967: 				 */
 1968: 				loopid++;
 1969: 				break;
 1970: 			case MBOX_PORT_ID_USED:
 1971: 				/*
 1972: 				 * This port is already logged in.
 1973: 				 * Snaffle the loop id it's using if it's
 1974: 				 * nonzero, otherwise we're hosed.
 1975: 				 */
 1976: 				if (mbs.param[1] != 0) {
 1977: 					loopid = mbs.param[1];
 1978: 					isp_prt(isp, ISP_LOGINFO, retained,
 1979: 					    loopid, (int) (lp - fcp->portdb),
 1980: 					    lp->portid);
 1981: 				} else {
 1982: 					loopid = MAX_FC_TARG;
 1983: 					break;
 1984: 				}
 1985: 				/* FALLTHROUGH */
 1986: 			case MBOX_COMMAND_COMPLETE:
 1987: 				lp->loggedin = 1;
 1988: 				lp->loopid = loopid;
 1989: 				break;
 1990: 			case MBOX_COMMAND_ERROR:
 1991: 				isp_prt(isp, ISP_LOGINFO, plogierr,
 1992: 				    portid, mbs.param[1]);
 1993: 				/* FALLTHROUGH */
 1994: 			case MBOX_ALL_IDS_USED: /* We're outta IDs */
 1995: 			default:
 1996: 				loopid = MAX_FC_TARG;
 1997: 				break;
 1998: 			}
 1999: 		} while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);
 2000: 
 2001: 		/*
 2002: 		 * If we get here and we haven't set a Loop ID,
 2003: 		 * we failed to log into this device.
 2004: 		 */
 2005: 
 2006: 		if (lp->loopid == FL_PORT_ID) {
 2007: 			lp->loopid = 0;
 2008: 			continue;
 2009: 		}
 2010: 
 2011: 		/*
 2012: 		 * Make sure we can get the approriate port information.
 2013: 		 */
 2014: 		if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
 2015: 			isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);
 2016: 			goto dump_em;
 2017: 		}
 2018: 
 2019: 		if (fcp->isp_fwstate != FW_READY ||
 2020: 		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
 2021: 			return (-1);
 2022: 		}
 2023: 
 2024: 		if (pdb.pdb_loopid != lp->loopid) {
 2025: 			isp_prt(isp, ISP_LOGWARN, pdbmfail1,
 2026: 			    lp->portid, pdb.pdb_loopid);
 2027: 			goto dump_em;
 2028: 		}
 2029: 
 2030: 		if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
 2031: 			isp_prt(isp, ISP_LOGWARN, pdbmfail2,
 2032: 			    lp->portid, BITS2WORD(pdb.pdb_portid_bits));
 2033: 			goto dump_em;
 2034: 		}
 2035: 
 2036: 		lp->roles =
 2037: 		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 2038: 		lp->node_wwn =
 2039: 		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
 2040: 		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
 2041: 		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
 2042: 		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
 2043: 		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
 2044: 		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
 2045: 		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
 2046: 		    (((u_int64_t)pdb.pdb_nodename[7]));
 2047: 		lp->port_wwn =
 2048: 		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
 2049: 		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
 2050: 		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
 2051: 		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
 2052: 		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
 2053: 		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
 2054: 		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
 2055: 		    (((u_int64_t)pdb.pdb_portname[7]));
 2056: 		/*
 2057: 		 * Check to make sure this all makes sense.
 2058: 		 */
 2059: 		if (lp->node_wwn && lp->port_wwn) {
 2060: 			lp->valid = 1;
 2061: 			loopid = lp - fcp->portdb;
 2062: 			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
 2063: 			continue;
 2064: 		}
 2065: dump_em:
 2066: 		lp->valid = 0;
 2067: 		isp_prt(isp, ISP_LOGINFO,
 2068: 		    ldumped, loopid, lp->loopid, lp->portid);
 2069: 		mbs.param[0] = MBOX_FABRIC_LOGOUT;
 2070: 		mbs.param[1] = lp->loopid << 8;
 2071: 		mbs.param[2] = 0;
 2072: 		mbs.param[3] = 0;
 2073: 		isp_mboxcmd(isp, &mbs, MBLOGNONE);
 2074: 		if (fcp->isp_fwstate != FW_READY ||
 2075: 		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {
 2076: 			return (-1);
 2077: 		}
 2078: 	}
 2079: 	/*
 2080: 	 * If we get here, we've for sure seen not only a valid loop
 2081: 	 * but know what is or isn't on it, so mark this for usage
 2082: 	 * in isp_start.
 2083: 	 */
 2084: 	fcp->loop_seen_once = 1;
 2085: 	fcp->isp_loopstate = LOOP_READY;
 2086: 	return (0);
 2087: }
 2088: 
 2089: static int
 2090: isp_scan_loop(struct ispsoftc *isp)
 2091: {
 2092: 	struct lportdb *lp;
 2093: 	fcparam *fcp = isp->isp_param;
 2094: 	isp_pdb_t pdb;
 2095: 	int loopid, lim, hival;
 2096: 
 2097: 	switch (fcp->isp_topo) {
 2098: 	case TOPO_NL_PORT:
 2099: 		hival = FL_PORT_ID;
 2100: 		break;
 2101: 	case TOPO_N_PORT:
 2102: 		hival = 2;
 2103: 		break;
 2104: 	case TOPO_FL_PORT:
 2105: 		hival = FC_PORT_ID;
 2106: 		break;
 2107: 	default:
 2108: 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
 2109: 		return (0);
 2110: 	}
 2111: 	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
 2112: 
 2113: 	/*
 2114: 	 * make sure the temp port database is clean...
 2115: 	 */
 2116: 	MEMZERO((void *)fcp->tport, sizeof (fcp->tport));
 2117: 
 2118: 	/*
 2119: 	 * Run through the local loop ports and get port database info
 2120: 	 * for each loop ID.
 2121: 	 *
 2122: 	 * There's a somewhat unexplained situation where the f/w passes back
 2123: 	 * the wrong database entity- if that happens, just restart (up to
 2124: 	 * FL_PORT_ID times).
 2125: 	 */
 2126: 	for (lim = loopid = 0; loopid < hival; loopid++) {
 2127: 		lp = &fcp->tport[loopid];
 2128: 
 2129: 		/*
 2130: 		 * Don't even try for ourselves...
 2131: 	 	 */
 2132: 		if (loopid == fcp->isp_loopid)
 2133: 			continue;
 2134: 
 2135: 		lp->node_wwn = isp_get_portname(isp, loopid, 1);
 2136: 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
 2137: 			return (-1);
 2138: 		if (lp->node_wwn == 0)
 2139: 			continue;
 2140: 		lp->port_wwn = isp_get_portname(isp, loopid, 0);
 2141: 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
 2142: 			return (-1);
 2143: 		if (lp->port_wwn == 0) {
 2144: 			lp->node_wwn = 0;
 2145: 			continue;
 2146: 		}
 2147: 
 2148: 		/*
 2149: 		 * Get an entry....
 2150: 		 */
 2151: 		if (isp_getpdb(isp, loopid, &pdb) != 0) {
 2152: 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
 2153: 				return (-1);
 2154: 			continue;
 2155: 		}
 2156: 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
 2157: 			return (-1);
 2158: 		}
 2159: 
 2160: 		/*
 2161: 		 * If the returned database element doesn't match what we
 2162: 		 * asked for, restart the process entirely (up to a point...).
 2163: 		 */
 2164: 		if (pdb.pdb_loopid != loopid) {
 2165: 			loopid = 0;
 2166: 			if (lim++ < hival) {
 2167: 				continue;
 2168: 			}
 2169: 			isp_prt(isp, ISP_LOGWARN,
 2170: 			    "giving up on synchronizing the port database");
 2171: 			return (-1);
 2172: 		}
 2173: 
 2174: 		/*
 2175: 		 * Save the pertinent info locally.
 2176: 		 */
 2177: 		lp->node_wwn =
 2178: 		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
 2179: 		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
 2180: 		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
 2181: 		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
 2182: 		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
 2183: 		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
 2184: 		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
 2185: 		    (((u_int64_t)pdb.pdb_nodename[7]));
 2186: 		lp->port_wwn =
 2187: 		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
 2188: 		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
 2189: 		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
 2190: 		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
 2191: 		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
 2192: 		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
 2193: 		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
 2194: 		    (((u_int64_t)pdb.pdb_portname[7]));
 2195: 		lp->roles =
 2196: 		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 2197: 		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
 2198: 		lp->loopid = pdb.pdb_loopid;
 2199: 	}
 2200: 
 2201: 	/*
 2202: 	 * Mark all of the permanent local loop database entries as invalid
 2203: 	 * (except our own entry).
 2204: 	 */
 2205: 	for (loopid = 0; loopid < hival; loopid++) {
 2206: 		if (loopid == fcp->isp_iid) {
 2207: 			fcp->portdb[loopid].valid = 1;
 2208: 			fcp->portdb[loopid].loopid = fcp->isp_loopid;
 2209: 			continue;
 2210: 		}
 2211: 		fcp->portdb[loopid].valid = 0;
 2212: 	}
 2213: 
 2214: 	/*
 2215: 	 * Now merge our local copy of the port database into our saved copy.
 2216: 	 * Notify the outer layers of new devices arriving.
 2217: 	 */
 2218: 	for (loopid = 0; loopid < hival; loopid++) {
 2219: 		int i;
 2220: 
 2221: 		/*
 2222: 		 * If we don't have a non-zero Port WWN, we're not here.
 2223: 		 */
 2224: 		if (fcp->tport[loopid].port_wwn == 0) {
 2225: 			continue;
 2226: 		}
 2227: 
 2228: 		/*
 2229: 		 * Skip ourselves.
 2230: 		 */
 2231: 		if (loopid == fcp->isp_iid) {
 2232: 			continue;
 2233: 		}
 2234: 
 2235: 		/*
 2236: 		 * For the purposes of deciding whether this is the
 2237: 		 * 'same' device or not, we only search for an identical
 2238: 		 * Port WWN. Node WWNs may or may not be the same as
 2239: 		 * the Port WWN, and there may be multiple different
 2240: 		 * Port WWNs with the same Node WWN. It would be chaos
 2241: 		 * to have multiple identical Port WWNs, so we don't
 2242: 		 * allow that.
 2243: 		 */
 2244: 
 2245: 		for (i = 0; i < hival; i++) {
 2246: 			int j;
 2247: 			if (fcp->portdb[i].port_wwn == 0)
 2248: 				continue;
 2249: 			if (fcp->portdb[i].port_wwn !=
 2250: 			    fcp->tport[loopid].port_wwn)
 2251: 				continue;
 2252: 			/*
 2253: 			 * We found this WWN elsewhere- it's changed
 2254: 			 * loopids then. We don't change it's actual
 2255: 			 * position in our cached port database- we
 2256: 			 * just change the actual loop ID we'd use.
 2257: 			 */
 2258: 			if (fcp->portdb[i].loopid != loopid) {
 2259: 				isp_prt(isp, ISP_LOGINFO, portshift, i,
 2260: 				    fcp->portdb[i].loopid,
 2261: 				    fcp->portdb[i].portid, loopid,
 2262: 				    fcp->tport[loopid].portid);
 2263: 			}
 2264: 			fcp->portdb[i].portid = fcp->tport[loopid].portid;
 2265: 			fcp->portdb[i].loopid = loopid;
 2266: 			fcp->portdb[i].valid = 1;
 2267: 			fcp->portdb[i].roles = fcp->tport[loopid].roles;
 2268: 
 2269: 			/*
 2270: 			 * Now make sure this Port WWN doesn't exist elsewhere
 2271: 			 * in the port database.
 2272: 			 */
 2273: 			for (j = i+1; j < hival; j++) {
 2274: 				if (fcp->portdb[i].port_wwn !=
 2275: 				    fcp->portdb[j].port_wwn) {
 2276: 					continue;
 2277: 				}
 2278: 				isp_prt(isp, ISP_LOGWARN, portdup, j, i);
 2279: 				/*
 2280: 				 * Invalidate the 'old' *and* 'new' ones.
 2281: 				 * This is really harsh and not quite right,
 2282: 				 * but if this happens, we really don't know
 2283: 				 * who is what at this point.
 2284: 				 */
 2285: 				fcp->portdb[i].valid = 0;
 2286: 				fcp->portdb[j].valid = 0;
 2287: 			}
 2288: 			break;
 2289: 		}
 2290: 
 2291: 		/*
 2292: 		 * If we didn't traverse the entire port database,
 2293: 		 * then we found (and remapped) an existing entry.
 2294: 		 * No need to notify anyone- go for the next one.
 2295: 		 */
 2296: 		if (i < hival) {
 2297: 			isp_prt(isp, ISP_LOGINFO, retained,
 2298: 			    fcp->portdb[i].loopid, i, fcp->portdb[i].portid);
 2299: 			continue;
 2300: 		}
 2301: 
 2302: 		/*
 2303: 		 * We've not found this Port WWN anywhere. It's a new entry.
 2304: 		 * See if we can leave it where it is (with target == loopid).
 2305: 		 */
 2306: 		if (fcp->portdb[loopid].port_wwn != 0) {
 2307: 			for (lim = 0; lim < hival; lim++) {
 2308: 				if (fcp->portdb[lim].port_wwn == 0)
 2309: 					break;
 2310: 			}
 2311: 			/* "Cannot Happen" */
 2312: 			if (lim == hival) {
 2313: 				isp_prt(isp, ISP_LOGWARN, "Remap Overflow");
 2314: 				continue;
 2315: 			}
 2316: 			i = lim;
 2317: 		} else {
 2318: 			i = loopid;
 2319: 		}
 2320: 
 2321: 		/*
 2322: 		 * NB:	The actual loopid we use here is loopid- we may
 2323: 		 *	in fact be at a completely different index (target).
 2324: 		 */
 2325: 		fcp->portdb[i].loopid = loopid;
 2326: 		fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;
 2327: 		fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;
 2328: 		fcp->portdb[i].roles = fcp->tport[loopid].roles;
 2329: 		fcp->portdb[i].portid = fcp->tport[loopid].portid;
 2330: 		fcp->portdb[i].valid = 1;
 2331: 
 2332: 		/*
 2333: 		 * Tell the outside world we've arrived.
 2334: 		 */
 2335: 		(void) isp_async(isp, ISPASYNC_PROMENADE, &i);
 2336: 	}
 2337: 
 2338: 	/*
 2339: 	 * Now find all previously used targets that are now invalid and
 2340: 	 * notify the outer layers that they're gone.
 2341: 	 */
 2342: 	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {
 2343: 		if (lp->valid || lp->port_wwn == 0) {
 2344: 			continue;
 2345: 		}
 2346: 
 2347: 		/*
 2348: 		 * Tell the outside world we've gone
 2349: 		 * away and erase our pdb entry.
 2350: 		 *
 2351: 		 */
 2352: 		loopid = lp - fcp->portdb;
 2353: 		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);
 2354: 		MEMZERO((void *) lp, sizeof (*lp));
 2355: 	}
 2356: 	fcp->isp_loopstate = LOOP_LSCAN_DONE;
 2357: 	return (0);
 2358: }
 2359: 
 2360: 
 2361: static int
 2362: isp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp)
 2363: {
 2364: 	isp_mboxcmd(isp, mbp, MBLOGNONE);
 2365: 	if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {
 2366: 		if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {
 2367: 			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
 2368: 		}
 2369: 		if (mbp->param[0] == MBOX_COMMAND_ERROR) {
 2370: 			char tbuf[16];
 2371: 			char *m;
 2372: 			switch (mbp->param[1]) {
 2373: 			case 1:
 2374: 				m = "No Loop";
 2375: 				break;
 2376: 			case 2:
 2377: 				m = "Failed to allocate IOCB buffer";
 2378: 				break;
 2379: 			case 3:
 2380: 				m = "Failed to allocate XCB buffer";
 2381: 				break;
 2382: 			case 4:
 2383: 				m = "timeout or transmit failed";
 2384: 				break;
 2385: 			case 5:
 2386: 				m = "no fabric loop";
 2387: 				break;
 2388: 			case 6:
 2389: 				m = "remote device not a target";
 2390: 				break;
 2391: 			default:
 2392: 				SNPRINTF(tbuf, sizeof tbuf, "%x",
 2393: 				    mbp->param[1]);
 2394: 				m = tbuf;
 2395: 				break;
 2396: 			}
 2397: 			isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);
 2398: 		}
 2399: 		return (-1);
 2400: 	}
 2401: 
 2402: 	if (FCPARAM(isp)->isp_fwstate != FW_READY ||
 2403: 	    FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {
 2404: 		return (-1);
 2405: 	}
 2406: 	return(0);
 2407: }
 2408: 
 2409: #ifdef	ISP_USE_GA_NXT
 2410: static int
 2411: isp_scan_fabric(struct ispsoftc *isp, int ftype)
 2412: {
 2413: 	fcparam *fcp = isp->isp_param;
 2414: 	u_int32_t portid, first_portid, last_portid;
 2415: 	int hicap, last_port_same;
 2416: 
 2417: 	if (fcp->isp_onfabric == 0) {
 2418: 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2419: 		return (0);
 2420: 	}
 2421: 
 2422: 	FC_SCRATCH_ACQUIRE(isp);
 2423: 
 2424: 	/*
 2425: 	 * Since Port IDs are 24 bits, we can check against having seen
 2426: 	 * anything yet with this value.
 2427: 	 */
 2428: 	last_port_same = 0;
 2429: 	last_portid = 0xffffffff;	/* not a port */
 2430: 	first_portid = portid = fcp->isp_portid;
 2431: 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
 2432: 
 2433: 	for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {
 2434: 		mbreg_t mbs;
 2435: 		sns_screq_t *rq;
 2436: 		sns_ga_nxt_rsp_t *rs0, *rs1;
 2437: 		struct lportdb lcl;
 2438: 		u_int8_t sc[SNS_GA_NXT_RESP_SIZE];
 2439: 
 2440: 		rq = (sns_screq_t *)sc;
 2441: 		MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);
 2442: 		rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;
 2443: 		rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);
 2444: 		rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);
 2445: 		rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);
 2446: 		rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);
 2447: 		rq->snscb_sblen = 6;
 2448: 		rq->snscb_data[0] = SNS_GA_NXT;
 2449: 		rq->snscb_data[4] = portid & 0xffff;
 2450: 		rq->snscb_data[5] = (portid >> 16) & 0xff;
 2451: 		isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);
 2452: 		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);
 2453: 		mbs.param[0] = MBOX_SEND_SNS;
 2454: 		mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;
 2455: 		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2456: 		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2457: 		/*
 2458: 		 * Leave 4 and 5 alone
 2459: 		 */
 2460: 		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2461: 		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2462: 		if (isp_fabric_mbox_cmd(isp, &mbs)) {
 2463: 			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
 2464: 				fcp->isp_loopstate = LOOP_PDB_RCVD;
 2465: 			}
 2466: 			FC_SCRATCH_RELEASE(isp);
 2467: 			return (-1);
 2468: 		}
 2469: 		MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);
 2470: 		rs1 = (sns_ga_nxt_rsp_t *) sc;
 2471: 		rs0 = (sns_ga_nxt_rsp_t *) ((u_int8_t *)fcp->isp_scratch+0x100);
 2472: 		isp_get_ga_nxt_response(isp, rs0, rs1);
 2473: 		if (rs1->snscb_cthdr.ct_response != FS_ACC) {
 2474: 			int level;
 2475: 			if (rs1->snscb_cthdr.ct_reason == 9 &&
 2476: 			    rs1->snscb_cthdr.ct_explanation == 7)
 2477: 				level = ISP_LOGDEBUG0;
 2478: 			else
 2479: 				level = ISP_LOGWARN;
 2480: 			isp_prt(isp, level, swrej, "GA_NXT",
 2481: 			    rs1->snscb_cthdr.ct_reason,
 2482: 			    rs1->snscb_cthdr.ct_explanation, portid);
 2483: 			FC_SCRATCH_RELEASE(isp);
 2484: 			fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2485: 			return (0);
 2486: 		}
 2487: 		portid =
 2488: 		    (((u_int32_t) rs1->snscb_port_id[0]) << 16) |
 2489: 		    (((u_int32_t) rs1->snscb_port_id[1]) << 8) |
 2490: 		    (((u_int32_t) rs1->snscb_port_id[2]));
 2491: 
 2492: 		/*
 2493: 		 * XXX: We should check to make sure that this entry
 2494: 		 * XXX: supports the type(s) we are interested in.
 2495: 		 */
 2496: 		/*
 2497: 		 * Okay, we now have information about a fabric object.
 2498: 		 * If it is the type we're interested in, tell the outer layers
 2499: 		 * about it. The outer layer needs to  know: Port ID, WWNN,
 2500: 		 * WWPN, FC4 type, and port type.
 2501: 		 *
 2502: 		 * The lportdb structure is adequate for this.
 2503: 		 */
 2504: 		MEMZERO(&lcl, sizeof (lcl));
 2505: 		lcl.port_type = rs1->snscb_port_type;
 2506: 		lcl.fc4_type = ftype;
 2507: 		lcl.portid = portid;
 2508: 		lcl.node_wwn =
 2509: 		    (((u_int64_t)rs1->snscb_nodename[0]) << 56) |
 2510: 		    (((u_int64_t)rs1->snscb_nodename[1]) << 48) |
 2511: 		    (((u_int64_t)rs1->snscb_nodename[2]) << 40) |
 2512: 		    (((u_int64_t)rs1->snscb_nodename[3]) << 32) |
 2513: 		    (((u_int64_t)rs1->snscb_nodename[4]) << 24) |
 2514: 		    (((u_int64_t)rs1->snscb_nodename[5]) << 16) |
 2515: 		    (((u_int64_t)rs1->snscb_nodename[6]) <<  8) |
 2516: 		    (((u_int64_t)rs1->snscb_nodename[7]));
 2517: 		lcl.port_wwn =
 2518: 		    (((u_int64_t)rs1->snscb_portname[0]) << 56) |
 2519: 		    (((u_int64_t)rs1->snscb_portname[1]) << 48) |
 2520: 		    (((u_int64_t)rs1->snscb_portname[2]) << 40) |
 2521: 		    (((u_int64_t)rs1->snscb_portname[3]) << 32) |
 2522: 		    (((u_int64_t)rs1->snscb_portname[4]) << 24) |
 2523: 		    (((u_int64_t)rs1->snscb_portname[5]) << 16) |
 2524: 		    (((u_int64_t)rs1->snscb_portname[6]) <<  8) |
 2525: 		    (((u_int64_t)rs1->snscb_portname[7]));
 2526: 
 2527: 		/*
 2528: 		 * Does this fabric object support the type we want?
 2529: 		 * If not, skip it.
 2530: 		 */
 2531: 		if (rs1->snscb_fc4_types[ftype >> 5] & (1 << (ftype & 0x1f))) {
 2532: 			if (first_portid == portid) {
 2533: 				lcl.last_fabric_dev = 1;
 2534: 			} else {
 2535: 				lcl.last_fabric_dev = 0;
 2536: 			}
 2537: 			(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
 2538: 		} else {
 2539: 			isp_prt(isp, ISP_LOGDEBUG0,
 2540: 			    "PortID 0x%x doesn't support FC4 type 0x%x",
 2541: 			    portid, ftype);
 2542: 		}
 2543: 		if (first_portid == portid) {
 2544: 			fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2545: 			FC_SCRATCH_RELEASE(isp);
 2546: 			return (0);
 2547: 		}
 2548: 		if (portid == last_portid) {
 2549: 			if (last_port_same++ > 20) {
 2550: 				isp_prt(isp, ISP_LOGWARN,
 2551: 				    "tangled fabric database detected");
 2552: 				break;
 2553: 			}
 2554: 		} else {
 2555: 			last_port_same = 0 ;
 2556: 			last_portid = portid;
 2557: 		}
 2558: 	}
 2559: 	FC_SCRATCH_RELEASE(isp);
 2560: 	if (hicap >= GA_NXT_MAX) {
 2561: 		isp_prt(isp, ISP_LOGWARN, "fabric too big (> %d)", GA_NXT_MAX);
 2562: 	}
 2563: 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2564: 	return (0);
 2565: }
 2566: #else
 2567: #define	GIDLEN	((ISP2100_SCRLEN >> 1) + 16)
 2568: #define	NGENT	((GIDLEN - 16) >> 2)
 2569: 
 2570: #define	IGPOFF	(ISP2100_SCRLEN - GIDLEN)
 2571: #define	GXOFF	(256)
 2572: 
 2573: static int
 2574: isp_scan_fabric(struct ispsoftc *isp, int ftype)
 2575: {
 2576: 	fcparam *fcp = FCPARAM(isp);
 2577: 	mbreg_t mbs;
 2578: 	int i;
 2579: 	sns_gid_ft_req_t *rq;
 2580: 	sns_gid_ft_rsp_t *rs0, *rs1;
 2581: 
 2582: 	if (fcp->isp_onfabric == 0) {
 2583: 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2584: 		return (0);
 2585: 	}
 2586: 
 2587: 	FC_SCRATCH_ACQUIRE(isp);
 2588: 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
 2589: 
 2590: 	rq = (sns_gid_ft_req_t *)fcp->tport;
 2591: 	MEMZERO((void *) rq, SNS_GID_FT_REQ_SIZE);
 2592: 	rq->snscb_rblen = GIDLEN >> 1;
 2593: 	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+IGPOFF);
 2594: 	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+IGPOFF);
 2595: 	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+IGPOFF);
 2596: 	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+IGPOFF);
 2597: 	rq->snscb_sblen = 6;
 2598: 	rq->snscb_cmd = SNS_GID_FT;
 2599: 	rq->snscb_mword_div_2 = NGENT;
 2600: 	rq->snscb_fc4_type = ftype;
 2601: 	isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *) fcp->isp_scratch);
 2602: 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
 2603: 	mbs.param[0] = MBOX_SEND_SNS;
 2604: 	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
 2605: 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2606: 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2607: 
 2608: 	/*
 2609: 	 * Leave 4 and 5 alone
 2610: 	 */
 2611: 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2612: 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2613: 	if (isp_fabric_mbox_cmd(isp, &mbs)) {
 2614: 		if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
 2615: 			fcp->isp_loopstate = LOOP_PDB_RCVD;
 2616: 		}
 2617: 		FC_SCRATCH_RELEASE(isp);
 2618: 		return (-1);
 2619: 	}
 2620: 	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2621: 		FC_SCRATCH_RELEASE(isp);
 2622: 		return (-1);
 2623: 	}
 2624: 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
 2625: 	rs1 = (sns_gid_ft_rsp_t *) fcp->tport;
 2626: 	rs0 = (sns_gid_ft_rsp_t *) ((u_int8_t *)fcp->isp_scratch+IGPOFF);
 2627: 	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
 2628: 	if (rs1->snscb_cthdr.ct_response != FS_ACC) {
 2629: 		int level;
 2630: 		if (rs1->snscb_cthdr.ct_reason == 9 &&
 2631: 		    rs1->snscb_cthdr.ct_explanation == 7)
 2632: 			level = ISP_LOGDEBUG0;
 2633: 		else
 2634: 			level = ISP_LOGWARN;
 2635: 		isp_prt(isp, level, swrej, "GID_FT",
 2636: 		    rs1->snscb_cthdr.ct_reason,
 2637: 		    rs1->snscb_cthdr.ct_explanation, 0);
 2638: 		FC_SCRATCH_RELEASE(isp);
 2639: 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2640: 		return (0);
 2641: 	}
 2642: 
 2643: 	/*
 2644: 	 * Okay, we now have a list of Port IDs for this class of device.
 2645: 	 * Go through the list and for each one get the WWPN/WWNN for it
 2646: 	 * and tell the outer layers about it. The outer layer needs to
 2647: 	 * know: Port ID, WWNN, WWPN, FC4 type, and (possibly) port type.
 2648: 	 *
 2649: 	 * The lportdb structure is adequate for this.
 2650: 	 */
 2651: 	i = -1;
 2652: 	do {
 2653: 		sns_gxn_id_req_t grqbuf, *gq = &grqbuf;
 2654: 		sns_gxn_id_rsp_t *gs0, grsbuf, *gs1 = &grsbuf;
 2655: 		struct lportdb lcl;
 2656: #if	0
 2657: 		sns_gff_id_rsp_t *fs0, ffsbuf, *fs1 = &ffsbuf;
 2658: #endif
 2659: 
 2660: 		i++;
 2661: 		MEMZERO(&lcl, sizeof (lcl));
 2662: 		lcl.fc4_type = ftype;
 2663: 		lcl.portid =
 2664: 		    (((u_int32_t) rs1->snscb_ports[i].portid[0]) << 16) |
 2665: 		    (((u_int32_t) rs1->snscb_ports[i].portid[1]) << 8) |
 2666: 		    (((u_int32_t) rs1->snscb_ports[i].portid[2]));
 2667: 
 2668: 		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
 2669: 		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
 2670: 		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
 2671: 		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
 2672: 		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
 2673: 		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
 2674: 		gq->snscb_sblen = 6;
 2675: 		gq->snscb_cmd = SNS_GPN_ID;
 2676: 		gq->snscb_portid = lcl.portid;
 2677: 		isp_put_gxn_id_request(isp, gq,
 2678: 		    (sns_gxn_id_req_t *) fcp->isp_scratch);
 2679: 		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
 2680: 		mbs.param[0] = MBOX_SEND_SNS;
 2681: 		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
 2682: 		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2683: 		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2684: 		/*
 2685: 		 * Leave 4 and 5 alone
 2686: 		 */
 2687: 		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2688: 		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2689: 		if (isp_fabric_mbox_cmd(isp, &mbs)) {
 2690: 			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
 2691: 				fcp->isp_loopstate = LOOP_PDB_RCVD;
 2692: 			}
 2693: 			FC_SCRATCH_RELEASE(isp);
 2694: 			return (-1);
 2695: 		}
 2696: 		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2697: 			FC_SCRATCH_RELEASE(isp);
 2698: 			return (-1);
 2699: 		}
 2700: 		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
 2701: 		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
 2702: 		isp_get_gxn_id_response(isp, gs0, gs1);
 2703: 		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
 2704: 			isp_prt(isp, ISP_LOGWARN, swrej, "GPN_ID",
 2705: 			    gs1->snscb_cthdr.ct_reason,
 2706: 			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
 2707: 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2708: 				FC_SCRATCH_RELEASE(isp);
 2709: 				return (-1);
 2710: 			}
 2711: 			continue;
 2712: 		}
 2713: 		lcl.port_wwn = 
 2714: 		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
 2715: 		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
 2716: 		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
 2717: 		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
 2718: 		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
 2719: 		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
 2720: 		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
 2721: 		    (((u_int64_t)gs1->snscb_wwn[7]));
 2722: 
 2723: 		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
 2724: 		gq->snscb_rblen = SNS_GXN_ID_RESP_SIZE >> 1;
 2725: 		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
 2726: 		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
 2727: 		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
 2728: 		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
 2729: 		gq->snscb_sblen = 6;
 2730: 		gq->snscb_cmd = SNS_GNN_ID;
 2731: 		gq->snscb_portid = lcl.portid;
 2732: 		isp_put_gxn_id_request(isp, gq,
 2733: 		    (sns_gxn_id_req_t *) fcp->isp_scratch);
 2734: 		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
 2735: 		mbs.param[0] = MBOX_SEND_SNS;
 2736: 		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
 2737: 		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2738: 		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2739: 		/*
 2740: 		 * Leave 4 and 5 alone
 2741: 		 */
 2742: 		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2743: 		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2744: 		if (isp_fabric_mbox_cmd(isp, &mbs)) {
 2745: 			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
 2746: 				fcp->isp_loopstate = LOOP_PDB_RCVD;
 2747: 			}
 2748: 			FC_SCRATCH_RELEASE(isp);
 2749: 			return (-1);
 2750: 		}
 2751: 		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2752: 			FC_SCRATCH_RELEASE(isp);
 2753: 			return (-1);
 2754: 		}
 2755: 		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GXN_ID_RESP_SIZE);
 2756: 		gs0 = (sns_gxn_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
 2757: 		isp_get_gxn_id_response(isp, gs0, gs1);
 2758: 		if (gs1->snscb_cthdr.ct_response != FS_ACC) {
 2759: 			isp_prt(isp, ISP_LOGWARN, swrej, "GNN_ID",
 2760: 			    gs1->snscb_cthdr.ct_reason,
 2761: 			    gs1->snscb_cthdr.ct_explanation, lcl.portid);
 2762: 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2763: 				FC_SCRATCH_RELEASE(isp);
 2764: 				return (-1);
 2765: 			}
 2766: 			continue;
 2767: 		}
 2768: 		lcl.node_wwn = 
 2769: 		    (((u_int64_t)gs1->snscb_wwn[0]) << 56) |
 2770: 		    (((u_int64_t)gs1->snscb_wwn[1]) << 48) |
 2771: 		    (((u_int64_t)gs1->snscb_wwn[2]) << 40) |
 2772: 		    (((u_int64_t)gs1->snscb_wwn[3]) << 32) |
 2773: 		    (((u_int64_t)gs1->snscb_wwn[4]) << 24) |
 2774: 		    (((u_int64_t)gs1->snscb_wwn[5]) << 16) |
 2775: 		    (((u_int64_t)gs1->snscb_wwn[6]) <<  8) |
 2776: 		    (((u_int64_t)gs1->snscb_wwn[7]));
 2777: 
 2778: 		/*
 2779: 		 * The QLogic f/w is bouncing this with a parameter error.
 2780: 		 */
 2781: #if	0
 2782: 		/*
 2783: 		 * Try and get FC4 Features (FC-GS-3 only).
 2784: 		 * We can use the sns_gxn_id_req_t for this request.
 2785: 		 */
 2786: 		MEMZERO((void *) gq, sizeof (sns_gxn_id_req_t));
 2787: 		gq->snscb_rblen = SNS_GFF_ID_RESP_SIZE >> 1;
 2788: 		gq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+GXOFF);
 2789: 		gq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+GXOFF);
 2790: 		gq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+GXOFF);
 2791: 		gq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+GXOFF);
 2792: 		gq->snscb_sblen = 6;
 2793: 		gq->snscb_cmd = SNS_GFF_ID;
 2794: 		gq->snscb_portid = lcl.portid;
 2795: 		isp_put_gxn_id_request(isp, gq,
 2796: 		    (sns_gxn_id_req_t *) fcp->isp_scratch);
 2797: 		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GXN_ID_REQ_SIZE);
 2798: 		mbs.param[0] = MBOX_SEND_SNS;
 2799: 		mbs.param[1] = SNS_GXN_ID_REQ_SIZE >> 1;
 2800: 		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2801: 		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2802: 		/*
 2803: 		 * Leave 4 and 5 alone
 2804: 		 */
 2805: 		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2806: 		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2807: 		if (isp_fabric_mbox_cmd(isp, &mbs)) {
 2808: 			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {
 2809: 				fcp->isp_loopstate = LOOP_PDB_RCVD;
 2810: 			}
 2811: 			FC_SCRATCH_RELEASE(isp);
 2812: 			return (-1);
 2813: 		}
 2814: 		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2815: 			FC_SCRATCH_RELEASE(isp);
 2816: 			return (-1);
 2817: 		}
 2818: 		MEMORYBARRIER(isp, SYNC_SFORCPU, GXOFF, SNS_GFF_ID_RESP_SIZE);
 2819: 		fs0 = (sns_gff_id_rsp_t *) ((u_int8_t *)fcp->isp_scratch+GXOFF);
 2820: 		isp_get_gff_id_response(isp, fs0, fs1);
 2821: 		if (fs1->snscb_cthdr.ct_response != FS_ACC) {
 2822: 			isp_prt(isp, /* ISP_LOGDEBUG0 */ ISP_LOGWARN,
 2823: 			    swrej, "GFF_ID",
 2824: 			    fs1->snscb_cthdr.ct_reason,
 2825: 			    fs1->snscb_cthdr.ct_explanation, lcl.portid);
 2826: 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 2827: 				FC_SCRATCH_RELEASE(isp);
 2828: 				return (-1);
 2829: 			}
 2830: 		} else {
 2831: 			int index = (ftype >> 3);
 2832: 			int bshft = (ftype & 0x7) * 4;
 2833: 			int fc4_fval =
 2834: 			    (fs1->snscb_fc4_features[index] >> bshft) & 0xf;
 2835: 			if (fc4_fval & 0x1) {
 2836: 				lcl.roles |=
 2837: 				    (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT);
 2838: 			}
 2839: 			if (fc4_fval & 0x2) {
 2840: 				lcl.roles |=
 2841: 				    (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT);
 2842: 			}
 2843: 		}
 2844: #endif
 2845: 
 2846: 		/*
 2847: 		 * If we really want to know what kind of port type this is,
 2848: 		 * we have to run another CT command. Otherwise, we'll leave
 2849: 		 * it as undefined.
 2850: 		 *
 2851: 		lcl.port_type = 0;
 2852: 		 */
 2853: 		if (rs1->snscb_ports[i].control & 0x80) {
 2854: 			lcl.last_fabric_dev = 1;
 2855: 		} else {
 2856: 			lcl.last_fabric_dev = 0;
 2857: 		}
 2858: 		(void) isp_async(isp, ISPASYNC_FABRIC_DEV, &lcl);
 2859: 
 2860: 	} while ((rs1->snscb_ports[i].control & 0x80) == 0 && i < NGENT-1);
 2861: 
 2862: 	/*
 2863: 	 * If we're not at the last entry, our list isn't big enough.
 2864: 	 */
 2865: 	if ((rs1->snscb_ports[i].control & 0x80) == 0) {
 2866: 		isp_prt(isp, ISP_LOGWARN, "fabric too big for scratch area");
 2867: 	}
 2868: 
 2869: 	FC_SCRATCH_RELEASE(isp);
 2870: 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
 2871: 	return (0);
 2872: }
 2873: #endif
 2874: 
 2875: static void
 2876: isp_register_fc4_type(struct ispsoftc *isp)
 2877: {
 2878: 	fcparam *fcp = isp->isp_param;
 2879: 	u_int8_t local[SNS_RFT_ID_REQ_SIZE];
 2880: 	sns_screq_t *reqp = (sns_screq_t *) local;
 2881: 	mbreg_t mbs;
 2882: 
 2883: 	MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
 2884: 	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
 2885: 	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
 2886: 	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
 2887: 	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
 2888: 	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
 2889: 	reqp->snscb_sblen = 22;
 2890: 	reqp->snscb_data[0] = SNS_RFT_ID;
 2891: 	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
 2892: 	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
 2893: 	reqp->snscb_data[6] = (1 << FC4_SCSI);
 2894: #if	0
 2895: 	reqp->snscb_data[6] |= (1 << FC4_IP);	/* ISO/IEC 8802-2 LLC/SNAP */
 2896: #endif
 2897: 	FC_SCRATCH_ACQUIRE(isp);
 2898: 	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
 2899: 	mbs.param[0] = MBOX_SEND_SNS;
 2900: 	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
 2901: 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
 2902: 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
 2903: 	/*
 2904: 	 * Leave 4 and 5 alone
 2905: 	 */
 2906: 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
 2907: 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
 2908: 	isp_mboxcmd(isp, &mbs, MBLOGALL);
 2909: 	FC_SCRATCH_RELEASE(isp);
 2910: 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 2911: 		isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded");
 2912: 	}
 2913: }
 2914: 
 2915: /*
 2916:  * Start a command. Locking is assumed done in the caller.
 2917:  */
 2918: 
 2919: int
 2920: isp_start(XS_T *xs)
 2921: {
 2922: 	struct ispsoftc *isp;
 2923: 	u_int16_t nxti, optr, handle;
 2924: 	u_int8_t local[QENTRY_LEN];
 2925: 	ispreq_t *reqp, *qep;
 2926: 	int target, i;
 2927: 
 2928: 	XS_INITERR(xs);
 2929: 	isp = XS_ISP(xs);
 2930: 
 2931: 	/*
 2932: 	 * Check to make sure we're supporting initiator role.
 2933: 	 */
 2934: 	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
 2935: 		XS_SETERR(xs, HBA_SELTIMEOUT);
 2936: 		return (CMD_COMPLETE);
 2937: 	}
 2938: 
 2939: 	/*
 2940: 	 * Now make sure we're running.
 2941: 	 */
 2942: 
 2943: 	if (isp->isp_state != ISP_RUNSTATE) {
 2944: 		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
 2945: 		XS_SETERR(xs, HBA_BOTCH);
 2946: 		return (CMD_COMPLETE);
 2947: 	}
 2948: 
 2949: 	/*
 2950: 	 * Check command CDB length, etc.. We really are limited to 16 bytes
 2951: 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
 2952: 	 * but probably only if we're running fairly new firmware (we'll
 2953: 	 * let the old f/w choke on an extended command queue entry).
 2954: 	 */
 2955: 
 2956: 	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
 2957: 		isp_prt(isp, ISP_LOGERR,
 2958: 		    "unsupported cdb length (%d, CDB[0]=0x%x)",
 2959: 		    XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
 2960: 		XS_SETERR(xs, HBA_BOTCH);
 2961: 		return (CMD_COMPLETE);
 2962: 	}
 2963: 
 2964: 	/*
 2965: 	 * Check to see whether we have good firmware state still or
 2966: 	 * need to refresh our port database for this target.
 2967: 	 */
 2968: 	target = XS_TGT(xs);
 2969: 	if (IS_FC(isp)) {
 2970: 		fcparam *fcp = isp->isp_param;
 2971: 		struct lportdb *lp;
 2972: #ifdef	HANDLE_LOOPSTATE_IN_OUTER_LAYERS
 2973: 		if (fcp->isp_fwstate != FW_READY ||
 2974: 		    fcp->isp_loopstate != LOOP_READY) {
 2975: 			return (CMD_RQLATER);
 2976: 		}
 2977: 
 2978: 		/*
 2979: 		 * If we're not on a Fabric, we can't have a target
 2980: 		 * above FL_PORT_ID-1.
 2981: 		 *
 2982: 		 * If we're on a fabric and *not* connected as an F-port,
 2983: 		 * we can't have a target less than FC_SNS_ID+1. This
 2984: 		 * keeps us from having to sort out the difference between
 2985: 		 * local public loop devices and those which we might get
 2986: 		 * from a switch's database.
 2987: 		 */
 2988: 		if (fcp->isp_onfabric == 0) {
 2989: 			if (target >= FL_PORT_ID) {
 2990: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 2991: 				return (CMD_COMPLETE);
 2992: 			}
 2993: 		} else {
 2994: 			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
 2995: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 2996: 				return (CMD_COMPLETE);
 2997: 			}
 2998: 			/*
 2999: 			 * We used to exclude having local loop ports
 3000: 			 * at the same time that we have fabric ports.
 3001: 			 * That is, we used to exclude having ports
 3002: 			 * at < FL_PORT_ID if we're FL-port.
 3003: 			 *
 3004: 			 * That's wrong. The only thing that could be
 3005: 			 * dicey is if the switch you're connected to
 3006: 			 * has these local loop ports appear on the
 3007: 			 * fabric and we somehow attach them twice.
 3008: 			 */
 3009: 		}
 3010: #else
 3011: 		/*
 3012: 		 * Check for f/w being in ready state. If the f/w
 3013: 		 * isn't in ready state, then we don't know our
 3014: 		 * loop ID and the f/w hasn't completed logging
 3015: 		 * into all targets on the loop. If this is the
 3016: 		 * case, then bounce the command. We pretend this is
 3017: 		 * a SELECTION TIMEOUT error if we've never gone to
 3018: 		 * FW_READY state at all- in this case we may not
 3019: 		 * be hooked to a loop at all and we shouldn't hang
 3020: 		 * the machine for this. Otherwise, defer this command
 3021: 		 * until later.
 3022: 		 */
 3023: 		if (fcp->isp_fwstate != FW_READY) {
 3024: 			/*
 3025: 			 * Give ourselves at most a 250ms delay.
 3026: 			 */
 3027: 			if (isp_fclink_test(isp, 250000)) {
 3028: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 3029: 				if (fcp->loop_seen_once) {
 3030: 					return (CMD_RQLATER);
 3031: 				} else {
 3032: 					return (CMD_COMPLETE);
 3033: 				}
 3034: 			}
 3035: 		}
 3036: 
 3037: 		/*
 3038: 		 * If we're not on a Fabric, we can't have a target
 3039: 		 * above FL_PORT_ID-1.
 3040: 		 *
 3041: 		 * If we're on a fabric and *not* connected as an F-port,
 3042: 		 * we can't have a target less than FC_SNS_ID+1. This
 3043: 		 * keeps us from having to sort out the difference between
 3044: 		 * local public loop devices and those which we might get
 3045: 		 * from a switch's database.
 3046: 		 */
 3047: 		if (fcp->isp_onfabric == 0) {
 3048: 			if (target >= FL_PORT_ID) {
 3049: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 3050: 				return (CMD_COMPLETE);
 3051: 			}
 3052: 		} else {
 3053: 			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
 3054: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 3055: 				return (CMD_COMPLETE);
 3056: 			}
 3057: 			if (fcp->isp_topo != TOPO_F_PORT &&
 3058: 			    target < FL_PORT_ID) {
 3059: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 3060: 				return (CMD_COMPLETE);
 3061: 			}
 3062: 		}
 3063: 
 3064: 		/*
 3065: 		 * If our loop state is such that we haven't yet received
 3066: 		 * a "Port Database Changed" notification (after a LIP or
 3067: 		 * a Loop Reset or firmware initialization), then defer
 3068: 		 * sending commands for a little while, but only if we've
 3069: 		 * seen a valid loop at one point (otherwise we can get
 3070: 		 * stuck at initialization time).
 3071: 		 */
 3072: 		if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
 3073: 			XS_SETERR(xs, HBA_SELTIMEOUT);
 3074: 			if (fcp->loop_seen_once) {
 3075: 				return (CMD_RQLATER);
 3076: 			} else {
 3077: 				return (CMD_COMPLETE);
 3078: 			}
 3079: 		}
 3080: 
 3081: 		/*
 3082: 		 * If we're in the middle of loop or fabric scanning
 3083: 		 * or merging the port databases, retry this command later.
 3084: 		 */
 3085: 		if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC ||
 3086: 		    fcp->isp_loopstate == LOOP_SCANNING_LOOP ||
 3087: 		    fcp->isp_loopstate == LOOP_SYNCING_PDB) {
 3088: 			return (CMD_RQLATER);
 3089: 		}
 3090: 
 3091: 		/*
 3092: 		 * If our loop state is now such that we've just now
 3093: 		 * received a Port Database Change notification, then
 3094: 		 * we have to go off and (re)scan the fabric. We back
 3095: 		 * out and try again later if this doesn't work.
 3096: 		 */
 3097: 		if (fcp->isp_loopstate == LOOP_PDB_RCVD && fcp->isp_onfabric) {
 3098: 			if (isp_scan_fabric(isp, FC4_SCSI)) {
 3099: 				return (CMD_RQLATER);
 3100: 			}
 3101: 			if (fcp->isp_fwstate != FW_READY ||
 3102: 			    fcp->isp_loopstate < LOOP_FSCAN_DONE) {
 3103: 				return (CMD_RQLATER);
 3104: 			}
 3105: 		}
 3106: 
 3107: 		/*
 3108: 		 * If our loop state is now such that we've just now
 3109: 		 * received a Port Database Change notification, then
 3110: 		 * we have to go off and (re)synchronize our port
 3111: 		 * database.
 3112: 		 */
 3113: 		if (fcp->isp_loopstate < LOOP_READY) {
 3114: 			if (isp_pdb_sync(isp)) {
 3115: 				return (CMD_RQLATER);
 3116: 			}
 3117: 			if (fcp->isp_fwstate != FW_READY ||
 3118: 			    fcp->isp_loopstate != LOOP_READY) {
 3119: 				return (CMD_RQLATER);
 3120: 			}
 3121: 		}
 3122: 
 3123: 		/*
 3124: 		 * XXX: Here's were we would cancel any loop_dead flag
 3125: 		 * XXX: also cancel in dead_loop timeout that's running
 3126: 		 */
 3127: #endif
 3128: 
 3129: 		/*
 3130: 		 * Now check whether we should even think about pursuing this.
 3131: 		 */
 3132: 		lp = &fcp->portdb[target];
 3133: 		if (lp->valid == 0) {
 3134: 			XS_SETERR(xs, HBA_SELTIMEOUT);
 3135: 			return (CMD_COMPLETE);
 3136: 		}
 3137: 		if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
 3138: 			isp_prt(isp, ISP_LOGDEBUG2,
 3139: 			    "Target %d does not have target service", target);
 3140: 			XS_SETERR(xs, HBA_SELTIMEOUT);
 3141: 			return (CMD_COMPLETE);
 3142: 		}
 3143: 		/*
 3144: 		 * Now turn target into what the actual Loop ID is.
 3145: 		 */
 3146: 		target = lp->loopid;
 3147: 	}
 3148: 
 3149: 	/*
 3150: 	 * Next check to see if any HBA or Device
 3151: 	 * parameters need to be updated.
 3152: 	 */
 3153: 	if (isp->isp_update != 0) {
 3154: 		isp_update(isp);
 3155: 	}
 3156: 
 3157: 	if (isp_getrqentry(isp, &nxti, &optr, (void **)&qep)) {
 3158: 		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
 3159: 		XS_SETERR(xs, HBA_BOTCH);
 3160: 		return (CMD_EAGAIN);
 3161: 	}
 3162: 
 3163: 	/*
 3164: 	 * Now see if we need to synchronize the ISP with respect to anything.
 3165: 	 * We do dual duty here (cough) for synchronizing for busses other
 3166: 	 * than which we got here to send a command to.
 3167: 	 */
 3168: 	reqp = (ispreq_t *) local;
 3169: 	if (isp->isp_sendmarker) {
 3170: 		u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
 3171: 		/*
 3172: 		 * Check ports to send markers for...
 3173: 		 */
 3174: 		for (i = 0; i < n; i++) {
 3175: 			if ((isp->isp_sendmarker & (1 << i)) == 0) {
 3176: 				continue;
 3177: 			}
 3178: 			MEMZERO((void *) reqp, QENTRY_LEN);
 3179: 			reqp->req_header.rqs_entry_count = 1;
 3180: 			reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
 3181: 			reqp->req_modifier = SYNC_ALL;
 3182: 			reqp->req_target = i << 7;	/* insert bus number */
 3183: 			isp_put_request(isp, reqp, qep);
 3184: 			ISP_ADD_REQUEST(isp, nxti);
 3185: 			isp->isp_sendmarker &= ~(1 << i);
 3186: 			if (isp_getrqentry(isp, &nxti, &optr, (void **) &qep)) {
 3187: 				isp_prt(isp, ISP_LOGDEBUG0,
 3188: 				    "Request Queue Overflow+");
 3189: 				XS_SETERR(xs, HBA_BOTCH);
 3190: 				return (CMD_EAGAIN);
 3191: 			}
 3192: 		}
 3193: 	}
 3194: 
 3195: 	MEMZERO((void *)reqp, QENTRY_LEN);
 3196: 	reqp->req_header.rqs_entry_count = 1;
 3197: 	if (IS_FC(isp)) {
 3198: 		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
 3199: 	} else {
 3200: 		if (XS_CDBLEN(xs) > 12)
 3201: 			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
 3202: 		else
 3203: 			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
 3204: 	}
 3205: 	/* reqp->req_header.rqs_flags = 0; */
 3206: 	/* reqp->req_header.rqs_seqno = 0; */
 3207: 	if (IS_FC(isp)) {
 3208: 		/*
 3209: 		 * See comment in isp_intr
 3210: 		 */
 3211: 		/* XS_RESID(xs) = 0; */
 3212: 
 3213: 		/*
 3214: 		 * Fibre Channel always requires some kind of tag.
 3215: 		 * The Qlogic drivers seem be happy not to use a tag,
 3216: 		 * but this breaks for some devices (IBM drives).
 3217: 		 */
 3218: 		if (XS_TAG_P(xs)) {
 3219: 			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
 3220: 		} else {
 3221: 			/*
 3222: 			 * If we don't know what tag to use, use HEAD OF QUEUE
 3223: 			 * for Request Sense or Simple.
 3224: 			 */
 3225: 			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
 3226: 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
 3227: 			else
 3228: 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
 3229: 		}
 3230: 	} else {
 3231: 		sdparam *sdp = (sdparam *)isp->isp_param;
 3232: 		sdp += XS_CHANNEL(xs);
 3233: 		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
 3234: 		    XS_TAG_P(xs)) {
 3235: 			reqp->req_flags = XS_TAG_TYPE(xs);
 3236: 		}
 3237: 	}
 3238: 	reqp->req_target = target | (XS_CHANNEL(xs) << 7);
 3239: 	if (IS_SCSI(isp)) {
 3240: 		reqp->req_lun_trn = XS_LUN(xs);
 3241: 		reqp->req_cdblen = XS_CDBLEN(xs);
 3242: 	} else {
 3243: 		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)
 3244: 			((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
 3245: 		else
 3246: 			((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
 3247: 	}
 3248: 	MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
 3249: 
 3250: 	reqp->req_time = XS_TIME(xs) / 1000;
 3251: 	if (reqp->req_time == 0 && XS_TIME(xs)) {
 3252: 		reqp->req_time = 1;
 3253: 	}
 3254: 
 3255: 	if (isp_save_xs(isp, xs, &handle)) {
 3256: 		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
 3257: 		XS_SETERR(xs, HBA_BOTCH);
 3258: 		return (CMD_EAGAIN);
 3259: 	}
 3260: 	reqp->req_handle = handle;
 3261: 
 3262: 	/*
 3263: 	 * Set up DMA and/or do any bus swizzling of the request entry
 3264: 	 * so that the Qlogic F/W understands what is being asked of it.
 3265: 	 */
 3266: 	i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
 3267: 	if (i != CMD_QUEUED) {
 3268: 		isp_destroy_handle(isp, handle);
 3269: 		/*
 3270: 		 * dmasetup sets actual error in packet, and
 3271: 		 * return what we were given to return.
 3272: 		 */
 3273: 		return (i);
 3274: 	}
 3275: 	XS_SETERR(xs, HBA_NOERROR);
 3276: 	isp_prt(isp, ISP_LOGDEBUG2,
 3277: 	    "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
 3278: 	    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
 3279: 	    (long) XS_XFRLEN(xs));
 3280: 	ISP_ADD_REQUEST(isp, nxti);
 3281: 	isp->isp_nactive++;
 3282: 	return (CMD_QUEUED);
 3283: }
 3284: 
 3285: /*
 3286:  * isp control
 3287:  * Locks (ints blocked) assumed held.
 3288:  */
 3289: 
 3290: int
 3291: isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg)
 3292: {
 3293: 	XS_T *xs;
 3294: 	mbreg_t mbs;
 3295: 	int bus, tgt;
 3296: 	u_int16_t handle;
 3297: 
 3298: 	switch (ctl) {
 3299: 	default:
 3300: 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
 3301: 		break;
 3302: 
 3303: 	case ISPCTL_RESET_BUS:
 3304: 		/*
 3305: 		 * Issue a bus reset.
 3306: 		 */
 3307: 		mbs.param[0] = MBOX_BUS_RESET;
 3308: 		mbs.param[2] = 0;
 3309: 		if (IS_SCSI(isp)) {
 3310: 			mbs.param[1] =
 3311: 			    ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
 3312: 			if (mbs.param[1] < 2)
 3313: 				mbs.param[1] = 2;
 3314: 			bus = *((int *) arg);
 3315: 			if (IS_DUALBUS(isp))
 3316: 				mbs.param[2] = bus;
 3317: 		} else {
 3318: 			mbs.param[1] = 10;
 3319: 			bus = 0;
 3320: 		}
 3321: 		isp->isp_sendmarker |= (1 << bus);
 3322: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 3323: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3324: 			break;
 3325: 		}
 3326: 		isp_prt(isp, ISP_LOGINFO,
 3327: 		    "driver initiated bus reset of bus %d", bus);
 3328: 		return (0);
 3329: 
 3330: 	case ISPCTL_RESET_DEV:
 3331: 		tgt = (*((int *) arg)) & 0xffff;
 3332: 		bus = (*((int *) arg)) >> 16;
 3333: 		mbs.param[0] = MBOX_ABORT_TARGET;
 3334: 		mbs.param[1] = (tgt << 8) | (bus << 15);
 3335: 		mbs.param[2] = 3;	/* 'delay', in seconds */
 3336: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 3337: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3338: 			break;
 3339: 		}
 3340: 		isp_prt(isp, ISP_LOGINFO,
 3341: 		    "Target %d on Bus %d Reset Succeeded", tgt, bus);
 3342: 		isp->isp_sendmarker |= (1 << bus);
 3343: 		return (0);
 3344: 
 3345: 	case ISPCTL_ABORT_CMD:
 3346: 		xs = (XS_T *) arg;
 3347: 		tgt = XS_TGT(xs);
 3348: 		handle = isp_find_handle(isp, xs);
 3349: 		if (handle == 0) {
 3350: 			isp_prt(isp, ISP_LOGWARN,
 3351: 			    "cannot find handle for command to abort");
 3352: 			break;
 3353: 		}
 3354: 		bus = XS_CHANNEL(xs);
 3355: 		mbs.param[0] = MBOX_ABORT;
 3356: 		if (IS_FC(isp)) {
 3357: 			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN)  {
 3358: 				mbs.param[1] = tgt << 8;
 3359: 				mbs.param[4] = 0;
 3360: 				mbs.param[5] = 0;
 3361: 				mbs.param[6] = XS_LUN(xs);
 3362: 			} else {
 3363: 				mbs.param[1] = tgt << 8 | XS_LUN(xs);
 3364: 			}
 3365: 		} else {
 3366: 			mbs.param[1] =
 3367: 			    (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
 3368: 		}
 3369: 		mbs.param[3] = 0;
 3370: 		mbs.param[2] = handle;
 3371: 		isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_ERROR);
 3372: 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 3373: 			return (0);
 3374: 		}
 3375: 		/*
 3376: 		 * XXX: Look for command in the REQUEST QUEUE. That is,
 3377: 		 * XXX: It hasen't been picked up by firmware yet.
 3378: 		 */
 3379: 		break;
 3380: 
 3381: 	case ISPCTL_UPDATE_PARAMS:
 3382: 
 3383: 		isp_update(isp);
 3384: 		return (0);
 3385: 
 3386: 	case ISPCTL_FCLINK_TEST:
 3387: 
 3388: 		if (IS_FC(isp)) {
 3389: 			int usdelay = (arg)? *((int *) arg) : 250000;
 3390: 			return (isp_fclink_test(isp, usdelay));
 3391: 		}
 3392: 		break;
 3393: 
 3394: 	case ISPCTL_SCAN_FABRIC:
 3395: 
 3396: 		if (IS_FC(isp)) {
 3397: 			int ftype = (arg)? *((int *) arg) : FC4_SCSI;
 3398: 			return (isp_scan_fabric(isp, ftype));
 3399: 		}
 3400: 		break;
 3401: 
 3402: 	case ISPCTL_SCAN_LOOP:
 3403: 
 3404: 		if (IS_FC(isp)) {
 3405: 			return (isp_scan_loop(isp));
 3406: 		}
 3407: 		break;
 3408: 
 3409: 	case ISPCTL_PDB_SYNC:
 3410: 
 3411: 		if (IS_FC(isp)) {
 3412: 			return (isp_pdb_sync(isp));
 3413: 		}
 3414: 		break;
 3415: 
 3416: 	case ISPCTL_SEND_LIP:
 3417: 
 3418: 		if (IS_FC(isp)) {
 3419: 			mbs.param[0] = MBOX_INIT_LIP;
 3420: 			isp_mboxcmd(isp, &mbs, MBLOGALL);
 3421: 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 3422: 				return (0);
 3423: 			}
 3424: 		}
 3425: 		break;
 3426: 
 3427: 	case ISPCTL_GET_POSMAP:
 3428: 
 3429: 		if (IS_FC(isp) && arg) {
 3430: 			return (isp_getmap(isp, arg));
 3431: 		}
 3432: 		break;
 3433: 
 3434: 	case ISPCTL_RUN_MBOXCMD:
 3435: 
 3436: 		isp_mboxcmd(isp, arg, MBLOGALL);
 3437: 		return(0);
 3438: 
 3439: #ifdef	ISP_TARGET_MODE
 3440: 	case ISPCTL_TOGGLE_TMODE:
 3441: 	{
 3442: 
 3443: 		/*
 3444: 		 * We don't check/set against role here- that's the
 3445: 		 * responsibility for the outer layer to coordinate.
 3446: 		 */
 3447: 		if (IS_SCSI(isp)) {
 3448: 			int param = *(int *)arg;
 3449: 			mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
 3450: 			mbs.param[1] = param & 0xffff;
 3451: 			mbs.param[2] = param >> 16;
 3452: 			isp_mboxcmd(isp, &mbs, MBLOGALL);
 3453: 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 3454: 				break;
 3455: 			}
 3456: 		}
 3457: 		return (0);
 3458: 	}
 3459: #endif
 3460: 	}
 3461: 	return (-1);
 3462: }
 3463: 
 3464: /*
 3465:  * Interrupt Service Routine(s).
 3466:  *
 3467:  * External (OS) framework has done the appropriate locking,
 3468:  * and the locking will be held throughout this function.
 3469:  */
 3470: 
 3471: /*
 3472:  * Limit our stack depth by sticking with the max likely number
 3473:  * of completions on a request queue at any one time.
 3474:  */
 3475: #ifndef	MAX_REQUESTQ_COMPLETIONS
 3476: #define	MAX_REQUESTQ_COMPLETIONS	64
 3477: #endif
 3478: 
 3479: void
 3480: isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox)
 3481: {
 3482: 	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
 3483: 	u_int16_t iptr, optr, junk;
 3484: 	int i, nlooked = 0, ndone = 0;
 3485: 
 3486: again:
 3487: 	/*
 3488: 	 * Is this a mailbox related interrupt?
 3489: 	 * The mailbox semaphore will be nonzero if so.
 3490: 	 */
 3491: 	if (sema) {
 3492: 		if (mbox & 0x4000) {
 3493: 			isp->isp_intmboxc++;
 3494: 			if (isp->isp_mboxbsy) {
 3495: 				int i = 0, obits = isp->isp_obits;
 3496: 				isp->isp_mboxtmp[i++] = mbox;
 3497: 				for (i = 1; i < MAX_MAILBOX; i++) {
 3498: 					if ((obits & (1 << i)) == 0) {
 3499: 						continue;
 3500: 					}
 3501: 					isp->isp_mboxtmp[i] =
 3502: 					    ISP_READ(isp, MBOX_OFF(i));
 3503: 				}
 3504: 				if (isp->isp_mbxwrk0) {
 3505: 					if (isp_mbox_continue(isp) == 0) {
 3506: 						return;
 3507: 					}
 3508: 				}
 3509: 				MBOX_NOTIFY_COMPLETE(isp);
 3510: 			} else {
 3511: 				isp_prt(isp, ISP_LOGWARN,
 3512: 				    "Mbox Command Async (0x%x) with no waiters",
 3513: 				    mbox);
 3514: 			}
 3515: 		} else if (isp_parse_async(isp, mbox) < 0) {
 3516: 			return;
 3517: 		}
 3518: 		if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
 3519: 		    isp->isp_state != ISP_RUNSTATE) {
 3520: 			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 3521: 			ISP_WRITE(isp, BIU_SEMA, 0);
 3522: 			return;
 3523: 		}
 3524: 	}
 3525: 
 3526: 	/*
 3527: 	 * We can't be getting this now.
 3528: 	 */
 3529: 	if (isp->isp_state != ISP_RUNSTATE) {
 3530: 		isp_prt(isp, ISP_LOGWARN,
 3531: 		    "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
 3532: 		/*
 3533: 		 * Thank you very much!  *Burrrp*!
 3534: 		 */
 3535: 		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp,
 3536: 		    READ_RESPONSE_QUEUE_IN_POINTER(isp));
 3537: 
 3538: 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 3539: 		ISP_WRITE(isp, BIU_SEMA, 0);
 3540: 		return;
 3541: 	}
 3542: 
 3543: 	/*
 3544: 	 * Get the current Response Queue Out Pointer.
 3545: 	 *
 3546: 	 * If we're a 2300, we can ask what hardware what it thinks.
 3547: 	 */
 3548: 	if (IS_23XX(isp)) {
 3549: 		optr = ISP_READ(isp, isp->isp_respoutrp);
 3550: 		/*
 3551: 		 * Debug: to be taken out eventually
 3552: 		 */
 3553: 		if (isp->isp_residx != optr) {
 3554: 			isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x",
 3555: 			    optr, isp->isp_residx);
 3556: 		}
 3557: 	} else {
 3558: 		optr = isp->isp_residx;
 3559: 	}
 3560: 
 3561: 	/*
 3562: 	 * You *must* read the Response Queue In Pointer
 3563: 	 * prior to clearing the RISC interrupt.
 3564: 	 *
 3565: 	 * Debounce the 2300 if revision less than 2.
 3566: 	 */
 3567: 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
 3568: 		i = 0;
 3569: 		do {
 3570: 			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
 3571: 			junk = READ_RESPONSE_QUEUE_IN_POINTER(isp);
 3572: 		} while (junk != iptr && ++i < 1000);
 3573: 
 3574: 		if (iptr != junk) {
 3575: 			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 3576: 			isp_prt(isp, ISP_LOGWARN,
 3577: 			    "Response Queue Out Pointer Unstable (%x, %x)",
 3578: 			    iptr, junk);
 3579: 			return;
 3580: 		}
 3581: 	} else {
 3582: 		iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
 3583: 	}
 3584: 	isp->isp_resodx = iptr;
 3585: 
 3586: 
 3587: 	if (optr == iptr && sema == 0) {
 3588: 		/*
 3589: 		 * There are a lot of these- reasons unknown- mostly on
 3590: 		 * faster Alpha machines.
 3591: 		 *
 3592: 		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
 3593: 		 * make sure the old interrupt went away (to avoid 'ringing'
 3594: 		 * effects), but that didn't stop this from occurring.
 3595: 		 */
 3596: 		if (IS_23XX(isp)) {
 3597: 			USEC_DELAY(100);
 3598: 			iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp);
 3599: 			junk = ISP_READ(isp, BIU_R2HSTSLO);
 3600: 		} else {
 3601: 			junk = ISP_READ(isp, BIU_ISR);
 3602: 		}
 3603: 		if (optr == iptr) {
 3604: 			if (IS_23XX(isp)) {
 3605: 				;
 3606: 			} else {
 3607: 				sema = ISP_READ(isp, BIU_SEMA);
 3608: 				mbox = ISP_READ(isp, OUTMAILBOX0);
 3609: 				if ((sema & 0x3) && (mbox & 0x8000)) {
 3610: 					goto again;
 3611: 				}
 3612: 			}
 3613: 			isp->isp_intbogus++;
 3614: 			isp_prt(isp, ISP_LOGDEBUG1,
 3615: 			    "bogus intr- isr %x (%x) iptr %x optr %x",
 3616: 			    isr, junk, iptr, optr);
 3617: 		}
 3618: 	}
 3619: 	isp->isp_resodx = iptr;
 3620: 	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 3621: 	ISP_WRITE(isp, BIU_SEMA, 0);
 3622: 
 3623: 	if (isp->isp_rspbsy) {
 3624: 		return;
 3625: 	}
 3626: 	isp->isp_rspbsy = 1;
 3627: 
 3628: 	while (optr != iptr) {
 3629: 		ispstatusreq_t local, *sp = &local;
 3630: 		isphdr_t *hp;
 3631: 		int type;
 3632: 		u_int16_t oop;
 3633: 		int buddaboom = 0;
 3634: 
 3635: 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
 3636: 		oop = optr;
 3637: 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
 3638: 		nlooked++;
 3639: 		/*
 3640: 		 * Synchronize our view of this response queue entry.
 3641: 		 */
 3642: 		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
 3643: 
 3644: 		type = isp_get_response_type(isp, hp);
 3645: 
 3646: 		if (type == RQSTYPE_RESPONSE) {
 3647: 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
 3648: 		} else if (type == RQSTYPE_RIO2) {
 3649: 			isp_rio2_t rio;
 3650: 			isp_get_rio2(isp, (isp_rio2_t *) hp, &rio);
 3651: 			for (i = 0; i < rio.req_header.rqs_seqno; i++) {
 3652: 				isp_fastpost_complete(isp, rio.req_handles[i]);
 3653: 			}
 3654: 			if (isp->isp_fpcchiwater < rio.req_header.rqs_seqno)
 3655: 				isp->isp_fpcchiwater = rio.req_header.rqs_seqno;
 3656: 			MEMZERO(hp, QENTRY_LEN);	/* PERF */
 3657: 			continue;
 3658: 		} else {
 3659: 			/*
 3660: 			 * Somebody reachable via isp_handle_other_response
 3661: 			 * may have updated the response queue pointers for
 3662: 			 * us, so we reload our goal index.
 3663: 			 */
 3664: 			if (isp_handle_other_response(isp, type, hp, &optr)) {
 3665: 				iptr = isp->isp_resodx;
 3666: 				MEMZERO(hp, QENTRY_LEN);	/* PERF */
 3667: 				continue;
 3668: 			}
 3669: 
 3670: 			/*
 3671: 			 * After this point, we'll just look at the header as
 3672: 			 * we don't know how to deal with the rest of the
 3673: 			 * response.
 3674: 			 */
 3675: 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
 3676: 
 3677: 			/*
 3678: 			 * It really has to be a bounced request just copied
 3679: 			 * from the request queue to the response queue. If
 3680: 			 * not, something bad has happened.
 3681: 			 */
 3682: 			if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
 3683: 				isp_prt(isp, ISP_LOGERR, notresp,
 3684: 				    sp->req_header.rqs_entry_type, oop, optr,
 3685: 				    nlooked);
 3686: 				if (isp->isp_dblev & ISP_LOGDEBUG0) {
 3687: 					isp_print_bytes(isp, "Queue Entry",
 3688: 					    QENTRY_LEN, sp);
 3689: 				}
 3690: 				MEMZERO(hp, QENTRY_LEN);	/* PERF */
 3691: 				continue;
 3692: 			}
 3693: 			buddaboom = 1;
 3694: 		}
 3695: 
 3696: 		if (sp->req_header.rqs_flags & 0xf) {
 3697: #define	_RQS_OFLAGS	\
 3698: 	~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
 3699: 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
 3700: 				isp_prt(isp, ISP_LOGWARN,
 3701: 				    "continuation segment");
 3702: 				WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
 3703: 				continue;
 3704: 			}
 3705: 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
 3706: 				isp_prt(isp, ISP_LOGDEBUG1,
 3707: 				    "internal queues full");
 3708: 				/*
 3709: 				 * We'll synthesize a QUEUE FULL message below.
 3710: 				 */
 3711: 			}
 3712: 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
 3713: 				isp_prt(isp, ISP_LOGERR,  "bad header flag");
 3714: 				buddaboom++;
 3715: 			}
 3716: 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
 3717: 				isp_prt(isp, ISP_LOGERR, "bad request packet");
 3718: 				buddaboom++;
 3719: 			}
 3720: 			if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
 3721: 				isp_prt(isp, ISP_LOGERR,
 3722: 				    "unknown flags (0x%x) in response",
 3723: 				    sp->req_header.rqs_flags);
 3724: 				buddaboom++;
 3725: 			}
 3726: #undef	_RQS_OFLAGS
 3727: 		}
 3728: 		if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
 3729: 			MEMZERO(hp, QENTRY_LEN);	/* PERF */
 3730: 			isp_prt(isp, ISP_LOGERR,
 3731: 			    "bad request handle %d (type 0x%x, flags 0x%x)",
 3732: 			    sp->req_handle, sp->req_header.rqs_entry_type,
 3733: 			    sp->req_header.rqs_flags);
 3734: 			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
 3735: 			continue;
 3736: 		}
 3737: 		xs = isp_find_xs(isp, sp->req_handle);
 3738: 		if (xs == NULL) {
 3739: 			u_int8_t ts = sp->req_completion_status & 0xff;
 3740: 			MEMZERO(hp, QENTRY_LEN);	/* PERF */
 3741: 			/*
 3742: 			 * Only whine if this isn't the expected fallout of
 3743: 			 * aborting the command.
 3744: 			 */
 3745: 			if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
 3746: 				isp_prt(isp, ISP_LOGERR,
 3747: 				    "cannot find handle 0x%x (type 0x%x)",
 3748: 				    sp->req_handle,
 3749: 				    sp->req_header.rqs_entry_type);
 3750: 			} else if (ts != RQCS_ABORTED) {
 3751: 				isp_prt(isp, ISP_LOGERR,
 3752: 				    "cannot find handle 0x%x (status 0x%x)",
 3753: 				    sp->req_handle, ts);
 3754: 			}
 3755: 			WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
 3756: 			continue;
 3757: 		}
 3758: 		isp_destroy_handle(isp, sp->req_handle);
 3759: 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
 3760: 			XS_SETERR(xs, HBA_BUSRESET);
 3761: 			isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
 3762: 		}
 3763: 		if (buddaboom) {
 3764: 			XS_SETERR(xs, HBA_BOTCH);
 3765: 		}
 3766: 
 3767: 		if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
 3768: 			/*
 3769: 			 * Fibre Channel F/W doesn't say we got status
 3770: 			 * if there's Sense Data instead. I guess they
 3771: 			 * think it goes w/o saying.
 3772: 			 */
 3773: 			sp->req_state_flags |= RQSF_GOT_STATUS;
 3774: 		}
 3775: 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
 3776: 			*XS_STSP(xs) = sp->req_scsi_status & 0xff;
 3777: 		}
 3778: 
 3779: 		switch (sp->req_header.rqs_entry_type) {
 3780: 		case RQSTYPE_RESPONSE:
 3781: 			XS_SET_STATE_STAT(isp, xs, sp);
 3782: 			isp_parse_status(isp, sp, xs);
 3783: 			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
 3784: 			    (*XS_STSP(xs) == SCSI_BUSY)) {
 3785: 				XS_SETERR(xs, HBA_TGTBSY);
 3786: 			}
 3787: 			if (IS_SCSI(isp)) {
 3788: 				XS_RESID(xs) = sp->req_resid;
 3789: 				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
 3790: 				    (*XS_STSP(xs) == SCSI_CHECK) &&
 3791: 				    (sp->req_state_flags & RQSF_GOT_SENSE)) {
 3792: 					XS_SAVE_SENSE(xs, sp);
 3793: 				}
 3794: 				/*
 3795: 				 * A new synchronous rate was negotiated for
 3796: 				 * this target. Mark state such that we'll go
 3797: 				 * look up that which has changed later.
 3798: 				 */
 3799: 				if (sp->req_status_flags & RQSTF_NEGOTIATION) {
 3800: 					int t = XS_TGT(xs);
 3801: 					sdparam *sdp = isp->isp_param;
 3802: 					sdp += XS_CHANNEL(xs);
 3803: 					sdp->isp_devparam[t].dev_refresh = 1;
 3804: 					isp->isp_update |=
 3805: 					    (1 << XS_CHANNEL(xs));
 3806: 				}
 3807: 			} else {
 3808: 				if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
 3809: 					XS_RESID(xs) = 0;
 3810: 				} else if (sp->req_scsi_status & RQCS_RESID) {
 3811: 					XS_RESID(xs) = sp->req_resid;
 3812: 				} else {
 3813: 					XS_RESID(xs) = 0;
 3814: 				}
 3815: 				if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
 3816: 				    (*XS_STSP(xs) == SCSI_CHECK) &&
 3817: 				    (sp->req_scsi_status & RQCS_SV)) {
 3818: 					XS_SAVE_SENSE(xs, sp);
 3819: 					/* solely for the benefit of debug */
 3820: 					sp->req_state_flags |= RQSF_GOT_SENSE;
 3821: 				}
 3822: 			}
 3823: 			isp_prt(isp, ISP_LOGDEBUG2,
 3824: 			   "asked for %ld got resid %ld", (long) XS_XFRLEN(xs),
 3825: 			   (long) sp->req_resid);
 3826: 			break;
 3827: 		case RQSTYPE_REQUEST:
 3828: 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
 3829: 				/*
 3830: 				 * Force Queue Full status.
 3831: 				 */
 3832: 				*XS_STSP(xs) = SCSI_QFULL;
 3833: 				XS_SETERR(xs, HBA_NOERROR);
 3834: 			} else if (XS_NOERR(xs)) {
 3835: 				/*
 3836: 				 * ????
 3837: 				 */
 3838: 				isp_prt(isp, ISP_LOGDEBUG0,
 3839: 				    "Request Queue Entry bounced back");
 3840: 				XS_SETERR(xs, HBA_BOTCH);
 3841: 			}
 3842: 			XS_RESID(xs) = XS_XFRLEN(xs);
 3843: 			break;
 3844: 		default:
 3845: 			isp_prt(isp, ISP_LOGWARN,
 3846: 			    "unhandled response queue type 0x%x",
 3847: 			    sp->req_header.rqs_entry_type);
 3848: 			if (XS_NOERR(xs)) {
 3849: 				XS_SETERR(xs, HBA_BOTCH);
 3850: 			}
 3851: 			break;
 3852: 		}
 3853: 
 3854: 		/*
 3855: 		 * Free any dma resources. As a side effect, this may
 3856: 		 * also do any cache flushing necessary for data coherence.			 */
 3857: 		if (XS_XFRLEN(xs)) {
 3858: 			ISP_DMAFREE(isp, xs, sp->req_handle);
 3859: 		}
 3860: 
 3861: 		if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
 3862: 		    ((isp->isp_dblev & ISP_LOGDEBUG1) && ((!XS_NOERR(xs)) ||
 3863: 		    (*XS_STSP(xs) != SCSI_GOOD)))) {
 3864: 			char skey;
 3865: 			if (sp->req_state_flags & RQSF_GOT_SENSE) {
 3866: 				skey = XS_SNSKEY(xs) & 0xf;
 3867: 				if (skey < 10)
 3868: 					skey += '0';
 3869: 				else
 3870: 					skey += 'a' - 10;
 3871: 			} else if (*XS_STSP(xs) == SCSI_CHECK) {
 3872: 				skey = '?';
 3873: 			} else {
 3874: 				skey = '.';
 3875: 			}
 3876: 			isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
 3877: 			    XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
 3878: 			    *XS_STSP(xs), skey, XS_ERR(xs));
 3879: 		}
 3880: 
 3881: 		if (isp->isp_nactive > 0)
 3882: 		    isp->isp_nactive--;
 3883: 		complist[ndone++] = xs;	/* defer completion call until later */
 3884: 		MEMZERO(hp, QENTRY_LEN);	/* PERF */
 3885: 		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
 3886: 			break;
 3887: 		}
 3888: 	}
 3889: 
 3890: 	/*
 3891: 	 * If we looked at any commands, then it's valid to find out
 3892: 	 * what the outpointer is. It also is a trigger to update the
 3893: 	 * ISP's notion of what we've seen so far.
 3894: 	 */
 3895: 	if (nlooked) {
 3896: 		WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr);
 3897: 		/*
 3898: 		 * While we're at it, read the requst queue out pointer.
 3899: 		 */
 3900: 		isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp);
 3901: 		if (isp->isp_rscchiwater < ndone)
 3902: 			isp->isp_rscchiwater = ndone;
 3903: 	}
 3904: 
 3905: 	isp->isp_residx = optr;
 3906: 	isp->isp_rspbsy = 0;
 3907: 	for (i = 0; i < ndone; i++) {
 3908: 		xs = complist[i];
 3909: 		if (xs) {
 3910: 			isp->isp_rsltccmplt++;
 3911: 			isp_done(xs);
 3912: 		}
 3913: 	}
 3914: }
 3915: 
 3916: /*
 3917:  * Support routines.
 3918:  */
 3919: 
 3920: static int
 3921: isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
 3922: {
 3923: 	int rval = 0;
 3924: 	int bus;
 3925: 
 3926: 	if (IS_DUALBUS(isp)) {
 3927: 		bus = ISP_READ(isp, OUTMAILBOX6);
 3928: 	} else {
 3929: 		bus = 0;
 3930: 	}
 3931: 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
 3932: 
 3933: 	switch (mbox) {
 3934: 	case ASYNC_BUS_RESET:
 3935: 		isp->isp_sendmarker |= (1 << bus);
 3936: #ifdef	ISP_TARGET_MODE
 3937: 		if (isp_target_async(isp, bus, mbox))
 3938: 			rval = -1;
 3939: #endif
 3940: 		isp_async(isp, ISPASYNC_BUS_RESET, &bus);
 3941: 		break;
 3942: 	case ASYNC_SYSTEM_ERROR:
 3943: #ifdef	ISP_FW_CRASH_DUMP
 3944: 		/*
 3945: 		 * If we have crash dumps enabled, it's up to the handler
 3946: 		 * for isp_async to reinit stuff and restart the firmware
 3947: 		 * after performing the crash dump. The reason we do things
 3948: 		 * this way is that we may need to activate a kernel thread
 3949: 		 * to do all the crash dump goop.
 3950: 		 */
 3951: 		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
 3952: #else
 3953: 		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
 3954: 		isp_reinit(isp);
 3955: 		isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
 3956: #endif
 3957: 		rval = -1;
 3958: 		break;
 3959: 
 3960: 	case ASYNC_RQS_XFER_ERR:
 3961: 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
 3962: 		break;
 3963: 
 3964: 	case ASYNC_RSP_XFER_ERR:
 3965: 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
 3966: 		break;
 3967: 
 3968: 	case ASYNC_QWAKEUP:
 3969: 		/*
 3970: 		 * We've just been notified that the Queue has woken up.
 3971: 		 * We don't need to be chatty about this- just unlatch things
 3972: 		 * and move on.
 3973: 		 */
 3974: 		mbox = READ_REQUEST_QUEUE_OUT_POINTER(isp);
 3975: 		break;
 3976: 
 3977: 	case ASYNC_TIMEOUT_RESET:
 3978: 		isp_prt(isp, ISP_LOGWARN,
 3979: 		    "timeout initiated SCSI bus reset of bus %d", bus);
 3980: 		isp->isp_sendmarker |= (1 << bus);
 3981: #ifdef	ISP_TARGET_MODE
 3982: 		if (isp_target_async(isp, bus, mbox))
 3983: 			rval = -1;
 3984: #endif
 3985: 		break;
 3986: 
 3987: 	case ASYNC_DEVICE_RESET:
 3988: 		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
 3989: 		isp->isp_sendmarker |= (1 << bus);
 3990: #ifdef	ISP_TARGET_MODE
 3991: 		if (isp_target_async(isp, bus, mbox))
 3992: 			rval = -1;
 3993: #endif
 3994: 		break;
 3995: 
 3996: 	case ASYNC_EXTMSG_UNDERRUN:
 3997: 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
 3998: 		break;
 3999: 
 4000: 	case ASYNC_SCAM_INT:
 4001: 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
 4002: 		break;
 4003: 
 4004: 	case ASYNC_HUNG_SCSI:
 4005: 		isp_prt(isp, ISP_LOGERR,
 4006: 		    "stalled SCSI Bus after DATA Overrun");
 4007: 		/* XXX: Need to issue SCSI reset at this point */
 4008: 		break;
 4009: 
 4010: 	case ASYNC_KILLED_BUS:
 4011: 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
 4012: 		break;
 4013: 
 4014: 	case ASYNC_BUS_TRANSIT:
 4015: 		mbox = ISP_READ(isp, OUTMAILBOX2);
 4016: 		switch (mbox & 0x1c00) {
 4017: 		case SXP_PINS_LVD_MODE:
 4018: 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
 4019: 			SDPARAM(isp)->isp_diffmode = 0;
 4020: 			SDPARAM(isp)->isp_ultramode = 0;
 4021: 			SDPARAM(isp)->isp_lvdmode = 1;
 4022: 			break;
 4023: 		case SXP_PINS_HVD_MODE:
 4024: 			isp_prt(isp, ISP_LOGINFO,
 4025: 			    "Transition to Differential mode");
 4026: 			SDPARAM(isp)->isp_diffmode = 1;
 4027: 			SDPARAM(isp)->isp_ultramode = 0;
 4028: 			SDPARAM(isp)->isp_lvdmode = 0;
 4029: 			break;
 4030: 		case SXP_PINS_SE_MODE:
 4031: 			isp_prt(isp, ISP_LOGINFO,
 4032: 			    "Transition to Single Ended mode");
 4033: 			SDPARAM(isp)->isp_diffmode = 0;
 4034: 			SDPARAM(isp)->isp_ultramode = 1;
 4035: 			SDPARAM(isp)->isp_lvdmode = 0;
 4036: 			break;
 4037: 		default:
 4038: 			isp_prt(isp, ISP_LOGWARN,
 4039: 			    "Transition to Unknown Mode 0x%x", mbox);
 4040: 			break;
 4041: 		}
 4042: 		/*
 4043: 		 * XXX: Set up to renegotiate again!
 4044: 		 */
 4045: 		/* Can only be for a 1080... */
 4046: 		isp->isp_sendmarker |= (1 << bus);
 4047: 		break;
 4048: 
 4049: 	/*
 4050: 	 * We can use bus, which will always be zero for FC cards,
 4051: 	 * as a mailbox pattern accumulator to be checked below.
 4052: 	 */
 4053: 	case ASYNC_RIO5:
 4054: 		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
 4055: 		break;
 4056: 
 4057: 	case ASYNC_RIO4:
 4058: 		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
 4059: 		break;
 4060: 
 4061: 	case ASYNC_RIO3:
 4062: 		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
 4063: 		break;
 4064: 
 4065: 	case ASYNC_RIO2:
 4066: 		bus = 0x106;	/* outgoing mailbox regs 1-2 */
 4067: 		break;
 4068: 
 4069: 	case ASYNC_RIO1:
 4070: 	case ASYNC_CMD_CMPLT:
 4071: 		bus = 0x102;	/* outgoing mailbox regs 1 */
 4072: 		break;
 4073: 
 4074: 	case ASYNC_RIO_RESP:
 4075: 		return (rval);
 4076: 
 4077: 	case ASYNC_CTIO_DONE:
 4078: 	{
 4079: #ifdef	ISP_TARGET_MODE
 4080: 		int handle =
 4081: 		    (ISP_READ(isp, OUTMAILBOX2) << 16) | 
 4082: 		    (ISP_READ(isp, OUTMAILBOX1));
 4083: 		if (isp_target_async(isp, handle, mbox))
 4084: 			rval = -1;
 4085: #else
 4086: 		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
 4087: #endif
 4088: 		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
 4089: 		break;
 4090: 	}
 4091: 	case ASYNC_LIP_F8:
 4092: 	case ASYNC_LIP_OCCURRED:
 4093: 		FCPARAM(isp)->isp_lipseq =
 4094: 		    ISP_READ(isp, OUTMAILBOX1);
 4095: 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
 4096: 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
 4097: 		isp->isp_sendmarker = 1;
 4098: 		isp_mark_getpdb_all(isp);
 4099: 		isp_async(isp, ISPASYNC_LIP, NULL);
 4100: #ifdef	ISP_TARGET_MODE
 4101: 		if (isp_target_async(isp, bus, mbox))
 4102: 			rval = -1;
 4103: #endif
 4104: 		/*
 4105: 		 * We've had problems with data corruption occuring on
 4106: 		 * commands that complete (with no apparent error) after
 4107: 		 * we receive a LIP. This has been observed mostly on
 4108: 		 * Local Loop topologies. To be safe, let's just mark
 4109: 		 * all active commands as dead.
 4110: 		 */
 4111: 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
 4112: 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
 4113: 			int i, j;
 4114: 			for (i = j = 0; i < isp->isp_maxcmds; i++) {
 4115: 				XS_T *xs;
 4116: 				xs = isp->isp_xflist[i];
 4117: 				if (xs != NULL) {
 4118: 					j++;
 4119: 					XS_SETERR(xs, HBA_BUSRESET);
 4120: 				}
 4121: 			}
 4122: 			if (j) {
 4123: 				isp_prt(isp, ISP_LOGERR,
 4124: 				    "LIP destroyed %d active commands", j);
 4125: 			}
 4126: 		}
 4127: 		break;
 4128: 
 4129: 	case ASYNC_LOOP_UP:
 4130: 		isp->isp_sendmarker = 1;
 4131: 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
 4132: 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
 4133: 		isp_mark_getpdb_all(isp);
 4134: 		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
 4135: #ifdef	ISP_TARGET_MODE
 4136: 		if (isp_target_async(isp, bus, mbox))
 4137: 			rval = -1;
 4138: #endif
 4139: 		break;
 4140: 
 4141: 	case ASYNC_LOOP_DOWN:
 4142: 		isp->isp_sendmarker = 1;
 4143: 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
 4144: 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
 4145: 		isp_mark_getpdb_all(isp);
 4146: 		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
 4147: #ifdef	ISP_TARGET_MODE
 4148: 		if (isp_target_async(isp, bus, mbox))
 4149: 			rval = -1;
 4150: #endif
 4151: 		break;
 4152: 
 4153: 	case ASYNC_LOOP_RESET:
 4154: 		isp->isp_sendmarker = 1;
 4155: 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
 4156: 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
 4157: 		isp_mark_getpdb_all(isp);
 4158: 		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
 4159: #ifdef	ISP_TARGET_MODE
 4160: 		if (isp_target_async(isp, bus, mbox))
 4161: 			rval = -1;
 4162: #endif
 4163: 		break;
 4164: 
 4165: 	case ASYNC_PDB_CHANGED:
 4166: 		isp->isp_sendmarker = 1;
 4167: 		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
 4168: 		isp_mark_getpdb_all(isp);
 4169: 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
 4170: 		break;
 4171: 
 4172: 	case ASYNC_CHANGE_NOTIFY:
 4173: 		/*
 4174: 		 * Not correct, but it will force us to rescan the loop.
 4175: 		 */
 4176: 		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
 4177: 		isp_mark_getpdb_all(isp);
 4178: 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
 4179: 		break;
 4180: 
 4181: 	case ASYNC_PTPMODE:
 4182: 		if (FCPARAM(isp)->isp_onfabric)
 4183: 			FCPARAM(isp)->isp_topo = TOPO_F_PORT;
 4184: 		else
 4185: 			FCPARAM(isp)->isp_topo = TOPO_N_PORT;
 4186: 		isp_mark_getpdb_all(isp);
 4187: 		isp->isp_sendmarker = 1;
 4188: 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
 4189: 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
 4190: 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
 4191: #ifdef	ISP_TARGET_MODE
 4192: 		if (isp_target_async(isp, bus, mbox))
 4193: 			rval = -1;
 4194: #endif
 4195: 		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
 4196: 		break;
 4197: 
 4198: 	case ASYNC_CONNMODE:
 4199: 		mbox = ISP_READ(isp, OUTMAILBOX1);
 4200: 		isp_mark_getpdb_all(isp);
 4201: 		switch (mbox) {
 4202: 		case ISP_CONN_LOOP:
 4203: 			isp_prt(isp, ISP_LOGINFO,
 4204: 			    "Point-to-Point -> Loop mode");
 4205: 			break;
 4206: 		case ISP_CONN_PTP:
 4207: 			isp_prt(isp, ISP_LOGINFO,
 4208: 			    "Loop -> Point-to-Point mode");
 4209: 			break;
 4210: 		case ISP_CONN_BADLIP:
 4211: 			isp_prt(isp, ISP_LOGWARN,
 4212: 			    "Point-to-Point -> Loop mode (BAD LIP)");
 4213: 			break;
 4214: 		case ISP_CONN_FATAL:
 4215: 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
 4216: 			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
 4217: 			isp_reinit(isp);
 4218: 			isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
 4219: 			return (-1);
 4220: 		case ISP_CONN_LOOPBACK:
 4221: 			isp_prt(isp, ISP_LOGWARN,
 4222: 			    "Looped Back in Point-to-Point mode");
 4223: 			break;
 4224: 		default:
 4225: 			isp_prt(isp, ISP_LOGWARN,
 4226: 			    "Unknown connection mode (0x%x)", mbox);
 4227: 			break;
 4228: 		}
 4229: 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
 4230: 		isp->isp_sendmarker = 1;
 4231: 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
 4232: 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
 4233: 		break;
 4234: 
 4235: 	default:
 4236: 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
 4237: 		break;
 4238: 	}
 4239: 
 4240: 	if (bus & 0x100) {
 4241: 		int i, nh;
 4242: 		u_int16_t handles[5];
 4243: 
 4244: 		for (nh = 0, i = 1; i < MAX_MAILBOX; i++) {
 4245: 			if ((bus & (1 << i)) == 0) {
 4246: 				continue;
 4247: 			}
 4248: 			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
 4249: 		}
 4250: 		for (i = 0; i < nh; i++) {
 4251: 			isp_fastpost_complete(isp, handles[i]);
 4252: 			isp_prt(isp,  ISP_LOGDEBUG3,
 4253: 			    "fast post completion of %u", handles[i]);
 4254: 		}
 4255: 		if (isp->isp_fpcchiwater < nh)
 4256: 			isp->isp_fpcchiwater = nh;
 4257: 	} else {
 4258: 		isp->isp_intoasync++;
 4259: 	}
 4260: 	return (rval);
 4261: }
 4262: 
 4263: /*
 4264:  * Handle other response entries. A pointer to the request queue output
 4265:  * index is here in case we want to eat several entries at once, although
 4266:  * this is not used currently.
 4267:  */
 4268: 
 4269: static int
 4270: isp_handle_other_response(struct ispsoftc *isp, int type,
 4271:     isphdr_t *hp, u_int16_t *optrp)
 4272: {
 4273: 	switch (type) {
 4274: 	case RQSTYPE_STATUS_CONT:
 4275: 		isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
 4276: 		return (1);
 4277: 	case RQSTYPE_ATIO:
 4278: 	case RQSTYPE_CTIO:
 4279: 	case RQSTYPE_ENABLE_LUN:
 4280: 	case RQSTYPE_MODIFY_LUN:
 4281: 	case RQSTYPE_NOTIFY:
 4282: 	case RQSTYPE_NOTIFY_ACK:
 4283: 	case RQSTYPE_CTIO1:
 4284: 	case RQSTYPE_ATIO2:
 4285: 	case RQSTYPE_CTIO2:
 4286: 	case RQSTYPE_CTIO3:
 4287: 		isp->isp_rsltccmplt++;	/* count as a response completion */
 4288: #ifdef	ISP_TARGET_MODE
 4289: 		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
 4290: 			return (1);
 4291: 		}
 4292: #else
 4293: 		optrp = optrp;
 4294: 		/* FALLTHROUGH */
 4295: #endif
 4296: 	case RQSTYPE_REQUEST:
 4297: 	default:
 4298: 		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
 4299: 			return (1);
 4300: 		}
 4301: 		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
 4302: 		    isp_get_response_type(isp, hp));
 4303: 		return (0);
 4304: 	}
 4305: }
 4306: 
 4307: static void
 4308: isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
 4309: {
 4310: 	switch (sp->req_completion_status & 0xff) {
 4311: 	case RQCS_COMPLETE:
 4312: 		if (XS_NOERR(xs)) {
 4313: 			XS_SETERR(xs, HBA_NOERROR);
 4314: 		}
 4315: 		return;
 4316: 
 4317: 	case RQCS_INCOMPLETE:
 4318: 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
 4319: 			isp_prt(isp, ISP_LOGDEBUG1,
 4320: 			    "Selection Timeout for %d.%d.%d",
 4321: 			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4322: 			if (XS_NOERR(xs)) {
 4323: 				XS_SETERR(xs, HBA_SELTIMEOUT);
 4324: 			}
 4325: 			return;
 4326: 		}
 4327: 		isp_prt(isp, ISP_LOGERR,
 4328: 		    "command incomplete for %d.%d.%d, state 0x%x",
 4329: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
 4330: 		    sp->req_state_flags);
 4331: 		break;
 4332: 
 4333: 	case RQCS_DMA_ERROR:
 4334: 		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
 4335: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4336: 		break;
 4337: 
 4338: 	case RQCS_TRANSPORT_ERROR:
 4339: 	{
 4340: 		char buf[172];
 4341: 		SNPRINTF(buf, sizeof (buf), "states=>");
 4342: 		if (sp->req_state_flags & RQSF_GOT_BUS) {
 4343: 			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
 4344: 		}
 4345: 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
 4346: 			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
 4347: 		}
 4348: 		if (sp->req_state_flags & RQSF_SENT_CDB) {
 4349: 			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
 4350: 		}
 4351: 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
 4352: 			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
 4353: 		}
 4354: 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
 4355: 			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
 4356: 		}
 4357: 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
 4358: 			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
 4359: 		}
 4360: 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
 4361: 			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
 4362: 		}
 4363: 		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
 4364: 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
 4365: 			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
 4366: 		}
 4367: 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
 4368: 			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
 4369: 		}
 4370: 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
 4371: 			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
 4372: 		}
 4373: 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
 4374: 			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
 4375: 		}
 4376: 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
 4377: 			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
 4378: 		}
 4379: 		if (sp->req_status_flags & RQSTF_ABORTED) {
 4380: 			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
 4381: 		}
 4382: 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
 4383: 			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
 4384: 		}
 4385: 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
 4386: 			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
 4387: 		}
 4388: 		isp_prt(isp, ISP_LOGERR, "%s", buf);
 4389: 		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
 4390: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
 4391: 		break;
 4392: 	}
 4393: 	case RQCS_RESET_OCCURRED:
 4394: 		isp_prt(isp, ISP_LOGWARN,
 4395: 		    "bus reset destroyed command for %d.%d.%d",
 4396: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4397: 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
 4398: 		if (XS_NOERR(xs)) {
 4399: 			XS_SETERR(xs, HBA_BUSRESET);
 4400: 		}
 4401: 		return;
 4402: 
 4403: 	case RQCS_ABORTED:
 4404: 		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
 4405: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4406: 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
 4407: 		if (XS_NOERR(xs)) {
 4408: 			XS_SETERR(xs, HBA_ABORTED);
 4409: 		}
 4410: 		return;
 4411: 
 4412: 	case RQCS_TIMEOUT:
 4413: 		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
 4414: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4415: 		/*
 4416: 	 	 * Check to see if we logged out the device.
 4417: 		 */
 4418: 		if (IS_FC(isp)) {
 4419: 			if ((sp->req_completion_status & RQSTF_LOGOUT) &&
 4420: 			    FCPARAM(isp)->portdb[XS_TGT(xs)].valid &&
 4421: 			    FCPARAM(isp)->portdb[XS_TGT(xs)].fabric_dev) {
 4422: 				FCPARAM(isp)->portdb[XS_TGT(xs)].relogin = 1;
 4423: 			}
 4424: 		}
 4425: 		if (XS_NOERR(xs)) {
 4426: 			XS_SETERR(xs, HBA_CMDTIMEOUT);
 4427: 		}
 4428: 		return;
 4429: 
 4430: 	case RQCS_DATA_OVERRUN:
 4431: 		XS_RESID(xs) = sp->req_resid;
 4432: 		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
 4433: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4434: 		if (XS_NOERR(xs)) {
 4435: 			XS_SETERR(xs, HBA_DATAOVR);
 4436: 		}
 4437: 		return;
 4438: 
 4439: 	case RQCS_COMMAND_OVERRUN:
 4440: 		isp_prt(isp, ISP_LOGERR,
 4441: 		    "command overrun for command on %d.%d.%d",
 4442: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4443: 		break;
 4444: 
 4445: 	case RQCS_STATUS_OVERRUN:
 4446: 		isp_prt(isp, ISP_LOGERR,
 4447: 		    "status overrun for command on %d.%d.%d",
 4448: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4449: 		break;
 4450: 
 4451: 	case RQCS_BAD_MESSAGE:
 4452: 		isp_prt(isp, ISP_LOGERR,
 4453: 		    "msg not COMMAND COMPLETE after status %d.%d.%d",
 4454: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4455: 		break;
 4456: 
 4457: 	case RQCS_NO_MESSAGE_OUT:
 4458: 		isp_prt(isp, ISP_LOGERR,
 4459: 		    "No MESSAGE OUT phase after selection on %d.%d.%d",
 4460: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4461: 		break;
 4462: 
 4463: 	case RQCS_EXT_ID_FAILED:
 4464: 		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
 4465: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4466: 		break;
 4467: 
 4468: 	case RQCS_IDE_MSG_FAILED:
 4469: 		isp_prt(isp, ISP_LOGERR,
 4470: 		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
 4471: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4472: 		break;
 4473: 
 4474: 	case RQCS_ABORT_MSG_FAILED:
 4475: 		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
 4476: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4477: 		break;
 4478: 
 4479: 	case RQCS_REJECT_MSG_FAILED:
 4480: 		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
 4481: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4482: 		break;
 4483: 
 4484: 	case RQCS_NOP_MSG_FAILED:
 4485: 		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
 4486: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4487: 		break;
 4488: 
 4489: 	case RQCS_PARITY_ERROR_MSG_FAILED:
 4490: 		isp_prt(isp, ISP_LOGERR,
 4491: 		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
 4492: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4493: 		break;
 4494: 
 4495: 	case RQCS_DEVICE_RESET_MSG_FAILED:
 4496: 		isp_prt(isp, ISP_LOGWARN,
 4497: 		    "BUS DEVICE RESET rejected by %d.%d.%d",
 4498: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4499: 		break;
 4500: 
 4501: 	case RQCS_ID_MSG_FAILED:
 4502: 		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
 4503: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4504: 		break;
 4505: 
 4506: 	case RQCS_UNEXP_BUS_FREE:
 4507: 		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
 4508: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4509: 		break;
 4510: 
 4511: 	case RQCS_DATA_UNDERRUN:
 4512: 	{
 4513: 		if (IS_FC(isp)) {
 4514: 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
 4515: 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
 4516: 				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
 4517: 				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
 4518: 				    (ru_marked)? "marked" : "not marked");
 4519: 				if (XS_NOERR(xs)) {
 4520: 					XS_SETERR(xs, HBA_BOTCH);
 4521: 				}
 4522: 				return;
 4523: 			}
 4524: 		}
 4525: 		XS_RESID(xs) = sp->req_resid;
 4526: 		if (XS_NOERR(xs)) {
 4527: 			XS_SETERR(xs, HBA_NOERROR);
 4528: 		}
 4529: 		return;
 4530: 	}
 4531: 
 4532: 	case RQCS_XACT_ERR1:
 4533: 		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
 4534: 		    XS_TGT(xs), XS_LUN(xs));
 4535: 		break;
 4536: 
 4537: 	case RQCS_XACT_ERR2:
 4538: 		isp_prt(isp, ISP_LOGERR, xact2,
 4539: 		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
 4540: 		break;
 4541: 
 4542: 	case RQCS_XACT_ERR3:
 4543: 		isp_prt(isp, ISP_LOGERR, xact3,
 4544: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4545: 		break;
 4546: 
 4547: 	case RQCS_BAD_ENTRY:
 4548: 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
 4549: 		break;
 4550: 
 4551: 	case RQCS_QUEUE_FULL:
 4552: 		isp_prt(isp, ISP_LOGDEBUG0,
 4553: 		    "internal queues full for %d.%d.%d status 0x%x",
 4554: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
 4555: 
 4556: 		/*
 4557: 		 * If QFULL or some other status byte is set, then this
 4558: 		 * isn't an error, per se.
 4559: 		 *
 4560: 		 * Unfortunately, some QLogic f/w writers have, in
 4561: 		 * some cases, ommitted to *set* status to QFULL.
 4562: 		 *
 4563: 
 4564: 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
 4565: 			XS_SETERR(xs, HBA_NOERROR);
 4566: 			return;
 4567: 		}
 4568: 
 4569: 		 *
 4570: 		 *
 4571: 		 */
 4572: 
 4573: 		*XS_STSP(xs) = SCSI_QFULL;
 4574: 		XS_SETERR(xs, HBA_NOERROR);
 4575: 		return;
 4576: 
 4577: 	case RQCS_PHASE_SKIPPED:
 4578: 		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
 4579: 		    XS_TGT(xs), XS_LUN(xs));
 4580: 		break;
 4581: 
 4582: 	case RQCS_ARQS_FAILED:
 4583: 		isp_prt(isp, ISP_LOGERR,
 4584: 		    "Auto Request Sense failed for %d.%d.%d",
 4585: 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
 4586: 		if (XS_NOERR(xs)) {
 4587: 			XS_SETERR(xs, HBA_ARQFAIL);
 4588: 		}
 4589: 		return;
 4590: 
 4591: 	case RQCS_WIDE_FAILED:
 4592: 		isp_prt(isp, ISP_LOGERR,
 4593: 		    "Wide Negotiation failed for %d.%d.%d",
 4594: 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
 4595: 		if (IS_SCSI(isp)) {
 4596: 			sdparam *sdp = isp->isp_param;
 4597: 			sdp += XS_CHANNEL(xs);
 4598: 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
 4599: 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
 4600: 			isp->isp_update |= (1 << XS_CHANNEL(xs));
 4601: 		}
 4602: 		if (XS_NOERR(xs)) {
 4603: 			XS_SETERR(xs, HBA_NOERROR);
 4604: 		}
 4605: 		return;
 4606: 
 4607: 	case RQCS_SYNCXFER_FAILED:
 4608: 		isp_prt(isp, ISP_LOGERR,
 4609: 		    "SDTR Message failed for target %d.%d.%d",
 4610: 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
 4611: 		if (IS_SCSI(isp)) {
 4612: 			sdparam *sdp = isp->isp_param;
 4613: 			sdp += XS_CHANNEL(xs);
 4614: 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
 4615: 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
 4616: 			isp->isp_update |= (1 << XS_CHANNEL(xs));
 4617: 		}
 4618: 		break;
 4619: 
 4620: 	case RQCS_LVD_BUSERR:
 4621: 		isp_prt(isp, ISP_LOGERR,
 4622: 		    "Bad LVD condition while talking to %d.%d.%d",
 4623: 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
 4624: 		break;
 4625: 
 4626: 	case RQCS_PORT_UNAVAILABLE:
 4627: 		/*
 4628: 		 * No such port on the loop. Moral equivalent of SELTIMEO
 4629: 		 */
 4630: 	case RQCS_PORT_LOGGED_OUT:
 4631: 		/*
 4632: 		 * It was there (maybe)- treat as a selection timeout.
 4633: 		 */
 4634: 		if ((sp->req_completion_status & 0xff) == RQCS_PORT_UNAVAILABLE)
 4635: 			isp_prt(isp, ISP_LOGINFO,
 4636: 			    "port unavailable for target %d", XS_TGT(xs));
 4637: 		else
 4638: 			isp_prt(isp, ISP_LOGINFO,
 4639: 			    "port logout for target %d", XS_TGT(xs));
 4640: 		/*
 4641: 		 * If we're on a local loop, force a LIP (which is overkill)
 4642: 		 * to force a re-login of this unit. If we're on fabric,
 4643: 		 * then we'll have to relogin as a matter of course.
 4644: 		 */
 4645: 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
 4646: 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
 4647: 			mbreg_t mbs;
 4648: 			mbs.param[0] = MBOX_INIT_LIP;
 4649: 			isp_mboxcmd_qnw(isp, &mbs, 1);
 4650: 		}
 4651: 
 4652: 		/*
 4653: 		 * Probably overkill.
 4654: 		 */
 4655: 		isp->isp_sendmarker = 1;
 4656: 		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
 4657: 		isp_mark_getpdb_all(isp);
 4658: 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
 4659: 		if (XS_NOERR(xs)) {
 4660: 			XS_SETERR(xs, HBA_SELTIMEOUT);
 4661: 		}
 4662: 		return;
 4663: 
 4664: 	case RQCS_PORT_CHANGED:
 4665: 		isp_prt(isp, ISP_LOGWARN,
 4666: 		    "port changed for target %d", XS_TGT(xs));
 4667: 		if (XS_NOERR(xs)) {
 4668: 			XS_SETERR(xs, HBA_SELTIMEOUT);
 4669: 		}
 4670: 		return;
 4671: 
 4672: 	case RQCS_PORT_BUSY:
 4673: 		isp_prt(isp, ISP_LOGWARN,
 4674: 		    "port busy for target %d", XS_TGT(xs));
 4675: 		if (XS_NOERR(xs)) {
 4676: 			XS_SETERR(xs, HBA_TGTBSY);
 4677: 		}
 4678: 		return;
 4679: 
 4680: 	default:
 4681: 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
 4682: 		    sp->req_completion_status);
 4683: 		break;
 4684: 	}
 4685: 	if (XS_NOERR(xs)) {
 4686: 		XS_SETERR(xs, HBA_BOTCH);
 4687: 	}
 4688: }
 4689: 
 4690: static void
 4691: isp_fastpost_complete(struct ispsoftc *isp, u_int16_t fph)
 4692: {
 4693: 	XS_T *xs;
 4694: 
 4695: 	if (fph == 0) {
 4696: 		return;
 4697: 	}
 4698: 	xs = isp_find_xs(isp, fph);
 4699: 	if (xs == NULL) {
 4700: 		isp_prt(isp, ISP_LOGWARN,
 4701: 		    "Command for fast post handle 0x%x not found", fph);
 4702: 		return;
 4703: 	}
 4704: 	isp_destroy_handle(isp, fph);
 4705: 
 4706: 	/*
 4707: 	 * Since we don't have a result queue entry item,
 4708: 	 * we must believe that SCSI status is zero and
 4709: 	 * that all data transferred.
 4710: 	 */
 4711: 	XS_SET_STATE_STAT(isp, xs, NULL);
 4712: 	XS_RESID(xs) = 0;
 4713: 	*XS_STSP(xs) = SCSI_GOOD;
 4714: 	if (XS_XFRLEN(xs)) {
 4715: 		ISP_DMAFREE(isp, xs, fph);
 4716: 	}
 4717: 	if (isp->isp_nactive)
 4718: 		isp->isp_nactive--;
 4719: 	isp->isp_fphccmplt++;
 4720: 	isp_done(xs);
 4721: }
 4722: 
 4723: static int
 4724: isp_mbox_continue(struct ispsoftc *isp)
 4725: {
 4726: 	mbreg_t mbs;
 4727: 	u_int16_t *ptr;
 4728: 
 4729: 	switch (isp->isp_lastmbxcmd) {
 4730: 	case MBOX_WRITE_RAM_WORD:
 4731: 	case MBOX_READ_RAM_WORD:
 4732: 	case MBOX_READ_RAM_WORD_EXTENDED:
 4733: 		break;
 4734: 	default:
 4735: 		return (1);
 4736: 	}
 4737: 	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
 4738: 		isp->isp_mbxwrk0 = 0;
 4739: 		return (-1);
 4740: 	}
 4741: 
 4742: 
 4743: 	/*
 4744: 	 * Clear the previous interrupt.
 4745: 	 */
 4746: 	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
 4747: 	ISP_WRITE(isp, BIU_SEMA, 0);
 4748: 
 4749: 	/*
 4750: 	 * Continue with next word.
 4751: 	 */
 4752: 	ptr = isp->isp_mbxworkp;
 4753: 	switch (isp->isp_lastmbxcmd) {
 4754: 	case MBOX_WRITE_RAM_WORD:
 4755: 		mbs.param[2] = *ptr++;
 4756: 		mbs.param[1] = isp->isp_mbxwrk1++;
 4757: 		break;
 4758: 	case MBOX_READ_RAM_WORD:
 4759: 	case MBOX_READ_RAM_WORD_EXTENDED:
 4760: 		*ptr++ = isp->isp_mboxtmp[2];
 4761: 		mbs.param[1] = isp->isp_mbxwrk1++;
 4762: 		break;
 4763: 	}
 4764: 	isp->isp_mbxworkp = ptr;
 4765: 	mbs.param[0] = isp->isp_lastmbxcmd;
 4766: 	isp->isp_mbxwrk0 -= 1;
 4767: 	isp_mboxcmd_qnw(isp, &mbs, 0);
 4768: 	return (0);
 4769: }
 4770: 
 4771: 
 4772: #define	HIBYT(x)			((x) >> 0x8)
 4773: #define	LOBYT(x)			((x)  & 0xff)
 4774: #define	ISPOPMAP(a, b)			(((a) << 8) | (b))
 4775: static u_int16_t mbpscsi[] = {
 4776: 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
 4777: 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
 4778: 	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
 4779: 	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
 4780: 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
 4781: 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
 4782: 	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
 4783: 	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
 4784: 	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
 4785: 	ISPOPMAP(0x00, 0x00),	/* 0x09: */
 4786: 	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
 4787: 	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
 4788: 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
 4789: 	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
 4790: 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
 4791: 	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
 4792: 	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
 4793: 	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
 4794: 	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
 4795: 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
 4796: 	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
 4797: 	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
 4798: 	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
 4799: 	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
 4800: 	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
 4801: 	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
 4802: 	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
 4803: 	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
 4804: 	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
 4805: 	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
 4806: 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
 4807: 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
 4808: 	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
 4809: 	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
 4810: 	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
 4811: 	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
 4812: 	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
 4813: 	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
 4814: 	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
 4815: 	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
 4816: 	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
 4817: 	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
 4818: 	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
 4819: 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
 4820: 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
 4821: 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
 4822: 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
 4823: 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
 4824: 	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
 4825: 	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
 4826: 	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
 4827: 	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
 4828: 	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
 4829: 	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
 4830: 	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
 4831: 	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
 4832: 	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
 4833: 	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
 4834: 	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
 4835: 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
 4836: 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
 4837: 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
 4838: 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
 4839: 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
 4840: 	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
 4841: 	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
 4842: 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
 4843: 	ISPOPMAP(0x00, 0x00),	/* 0x43: */
 4844: 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
 4845: 	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
 4846: 	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
 4847: 	ISPOPMAP(0x00, 0x00),	/* 0x47: */
 4848: 	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
 4849: 	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
 4850: 	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
 4851: 	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
 4852: 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
 4853: 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
 4854: 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
 4855: 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
 4856: 	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
 4857: 	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
 4858: 	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
 4859: 	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
 4860: 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
 4861: 	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
 4862: 	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
 4863: 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
 4864: 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
 4865: 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
 4866: 	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
 4867: 	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
 4868: 	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
 4869: 	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
 4870: };
 4871: 
 4872: #ifndef	ISP_STRIPPED
 4873: static char *scsi_mbcmd_names[] = {
 4874: 	"NO-OP",
 4875: 	"LOAD RAM",
 4876: 	"EXEC FIRMWARE",
 4877: 	"DUMP RAM",
 4878: 	"WRITE RAM WORD",
 4879: 	"READ RAM WORD",
 4880: 	"MAILBOX REG TEST",
 4881: 	"VERIFY CHECKSUM",
 4882: 	"ABOUT FIRMWARE",
 4883: 	NULL,
 4884: 	NULL,
 4885: 	NULL,
 4886: 	NULL,
 4887: 	NULL,
 4888: 	"CHECK FIRMWARE",
 4889: 	NULL,
 4890: 	"INIT REQUEST QUEUE",
 4891: 	"INIT RESULT QUEUE",
 4892: 	"EXECUTE IOCB",
 4893: 	"WAKE UP",
 4894: 	"STOP FIRMWARE",
 4895: 	"ABORT",
 4896: 	"ABORT DEVICE",
 4897: 	"ABORT TARGET",
 4898: 	"BUS RESET",
 4899: 	"STOP QUEUE",
 4900: 	"START QUEUE",
 4901: 	"SINGLE STEP QUEUE",
 4902: 	"ABORT QUEUE",
 4903: 	"GET DEV QUEUE STATUS",
 4904: 	NULL,
 4905: 	"GET FIRMWARE STATUS",
 4906: 	"GET INIT SCSI ID",
 4907: 	"GET SELECT TIMEOUT",
 4908: 	"GET RETRY COUNT",
 4909: 	"GET TAG AGE LIMIT",
 4910: 	"GET CLOCK RATE",
 4911: 	"GET ACT NEG STATE",
 4912: 	"GET ASYNC DATA SETUP TIME",
 4913: 	"GET PCI PARAMS",
 4914: 	"GET TARGET PARAMS",
 4915: 	"GET DEV QUEUE PARAMS",
 4916: 	"GET RESET DELAY PARAMS",
 4917: 	NULL,
 4918: 	NULL,
 4919: 	NULL,
 4920: 	NULL,
 4921: 	NULL,
 4922: 	"SET INIT SCSI ID",
 4923: 	"SET SELECT TIMEOUT",
 4924: 	"SET RETRY COUNT",
 4925: 	"SET TAG AGE LIMIT",
 4926: 	"SET CLOCK RATE",
 4927: 	"SET ACT NEG STATE",
 4928: 	"SET ASYNC DATA SETUP TIME",
 4929: 	"SET PCI CONTROL PARAMS",
 4930: 	"SET TARGET PARAMS",
 4931: 	"SET DEV QUEUE PARAMS",
 4932: 	"SET RESET DELAY PARAMS",
 4933: 	NULL,
 4934: 	NULL,
 4935: 	NULL,
 4936: 	NULL,
 4937: 	NULL,
 4938: 	"RETURN BIOS BLOCK ADDR",
 4939: 	"WRITE FOUR RAM WORDS",
 4940: 	"EXEC BIOS IOCB",
 4941: 	NULL,
 4942: 	NULL,
 4943: 	"SET SYSTEM PARAMETER",
 4944: 	"GET SYSTEM PARAMETER",
 4945: 	NULL,
 4946: 	"GET SCAM CONFIGURATION",
 4947: 	"SET SCAM CONFIGURATION",
 4948: 	"SET FIRMWARE FEATURES",
 4949: 	"GET FIRMWARE FEATURES",
 4950: 	NULL,
 4951: 	NULL,
 4952: 	NULL,
 4953: 	NULL,
 4954: 	"LOAD RAM A64",
 4955: 	"DUMP RAM A64",
 4956: 	"INITIALIZE REQUEST QUEUE A64",
 4957: 	"INITIALIZE RESPONSE QUEUE A64",
 4958: 	"EXECUTE IOCB A64",
 4959: 	"ENABLE TARGET MODE",
 4960: 	"GET TARGET MODE STATE",
 4961: 	NULL,
 4962: 	NULL,
 4963: 	NULL,
 4964: 	"SET DATA OVERRUN RECOVERY MODE",
 4965: 	"GET DATA OVERRUN RECOVERY MODE",
 4966: 	"SET HOST DATA",
 4967: 	"GET NOST DATA",
 4968: };
 4969: #endif
 4970: 
 4971: static u_int16_t mbpfc[] = {
 4972: 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
 4973: 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
 4974: 	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
 4975: 	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
 4976: 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
 4977: 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
 4978: 	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
 4979: 	ISPOPMAP(0x03, 0x05),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
 4980: 	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
 4981: 	ISPOPMAP(0xdf, 0x01),	/* 0x09: LOAD RAM */
 4982: 	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
 4983: 	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
 4984: 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
 4985: 	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
 4986: 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
 4987: 	ISPOPMAP(0x03, 0x07),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */
 4988: 	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
 4989: 	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
 4990: 	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
 4991: 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
 4992: 	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
 4993: 	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
 4994: 	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
 4995: 	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
 4996: 	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
 4997: 	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
 4998: 	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
 4999: 	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
 5000: 	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
 5001: 	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
 5002: 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
 5003: 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
 5004: 	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
 5005: 	ISPOPMAP(0x00, 0x00),	/* 0x21: */
 5006: 	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
 5007: 	ISPOPMAP(0x00, 0x00),	/* 0x23: */
 5008: 	ISPOPMAP(0x00, 0x00),	/* 0x24: */
 5009: 	ISPOPMAP(0x00, 0x00),	/* 0x25: */
 5010: 	ISPOPMAP(0x00, 0x00),	/* 0x26: */
 5011: 	ISPOPMAP(0x00, 0x00),	/* 0x27: */
 5012: 	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
 5013: 	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
 5014: 	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
 5015: 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
 5016: 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
 5017: 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
 5018: 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
 5019: 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
 5020: 	ISPOPMAP(0x00, 0x00),	/* 0x30: */
 5021: 	ISPOPMAP(0x00, 0x00),	/* 0x31: */
 5022: 	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
 5023: 	ISPOPMAP(0x00, 0x00),	/* 0x33: */
 5024: 	ISPOPMAP(0x00, 0x00),	/* 0x34: */
 5025: 	ISPOPMAP(0x00, 0x00),	/* 0x35: */
 5026: 	ISPOPMAP(0x00, 0x00),	/* 0x36: */
 5027: 	ISPOPMAP(0x00, 0x00),	/* 0x37: */
 5028: 	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
 5029: 	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
 5030: 	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
 5031: 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
 5032: 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
 5033: 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
 5034: 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
 5035: 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
 5036: 	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
 5037: 	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
 5038: 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNTS */
 5039: 	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_NON_PARTICIPATING_MODE */
 5040: 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
 5041: 	ISPOPMAP(0x00, 0x00),	/* 0x45: */
 5042: 	ISPOPMAP(0x00, 0x00),	/* 0x46: */
 5043: 	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
 5044: 	ISPOPMAP(0x00, 0x00),	/* 0x48: */
 5045: 	ISPOPMAP(0x00, 0x00),	/* 0x49: */
 5046: 	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
 5047: 	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
 5048: 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
 5049: 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
 5050: 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
 5051: 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
 5052: 	ISPOPMAP(0x00, 0x00),	/* 0x50: */
 5053: 	ISPOPMAP(0x00, 0x00),	/* 0x51: */
 5054: 	ISPOPMAP(0x00, 0x00),	/* 0x52: */
 5055: 	ISPOPMAP(0x00, 0x00),	/* 0x53: */
 5056: 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
 5057: 	ISPOPMAP(0x00, 0x00),	/* 0x55: */
 5058: 	ISPOPMAP(0x00, 0x00),	/* 0x56: */
 5059: 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
 5060: 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
 5061: 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
 5062: 	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
 5063: 	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
 5064: 	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
 5065: 	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
 5066: 	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
 5067: 	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
 5068: 	ISPOPMAP(0xfd, 0x31),	/* 0x60: MBOX_INIT_FIRMWARE */
 5069: 	ISPOPMAP(0x00, 0x00),	/* 0x61: */
 5070: 	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
 5071: 	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
 5072: 	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
 5073: 	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
 5074: 	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
 5075: 	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
 5076: 	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
 5077: 	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
 5078: 	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
 5079: 	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
 5080: 	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
 5081: 	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
 5082: 	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
 5083: 	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
 5084: 	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
 5085: 	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
 5086: 	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
 5087: 	ISPOPMAP(0x00, 0x00),	/* 0x73: */
 5088: 	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
 5089: 	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
 5090: 	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
 5091: 	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
 5092: 	ISPOPMAP(0x00, 0x00),	/* 0x78: */
 5093: 	ISPOPMAP(0x00, 0x00),	/* 0x79: */
 5094: 	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
 5095: 	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
 5096: 	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
 5097: 	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
 5098: 	ISPOPMAP(0x07, 0x01)	/* 0x7e: Lun RESET */
 5099: };
 5100: /*
 5101:  * Footnotes
 5102:  *
 5103:  * (1): this sets bits 21..16 in mailbox register #8, which we nominally 
 5104:  *	do not access at this time in the core driver. The caller is
 5105:  *	responsible for setting this register first (Gross!).
 5106:  */
 5107: 
 5108: #ifndef	ISP_STRIPPED
 5109: static char *fc_mbcmd_names[] = {
 5110: 	"NO-OP",
 5111: 	"LOAD RAM",
 5112: 	"EXEC FIRMWARE",
 5113: 	"DUMP RAM",
 5114: 	"WRITE RAM WORD",
 5115: 	"READ RAM WORD",
 5116: 	"MAILBOX REG TEST",
 5117: 	"VERIFY CHECKSUM",
 5118: 	"ABOUT FIRMWARE",
 5119: 	"LOAD RAM",
 5120: 	"DUMP RAM",
 5121: 	NULL,
 5122: 	NULL,
 5123: 	"READ RAM WORD EXTENDED",
 5124: 	"CHECK FIRMWARE",
 5125: 	NULL,
 5126: 	"INIT REQUEST QUEUE",
 5127: 	"INIT RESULT QUEUE",
 5128: 	"EXECUTE IOCB",
 5129: 	"WAKE UP",
 5130: 	"STOP FIRMWARE",
 5131: 	"ABORT",
 5132: 	"ABORT DEVICE",
 5133: 	"ABORT TARGET",
 5134: 	"BUS RESET",
 5135: 	"STOP QUEUE",
 5136: 	"START QUEUE",
 5137: 	"SINGLE STEP QUEUE",
 5138: 	"ABORT QUEUE",
 5139: 	"GET DEV QUEUE STATUS",
 5140: 	NULL,
 5141: 	"GET FIRMWARE STATUS",
 5142: 	"GET LOOP ID",
 5143: 	NULL,
 5144: 	"GET RETRY COUNT",
 5145: 	NULL,
 5146: 	NULL,
 5147: 	NULL,
 5148: 	NULL,
 5149: 	NULL,
 5150: 	"GET FIRMWARE OPTIONS",
 5151: 	"GET PORT QUEUE PARAMS",
 5152: 	NULL,
 5153: 	NULL,
 5154: 	NULL,
 5155: 	NULL,
 5156: 	NULL,
 5157: 	NULL,
 5158: 	NULL,
 5159: 	NULL,
 5160: 	"SET RETRY COUNT",
 5161: 	NULL,
 5162: 	NULL,
 5163: 	NULL,
 5164: 	NULL,
 5165: 	NULL,
 5166: 	"SET FIRMWARE OPTIONS",
 5167: 	"SET PORT QUEUE PARAMS",
 5168: 	NULL,
 5169: 	NULL,
 5170: 	NULL,
 5171: 	NULL,
 5172: 	NULL,
 5173: 	NULL,
 5174: 	"LOOP PORT BYPASS",
 5175: 	"LOOP PORT ENABLE",
 5176: 	"GET RESOURCE COUNTS",
 5177: 	"REQUEST NON PARTICIPATING MODE",
 5178: 	NULL,
 5179: 	NULL,
 5180: 	NULL,
 5181: 	"GET PORT DATABASE,, ENHANCED",
 5182: 	NULL,
 5183: 	NULL,
 5184: 	NULL,
 5185: 	NULL,
 5186: 	NULL,
 5187: 	NULL,
 5188: 	NULL,
 5189: 	NULL,
 5190: 	NULL,
 5191: 	NULL,
 5192: 	NULL,
 5193: 	NULL,
 5194: 	"EXECUTE IOCB A64",
 5195: 	NULL,
 5196: 	NULL,
 5197: 	NULL,
 5198: 	NULL,
 5199: 	NULL,
 5200: 	NULL,
 5201: 	NULL,
 5202: 	NULL,
 5203: 	"GET/SET DATA RATE",
 5204: 	NULL,
 5205: 	NULL,
 5206: 	"INIT FIRMWARE",
 5207: 	NULL,
 5208: 	"INIT LIP",
 5209: 	"GET FC-AL POSITION MAP",
 5210: 	"GET PORT DATABASE",
 5211: 	"CLEAR ACA",
 5212: 	"TARGET RESET",
 5213: 	"CLEAR TASK SET",
 5214: 	"ABORT TASK SET",
 5215: 	"GET FW STATE",
 5216: 	"GET PORT NAME",
 5217: 	"GET LINK STATUS",
 5218: 	"INIT LIP RESET",
 5219: 	NULL,
 5220: 	"SEND SNS",
 5221: 	"FABRIC LOGIN",
 5222: 	"SEND CHANGE REQUEST",
 5223: 	"FABRIC LOGOUT",
 5224: 	"INIT LIP LOGIN",
 5225: 	NULL,
 5226: 	"LOGIN LOOP PORT",
 5227: 	"GET PORT/NODE NAME LIST",
 5228: 	"SET VENDOR ID",
 5229: 	"INITIALIZE IP MAILBOX",
 5230: 	NULL,
 5231: 	NULL,
 5232: 	NULL,
 5233: 	NULL,
 5234: 	"Get ID List",
 5235: 	"SEND LFA",
 5236: 	"Lun RESET"
 5237: };
 5238: #endif
 5239: 
 5240: static void
 5241: isp_mboxcmd_qnw(struct ispsoftc *isp, mbreg_t *mbp, int nodelay)
 5242: {
 5243: 	unsigned int lim, ibits, obits, box, opcode;
 5244: 	u_int16_t *mcp;
 5245: 
 5246: 	if (IS_FC(isp)) {
 5247: 		mcp = mbpfc;
 5248: 		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
 5249: 	} else {
 5250: 		mcp = mbpscsi;
 5251: 		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
 5252: 	}
 5253: 	opcode = mbp->param[0];
 5254: 	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
 5255: 	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
 5256: 	for (box = 0; box < MAX_MAILBOX; box++) {
 5257: 		if (ibits & (1 << box)) {
 5258: 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
 5259: 		}
 5260: 		if (nodelay == 0) {
 5261: 			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
 5262: 		}
 5263: 	}
 5264: 	if (nodelay == 0) {
 5265: 		isp->isp_lastmbxcmd = opcode;
 5266: 		isp->isp_obits = obits;
 5267: 		isp->isp_mboxbsy = 1;
 5268: 	}
 5269: 	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
 5270: 	/*
 5271: 	 * Oddly enough, if we're not delaying for an answer,
 5272: 	 * delay a bit to give the f/w a chance to pick up the
 5273: 	 * command.
 5274: 	 */
 5275: 	if (nodelay) {
 5276: 		USEC_DELAY(1000);
 5277: 	}
 5278: }
 5279: 
 5280: static void
 5281: isp_mboxcmd(struct ispsoftc *isp, mbreg_t *mbp, int logmask)
 5282: {
 5283: 	char *cname, *xname, tname[16], mname[16];
 5284: 	unsigned int lim, ibits, obits, box, opcode;
 5285: 	u_int16_t *mcp;
 5286: 
 5287: 	if (IS_FC(isp)) {
 5288: 		mcp = mbpfc;
 5289: 		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
 5290: 	} else {
 5291: 		mcp = mbpscsi;
 5292: 		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
 5293: 	}
 5294: 
 5295: 	if ((opcode = mbp->param[0]) >= lim) {
 5296: 		mbp->param[0] = MBOX_INVALID_COMMAND;
 5297: 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
 5298: 		return;
 5299: 	}
 5300: 
 5301: 	ibits = HIBYT(mcp[opcode]) & NMBOX_BMASK(isp);
 5302: 	obits = LOBYT(mcp[opcode]) & NMBOX_BMASK(isp);
 5303: 
 5304: 	if (ibits == 0 && obits == 0) {
 5305: 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
 5306: 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
 5307: 		return;
 5308: 	}
 5309: 
 5310: 	/*
 5311: 	 * Get exclusive usage of mailbox registers.
 5312: 	 */
 5313: 	MBOX_ACQUIRE(isp);
 5314: 
 5315: 	for (box = 0; box < MAX_MAILBOX; box++) {
 5316: 		if (ibits & (1 << box)) {
 5317: 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
 5318: 		}
 5319: 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
 5320: 	}
 5321: 
 5322: 	isp->isp_lastmbxcmd = opcode;
 5323: 
 5324: 	/*
 5325: 	 * We assume that we can't overwrite a previous command.
 5326: 	 */
 5327: 	isp->isp_obits = obits;
 5328: 	isp->isp_mboxbsy = 1;
 5329: 
 5330: 	/*
 5331: 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
 5332: 	 */
 5333: 	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
 5334: 
 5335: 	/*
 5336: 	 * While we haven't finished the command, spin our wheels here.
 5337: 	 */
 5338: 	MBOX_WAIT_COMPLETE(isp);
 5339: 
 5340: 	if (isp->isp_mboxbsy) {
 5341: 		/*
 5342: 		 * Command timed out.
 5343: 		 */
 5344: 		isp->isp_mboxbsy = 0;
 5345: 		MBOX_RELEASE(isp);
 5346: 		return;
 5347: 	}
 5348: 
 5349: 	/*
 5350: 	 * Copy back output registers.
 5351: 	 */
 5352: 	for (box = 0; box < MAX_MAILBOX; box++) {
 5353: 		if (obits & (1 << box)) {
 5354: 			mbp->param[box] = isp->isp_mboxtmp[box];
 5355: 		}
 5356: 	}
 5357: 
 5358: 	MBOX_RELEASE(isp);
 5359: 
 5360: 	if (logmask == 0 || opcode == MBOX_EXEC_FIRMWARE) {
 5361: 		return;
 5362: 	}
 5363: #ifdef	ISP_STRIPPED
 5364: 	cname = NULL;
 5365: #else
 5366: 	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
 5367: #endif
 5368: 	if (cname == NULL) {
 5369: 		cname = tname;
 5370: 		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
 5371: 	}
 5372: 
 5373: 	/*
 5374: 	 * Just to be chatty here...
 5375: 	 */
 5376: 	xname = NULL;
 5377: 	switch (mbp->param[0]) {
 5378: 	case MBOX_COMMAND_COMPLETE:
 5379: 		break;
 5380: 	case MBOX_INVALID_COMMAND:
 5381: 		if (logmask & MBLOGMASK(MBOX_COMMAND_COMPLETE))
 5382: 			xname = "INVALID COMMAND";
 5383: 		break;
 5384: 	case MBOX_HOST_INTERFACE_ERROR:
 5385: 		if (logmask & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR))
 5386: 			xname = "HOST INTERFACE ERROR";
 5387: 		break;
 5388: 	case MBOX_TEST_FAILED:
 5389: 		if (logmask & MBLOGMASK(MBOX_TEST_FAILED))
 5390: 			xname = "TEST FAILED";
 5391: 		break;
 5392: 	case MBOX_COMMAND_ERROR:
 5393: 		if (logmask & MBLOGMASK(MBOX_COMMAND_ERROR))
 5394: 			xname = "COMMAND ERROR";
 5395: 		break;
 5396: 	case MBOX_COMMAND_PARAM_ERROR:
 5397: 		if (logmask & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR))
 5398: 			xname = "COMMAND PARAMETER ERROR";
 5399: 		break;
 5400: 	case MBOX_LOOP_ID_USED:
 5401: 		if (logmask & MBLOGMASK(MBOX_LOOP_ID_USED))
 5402: 			xname = "LOOP ID ALREADY IN USE";
 5403: 		break;
 5404: 	case MBOX_PORT_ID_USED:
 5405: 		if (logmask & MBLOGMASK(MBOX_PORT_ID_USED))
 5406: 			xname = "PORT ID ALREADY IN USE";
 5407: 		break;
 5408: 	case MBOX_ALL_IDS_USED:
 5409: 		if (logmask & MBLOGMASK(MBOX_ALL_IDS_USED))
 5410: 			xname = "ALL LOOP IDS IN USE";
 5411: 		break;
 5412: 	case 0:		/* special case */
 5413: 		xname = "TIMEOUT";
 5414: 		break;
 5415: 	default:
 5416: 		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
 5417: 		xname = mname;
 5418: 		break;
 5419: 	}
 5420: 	if (xname)
 5421: 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
 5422: 		    cname, xname);
 5423: }
 5424: 
 5425: static void
 5426: isp_fw_state(struct ispsoftc *isp)
 5427: {
 5428: 	if (IS_FC(isp)) {
 5429: 		mbreg_t mbs;
 5430: 		fcparam *fcp = isp->isp_param;
 5431: 
 5432: 		mbs.param[0] = MBOX_GET_FW_STATE;
 5433: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 5434: 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 5435: 			fcp->isp_fwstate = mbs.param[1];
 5436: 		}
 5437: 	}
 5438: }
 5439: 
 5440: static void
 5441: isp_update(struct ispsoftc *isp)
 5442: {
 5443: 	int bus, upmask;
 5444: 
 5445: 	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
 5446: 		if (upmask & (1 << bus)) {
 5447: 			isp_update_bus(isp, bus);
 5448: 		}
 5449: 		upmask &= ~(1 << bus);
 5450: 	}
 5451: }
 5452: 
 5453: static void
 5454: isp_update_bus(struct ispsoftc *isp, int bus)
 5455: {
 5456: 	int tgt;
 5457: 	mbreg_t mbs;
 5458: 	sdparam *sdp;
 5459: 
 5460: 	isp->isp_update &= ~(1 << bus);
 5461: 	if (IS_FC(isp)) {
 5462: 		/*
 5463: 		 * There are no 'per-bus' settings for Fibre Channel.
 5464: 		 */
 5465: 		return;
 5466: 	}
 5467: 	sdp = isp->isp_param;
 5468: 	sdp += bus;
 5469: 
 5470: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 5471: 		u_int16_t flags, period, offset;
 5472: 		int get;
 5473: 
 5474: 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
 5475: 			sdp->isp_devparam[tgt].dev_update = 0;
 5476: 			sdp->isp_devparam[tgt].dev_refresh = 0;
 5477: 			isp_prt(isp, ISP_LOGDEBUG0,
 5478: 	 		    "skipping target %d bus %d update", tgt, bus);
 5479: 			continue;
 5480: 		}
 5481: 		/*
 5482: 		 * If the goal is to update the status of the device,
 5483: 		 * take what's in goal_flags and try and set the device
 5484: 		 * toward that. Otherwise, if we're just refreshing the
 5485: 		 * current device state, get the current parameters.
 5486: 		 */
 5487: 
 5488: 		/*
 5489: 		 * Refresh overrides set
 5490: 		 */
 5491: 		if (sdp->isp_devparam[tgt].dev_refresh) {
 5492: 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
 5493: 			sdp->isp_devparam[tgt].dev_refresh = 0;
 5494: 			get = 1;
 5495: 		} else if (sdp->isp_devparam[tgt].dev_update) {
 5496: 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
 5497: 			/*
 5498: 			 * Make sure goal_flags has "Renegotiate on Error"
 5499: 			 * on and "Freeze Queue on Error" off.
 5500: 			 */
 5501: 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
 5502: 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
 5503: 
 5504: 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
 5505: 
 5506: 			/*
 5507: 			 * Insist that PARITY must be enabled
 5508: 			 * if SYNC or WIDE is enabled.
 5509: 			 */
 5510: 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
 5511: 				mbs.param[2] |= DPARM_PARITY;
 5512: 			}
 5513: 
 5514: 			if ((mbs.param[2] & DPARM_SYNC) == 0) {
 5515: 				mbs.param[3] = 0;
 5516: 			} else {
 5517: 				mbs.param[3] =
 5518: 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
 5519: 				    (sdp->isp_devparam[tgt].goal_period);
 5520: 			}
 5521: 			/*
 5522: 			 * A command completion later that has
 5523: 			 * RQSTF_NEGOTIATION set can cause
 5524: 			 * the dev_refresh/announce cycle also.
 5525: 			 *
 5526: 			 * Note: It is really important to update our current
 5527: 			 * flags with at least the state of TAG capabilities-
 5528: 			 * otherwise we might try and send a tagged command
 5529: 			 * when we have it all turned off. So change it here
 5530: 			 * to say that current already matches goal.
 5531: 			 */
 5532: 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
 5533: 			sdp->isp_devparam[tgt].actv_flags |=
 5534: 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
 5535: 			isp_prt(isp, ISP_LOGDEBUG0,
 5536: 			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
 5537: 			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
 5538: 			    mbs.param[3] & 0xff);
 5539: 			sdp->isp_devparam[tgt].dev_update = 0;
 5540: 			sdp->isp_devparam[tgt].dev_refresh = 1;
 5541: 			get = 0;
 5542: 		} else {
 5543: 			continue;
 5544: 		}
 5545: 		mbs.param[1] = (bus << 15) | (tgt << 8);
 5546: 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 5547: 		if (get == 0) {
 5548: 			isp->isp_sendmarker |= (1 << bus);
 5549: 			continue;
 5550: 		}
 5551: 		flags = mbs.param[2];
 5552: 		period = mbs.param[3] & 0xff;
 5553: 		offset = mbs.param[3] >> 8;
 5554: 		sdp->isp_devparam[tgt].actv_flags = flags;
 5555: 		sdp->isp_devparam[tgt].actv_period = period;
 5556: 		sdp->isp_devparam[tgt].actv_offset = offset;
 5557: 		get = (bus << 16) | tgt;
 5558: 		(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
 5559: 	}
 5560: 
 5561: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 5562: 		if (sdp->isp_devparam[tgt].dev_update ||
 5563: 		    sdp->isp_devparam[tgt].dev_refresh) {
 5564: 			isp->isp_update |= (1 << bus);
 5565: 			break;
 5566: 		}
 5567: 	}
 5568: }
 5569: 
 5570: #ifndef	DEFAULT_FRAMESIZE
 5571: #define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
 5572: #endif
 5573: #ifndef	DEFAULT_EXEC_THROTTLE
 5574: #define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
 5575: #endif
 5576: 
 5577: static void
 5578: isp_setdfltparm(struct ispsoftc *isp, int channel)
 5579: {
 5580: 	int tgt;
 5581: 	mbreg_t mbs;
 5582: 	sdparam *sdp;
 5583: 
 5584: 	if (IS_FC(isp)) {
 5585: 		fcparam *fcp = (fcparam *) isp->isp_param;
 5586: 		int nvfail;
 5587: 
 5588: 		fcp += channel;
 5589: 		if (fcp->isp_gotdparms) {
 5590: 			return;
 5591: 		}
 5592: 		fcp->isp_gotdparms = 1;
 5593: 		fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
 5594: 		fcp->isp_maxalloc = ICB_DFLT_ALLOC;
 5595: 		fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
 5596: 		fcp->isp_retry_delay = ICB_DFLT_RDELAY;
 5597: 		fcp->isp_retry_count = ICB_DFLT_RCOUNT;
 5598: 		/* Platform specific.... */
 5599: 		fcp->isp_loopid = DEFAULT_LOOPID(isp);
 5600: 		fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
 5601: 		fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
 5602: 		fcp->isp_fwoptions = 0;
 5603: 		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
 5604: 		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
 5605: 		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
 5606: #ifndef	ISP_NO_FASTPOST_FC
 5607: 		fcp->isp_fwoptions |= ICBOPT_FAST_POST;
 5608: #endif
 5609: 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
 5610: 			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
 5611: 
 5612: 		/*
 5613: 		 * Make sure this is turned off now until we get
 5614: 		 * extended options from NVRAM
 5615: 		 */
 5616: 		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
 5617: 
 5618: 		/*
 5619: 		 * Now try and read NVRAM unless told to not do so.
 5620: 		 * This will set fcparam's isp_nodewwn && isp_portwwn.
 5621: 		 */
 5622: 		if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
 5623: 		    	nvfail = isp_read_nvram(isp);
 5624: 			if (nvfail)
 5625: 				isp->isp_confopts |= ISP_CFG_NONVRAM;
 5626: 		} else {
 5627: 			nvfail = 1;
 5628: 		}
 5629: 		/*
 5630: 		 * Set node && port to override platform set defaults
 5631: 		 * unless the nvram read failed (or none was done),
 5632: 		 * or the platform code wants to use what had been
 5633: 		 * set in the defaults.
 5634: 		 */
 5635: 		if (nvfail) {
 5636: 			isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
 5637: 		}
 5638: 		if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
 5639: 			isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
 5640: 			    (u_int32_t) (DEFAULT_NODEWWN(isp) >> 32),
 5641: 			    (u_int32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
 5642: 			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
 5643: 		} else {
 5644: 			/*
 5645: 			 * We always start out with values derived
 5646: 			 * from NVRAM or our platform default.
 5647: 			 */
 5648: 			ISP_NODEWWN(isp) = fcp->isp_nodewwn;
 5649: 		}
 5650: 		if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
 5651: 			isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
 5652: 			    (u_int32_t) (DEFAULT_PORTWWN(isp) >> 32),
 5653: 			    (u_int32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
 5654: 			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
 5655: 		} else {
 5656: 			/*
 5657: 			 * We always start out with values derived
 5658: 			 * from NVRAM or our platform default.
 5659: 			 */
 5660: 			ISP_PORTWWN(isp) = fcp->isp_portwwn;
 5661: 		}
 5662: 		return;
 5663: 	}
 5664: 
 5665: 	sdp = (sdparam *) isp->isp_param;
 5666: 	sdp += channel;
 5667: 
 5668: 	/*
 5669: 	 * Been there, done that, got the T-shirt...
 5670: 	 */
 5671: 	if (sdp->isp_gotdparms) {
 5672: 		return;
 5673: 	}
 5674: 	sdp->isp_gotdparms = 1;
 5675: 
 5676: 	/*
 5677: 	 * Establish some default parameters.
 5678: 	 */
 5679: 	sdp->isp_cmd_dma_burst_enable = 0;
 5680: 	sdp->isp_data_dma_burst_enabl = 1;
 5681: 	sdp->isp_fifo_threshold = 0;
 5682: 	sdp->isp_initiator_id = DEFAULT_IID(isp);
 5683: 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
 5684: 		sdp->isp_async_data_setup = 9;
 5685: 	} else {
 5686: 		sdp->isp_async_data_setup = 6;
 5687: 	}
 5688: 	sdp->isp_selection_timeout = 250;
 5689: 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
 5690: 	sdp->isp_tag_aging = 8;
 5691: 	sdp->isp_bus_reset_delay = 5;
 5692: 	/*
 5693: 	 * Don't retry selection, busy or queue full automatically- reflect
 5694: 	 * these back to us.
 5695: 	 */
 5696: 	sdp->isp_retry_count = 0;
 5697: 	sdp->isp_retry_delay = 0;
 5698: 
 5699: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 5700: 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
 5701: 		sdp->isp_devparam[tgt].dev_enable = 1;
 5702: 	}
 5703: 
 5704: 	/*
 5705: 	 * If we've not been told to avoid reading NVRAM, try and read it.
 5706: 	 * If we're successful reading it, we can then return because NVRAM
 5707: 	 * will tell us what the desired settings are. Otherwise, we establish
 5708: 	 * some reasonable 'fake' nvram and goal defaults.
 5709: 	 */
 5710: 
 5711: 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
 5712: 		if (isp_read_nvram(isp) == 0) {
 5713: 			return;
 5714: 		}
 5715: 	}
 5716: 
 5717: 	/*
 5718: 	 * Now try and see whether we have specific values for them.
 5719: 	 */
 5720: 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
 5721: 		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
 5722: 		isp_mboxcmd(isp, &mbs, MBLOGNONE);
 5723: 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 5724: 			sdp->isp_req_ack_active_neg = 1;
 5725: 			sdp->isp_data_line_active_neg = 1;
 5726: 		} else {
 5727: 			sdp->isp_req_ack_active_neg =
 5728: 			    (mbs.param[1+channel] >> 4) & 0x1;
 5729: 			sdp->isp_data_line_active_neg =
 5730: 			    (mbs.param[1+channel] >> 5) & 0x1;
 5731: 		}
 5732: 	}
 5733: 
 5734: 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
 5735: 	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
 5736: 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
 5737: 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
 5738: 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
 5739: 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
 5740: 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
 5741: 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
 5742: 
 5743: 	/*
 5744: 	 * The trick here is to establish a default for the default (honk!)
 5745: 	 * state (goal_flags). Then try and get the current status from
 5746: 	 * the card to fill in the current state. We don't, in fact, set
 5747: 	 * the default to the SAFE default state- that's not the goal state.
 5748: 	 */
 5749: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 5750: 		u_int8_t off, per;
 5751: 		sdp->isp_devparam[tgt].actv_offset = 0;
 5752: 		sdp->isp_devparam[tgt].actv_period = 0;
 5753: 		sdp->isp_devparam[tgt].actv_flags = 0;
 5754: 
 5755: 		sdp->isp_devparam[tgt].goal_flags =
 5756: 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
 5757: 
 5758: 		/*
 5759: 		 * We default to Wide/Fast for versions less than a 1040
 5760: 		 * (unless it's SBus).
 5761: 		 */
 5762: 		if (IS_ULTRA3(isp)) {
 5763: 			off = ISP_80M_SYNCPARMS >> 8;
 5764: 			per = ISP_80M_SYNCPARMS & 0xff;
 5765: 		} else if (IS_ULTRA2(isp)) {
 5766: 			off = ISP_40M_SYNCPARMS >> 8;
 5767: 			per = ISP_40M_SYNCPARMS & 0xff;
 5768: 		} else if (IS_1240(isp)) {
 5769: 			off = ISP_20M_SYNCPARMS >> 8;
 5770: 			per = ISP_20M_SYNCPARMS & 0xff;
 5771: 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
 5772: 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
 5773: 		    (isp->isp_bustype == ISP_BT_PCI &&
 5774: 		    isp->isp_type < ISP_HA_SCSI_1040) ||
 5775: 		    (isp->isp_clock && isp->isp_clock < 60) ||
 5776: 		    (sdp->isp_ultramode == 0)) {
 5777: 			off = ISP_10M_SYNCPARMS >> 8;
 5778: 			per = ISP_10M_SYNCPARMS & 0xff;
 5779: 		} else {
 5780: 			off = ISP_20M_SYNCPARMS_1040 >> 8;
 5781: 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
 5782: 		}
 5783: 		sdp->isp_devparam[tgt].goal_offset =
 5784: 		    sdp->isp_devparam[tgt].nvrm_offset = off;
 5785: 		sdp->isp_devparam[tgt].goal_period =
 5786: 		    sdp->isp_devparam[tgt].nvrm_period = per;
 5787: 
 5788: 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
 5789: 		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
 5790: 		    sdp->isp_devparam[tgt].nvrm_offset,
 5791: 		    sdp->isp_devparam[tgt].nvrm_period);
 5792: 	}
 5793: }
 5794: 
 5795: /*
 5796:  * Re-initialize the ISP and complete all orphaned commands
 5797:  * with a 'botched' notice. The reset/init routines should
 5798:  * not disturb an already active list of commands.
 5799:  *
 5800:  * Locks held prior to coming here.
 5801:  */
 5802: 
 5803: void
 5804: isp_reinit(struct ispsoftc *isp)
 5805: {
 5806: 	XS_T *xs;
 5807: 	u_int16_t handle;
 5808: 
 5809: 	isp_reset(isp);
 5810: 	if (isp->isp_state != ISP_RESETSTATE) {
 5811: 		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
 5812: 	} else if (isp->isp_role != ISP_ROLE_NONE) {
 5813: 		isp_init(isp);
 5814: 		if (isp->isp_state == ISP_INITSTATE) {
 5815: 			isp->isp_state = ISP_RUNSTATE;
 5816: 		}
 5817: 		if (isp->isp_state != ISP_RUNSTATE) {
 5818: 			isp_prt(isp, ISP_LOGERR,
 5819: 			    "isp_reinit cannot restart card");
 5820: 		}
 5821: 	}
 5822: 	isp->isp_nactive = 0;
 5823: 
 5824: 	for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
 5825: 		xs = isp_find_xs(isp, handle);
 5826: 		if (xs == NULL) {
 5827: 			continue;
 5828: 		}
 5829: 		isp_destroy_handle(isp, handle);
 5830: 		if (XS_XFRLEN(xs)) {
 5831: 			ISP_DMAFREE(isp, xs, handle);
 5832: 			XS_RESID(xs) = XS_XFRLEN(xs);
 5833: 		} else {
 5834: 			XS_RESID(xs) = 0;
 5835: 		}
 5836: 		XS_SETERR(xs, HBA_BUSRESET);
 5837: 		isp_done(xs);
 5838: 	}
 5839: }
 5840: 
 5841: /*
 5842:  * NVRAM Routines
 5843:  */
 5844: static int
 5845: isp_read_nvram(struct ispsoftc *isp)
 5846: {
 5847: 	int i, amt;
 5848: 	u_int8_t csum, minversion;
 5849: 	union {
 5850: 		u_int8_t _x[ISP2100_NVRAM_SIZE];
 5851: 		u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
 5852: 	} _n;
 5853: #define	nvram_data	_n._x
 5854: #define	nvram_words	_n._s
 5855: 
 5856: 	if (IS_FC(isp)) {
 5857: 		amt = ISP2100_NVRAM_SIZE;
 5858: 		minversion = 1;
 5859: 	} else if (IS_ULTRA2(isp)) {
 5860: 		amt = ISP1080_NVRAM_SIZE;
 5861: 		minversion = 0;
 5862: 	} else {
 5863: 		amt = ISP_NVRAM_SIZE;
 5864: 		minversion = 2;
 5865: 	}
 5866: 
 5867: 	/*
 5868: 	 * Just read the first two words first to see if we have a valid
 5869: 	 * NVRAM to continue reading the rest with.
 5870: 	 */
 5871: 	for (i = 0; i < 2; i++) {
 5872: 		isp_rdnvram_word(isp, i, &nvram_words[i]);
 5873: 	}
 5874: 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
 5875: 	    nvram_data[2] != 'P') {
 5876: 		if (isp->isp_bustype != ISP_BT_SBUS) {
 5877: 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
 5878: 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
 5879: 			    nvram_data[0], nvram_data[1], nvram_data[2]);
 5880: 		}
 5881: 		return (-1);
 5882: 	}
 5883: 	for (i = 2; i < amt>>1; i++) {
 5884: 		isp_rdnvram_word(isp, i, &nvram_words[i]);
 5885: 	}
 5886: 	for (csum = 0, i = 0; i < amt; i++) {
 5887: 		csum += nvram_data[i];
 5888: 	}
 5889: 	if (csum != 0) {
 5890: 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
 5891: 		return (-1);
 5892: 	}
 5893: 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
 5894: 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
 5895: 		    ISP_NVRAM_VERSION(nvram_data));
 5896: 		return (-1);
 5897: 	}
 5898: 
 5899: 	if (IS_ULTRA3(isp)) {
 5900: 		isp_parse_nvram_12160(isp, 0, nvram_data);
 5901: 		if (IS_12160(isp))
 5902: 			isp_parse_nvram_12160(isp, 1, nvram_data);
 5903: 	} else if (IS_1080(isp)) {
 5904: 		isp_parse_nvram_1080(isp, 0, nvram_data);
 5905: 	} else if (IS_1280(isp) || IS_1240(isp)) {
 5906: 		isp_parse_nvram_1080(isp, 0, nvram_data);
 5907: 		isp_parse_nvram_1080(isp, 1, nvram_data);
 5908: 	} else if (IS_SCSI(isp)) {
 5909: 		isp_parse_nvram_1020(isp, nvram_data);
 5910: 	} else {
 5911: 		isp_parse_nvram_2100(isp, nvram_data);
 5912: 	}
 5913: 	return (0);
 5914: #undef	nvram_data
 5915: #undef	nvram_words
 5916: }
 5917: 
 5918: static void
 5919: isp_rdnvram_word(struct ispsoftc *isp, int wo, u_int16_t *rp)
 5920: {
 5921: 	int i, cbits;
 5922: 	u_int16_t bit, rqst;
 5923: 
 5924: 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
 5925: 	USEC_DELAY(2);
 5926: 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
 5927: 	USEC_DELAY(2);
 5928: 
 5929: 	if (IS_FC(isp)) {
 5930: 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
 5931: 		if (IS_2312(isp) && isp->isp_port) {
 5932: 			wo += 128;
 5933: 		}
 5934: 		rqst = (ISP_NVRAM_READ << 8) | wo;
 5935: 		cbits = 10;
 5936: 	} else if (IS_ULTRA2(isp)) {
 5937: 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
 5938: 		rqst = (ISP_NVRAM_READ << 8) | wo;
 5939: 		cbits = 10;
 5940: 	} else {
 5941: 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
 5942: 		rqst = (ISP_NVRAM_READ << 6) | wo;
 5943: 		cbits = 8;
 5944: 	}
 5945: 
 5946: 	/*
 5947: 	 * Clock the word select request out...
 5948: 	 */
 5949: 	for (i = cbits; i >= 0; i--) {
 5950: 		if ((rqst >> i) & 1) {
 5951: 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
 5952: 		} else {
 5953: 			bit = BIU_NVRAM_SELECT;
 5954: 		}
 5955: 		ISP_WRITE(isp, BIU_NVRAM, bit);
 5956: 		USEC_DELAY(2);
 5957: 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
 5958: 		USEC_DELAY(2);
 5959: 		ISP_WRITE(isp, BIU_NVRAM, bit);
 5960: 		USEC_DELAY(2);
 5961: 	}
 5962: 	/*
 5963: 	 * Now read the result back in (bits come back in MSB format).
 5964: 	 */
 5965: 	*rp = 0;
 5966: 	for (i = 0; i < 16; i++) {
 5967: 		u_int16_t rv;
 5968: 		*rp <<= 1;
 5969: 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
 5970: 		USEC_DELAY(2);
 5971: 		rv = ISP_READ(isp, BIU_NVRAM);
 5972: 		if (rv & BIU_NVRAM_DATAIN) {
 5973: 			*rp |= 1;
 5974: 		}
 5975: 		USEC_DELAY(2);
 5976: 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
 5977: 		USEC_DELAY(2);
 5978: 	}
 5979: 	ISP_WRITE(isp, BIU_NVRAM, 0);
 5980: 	USEC_DELAY(2);
 5981: 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
 5982: }
 5983: 
 5984: static void
 5985: isp_parse_nvram_1020(struct ispsoftc *isp, u_int8_t *nvram_data)
 5986: {
 5987: 	sdparam *sdp = (sdparam *) isp->isp_param;
 5988: 	int tgt;
 5989: 
 5990: 	sdp->isp_fifo_threshold =
 5991: 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
 5992: 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
 5993: 
 5994: 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 5995: 		sdp->isp_initiator_id =
 5996: 			ISP_NVRAM_INITIATOR_ID(nvram_data);
 5997: 
 5998: 	sdp->isp_bus_reset_delay =
 5999: 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
 6000: 
 6001: 	sdp->isp_retry_count =
 6002: 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
 6003: 
 6004: 	sdp->isp_retry_delay =
 6005: 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
 6006: 
 6007: 	sdp->isp_async_data_setup =
 6008: 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
 6009: 
 6010: 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
 6011: 		if (sdp->isp_async_data_setup < 9) {
 6012: 			sdp->isp_async_data_setup = 9;
 6013: 		}
 6014: 	} else {
 6015: 		if (sdp->isp_async_data_setup != 6) {
 6016: 			sdp->isp_async_data_setup = 6;
 6017: 		}
 6018: 	}
 6019: 
 6020: 	sdp->isp_req_ack_active_neg =
 6021: 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
 6022: 
 6023: 	sdp->isp_data_line_active_neg =
 6024: 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
 6025: 
 6026: 	sdp->isp_data_dma_burst_enabl =
 6027: 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
 6028: 
 6029: 	sdp->isp_cmd_dma_burst_enable =
 6030: 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
 6031: 
 6032: 	sdp->isp_tag_aging =
 6033: 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
 6034: 
 6035: 	sdp->isp_selection_timeout =
 6036: 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
 6037: 
 6038: 	sdp->isp_max_queue_depth =
 6039: 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
 6040: 
 6041: 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
 6042: 
 6043: 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
 6044: 	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
 6045: 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
 6046: 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
 6047: 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
 6048: 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
 6049: 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
 6050: 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
 6051: 
 6052: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 6053: 		sdp->isp_devparam[tgt].dev_enable =
 6054: 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
 6055: 		sdp->isp_devparam[tgt].exc_throttle =
 6056: 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
 6057: 		sdp->isp_devparam[tgt].nvrm_offset =
 6058: 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
 6059: 		sdp->isp_devparam[tgt].nvrm_period =
 6060: 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
 6061: 		/*
 6062: 		 * We probably shouldn't lie about this, but it
 6063: 		 * it makes it much safer if we limit NVRAM values
 6064: 		 * to sanity.
 6065: 		 */
 6066: 		if (isp->isp_type < ISP_HA_SCSI_1040) {
 6067: 			/*
 6068: 			 * If we're not ultra, we can't possibly
 6069: 			 * be a shorter period than this.
 6070: 			 */
 6071: 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
 6072: 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
 6073: 			}
 6074: 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
 6075: 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
 6076: 			}
 6077: 		} else {
 6078: 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
 6079: 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
 6080: 			}
 6081: 		}
 6082: 		sdp->isp_devparam[tgt].nvrm_flags = 0;
 6083: 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
 6084: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
 6085: 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
 6086: 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
 6087: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
 6088: 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
 6089: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
 6090: 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
 6091: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
 6092: 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
 6093: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
 6094: 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
 6095: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
 6096: 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
 6097: 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
 6098: 		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
 6099: 		    sdp->isp_devparam[tgt].nvrm_offset,
 6100: 		    sdp->isp_devparam[tgt].nvrm_period);
 6101: 		sdp->isp_devparam[tgt].goal_offset =
 6102: 		    sdp->isp_devparam[tgt].nvrm_offset;
 6103: 		sdp->isp_devparam[tgt].goal_period =
 6104: 		    sdp->isp_devparam[tgt].nvrm_period;
 6105: 		sdp->isp_devparam[tgt].goal_flags =
 6106: 		    sdp->isp_devparam[tgt].nvrm_flags;
 6107: 	}
 6108: }
 6109: 
 6110: static void
 6111: isp_parse_nvram_1080(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
 6112: {
 6113: 	sdparam *sdp = (sdparam *) isp->isp_param;
 6114: 	int tgt;
 6115: 
 6116: 	sdp += bus;
 6117: 
 6118: 	sdp->isp_fifo_threshold =
 6119: 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
 6120: 
 6121: 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 6122: 		sdp->isp_initiator_id =
 6123: 		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
 6124: 
 6125: 	sdp->isp_bus_reset_delay =
 6126: 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
 6127: 
 6128: 	sdp->isp_retry_count =
 6129: 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
 6130: 
 6131: 	sdp->isp_retry_delay =
 6132: 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
 6133: 
 6134: 	sdp->isp_async_data_setup =
 6135: 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
 6136: 
 6137: 	sdp->isp_req_ack_active_neg =
 6138: 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
 6139: 
 6140: 	sdp->isp_data_line_active_neg =
 6141: 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
 6142: 
 6143: 	sdp->isp_data_dma_burst_enabl =
 6144: 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
 6145: 
 6146: 	sdp->isp_cmd_dma_burst_enable =
 6147: 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
 6148: 
 6149: 	sdp->isp_selection_timeout =
 6150: 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
 6151: 
 6152: 	sdp->isp_max_queue_depth =
 6153: 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
 6154: 
 6155: 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
 6156: 	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
 6157: 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
 6158: 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
 6159: 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
 6160: 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
 6161: 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
 6162: 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
 6163: 
 6164: 
 6165: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 6166: 		sdp->isp_devparam[tgt].dev_enable =
 6167: 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
 6168: 		sdp->isp_devparam[tgt].exc_throttle =
 6169: 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
 6170: 		sdp->isp_devparam[tgt].nvrm_offset =
 6171: 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
 6172: 		sdp->isp_devparam[tgt].nvrm_period =
 6173: 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
 6174: 		sdp->isp_devparam[tgt].nvrm_flags = 0;
 6175: 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
 6176: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
 6177: 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
 6178: 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
 6179: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
 6180: 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
 6181: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
 6182: 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
 6183: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
 6184: 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
 6185: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
 6186: 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
 6187: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
 6188: 		sdp->isp_devparam[tgt].actv_flags = 0;
 6189: 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
 6190: 		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
 6191: 		    sdp->isp_devparam[tgt].nvrm_offset,
 6192: 		    sdp->isp_devparam[tgt].nvrm_period);
 6193: 		sdp->isp_devparam[tgt].goal_offset =
 6194: 		    sdp->isp_devparam[tgt].nvrm_offset;
 6195: 		sdp->isp_devparam[tgt].goal_period =
 6196: 		    sdp->isp_devparam[tgt].nvrm_period;
 6197: 		sdp->isp_devparam[tgt].goal_flags =
 6198: 		    sdp->isp_devparam[tgt].nvrm_flags;
 6199: 	}
 6200: }
 6201: 
 6202: static void
 6203: isp_parse_nvram_12160(struct ispsoftc *isp, int bus, u_int8_t *nvram_data)
 6204: {
 6205: 	sdparam *sdp = (sdparam *) isp->isp_param;
 6206: 	int tgt;
 6207: 
 6208: 	sdp += bus;
 6209: 
 6210: 	sdp->isp_fifo_threshold =
 6211: 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
 6212: 
 6213: 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 6214: 		sdp->isp_initiator_id =
 6215: 		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
 6216: 
 6217: 	sdp->isp_bus_reset_delay =
 6218: 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
 6219: 
 6220: 	sdp->isp_retry_count =
 6221: 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
 6222: 
 6223: 	sdp->isp_retry_delay =
 6224: 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
 6225: 
 6226: 	sdp->isp_async_data_setup =
 6227: 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
 6228: 
 6229: 	sdp->isp_req_ack_active_neg =
 6230: 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
 6231: 
 6232: 	sdp->isp_data_line_active_neg =
 6233: 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
 6234: 
 6235: 	sdp->isp_data_dma_burst_enabl =
 6236: 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
 6237: 
 6238: 	sdp->isp_cmd_dma_burst_enable =
 6239: 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
 6240: 
 6241: 	sdp->isp_selection_timeout =
 6242: 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
 6243: 
 6244: 	sdp->isp_max_queue_depth =
 6245: 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
 6246: 
 6247: 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
 6248: 	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
 6249: 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
 6250: 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
 6251: 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
 6252: 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
 6253: 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
 6254: 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
 6255: 
 6256: 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
 6257: 		sdp->isp_devparam[tgt].dev_enable =
 6258: 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
 6259: 		sdp->isp_devparam[tgt].exc_throttle =
 6260: 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
 6261: 		sdp->isp_devparam[tgt].nvrm_offset =
 6262: 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
 6263: 		sdp->isp_devparam[tgt].nvrm_period =
 6264: 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
 6265: 		sdp->isp_devparam[tgt].nvrm_flags = 0;
 6266: 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
 6267: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
 6268: 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
 6269: 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
 6270: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
 6271: 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
 6272: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
 6273: 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
 6274: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
 6275: 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
 6276: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
 6277: 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
 6278: 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
 6279: 		sdp->isp_devparam[tgt].actv_flags = 0;
 6280: 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
 6281: 		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
 6282: 		    sdp->isp_devparam[tgt].nvrm_offset,
 6283: 		    sdp->isp_devparam[tgt].nvrm_period);
 6284: 		sdp->isp_devparam[tgt].goal_offset =
 6285: 		    sdp->isp_devparam[tgt].nvrm_offset;
 6286: 		sdp->isp_devparam[tgt].goal_period =
 6287: 		    sdp->isp_devparam[tgt].nvrm_period;
 6288: 		sdp->isp_devparam[tgt].goal_flags =
 6289: 		    sdp->isp_devparam[tgt].nvrm_flags;
 6290: 	}
 6291: }
 6292: 
 6293: static void
 6294: isp_parse_nvram_2100(struct ispsoftc *isp, u_int8_t *nvram_data)
 6295: {
 6296: 	fcparam *fcp = (fcparam *) isp->isp_param;
 6297: 	u_int64_t wwn;
 6298: 
 6299: 	/*
 6300: 	 * There is NVRAM storage for both Port and Node entities-
 6301: 	 * but the Node entity appears to be unused on all the cards
 6302: 	 * I can find. However, we should account for this being set
 6303: 	 * at some point in the future.
 6304: 	 *
 6305: 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
 6306: 	 * bits 48..60. In the case of the 2202, it appears that they do
 6307: 	 * use bit 48 to distinguish between the two instances on the card.
 6308: 	 * The 2204, which I've never seen, *probably* extends this method.
 6309: 	 */
 6310: 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
 6311: 	if (wwn) {
 6312: 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
 6313: 		    (u_int32_t) (wwn >> 32), (u_int32_t) (wwn & 0xffffffff));
 6314: 		if ((wwn >> 60) == 0) {
 6315: 			wwn |= (((u_int64_t) 2)<< 60);
 6316: 		}
 6317: 	}
 6318: 	fcp->isp_portwwn = wwn;
 6319: 	if (IS_2200(isp) || IS_23XX(isp)) {
 6320: 		wwn = ISP2200_NVRAM_NODE_NAME(nvram_data);
 6321: 		if (wwn) {
 6322: 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
 6323: 			    (u_int32_t) (wwn >> 32),
 6324: 			    (u_int32_t) (wwn & 0xffffffff));
 6325: 			if ((wwn >> 60) == 0) {
 6326: 				wwn |= (((u_int64_t) 2)<< 60);
 6327: 			}
 6328: 		}
 6329: 	} else {
 6330: 		wwn &= ~((u_int64_t) 0xfff << 48);
 6331: 	}
 6332: 	fcp->isp_nodewwn = wwn;
 6333: 
 6334: 	/*
 6335: 	 * Make sure we have both Node and Port as non-zero values.
 6336: 	 */
 6337: 	if (fcp->isp_nodewwn != 0 && fcp->isp_portwwn == 0) {
 6338: 		fcp->isp_portwwn = fcp->isp_nodewwn;
 6339: 	} else if (fcp->isp_nodewwn == 0 && fcp->isp_portwwn != 0) {
 6340: 		fcp->isp_nodewwn = fcp->isp_portwwn;
 6341: 	}
 6342: 
 6343: 	/*
 6344: 	 * Make the Node and Port values sane if they're NAA == 2.
 6345: 	 * This means to clear bits 48..56 for the Node WWN and
 6346: 	 * make sure that there's some non-zero value in 48..56
 6347: 	 * for the Port WWN.
 6348: 	 */
 6349: 	if (fcp->isp_nodewwn && fcp->isp_portwwn) {
 6350: 		if ((fcp->isp_nodewwn & (((u_int64_t) 0xfff) << 48)) != 0 &&
 6351: 		    (fcp->isp_nodewwn >> 60) == 2) {
 6352: 			fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
 6353: 		}
 6354: 		if ((fcp->isp_portwwn & (((u_int64_t) 0xfff) << 48)) == 0 &&
 6355: 		    (fcp->isp_portwwn >> 60) == 2) {
 6356: 			fcp->isp_portwwn |= ((u_int64_t) 1 << 56);
 6357: 		}
 6358: 	}
 6359: 
 6360: 	isp_prt(isp, ISP_LOGDEBUG0,
 6361: 	    "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x",
 6362: 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data),
 6363: 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
 6364: 	    ISP2100_NVRAM_OPTIONS(nvram_data),
 6365: 	    ISP2100_NVRAM_HARDLOOPID(nvram_data));
 6366: 
 6367: 	fcp->isp_maxalloc =
 6368: 		ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
 6369: 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0)
 6370: 		fcp->isp_maxfrmlen =
 6371: 			ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
 6372: 	fcp->isp_retry_delay =
 6373: 		ISP2100_NVRAM_RETRY_DELAY(nvram_data);
 6374: 	fcp->isp_retry_count =
 6375: 		ISP2100_NVRAM_RETRY_COUNT(nvram_data);
 6376: 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
 6377: 		fcp->isp_loopid =
 6378: 			ISP2100_NVRAM_HARDLOOPID(nvram_data);
 6379: 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0)
 6380: 		fcp->isp_execthrottle =
 6381: 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
 6382: 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
 6383: }
 6384: 
 6385: #ifdef	ISP_FW_CRASH_DUMP
 6386: static void isp2200_fw_dump(struct ispsoftc *);
 6387: static void isp2300_fw_dump(struct ispsoftc *);
 6388: 
 6389: static void
 6390: isp2200_fw_dump(struct ispsoftc *isp)
 6391: {
 6392: 	int i, j;
 6393: 	mbreg_t mbs;
 6394: 	u_int16_t *ptr;
 6395: 
 6396: 	ptr = FCPARAM(isp)->isp_dump_data;
 6397: 	if (ptr == NULL) {
 6398: 		isp_prt(isp, ISP_LOGERR,
 6399: 		   "No place to dump RISC registers and SRAM");
 6400: 		return;
 6401: 	}
 6402: 	if (*ptr++) {
 6403: 		isp_prt(isp, ISP_LOGERR,
 6404: 		   "dump area for RISC registers and SRAM already used");
 6405: 		return;
 6406: 	}
 6407: 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
 6408: 	for (i = 0; i < 100; i++) {
 6409: 		USEC_DELAY(100);
 6410: 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
 6411: 			break;
 6412: 		}
 6413: 	}
 6414: 	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
 6415: 		/*
 6416: 		 * PBIU Registers
 6417: 		 */
 6418: 		for (i = 0; i < 8; i++) {
 6419: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
 6420: 		}
 6421: 
 6422: 		/*
 6423: 		 * Mailbox Registers
 6424: 		 */
 6425: 		for (i = 0; i < 8; i++) {
 6426: 			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
 6427: 		}
 6428: 
 6429: 		/*
 6430: 		 * DMA Registers
 6431: 		 */
 6432: 		for (i = 0; i < 48; i++) {
 6433: 			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
 6434: 		}
 6435: 
 6436: 		/*
 6437: 		 * RISC H/W Registers
 6438: 		 */
 6439: 		ISP_WRITE(isp, BIU2100_CSR, 0);
 6440: 		for (i = 0; i < 16; i++) {
 6441: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
 6442: 		}
 6443: 
 6444: 		/*
 6445: 		 * RISC GP Registers
 6446: 		 */
 6447: 		for (j = 0; j < 8; j++) {
 6448: 			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
 6449: 			for (i = 0; i < 16; i++) {
 6450: 				*ptr++ =
 6451: 				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6452: 			}
 6453: 		}
 6454: 
 6455: 		/*
 6456: 		 * Frame Buffer Hardware Registers
 6457: 		 */
 6458: 		ISP_WRITE(isp, BIU2100_CSR, 0x10);
 6459: 		for (i = 0; i < 16; i++) {
 6460: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6461: 		}
 6462: 
 6463: 		/*
 6464: 		 * Fibre Protocol Module 0 Hardware Registers
 6465: 		 */
 6466: 		ISP_WRITE(isp, BIU2100_CSR, 0x20);
 6467: 		for (i = 0; i < 64; i++) {
 6468: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6469: 		}
 6470: 
 6471: 		/*
 6472: 		 * Fibre Protocol Module 1 Hardware Registers
 6473: 		 */
 6474: 		ISP_WRITE(isp, BIU2100_CSR, 0x30);
 6475: 		for (i = 0; i < 64; i++) {
 6476: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6477: 		}
 6478: 	} else {
 6479: 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
 6480: 		return;
 6481: 	}
 6482: 	isp_prt(isp, ISP_LOGALL,
 6483: 	   "isp_fw_dump: RISC registers dumped successfully");
 6484: 	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
 6485: 	for (i = 0; i < 100; i++) {
 6486: 		USEC_DELAY(100);
 6487: 		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
 6488: 			break;
 6489: 		}
 6490: 	}
 6491: 	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
 6492: 		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
 6493: 		return;
 6494: 	}
 6495: 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
 6496: 	for (i = 0; i < 100; i++) {
 6497: 		USEC_DELAY(100);
 6498: 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
 6499: 			break;
 6500: 		}
 6501: 	}
 6502: 	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
 6503: 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
 6504: 		return;
 6505: 	}
 6506: 	ISP_WRITE(isp, RISC_EMB, 0xf2);
 6507: 	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
 6508: 	for (i = 0; i < 100; i++) {
 6509: 		USEC_DELAY(100);
 6510: 		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
 6511: 			break;
 6512: 		}
 6513: 	}
 6514: 	ENABLE_INTS(isp);
 6515: 	mbs.param[0] = MBOX_READ_RAM_WORD;
 6516: 	mbs.param[1] = 0x1000;
 6517: 	isp->isp_mbxworkp = (void *) ptr;
 6518: 	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
 6519: 	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
 6520: 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
 6521: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 6522: 		isp_prt(isp, ISP_LOGWARN,
 6523: 		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
 6524: 		return;
 6525: 	}
 6526: 	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
 6527: 	*ptr++ = isp->isp_mboxtmp[2];
 6528: 	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully");
 6529: 	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
 6530: 	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
 6531: }
 6532: 
 6533: static void
 6534: isp2300_fw_dump(struct ispsoftc *isp)
 6535: {
 6536: 	int i, j;
 6537: 	mbreg_t mbs;
 6538: 	u_int16_t *ptr;
 6539: 
 6540: 	ptr = FCPARAM(isp)->isp_dump_data;
 6541: 	if (ptr == NULL) {
 6542: 		isp_prt(isp, ISP_LOGERR,
 6543: 		   "No place to dump RISC registers and SRAM");
 6544: 		return;
 6545: 	}
 6546: 	if (*ptr++) {
 6547: 		isp_prt(isp, ISP_LOGERR,
 6548: 		   "dump area for RISC registers and SRAM already used");
 6549: 		return;
 6550: 	}
 6551: 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
 6552: 	for (i = 0; i < 100; i++) {
 6553: 		USEC_DELAY(100);
 6554: 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
 6555: 			break;
 6556: 		}
 6557: 	}
 6558: 	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
 6559: 		/*
 6560: 		 * PBIU registers
 6561: 		 */
 6562: 		for (i = 0; i < 8; i++) {
 6563: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
 6564: 		}
 6565: 
 6566: 		/*
 6567: 		 * ReqQ-RspQ-Risc2Host Status registers
 6568: 		 */
 6569: 		for (i = 0; i < 8; i++) {
 6570: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
 6571: 		}
 6572: 
 6573: 		/*
 6574: 		 * Mailbox Registers
 6575: 		 */
 6576: 		for (i = 0; i < 32; i++) {
 6577: 			*ptr++ =
 6578: 			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
 6579: 		}
 6580: 
 6581: 		/*
 6582: 		 * Auto Request Response DMA registers
 6583: 		 */
 6584: 		ISP_WRITE(isp, BIU2100_CSR, 0x40);
 6585: 		for (i = 0; i < 32; i++) {
 6586: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6587: 		}
 6588: 
 6589: 		/*
 6590: 		 * DMA registers
 6591: 		 */
 6592: 		ISP_WRITE(isp, BIU2100_CSR, 0x50);
 6593: 		for (i = 0; i < 48; i++) {
 6594: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6595: 		}
 6596: 
 6597: 		/*
 6598: 		 * RISC hardware registers
 6599: 		 */
 6600: 		ISP_WRITE(isp, BIU2100_CSR, 0);
 6601: 		for (i = 0; i < 16; i++) {
 6602: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
 6603: 		}
 6604: 
 6605: 		/*
 6606: 		 * RISC GP? registers
 6607: 		 */
 6608: 		for (j = 0; j < 8; j++) {
 6609: 			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
 6610: 			for (i = 0; i < 16; i++) {
 6611: 				*ptr++ =
 6612: 				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6613: 			}
 6614: 		}
 6615: 
 6616: 		/*
 6617: 		 * frame buffer hardware registers
 6618: 		 */
 6619: 		ISP_WRITE(isp, BIU2100_CSR, 0x10);
 6620: 		for (i = 0; i < 64; i++) {
 6621: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6622: 		}
 6623: 
 6624: 		/*
 6625: 		 * FPM B0 hardware registers
 6626: 		 */
 6627: 		ISP_WRITE(isp, BIU2100_CSR, 0x20);
 6628: 		for (i = 0; i < 64; i++) {
 6629: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6630: 		}
 6631: 
 6632: 		/*
 6633: 		 * FPM B1 hardware registers
 6634: 		 */
 6635: 		ISP_WRITE(isp, BIU2100_CSR, 0x30);
 6636: 		for (i = 0; i < 64; i++) {
 6637: 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
 6638: 		}
 6639: 	} else {
 6640: 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
 6641: 		return;
 6642: 	}
 6643: 	isp_prt(isp, ISP_LOGALL,
 6644: 	   "isp_fw_dump: RISC registers dumped successfully");
 6645: 	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
 6646: 	for (i = 0; i < 100; i++) {
 6647: 		USEC_DELAY(100);
 6648: 		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
 6649: 			break;
 6650: 		}
 6651: 	}
 6652: 	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
 6653: 		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
 6654: 		return;
 6655: 	}
 6656: 	ENABLE_INTS(isp);
 6657: 	mbs.param[0] = MBOX_READ_RAM_WORD;
 6658: 	mbs.param[1] = 0x800;
 6659: 	isp->isp_mbxworkp = (void *) ptr;
 6660: 	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
 6661: 	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
 6662: 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
 6663: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 6664: 		isp_prt(isp, ISP_LOGWARN,
 6665: 		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
 6666: 		return;
 6667: 	}
 6668: 	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
 6669: 	*ptr++ = isp->isp_mboxtmp[2];
 6670: 
 6671: 	/*
 6672: 	 * We don't have access to mailbox registers 8.. onward
 6673: 	 * in our 'common' device model- so we have to set it
 6674: 	 * here and hope it stays the same!
 6675: 	 */
 6676: 	ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1);
 6677: 
 6678: 	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
 6679: 	mbs.param[1] = 0;
 6680: 	isp->isp_mbxworkp = (void *) ptr;
 6681: 	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
 6682: 	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
 6683: 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
 6684: 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 6685: 		isp_prt(isp, ISP_LOGWARN,
 6686: 		    "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
 6687: 		return;
 6688: 	}
 6689: 	ptr = isp->isp_mbxworkp;	/* finish final word */
 6690: 	*ptr++ = mbs.param[2];
 6691: 	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully");
 6692: 	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
 6693: 	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
 6694: }
 6695: 
 6696: void
 6697: isp_fw_dump(struct ispsoftc *isp)
 6698: {
 6699: 	if (IS_2200(isp))
 6700: 		isp2200_fw_dump(isp);
 6701: 	else if (IS_23XX(isp))
 6702: 		isp2300_fw_dump(isp);
 6703: }
 6704: #endif