Home | History | Annotate | Line # | Download | only in ic
isp.c revision 1.113
      1  1.113    mjacob /* $NetBSD: isp.c,v 1.113 2007/07/07 00:49:48 mjacob Exp $ */
      2    1.1       cgd /*
      3   1.54    mjacob  * Machine and OS Independent (well, as best as possible)
      4   1.54    mjacob  * code for the Qlogic ISP SCSI adapters.
      5   1.54    mjacob  *
      6  1.111    mjacob  * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration
      7  1.111    mjacob  * All rights reserved.
      8  1.111    mjacob  *
      9  1.111    mjacob  * Additional Copyright (C) 2000-2007 by Matthew Jacob
     10    1.1       cgd  * All rights reserved.
     11    1.1       cgd  *
     12    1.1       cgd  * Redistribution and use in source and binary forms, with or without
     13    1.1       cgd  * modification, are permitted provided that the following conditions
     14    1.1       cgd  * are met:
     15  1.111    mjacob  *
     16    1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     17  1.111    mjacob  *    notice, this list of conditions and the following disclaimer.
     18  1.111    mjacob  * 2. Redistributions in binary form must reproduce the above copyright
     19  1.111    mjacob  *    notice, this list of conditions and the following disclaimer in the
     20  1.111    mjacob  *    documentation and/or other materials provided with the distribution.
     21  1.111    mjacob  *
     22  1.111    mjacob  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     23   1.54    mjacob  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24   1.54    mjacob  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  1.111    mjacob  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
     26  1.111    mjacob  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27   1.54    mjacob  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28   1.54    mjacob  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29   1.54    mjacob  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30   1.54    mjacob  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31   1.54    mjacob  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32   1.54    mjacob  * SUCH DAMAGE.
     33    1.1       cgd  */
     34   1.70    mjacob 
     35    1.1       cgd /*
     36    1.1       cgd  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
     37   1.23    mjacob  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
     38   1.23    mjacob  * ideas dredged from the Solaris driver.
     39    1.1       cgd  */
     40    1.1       cgd 
     41   1.23    mjacob /*
     42   1.23    mjacob  * Include header file appropriate for platform we're building on.
     43   1.23    mjacob  */
     44  1.111    mjacob #ifdef	__NetBSD__
     45   1.85     lukem #include <sys/cdefs.h>
     46  1.113    mjacob __KERNEL_RCSID(0, "$NetBSD: isp.c,v 1.113 2007/07/07 00:49:48 mjacob Exp $");
     47   1.23    mjacob #include <dev/ic/isp_netbsd.h>
     48   1.23    mjacob #endif
     49   1.23    mjacob #ifdef	__FreeBSD__
     50  1.111    mjacob #include <sys/cdefs.h>
     51  1.111    mjacob __FBSDID("$FreeBSD$");
     52   1.23    mjacob #include <dev/isp/isp_freebsd.h>
     53   1.23    mjacob #endif
     54   1.33    mjacob #ifdef	__OpenBSD__
     55   1.33    mjacob #include <dev/ic/isp_openbsd.h>
     56   1.33    mjacob #endif
     57   1.23    mjacob #ifdef	__linux__
     58   1.29    mjacob #include "isp_linux.h"
     59   1.23    mjacob #endif
     60   1.57    mjacob #ifdef	__svr4__
     61   1.57    mjacob #include "isp_solaris.h"
     62   1.57    mjacob #endif
     63    1.1       cgd 
     64   1.23    mjacob /*
     65   1.23    mjacob  * General defines
     66   1.23    mjacob  */
     67    1.1       cgd 
     68   1.23    mjacob #define	MBOX_DELAY_COUNT	1000000 / 100
     69  1.111    mjacob #define	ISP_MARK_PORTDB(a, b)	\
     70  1.111    mjacob     isp_prt(isp, ISP_LOGSANCFG, "line %d: markportdb", __LINE__); \
     71  1.111    mjacob     isp_mark_portdb(a, b)
     72    1.1       cgd 
     73   1.23    mjacob /*
     74   1.27    mjacob  * Local static data
     75   1.27    mjacob  */
     76  1.111    mjacob static const char fconf[] =
     77  1.111    mjacob     "PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n"
     78  1.111    mjacob     " database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
     79   1.66    mjacob static const char notresp[] =
     80   1.63    mjacob   "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
     81   1.66    mjacob static const char xact1[] =
     82   1.57    mjacob     "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
     83   1.66    mjacob static const char xact2[] =
     84   1.57    mjacob     "HBA attempted queued transaction to target routine %d on target %d bus %d";
     85   1.66    mjacob static const char xact3[] =
     86   1.57    mjacob     "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
     87   1.66    mjacob static const char pskip[] =
     88   1.57    mjacob     "SCSI phase skipped for target %d.%d.%d";
     89   1.66    mjacob static const char topology[] =
     90  1.111    mjacob     "HBA PortID 0x%06x N-Port Handle %d, Connection Topology '%s'";
     91  1.111    mjacob static const char ourwwn[] =
     92  1.111    mjacob     "HBA WWNN 0x%08x%08x HBA WWPN 0x%08x%08x";
     93   1.66    mjacob static const char finmsg[] =
     94  1.111    mjacob     "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
     95   1.79    mjacob static const char sc0[] =
     96   1.79    mjacob     "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
     97   1.79    mjacob static const char sc1[] =
     98   1.79    mjacob     "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
     99   1.79    mjacob static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
    100   1.79    mjacob static const char sc3[] = "Generated";
    101   1.79    mjacob static const char sc4[] = "NVRAM";
    102   1.94    mjacob static const char bun[] =
    103   1.94    mjacob     "bad underrun for %d.%d (count %d, resid %d, status %s)";
    104   1.79    mjacob 
    105   1.27    mjacob /*
    106   1.25    mjacob  * Local function prototypes.
    107   1.23    mjacob  */
    108  1.111    mjacob static int isp_parse_async(ispsoftc_t *, uint16_t);
    109  1.111    mjacob static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *,
    110  1.111    mjacob     uint32_t *);
    111  1.111    mjacob static void
    112  1.111    mjacob isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *);
    113   1.86    mjacob static void
    114  1.111    mjacob isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
    115  1.111    mjacob static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
    116  1.111    mjacob static int isp_mbox_continue(ispsoftc_t *);
    117  1.111    mjacob static void isp_scsi_init(ispsoftc_t *);
    118  1.111    mjacob static void isp_scsi_channel_init(ispsoftc_t *, int);
    119  1.111    mjacob static void isp_fibre_init(ispsoftc_t *);
    120  1.111    mjacob static void isp_fibre_init_2400(ispsoftc_t *);
    121  1.111    mjacob static void isp_mark_portdb(ispsoftc_t *, int);
    122  1.111    mjacob static int isp_plogx(ispsoftc_t *, uint16_t, uint32_t, int, int);
    123  1.111    mjacob static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
    124  1.111    mjacob static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
    125  1.111    mjacob static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int);
    126  1.111    mjacob static uint64_t isp_get_portname(ispsoftc_t *, int, int);
    127  1.111    mjacob static int isp_fclink_test(ispsoftc_t *, int);
    128  1.111    mjacob static const char *ispfc_fw_statename(int);
    129  1.111    mjacob static int isp_pdb_sync(ispsoftc_t *);
    130  1.111    mjacob static int isp_scan_loop(ispsoftc_t *);
    131  1.111    mjacob static int isp_gid_ft_sns(ispsoftc_t *);
    132  1.111    mjacob static int isp_gid_ft_ct_passthru(ispsoftc_t *);
    133  1.111    mjacob static int isp_scan_fabric(ispsoftc_t *);
    134  1.111    mjacob static int isp_login_device(ispsoftc_t *, uint32_t, isp_pdb_t *, uint16_t *);
    135  1.111    mjacob static int isp_register_fc4_type(ispsoftc_t *);
    136  1.111    mjacob static int isp_register_fc4_type_24xx(ispsoftc_t *);
    137  1.111    mjacob static uint16_t isp_nxt_handle(ispsoftc_t *, uint16_t);
    138  1.111    mjacob static void isp_fw_state(ispsoftc_t *);
    139  1.111    mjacob static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
    140  1.111    mjacob static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
    141  1.111    mjacob 
    142  1.111    mjacob static void isp_update(ispsoftc_t *);
    143  1.111    mjacob static void isp_update_bus(ispsoftc_t *, int);
    144  1.111    mjacob static void isp_setdfltparm(ispsoftc_t *, int);
    145  1.111    mjacob static void isp_setdfltfcparm(ispsoftc_t *);
    146  1.111    mjacob static int isp_read_nvram(ispsoftc_t *);
    147  1.111    mjacob static int isp_read_nvram_2400(ispsoftc_t *);
    148  1.111    mjacob static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
    149  1.111    mjacob static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
    150  1.111    mjacob static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
    151  1.111    mjacob static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
    152  1.111    mjacob static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
    153  1.111    mjacob static void isp_fix_nvram_wwns(ispsoftc_t *);
    154  1.111    mjacob static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
    155  1.111    mjacob static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
    156   1.49    mjacob 
    157    1.1       cgd /*
    158    1.1       cgd  * Reset Hardware.
    159   1.25    mjacob  *
    160   1.43    mjacob  * Hit the chip over the head, download new f/w if available and set it running.
    161   1.25    mjacob  *
    162   1.24    mjacob  * Locking done elsewhere.
    163    1.1       cgd  */
    164   1.79    mjacob 
    165    1.1       cgd void
    166  1.111    mjacob isp_reset(ispsoftc_t *isp)
    167    1.1       cgd {
    168    1.1       cgd 	mbreg_t mbs;
    169  1.111    mjacob 	uint32_t code_org, val;
    170   1.95    mjacob 	int loops, i, dodnld = 1;
    171  1.111    mjacob 	static const char *btype = "????";
    172  1.111    mjacob 	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
    173    1.1       cgd 
    174    1.1       cgd 	isp->isp_state = ISP_NILSTATE;
    175    1.4    mjacob 
    176    1.4    mjacob 	/*
    177   1.25    mjacob 	 * Basic types (SCSI, FibreChannel and PCI or SBus)
    178   1.25    mjacob 	 * have been set in the MD code. We figure out more
    179   1.79    mjacob 	 * here. Possibly more refined types based upon PCI
    180   1.79    mjacob 	 * identification. Chip revision has been gathered.
    181   1.57    mjacob 	 *
    182   1.32    mjacob 	 * After we've fired this chip up, zero out the conf1 register
    183   1.57    mjacob 	 * for SCSI adapters and do other settings for the 2100.
    184   1.32    mjacob 	 */
    185   1.32    mjacob 
    186   1.32    mjacob 	/*
    187   1.31    mjacob 	 * Get the current running firmware revision out of the
    188   1.31    mjacob 	 * chip before we hit it over the head (if this is our
    189   1.31    mjacob 	 * first time through). Note that we store this as the
    190   1.31    mjacob 	 * 'ROM' firmware revision- which it may not be. In any
    191   1.31    mjacob 	 * case, we don't really use this yet, but we may in
    192   1.31    mjacob 	 * the future.
    193   1.31    mjacob 	 */
    194   1.95    mjacob 	if (isp->isp_touched == 0) {
    195   1.31    mjacob 		/*
    196   1.57    mjacob 		 * First see whether or not we're sitting in the ISP PROM.
    197   1.57    mjacob 		 * If we've just been reset, we'll have the string "ISP   "
    198   1.80    mjacob 		 * spread through outgoing mailbox registers 1-3. We do
    199   1.80    mjacob 		 * this for PCI cards because otherwise we really don't
    200   1.80    mjacob 		 * know what state the card is in and we could hang if
    201   1.80    mjacob 		 * we try this command otherwise.
    202   1.80    mjacob 		 *
    203   1.80    mjacob 		 * For SBus cards, we just do this because they almost
    204   1.80    mjacob 		 * certainly will be running firmware by now.
    205   1.57    mjacob 		 */
    206   1.57    mjacob 		if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
    207   1.57    mjacob 		    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
    208   1.57    mjacob 		    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
    209   1.57    mjacob 			/*
    210   1.57    mjacob 			 * Just in case it was paused...
    211   1.57    mjacob 			 */
    212  1.111    mjacob 			if (IS_24XX(isp)) {
    213  1.111    mjacob 				ISP_WRITE(isp, BIU2400_HCCR,
    214  1.111    mjacob 				    HCCR_2400_CMD_RELEASE);
    215  1.111    mjacob 			} else {
    216  1.111    mjacob 				ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
    217  1.111    mjacob 			}
    218  1.111    mjacob 			MEMZERO(&mbs, sizeof (mbs));
    219   1.57    mjacob 			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
    220  1.111    mjacob 			mbs.logval = MBLOGNONE;
    221  1.111    mjacob 			isp_mboxcmd(isp, &mbs);
    222   1.57    mjacob 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
    223   1.57    mjacob 				isp->isp_romfw_rev[0] = mbs.param[1];
    224   1.57    mjacob 				isp->isp_romfw_rev[1] = mbs.param[2];
    225   1.57    mjacob 				isp->isp_romfw_rev[2] = mbs.param[3];
    226   1.57    mjacob 			}
    227   1.30    mjacob 		}
    228   1.43    mjacob 		isp->isp_touched = 1;
    229   1.30    mjacob 	}
    230   1.30    mjacob 
    231  1.111    mjacob 	ISP_DISABLE_INTS(isp);
    232  1.111    mjacob 
    233  1.111    mjacob 	/*
    234  1.111    mjacob 	 * Pick an initial maxcmds value which will be used
    235  1.111    mjacob 	 * to allocate xflist pointer space. It may be changed
    236  1.111    mjacob 	 * later by the firmware.
    237  1.111    mjacob 	 */
    238  1.111    mjacob 	if (IS_24XX(isp)) {
    239  1.111    mjacob 		isp->isp_maxcmds = 4096;
    240  1.111    mjacob 	} else if (IS_2322(isp)) {
    241  1.111    mjacob 		isp->isp_maxcmds = 2048;
    242  1.111    mjacob 	} else if (IS_23XX(isp) || IS_2200(isp)) {
    243  1.111    mjacob 		isp->isp_maxcmds = 1024;
    244  1.111    mjacob  	} else {
    245  1.111    mjacob 		isp->isp_maxcmds = 512;
    246  1.111    mjacob 	}
    247  1.111    mjacob 
    248  1.111    mjacob 	/*
    249  1.111    mjacob 	 * Set up DMA for the request and result queues.
    250  1.111    mjacob 	 *
    251  1.111    mjacob 	 * We do this now so we can use the request queue
    252  1.111    mjacob 	 * for a dma
    253  1.111    mjacob 	 */
    254  1.111    mjacob 	if (ISP_MBOXDMASETUP(isp) != 0) {
    255  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
    256  1.111    mjacob 		return;
    257  1.111    mjacob 	}
    258  1.111    mjacob 
    259   1.80    mjacob 
    260   1.79    mjacob 	/*
    261   1.79    mjacob 	 * Set up default request/response queue in-pointer/out-pointer
    262   1.79    mjacob 	 * register indices.
    263   1.79    mjacob 	 */
    264  1.111    mjacob 	if (IS_24XX(isp)) {
    265  1.111    mjacob 		isp->isp_rqstinrp = BIU2400_REQINP;
    266  1.111    mjacob 		isp->isp_rqstoutrp = BIU2400_REQOUTP;
    267  1.111    mjacob 		isp->isp_respinrp = BIU2400_RSPINP;
    268  1.111    mjacob 		isp->isp_respoutrp = BIU2400_RSPOUTP;
    269  1.111    mjacob 		isp->isp_atioinrp = BIU2400_ATIO_RSPINP;
    270  1.111    mjacob 		isp->isp_atiooutrp = BIU2400_ATIO_REQINP;
    271  1.111    mjacob 	} else if (IS_23XX(isp)) {
    272   1.80    mjacob 		isp->isp_rqstinrp = BIU_REQINP;
    273   1.80    mjacob 		isp->isp_rqstoutrp = BIU_REQOUTP;
    274   1.80    mjacob 		isp->isp_respinrp = BIU_RSPINP;
    275   1.80    mjacob 		isp->isp_respoutrp = BIU_RSPOUTP;
    276   1.80    mjacob 	} else {
    277   1.80    mjacob 		isp->isp_rqstinrp = INMAILBOX4;
    278   1.80    mjacob 		isp->isp_rqstoutrp = OUTMAILBOX4;
    279   1.80    mjacob 		isp->isp_respinrp = OUTMAILBOX5;
    280   1.80    mjacob 		isp->isp_respoutrp = INMAILBOX5;
    281   1.80    mjacob 	}
    282   1.35    mjacob 
    283   1.31    mjacob 	/*
    284   1.70    mjacob 	 * Put the board into PAUSE mode (so we can read the SXP registers
    285   1.70    mjacob 	 * or write FPM/FBM registers).
    286   1.31    mjacob 	 */
    287  1.111    mjacob 	if (IS_24XX(isp)) {
    288  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
    289  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
    290  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
    291  1.111    mjacob 	} else {
    292  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
    293  1.111    mjacob 	}
    294   1.31    mjacob 
    295   1.37    mjacob 	if (IS_FC(isp)) {
    296   1.37    mjacob 		switch (isp->isp_type) {
    297   1.37    mjacob 		case ISP_HA_FC_2100:
    298   1.79    mjacob 			btype = "2100";
    299   1.37    mjacob 			break;
    300   1.37    mjacob 		case ISP_HA_FC_2200:
    301   1.79    mjacob 			btype = "2200";
    302   1.37    mjacob 			break;
    303   1.76    mjacob 		case ISP_HA_FC_2300:
    304   1.88    mjacob 			btype = "2300";
    305   1.88    mjacob 			break;
    306   1.87    mjacob 		case ISP_HA_FC_2312:
    307   1.88    mjacob 			btype = "2312";
    308   1.76    mjacob 			break;
    309  1.111    mjacob 		case ISP_HA_FC_2322:
    310  1.111    mjacob 			btype = "2322";
    311  1.111    mjacob 			break;
    312  1.111    mjacob 		case ISP_HA_FC_2400:
    313  1.111    mjacob 			btype = "2422";
    314  1.111    mjacob 			break;
    315   1.37    mjacob 		default:
    316   1.37    mjacob 			break;
    317   1.37    mjacob 		}
    318  1.111    mjacob 
    319  1.111    mjacob 		if (!IS_24XX(isp)) {
    320  1.111    mjacob 			/*
    321  1.111    mjacob 			 * While we're paused, reset the FPM module and FBM
    322  1.111    mjacob 			 * fifos.
    323  1.111    mjacob 			 */
    324  1.111    mjacob 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
    325  1.111    mjacob 			ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
    326  1.111    mjacob 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
    327  1.111    mjacob 			ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
    328  1.111    mjacob 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
    329  1.111    mjacob 		}
    330   1.44    mjacob 	} else if (IS_1240(isp)) {
    331   1.44    mjacob 		sdparam *sdp = isp->isp_param;
    332   1.79    mjacob 		btype = "1240";
    333   1.36    mjacob 		isp->isp_clock = 60;
    334   1.44    mjacob 		sdp->isp_ultramode = 1;
    335   1.44    mjacob 		sdp++;
    336   1.44    mjacob 		sdp->isp_ultramode = 1;
    337   1.44    mjacob 		/*
    338   1.44    mjacob 		 * XXX: Should probably do some bus sensing.
    339   1.44    mjacob 		 */
    340   1.44    mjacob 	} else if (IS_ULTRA2(isp)) {
    341   1.66    mjacob 		static const char m[] = "bus %d is in %s Mode";
    342  1.111    mjacob 		uint16_t l;
    343   1.33    mjacob 		sdparam *sdp = isp->isp_param;
    344   1.44    mjacob 
    345   1.44    mjacob 		isp->isp_clock = 100;
    346   1.44    mjacob 
    347   1.49    mjacob 		if (IS_1280(isp))
    348   1.79    mjacob 			btype = "1280";
    349   1.49    mjacob 		else if (IS_1080(isp))
    350   1.79    mjacob 			btype = "1080";
    351   1.99    mjacob 		else if (IS_10160(isp))
    352   1.99    mjacob 			btype = "10160";
    353   1.49    mjacob 		else if (IS_12160(isp))
    354   1.79    mjacob 			btype = "12160";
    355   1.49    mjacob 		else
    356   1.79    mjacob 			btype = "<UNKLVD>";
    357   1.49    mjacob 
    358   1.34    mjacob 		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
    359   1.34    mjacob 		switch (l) {
    360   1.34    mjacob 		case ISP1080_LVD_MODE:
    361   1.34    mjacob 			sdp->isp_lvdmode = 1;
    362   1.57    mjacob 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
    363   1.34    mjacob 			break;
    364   1.34    mjacob 		case ISP1080_HVD_MODE:
    365   1.34    mjacob 			sdp->isp_diffmode = 1;
    366   1.57    mjacob 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
    367   1.34    mjacob 			break;
    368   1.34    mjacob 		case ISP1080_SE_MODE:
    369   1.34    mjacob 			sdp->isp_ultramode = 1;
    370   1.57    mjacob 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
    371   1.34    mjacob 			break;
    372   1.34    mjacob 		default:
    373   1.57    mjacob 			isp_prt(isp, ISP_LOGERR,
    374   1.57    mjacob 			    "unknown mode on bus %d (0x%x)", 0, l);
    375   1.34    mjacob 			break;
    376   1.34    mjacob 		}
    377   1.44    mjacob 
    378   1.49    mjacob 		if (IS_DUALBUS(isp)) {
    379   1.44    mjacob 			sdp++;
    380   1.44    mjacob 			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
    381   1.44    mjacob 			l &= ISP1080_MODE_MASK;
    382   1.44    mjacob 			switch(l) {
    383   1.44    mjacob 			case ISP1080_LVD_MODE:
    384   1.44    mjacob 				sdp->isp_lvdmode = 1;
    385   1.57    mjacob 				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
    386   1.44    mjacob 				break;
    387   1.44    mjacob 			case ISP1080_HVD_MODE:
    388   1.44    mjacob 				sdp->isp_diffmode = 1;
    389   1.57    mjacob 				isp_prt(isp, ISP_LOGCONFIG,
    390   1.57    mjacob 				    m, 1, "Differential");
    391   1.44    mjacob 				break;
    392   1.44    mjacob 			case ISP1080_SE_MODE:
    393   1.44    mjacob 				sdp->isp_ultramode = 1;
    394   1.57    mjacob 				isp_prt(isp, ISP_LOGCONFIG,
    395   1.57    mjacob 				    m, 1, "Single-Ended");
    396   1.44    mjacob 				break;
    397   1.44    mjacob 			default:
    398   1.57    mjacob 				isp_prt(isp, ISP_LOGERR,
    399   1.57    mjacob 				    "unknown mode on bus %d (0x%x)", 1, l);
    400   1.44    mjacob 				break;
    401   1.44    mjacob 			}
    402   1.44    mjacob 		}
    403   1.10    mjacob 	} else {
    404   1.25    mjacob 		sdparam *sdp = isp->isp_param;
    405   1.30    mjacob 		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
    406   1.30    mjacob 		switch (i) {
    407   1.10    mjacob 		default:
    408   1.57    mjacob 			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
    409   1.25    mjacob 			/* FALLTHROUGH */
    410   1.10    mjacob 		case 1:
    411   1.79    mjacob 			btype = "1020";
    412   1.10    mjacob 			isp->isp_type = ISP_HA_SCSI_1020;
    413   1.36    mjacob 			isp->isp_clock = 40;
    414   1.22    mjacob 			break;
    415   1.22    mjacob 		case 2:
    416   1.25    mjacob 			/*
    417   1.25    mjacob 			 * Some 1020A chips are Ultra Capable, but don't
    418   1.25    mjacob 			 * run the clock rate up for that unless told to
    419   1.25    mjacob 			 * do so by the Ultra Capable bits being set.
    420   1.25    mjacob 			 */
    421   1.79    mjacob 			btype = "1020A";
    422   1.22    mjacob 			isp->isp_type = ISP_HA_SCSI_1020A;
    423   1.36    mjacob 			isp->isp_clock = 40;
    424   1.10    mjacob 			break;
    425   1.10    mjacob 		case 3:
    426   1.79    mjacob 			btype = "1040";
    427   1.25    mjacob 			isp->isp_type = ISP_HA_SCSI_1040;
    428   1.36    mjacob 			isp->isp_clock = 60;
    429   1.25    mjacob 			break;
    430   1.25    mjacob 		case 4:
    431   1.79    mjacob 			btype = "1040A";
    432   1.10    mjacob 			isp->isp_type = ISP_HA_SCSI_1040A;
    433   1.36    mjacob 			isp->isp_clock = 60;
    434   1.10    mjacob 			break;
    435   1.10    mjacob 		case 5:
    436   1.79    mjacob 			btype = "1040B";
    437   1.10    mjacob 			isp->isp_type = ISP_HA_SCSI_1040B;
    438   1.36    mjacob 			isp->isp_clock = 60;
    439   1.10    mjacob 			break;
    440   1.78    mjacob 		case 6:
    441   1.79    mjacob 			btype = "1040C";
    442   1.35    mjacob 			isp->isp_type = ISP_HA_SCSI_1040C;
    443   1.36    mjacob 			isp->isp_clock = 60;
    444   1.78    mjacob                         break;
    445    1.8    mjacob 		}
    446   1.25    mjacob 		/*
    447   1.31    mjacob 		 * Now, while we're at it, gather info about ultra
    448   1.31    mjacob 		 * and/or differential mode.
    449   1.25    mjacob 		 */
    450   1.31    mjacob 		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
    451   1.57    mjacob 			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
    452   1.31    mjacob 			sdp->isp_diffmode = 1;
    453   1.31    mjacob 		} else {
    454   1.31    mjacob 			sdp->isp_diffmode = 0;
    455   1.31    mjacob 		}
    456   1.31    mjacob 		i = ISP_READ(isp, RISC_PSR);
    457   1.31    mjacob 		if (isp->isp_bustype == ISP_BT_SBUS) {
    458   1.31    mjacob 			i &= RISC_PSR_SBUS_ULTRA;
    459   1.30    mjacob 		} else {
    460   1.31    mjacob 			i &= RISC_PSR_PCI_ULTRA;
    461   1.31    mjacob 		}
    462   1.31    mjacob 		if (i != 0) {
    463   1.57    mjacob 			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
    464   1.31    mjacob 			sdp->isp_ultramode = 1;
    465   1.33    mjacob 			/*
    466  1.101    mjacob 			 * If we're in Ultra Mode, we have to be 60MHz clock-
    467   1.33    mjacob 			 * even for the SBus version.
    468   1.33    mjacob 			 */
    469   1.36    mjacob 			isp->isp_clock = 60;
    470   1.34    mjacob 		} else {
    471   1.31    mjacob 			sdp->isp_ultramode = 0;
    472   1.33    mjacob 			/*
    473   1.33    mjacob 			 * Clock is known. Gronk.
    474   1.33    mjacob 			 */
    475   1.25    mjacob 		}
    476   1.25    mjacob 
    477   1.25    mjacob 		/*
    478   1.25    mjacob 		 * Machine dependent clock (if set) overrides
    479   1.25    mjacob 		 * our generic determinations.
    480   1.25    mjacob 		 */
    481   1.25    mjacob 		if (isp->isp_mdvec->dv_clock) {
    482   1.36    mjacob 			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
    483   1.36    mjacob 				isp->isp_clock = isp->isp_mdvec->dv_clock;
    484   1.25    mjacob 			}
    485   1.25    mjacob 		}
    486   1.31    mjacob 
    487    1.4    mjacob 	}
    488    1.8    mjacob 
    489    1.1       cgd 	/*
    490   1.63    mjacob 	 * Clear instrumentation
    491   1.63    mjacob 	 */
    492   1.63    mjacob 	isp->isp_intcnt = isp->isp_intbogus = 0;
    493   1.63    mjacob 
    494   1.63    mjacob 	/*
    495   1.10    mjacob 	 * Do MD specific pre initialization
    496    1.1       cgd 	 */
    497   1.10    mjacob 	ISP_RESET0(isp);
    498   1.25    mjacob 
    499    1.1       cgd 	/*
    500   1.10    mjacob 	 * Hit the chip over the head with hammer,
    501   1.10    mjacob 	 * and give the ISP a chance to recover.
    502    1.1       cgd 	 */
    503    1.1       cgd 
    504   1.33    mjacob 	if (IS_SCSI(isp)) {
    505   1.10    mjacob 		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
    506   1.10    mjacob 		/*
    507   1.10    mjacob 		 * A slight delay...
    508   1.10    mjacob 		 */
    509   1.57    mjacob 		USEC_DELAY(100);
    510   1.33    mjacob 
    511   1.10    mjacob 		/*
    512   1.10    mjacob 		 * Clear data && control DMA engines.
    513   1.10    mjacob 		 */
    514   1.10    mjacob 		ISP_WRITE(isp, CDMA_CONTROL,
    515   1.34    mjacob 		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
    516   1.10    mjacob 		ISP_WRITE(isp, DDMA_CONTROL,
    517   1.34    mjacob 		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
    518   1.33    mjacob 
    519   1.33    mjacob 
    520  1.111    mjacob 	} else if (IS_24XX(isp)) {
    521  1.111    mjacob 		/*
    522  1.111    mjacob 		 * Stop DMA and wait for it to stop.
    523  1.111    mjacob 		 */
    524  1.111    mjacob 		ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
    525  1.111    mjacob 		for (val = loops = 0; loops < 30000; loops++) {
    526  1.111    mjacob 			USEC_DELAY(10);
    527  1.111    mjacob 			val = ISP_READ(isp, BIU2400_CSR);
    528  1.111    mjacob 			if ((val & BIU2400_DMA_ACTIVE) == 0) {
    529  1.111    mjacob 				break;
    530  1.111    mjacob 			}
    531  1.111    mjacob 		}
    532  1.111    mjacob 		if (val & BIU2400_DMA_ACTIVE) {
    533  1.111    mjacob 			ISP_RESET0(isp);
    534  1.111    mjacob 			isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
    535  1.111    mjacob 			return;
    536  1.111    mjacob 		}
    537  1.111    mjacob 		/*
    538  1.111    mjacob 		 * Hold it in SOFT_RESET and STOP state for 100us.
    539  1.111    mjacob 		 */
    540  1.111    mjacob 		ISP_WRITE(isp, BIU2400_CSR,
    541  1.111    mjacob 		    BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
    542  1.111    mjacob 		USEC_DELAY(100);
    543  1.111    mjacob 		for (loops = 0; loops < 10000; loops++) {
    544  1.111    mjacob 			USEC_DELAY(5);
    545  1.111    mjacob 			val = ISP_READ(isp, OUTMAILBOX0);
    546  1.111    mjacob 		}
    547  1.111    mjacob 		for (val = loops = 0; loops < 500000; loops ++) {
    548  1.111    mjacob 			val = ISP_READ(isp, BIU2400_CSR);
    549  1.111    mjacob 			if ((val & BIU2400_SOFT_RESET) == 0) {
    550  1.111    mjacob 				break;
    551  1.111    mjacob 			}
    552  1.111    mjacob 		}
    553  1.111    mjacob 		if (val & BIU2400_SOFT_RESET) {
    554  1.111    mjacob 			ISP_RESET0(isp);
    555  1.111    mjacob 			isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
    556  1.111    mjacob 			return;
    557  1.111    mjacob 		}
    558   1.10    mjacob 	} else {
    559   1.10    mjacob 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
    560   1.10    mjacob 		/*
    561   1.10    mjacob 		 * A slight delay...
    562   1.10    mjacob 		 */
    563   1.57    mjacob 		USEC_DELAY(100);
    564   1.31    mjacob 
    565   1.31    mjacob 		/*
    566   1.31    mjacob 		 * Clear data && control DMA engines.
    567   1.31    mjacob 		 */
    568   1.10    mjacob 		ISP_WRITE(isp, CDMA2100_CONTROL,
    569   1.10    mjacob 			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
    570   1.10    mjacob 		ISP_WRITE(isp, TDMA2100_CONTROL,
    571   1.10    mjacob 			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
    572   1.10    mjacob 		ISP_WRITE(isp, RDMA2100_CONTROL,
    573   1.10    mjacob 			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
    574   1.10    mjacob 	}
    575   1.10    mjacob 
    576    1.1       cgd 	/*
    577    1.1       cgd 	 * Wait for ISP to be ready to go...
    578    1.1       cgd 	 */
    579    1.1       cgd 	loops = MBOX_DELAY_COUNT;
    580   1.10    mjacob 	for (;;) {
    581   1.38    mjacob 		if (IS_SCSI(isp)) {
    582  1.111    mjacob 			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
    583   1.10    mjacob 				break;
    584  1.111    mjacob 			}
    585  1.111    mjacob 		} else if (IS_24XX(isp)) {
    586  1.111    mjacob 			if (ISP_READ(isp, OUTMAILBOX0) == 0) {
    587  1.111    mjacob 				break;
    588  1.111    mjacob 			}
    589   1.10    mjacob 		} else {
    590   1.10    mjacob 			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
    591   1.10    mjacob 				break;
    592   1.10    mjacob 		}
    593   1.57    mjacob 		USEC_DELAY(100);
    594    1.1       cgd 		if (--loops < 0) {
    595   1.57    mjacob 			ISP_DUMPREGS(isp, "chip reset timed out");
    596  1.111    mjacob 			ISP_RESET0(isp);
    597    1.1       cgd 			return;
    598    1.1       cgd 		}
    599    1.1       cgd 	}
    600   1.31    mjacob 
    601    1.1       cgd 	/*
    602   1.31    mjacob 	 * After we've fired this chip up, zero out the conf1 register
    603   1.31    mjacob 	 * for SCSI adapters and other settings for the 2100.
    604    1.1       cgd 	 */
    605   1.31    mjacob 
    606   1.33    mjacob 	if (IS_SCSI(isp)) {
    607   1.10    mjacob 		ISP_WRITE(isp, BIU_CONF1, 0);
    608  1.111    mjacob 	} else if (!IS_24XX(isp)) {
    609   1.10    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0);
    610   1.10    mjacob 	}
    611    1.1       cgd 
    612   1.31    mjacob 	/*
    613   1.31    mjacob 	 * Reset RISC Processor
    614   1.31    mjacob 	 */
    615  1.111    mjacob 	if (IS_24XX(isp)) {
    616  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
    617  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
    618  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
    619  1.111    mjacob 	} else {
    620  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
    621  1.111    mjacob 		USEC_DELAY(100);
    622  1.111    mjacob 		ISP_WRITE(isp, BIU_SEMA, 0);
    623  1.111    mjacob 	}
    624    1.1       cgd 
    625  1.111    mjacob 
    626   1.30    mjacob 	/*
    627  1.111    mjacob 	 * Post-RISC Reset stuff.
    628   1.30    mjacob 	 */
    629  1.111    mjacob 	if (IS_24XX(isp)) {
    630  1.111    mjacob 		for (val = loops = 0; loops < 5000000; loops++) {
    631  1.111    mjacob 			USEC_DELAY(5);
    632  1.111    mjacob 			val = ISP_READ(isp, OUTMAILBOX0);
    633  1.111    mjacob 			if (val == 0) {
    634  1.111    mjacob 				break;
    635  1.111    mjacob 			}
    636  1.111    mjacob 		}
    637  1.111    mjacob 		if (val != 0) {
    638  1.111    mjacob 			ISP_RESET0(isp);
    639  1.111    mjacob 			isp_prt(isp, ISP_LOGERR, "reset didn't clear");
    640  1.111    mjacob 			return;
    641  1.111    mjacob 		}
    642  1.111    mjacob 	} else if (IS_SCSI(isp)) {
    643  1.111    mjacob 		uint16_t tmp = isp->isp_mdvec->dv_conf1;
    644   1.30    mjacob 		/*
    645   1.30    mjacob 		 * Busted FIFO. Turn off all but burst enables.
    646   1.30    mjacob 		 */
    647   1.30    mjacob 		if (isp->isp_type == ISP_HA_SCSI_1040A) {
    648   1.31    mjacob 			tmp &= BIU_BURST_ENABLE;
    649   1.30    mjacob 		}
    650   1.31    mjacob 		ISP_SETBITS(isp, BIU_CONF1, tmp);
    651   1.31    mjacob 		if (tmp & BIU_BURST_ENABLE) {
    652    1.1       cgd 			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
    653    1.1       cgd 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
    654    1.1       cgd 		}
    655  1.111    mjacob 		if (SDPARAM(isp)->isp_ptisp) {
    656  1.111    mjacob 			if (SDPARAM(isp)->isp_ultramode) {
    657  1.111    mjacob 				while (ISP_READ(isp, RISC_MTR) != 0x1313) {
    658  1.111    mjacob 					ISP_WRITE(isp, RISC_MTR, 0x1313);
    659  1.111    mjacob 					ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
    660  1.111    mjacob 				}
    661  1.111    mjacob 			} else {
    662  1.111    mjacob 				ISP_WRITE(isp, RISC_MTR, 0x1212);
    663   1.31    mjacob 			}
    664  1.111    mjacob 			/*
    665  1.111    mjacob 			 * PTI specific register
    666  1.111    mjacob 			 */
    667  1.111    mjacob 			ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
    668   1.34    mjacob 		} else {
    669   1.31    mjacob 			ISP_WRITE(isp, RISC_MTR, 0x1212);
    670   1.31    mjacob 		}
    671  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
    672   1.31    mjacob 	} else {
    673   1.31    mjacob 		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
    674   1.87    mjacob 		if (IS_2200(isp) || IS_23XX(isp)) {
    675   1.70    mjacob 			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
    676   1.70    mjacob 		}
    677  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
    678    1.1       cgd 	}
    679   1.31    mjacob 
    680  1.111    mjacob 	ISP_WRITE(isp, isp->isp_rqstinrp, 0);
    681  1.111    mjacob 	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
    682  1.111    mjacob 	ISP_WRITE(isp, isp->isp_respinrp, 0);
    683  1.111    mjacob 	ISP_WRITE(isp, isp->isp_respoutrp, 0);
    684  1.111    mjacob 
    685    1.1       cgd 
    686    1.1       cgd 	/*
    687    1.1       cgd 	 * Do MD specific post initialization
    688    1.1       cgd 	 */
    689    1.1       cgd 	ISP_RESET1(isp);
    690    1.1       cgd 
    691    1.1       cgd 	/*
    692   1.81    mjacob 	 * Wait for everything to finish firing up.
    693   1.81    mjacob 	 *
    694   1.81    mjacob 	 * Avoid doing this on the 2312 because you can generate a PCI
    695   1.81    mjacob 	 * parity error (chip breakage).
    696   1.31    mjacob 	 */
    697  1.111    mjacob 	if (IS_2312(isp)) {
    698  1.111    mjacob 		USEC_DELAY(100);
    699   1.81    mjacob 	} else {
    700   1.81    mjacob 		loops = MBOX_DELAY_COUNT;
    701   1.81    mjacob 		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
    702   1.81    mjacob 			USEC_DELAY(100);
    703   1.81    mjacob 			if (--loops < 0) {
    704  1.111    mjacob 				ISP_RESET0(isp);
    705   1.81    mjacob 				isp_prt(isp, ISP_LOGERR,
    706   1.81    mjacob 				    "MBOX_BUSY never cleared on reset");
    707   1.81    mjacob 				return;
    708   1.81    mjacob 			}
    709   1.31    mjacob 		}
    710   1.31    mjacob 	}
    711   1.31    mjacob 
    712   1.31    mjacob 	/*
    713   1.31    mjacob 	 * Up until this point we've done everything by just reading or
    714   1.31    mjacob 	 * setting registers. From this point on we rely on at least *some*
    715   1.31    mjacob 	 * kind of firmware running in the card.
    716   1.31    mjacob 	 */
    717   1.31    mjacob 
    718   1.31    mjacob 	/*
    719    1.1       cgd 	 * Do some sanity checking.
    720    1.1       cgd 	 */
    721  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
    722    1.1       cgd 	mbs.param[0] = MBOX_NO_OP;
    723  1.111    mjacob 	mbs.logval = MBLOGALL;
    724  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
    725    1.1       cgd 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    726  1.111    mjacob 		ISP_RESET0(isp);
    727    1.1       cgd 		return;
    728    1.1       cgd 	}
    729    1.1       cgd 
    730  1.111    mjacob 	if (IS_SCSI(isp) || IS_24XX(isp)) {
    731  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
    732   1.10    mjacob 		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
    733   1.10    mjacob 		mbs.param[1] = 0xdead;
    734   1.10    mjacob 		mbs.param[2] = 0xbeef;
    735   1.10    mjacob 		mbs.param[3] = 0xffff;
    736   1.10    mjacob 		mbs.param[4] = 0x1111;
    737   1.10    mjacob 		mbs.param[5] = 0xa5a5;
    738  1.111    mjacob 		mbs.param[6] = 0x0000;
    739  1.111    mjacob 		mbs.param[7] = 0x0000;
    740  1.111    mjacob 		mbs.logval = MBLOGALL;
    741  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
    742    1.1       cgd 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    743  1.111    mjacob 			ISP_RESET0(isp);
    744   1.10    mjacob 			return;
    745   1.10    mjacob 		}
    746   1.10    mjacob 		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
    747   1.10    mjacob 		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
    748   1.10    mjacob 		    mbs.param[5] != 0xa5a5) {
    749  1.111    mjacob 			ISP_RESET0(isp);
    750   1.57    mjacob 			isp_prt(isp, ISP_LOGERR,
    751   1.57    mjacob 			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
    752   1.57    mjacob 			    mbs.param[1], mbs.param[2], mbs.param[3],
    753   1.57    mjacob 			    mbs.param[4], mbs.param[5]);
    754    1.1       cgd 			return;
    755    1.1       cgd 		}
    756   1.10    mjacob 
    757    1.1       cgd 	}
    758    1.1       cgd 
    759    1.1       cgd 	/*
    760   1.18    mjacob 	 * Download new Firmware, unless requested not to do so.
    761   1.18    mjacob 	 * This is made slightly trickier in some cases where the
    762   1.18    mjacob 	 * firmware of the ROM revision is newer than the revision
    763   1.18    mjacob 	 * compiled into the driver. So, where we used to compare
    764   1.18    mjacob 	 * versions of our f/w and the ROM f/w, now we just see
    765   1.18    mjacob 	 * whether we have f/w at all and whether a config flag
    766   1.18    mjacob 	 * has disabled our download.
    767    1.1       cgd 	 */
    768   1.43    mjacob 	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
    769   1.23    mjacob 	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
    770   1.10    mjacob 		dodnld = 0;
    771   1.10    mjacob 	}
    772   1.10    mjacob 
    773  1.111    mjacob 	if (IS_24XX(isp)) {
    774  1.111    mjacob 		code_org = ISP_CODE_ORG_2400;
    775  1.111    mjacob 	} else if (IS_23XX(isp)) {
    776   1.79    mjacob 		code_org = ISP_CODE_ORG_2300;
    777  1.111    mjacob 	} else {
    778   1.79    mjacob 		code_org = ISP_CODE_ORG;
    779  1.111    mjacob 	}
    780  1.111    mjacob 
    781  1.111    mjacob 	if (dodnld && IS_24XX(isp)) {
    782  1.111    mjacob 		const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
    783  1.111    mjacob 
    784  1.111    mjacob 		/*
    785  1.111    mjacob 		 * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE
    786  1.111    mjacob 		 * NB: command to the 2400 while loading new firmware. This
    787  1.111    mjacob 		 * NB: causes the new f/w to start and immediately crash back
    788  1.111    mjacob 		 * NB: to the ROM.
    789  1.111    mjacob 		 */
    790  1.111    mjacob 
    791  1.111    mjacob 		/*
    792  1.111    mjacob 		 * Keep loading until we run out of f/w.
    793  1.111    mjacob 		 */
    794  1.111    mjacob 		code_org = ptr[2];	/* 1st load address is our start addr */
    795  1.111    mjacob 
    796  1.111    mjacob 		for (;;) {
    797  1.111    mjacob 			uint32_t la, wi, wl;
    798  1.111    mjacob 
    799  1.111    mjacob 			isp_prt(isp, ISP_LOGDEBUG0,
    800  1.111    mjacob 			    "load 0x%x words of code at load address 0x%x",
    801  1.111    mjacob 			    ptr[3], ptr[2]);
    802  1.111    mjacob 
    803  1.111    mjacob 			wi = 0;
    804  1.111    mjacob 			la = ptr[2];
    805  1.111    mjacob 			wl = ptr[3];
    806  1.111    mjacob 
    807  1.111    mjacob 			while (wi < ptr[3]) {
    808  1.111    mjacob 				uint32_t *cp;
    809  1.111    mjacob 				uint32_t nw;
    810  1.111    mjacob 
    811  1.111    mjacob 				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
    812  1.111    mjacob 				if (nw > wl) {
    813  1.111    mjacob 					nw = wl;
    814  1.111    mjacob 				}
    815  1.111    mjacob 				cp = isp->isp_rquest;
    816  1.111    mjacob 				for (i = 0; i < nw; i++) {
    817  1.112    mjacob 					ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
    818  1.111    mjacob 					wl--;
    819  1.111    mjacob 				}
    820  1.111    mjacob 				MEMORYBARRIER(isp, SYNC_REQUEST,
    821  1.111    mjacob 				    0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
    822  1.111    mjacob 				MEMZERO(&mbs, sizeof (mbs));
    823  1.111    mjacob 				mbs.param[0] = MBOX_LOAD_RISC_RAM;
    824  1.111    mjacob 				mbs.param[1] = la;
    825  1.111    mjacob 				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
    826  1.111    mjacob 				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
    827  1.111    mjacob 				mbs.param[4] = nw >> 16;
    828  1.111    mjacob 				mbs.param[5] = nw;
    829  1.111    mjacob 				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
    830  1.111    mjacob 				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
    831  1.111    mjacob 				mbs.param[8] = la >> 16;
    832  1.111    mjacob 				mbs.logval = MBLOGALL;
    833  1.111    mjacob 				isp_mboxcmd(isp, &mbs);
    834  1.111    mjacob 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    835  1.111    mjacob 					isp_prt(isp, ISP_LOGERR,
    836  1.111    mjacob 					    "F/W Risc Ram Load Failed");
    837  1.111    mjacob 					ISP_RESET0(isp);
    838  1.111    mjacob 					return;
    839  1.111    mjacob 				}
    840  1.111    mjacob 				la += nw;
    841  1.111    mjacob 			}
    842  1.111    mjacob 
    843  1.111    mjacob 			if (ptr[1] == 0) {
    844  1.111    mjacob 				break;
    845  1.111    mjacob 			}
    846  1.111    mjacob 			ptr += ptr[3];
    847  1.111    mjacob 		}
    848  1.111    mjacob 		isp->isp_loaded_fw = 1;
    849  1.111    mjacob 	} else if (dodnld && IS_23XX(isp)) {
    850  1.111    mjacob 		const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
    851  1.111    mjacob 		uint16_t wi, wl, segno;
    852  1.111    mjacob 		uint32_t la;
    853  1.111    mjacob 
    854  1.111    mjacob 		la = code_org;
    855  1.111    mjacob 		segno = 0;
    856  1.111    mjacob 
    857  1.111    mjacob 		for (;;) {
    858  1.111    mjacob 			uint32_t nxtaddr;
    859  1.111    mjacob 
    860  1.111    mjacob 			isp_prt(isp, ISP_LOGDEBUG0,
    861  1.111    mjacob 			    "load 0x%x words of code at load address 0x%x",
    862  1.111    mjacob 			    ptr[3], la);
    863  1.111    mjacob 
    864  1.111    mjacob 			wi = 0;
    865  1.111    mjacob 			wl = ptr[3];
    866  1.111    mjacob 
    867  1.111    mjacob 			while (wi < ptr[3]) {
    868  1.111    mjacob 				uint16_t *cp;
    869  1.111    mjacob 				uint32_t nw;
    870  1.111    mjacob 
    871  1.111    mjacob 				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
    872  1.111    mjacob 				if (nw > wl) {
    873  1.111    mjacob 					nw = wl;
    874  1.111    mjacob 				}
    875  1.111    mjacob 				if (nw > (1 << 15)) {
    876  1.111    mjacob 					nw = 1 << 15;
    877  1.111    mjacob 				}
    878  1.111    mjacob 				cp = isp->isp_rquest;
    879  1.111    mjacob 				for (i = 0; i < nw; i++) {
    880  1.112    mjacob 					ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
    881  1.111    mjacob 					wl--;
    882  1.111    mjacob 				}
    883  1.111    mjacob 				MEMORYBARRIER(isp, SYNC_REQUEST,
    884  1.111    mjacob 				    0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
    885  1.111    mjacob 				MEMZERO(&mbs, sizeof (mbs));
    886  1.111    mjacob 				mbs.param[0] = MBOX_LOAD_RISC_RAM;
    887  1.111    mjacob 				mbs.param[1] = la;
    888  1.111    mjacob 				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
    889  1.111    mjacob 				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
    890  1.111    mjacob 				mbs.param[4] = nw;
    891  1.111    mjacob 				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
    892  1.111    mjacob 				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
    893  1.111    mjacob 				mbs.param[8] = la >> 16;
    894  1.111    mjacob 				mbs.logval = MBLOGALL;
    895  1.111    mjacob 				isp_mboxcmd(isp, &mbs);
    896  1.111    mjacob 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    897  1.111    mjacob 					isp_prt(isp, ISP_LOGERR,
    898  1.111    mjacob 					    "F/W Risc Ram Load Failed");
    899  1.111    mjacob 					ISP_RESET0(isp);
    900  1.111    mjacob 					return;
    901  1.111    mjacob 				}
    902  1.111    mjacob 				la += nw;
    903  1.111    mjacob 			}
    904  1.111    mjacob 
    905  1.111    mjacob 			if (!IS_2322(isp)) {
    906  1.111    mjacob 				/*
    907  1.111    mjacob 				 * Verify that it downloaded correctly.
    908  1.111    mjacob 				 */
    909  1.111    mjacob 				MEMZERO(&mbs, sizeof (mbs));
    910  1.111    mjacob 				mbs.param[0] = MBOX_VERIFY_CHECKSUM;
    911  1.111    mjacob 				mbs.param[1] = code_org;
    912  1.111    mjacob 				mbs.logval = MBLOGNONE;
    913  1.111    mjacob 				isp_mboxcmd(isp, &mbs);
    914  1.111    mjacob 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    915  1.111    mjacob 					isp_prt(isp, ISP_LOGERR, dcrc);
    916  1.111    mjacob 					ISP_RESET0(isp);
    917  1.111    mjacob 					return;
    918  1.111    mjacob 				}
    919  1.111    mjacob 				break;
    920  1.111    mjacob 			}
    921   1.79    mjacob 
    922  1.111    mjacob 			if (++segno == 3) {
    923  1.111    mjacob 				break;
    924  1.111    mjacob 			}
    925  1.111    mjacob 
    926  1.111    mjacob 			/*
    927  1.111    mjacob 			 * If we're a 2322, the firmware actually comes in
    928  1.111    mjacob 			 * three chunks. We loaded the first at the code_org
    929  1.111    mjacob 			 * address. The other two chunks, which follow right
    930  1.111    mjacob 			 * after each other in memory here, get loaded at
    931  1.111    mjacob 			 * addresses specfied at offset 0x9..0xB.
    932  1.111    mjacob 			 */
    933  1.111    mjacob 
    934  1.111    mjacob 			nxtaddr = ptr[3];
    935  1.111    mjacob 			ptr = &ptr[nxtaddr];
    936  1.111    mjacob 			la = ptr[5] | ((ptr[4] & 0x3f) << 16);
    937  1.111    mjacob 		}
    938  1.111    mjacob 		isp->isp_loaded_fw = 1;
    939  1.111    mjacob 	} else if (dodnld) {
    940  1.111    mjacob 		union {
    941  1.111    mjacob 			const uint16_t *cp;
    942  1.111    mjacob 			uint16_t *np;
    943  1.111    mjacob 		} u;
    944  1.111    mjacob 		u.cp = isp->isp_mdvec->dv_ispfw;
    945  1.111    mjacob 		isp->isp_mbxworkp = &u.np[1];
    946  1.111    mjacob 		isp->isp_mbxwrk0 = u.np[3] - 1;
    947   1.88    mjacob 		isp->isp_mbxwrk1 = code_org + 1;
    948  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
    949   1.88    mjacob 		mbs.param[0] = MBOX_WRITE_RAM_WORD;
    950   1.88    mjacob 		mbs.param[1] = code_org;
    951  1.111    mjacob 		mbs.param[2] = u.np[0];
    952  1.111    mjacob 		mbs.logval = MBLOGNONE;
    953  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
    954   1.88    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    955   1.88    mjacob 			isp_prt(isp, ISP_LOGERR,
    956   1.88    mjacob 			    "F/W download failed at word %d",
    957   1.88    mjacob 			    isp->isp_mbxwrk1 - code_org);
    958  1.111    mjacob 			ISP_RESET0(isp);
    959  1.111    mjacob 			return;
    960   1.10    mjacob 		}
    961   1.31    mjacob 		/*
    962   1.31    mjacob 		 * Verify that it downloaded correctly.
    963   1.31    mjacob 		 */
    964  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
    965   1.31    mjacob 		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
    966   1.79    mjacob 		mbs.param[1] = code_org;
    967  1.111    mjacob 		mbs.logval = MBLOGNONE;
    968  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
    969   1.31    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
    970  1.111    mjacob 			isp_prt(isp, ISP_LOGERR, dcrc);
    971  1.111    mjacob 			ISP_RESET0(isp);
    972   1.31    mjacob 			return;
    973   1.10    mjacob 		}
    974   1.58    mjacob 		isp->isp_loaded_fw = 1;
    975   1.10    mjacob 	} else {
    976   1.58    mjacob 		isp->isp_loaded_fw = 0;
    977   1.57    mjacob 		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
    978    1.1       cgd 	}
    979    1.1       cgd 
    980    1.1       cgd 	/*
    981   1.10    mjacob 	 * Now start it rolling.
    982   1.10    mjacob 	 *
    983   1.10    mjacob 	 * If we didn't actually download f/w,
    984   1.10    mjacob 	 * we still need to (re)start it.
    985    1.1       cgd 	 */
    986    1.1       cgd 
    987   1.79    mjacob 
    988  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
    989  1.111    mjacob 	mbs.timeout = 1000000;
    990    1.1       cgd 	mbs.param[0] = MBOX_EXEC_FIRMWARE;
    991  1.111    mjacob 	if (IS_24XX(isp)) {
    992  1.111    mjacob 		mbs.param[1] = code_org >> 16;
    993  1.111    mjacob 		mbs.param[2] = code_org;
    994  1.111    mjacob 		if (isp->isp_loaded_fw) {
    995  1.111    mjacob 			mbs.param[3] = 0;
    996  1.111    mjacob 		} else {
    997  1.111    mjacob 			mbs.param[3] = 1;
    998  1.111    mjacob 		}
    999  1.111    mjacob 	} else if (IS_2322(isp)) {
   1000  1.111    mjacob 		mbs.param[1] = code_org;
   1001  1.111    mjacob 		if (isp->isp_loaded_fw) {
   1002  1.111    mjacob 			mbs.param[2] = 0;
   1003  1.111    mjacob 		} else {
   1004  1.111    mjacob 			mbs.param[2] = 1;
   1005  1.111    mjacob 		}
   1006  1.111    mjacob 	} else {
   1007  1.111    mjacob 		mbs.param[1] = code_org;
   1008  1.111    mjacob 	}
   1009  1.111    mjacob 
   1010  1.111    mjacob 	mbs.logval = MBLOGALL;
   1011  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1012  1.111    mjacob 	if (IS_2322(isp) || IS_24XX(isp)) {
   1013  1.111    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1014  1.111    mjacob 			ISP_RESET0(isp);
   1015  1.111    mjacob 			return;
   1016  1.111    mjacob 		}
   1017  1.111    mjacob 	}
   1018  1.111    mjacob 
   1019   1.94    mjacob 	/*
   1020  1.111    mjacob 	 * Give it a chance to finish starting up.
   1021   1.94    mjacob 	 */
   1022  1.111    mjacob 	USEC_DELAY(250000);
   1023    1.4    mjacob 
   1024   1.38    mjacob 	if (IS_SCSI(isp)) {
   1025   1.10    mjacob 		/*
   1026   1.25    mjacob 		 * Set CLOCK RATE, but only if asked to.
   1027   1.10    mjacob 		 */
   1028   1.36    mjacob 		if (isp->isp_clock) {
   1029   1.10    mjacob 			mbs.param[0] = MBOX_SET_CLOCK_RATE;
   1030   1.36    mjacob 			mbs.param[1] = isp->isp_clock;
   1031  1.111    mjacob 			mbs.logval = MBLOGNONE;
   1032  1.111    mjacob 			isp_mboxcmd(isp, &mbs);
   1033   1.57    mjacob 			/* we will try not to care if this fails */
   1034    1.4    mjacob 		}
   1035    1.4    mjacob 	}
   1036   1.57    mjacob 
   1037  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1038    1.1       cgd 	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
   1039  1.111    mjacob 	mbs.logval = MBLOGALL;
   1040  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1041    1.1       cgd 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1042  1.111    mjacob 		ISP_RESET0(isp);
   1043  1.111    mjacob 		return;
   1044  1.111    mjacob 	}
   1045  1.111    mjacob 
   1046  1.111    mjacob 	if (IS_24XX(isp) && mbs.param[1] == 0xdead) {
   1047  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
   1048  1.111    mjacob 		ISP_RESET0(isp);
   1049    1.1       cgd 		return;
   1050    1.1       cgd 	}
   1051   1.80    mjacob 
   1052   1.80    mjacob 	/*
   1053   1.80    mjacob 	 * The SBus firmware that we are using apparently does not return
   1054   1.80    mjacob 	 * major, minor, micro revisions in the mailbox registers, which
   1055   1.80    mjacob 	 * is really, really, annoying.
   1056   1.80    mjacob 	 */
   1057   1.86    mjacob 	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
   1058   1.80    mjacob 		if (dodnld) {
   1059   1.80    mjacob #ifdef	ISP_TARGET_MODE
   1060   1.80    mjacob 			isp->isp_fwrev[0] = 7;
   1061   1.80    mjacob 			isp->isp_fwrev[1] = 55;
   1062   1.80    mjacob #else
   1063   1.80    mjacob 			isp->isp_fwrev[0] = 1;
   1064   1.80    mjacob 			isp->isp_fwrev[1] = 37;
   1065   1.80    mjacob #endif
   1066   1.80    mjacob 			isp->isp_fwrev[2] = 0;
   1067  1.111    mjacob 		}
   1068   1.80    mjacob 	} else {
   1069   1.80    mjacob 		isp->isp_fwrev[0] = mbs.param[1];
   1070   1.80    mjacob 		isp->isp_fwrev[1] = mbs.param[2];
   1071   1.80    mjacob 		isp->isp_fwrev[2] = mbs.param[3];
   1072   1.80    mjacob 	}
   1073  1.111    mjacob 
   1074  1.111    mjacob 	isp_prt(isp, ISP_LOGALL,
   1075   1.79    mjacob 	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
   1076   1.79    mjacob 	    btype, isp->isp_revision, dodnld? "loaded" : "resident",
   1077   1.80    mjacob 	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
   1078   1.80    mjacob 
   1079   1.34    mjacob 	if (IS_FC(isp)) {
   1080   1.80    mjacob 		/*
   1081   1.80    mjacob 		 * We do not believe firmware attributes for 2100 code less
   1082   1.98    mjacob 		 * than 1.17.0, unless it's the firmware we specifically
   1083   1.98    mjacob 		 * are loading.
   1084   1.98    mjacob 		 *
   1085  1.111    mjacob 		 * Note that all 22XX and later f/w is greater than 1.X.0.
   1086   1.80    mjacob 		 */
   1087  1.111    mjacob 		if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
   1088   1.98    mjacob #ifdef	USE_SMALLER_2100_FIRMWARE
   1089   1.98    mjacob 			FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
   1090   1.98    mjacob #else
   1091   1.80    mjacob 			FCPARAM(isp)->isp_fwattr = 0;
   1092   1.98    mjacob #endif
   1093   1.80    mjacob 		} else {
   1094   1.80    mjacob 			FCPARAM(isp)->isp_fwattr = mbs.param[6];
   1095   1.80    mjacob 			isp_prt(isp, ISP_LOGDEBUG0,
   1096   1.80    mjacob 			    "Firmware Attributes = 0x%x", mbs.param[6]);
   1097   1.80    mjacob 		}
   1098  1.111    mjacob 		FCPARAM(isp)->isp_2klogin = 0;
   1099  1.111    mjacob 		FCPARAM(isp)->isp_sccfw = 0;
   1100  1.111    mjacob 		FCPARAM(isp)->isp_tmode = 0;
   1101  1.111    mjacob 		if (IS_24XX(isp)) {
   1102  1.111    mjacob 			FCPARAM(isp)->isp_2klogin = 1;
   1103  1.111    mjacob 			FCPARAM(isp)->isp_sccfw = 1;
   1104  1.111    mjacob 			FCPARAM(isp)->isp_tmode = 1;
   1105  1.111    mjacob 		} else {
   1106  1.111    mjacob 			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
   1107  1.111    mjacob 				FCPARAM(isp)->isp_sccfw = 1;
   1108  1.111    mjacob 			}
   1109  1.111    mjacob 			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_2KLOGINS) {
   1110  1.111    mjacob 				FCPARAM(isp)->isp_2klogin = 1;
   1111  1.111    mjacob 				FCPARAM(isp)->isp_sccfw = 1;
   1112  1.111    mjacob 			}
   1113  1.111    mjacob 			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) {
   1114  1.111    mjacob 				FCPARAM(isp)->isp_tmode = 1;
   1115  1.111    mjacob 			}
   1116  1.111    mjacob 		}
   1117  1.111    mjacob 		if (FCPARAM(isp)->isp_2klogin) {
   1118  1.111    mjacob 			isp_prt(isp, ISP_LOGCONFIG, "2K Logins Supported");
   1119   1.32    mjacob 		}
   1120   1.32    mjacob 	}
   1121   1.38    mjacob 
   1122   1.35    mjacob 	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
   1123   1.35    mjacob 	    isp->isp_romfw_rev[2]) {
   1124   1.57    mjacob 		isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",
   1125   1.35    mjacob 		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
   1126   1.35    mjacob 		    isp->isp_romfw_rev[2]);
   1127   1.25    mjacob 	}
   1128   1.38    mjacob 
   1129  1.111    mjacob 	if (!IS_24XX(isp)) {
   1130  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1131  1.111    mjacob 		mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
   1132  1.111    mjacob 		mbs.logval = MBLOGALL;
   1133  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1134  1.111    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1135  1.111    mjacob 			ISP_RESET0(isp);
   1136  1.111    mjacob 			return;
   1137  1.111    mjacob 		}
   1138  1.111    mjacob 		if (isp->isp_maxcmds >= mbs.param[2]) {
   1139  1.111    mjacob 			isp->isp_maxcmds = mbs.param[2];
   1140  1.111    mjacob 		}
   1141   1.38    mjacob 	}
   1142  1.111    mjacob 	isp_prt(isp, ISP_LOGCONFIG,
   1143  1.111    mjacob 	    "%d max I/O command limit set", isp->isp_maxcmds);
   1144   1.10    mjacob 	isp_fw_state(isp);
   1145   1.38    mjacob 
   1146    1.1       cgd 	isp->isp_state = ISP_RESETSTATE;
   1147   1.54    mjacob 
   1148   1.54    mjacob 	/*
   1149   1.54    mjacob 	 * Okay- now that we have new firmware running, we now (re)set our
   1150   1.54    mjacob 	 * notion of how many luns we support. This is somewhat tricky because
   1151   1.80    mjacob 	 * if we haven't loaded firmware, we sometimes do not have an easy way
   1152   1.80    mjacob 	 * of knowing how many luns we support.
   1153   1.54    mjacob 	 *
   1154   1.54    mjacob 	 * Expanded lun firmware gives you 32 luns for SCSI cards and
   1155   1.93    mjacob 	 * 16384 luns for Fibre Channel cards.
   1156   1.54    mjacob 	 *
   1157   1.80    mjacob 	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
   1158   1.80    mjacob 	 * we do get a firmware attributes word returned in mailbox register 6.
   1159   1.80    mjacob 	 *
   1160  1.101    mjacob 	 * Because the lun is in a different position in the Request Queue
   1161   1.54    mjacob 	 * Entry structure for Fibre Channel with expanded lun firmware, we
   1162   1.54    mjacob 	 * can only support one lun (lun zero) when we don't know what kind
   1163   1.54    mjacob 	 * of firmware we're running.
   1164   1.54    mjacob 	 */
   1165   1.95    mjacob 	if (IS_SCSI(isp)) {
   1166   1.95    mjacob 		if (dodnld) {
   1167   1.95    mjacob 			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
   1168   1.54    mjacob 				isp->isp_maxluns = 32;
   1169   1.54    mjacob 			} else {
   1170   1.80    mjacob 				isp->isp_maxluns = 8;
   1171   1.54    mjacob 			}
   1172   1.54    mjacob 		} else {
   1173   1.95    mjacob 			isp->isp_maxluns = 8;
   1174   1.95    mjacob 		}
   1175   1.95    mjacob 	} else {
   1176  1.111    mjacob 		if (FCPARAM(isp)->isp_sccfw) {
   1177   1.95    mjacob 			isp->isp_maxluns = 16384;
   1178   1.95    mjacob 		} else {
   1179   1.95    mjacob 			isp->isp_maxluns = 16;
   1180   1.54    mjacob 		}
   1181   1.54    mjacob 	}
   1182  1.111    mjacob 	/*
   1183  1.111    mjacob 	 * Must do this first to get defaults established.
   1184  1.111    mjacob 	 */
   1185  1.111    mjacob 	if (IS_SCSI(isp)) {
   1186  1.111    mjacob 		isp_setdfltparm(isp, 0);
   1187  1.111    mjacob 		if (IS_DUALBUS(isp)) {
   1188  1.111    mjacob 			isp_setdfltparm(isp, 1);
   1189  1.111    mjacob 		}
   1190  1.111    mjacob 	} else {
   1191  1.111    mjacob 		isp_setdfltfcparm(isp);
   1192  1.111    mjacob 	}
   1193  1.111    mjacob 
   1194    1.1       cgd }
   1195    1.1       cgd 
   1196    1.1       cgd /*
   1197   1.31    mjacob  * Initialize Parameters of Hardware to a known state.
   1198   1.24    mjacob  *
   1199   1.24    mjacob  * Locks are held before coming here.
   1200    1.1       cgd  */
   1201   1.24    mjacob 
   1202    1.1       cgd void
   1203  1.111    mjacob isp_init(ispsoftc_t *isp)
   1204    1.1       cgd {
   1205   1.70    mjacob 	if (IS_FC(isp)) {
   1206  1.111    mjacob 		/*
   1207  1.111    mjacob 		 * Do this *before* initializing the firmware.
   1208  1.111    mjacob 		 */
   1209  1.111    mjacob 		ISP_MARK_PORTDB(isp, 0);
   1210  1.111    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   1211  1.111    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
   1212  1.111    mjacob 
   1213  1.111    mjacob 		if (isp->isp_role != ISP_ROLE_NONE) {
   1214  1.111    mjacob 			if (IS_24XX(isp)) {
   1215  1.111    mjacob 				isp_fibre_init_2400(isp);
   1216  1.111    mjacob 			} else {
   1217  1.111    mjacob 				isp_fibre_init(isp);
   1218  1.111    mjacob 			}
   1219  1.111    mjacob 		}
   1220   1.70    mjacob 	} else {
   1221   1.70    mjacob 		isp_scsi_init(isp);
   1222   1.36    mjacob 	}
   1223   1.36    mjacob }
   1224   1.36    mjacob 
   1225   1.36    mjacob static void
   1226  1.111    mjacob isp_scsi_init(ispsoftc_t *isp)
   1227   1.36    mjacob {
   1228   1.36    mjacob 	sdparam *sdp_chan0, *sdp_chan1;
   1229    1.1       cgd 	mbreg_t mbs;
   1230   1.36    mjacob 
   1231   1.36    mjacob 	sdp_chan0 = isp->isp_param;
   1232   1.36    mjacob 	sdp_chan1 = sdp_chan0;
   1233   1.44    mjacob 	if (IS_DUALBUS(isp)) {
   1234   1.36    mjacob 		sdp_chan1++;
   1235   1.36    mjacob 	}
   1236   1.36    mjacob 
   1237   1.70    mjacob 	/*
   1238   1.70    mjacob 	 * If we have no role (neither target nor initiator), return.
   1239   1.70    mjacob 	 */
   1240   1.70    mjacob 	if (isp->isp_role == ISP_ROLE_NONE) {
   1241   1.70    mjacob 		return;
   1242   1.70    mjacob 	}
   1243   1.70    mjacob 
   1244   1.36    mjacob 	/* First do overall per-card settings. */
   1245   1.25    mjacob 
   1246   1.25    mjacob 	/*
   1247   1.36    mjacob 	 * If we have fast memory timing enabled, turn it on.
   1248   1.25    mjacob 	 */
   1249   1.58    mjacob 	if (sdp_chan0->isp_fast_mttr) {
   1250   1.36    mjacob 		ISP_WRITE(isp, RISC_MTR, 0x1313);
   1251   1.36    mjacob 	}
   1252   1.25    mjacob 
   1253   1.25    mjacob 	/*
   1254   1.36    mjacob 	 * Set Retry Delay and Count.
   1255   1.36    mjacob 	 * You set both channels at the same time.
   1256   1.33    mjacob 	 */
   1257  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1258   1.36    mjacob 	mbs.param[0] = MBOX_SET_RETRY_COUNT;
   1259   1.36    mjacob 	mbs.param[1] = sdp_chan0->isp_retry_count;
   1260   1.36    mjacob 	mbs.param[2] = sdp_chan0->isp_retry_delay;
   1261   1.36    mjacob 	mbs.param[6] = sdp_chan1->isp_retry_count;
   1262   1.36    mjacob 	mbs.param[7] = sdp_chan1->isp_retry_delay;
   1263  1.111    mjacob 	mbs.logval = MBLOGALL;
   1264  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1265   1.36    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1266   1.33    mjacob 		return;
   1267   1.33    mjacob 	}
   1268   1.34    mjacob 
   1269   1.33    mjacob 	/*
   1270   1.36    mjacob 	 * Set ASYNC DATA SETUP time. This is very important.
   1271   1.25    mjacob 	 */
   1272  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1273   1.36    mjacob 	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
   1274   1.36    mjacob 	mbs.param[1] = sdp_chan0->isp_async_data_setup;
   1275   1.36    mjacob 	mbs.param[2] = sdp_chan1->isp_async_data_setup;
   1276  1.111    mjacob 	mbs.logval = MBLOGALL;
   1277  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1278   1.36    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1279   1.10    mjacob 		return;
   1280    1.1       cgd 	}
   1281    1.1       cgd 
   1282   1.10    mjacob 	/*
   1283   1.36    mjacob 	 * Set ACTIVE Negation State.
   1284   1.32    mjacob 	 */
   1285  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1286   1.36    mjacob 	mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
   1287   1.36    mjacob 	mbs.param[1] =
   1288   1.36    mjacob 	    (sdp_chan0->isp_req_ack_active_neg << 4) |
   1289   1.36    mjacob 	    (sdp_chan0->isp_data_line_active_neg << 5);
   1290   1.36    mjacob 	mbs.param[2] =
   1291   1.36    mjacob 	    (sdp_chan1->isp_req_ack_active_neg << 4) |
   1292   1.36    mjacob 	    (sdp_chan1->isp_data_line_active_neg << 5);
   1293  1.111    mjacob 	mbs.logval = MBLOGNONE;
   1294  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1295   1.36    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1296   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   1297   1.57    mjacob 		    "failed to set active negation state (%d,%d), (%d,%d)",
   1298   1.36    mjacob 		    sdp_chan0->isp_req_ack_active_neg,
   1299   1.36    mjacob 		    sdp_chan0->isp_data_line_active_neg,
   1300   1.36    mjacob 		    sdp_chan1->isp_req_ack_active_neg,
   1301   1.36    mjacob 		    sdp_chan1->isp_data_line_active_neg);
   1302   1.36    mjacob 		/*
   1303   1.36    mjacob 		 * But don't return.
   1304   1.36    mjacob 		 */
   1305   1.32    mjacob 	}
   1306   1.32    mjacob 
   1307   1.32    mjacob 	/*
   1308   1.36    mjacob 	 * Set the Tag Aging limit
   1309   1.10    mjacob 	 */
   1310  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1311   1.36    mjacob 	mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
   1312   1.36    mjacob 	mbs.param[1] = sdp_chan0->isp_tag_aging;
   1313   1.36    mjacob 	mbs.param[2] = sdp_chan1->isp_tag_aging;
   1314  1.111    mjacob 	mbs.logval = MBLOGALL;
   1315  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1316    1.1       cgd 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1317   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
   1318   1.57    mjacob 		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
   1319    1.1       cgd 		return;
   1320    1.1       cgd 	}
   1321    1.1       cgd 
   1322   1.25    mjacob 	/*
   1323   1.36    mjacob 	 * Set selection timeout.
   1324   1.25    mjacob 	 */
   1325  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1326   1.36    mjacob 	mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
   1327   1.36    mjacob 	mbs.param[1] = sdp_chan0->isp_selection_timeout;
   1328   1.36    mjacob 	mbs.param[2] = sdp_chan1->isp_selection_timeout;
   1329  1.111    mjacob 	mbs.logval = MBLOGALL;
   1330  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1331    1.1       cgd 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1332    1.1       cgd 		return;
   1333    1.1       cgd 	}
   1334    1.1       cgd 
   1335   1.36    mjacob 	/* now do per-channel settings */
   1336   1.36    mjacob 	isp_scsi_channel_init(isp, 0);
   1337   1.44    mjacob 	if (IS_DUALBUS(isp))
   1338   1.36    mjacob 		isp_scsi_channel_init(isp, 1);
   1339   1.36    mjacob 
   1340   1.25    mjacob 	/*
   1341   1.36    mjacob 	 * Now enable request/response queues
   1342   1.25    mjacob 	 */
   1343   1.36    mjacob 
   1344   1.99    mjacob 	if (IS_ULTRA2(isp) || IS_1240(isp)) {
   1345  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1346   1.99    mjacob 		mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
   1347   1.99    mjacob 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
   1348   1.99    mjacob 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
   1349   1.99    mjacob 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
   1350   1.99    mjacob 		mbs.param[4] = 0;
   1351   1.99    mjacob 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
   1352   1.99    mjacob 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
   1353  1.111    mjacob 		mbs.logval = MBLOGALL;
   1354  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1355   1.99    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1356   1.99    mjacob 			return;
   1357   1.99    mjacob 		}
   1358   1.99    mjacob 		isp->isp_residx = mbs.param[5];
   1359   1.99    mjacob 
   1360  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1361   1.99    mjacob 		mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
   1362   1.99    mjacob 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
   1363   1.99    mjacob 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
   1364   1.99    mjacob 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
   1365   1.99    mjacob 		mbs.param[5] = 0;
   1366   1.99    mjacob 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
   1367   1.99    mjacob 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
   1368  1.111    mjacob 		mbs.logval = MBLOGALL;
   1369  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1370   1.99    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1371   1.99    mjacob 			return;
   1372   1.99    mjacob 		}
   1373   1.99    mjacob 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
   1374   1.99    mjacob 	} else {
   1375  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1376   1.99    mjacob 		mbs.param[0] = MBOX_INIT_RES_QUEUE;
   1377   1.99    mjacob 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
   1378   1.99    mjacob 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
   1379   1.99    mjacob 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
   1380   1.99    mjacob 		mbs.param[4] = 0;
   1381  1.111    mjacob 		mbs.logval = MBLOGALL;
   1382  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1383   1.99    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1384   1.99    mjacob 			return;
   1385   1.99    mjacob 		}
   1386   1.99    mjacob 		isp->isp_residx = mbs.param[5];
   1387    1.1       cgd 
   1388  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1389   1.99    mjacob 		mbs.param[0] = MBOX_INIT_REQ_QUEUE;
   1390   1.99    mjacob 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
   1391   1.99    mjacob 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
   1392   1.99    mjacob 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
   1393   1.99    mjacob 		mbs.param[5] = 0;
   1394  1.111    mjacob 		mbs.logval = MBLOGALL;
   1395  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1396   1.99    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1397   1.99    mjacob 			return;
   1398   1.99    mjacob 		}
   1399   1.99    mjacob 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
   1400    1.1       cgd 	}
   1401    1.1       cgd 
   1402   1.25    mjacob 	/*
   1403   1.45    mjacob 	 * Turn on Fast Posting, LVD transitions
   1404   1.45    mjacob 	 *
   1405   1.45    mjacob 	 * Ultra2 F/W always has had fast posting (and LVD transitions)
   1406   1.45    mjacob 	 *
   1407   1.50    mjacob 	 * Ultra and older (i.e., SBus) cards may not. It's just safer
   1408   1.50    mjacob 	 * to assume not for them.
   1409   1.25    mjacob 	 */
   1410   1.25    mjacob 
   1411  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1412   1.45    mjacob 	mbs.param[0] = MBOX_SET_FW_FEATURES;
   1413   1.45    mjacob 	mbs.param[1] = 0;
   1414   1.45    mjacob 	if (IS_ULTRA2(isp))
   1415   1.45    mjacob 		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
   1416   1.88    mjacob #ifndef	ISP_NO_RIO
   1417   1.88    mjacob 	if (IS_ULTRA2(isp) || IS_1240(isp))
   1418   1.88    mjacob 		mbs.param[1] |= FW_FEATURE_RIO_16BIT;
   1419   1.88    mjacob #else
   1420   1.49    mjacob 	if (IS_ULTRA2(isp) || IS_1240(isp))
   1421   1.49    mjacob 		mbs.param[1] |= FW_FEATURE_FAST_POST;
   1422   1.88    mjacob #endif
   1423   1.45    mjacob 	if (mbs.param[1] != 0) {
   1424  1.111    mjacob 		uint16_t sfeat = mbs.param[1];
   1425  1.111    mjacob 		mbs.logval = MBLOGALL;
   1426  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1427   1.57    mjacob 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
   1428   1.57    mjacob 			isp_prt(isp, ISP_LOGINFO,
   1429   1.57    mjacob 			    "Enabled FW features (0x%x)", sfeat);
   1430   1.36    mjacob 		}
   1431    1.1       cgd 	}
   1432    1.1       cgd 
   1433   1.25    mjacob 	/*
   1434   1.36    mjacob 	 * Let the outer layers decide whether to issue a SCSI bus reset.
   1435   1.25    mjacob 	 */
   1436   1.36    mjacob 	isp->isp_state = ISP_INITSTATE;
   1437   1.36    mjacob }
   1438   1.25    mjacob 
   1439   1.36    mjacob static void
   1440  1.111    mjacob isp_scsi_channel_init(ispsoftc_t *isp, int channel)
   1441   1.36    mjacob {
   1442   1.36    mjacob 	sdparam *sdp;
   1443   1.36    mjacob 	mbreg_t mbs;
   1444   1.36    mjacob 	int tgt;
   1445   1.36    mjacob 
   1446   1.36    mjacob 	sdp = isp->isp_param;
   1447   1.36    mjacob 	sdp += channel;
   1448   1.36    mjacob 
   1449   1.36    mjacob 	/*
   1450   1.36    mjacob 	 * Set (possibly new) Initiator ID.
   1451   1.36    mjacob 	 */
   1452  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1453   1.36    mjacob 	mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
   1454   1.36    mjacob 	mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
   1455  1.111    mjacob 	mbs.logval = MBLOGALL;
   1456  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1457    1.1       cgd 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1458    1.1       cgd 		return;
   1459    1.1       cgd 	}
   1460   1.73    mjacob 	isp_prt(isp, ISP_LOGINFO, "Initiator ID is %d on Channel %d",
   1461   1.73    mjacob 	    sdp->isp_initiator_id, channel);
   1462   1.62    mjacob 
   1463    1.1       cgd 
   1464   1.25    mjacob 	/*
   1465   1.79    mjacob 	 * Set current per-target parameters to an initial safe minimum.
   1466   1.25    mjacob 	 */
   1467   1.25    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   1468   1.54    mjacob 		int lun;
   1469  1.111    mjacob 		uint16_t sdf;
   1470   1.10    mjacob 
   1471   1.36    mjacob 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
   1472    1.1       cgd 			continue;
   1473   1.36    mjacob 		}
   1474   1.74    mjacob #ifndef	ISP_TARGET_MODE
   1475   1.79    mjacob 		sdf = sdp->isp_devparam[tgt].goal_flags;
   1476   1.79    mjacob 		sdf &= DPARM_SAFE_DFLT;
   1477   1.79    mjacob 		/*
   1478   1.79    mjacob 		 * It is not quite clear when this changed over so that
   1479   1.79    mjacob 		 * we could force narrow and async for 1000/1020 cards,
   1480   1.79    mjacob 		 * but assume that this is only the case for loaded
   1481   1.79    mjacob 		 * firmware.
   1482   1.79    mjacob 		 */
   1483   1.79    mjacob 		if (isp->isp_loaded_fw) {
   1484   1.79    mjacob 			sdf |= DPARM_NARROW | DPARM_ASYNC;
   1485   1.74    mjacob 		}
   1486   1.74    mjacob #else
   1487   1.36    mjacob 		/*
   1488   1.74    mjacob 		 * The !$*!)$!$)* f/w uses the same index into some
   1489   1.74    mjacob 		 * internal table to decide how to respond to negotiations,
   1490   1.74    mjacob 		 * so if we've said "let's be safe" for ID X, and ID X
   1491   1.74    mjacob 		 * selects *us*, the negotiations will back to 'safe'
   1492   1.74    mjacob 		 * (as in narrow/async). What the f/w *should* do is
   1493   1.74    mjacob 		 * use the initiator id settings to decide how to respond.
   1494   1.36    mjacob 		 */
   1495   1.79    mjacob 		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
   1496   1.74    mjacob #endif
   1497  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1498   1.32    mjacob 		mbs.param[0] = MBOX_SET_TARGET_PARAMS;
   1499   1.74    mjacob 		mbs.param[1] = (channel << 15) | (tgt << 8);
   1500   1.32    mjacob 		mbs.param[2] = sdf;
   1501   1.58    mjacob 		if ((sdf & DPARM_SYNC) == 0) {
   1502   1.58    mjacob 			mbs.param[3] = 0;
   1503   1.58    mjacob 		} else {
   1504   1.58    mjacob 			mbs.param[3] =
   1505   1.79    mjacob 			    (sdp->isp_devparam[tgt].goal_offset << 8) |
   1506   1.79    mjacob 			    (sdp->isp_devparam[tgt].goal_period);
   1507   1.58    mjacob 		}
   1508   1.74    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   1509   1.79    mjacob 		    "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
   1510   1.74    mjacob 		    channel, tgt, mbs.param[2], mbs.param[3] >> 8,
   1511   1.74    mjacob 		    mbs.param[3] & 0xff);
   1512  1.111    mjacob 		mbs.logval = MBLOGNONE;
   1513  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1514    1.1       cgd 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1515   1.32    mjacob 			sdf = DPARM_SAFE_DFLT;
   1516  1.111    mjacob 			MEMZERO(&mbs, sizeof (mbs));
   1517   1.10    mjacob 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
   1518   1.36    mjacob 			mbs.param[1] = (tgt << 8) | (channel << 15);
   1519   1.32    mjacob 			mbs.param[2] = sdf;
   1520   1.58    mjacob 			mbs.param[3] = 0;
   1521  1.111    mjacob 			mbs.logval = MBLOGALL;
   1522  1.111    mjacob 			isp_mboxcmd(isp, &mbs);
   1523   1.10    mjacob 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1524   1.25    mjacob 				continue;
   1525   1.10    mjacob 			}
   1526    1.1       cgd 		}
   1527   1.45    mjacob 
   1528   1.34    mjacob 		/*
   1529   1.58    mjacob 		 * We don't update any information directly from the f/w
   1530   1.58    mjacob 		 * because we need to run at least one command to cause a
   1531   1.58    mjacob 		 * new state to be latched up. So, we just assume that we
   1532   1.58    mjacob 		 * converge to the values we just had set.
   1533   1.58    mjacob 		 *
   1534   1.34    mjacob 		 * Ensure that we don't believe tagged queuing is enabled yet.
   1535   1.34    mjacob 		 * It turns out that sometimes the ISP just ignores our
   1536   1.34    mjacob 		 * attempts to set parameters for devices that it hasn't
   1537   1.34    mjacob 		 * seen yet.
   1538   1.34    mjacob 		 */
   1539   1.79    mjacob 		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
   1540   1.57    mjacob 		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
   1541  1.111    mjacob 			MEMZERO(&mbs, sizeof (mbs));
   1542    1.1       cgd 			mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
   1543   1.36    mjacob 			mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
   1544   1.10    mjacob 			mbs.param[2] = sdp->isp_max_queue_depth;
   1545   1.25    mjacob 			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
   1546  1.111    mjacob 			mbs.logval = MBLOGALL;
   1547  1.111    mjacob 			isp_mboxcmd(isp, &mbs);
   1548    1.1       cgd 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1549   1.25    mjacob 				break;
   1550    1.1       cgd 			}
   1551    1.1       cgd 		}
   1552   1.31    mjacob 	}
   1553   1.60    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   1554   1.60    mjacob 		if (sdp->isp_devparam[tgt].dev_refresh) {
   1555   1.60    mjacob 			isp->isp_sendmarker |= (1 << channel);
   1556   1.60    mjacob 			isp->isp_update |= (1 << channel);
   1557   1.60    mjacob 			break;
   1558   1.60    mjacob 		}
   1559   1.60    mjacob 	}
   1560    1.1       cgd }
   1561    1.1       cgd 
   1562   1.24    mjacob /*
   1563   1.24    mjacob  * Fibre Channel specific initialization.
   1564   1.24    mjacob  */
   1565   1.10    mjacob static void
   1566  1.111    mjacob isp_fibre_init(ispsoftc_t *isp)
   1567   1.10    mjacob {
   1568   1.10    mjacob 	fcparam *fcp;
   1569   1.86    mjacob 	isp_icb_t local, *icbp = &local;
   1570   1.10    mjacob 	mbreg_t mbs;
   1571  1.111    mjacob 	int ownloopid;
   1572  1.111    mjacob 	uint64_t nwwn, pwwn;
   1573   1.10    mjacob 
   1574   1.10    mjacob 	fcp = isp->isp_param;
   1575   1.10    mjacob 
   1576   1.30    mjacob 	MEMZERO(icbp, sizeof (*icbp));
   1577   1.25    mjacob 	icbp->icb_version = ICB_VERSION1;
   1578  1.111    mjacob 	icbp->icb_fwoptions = fcp->isp_fwoptions;
   1579   1.58    mjacob 
   1580   1.58    mjacob 	/*
   1581   1.58    mjacob 	 * Firmware Options are either retrieved from NVRAM or
   1582   1.58    mjacob 	 * are patched elsewhere. We check them for sanity here
   1583   1.58    mjacob 	 * and make changes based on board revision, but otherwise
   1584   1.58    mjacob 	 * let others decide policy.
   1585   1.58    mjacob 	 */
   1586   1.58    mjacob 
   1587   1.43    mjacob 	/*
   1588   1.43    mjacob 	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
   1589   1.43    mjacob 	 */
   1590  1.111    mjacob 	if (IS_2100(isp) && isp->isp_revision < 5) {
   1591  1.111    mjacob 		icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
   1592   1.43    mjacob 	}
   1593   1.58    mjacob 
   1594   1.37    mjacob 	/*
   1595   1.38    mjacob 	 * We have to use FULL LOGIN even though it resets the loop too much
   1596   1.38    mjacob 	 * because otherwise port database entries don't get updated after
   1597   1.52        he 	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
   1598   1.37    mjacob 	 */
   1599   1.97    mjacob 	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
   1600  1.111    mjacob 		icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
   1601   1.38    mjacob 	}
   1602   1.37    mjacob 
   1603   1.37    mjacob 	/*
   1604   1.60    mjacob 	 * Insist on Port Database Update Async notifications
   1605   1.60    mjacob 	 */
   1606  1.111    mjacob 	icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
   1607   1.60    mjacob 
   1608   1.70    mjacob 	/*
   1609   1.70    mjacob 	 * Make sure that target role reflects into fwoptions.
   1610   1.70    mjacob 	 */
   1611   1.70    mjacob 	if (isp->isp_role & ISP_ROLE_TARGET) {
   1612  1.111    mjacob 		icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
   1613   1.70    mjacob 	} else {
   1614  1.111    mjacob 		icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
   1615  1.111    mjacob 	}
   1616  1.111    mjacob 
   1617  1.111    mjacob 	if (isp->isp_role & ISP_ROLE_INITIATOR) {
   1618  1.111    mjacob 		icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
   1619  1.111    mjacob 	} else {
   1620  1.111    mjacob 		icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
   1621   1.70    mjacob 	}
   1622   1.70    mjacob 
   1623   1.25    mjacob 	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
   1624   1.25    mjacob 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
   1625   1.25    mjacob 	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
   1626   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   1627   1.57    mjacob 		    "bad frame length (%d) from NVRAM- using %d",
   1628   1.57    mjacob 		    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
   1629   1.35    mjacob 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
   1630   1.25    mjacob 	}
   1631   1.25    mjacob 	icbp->icb_maxalloc = fcp->isp_maxalloc;
   1632   1.37    mjacob 	if (icbp->icb_maxalloc < 1) {
   1633   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   1634   1.57    mjacob 		    "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
   1635   1.35    mjacob 		icbp->icb_maxalloc = 16;
   1636   1.35    mjacob 	}
   1637   1.25    mjacob 	icbp->icb_execthrottle = fcp->isp_execthrottle;
   1638   1.35    mjacob 	if (icbp->icb_execthrottle < 1) {
   1639   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   1640   1.57    mjacob 		    "bad execution throttle of %d- using 16",
   1641   1.57    mjacob 		    fcp->isp_execthrottle);
   1642   1.37    mjacob 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
   1643   1.35    mjacob 	}
   1644   1.25    mjacob 	icbp->icb_retry_delay = fcp->isp_retry_delay;
   1645   1.25    mjacob 	icbp->icb_retry_count = fcp->isp_retry_count;
   1646  1.111    mjacob 	icbp->icb_hardaddr = fcp->isp_loopid;
   1647  1.111    mjacob 	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
   1648  1.111    mjacob 	if (icbp->icb_hardaddr > 125) {
   1649  1.111    mjacob 		icbp->icb_hardaddr = 0;
   1650  1.111    mjacob 		ownloopid = 0;
   1651  1.111    mjacob 	}
   1652  1.111    mjacob 
   1653  1.111    mjacob 	/*
   1654  1.111    mjacob 	 * Our life seems so much better with 2200s and later with
   1655  1.111    mjacob 	 * the latest f/w if we set Hard Address.
   1656  1.111    mjacob 	 */
   1657  1.111    mjacob 	if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
   1658  1.111    mjacob 		icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
   1659  1.111    mjacob 	}
   1660  1.111    mjacob 
   1661   1.58    mjacob 	/*
   1662   1.58    mjacob 	 * Right now we just set extended options to prefer point-to-point
   1663   1.58    mjacob 	 * over loop based upon some soft config options.
   1664  1.111    mjacob 	 *
   1665   1.79    mjacob 	 * NB: for the 2300, ICBOPT_EXTENDED is required.
   1666   1.58    mjacob 	 */
   1667   1.87    mjacob 	if (IS_2200(isp) || IS_23XX(isp)) {
   1668   1.49    mjacob 		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
   1669   1.49    mjacob 		/*
   1670   1.49    mjacob 		 * Prefer or force Point-To-Point instead Loop?
   1671   1.49    mjacob 		 */
   1672   1.63    mjacob 		switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
   1673   1.63    mjacob 		case ISP_CFG_NPORT:
   1674   1.81    mjacob 			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
   1675   1.63    mjacob 			break;
   1676   1.63    mjacob 		case ISP_CFG_NPORT_ONLY:
   1677   1.81    mjacob 			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
   1678   1.63    mjacob 			break;
   1679   1.63    mjacob 		case ISP_CFG_LPORT_ONLY:
   1680   1.81    mjacob 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
   1681   1.63    mjacob 			break;
   1682   1.63    mjacob 		default:
   1683   1.81    mjacob 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
   1684   1.63    mjacob 			break;
   1685   1.63    mjacob 		}
   1686  1.111    mjacob 		if (IS_2200(isp)) {
   1687  1.111    mjacob 			if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
   1688  1.111    mjacob 				icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT;
   1689  1.113    mjacob 				icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
   1690  1.111    mjacob 				icbp->icb_racctimer = 4;
   1691  1.111    mjacob 				icbp->icb_idelaytimer = 8;
   1692  1.113    mjacob 			} else {
   1693  1.113    mjacob 				icbp->icb_fwoptions |= ICBOPT_FAST_POST;
   1694  1.111    mjacob 			}
   1695  1.111    mjacob 		} else {
   1696   1.97    mjacob 			/*
   1697   1.97    mjacob 			 * QLogic recommends that FAST Posting be turned
   1698   1.97    mjacob 			 * off for 23XX cards and instead allow the HBA
   1699   1.97    mjacob 			 * to write response queue entries and interrupt
   1700   1.97    mjacob 			 * after a delay (ZIO).
   1701   1.97    mjacob 			 */
   1702  1.111    mjacob 			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
   1703  1.111    mjacob 			if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) ==
   1704  1.111    mjacob 			    ICBXOPT_ZIO) {
   1705  1.111    mjacob 				icbp->icb_xfwoptions |= ICBXOPT_ZIO;
   1706  1.111    mjacob 				icbp->icb_idelaytimer = 10;
   1707  1.111    mjacob 			}
   1708   1.81    mjacob 			if (isp->isp_confopts & ISP_CFG_ONEGB) {
   1709   1.81    mjacob 				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
   1710   1.81    mjacob 			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
   1711   1.81    mjacob 				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
   1712   1.81    mjacob 			} else {
   1713   1.81    mjacob 				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
   1714   1.81    mjacob 			}
   1715  1.111    mjacob 			if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
   1716  1.111    mjacob 				icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
   1717  1.111    mjacob 			}
   1718   1.79    mjacob 		}
   1719   1.88    mjacob 	}
   1720   1.88    mjacob 
   1721   1.79    mjacob 
   1722   1.97    mjacob 	/*
   1723  1.111    mjacob 	 * For 22XX > 2.1.26 && 23XX, set some options.
   1724   1.97    mjacob 	 * XXX: Probably okay for newer 2100 f/w too.
   1725   1.97    mjacob 	 */
   1726   1.97    mjacob 	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
   1727   1.79    mjacob 		/*
   1728   1.79    mjacob 		 * Turn on LIP F8 async event (1)
   1729   1.79    mjacob 		 * Turn on generate AE 8013 on all LIP Resets (2)
   1730   1.79    mjacob 		 * Disable LIP F7 switching (8)
   1731   1.79    mjacob 		 */
   1732  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1733   1.79    mjacob 		mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
   1734   1.79    mjacob 		mbs.param[1] = 0xb;
   1735   1.79    mjacob 		mbs.param[2] = 0;
   1736   1.79    mjacob 		mbs.param[3] = 0;
   1737  1.111    mjacob 		mbs.logval = MBLOGALL;
   1738  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1739  1.111    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1740  1.111    mjacob 			return;
   1741  1.111    mjacob 		}
   1742   1.49    mjacob 	}
   1743  1.111    mjacob 	icbp->icb_logintime = ICB_LOGIN_TOV;
   1744  1.111    mjacob 	icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
   1745   1.25    mjacob 
   1746   1.62    mjacob 	nwwn = ISP_NODEWWN(isp);
   1747   1.62    mjacob 	pwwn = ISP_PORTWWN(isp);
   1748   1.62    mjacob 	if (nwwn && pwwn) {
   1749   1.72    mjacob 		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
   1750   1.62    mjacob 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
   1751   1.62    mjacob 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
   1752   1.62    mjacob 		isp_prt(isp, ISP_LOGDEBUG1,
   1753   1.62    mjacob 		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
   1754  1.111    mjacob 		    ((uint32_t) (nwwn >> 32)),
   1755  1.111    mjacob 		    ((uint32_t) (nwwn & 0xffffffff)),
   1756  1.111    mjacob 		    ((uint32_t) (pwwn >> 32)),
   1757  1.111    mjacob 		    ((uint32_t) (pwwn & 0xffffffff)));
   1758  1.111    mjacob 	} else if (pwwn) {
   1759  1.111    mjacob 		icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
   1760  1.111    mjacob 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
   1761  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG1,
   1762  1.111    mjacob 		    "Setting ICB Port 0x%08x%08x",
   1763  1.111    mjacob 		    ((uint32_t) (pwwn >> 32)),
   1764  1.111    mjacob 		    ((uint32_t) (pwwn & 0xffffffff)));
   1765   1.35    mjacob 	} else {
   1766  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
   1767  1.111    mjacob 		return;
   1768   1.28    mjacob 	}
   1769   1.57    mjacob 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
   1770  1.111    mjacob 	if (icbp->icb_rqstqlen < 1) {
   1771  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "bad request queue length");
   1772  1.111    mjacob 	}
   1773   1.57    mjacob 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
   1774  1.111    mjacob 	if (icbp->icb_rsltqlen < 1) {
   1775  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "bad result queue length");
   1776  1.111    mjacob 	}
   1777   1.79    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
   1778   1.79    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
   1779   1.79    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
   1780   1.79    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
   1781   1.79    mjacob 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
   1782   1.79    mjacob 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
   1783   1.79    mjacob 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
   1784   1.79    mjacob 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
   1785  1.111    mjacob 
   1786   1.97    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   1787   1.97    mjacob 	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
   1788   1.97    mjacob 	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
   1789   1.88    mjacob 
   1790   1.88    mjacob 	FC_SCRATCH_ACQUIRE(isp);
   1791   1.86    mjacob 	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
   1792   1.70    mjacob 
   1793   1.38    mjacob 	/*
   1794   1.70    mjacob 	 * Init the firmware
   1795   1.38    mjacob 	 */
   1796  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1797   1.57    mjacob 	mbs.param[0] = MBOX_INIT_FIRMWARE;
   1798   1.79    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
   1799   1.79    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
   1800   1.79    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
   1801   1.79    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
   1802  1.111    mjacob 	mbs.logval = MBLOGALL;
   1803  1.111    mjacob 	mbs.timeout = 30 * 1000000;
   1804  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
   1805  1.111    mjacob 	    fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
   1806  1.111    mjacob 	    (uint32_t) fcp->isp_scdma);
   1807  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
   1808  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1809   1.88    mjacob 	FC_SCRATCH_RELEASE(isp);
   1810   1.57    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1811  1.111    mjacob 		isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
   1812   1.57    mjacob 		return;
   1813   1.10    mjacob 	}
   1814  1.111    mjacob 	isp->isp_reqidx = 0;
   1815  1.111    mjacob 	isp->isp_reqodx = 0;
   1816   1.10    mjacob 	isp->isp_residx = 0;
   1817   1.33    mjacob 
   1818   1.33    mjacob 	/*
   1819   1.33    mjacob 	 * Whatever happens, we're now committed to being here.
   1820   1.33    mjacob 	 */
   1821   1.33    mjacob 	isp->isp_state = ISP_INITSTATE;
   1822   1.33    mjacob }
   1823   1.33    mjacob 
   1824  1.111    mjacob static void
   1825  1.111    mjacob isp_fibre_init_2400(ispsoftc_t *isp)
   1826   1.70    mjacob {
   1827  1.111    mjacob 	fcparam *fcp;
   1828  1.111    mjacob 	isp_icb_2400_t local, *icbp = &local;
   1829   1.70    mjacob 	mbreg_t mbs;
   1830  1.111    mjacob 	int ownloopid;
   1831  1.111    mjacob 	uint64_t nwwn, pwwn;
   1832  1.111    mjacob 
   1833  1.111    mjacob 	fcp = isp->isp_param;
   1834  1.111    mjacob 
   1835  1.111    mjacob 	/*
   1836  1.111    mjacob 	 * Turn on LIP F8 async event (1)
   1837  1.111    mjacob 	 */
   1838  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   1839  1.111    mjacob 	mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
   1840  1.111    mjacob 	mbs.param[1] = 1;
   1841  1.111    mjacob 	mbs.logval = MBLOGALL;
   1842  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   1843  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1844  1.111    mjacob 		return;
   1845  1.111    mjacob 	}
   1846  1.111    mjacob 
   1847  1.111    mjacob 	/*
   1848  1.111    mjacob 	 * XXX: This should be applied to icb- not fwoptions
   1849  1.111    mjacob 	 */
   1850  1.111    mjacob 	if (isp->isp_role & ISP_ROLE_TARGET) {
   1851  1.111    mjacob 		fcp->isp_fwoptions |= ICB2400_OPT1_TGT_ENABLE;
   1852  1.111    mjacob 	} else {
   1853  1.111    mjacob 		fcp->isp_fwoptions &= ~ICB2400_OPT1_TGT_ENABLE;
   1854  1.111    mjacob 	}
   1855  1.111    mjacob 
   1856  1.111    mjacob 	if (isp->isp_role & ISP_ROLE_INITIATOR) {
   1857  1.111    mjacob 		fcp->isp_fwoptions &= ~ICB2400_OPT1_INI_DISABLE;
   1858  1.111    mjacob 	} else {
   1859  1.111    mjacob 		fcp->isp_fwoptions |= ICB2400_OPT1_INI_DISABLE;
   1860  1.111    mjacob 	}
   1861  1.111    mjacob 
   1862  1.111    mjacob 	MEMZERO(icbp, sizeof (*icbp));
   1863  1.111    mjacob 	icbp->icb_version = ICB_VERSION1;
   1864  1.111    mjacob 	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
   1865  1.111    mjacob 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
   1866  1.111    mjacob 	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
   1867  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   1868  1.111    mjacob 		    "bad frame length (%d) from NVRAM- using %d",
   1869  1.111    mjacob 		    fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
   1870  1.111    mjacob 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
   1871  1.111    mjacob 	}
   1872  1.111    mjacob 
   1873  1.111    mjacob 	icbp->icb_execthrottle = fcp->isp_execthrottle;
   1874  1.111    mjacob 	if (icbp->icb_execthrottle < 1) {
   1875  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   1876  1.111    mjacob 		    "bad execution throttle of %d- using 16",
   1877  1.111    mjacob 		    fcp->isp_execthrottle);
   1878  1.111    mjacob 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
   1879  1.111    mjacob 	}
   1880   1.70    mjacob 
   1881  1.111    mjacob 	if (isp->isp_role & ISP_ROLE_TARGET) {
   1882  1.111    mjacob 		/*
   1883  1.111    mjacob 		 * Get current resource count
   1884  1.111    mjacob 		 */
   1885  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   1886  1.111    mjacob 		mbs.param[0] = MBOX_GET_RESOURCE_COUNT;
   1887  1.111    mjacob 		mbs.obits = 0x4cf;
   1888  1.111    mjacob 		mbs.logval = MBLOGALL;
   1889  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   1890  1.111    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   1891  1.111    mjacob 			return;
   1892  1.111    mjacob 		}
   1893  1.111    mjacob 		icbp->icb_xchgcnt = mbs.param[3];
   1894  1.111    mjacob 	}
   1895  1.111    mjacob 
   1896  1.111    mjacob 	icbp->icb_fwoptions1 = fcp->isp_fwoptions;
   1897  1.111    mjacob 
   1898  1.111    mjacob 	icbp->icb_hardaddr = fcp->isp_loopid;
   1899  1.111    mjacob 	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
   1900  1.111    mjacob 	if (icbp->icb_hardaddr > 125) {
   1901  1.111    mjacob 		icbp->icb_hardaddr = 0;
   1902  1.111    mjacob 		ownloopid = 0;
   1903  1.111    mjacob 	}
   1904  1.111    mjacob 	if (ownloopid) {
   1905  1.111    mjacob 		icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
   1906  1.111    mjacob 	}
   1907  1.111    mjacob 
   1908  1.111    mjacob 	icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
   1909  1.111    mjacob 	switch(isp->isp_confopts & ISP_CFG_PORT_PREF) {
   1910  1.111    mjacob 	case ISP_CFG_NPORT:
   1911  1.111    mjacob 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
   1912  1.111    mjacob 		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
   1913  1.111    mjacob 		break;
   1914  1.111    mjacob 	case ISP_CFG_NPORT_ONLY:
   1915  1.111    mjacob 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
   1916  1.111    mjacob 		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
   1917  1.111    mjacob 		break;
   1918  1.111    mjacob 	case ISP_CFG_LPORT_ONLY:
   1919  1.111    mjacob 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
   1920  1.111    mjacob 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
   1921  1.111    mjacob 		break;
   1922  1.111    mjacob 	default:
   1923  1.111    mjacob 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
   1924  1.111    mjacob 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
   1925  1.111    mjacob 		break;
   1926  1.111    mjacob 	}
   1927  1.111    mjacob 
   1928  1.111    mjacob 	switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
   1929  1.111    mjacob 	case ICB2400_OPT2_ZIO:
   1930  1.111    mjacob 	case ICB2400_OPT2_ZIO1:
   1931  1.111    mjacob 		icbp->icb_idelaytimer = 0;
   1932  1.111    mjacob 		break;
   1933  1.111    mjacob 	case 0:
   1934  1.111    mjacob 		break;
   1935  1.111    mjacob 	default:
   1936  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field",
   1937  1.111    mjacob 		    icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
   1938  1.111    mjacob 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
   1939  1.111    mjacob 		break;
   1940  1.111    mjacob 	}
   1941  1.111    mjacob 
   1942  1.111    mjacob 	icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
   1943  1.111    mjacob 	icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
   1944  1.111    mjacob 	if (isp->isp_confopts & ISP_CFG_ONEGB) {
   1945  1.111    mjacob 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
   1946  1.111    mjacob 	} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
   1947  1.111    mjacob 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
   1948  1.111    mjacob 	} else if (isp->isp_confopts & ISP_CFG_FOURGB) {
   1949  1.111    mjacob 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
   1950  1.111    mjacob 	} else {
   1951  1.111    mjacob 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
   1952  1.111    mjacob 	}
   1953  1.111    mjacob 
   1954  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
   1955  1.111    mjacob 		icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
   1956  1.111    mjacob 	}
   1957  1.111    mjacob 	icbp->icb_logintime = ICB_LOGIN_TOV;
   1958  1.111    mjacob 
   1959  1.111    mjacob 	nwwn = ISP_NODEWWN(isp);
   1960  1.111    mjacob 	pwwn = ISP_PORTWWN(isp);
   1961  1.111    mjacob 
   1962  1.111    mjacob 	if (nwwn && pwwn) {
   1963  1.111    mjacob 		icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
   1964  1.111    mjacob 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, nwwn);
   1965  1.111    mjacob 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
   1966  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG1,
   1967  1.111    mjacob 		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
   1968  1.111    mjacob 		    ((uint32_t) (nwwn >> 32)),
   1969  1.111    mjacob 		    ((uint32_t) (nwwn & 0xffffffff)),
   1970  1.111    mjacob 		    ((uint32_t) (pwwn >> 32)),
   1971  1.111    mjacob 		    ((uint32_t) (pwwn & 0xffffffff)));
   1972  1.111    mjacob 	} else if (pwwn) {
   1973  1.111    mjacob 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
   1974  1.111    mjacob 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, pwwn);
   1975  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG1,
   1976  1.111    mjacob 		    "Setting ICB Port 0x%08x%08x",
   1977  1.111    mjacob 		    ((uint32_t) (pwwn >> 32)),
   1978  1.111    mjacob 		    ((uint32_t) (pwwn & 0xffffffff)));
   1979  1.111    mjacob 	} else {
   1980  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
   1981  1.111    mjacob 		return;
   1982  1.111    mjacob 	}
   1983  1.111    mjacob 	icbp->icb_retry_count = fcp->isp_retry_count;
   1984  1.111    mjacob 
   1985  1.111    mjacob 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
   1986  1.111    mjacob 	if (icbp->icb_rqstqlen < 8) {
   1987  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "bad request queue length %d",
   1988  1.111    mjacob 		    icbp->icb_rqstqlen);
   1989  1.111    mjacob 		return;
   1990  1.111    mjacob 	}
   1991  1.111    mjacob 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
   1992  1.111    mjacob 	if (icbp->icb_rsltqlen < 8) {
   1993  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
   1994  1.111    mjacob 		    icbp->icb_rsltqlen);
   1995  1.111    mjacob 		return;
   1996  1.111    mjacob 	}
   1997  1.111    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
   1998  1.111    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
   1999  1.111    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
   2000  1.111    mjacob 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
   2001  1.111    mjacob 
   2002  1.111    mjacob 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
   2003  1.111    mjacob 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
   2004  1.111    mjacob 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
   2005  1.111    mjacob 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
   2006  1.111    mjacob 
   2007  1.111    mjacob #ifdef	ISP_TARGET_MODE
   2008  1.111    mjacob 	if (isp->isp_role & ISP_ROLE_TARGET) {
   2009  1.111    mjacob 		icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
   2010  1.111    mjacob 		if (icbp->icb_atioqlen < 8) {
   2011  1.111    mjacob 			isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d",
   2012  1.111    mjacob 			    icbp->icb_atioqlen);
   2013  1.111    mjacob 			return;
   2014  1.111    mjacob 		}
   2015  1.111    mjacob 		icbp->icb_atioqaddr[RQRSP_ADDR0015] =
   2016  1.111    mjacob 		    DMA_WD0(isp->isp_atioq_dma);
   2017  1.111    mjacob 		icbp->icb_atioqaddr[RQRSP_ADDR1631] =
   2018  1.111    mjacob 		    DMA_WD1(isp->isp_atioq_dma);
   2019  1.111    mjacob 		icbp->icb_atioqaddr[RQRSP_ADDR3247] =
   2020  1.111    mjacob 		    DMA_WD2(isp->isp_atioq_dma);
   2021  1.111    mjacob 		icbp->icb_atioqaddr[RQRSP_ADDR4863] =
   2022  1.111    mjacob 		    DMA_WD3(isp->isp_atioq_dma);
   2023  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   2024  1.111    mjacob 		    "isp_fibre_init_2400: atioq %04x%04x%04x%04x",
   2025  1.111    mjacob 		    DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
   2026  1.111    mjacob 		    DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
   2027  1.111    mjacob 	}
   2028  1.111    mjacob #endif
   2029  1.111    mjacob 
   2030  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   2031  1.111    mjacob 	    "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
   2032  1.111    mjacob 	    icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
   2033  1.111    mjacob 
   2034  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   2035  1.111    mjacob 	    "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x",
   2036  1.111    mjacob 	    DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
   2037  1.111    mjacob 	    DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma),
   2038  1.111    mjacob 	    DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
   2039  1.111    mjacob 	    DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
   2040  1.111    mjacob 
   2041  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   2042  1.111    mjacob 		isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp),
   2043  1.111    mjacob 		    icbp);
   2044  1.111    mjacob 	}
   2045  1.111    mjacob 	FC_SCRATCH_ACQUIRE(isp);
   2046  1.111    mjacob 	isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
   2047  1.111    mjacob 
   2048  1.111    mjacob 
   2049  1.111    mjacob 	/*
   2050  1.111    mjacob 	 * Init the firmware
   2051  1.111    mjacob 	 */
   2052  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2053  1.111    mjacob 	mbs.param[0] = MBOX_INIT_FIRMWARE;
   2054   1.79    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
   2055   1.79    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
   2056  1.111    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
   2057  1.111    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
   2058  1.111    mjacob 	mbs.logval = MBLOGALL;
   2059  1.111    mjacob 	mbs.timeout = 30 * 1000000;
   2060  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x",
   2061  1.111    mjacob 	    DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma),
   2062  1.111    mjacob 	    DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
   2063  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp));
   2064  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2065  1.111    mjacob 	FC_SCRATCH_RELEASE(isp);
   2066  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   2067  1.111    mjacob 		return;
   2068  1.111    mjacob 	}
   2069  1.111    mjacob 	isp->isp_reqidx = 0;
   2070  1.111    mjacob 	isp->isp_reqodx = 0;
   2071  1.111    mjacob 	isp->isp_residx = 0;
   2072  1.111    mjacob 
   2073   1.70    mjacob 	/*
   2074  1.111    mjacob 	 * Whatever happens, we're now committed to being here.
   2075   1.70    mjacob 	 */
   2076  1.111    mjacob 	isp->isp_state = ISP_INITSTATE;
   2077   1.70    mjacob }
   2078   1.70    mjacob 
   2079   1.33    mjacob static void
   2080  1.111    mjacob isp_mark_portdb(ispsoftc_t *isp, int onprobation)
   2081   1.33    mjacob {
   2082   1.33    mjacob 	fcparam *fcp = (fcparam *) isp->isp_param;
   2083   1.37    mjacob 	int i;
   2084  1.111    mjacob 
   2085   1.37    mjacob 	for (i = 0; i < MAX_FC_TARG; i++) {
   2086  1.111    mjacob 		if (onprobation == 0) {
   2087  1.111    mjacob 			MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
   2088  1.111    mjacob 		} else {
   2089  1.111    mjacob 			switch (fcp->portdb[i].state) {
   2090  1.111    mjacob 			case FC_PORTDB_STATE_CHANGED:
   2091  1.111    mjacob 			case FC_PORTDB_STATE_PENDING_VALID:
   2092  1.111    mjacob 			case FC_PORTDB_STATE_VALID:
   2093  1.111    mjacob 			case FC_PORTDB_STATE_PROBATIONAL:
   2094  1.111    mjacob 				fcp->portdb[i].state =
   2095  1.111    mjacob 					FC_PORTDB_STATE_PROBATIONAL;
   2096  1.111    mjacob 				break;
   2097  1.111    mjacob 			case FC_PORTDB_STATE_ZOMBIE:
   2098  1.111    mjacob 				break;
   2099  1.111    mjacob 			case FC_PORTDB_STATE_NIL:
   2100  1.111    mjacob 			default:
   2101  1.111    mjacob 				MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
   2102  1.111    mjacob 				fcp->portdb[i].state =
   2103  1.111    mjacob 					FC_PORTDB_STATE_NIL;
   2104  1.111    mjacob 				break;
   2105  1.111    mjacob 			}
   2106  1.111    mjacob 		}
   2107  1.111    mjacob 	}
   2108  1.111    mjacob }
   2109  1.111    mjacob 
   2110  1.111    mjacob /*
   2111  1.111    mjacob  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
   2112  1.111    mjacob  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
   2113  1.111    mjacob  */
   2114  1.111    mjacob static int
   2115  1.111    mjacob isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs)
   2116  1.111    mjacob {
   2117  1.111    mjacob 	mbreg_t mbs;
   2118  1.111    mjacob 	uint8_t q[QENTRY_LEN];
   2119  1.111    mjacob 	isp_plogx_t *plp;
   2120  1.111    mjacob 	uint8_t *scp;
   2121  1.111    mjacob 	uint32_t sst, parm1;
   2122  1.111    mjacob 	int rval;
   2123  1.111    mjacob 
   2124  1.111    mjacob 	if (!IS_24XX(isp)) {
   2125  1.111    mjacob 		int action = flags & PLOGX_FLG_CMD_MASK;
   2126  1.111    mjacob 		if (action == PLOGX_FLG_CMD_PLOGI) {
   2127  1.111    mjacob 			return (isp_port_login(isp, handle, portid));
   2128  1.111    mjacob 		} else if (action == PLOGX_FLG_CMD_LOGO) {
   2129  1.111    mjacob 			return (isp_port_logout(isp, handle, portid));
   2130  1.111    mjacob 		} else {
   2131  1.111    mjacob 			return (MBOX_INVALID_COMMAND);
   2132  1.111    mjacob 		}
   2133  1.111    mjacob 	}
   2134  1.111    mjacob 
   2135  1.111    mjacob 	MEMZERO(q, QENTRY_LEN);
   2136  1.111    mjacob 	plp = (isp_plogx_t *) q;
   2137  1.111    mjacob 	plp->plogx_header.rqs_entry_count = 1;
   2138  1.111    mjacob 	plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
   2139  1.111    mjacob 	plp->plogx_handle = 0xffffffff;
   2140  1.111    mjacob 	plp->plogx_nphdl = handle;
   2141  1.111    mjacob 	plp->plogx_portlo = portid;
   2142  1.111    mjacob 	plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
   2143  1.111    mjacob 	plp->plogx_flags = flags;
   2144  1.111    mjacob 
   2145  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   2146  1.111    mjacob 		isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
   2147  1.111    mjacob 	}
   2148  1.111    mjacob 
   2149  1.111    mjacob 	if (gs == 0) {
   2150  1.111    mjacob 		FC_SCRATCH_ACQUIRE(isp);
   2151  1.111    mjacob 	}
   2152  1.111    mjacob 	scp = FCPARAM(isp)->isp_scratch;
   2153  1.111    mjacob 	isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
   2154  1.111    mjacob 
   2155  1.111    mjacob 
   2156  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2157  1.111    mjacob 	mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
   2158  1.111    mjacob 	mbs.param[1] = QENTRY_LEN;
   2159  1.111    mjacob 	mbs.param[2] = DMA_WD1(FCPARAM(isp)->isp_scdma);
   2160  1.111    mjacob 	mbs.param[3] = DMA_WD0(FCPARAM(isp)->isp_scdma);
   2161  1.111    mjacob 	mbs.param[6] = DMA_WD3(FCPARAM(isp)->isp_scdma);
   2162  1.111    mjacob 	mbs.param[7] = DMA_WD2(FCPARAM(isp)->isp_scdma);
   2163  1.111    mjacob 	mbs.timeout = 500000;
   2164  1.111    mjacob 	mbs.logval = MBLOGALL;
   2165  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN);
   2166  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2167  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   2168  1.111    mjacob 		rval = mbs.param[0];
   2169  1.111    mjacob 		goto out;
   2170  1.111    mjacob 	}
   2171  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN);
   2172  1.111    mjacob 	scp += QENTRY_LEN;
   2173  1.111    mjacob 	isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
   2174  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   2175  1.111    mjacob 		isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
   2176  1.111    mjacob 	}
   2177  1.111    mjacob 
   2178  1.111    mjacob 	if (plp->plogx_status == PLOGX_STATUS_OK) {
   2179  1.111    mjacob 		rval = 0;
   2180  1.111    mjacob 		goto out;
   2181  1.111    mjacob 	} else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
   2182  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "status 0x%x on port login IOCB",
   2183  1.111    mjacob 		    plp->plogx_status);
   2184  1.111    mjacob 		rval = -1;
   2185  1.111    mjacob 		goto out;
   2186  1.111    mjacob 	}
   2187  1.111    mjacob 
   2188  1.111    mjacob 	sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
   2189  1.111    mjacob 	parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
   2190  1.111    mjacob 
   2191  1.111    mjacob 	rval = -1;
   2192  1.111    mjacob 
   2193  1.111    mjacob 	switch (sst) {
   2194  1.111    mjacob 	case PLOGX_IOCBERR_NOLINK:
   2195  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- no link");
   2196  1.111    mjacob 		break;
   2197  1.111    mjacob 	case PLOGX_IOCBERR_NOIOCB:
   2198  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- no IOCB buffer");
   2199  1.111    mjacob 		break;
   2200  1.111    mjacob 	case PLOGX_IOCBERR_NOXGHG:
   2201  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   2202  1.111    mjacob 		    "PLOGX failed- no Exchange Control Block");
   2203  1.111    mjacob 		break;
   2204  1.111    mjacob 	case PLOGX_IOCBERR_FAILED:
   2205  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   2206  1.111    mjacob 		    "PLOGX(0x%x) of Port 0x%06x failed: reason 0x%x (last LOGIN"
   2207  1.111    mjacob 		    " state 0x%x)", flags, portid, parm1 & 0xff,
   2208  1.111    mjacob 		    (parm1 >> 8) & 0xff);
   2209  1.111    mjacob 		break;
   2210  1.111    mjacob 	case PLOGX_IOCBERR_NOFABRIC:
   2211  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- no fabric");
   2212  1.111    mjacob 		break;
   2213  1.111    mjacob 	case PLOGX_IOCBERR_NOTREADY:
   2214  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- f/w not ready");
   2215  1.111    mjacob 		break;
   2216  1.111    mjacob 	case PLOGX_IOCBERR_NOLOGIN:
   2217  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   2218  1.111    mjacob 		    "PLOGX failed- not logged in (last LOGIN state 0x%x)",
   2219  1.111    mjacob 		    parm1);
   2220  1.111    mjacob 		rval = MBOX_NOT_LOGGED_IN;
   2221  1.111    mjacob 		break;
   2222  1.111    mjacob 	case PLOGX_IOCBERR_REJECT:
   2223  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed: LS_RJT = 0x%x", parm1);
   2224  1.111    mjacob 		break;
   2225  1.111    mjacob 	case PLOGX_IOCBERR_NOPCB:
   2226  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- no PCB allocated");
   2227  1.111    mjacob 		break;
   2228  1.111    mjacob 	case PLOGX_IOCBERR_EINVAL:
   2229  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   2230  1.111    mjacob 		    "PLOGX failed: invalid parameter at offset 0x%x", parm1);
   2231  1.111    mjacob 		break;
   2232  1.111    mjacob 	case PLOGX_IOCBERR_PORTUSED:
   2233  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   2234  1.111    mjacob 		    "portid 0x%x already logged in with N-port handle 0x%x",
   2235  1.111    mjacob 		    portid, parm1);
   2236  1.111    mjacob 		rval = MBOX_PORT_ID_USED | (handle << 16);
   2237  1.111    mjacob 		break;
   2238  1.111    mjacob 	case PLOGX_IOCBERR_HNDLUSED:
   2239  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   2240  1.111    mjacob 		    "N-port handle 0x%x already used for portid 0x%x",
   2241  1.111    mjacob 		    handle, parm1);
   2242  1.111    mjacob 		rval = MBOX_LOOP_ID_USED;
   2243  1.111    mjacob 		break;
   2244  1.111    mjacob 	case PLOGX_IOCBERR_NOHANDLE:
   2245  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- no handle allocated");
   2246  1.111    mjacob 		break;
   2247  1.111    mjacob 	case PLOGX_IOCBERR_NOFLOGI:
   2248  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "PLOGX failed- no FLOGI_ACC");
   2249  1.111    mjacob 		break;
   2250  1.111    mjacob 	default:
   2251  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "status %x from %x", plp->plogx_status,
   2252  1.111    mjacob 		    flags);
   2253  1.111    mjacob 		rval = -1;
   2254  1.111    mjacob 		break;
   2255  1.111    mjacob 	}
   2256  1.111    mjacob out:
   2257  1.111    mjacob 	if (gs == 0) {
   2258  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   2259  1.111    mjacob 	}
   2260  1.111    mjacob 	return (rval);
   2261  1.111    mjacob }
   2262  1.111    mjacob 
   2263  1.111    mjacob static int
   2264  1.111    mjacob isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
   2265  1.111    mjacob {
   2266  1.111    mjacob 	mbreg_t mbs;
   2267  1.111    mjacob 
   2268  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2269  1.111    mjacob 	mbs.param[0] = MBOX_FABRIC_LOGIN;
   2270  1.111    mjacob 	if (FCPARAM(isp)->isp_2klogin) {
   2271  1.111    mjacob 		mbs.param[1] = handle;
   2272  1.111    mjacob 		mbs.ibits = (1 << 10);
   2273  1.111    mjacob 	} else {
   2274  1.111    mjacob 		mbs.param[1] = handle << 8;
   2275  1.111    mjacob 	}
   2276  1.111    mjacob 	mbs.param[2] = portid >> 16;
   2277  1.111    mjacob 	mbs.param[3] = portid;
   2278  1.111    mjacob 	mbs.logval = MBLOGNONE;
   2279  1.111    mjacob 	mbs.timeout = 500000;
   2280  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2281  1.111    mjacob 
   2282  1.111    mjacob 	switch (mbs.param[0]) {
   2283  1.111    mjacob 	case MBOX_PORT_ID_USED:
   2284  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   2285  1.111    mjacob 		    "isp_plogi_old: portid 0x%06x already logged in as %u",
   2286  1.111    mjacob 		    portid, mbs.param[1]);
   2287  1.111    mjacob 		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
   2288  1.111    mjacob 
   2289  1.111    mjacob 	case MBOX_LOOP_ID_USED:
   2290  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   2291  1.111    mjacob 		    "isp_plogi_old: handle %u in use for port id 0x%02xXXXX",
   2292  1.111    mjacob 		    handle, mbs.param[1] & 0xff);
   2293  1.111    mjacob 		return (MBOX_LOOP_ID_USED);
   2294  1.111    mjacob 
   2295  1.111    mjacob 	case MBOX_COMMAND_COMPLETE:
   2296  1.111    mjacob 		return (0);
   2297  1.111    mjacob 
   2298  1.111    mjacob 	case MBOX_COMMAND_ERROR:
   2299  1.111    mjacob 		isp_prt(isp, ISP_LOGINFO,
   2300  1.111    mjacob 		    "isp_plogi_old: error 0x%x in PLOGI to port 0x%06x",
   2301  1.111    mjacob 		    mbs.param[1], portid);
   2302  1.111    mjacob 		return (MBOX_COMMAND_ERROR);
   2303  1.111    mjacob 
   2304  1.111    mjacob 	case MBOX_ALL_IDS_USED:
   2305  1.111    mjacob 		isp_prt(isp, ISP_LOGINFO,
   2306  1.111    mjacob 		    "isp_plogi_old: all IDs used for fabric login");
   2307  1.111    mjacob 		return (MBOX_ALL_IDS_USED);
   2308  1.111    mjacob 
   2309  1.111    mjacob 	default:
   2310  1.111    mjacob 		isp_prt(isp, ISP_LOGINFO,
   2311  1.111    mjacob 		    "isp_plogi_old: error 0x%x on port login of 0x%06x@0x%0x",
   2312  1.111    mjacob 		    mbs.param[0], portid, handle);
   2313  1.111    mjacob 		return (mbs.param[0]);
   2314  1.111    mjacob 	}
   2315  1.111    mjacob }
   2316  1.111    mjacob 
   2317  1.111    mjacob static int
   2318  1.111    mjacob isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
   2319  1.111    mjacob {
   2320  1.111    mjacob 	mbreg_t mbs;
   2321  1.111    mjacob 
   2322  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2323  1.111    mjacob 	mbs.param[0] = MBOX_FABRIC_LOGOUT;
   2324  1.111    mjacob 	if (FCPARAM(isp)->isp_2klogin) {
   2325  1.111    mjacob 		mbs.param[1] = handle;
   2326  1.111    mjacob 		mbs.ibits = (1 << 10);
   2327  1.111    mjacob 	} else {
   2328  1.111    mjacob 		mbs.param[1] = handle << 8;
   2329   1.33    mjacob 	}
   2330  1.111    mjacob 	mbs.logval = MBLOGNONE;
   2331  1.111    mjacob 	mbs.timeout = 100000;
   2332  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2333  1.111    mjacob 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
   2334   1.33    mjacob }
   2335   1.33    mjacob 
   2336   1.33    mjacob static int
   2337  1.111    mjacob isp_getpdb(ispsoftc_t *isp, uint16_t id, isp_pdb_t *pdb, int dolock)
   2338   1.33    mjacob {
   2339   1.33    mjacob 	fcparam *fcp = (fcparam *) isp->isp_param;
   2340   1.33    mjacob 	mbreg_t mbs;
   2341  1.111    mjacob 	union {
   2342  1.111    mjacob 		isp_pdb_21xx_t fred;
   2343  1.111    mjacob 		isp_pdb_24xx_t bill;
   2344  1.111    mjacob 	} un;
   2345   1.37    mjacob 
   2346  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2347   1.33    mjacob 	mbs.param[0] = MBOX_GET_PORT_DB;
   2348  1.111    mjacob 	if (IS_24XX(isp)) {
   2349  1.111    mjacob 		mbs.ibits = 0x3ff;
   2350  1.111    mjacob 		mbs.param[1] = id;
   2351  1.111    mjacob 	} else if (FCPARAM(isp)->isp_2klogin) {
   2352  1.111    mjacob 		mbs.param[1] = id;
   2353  1.111    mjacob 		mbs.ibits = (1 << 10);
   2354  1.111    mjacob 	} else {
   2355  1.111    mjacob 		mbs.param[1] = id << 8;
   2356  1.111    mjacob 	}
   2357   1.79    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
   2358   1.79    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
   2359   1.79    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
   2360   1.79    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
   2361  1.111    mjacob 	mbs.timeout = 250000;
   2362  1.111    mjacob 	mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
   2363  1.111    mjacob 	if (dolock) {
   2364  1.111    mjacob 		FC_SCRATCH_ACQUIRE(isp);
   2365  1.111    mjacob 	}
   2366  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un));
   2367  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2368  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   2369  1.111    mjacob 		if (dolock) {
   2370  1.111    mjacob 			FC_SCRATCH_RELEASE(isp);
   2371  1.111    mjacob 		}
   2372  1.111    mjacob 		return (-1);
   2373  1.111    mjacob 	}
   2374  1.111    mjacob 	if (IS_24XX(isp)) {
   2375  1.111    mjacob 		isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
   2376  1.111    mjacob 		pdb->handle = un.bill.pdb_handle;
   2377  1.111    mjacob 		pdb->s3_role = un.bill.pdb_prli_svc3;
   2378  1.111    mjacob 		pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
   2379  1.111    mjacob 		MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
   2380  1.111    mjacob 		MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
   2381  1.111    mjacob 	} else {
   2382  1.111    mjacob 		isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
   2383  1.111    mjacob 		pdb->handle = un.fred.pdb_loopid;
   2384  1.111    mjacob 		pdb->s3_role = un.fred.pdb_prli_svc3;
   2385  1.111    mjacob 		pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
   2386  1.111    mjacob 		MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
   2387  1.111    mjacob 		MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
   2388  1.111    mjacob 	}
   2389  1.111    mjacob 	if (dolock) {
   2390   1.88    mjacob 		FC_SCRATCH_RELEASE(isp);
   2391   1.33    mjacob 	}
   2392  1.111    mjacob 	return (0);
   2393   1.33    mjacob }
   2394   1.33    mjacob 
   2395  1.111    mjacob static uint64_t
   2396  1.111    mjacob isp_get_portname(ispsoftc_t *isp, int loopid, int nodename)
   2397   1.37    mjacob {
   2398  1.111    mjacob 	uint64_t wwn = (uint64_t) -1;
   2399   1.37    mjacob 	mbreg_t mbs;
   2400   1.37    mjacob 
   2401  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2402   1.37    mjacob 	mbs.param[0] = MBOX_GET_PORT_NAME;
   2403  1.111    mjacob 	if (FCPARAM(isp)->isp_2klogin || IS_24XX(isp)) {
   2404  1.111    mjacob 		mbs.param[1] = loopid;
   2405  1.111    mjacob 		mbs.ibits = (1 << 10);
   2406  1.111    mjacob 		if (nodename) {
   2407  1.111    mjacob 			mbs.param[10] = 1;
   2408  1.111    mjacob 		}
   2409  1.111    mjacob 	} else {
   2410  1.111    mjacob 		mbs.param[1] = loopid << 8;
   2411  1.111    mjacob 		if (nodename) {
   2412  1.111    mjacob 			mbs.param[1] |= 1;
   2413  1.111    mjacob 		}
   2414  1.111    mjacob 	}
   2415  1.111    mjacob 	mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR;
   2416  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2417  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   2418  1.111    mjacob 		return (wwn);
   2419  1.111    mjacob 	}
   2420  1.111    mjacob 	if (IS_24XX(isp)) {
   2421  1.111    mjacob 		wwn =
   2422  1.111    mjacob 		    (((uint64_t)(mbs.param[2] >> 8))  << 56) |
   2423  1.111    mjacob 		    (((uint64_t)(mbs.param[2] & 0xff))	<< 48) |
   2424  1.111    mjacob 		    (((uint64_t)(mbs.param[3] >> 8))	<< 40) |
   2425  1.111    mjacob 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 32) |
   2426  1.111    mjacob 		    (((uint64_t)(mbs.param[6] >> 8))	<< 24) |
   2427  1.111    mjacob 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 16) |
   2428  1.111    mjacob 		    (((uint64_t)(mbs.param[7] >> 8))	<<  8) |
   2429  1.111    mjacob 		    (((uint64_t)(mbs.param[7] & 0xff)));
   2430  1.111    mjacob 	} else {
   2431   1.37    mjacob 		wwn =
   2432  1.111    mjacob 		    (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
   2433  1.111    mjacob 		    (((uint64_t)(mbs.param[2] >> 8))	<< 48) |
   2434  1.111    mjacob 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 40) |
   2435  1.111    mjacob 		    (((uint64_t)(mbs.param[3] >> 8))	<< 32) |
   2436  1.111    mjacob 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 24) |
   2437  1.111    mjacob 		    (((uint64_t)(mbs.param[6] >> 8))	<< 16) |
   2438  1.111    mjacob 		    (((uint64_t)(mbs.param[7] & 0xff))	<<  8) |
   2439  1.111    mjacob 		    (((uint64_t)(mbs.param[7] >> 8)));
   2440   1.37    mjacob 	}
   2441   1.37    mjacob 	return (wwn);
   2442   1.37    mjacob }
   2443   1.37    mjacob 
   2444   1.33    mjacob /*
   2445  1.111    mjacob  * Make sure we have good FC link.
   2446   1.33    mjacob  */
   2447   1.33    mjacob 
   2448   1.33    mjacob static int
   2449  1.111    mjacob isp_fclink_test(ispsoftc_t *isp, int usdelay)
   2450   1.33    mjacob {
   2451  1.107  christos 	static const char *toponames[] = {
   2452   1.38    mjacob 		"Private Loop",
   2453   1.38    mjacob 		"FL Port",
   2454   1.38    mjacob 		"N-Port to N-Port",
   2455   1.52        he 		"F Port",
   2456   1.52        he 		"F Port (no FLOGI_ACC response)"
   2457   1.38    mjacob 	};
   2458   1.33    mjacob 	mbreg_t mbs;
   2459   1.70    mjacob 	int count, check_for_fabric;
   2460  1.111    mjacob 	uint8_t lwfs;
   2461  1.111    mjacob 	int loopid;
   2462   1.33    mjacob 	fcparam *fcp;
   2463  1.111    mjacob 	fcportdb_t *lp;
   2464   1.37    mjacob 	isp_pdb_t pdb;
   2465   1.70    mjacob 
   2466   1.33    mjacob 	fcp = isp->isp_param;
   2467   1.10    mjacob 
   2468  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Entry");
   2469  1.111    mjacob 	ISP_MARK_PORTDB(isp, 1);
   2470   1.57    mjacob 
   2471   1.57    mjacob 	/*
   2472   1.33    mjacob 	 * Wait up to N microseconds for F/W to go to a ready state.
   2473   1.10    mjacob 	 */
   2474   1.23    mjacob 	lwfs = FW_CONFIG_WAIT;
   2475   1.57    mjacob 	count = 0;
   2476   1.57    mjacob 	while (count < usdelay) {
   2477  1.111    mjacob 		uint64_t enano;
   2478  1.111    mjacob 		uint32_t wrk;
   2479   1.57    mjacob 		NANOTIME_T hra, hrb;
   2480   1.57    mjacob 
   2481   1.57    mjacob 		GET_NANOTIME(&hra);
   2482   1.10    mjacob 		isp_fw_state(isp);
   2483   1.23    mjacob 		if (lwfs != fcp->isp_fwstate) {
   2484  1.111    mjacob 			isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG,
   2485  1.111    mjacob 			    "Firmware State <%s->%s>",
   2486  1.111    mjacob 			    ispfc_fw_statename((int)lwfs),
   2487  1.111    mjacob 			    ispfc_fw_statename((int)fcp->isp_fwstate));
   2488   1.23    mjacob 			lwfs = fcp->isp_fwstate;
   2489   1.23    mjacob 		}
   2490   1.23    mjacob 		if (fcp->isp_fwstate == FW_READY) {
   2491   1.10    mjacob 			break;
   2492   1.23    mjacob 		}
   2493   1.57    mjacob 		GET_NANOTIME(&hrb);
   2494   1.57    mjacob 
   2495   1.57    mjacob 		/*
   2496   1.57    mjacob 		 * Get the elapsed time in nanoseconds.
   2497   1.57    mjacob 		 * Always guaranteed to be non-zero.
   2498   1.57    mjacob 		 */
   2499   1.57    mjacob 		enano = NANOTIME_SUB(&hrb, &hra);
   2500   1.57    mjacob 
   2501   1.73    mjacob 		isp_prt(isp, ISP_LOGDEBUG1,
   2502   1.73    mjacob 		    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",
   2503   1.66    mjacob 		    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
   2504  1.111    mjacob 		    (uint32_t)(enano >> 32), (uint32_t)(enano & 0xffffffff));
   2505   1.66    mjacob 
   2506   1.57    mjacob 		/*
   2507   1.57    mjacob 		 * If the elapsed time is less than 1 millisecond,
   2508   1.57    mjacob 		 * delay a period of time up to that millisecond of
   2509   1.57    mjacob 		 * waiting.
   2510   1.66    mjacob 		 *
   2511   1.57    mjacob 		 * This peculiar code is an attempt to try and avoid
   2512  1.111    mjacob 		 * invoking uint64_t math support functions for some
   2513   1.57    mjacob 		 * platforms where linkage is a problem.
   2514   1.57    mjacob 		 */
   2515   1.57    mjacob 		if (enano < (1000 * 1000)) {
   2516   1.57    mjacob 			count += 1000;
   2517   1.57    mjacob 			enano = (1000 * 1000) - enano;
   2518  1.111    mjacob 			while (enano > (uint64_t) 4000000000U) {
   2519   1.63    mjacob 				USEC_SLEEP(isp, 4000000);
   2520  1.111    mjacob 				enano -= (uint64_t) 4000000000U;
   2521   1.57    mjacob 			}
   2522   1.57    mjacob 			wrk = enano;
   2523   1.73    mjacob 			wrk /= 1000;
   2524   1.73    mjacob 			USEC_SLEEP(isp, wrk);
   2525   1.57    mjacob 		} else {
   2526  1.111    mjacob 			while (enano > (uint64_t) 4000000000U) {
   2527   1.57    mjacob 				count += 4000000;
   2528  1.111    mjacob 				enano -= (uint64_t) 4000000000U;
   2529   1.57    mjacob 			}
   2530   1.57    mjacob 			wrk = enano;
   2531   1.57    mjacob 			count += (wrk / 1000);
   2532   1.57    mjacob 		}
   2533   1.10    mjacob 	}
   2534   1.10    mjacob 
   2535   1.10    mjacob 	/*
   2536   1.33    mjacob 	 * If we haven't gone to 'ready' state, return.
   2537   1.33    mjacob 	 */
   2538   1.33    mjacob 	if (fcp->isp_fwstate != FW_READY) {
   2539  1.111    mjacob 		isp_prt(isp, ISP_LOGSANCFG,
   2540  1.111    mjacob 		    "isp_fclink_test: not at FW_READY state");
   2541   1.33    mjacob 		return (-1);
   2542   1.33    mjacob 	}
   2543   1.34    mjacob 
   2544   1.33    mjacob 	/*
   2545  1.111    mjacob 	 * Get our Loop ID and Port ID.
   2546   1.10    mjacob 	 */
   2547  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   2548   1.33    mjacob 	mbs.param[0] = MBOX_GET_LOOP_ID;
   2549  1.111    mjacob 	mbs.logval = MBLOGALL;
   2550  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   2551   1.33    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   2552   1.33    mjacob 		return (-1);
   2553   1.23    mjacob 	}
   2554  1.111    mjacob 
   2555  1.111    mjacob 	if (FCPARAM(isp)->isp_2klogin) {
   2556  1.111    mjacob 		fcp->isp_loopid = mbs.param[1];
   2557  1.111    mjacob 	} else {
   2558  1.111    mjacob 		fcp->isp_loopid = mbs.param[1] & 0xff;
   2559  1.111    mjacob 	}
   2560  1.111    mjacob 
   2561  1.111    mjacob 	if (IS_2100(isp)) {
   2562  1.111    mjacob 		fcp->isp_topo = TOPO_NL_PORT;
   2563  1.111    mjacob 	} else {
   2564   1.52        he 		int topo = (int) mbs.param[6];
   2565  1.111    mjacob 		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
   2566   1.52        he 			topo = TOPO_PTP_STUB;
   2567  1.111    mjacob 		}
   2568   1.52        he 		fcp->isp_topo = topo;
   2569   1.38    mjacob 	}
   2570  1.111    mjacob 	fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
   2571   1.70    mjacob 
   2572   1.98    mjacob 	if (IS_2100(isp)) {
   2573   1.98    mjacob 		/*
   2574   1.98    mjacob 		 * Don't bother with fabric if we are using really old
   2575   1.98    mjacob 		 * 2100 firmware. It's just not worth it.
   2576   1.98    mjacob 		 */
   2577   1.98    mjacob 		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
   2578   1.98    mjacob 			check_for_fabric = 1;
   2579   1.98    mjacob 		} else {
   2580   1.98    mjacob 			check_for_fabric = 0;
   2581   1.98    mjacob 		}
   2582   1.98    mjacob 	} else if (fcp->isp_topo == TOPO_FL_PORT ||
   2583   1.98    mjacob 	    fcp->isp_topo == TOPO_F_PORT) {
   2584   1.70    mjacob 		check_for_fabric = 1;
   2585  1.111    mjacob 	} else {
   2586   1.70    mjacob 		check_for_fabric = 0;
   2587  1.111    mjacob 	}
   2588   1.70    mjacob 
   2589  1.111    mjacob 	if (IS_24XX(isp)) {
   2590  1.111    mjacob 		loopid = NPH_FL_ID;
   2591  1.111    mjacob 	} else {
   2592  1.111    mjacob 		loopid = FL_ID;
   2593  1.111    mjacob 	}
   2594  1.111    mjacob 
   2595  1.111    mjacob 	if (check_for_fabric && isp_getpdb(isp, loopid, &pdb, 1) == 0) {
   2596  1.111    mjacob 		int r;
   2597   1.52        he 		if (IS_2100(isp)) {
   2598   1.52        he 			fcp->isp_topo = TOPO_FL_PORT;
   2599   1.52        he 		}
   2600  1.111    mjacob 		if (pdb.portid == 0) {
   2601   1.70    mjacob 			/*
   2602   1.70    mjacob 			 * Crock.
   2603   1.70    mjacob 			 */
   2604   1.70    mjacob 			fcp->isp_topo = TOPO_NL_PORT;
   2605   1.70    mjacob 			goto not_on_fabric;
   2606   1.70    mjacob 		}
   2607   1.37    mjacob 
   2608   1.37    mjacob 		/*
   2609   1.52        he 		 * Save the Fabric controller's port database entry.
   2610   1.37    mjacob 		 */
   2611  1.111    mjacob 		lp = &fcp->portdb[FL_ID];
   2612  1.111    mjacob 		lp->state = FC_PORTDB_STATE_PENDING_VALID;
   2613  1.111    mjacob 		MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
   2614  1.111    mjacob 		MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
   2615  1.111    mjacob 		lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
   2616  1.111    mjacob 		lp->portid = pdb.portid;
   2617  1.111    mjacob 		lp->handle = pdb.handle;
   2618  1.111    mjacob 		lp->new_portid = lp->portid;
   2619  1.111    mjacob 		lp->new_roles = lp->roles;
   2620  1.111    mjacob 		if (IS_24XX(isp)) {
   2621  1.111    mjacob 			r = isp_register_fc4_type_24xx(isp);
   2622  1.111    mjacob 		} else {
   2623  1.111    mjacob 			r = isp_register_fc4_type(isp);
   2624  1.111    mjacob 		}
   2625  1.111    mjacob 		if (r) {
   2626  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG,
   2627  1.111    mjacob 			    "isp_fclink_test: register fc4 type failed");
   2628  1.111    mjacob 			return (-1);
   2629  1.111    mjacob 		}
   2630   1.70    mjacob 	} else {
   2631   1.70    mjacob not_on_fabric:
   2632  1.111    mjacob 		fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
   2633   1.52        he 	}
   2634   1.52        he 
   2635   1.81    mjacob 	fcp->isp_gbspeed = 1;
   2636  1.111    mjacob 	if (IS_23XX(isp) || IS_24XX(isp)) {
   2637  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   2638   1.81    mjacob 		mbs.param[0] = MBOX_GET_SET_DATA_RATE;
   2639   1.81    mjacob 		mbs.param[1] = MBGSD_GET_RATE;
   2640   1.81    mjacob 		/* mbs.param[2] undefined if we're just getting rate */
   2641  1.111    mjacob 		mbs.logval = MBLOGALL;
   2642  1.111    mjacob 		mbs.timeout = 3000000;
   2643  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   2644   1.81    mjacob 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
   2645  1.111    mjacob 			if (mbs.param[1] == MBGSD_FOURGB) {
   2646  1.111    mjacob 				isp_prt(isp, ISP_LOGINFO, "4Gb link speed/s");
   2647  1.111    mjacob 				fcp->isp_gbspeed = 4;
   2648  1.111    mjacob 			} if (mbs.param[1] == MBGSD_TWOGB) {
   2649   1.81    mjacob 				isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");
   2650   1.81    mjacob 				fcp->isp_gbspeed = 2;
   2651   1.81    mjacob 			}
   2652   1.81    mjacob 		}
   2653   1.81    mjacob 	}
   2654   1.81    mjacob 
   2655   1.70    mjacob 	/*
   2656  1.111    mjacob 	 * Announce ourselves, too.
   2657   1.70    mjacob 	 */
   2658  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, fcp->isp_portid,
   2659  1.111    mjacob 	    fcp->isp_loopid, toponames[fcp->isp_topo]);
   2660  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, ourwwn,
   2661  1.111    mjacob 	    (uint32_t) (ISP_NODEWWN(isp) >> 32),
   2662  1.111    mjacob 	    (uint32_t) ISP_NODEWWN(isp),
   2663  1.111    mjacob 	    (uint32_t) (ISP_PORTWWN(isp) >> 32),
   2664  1.111    mjacob 	    (uint32_t) ISP_PORTWWN(isp));
   2665  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Link Test Complete");
   2666   1.33    mjacob 	return (0);
   2667   1.37    mjacob }
   2668   1.37    mjacob 
   2669  1.107  christos static const char *
   2670  1.111    mjacob ispfc_fw_statename(int state)
   2671   1.57    mjacob {
   2672   1.57    mjacob 	switch(state) {
   2673   1.57    mjacob 	case FW_CONFIG_WAIT:	return "Config Wait";
   2674   1.57    mjacob 	case FW_WAIT_AL_PA:	return "Waiting for AL_PA";
   2675   1.57    mjacob 	case FW_WAIT_LOGIN:	return "Wait Login";
   2676   1.57    mjacob 	case FW_READY:		return "Ready";
   2677   1.57    mjacob 	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";
   2678   1.57    mjacob 	case FW_ERROR:		return "Error";
   2679   1.57    mjacob 	case FW_REINIT:		return "Re-Init";
   2680  1.111    mjacob 	case FW_NON_PART:	return "Nonparticipating";
   2681  1.111    mjacob 	default:		return "?????";
   2682  1.111    mjacob 	}
   2683  1.111    mjacob }
   2684  1.111    mjacob 
   2685  1.111    mjacob /*
   2686  1.111    mjacob  * Complete the synchronization of our Port Database.
   2687  1.111    mjacob  *
   2688  1.111    mjacob  * At this point, we've scanned the local loop (if any) and the fabric
   2689  1.111    mjacob  * and performed fabric logins on all new devices.
   2690  1.111    mjacob  *
   2691  1.111    mjacob  * Our task here is to go through our port database and remove any entities
   2692  1.111    mjacob  * that are still marked probational (issuing PLOGO for ones which we had
   2693  1.111    mjacob  * PLOGI'd into) or are dead.
   2694  1.111    mjacob  *
   2695  1.111    mjacob  * Our task here is to also check policy to decide whether devices which
   2696  1.111    mjacob  * have *changed* in some way should still be kept active. For example,
   2697  1.111    mjacob  * if a device has just changed PortID, we can either elect to treat it
   2698  1.111    mjacob  * as an old device or as a newly arrived device (and notify the outer
   2699  1.111    mjacob  * layer appropriately).
   2700  1.111    mjacob  *
   2701  1.111    mjacob  * We also do initiator map target id assignment here for new initiator
   2702  1.111    mjacob  * devices and refresh old ones ot make sure that they point to the corret
   2703  1.111    mjacob  * entities.
   2704  1.111    mjacob  */
   2705  1.111    mjacob static int
   2706  1.111    mjacob isp_pdb_sync(ispsoftc_t *isp)
   2707  1.111    mjacob {
   2708  1.111    mjacob 	fcparam *fcp = isp->isp_param;
   2709  1.111    mjacob 	fcportdb_t *lp;
   2710  1.111    mjacob 	uint16_t dbidx;
   2711  1.111    mjacob 
   2712  1.111    mjacob 	if (fcp->isp_loopstate == LOOP_READY) {
   2713  1.111    mjacob 		return (0);
   2714  1.111    mjacob 	}
   2715  1.111    mjacob 
   2716  1.111    mjacob 	/*
   2717  1.111    mjacob 	 * Make sure we're okay for doing this right now.
   2718  1.111    mjacob 	 */
   2719  1.111    mjacob 	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
   2720  1.111    mjacob 	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
   2721  1.111    mjacob 	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
   2722  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
   2723  1.111    mjacob 		    fcp->isp_loopstate);
   2724  1.111    mjacob 		return (-1);
   2725  1.111    mjacob 	}
   2726  1.111    mjacob 
   2727  1.111    mjacob 	if (fcp->isp_topo == TOPO_FL_PORT ||
   2728  1.111    mjacob 	    fcp->isp_topo == TOPO_NL_PORT ||
   2729  1.111    mjacob 	    fcp->isp_topo == TOPO_N_PORT) {
   2730  1.111    mjacob 		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
   2731  1.111    mjacob 			if (isp_scan_loop(isp) != 0) {
   2732  1.111    mjacob 				isp_prt(isp, ISP_LOGWARN,
   2733  1.111    mjacob 				    "isp_pdb_sync: isp_scan_loop failed");
   2734  1.111    mjacob 				return (-1);
   2735  1.111    mjacob 			}
   2736  1.111    mjacob 		}
   2737  1.111    mjacob 	}
   2738  1.111    mjacob 
   2739  1.111    mjacob 	if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
   2740  1.111    mjacob 		if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
   2741  1.111    mjacob 			if (isp_scan_fabric(isp) != 0) {
   2742  1.111    mjacob 				isp_prt(isp, ISP_LOGWARN,
   2743  1.111    mjacob 				    "isp_pdb_sync: isp_scan_fabric failed");
   2744  1.111    mjacob 				return (-1);
   2745  1.111    mjacob 			}
   2746  1.111    mjacob 		}
   2747  1.111    mjacob 	}
   2748  1.111    mjacob 
   2749  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Synchronizing PDBs");
   2750  1.111    mjacob 
   2751  1.111    mjacob 	fcp->isp_loopstate = LOOP_SYNCING_PDB;
   2752  1.111    mjacob 
   2753  1.111    mjacob 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
   2754  1.111    mjacob 		lp = &fcp->portdb[dbidx];
   2755  1.111    mjacob 
   2756  1.111    mjacob 		if (lp->state == FC_PORTDB_STATE_NIL) {
   2757  1.111    mjacob 			continue;
   2758  1.111    mjacob 		}
   2759  1.111    mjacob 
   2760  1.111    mjacob 		if (lp->state == FC_PORTDB_STATE_VALID) {
   2761  1.111    mjacob 			if (dbidx != FL_ID) {
   2762  1.111    mjacob 				isp_prt(isp,
   2763  1.111    mjacob 				    ISP_LOGERR, "portdb idx %d already valid",
   2764  1.111    mjacob 			    	    dbidx);
   2765  1.111    mjacob 			}
   2766  1.111    mjacob 			continue;
   2767  1.111    mjacob 		}
   2768  1.111    mjacob 
   2769  1.111    mjacob 		switch (lp->state) {
   2770  1.111    mjacob 		case FC_PORTDB_STATE_PROBATIONAL:
   2771  1.111    mjacob 		case FC_PORTDB_STATE_DEAD:
   2772  1.111    mjacob 			/*
   2773  1.111    mjacob 			 * It's up to the outer layers to clear isp_ini_map.
   2774  1.111    mjacob 			 */
   2775  1.111    mjacob 			lp->state = FC_PORTDB_STATE_NIL;
   2776  1.111    mjacob 			isp_async(isp, ISPASYNC_DEV_GONE, lp);
   2777  1.111    mjacob 			if (lp->autologin == 0) {
   2778  1.111    mjacob 				(void) isp_plogx(isp, lp->handle, lp->portid,
   2779  1.111    mjacob 				    PLOGX_FLG_CMD_LOGO |
   2780  1.111    mjacob 				    PLOGX_FLG_IMPLICIT |
   2781  1.111    mjacob 				    PLOGX_FLG_FREE_NPHDL, 0);
   2782  1.111    mjacob 			} else {
   2783  1.111    mjacob 				lp->autologin = 0;
   2784  1.111    mjacob 			}
   2785  1.111    mjacob 			lp->new_roles = 0;
   2786  1.111    mjacob 			lp->new_portid = 0;
   2787  1.111    mjacob 			/*
   2788  1.111    mjacob 			 * Note that we might come out of this with our state
   2789  1.111    mjacob 			 * set to FC_PORTDB_STATE_ZOMBIE.
   2790  1.111    mjacob 			 */
   2791  1.111    mjacob 			break;
   2792  1.111    mjacob 		case FC_PORTDB_STATE_NEW:
   2793  1.111    mjacob 			/*
   2794  1.111    mjacob 			 * It's up to the outer layers to assign a virtual
   2795  1.111    mjacob 			 * target id in isp_ini_map (if any).
   2796  1.111    mjacob 			 */
   2797  1.111    mjacob 			lp->portid = lp->new_portid;
   2798  1.111    mjacob 			lp->roles = lp->new_roles;
   2799  1.111    mjacob 			lp->state = FC_PORTDB_STATE_VALID;
   2800  1.111    mjacob 			isp_async(isp, ISPASYNC_DEV_ARRIVED, lp);
   2801  1.111    mjacob 			lp->new_roles = 0;
   2802  1.111    mjacob 			lp->new_portid = 0;
   2803  1.111    mjacob 			lp->reserved = 0;
   2804  1.111    mjacob 			lp->new_reserved = 0;
   2805  1.111    mjacob 			break;
   2806  1.111    mjacob 		case FC_PORTDB_STATE_CHANGED:
   2807  1.111    mjacob /*
   2808  1.111    mjacob  * XXXX FIX THIS
   2809  1.111    mjacob  */
   2810  1.111    mjacob 			lp->state = FC_PORTDB_STATE_VALID;
   2811  1.111    mjacob 			isp_async(isp, ISPASYNC_DEV_CHANGED, lp);
   2812  1.111    mjacob 			lp->new_roles = 0;
   2813  1.111    mjacob 			lp->new_portid = 0;
   2814  1.111    mjacob 			lp->reserved = 0;
   2815  1.111    mjacob 			lp->new_reserved = 0;
   2816  1.111    mjacob 			break;
   2817  1.111    mjacob 		case FC_PORTDB_STATE_PENDING_VALID:
   2818  1.111    mjacob 			lp->portid = lp->new_portid;
   2819  1.111    mjacob 			lp->roles = lp->new_roles;
   2820  1.111    mjacob 			if (lp->ini_map_idx) {
   2821  1.111    mjacob 				int t = lp->ini_map_idx - 1;
   2822  1.111    mjacob 				fcp->isp_ini_map[t] = dbidx + 1;
   2823  1.111    mjacob 			}
   2824  1.111    mjacob 			lp->state = FC_PORTDB_STATE_VALID;
   2825  1.111    mjacob 			isp_async(isp, ISPASYNC_DEV_STAYED, lp);
   2826  1.111    mjacob 			if (dbidx != FL_ID) {
   2827  1.111    mjacob 				lp->new_roles = 0;
   2828  1.111    mjacob 				lp->new_portid = 0;
   2829  1.111    mjacob 			}
   2830  1.111    mjacob 			lp->reserved = 0;
   2831  1.111    mjacob 			lp->new_reserved = 0;
   2832  1.111    mjacob 			break;
   2833  1.111    mjacob 		case FC_PORTDB_STATE_ZOMBIE:
   2834  1.111    mjacob 			break;
   2835  1.111    mjacob 		default:
   2836  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN,
   2837  1.111    mjacob 			    "isp_scan_loop: state %d for idx %d",
   2838  1.111    mjacob 			    lp->state, dbidx);
   2839  1.111    mjacob 			isp_dump_portdb(isp);
   2840  1.111    mjacob 		}
   2841  1.111    mjacob 	}
   2842  1.111    mjacob 
   2843  1.111    mjacob 	/*
   2844  1.111    mjacob 	 * If we get here, we've for sure seen not only a valid loop
   2845  1.111    mjacob 	 * but know what is or isn't on it, so mark this for usage
   2846  1.111    mjacob 	 * in isp_start.
   2847  1.111    mjacob 	 */
   2848  1.111    mjacob 	fcp->loop_seen_once = 1;
   2849  1.111    mjacob 	fcp->isp_loopstate = LOOP_READY;
   2850  1.111    mjacob 	return (0);
   2851   1.57    mjacob }
   2852   1.33    mjacob 
   2853    1.1       cgd /*
   2854  1.111    mjacob  * Scan local loop for devices.
   2855   1.37    mjacob  */
   2856   1.37    mjacob static int
   2857  1.111    mjacob isp_scan_loop(ispsoftc_t *isp)
   2858   1.37    mjacob {
   2859  1.111    mjacob 	fcportdb_t *lp, tmp;
   2860   1.37    mjacob 	fcparam *fcp = isp->isp_param;
   2861  1.111    mjacob 	int i;
   2862   1.37    mjacob 	isp_pdb_t pdb;
   2863  1.111    mjacob 	uint16_t handle, lim = 0;
   2864   1.37    mjacob 
   2865  1.111    mjacob 	if (fcp->isp_fwstate < FW_READY ||
   2866  1.111    mjacob 	    fcp->isp_loopstate < LOOP_PDB_RCVD) {
   2867   1.70    mjacob 		return (-1);
   2868   1.70    mjacob 	}
   2869   1.70    mjacob 
   2870  1.111    mjacob 	if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
   2871  1.111    mjacob 		return (0);
   2872   1.70    mjacob 	}
   2873   1.70    mjacob 
   2874   1.37    mjacob 	/*
   2875  1.111    mjacob 	 * Check our connection topology.
   2876  1.111    mjacob 	 *
   2877  1.111    mjacob 	 * If we're a public or private loop, we scan 0..125 as handle values.
   2878  1.111    mjacob 	 * The firmware has (typically) peformed a PLOGI for us.
   2879  1.111    mjacob 	 *
   2880  1.111    mjacob 	 * If we're a N-port connection, we treat this is a short loop (0..1).
   2881  1.111    mjacob 	 *
   2882  1.111    mjacob 	 * If we're in target mode, we can all possible handles to see who
   2883  1.111    mjacob 	 * might have logged into us.
   2884   1.37    mjacob 	 */
   2885  1.111    mjacob 	switch (fcp->isp_topo) {
   2886  1.111    mjacob 	case TOPO_NL_PORT:
   2887  1.111    mjacob 	case TOPO_FL_PORT:
   2888  1.111    mjacob 		lim = LOCAL_LOOP_LIM;
   2889  1.111    mjacob 		break;
   2890  1.111    mjacob 	case TOPO_N_PORT:
   2891  1.111    mjacob 		lim = 2;
   2892  1.111    mjacob 		break;
   2893  1.111    mjacob 	default:
   2894  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, "no loop topology to scan");
   2895  1.111    mjacob 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
   2896   1.70    mjacob 		return (0);
   2897   1.52        he 	}
   2898   1.52        he 
   2899  1.111    mjacob 	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
   2900   1.70    mjacob 
   2901  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC scan loop 0..%d", lim-1);
   2902   1.70    mjacob 
   2903   1.46    mjacob 
   2904   1.43    mjacob 	/*
   2905  1.111    mjacob 	 * Run through the list and get the port database info for each one.
   2906   1.43    mjacob 	 */
   2907  1.111    mjacob 	for (handle = 0; handle < lim; handle++) {
   2908  1.111    mjacob 		/*
   2909  1.111    mjacob 		 * But don't even try for ourselves...
   2910  1.111    mjacob 	 	 */
   2911  1.111    mjacob 		if (handle == fcp->isp_loopid) {
   2912   1.37    mjacob 			continue;
   2913   1.70    mjacob 		}
   2914   1.70    mjacob 
   2915   1.70    mjacob 		/*
   2916  1.111    mjacob 		 * In older cards with older f/w GET_PORT_DATABASE has been
   2917  1.111    mjacob 		 * known to hang. This trick gets around that problem.
   2918   1.70    mjacob 		 */
   2919  1.111    mjacob 		if (IS_2100(isp) || IS_2200(isp)) {
   2920  1.111    mjacob 			uint64_t node_wwn = isp_get_portname(isp, handle, 1);
   2921  1.111    mjacob 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
   2922  1.111    mjacob 				return (-1);
   2923  1.111    mjacob 			}
   2924  1.111    mjacob 			if (node_wwn == 0) {
   2925  1.111    mjacob 				continue;
   2926  1.111    mjacob 			}
   2927   1.37    mjacob 		}
   2928   1.38    mjacob 
   2929   1.37    mjacob 		/*
   2930  1.111    mjacob 		 * Get the port database entity for this index.
   2931   1.37    mjacob 		 */
   2932  1.111    mjacob 		if (isp_getpdb(isp, handle, &pdb, 1) != 0) {
   2933  1.111    mjacob 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
   2934  1.111    mjacob 				ISP_MARK_PORTDB(isp, 1);
   2935  1.111    mjacob 				return (-1);
   2936  1.111    mjacob 			}
   2937   1.37    mjacob 			continue;
   2938   1.37    mjacob 		}
   2939   1.38    mjacob 
   2940  1.111    mjacob 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
   2941  1.111    mjacob 			ISP_MARK_PORTDB(isp, 1);
   2942  1.111    mjacob 			return (-1);
   2943  1.111    mjacob 		}
   2944   1.52        he 
   2945   1.37    mjacob 		/*
   2946  1.111    mjacob 		 * On *very* old 2100 firmware we would end up sometimes
   2947  1.111    mjacob 		 * with the firmware returning the port database entry
   2948  1.111    mjacob 		 * for something else. We used to restart this, but
   2949  1.111    mjacob 		 * now we just punt.
   2950  1.111    mjacob 		 */
   2951  1.111    mjacob 		if (IS_2100(isp) && pdb.handle != handle) {
   2952  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN,
   2953  1.111    mjacob 			    "giving up on synchronizing the port database");
   2954  1.111    mjacob 			ISP_MARK_PORTDB(isp, 1);
   2955   1.70    mjacob 			return (-1);
   2956   1.37    mjacob 		}
   2957   1.37    mjacob 
   2958   1.37    mjacob 		/*
   2959  1.111    mjacob 		 * Save the pertinent info locally.
   2960   1.37    mjacob 		 */
   2961  1.111    mjacob 		MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
   2962  1.111    mjacob 		MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
   2963  1.111    mjacob 		tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
   2964  1.111    mjacob 		tmp.portid = pdb.portid;
   2965  1.111    mjacob 		tmp.handle = pdb.handle;
   2966  1.111    mjacob 
   2967  1.111    mjacob 		/*
   2968  1.111    mjacob 		 * Check to make sure it's still a valid entry. The 24XX seems
   2969  1.111    mjacob 		 * to return a portid but not a WWPN/WWNN or role for devices
   2970  1.111    mjacob 		 * which shift on a loop.
   2971  1.111    mjacob 		 */
   2972  1.111    mjacob 		if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
   2973  1.111    mjacob 			int a, b, c;
   2974  1.111    mjacob 			a = (tmp.node_wwn == 0);
   2975  1.111    mjacob 			b = (tmp.port_wwn == 0);
   2976  1.111    mjacob 			c = (tmp.portid == 0);
   2977  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN,
   2978  1.111    mjacob 			    "bad pdb (%1d%1d%1d) @ handle 0x%x", a, b, c,
   2979  1.111    mjacob 			    handle);
   2980  1.111    mjacob 			isp_dump_portdb(isp);
   2981  1.111    mjacob 			continue;
   2982   1.37    mjacob 		}
   2983   1.37    mjacob 
   2984   1.37    mjacob 		/*
   2985  1.111    mjacob 		 * Now search the entire port database
   2986  1.111    mjacob 		 * for the same Port and Node WWN.
   2987   1.37    mjacob 		 */
   2988  1.111    mjacob 		for (i = 0; i < MAX_FC_TARG; i++) {
   2989  1.111    mjacob 			lp = &fcp->portdb[i];
   2990  1.111    mjacob 			if (lp->state == FC_PORTDB_STATE_NIL) {
   2991  1.111    mjacob 				continue;
   2992  1.111    mjacob 			}
   2993  1.111    mjacob 			if (lp->node_wwn != tmp.node_wwn) {
   2994  1.111    mjacob 				continue;
   2995  1.111    mjacob 			}
   2996  1.111    mjacob 			if (lp->port_wwn != tmp.port_wwn) {
   2997  1.111    mjacob 				continue;
   2998  1.111    mjacob 			}
   2999  1.111    mjacob 
   3000  1.111    mjacob 			/*
   3001  1.111    mjacob 			 * Okay- we've found a non-nil entry that matches.
   3002  1.111    mjacob 			 * Check to make sure it's probational or a zombie.
   3003  1.111    mjacob 			 */
   3004  1.111    mjacob 			if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
   3005  1.111    mjacob 			    lp->state != FC_PORTDB_STATE_ZOMBIE) {
   3006  1.111    mjacob 				isp_prt(isp, ISP_LOGERR,
   3007  1.111    mjacob 				    "[%d] not probational/zombie (0x%x)",
   3008  1.111    mjacob 				    i, lp->state);
   3009  1.111    mjacob 				isp_dump_portdb(isp);
   3010  1.111    mjacob 				ISP_MARK_PORTDB(isp, 1);
   3011   1.70    mjacob 				return (-1);
   3012   1.37    mjacob 			}
   3013  1.111    mjacob 
   3014  1.111    mjacob 			/*
   3015  1.111    mjacob 			 * Mark the device as something the f/w logs into
   3016  1.111    mjacob 			 * automatically.
   3017  1.111    mjacob 			 */
   3018  1.111    mjacob 			lp->autologin = 1;
   3019  1.111    mjacob 
   3020  1.111    mjacob 			/*
   3021  1.111    mjacob 			 * Check to make see if really still the same
   3022  1.111    mjacob 			 * device. If it is, we mark it pending valid.
   3023  1.111    mjacob 			 */
   3024  1.111    mjacob 			if (lp->portid == tmp.portid &&
   3025  1.111    mjacob 			    lp->handle == tmp.handle &&
   3026  1.111    mjacob 			    lp->roles == tmp.roles) {
   3027  1.111    mjacob 				lp->new_portid = tmp.portid;
   3028  1.111    mjacob 				lp->new_roles = tmp.roles;
   3029  1.111    mjacob 				lp->state = FC_PORTDB_STATE_PENDING_VALID;
   3030  1.111    mjacob 				isp_prt(isp, ISP_LOGSANCFG,
   3031  1.111    mjacob 				    "Loop Port 0x%02x@0x%x Pending Valid",
   3032  1.111    mjacob 				    tmp.portid, tmp.handle);
   3033   1.70    mjacob 				break;
   3034   1.37    mjacob 			}
   3035  1.111    mjacob 
   3036  1.111    mjacob 			/*
   3037  1.111    mjacob 			 * We can wipe out the old handle value
   3038  1.111    mjacob 			 * here because it's no longer valid.
   3039  1.111    mjacob 			 */
   3040  1.111    mjacob 			lp->handle = tmp.handle;
   3041  1.111    mjacob 
   3042  1.111    mjacob 			/*
   3043  1.111    mjacob 			 * Claim that this has changed and let somebody else
   3044  1.111    mjacob 			 * decide what to do.
   3045  1.111    mjacob 			 */
   3046  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG,
   3047  1.111    mjacob 			    "Loop Port 0x%02x@0x%x changed",
   3048  1.111    mjacob 			    tmp.portid, tmp.handle);
   3049  1.111    mjacob 			lp->state = FC_PORTDB_STATE_CHANGED;
   3050  1.111    mjacob 			lp->new_portid = tmp.portid;
   3051  1.111    mjacob 			lp->new_roles = tmp.roles;
   3052  1.111    mjacob 			break;
   3053  1.111    mjacob 		}
   3054   1.37    mjacob 
   3055   1.37    mjacob 		/*
   3056  1.111    mjacob 		 * Did we find and update an old entry?
   3057   1.37    mjacob 		 */
   3058  1.111    mjacob 		if (i < MAX_FC_TARG) {
   3059   1.37    mjacob 			continue;
   3060   1.37    mjacob 		}
   3061   1.37    mjacob 
   3062   1.37    mjacob 		/*
   3063  1.111    mjacob 		 * Ah. A new device entry. Find an empty slot
   3064  1.111    mjacob 		 * for it and save info for later disposition.
   3065   1.37    mjacob 		 */
   3066  1.111    mjacob 		for (i = 0; i < MAX_FC_TARG; i++) {
   3067  1.111    mjacob 			if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
   3068  1.111    mjacob 				break;
   3069  1.111    mjacob 			}
   3070  1.111    mjacob 		}
   3071  1.111    mjacob 		if (i == MAX_FC_TARG) {
   3072  1.111    mjacob 			isp_prt(isp, ISP_LOGERR, "out of portdb entries");
   3073  1.111    mjacob 			continue;
   3074   1.70    mjacob 		}
   3075  1.111    mjacob 		lp = &fcp->portdb[i];
   3076  1.111    mjacob 
   3077  1.111    mjacob 		MEMZERO(lp, sizeof (fcportdb_t));
   3078  1.111    mjacob 		lp->autologin = 1;
   3079  1.111    mjacob 		lp->state = FC_PORTDB_STATE_NEW;
   3080  1.111    mjacob 		lp->new_portid = tmp.portid;
   3081  1.111    mjacob 		lp->new_roles = tmp.roles;
   3082  1.111    mjacob 		lp->handle = tmp.handle;
   3083  1.111    mjacob 		lp->port_wwn = tmp.port_wwn;
   3084  1.111    mjacob 		lp->node_wwn = tmp.node_wwn;
   3085  1.111    mjacob 		isp_prt(isp, ISP_LOGSANCFG,
   3086  1.111    mjacob 		    "Loop Port 0x%02x@0x%x is New Entry",
   3087  1.111    mjacob 		    tmp.portid, tmp.handle);
   3088  1.111    mjacob 	}
   3089  1.111    mjacob 	fcp->isp_loopstate = LOOP_LSCAN_DONE;
   3090  1.111    mjacob 	return (0);
   3091  1.111    mjacob }
   3092  1.111    mjacob 
   3093  1.111    mjacob /*
   3094  1.111    mjacob  * Scan the fabric for devices and add them to our port database.
   3095  1.111    mjacob  *
   3096  1.111    mjacob  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
   3097  1.111    mjacob  *
   3098  1.111    mjacob  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
   3099  1.111    mjacob  * name server commands to the switch management server via the QLogic f/w.
   3100  1.111    mjacob  *
   3101  1.111    mjacob  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
   3102  1.111    mjacob  * mailbox command.
   3103  1.111    mjacob  *
   3104  1.111    mjacob  * The net result is to leave the list of Port IDs setting untranslated in
   3105  1.111    mjacob  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
   3106  1.111    mjacob  * host order at OGPOFF.
   3107  1.111    mjacob  */
   3108  1.111    mjacob 
   3109  1.111    mjacob /*
   3110  1.111    mjacob  * Take less than half of our scratch area to store Port IDs
   3111  1.111    mjacob  */
   3112  1.111    mjacob #define	GIDLEN	((ISP2100_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
   3113  1.111    mjacob #define	NGENT	((GIDLEN - 16) >> 2)
   3114  1.111    mjacob 
   3115  1.111    mjacob #define	IGPOFF	(2 * QENTRY_LEN)
   3116  1.111    mjacob #define	OGPOFF	(ISP2100_SCRLEN >> 1)
   3117  1.111    mjacob #define	ZTXOFF	(ISP2100_SCRLEN - (1 * QENTRY_LEN))
   3118  1.111    mjacob #define	CTXOFF	(ISP2100_SCRLEN - (2 * QENTRY_LEN))
   3119  1.111    mjacob #define	XTXOFF	(ISP2100_SCRLEN - (3 * QENTRY_LEN))
   3120  1.111    mjacob 
   3121  1.111    mjacob static int
   3122  1.111    mjacob isp_gid_ft_sns(ispsoftc_t *isp)
   3123  1.111    mjacob {
   3124  1.111    mjacob 	union {
   3125  1.111    mjacob 		sns_gid_ft_req_t _x;
   3126  1.111    mjacob 		uint8_t _y[SNS_GID_FT_REQ_SIZE];
   3127  1.111    mjacob 	} un;
   3128  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   3129  1.111    mjacob 	sns_gid_ft_req_t *rq = &un._x;
   3130  1.111    mjacob 	mbreg_t mbs;
   3131  1.111    mjacob 
   3132  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via SNS");
   3133  1.111    mjacob 
   3134  1.111    mjacob 	MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
   3135  1.111    mjacob 	rq->snscb_rblen = GIDLEN >> 1;
   3136  1.111    mjacob 	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
   3137  1.111    mjacob 	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
   3138  1.111    mjacob 	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
   3139  1.111    mjacob 	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
   3140  1.111    mjacob 	rq->snscb_sblen = 6;
   3141  1.111    mjacob 	rq->snscb_cmd = SNS_GID_FT;
   3142  1.111    mjacob 	rq->snscb_mword_div_2 = NGENT;
   3143  1.111    mjacob 	rq->snscb_fc4_type = FC4_SCSI;
   3144   1.70    mjacob 
   3145  1.111    mjacob 	isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
   3146  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE);
   3147  1.111    mjacob 
   3148  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   3149  1.111    mjacob 	mbs.param[0] = MBOX_SEND_SNS;
   3150  1.111    mjacob 	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
   3151  1.111    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
   3152  1.111    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
   3153  1.111    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
   3154  1.111    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
   3155  1.111    mjacob 	mbs.logval = MBLOGALL;
   3156  1.111    mjacob 	mbs.timeout = 10000000;
   3157  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   3158  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   3159  1.111    mjacob 		if (mbs.param[0] == MBOX_INVALID_COMMAND) {
   3160  1.111    mjacob 			return (1);
   3161  1.111    mjacob 		} else {
   3162   1.70    mjacob 			return (-1);
   3163   1.70    mjacob 		}
   3164  1.111    mjacob 	}
   3165  1.111    mjacob 	return (0);
   3166  1.111    mjacob }
   3167  1.111    mjacob 
   3168  1.111    mjacob static int
   3169  1.111    mjacob isp_gid_ft_ct_passthru(ispsoftc_t *isp)
   3170  1.111    mjacob {
   3171  1.111    mjacob 	mbreg_t mbs;
   3172  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   3173  1.111    mjacob 	union {
   3174  1.111    mjacob 		isp_ct_pt_t plocal;
   3175  1.111    mjacob 		ct_hdr_t clocal;
   3176  1.111    mjacob 		uint8_t q[QENTRY_LEN];
   3177  1.111    mjacob 	} un;
   3178  1.111    mjacob 	isp_ct_pt_t *pt;
   3179  1.111    mjacob 	ct_hdr_t *ct;
   3180  1.111    mjacob 	uint32_t *rp;
   3181  1.111    mjacob 	uint8_t *scp = fcp->isp_scratch;
   3182  1.111    mjacob 
   3183  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT) via CT");
   3184  1.111    mjacob 
   3185  1.111    mjacob 	if (!IS_24XX(isp)) {
   3186  1.111    mjacob 		return (1);
   3187  1.111    mjacob 	}
   3188   1.70    mjacob 
   3189  1.111    mjacob 	/*
   3190  1.111    mjacob 	 * Build a Passthrough IOCB in memory.
   3191  1.111    mjacob 	 */
   3192  1.111    mjacob 	pt = &un.plocal;
   3193  1.111    mjacob 	MEMZERO(un.q, QENTRY_LEN);
   3194  1.111    mjacob 	pt->ctp_header.rqs_entry_count = 1;
   3195  1.111    mjacob 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
   3196  1.111    mjacob 	pt->ctp_handle = 0xffffffff;
   3197  1.111    mjacob 	pt->ctp_nphdl = NPH_SNS_ID;
   3198  1.111    mjacob 	pt->ctp_cmd_cnt = 1;
   3199  1.111    mjacob 	pt->ctp_time = 30;
   3200  1.111    mjacob 	pt->ctp_rsp_cnt = 1;
   3201  1.111    mjacob 	pt->ctp_rsp_bcnt = GIDLEN;
   3202  1.111    mjacob 	pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
   3203  1.111    mjacob 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
   3204  1.111    mjacob 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
   3205  1.111    mjacob 	pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
   3206  1.111    mjacob 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
   3207  1.111    mjacob 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
   3208  1.111    mjacob 	pt->ctp_dataseg[1].ds_count = GIDLEN;
   3209  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   3210  1.111    mjacob 		isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
   3211   1.37    mjacob 	}
   3212  1.111    mjacob 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
   3213  1.111    mjacob 
   3214   1.37    mjacob 	/*
   3215  1.111    mjacob 	 * Build the CT header and command in memory.
   3216  1.111    mjacob 	 *
   3217  1.111    mjacob 	 * Note that the CT header has to end up as Big Endian format in memory.
   3218   1.37    mjacob 	 */
   3219  1.111    mjacob 	ct = &un.clocal;
   3220  1.111    mjacob 	MEMZERO(ct, sizeof (*ct));
   3221  1.111    mjacob 	ct->ct_revision = CT_REVISION;
   3222  1.111    mjacob 	ct->ct_fcs_type = CT_FC_TYPE_FC;
   3223  1.111    mjacob 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
   3224  1.111    mjacob 	ct->ct_cmd_resp = SNS_GID_FT;
   3225  1.111    mjacob 	ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
   3226  1.111    mjacob 
   3227  1.111    mjacob 	isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
   3228  1.111    mjacob 	rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
   3229  1.111    mjacob 	ISP_IOZPUT_32(isp, FC4_SCSI, rp);
   3230  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   3231  1.111    mjacob 		isp_print_bytes(isp, "CT HDR + payload after put",
   3232  1.111    mjacob 		    sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
   3233  1.111    mjacob 	}
   3234  1.111    mjacob 	MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
   3235  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   3236  1.111    mjacob 	mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
   3237  1.111    mjacob 	mbs.param[1] = QENTRY_LEN;
   3238  1.111    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
   3239  1.111    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
   3240  1.111    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
   3241  1.111    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
   3242  1.111    mjacob 	mbs.timeout = 500000;
   3243  1.111    mjacob 	mbs.logval = MBLOGALL;
   3244  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
   3245  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   3246  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   3247  1.111    mjacob 		return (-1);
   3248  1.111    mjacob 	}
   3249  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
   3250  1.111    mjacob 	pt = &un.plocal;
   3251  1.111    mjacob 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
   3252  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   3253  1.111    mjacob 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
   3254  1.111    mjacob 	}
   3255  1.111    mjacob 
   3256  1.111    mjacob 	if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
   3257  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x",
   3258  1.111    mjacob 		    pt->ctp_status);
   3259  1.111    mjacob 		return (-1);
   3260  1.111    mjacob 	}
   3261  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16);
   3262  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   3263  1.111    mjacob 		isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
   3264  1.111    mjacob 	}
   3265   1.70    mjacob 	return (0);
   3266   1.70    mjacob }
   3267   1.70    mjacob 
   3268   1.70    mjacob static int
   3269  1.111    mjacob isp_scan_fabric(ispsoftc_t *isp)
   3270   1.70    mjacob {
   3271  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   3272  1.111    mjacob 	uint32_t portid;
   3273  1.111    mjacob 	uint16_t handle, oldhandle;
   3274  1.111    mjacob 	int portidx, portlim, r;
   3275  1.111    mjacob 	sns_gid_ft_rsp_t *rs0, *rs1;
   3276  1.111    mjacob 
   3277  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric");
   3278  1.111    mjacob 	if (fcp->isp_fwstate != FW_READY ||
   3279  1.111    mjacob 	    fcp->isp_loopstate < LOOP_LSCAN_DONE) {
   3280  1.111    mjacob 		return (-1);
   3281  1.111    mjacob 	}
   3282  1.111    mjacob 	if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
   3283  1.111    mjacob 		return (0);
   3284  1.111    mjacob 	}
   3285  1.111    mjacob 	if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
   3286  1.111    mjacob 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
   3287  1.111    mjacob 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3288  1.111    mjacob 		    "FC Scan Fabric Done (no fabric)");
   3289  1.111    mjacob 		return (0);
   3290  1.111    mjacob 	}
   3291  1.111    mjacob 
   3292  1.111    mjacob 	FC_SCRATCH_ACQUIRE(isp);
   3293  1.111    mjacob 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
   3294  1.111    mjacob 
   3295  1.111    mjacob 	if (IS_24XX(isp)) {
   3296  1.111    mjacob 		r = isp_gid_ft_ct_passthru(isp);
   3297  1.111    mjacob 	} else {
   3298  1.111    mjacob 		r = isp_gid_ft_sns(isp);
   3299  1.111    mjacob 	}
   3300  1.111    mjacob 
   3301  1.111    mjacob 	if (r > 0) {
   3302  1.111    mjacob 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
   3303  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   3304  1.111    mjacob 		return (0);
   3305  1.111    mjacob 	} else if (r < 0) {
   3306  1.111    mjacob 		fcp->isp_loopstate = LOOP_PDB_RCVD;	/* try again */
   3307  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   3308  1.111    mjacob 		return (0);
   3309  1.111    mjacob 	}
   3310  1.111    mjacob 	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3311  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   3312  1.111    mjacob 		return (-1);
   3313  1.111    mjacob 	}
   3314  1.111    mjacob 
   3315  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN);
   3316  1.111    mjacob 	rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
   3317  1.111    mjacob 	rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
   3318  1.111    mjacob 	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
   3319  1.111    mjacob 	if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
   3320  1.111    mjacob 		int level;
   3321  1.111    mjacob 		if (rs1->snscb_cthdr.ct_reason == 9 &&
   3322  1.111    mjacob 		    rs1->snscb_cthdr.ct_explanation == 7) {
   3323  1.111    mjacob 			level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
   3324  1.111    mjacob 		} else {
   3325  1.111    mjacob 			level = ISP_LOGWARN;
   3326  1.111    mjacob 		}
   3327  1.111    mjacob 		isp_prt(isp, level, "Fabric Nameserver rejected GID_FT "
   3328  1.111    mjacob 		    "(Reason=0x%x Expl=0x%x)", rs1->snscb_cthdr.ct_reason,
   3329  1.111    mjacob 		    rs1->snscb_cthdr.ct_explanation);
   3330  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   3331  1.111    mjacob 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
   3332  1.111    mjacob 		return (0);
   3333  1.111    mjacob 	}
   3334  1.111    mjacob 
   3335  1.111    mjacob 
   3336  1.111    mjacob 	/*
   3337  1.111    mjacob 	 * If we get this far, we certainly still have the fabric controller.
   3338  1.111    mjacob 	 */
   3339  1.111    mjacob 	fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
   3340  1.111    mjacob 
   3341  1.111    mjacob 	/*
   3342  1.111    mjacob 	 * Prime the handle we will start using.
   3343  1.111    mjacob 	 */
   3344  1.111    mjacob 	oldhandle = NIL_HANDLE;
   3345  1.111    mjacob 
   3346  1.111    mjacob 	/*
   3347  1.111    mjacob 	 * Okay, we now have a list of Port IDs for all FC4 SCSI devices
   3348  1.111    mjacob 	 * that the Fabric Name server knows about. Go through the list
   3349  1.111    mjacob 	 * and remove duplicate port ids.
   3350  1.111    mjacob 	 */
   3351  1.111    mjacob 
   3352  1.111    mjacob 	portlim = 0;
   3353  1.111    mjacob 	portidx = 0;
   3354  1.111    mjacob 	for (portidx = 0; portidx < NGENT-1; portidx++) {
   3355  1.111    mjacob 		if (rs1->snscb_ports[portidx].control & 0x80) {
   3356  1.111    mjacob 			break;
   3357  1.111    mjacob 		}
   3358  1.111    mjacob 	}
   3359  1.111    mjacob 
   3360  1.111    mjacob 	/*
   3361  1.111    mjacob 	 * If we're not at the last entry, our list wasn't big enough.
   3362  1.111    mjacob 	 */
   3363  1.111    mjacob 	if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
   3364  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN,
   3365  1.111    mjacob 		    "fabric too big for scratch area: increase ISP2100_SCRLEN");
   3366  1.111    mjacob 	}
   3367  1.111    mjacob 	portlim = portidx + 1;
   3368  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG,
   3369  1.111    mjacob 	    "got %d ports back from name server", portlim);
   3370  1.111    mjacob 
   3371  1.111    mjacob 	for (portidx = 0; portidx < portlim; portidx++) {
   3372  1.111    mjacob 		int npidx;
   3373  1.111    mjacob 
   3374  1.111    mjacob 		portid =
   3375  1.111    mjacob 		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
   3376  1.111    mjacob 		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
   3377  1.111    mjacob 		    ((rs1->snscb_ports[portidx].portid[2]));
   3378  1.111    mjacob 
   3379  1.111    mjacob 		for (npidx = portidx + 1; npidx < portlim; npidx++) {
   3380  1.111    mjacob 			uint32_t new_portid =
   3381  1.111    mjacob 			    ((rs1->snscb_ports[npidx].portid[0]) << 16) |
   3382  1.111    mjacob 			    ((rs1->snscb_ports[npidx].portid[1]) << 8) |
   3383  1.111    mjacob 			    ((rs1->snscb_ports[npidx].portid[2]));
   3384  1.111    mjacob 			if (new_portid == portid) {
   3385  1.111    mjacob 				break;
   3386  1.111    mjacob 			}
   3387  1.111    mjacob 		}
   3388   1.37    mjacob 
   3389  1.111    mjacob 		if (npidx < portlim) {
   3390  1.111    mjacob 			rs1->snscb_ports[npidx].portid[0] = 0;
   3391  1.111    mjacob 			rs1->snscb_ports[npidx].portid[1] = 0;
   3392  1.111    mjacob 			rs1->snscb_ports[npidx].portid[2] = 0;
   3393  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3394  1.111    mjacob 			    "removing duplicate PortID 0x%x entry from list",
   3395  1.111    mjacob 			    portid);
   3396  1.111    mjacob 		}
   3397   1.37    mjacob 	}
   3398   1.70    mjacob 
   3399   1.70    mjacob 	/*
   3400  1.111    mjacob 	 * Okay, we now have a list of Port IDs for all FC4 SCSI devices
   3401  1.111    mjacob 	 * that the Fabric Name server knows about.
   3402  1.111    mjacob 	 *
   3403  1.111    mjacob 	 * For each entry on this list go through our port database looking
   3404  1.111    mjacob 	 * for probational entries- if we find one, then an old entry is
   3405  1.111    mjacob 	 * is maybe still this one. We get some information to find out.
   3406   1.70    mjacob 	 *
   3407  1.111    mjacob 	 * Otherwise, it's a new fabric device, and we log into it
   3408  1.111    mjacob 	 * (unconditionally). After searching the entire database
   3409  1.111    mjacob 	 * again to make sure that we never ever ever ever have more
   3410  1.111    mjacob 	 * than one entry that has the same PortID or the same
   3411  1.111    mjacob 	 * WWNN/WWPN duple, we enter the device into our database.
   3412   1.37    mjacob 	 */
   3413   1.70    mjacob 
   3414  1.111    mjacob 	for (portidx = 0; portidx < portlim; portidx++) {
   3415  1.111    mjacob 		fcportdb_t *lp;
   3416  1.111    mjacob 		isp_pdb_t pdb;
   3417  1.111    mjacob 		uint64_t wwnn, wwpn;
   3418  1.111    mjacob 		int dbidx, nr;
   3419   1.37    mjacob 
   3420  1.111    mjacob 		portid =
   3421  1.111    mjacob 		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
   3422  1.111    mjacob 		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
   3423  1.111    mjacob 		    ((rs1->snscb_ports[portidx].portid[2]));
   3424  1.111    mjacob 
   3425  1.111    mjacob 		if (portid == 0) {
   3426  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG,
   3427  1.111    mjacob 			    "skipping null PortID at idx %d", portidx);
   3428   1.69    mjacob 			continue;
   3429   1.69    mjacob 		}
   3430   1.69    mjacob 
   3431   1.37    mjacob 		/*
   3432  1.111    mjacob 		 * Skip ourselves...
   3433   1.37    mjacob 		 */
   3434  1.111    mjacob 		if (portid == fcp->isp_portid) {
   3435  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG,
   3436  1.111    mjacob 			    "skip ourselves @ PortID 0x%06x", portid);
   3437   1.37    mjacob 			continue;
   3438   1.69    mjacob 		}
   3439  1.111    mjacob 		isp_prt(isp, ISP_LOGSANCFG,
   3440  1.111    mjacob 		    "Checking Fabric Port 0x%06x", portid);
   3441   1.50    mjacob 
   3442   1.37    mjacob 		/*
   3443  1.111    mjacob 		 * We now search our Port Database for any
   3444  1.111    mjacob 		 * probational entries with this PortID. We don't
   3445  1.111    mjacob 		 * look for zombies here- only probational
   3446  1.111    mjacob 		 * entries (we've already logged out of zombies).
   3447   1.70    mjacob 		 */
   3448  1.111    mjacob 		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
   3449  1.111    mjacob 			lp = &fcp->portdb[dbidx];
   3450  1.111    mjacob 
   3451  1.111    mjacob 			if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
   3452   1.70    mjacob 				continue;
   3453   1.70    mjacob 			}
   3454  1.111    mjacob 			if (lp->portid == portid) {
   3455  1.111    mjacob 				break;
   3456  1.111    mjacob 			}
   3457   1.70    mjacob 		}
   3458   1.70    mjacob 
   3459   1.70    mjacob 		/*
   3460  1.111    mjacob 		 * We found a probational entry with this Port ID.
   3461   1.37    mjacob 		 */
   3462  1.111    mjacob 		if (dbidx < MAX_FC_TARG) {
   3463  1.111    mjacob 			int handle_changed = 0;
   3464   1.70    mjacob 
   3465  1.111    mjacob 			lp = &fcp->portdb[dbidx];
   3466   1.37    mjacob 
   3467  1.111    mjacob 			/*
   3468  1.111    mjacob 			 * See if we're still logged into it.
   3469  1.111    mjacob 			 *
   3470  1.111    mjacob 			 * If we aren't, mark it as a dead device and
   3471  1.111    mjacob 			 * leave the new portid in the database entry
   3472  1.111    mjacob 			 * for somebody further along to decide what to
   3473  1.111    mjacob 			 * do (policy choice).
   3474  1.111    mjacob 			 *
   3475  1.111    mjacob 			 * If we are, check to see if it's the same
   3476  1.111    mjacob 			 * device still (it should be). If for some
   3477  1.111    mjacob 			 * reason it isn't, mark it as a changed device
   3478  1.111    mjacob 			 * and leave the new portid and role in the
   3479  1.111    mjacob 			 * database entry for somebody further along to
   3480  1.111    mjacob 			 * decide what to do (policy choice).
   3481  1.111    mjacob 			 *
   3482  1.111    mjacob 			 */
   3483   1.52        he 
   3484  1.111    mjacob 			r = isp_getpdb(isp, lp->handle, &pdb, 0);
   3485  1.111    mjacob 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3486  1.111    mjacob 				FC_SCRATCH_RELEASE(isp);
   3487  1.111    mjacob 				ISP_MARK_PORTDB(isp, 1);
   3488  1.111    mjacob 				return (-1);
   3489  1.111    mjacob 			}
   3490  1.111    mjacob 			if (r != 0) {
   3491  1.111    mjacob 				lp->new_portid = portid;
   3492  1.111    mjacob 				lp->state = FC_PORTDB_STATE_DEAD;
   3493  1.111    mjacob 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3494  1.111    mjacob 				    "Fabric Port 0x%06x considered dead",
   3495  1.111    mjacob 				    portid);
   3496  1.111    mjacob 				continue;
   3497  1.111    mjacob 			}
   3498   1.52        he 
   3499   1.37    mjacob 
   3500   1.70    mjacob 			/*
   3501  1.111    mjacob 			 * Check to make sure that handle, portid, WWPN and
   3502  1.111    mjacob 			 * WWNN agree. If they don't, then the association
   3503  1.111    mjacob 			 * between this PortID and the stated handle has been
   3504  1.111    mjacob 			 * broken by the firmware.
   3505   1.70    mjacob 			 */
   3506  1.111    mjacob 			MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
   3507  1.111    mjacob 			MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
   3508  1.111    mjacob 			if (pdb.handle != lp->handle ||
   3509  1.111    mjacob 			    pdb.portid != portid ||
   3510  1.111    mjacob 			    wwpn != lp->port_wwn ||
   3511  1.111    mjacob 			    wwnn != lp->node_wwn) {
   3512  1.111    mjacob 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3513  1.111    mjacob 				    fconf, dbidx, pdb.handle, pdb.portid,
   3514  1.111    mjacob 				    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
   3515  1.111    mjacob 				    (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
   3516  1.111    mjacob 				    lp->handle, portid,
   3517  1.111    mjacob 				    (uint32_t) (lp->node_wwn >> 32),
   3518  1.111    mjacob 				    (uint32_t) lp->node_wwn,
   3519  1.111    mjacob 				    (uint32_t) (lp->port_wwn >> 32),
   3520  1.111    mjacob 				    (uint32_t) lp->port_wwn);
   3521  1.111    mjacob 				/*
   3522  1.111    mjacob 				 * Try to re-login to this device using a
   3523  1.111    mjacob 				 * new handle. If that fails, mark it dead.
   3524  1.111    mjacob 				 *
   3525  1.111    mjacob 				 * isp_login_device will check for handle and
   3526  1.111    mjacob 				 * portid consistency after re-login.
   3527  1.111    mjacob 				 *
   3528  1.111    mjacob 				 */
   3529  1.111    mjacob 				if (isp_login_device(isp, portid, &pdb,
   3530  1.111    mjacob 				    &oldhandle)) {
   3531  1.111    mjacob 					lp->new_portid = portid;
   3532  1.111    mjacob 					lp->state = FC_PORTDB_STATE_DEAD;
   3533  1.111    mjacob 					if (fcp->isp_loopstate !=
   3534  1.111    mjacob 					    LOOP_SCANNING_FABRIC) {
   3535  1.111    mjacob 						FC_SCRATCH_RELEASE(isp);
   3536  1.111    mjacob 						ISP_MARK_PORTDB(isp, 1);
   3537  1.111    mjacob 						return (-1);
   3538  1.111    mjacob 					}
   3539  1.111    mjacob 					continue;
   3540  1.111    mjacob 				}
   3541  1.111    mjacob 				MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
   3542  1.111    mjacob 				MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
   3543  1.111    mjacob 				if (wwpn != lp->port_wwn ||
   3544  1.111    mjacob 				    wwnn != lp->node_wwn) {
   3545  1.111    mjacob 					isp_prt(isp, ISP_LOGWARN, "changed WWN"
   3546  1.111    mjacob 					    " after relogin");
   3547  1.111    mjacob 					lp->new_portid = portid;
   3548  1.111    mjacob 					lp->state = FC_PORTDB_STATE_DEAD;
   3549  1.111    mjacob 					continue;
   3550  1.111    mjacob 				}
   3551  1.111    mjacob 
   3552  1.111    mjacob 				lp->handle = pdb.handle;
   3553  1.111    mjacob 				handle_changed++;
   3554  1.111    mjacob 			}
   3555  1.111    mjacob 
   3556  1.111    mjacob 			nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
   3557   1.70    mjacob 
   3558   1.70    mjacob 			/*
   3559  1.111    mjacob 			 * Check to see whether the portid and roles have
   3560  1.111    mjacob 			 * stayed the same. If they have stayed the same,
   3561  1.111    mjacob 			 * we believe that this is the same device and it
   3562  1.111    mjacob 			 * hasn't become disconnected and reconnected, so
   3563  1.111    mjacob 			 * mark it as pending valid.
   3564  1.111    mjacob 			 *
   3565  1.111    mjacob 			 * If they aren't the same, mark the device as a
   3566  1.111    mjacob 			 * changed device and save the new port id and role
   3567  1.111    mjacob 			 * and let somebody else decide.
   3568   1.70    mjacob 			 */
   3569  1.111    mjacob 
   3570  1.111    mjacob 			lp->new_portid = portid;
   3571  1.111    mjacob 			lp->new_roles = nr;
   3572  1.111    mjacob 			if (pdb.portid != lp->portid || nr != lp->roles ||
   3573  1.111    mjacob 			    handle_changed) {
   3574  1.111    mjacob 				isp_prt(isp, ISP_LOGSANCFG,
   3575  1.111    mjacob 				    "Fabric Port 0x%06x changed", portid);
   3576  1.111    mjacob 				lp->state = FC_PORTDB_STATE_CHANGED;
   3577  1.111    mjacob 			} else {
   3578  1.111    mjacob 				isp_prt(isp, ISP_LOGSANCFG,
   3579  1.111    mjacob 				    "Fabric Port 0x%06x Now Pending Valid",
   3580  1.111    mjacob 				    portid);
   3581  1.111    mjacob 				lp->state = FC_PORTDB_STATE_PENDING_VALID;
   3582  1.111    mjacob 			}
   3583  1.111    mjacob 			continue;
   3584  1.111    mjacob 		}
   3585  1.111    mjacob 
   3586  1.111    mjacob 		/*
   3587  1.111    mjacob 		 * Ah- a new entry. Search the database again for all non-NIL
   3588  1.111    mjacob 		 * entries to make sure we never ever make a new database entry
   3589  1.111    mjacob 		 * with the same port id. While we're at it, mark where the
   3590  1.111    mjacob 		 * last free entry was.
   3591  1.111    mjacob 		 */
   3592  1.111    mjacob 
   3593  1.111    mjacob 		dbidx = MAX_FC_TARG;
   3594  1.111    mjacob 		for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
   3595  1.111    mjacob 			if (lp >= &fcp->portdb[FL_ID] &&
   3596  1.111    mjacob 			    lp <= &fcp->portdb[SNS_ID]) {
   3597  1.111    mjacob 				continue;
   3598  1.111    mjacob 			}
   3599  1.111    mjacob 			if (lp->state == FC_PORTDB_STATE_NIL) {
   3600  1.111    mjacob 				if (dbidx == MAX_FC_TARG) {
   3601  1.111    mjacob 					dbidx = lp - fcp->portdb;
   3602   1.70    mjacob 				}
   3603  1.111    mjacob 				continue;
   3604  1.111    mjacob 			}
   3605  1.111    mjacob 			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
   3606  1.111    mjacob 				continue;
   3607  1.111    mjacob 			}
   3608  1.111    mjacob 			if (lp->portid == portid) {
   3609  1.111    mjacob 				break;
   3610   1.38    mjacob 			}
   3611   1.70    mjacob 		}
   3612   1.52        he 
   3613  1.111    mjacob 		if (lp < &fcp->portdb[MAX_FC_TARG]) {
   3614  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN,
   3615  1.111    mjacob 			    "PortID 0x%06x already at %d handle %d state %d",
   3616  1.111    mjacob 			    portid, dbidx, lp->handle, lp->state);
   3617   1.43    mjacob 			continue;
   3618   1.52        he 		}
   3619   1.43    mjacob 
   3620   1.52        he 		/*
   3621  1.111    mjacob 		 * We should have the index of the first free entry seen.
   3622   1.52        he 		 */
   3623  1.111    mjacob 		if (dbidx == MAX_FC_TARG) {
   3624  1.111    mjacob 			isp_prt(isp, ISP_LOGERR,
   3625  1.111    mjacob 			    "port database too small to login PortID 0x%06x"
   3626  1.111    mjacob 			    "- increase MAX_FC_TARG", portid);
   3627  1.111    mjacob 			continue;
   3628   1.43    mjacob 		}
   3629   1.52        he 
   3630   1.70    mjacob 		/*
   3631  1.111    mjacob 		 * Otherwise, point to our new home.
   3632   1.70    mjacob 		 */
   3633  1.111    mjacob 		lp = &fcp->portdb[dbidx];
   3634   1.70    mjacob 
   3635   1.70    mjacob 		/*
   3636  1.111    mjacob 		 * Try to see if we are logged into this device,
   3637  1.111    mjacob 		 * and maybe log into it.
   3638  1.111    mjacob 		 *
   3639  1.111    mjacob 		 * isp_login_device will check for handle and
   3640  1.111    mjacob 		 * portid consistency after login.
   3641   1.70    mjacob 		 */
   3642  1.111    mjacob 		if (isp_login_device(isp, portid, &pdb, &oldhandle)) {
   3643  1.111    mjacob 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3644  1.111    mjacob 				FC_SCRATCH_RELEASE(isp);
   3645  1.111    mjacob 				ISP_MARK_PORTDB(isp, 1);
   3646  1.111    mjacob 				return (-1);
   3647  1.111    mjacob 			}
   3648   1.70    mjacob 			continue;
   3649   1.43    mjacob 		}
   3650   1.52        he 
   3651  1.111    mjacob 		handle = pdb.handle;
   3652  1.111    mjacob 		MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
   3653  1.111    mjacob 		MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
   3654  1.111    mjacob 		nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
   3655  1.111    mjacob 
   3656   1.43    mjacob 		/*
   3657  1.111    mjacob 		 * And go through the database *one* more time to make sure
   3658  1.111    mjacob 		 * that we do not make more than one entry that has the same
   3659  1.111    mjacob 		 * WWNN/WWPN duple
   3660   1.43    mjacob 		 */
   3661  1.111    mjacob 		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
   3662  1.111    mjacob 			if (dbidx >= FL_ID && dbidx <= SNS_ID) {
   3663  1.111    mjacob 				continue;
   3664  1.111    mjacob 			}
   3665  1.111    mjacob 			if (fcp->portdb[dbidx].state == FC_PORTDB_STATE_NIL) {
   3666  1.111    mjacob 				continue;
   3667  1.111    mjacob 			}
   3668  1.111    mjacob 			if (fcp->portdb[dbidx].node_wwn == wwnn &&
   3669  1.111    mjacob 			    fcp->portdb[dbidx].port_wwn == wwpn) {
   3670   1.91    mjacob 				break;
   3671   1.91    mjacob 			}
   3672   1.91    mjacob 		}
   3673   1.91    mjacob 
   3674  1.111    mjacob 		if (dbidx == MAX_FC_TARG) {
   3675  1.111    mjacob 			MEMZERO(lp, sizeof (fcportdb_t));
   3676  1.111    mjacob 			lp->handle = handle;
   3677  1.111    mjacob 			lp->node_wwn = wwnn;
   3678  1.111    mjacob 			lp->port_wwn = wwpn;
   3679  1.111    mjacob 			lp->new_portid = portid;
   3680  1.111    mjacob 			lp->new_roles = nr;
   3681  1.111    mjacob 			lp->state = FC_PORTDB_STATE_NEW;
   3682  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG,
   3683  1.111    mjacob 			    "Fabric Port 0x%06x is New Entry", portid);
   3684  1.111    mjacob 			continue;
   3685  1.111    mjacob 		}
   3686   1.91    mjacob 
   3687  1.111    mjacob     		if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
   3688  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN,
   3689  1.111    mjacob 			    "PortID 0x%x 0x%08x%08x/0x%08x%08x %ld already at "
   3690  1.111    mjacob 			    "idx %d, state 0x%x", portid,
   3691  1.111    mjacob 			    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
   3692  1.111    mjacob 			    (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
   3693  1.111    mjacob 			    (long) (lp - fcp->portdb), dbidx,
   3694  1.111    mjacob 			    fcp->portdb[dbidx].state);
   3695  1.111    mjacob 			continue;
   3696   1.37    mjacob 		}
   3697   1.91    mjacob 
   3698   1.91    mjacob 		/*
   3699  1.111    mjacob 		 * We found a zombie entry that matches us.
   3700  1.111    mjacob 		 * Revive it. We know that WWN and WWPN
   3701  1.111    mjacob 		 * are the same. For fabric devices, we
   3702  1.111    mjacob 		 * don't care that handle is different
   3703  1.111    mjacob 		 * as we assign that. If role or portid
   3704  1.111    mjacob 		 * are different, it maybe a changed device.
   3705  1.111    mjacob 		 */
   3706  1.111    mjacob 		lp = &fcp->portdb[dbidx];
   3707  1.111    mjacob 		lp->handle = handle;
   3708  1.111    mjacob 		lp->new_portid = portid;
   3709  1.111    mjacob 		lp->new_roles = nr;
   3710  1.111    mjacob 		if (lp->portid != portid || lp->roles != nr) {
   3711  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3712  1.111    mjacob 			    "Zombie Fabric Port 0x%06x Now Changed", portid);
   3713  1.111    mjacob 			lp->state = FC_PORTDB_STATE_CHANGED;
   3714   1.82    mjacob 		} else {
   3715  1.111    mjacob 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3716  1.111    mjacob 			    "Zombie Fabric Port 0x%06x Now Pending Valid",
   3717  1.111    mjacob 			    portid);
   3718  1.111    mjacob 			lp->state = FC_PORTDB_STATE_PENDING_VALID;
   3719   1.82    mjacob 		}
   3720   1.37    mjacob 	}
   3721  1.111    mjacob 
   3722   1.91    mjacob 	FC_SCRATCH_RELEASE(isp);
   3723  1.111    mjacob 	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3724  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   3725  1.111    mjacob 		return (-1);
   3726   1.91    mjacob 	}
   3727   1.91    mjacob 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
   3728  1.111    mjacob 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "FC Scan Fabric Done");
   3729   1.91    mjacob 	return (0);
   3730   1.91    mjacob }
   3731   1.70    mjacob 
   3732  1.111    mjacob /*
   3733  1.111    mjacob  * Find an unused handle and try and use to login to a port.
   3734  1.111    mjacob  */
   3735   1.91    mjacob static int
   3736  1.111    mjacob isp_login_device(ispsoftc_t *isp, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
   3737   1.91    mjacob {
   3738  1.111    mjacob 	int lim, i, r;
   3739  1.111    mjacob 	uint16_t handle;
   3740   1.91    mjacob 
   3741  1.111    mjacob 	if (FCPARAM(isp)->isp_2klogin) {
   3742  1.111    mjacob 		lim = NPH_MAX_2K;
   3743  1.111    mjacob 	} else {
   3744  1.111    mjacob 		lim = NPH_MAX;
   3745   1.82    mjacob 	}
   3746   1.70    mjacob 
   3747  1.111    mjacob 	handle = isp_nxt_handle(isp, *ohp);
   3748  1.111    mjacob 	for (i = 0; i < lim; i++) {
   3749  1.111    mjacob 		/*
   3750  1.111    mjacob 		 * See if we're still logged into something with
   3751  1.111    mjacob 		 * this handle and that something agrees with this
   3752  1.111    mjacob 		 * port id.
   3753  1.111    mjacob 		 */
   3754  1.111    mjacob 		r = isp_getpdb(isp, handle, p, 0);
   3755  1.111    mjacob 		if (r == 0 && p->portid != portid) {
   3756  1.111    mjacob 			(void) isp_plogx(isp, handle, portid,
   3757  1.111    mjacob 			    PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1);
   3758  1.111    mjacob 		} else if (r == 0) {
   3759  1.111    mjacob 			break;
   3760   1.91    mjacob 		}
   3761  1.111    mjacob 		if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3762   1.92    mjacob 			return (-1);
   3763   1.92    mjacob 		}
   3764  1.111    mjacob 		/*
   3765  1.111    mjacob 		 * Now try and log into the device
   3766  1.111    mjacob 		 */
   3767  1.111    mjacob 		r = isp_plogx(isp, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
   3768  1.111    mjacob 		if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3769   1.92    mjacob 			return (-1);
   3770   1.92    mjacob 		}
   3771  1.111    mjacob 		if (r == 0) {
   3772  1.111    mjacob 			*ohp = handle;
   3773  1.111    mjacob 			break;
   3774  1.111    mjacob 		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
   3775  1.111    mjacob 			handle = r >> 16;
   3776  1.111    mjacob 			break;
   3777  1.111    mjacob 		} else if (r != MBOX_LOOP_ID_USED) {
   3778  1.111    mjacob 			i = lim;
   3779  1.111    mjacob 			break;
   3780   1.92    mjacob 		} else {
   3781  1.111    mjacob 			*ohp = handle;
   3782  1.111    mjacob 			handle = isp_nxt_handle(isp, *ohp);
   3783   1.92    mjacob 		}
   3784  1.111    mjacob 	}
   3785   1.91    mjacob 
   3786  1.111    mjacob 	if (i == lim) {
   3787  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "PLOGI 0x%06x failed", portid);
   3788  1.111    mjacob 		return (-1);
   3789  1.111    mjacob 	}
   3790   1.91    mjacob 
   3791   1.91    mjacob 	/*
   3792  1.111    mjacob 	 * If we successfully logged into it, get the PDB for it
   3793  1.111    mjacob 	 * so we can crosscheck that it is still what we think it
   3794  1.111    mjacob 	 * is and that we also have the role it plays
   3795   1.91    mjacob 	 */
   3796  1.111    mjacob 	r = isp_getpdb(isp, handle, p, 0);
   3797  1.111    mjacob 	if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) {
   3798  1.111    mjacob 		return (-1);
   3799  1.111    mjacob 	}
   3800  1.111    mjacob 	if (r != 0) {
   3801  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "new device 0x%06x@0x%x disappeared",
   3802  1.111    mjacob 		    portid, handle);
   3803  1.111    mjacob 		return (-1);
   3804   1.91    mjacob 	}
   3805   1.91    mjacob 
   3806  1.111    mjacob 	if (p->handle != handle || p->portid != portid) {
   3807  1.111    mjacob 		isp_prt(isp, ISP_LOGERR,
   3808  1.111    mjacob 		    "new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
   3809  1.111    mjacob 		    portid, handle, p->portid, p->handle);
   3810  1.111    mjacob 		return (-1);
   3811  1.111    mjacob 	}
   3812   1.37    mjacob 	return (0);
   3813   1.37    mjacob }
   3814   1.69    mjacob 
   3815  1.111    mjacob static int
   3816  1.111    mjacob isp_register_fc4_type(ispsoftc_t *isp)
   3817   1.69    mjacob {
   3818   1.69    mjacob 	fcparam *fcp = isp->isp_param;
   3819  1.111    mjacob 	uint8_t local[SNS_RFT_ID_REQ_SIZE];
   3820   1.86    mjacob 	sns_screq_t *reqp = (sns_screq_t *) local;
   3821   1.69    mjacob 	mbreg_t mbs;
   3822   1.69    mjacob 
   3823   1.91    mjacob 	MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
   3824   1.91    mjacob 	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
   3825   1.79    mjacob 	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
   3826   1.79    mjacob 	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
   3827   1.79    mjacob 	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
   3828   1.79    mjacob 	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
   3829   1.69    mjacob 	reqp->snscb_sblen = 22;
   3830   1.91    mjacob 	reqp->snscb_data[0] = SNS_RFT_ID;
   3831   1.69    mjacob 	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
   3832   1.69    mjacob 	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
   3833   1.91    mjacob 	reqp->snscb_data[6] = (1 << FC4_SCSI);
   3834   1.88    mjacob 	FC_SCRATCH_ACQUIRE(isp);
   3835   1.86    mjacob 	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
   3836  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   3837   1.69    mjacob 	mbs.param[0] = MBOX_SEND_SNS;
   3838   1.91    mjacob 	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
   3839   1.79    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
   3840   1.79    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
   3841   1.79    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
   3842   1.79    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
   3843  1.111    mjacob 	mbs.logval = MBLOGALL;
   3844  1.111    mjacob 	mbs.timeout = 10000000;
   3845  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE);
   3846  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   3847   1.88    mjacob 	FC_SCRATCH_RELEASE(isp);
   3848   1.69    mjacob 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
   3849  1.111    mjacob 		return (0);
   3850  1.111    mjacob 	} else {
   3851  1.111    mjacob 		return (-1);
   3852  1.111    mjacob 	}
   3853  1.111    mjacob }
   3854  1.111    mjacob 
   3855  1.111    mjacob static int
   3856  1.111    mjacob isp_register_fc4_type_24xx(ispsoftc_t *isp)
   3857  1.111    mjacob {
   3858  1.111    mjacob 	mbreg_t mbs;
   3859  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   3860  1.111    mjacob 	union {
   3861  1.111    mjacob 		isp_ct_pt_t plocal;
   3862  1.111    mjacob 		rft_id_t clocal;
   3863  1.111    mjacob 		uint8_t q[QENTRY_LEN];
   3864  1.111    mjacob 	} un;
   3865  1.111    mjacob 	isp_ct_pt_t *pt;
   3866  1.111    mjacob 	ct_hdr_t *ct;
   3867  1.111    mjacob 	rft_id_t *rp;
   3868  1.111    mjacob 	uint8_t *scp = fcp->isp_scratch;
   3869  1.111    mjacob 
   3870  1.111    mjacob 	FC_SCRATCH_ACQUIRE(isp);
   3871  1.111    mjacob 	/*
   3872  1.111    mjacob 	 * Build a Passthrough IOCB in memory.
   3873  1.111    mjacob 	 */
   3874  1.111    mjacob 	MEMZERO(un.q, QENTRY_LEN);
   3875  1.111    mjacob 	pt = &un.plocal;
   3876  1.111    mjacob 	pt->ctp_header.rqs_entry_count = 1;
   3877  1.111    mjacob 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
   3878  1.111    mjacob 	pt->ctp_handle = 0xffffffff;
   3879  1.111    mjacob 	pt->ctp_nphdl = NPH_SNS_ID;
   3880  1.111    mjacob 	pt->ctp_cmd_cnt = 1;
   3881  1.111    mjacob 	pt->ctp_time = 1;
   3882  1.111    mjacob 	pt->ctp_rsp_cnt = 1;
   3883  1.111    mjacob 	pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
   3884  1.111    mjacob 	pt->ctp_cmd_bcnt = sizeof (rft_id_t);
   3885  1.111    mjacob 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
   3886  1.111    mjacob 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
   3887  1.111    mjacob 	pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
   3888  1.111    mjacob 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
   3889  1.111    mjacob 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
   3890  1.111    mjacob 	pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
   3891  1.111    mjacob 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
   3892  1.111    mjacob 
   3893  1.111    mjacob 	/*
   3894  1.111    mjacob 	 * Build the CT header and command in memory.
   3895  1.111    mjacob 	 *
   3896  1.111    mjacob 	 * Note that the CT header has to end up as Big Endian format in memory.
   3897  1.111    mjacob 	 */
   3898  1.111    mjacob 	MEMZERO(&un.clocal, sizeof (un.clocal));
   3899  1.111    mjacob 	ct = &un.clocal.rftid_hdr;
   3900  1.111    mjacob 	ct->ct_revision = CT_REVISION;
   3901  1.111    mjacob 	ct->ct_fcs_type = CT_FC_TYPE_FC;
   3902  1.111    mjacob 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
   3903  1.111    mjacob 	ct->ct_cmd_resp = SNS_RFT_ID;
   3904  1.111    mjacob 	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
   3905  1.111    mjacob 	rp = &un.clocal;
   3906  1.111    mjacob 	rp->rftid_portid[0] = fcp->isp_portid >> 16;
   3907  1.111    mjacob 	rp->rftid_portid[1] = fcp->isp_portid >> 8;
   3908  1.111    mjacob 	rp->rftid_portid[2] = fcp->isp_portid;
   3909  1.111    mjacob 	rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
   3910  1.111    mjacob 	isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
   3911  1.111    mjacob 
   3912  1.111    mjacob 	MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
   3913  1.111    mjacob 
   3914  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   3915  1.111    mjacob 	mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64;
   3916  1.111    mjacob 	mbs.param[1] = QENTRY_LEN;
   3917  1.111    mjacob 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
   3918  1.111    mjacob 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
   3919  1.111    mjacob 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
   3920  1.111    mjacob 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
   3921  1.111    mjacob 	mbs.timeout = 500000;
   3922  1.111    mjacob 	mbs.logval = MBLOGALL;
   3923  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN);
   3924  1.111    mjacob 	isp_mboxcmd(isp, &mbs);
   3925  1.111    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   3926  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   3927  1.111    mjacob 		return (-1);
   3928  1.111    mjacob 	}
   3929  1.111    mjacob 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN);
   3930  1.111    mjacob 	pt = &un.plocal;
   3931  1.111    mjacob 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
   3932  1.111    mjacob 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
   3933  1.111    mjacob 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
   3934  1.111    mjacob 	}
   3935  1.111    mjacob 	if (pt->ctp_status) {
   3936  1.111    mjacob 		FC_SCRATCH_RELEASE(isp);
   3937  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "CT Passthrough returned 0x%x",
   3938  1.111    mjacob 		    pt->ctp_status);
   3939  1.111    mjacob 		return (-1);
   3940  1.111    mjacob 	}
   3941  1.111    mjacob 
   3942  1.111    mjacob 	isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
   3943  1.111    mjacob 	FC_SCRATCH_RELEASE(isp);
   3944  1.111    mjacob 
   3945  1.111    mjacob 	if (ct->ct_cmd_resp == LS_RJT) {
   3946  1.111    mjacob 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3947  1.111    mjacob 		    "Register FC4 Type rejected");
   3948  1.111    mjacob 		return (-1);
   3949  1.111    mjacob 	} else if (ct->ct_cmd_resp == LS_ACC) {
   3950  1.111    mjacob 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
   3951  1.111    mjacob 		    "Register FC4 Type accepted");
   3952  1.111    mjacob 		return(0);
   3953  1.111    mjacob 	} else {
   3954  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN,
   3955  1.111    mjacob 		    "Register FC4 Type: 0x%x", ct->ct_cmd_resp);
   3956  1.111    mjacob 		return (-1);
   3957  1.111    mjacob 	}
   3958  1.111    mjacob }
   3959  1.111    mjacob 
   3960  1.111    mjacob static uint16_t
   3961  1.111    mjacob isp_nxt_handle(ispsoftc_t *isp, uint16_t handle)
   3962  1.111    mjacob {
   3963  1.111    mjacob 	int i;
   3964  1.111    mjacob 	if (handle == NIL_HANDLE) {
   3965  1.111    mjacob 		if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
   3966  1.111    mjacob 			handle = 0;
   3967  1.111    mjacob 		} else {
   3968  1.111    mjacob 			handle = SNS_ID+1;
   3969  1.111    mjacob 		}
   3970  1.111    mjacob 	} else {
   3971  1.111    mjacob 		handle += 1;
   3972  1.111    mjacob 		if (handle >= FL_ID && handle <= SNS_ID) {
   3973  1.111    mjacob 			handle = SNS_ID+1;
   3974  1.111    mjacob 		}
   3975  1.111    mjacob 		if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
   3976  1.111    mjacob 			handle = NPH_FL_ID+1;
   3977  1.111    mjacob 		}
   3978  1.111    mjacob 		if (FCPARAM(isp)->isp_2klogin) {
   3979  1.111    mjacob 			if (handle == NPH_MAX_2K) {
   3980  1.111    mjacob 				handle = 0;
   3981  1.111    mjacob 			}
   3982  1.111    mjacob 		} else {
   3983  1.111    mjacob 			if (handle == NPH_MAX) {
   3984  1.111    mjacob 				handle = 0;
   3985  1.111    mjacob 			}
   3986  1.111    mjacob 		}
   3987  1.111    mjacob 	}
   3988  1.111    mjacob 	if (handle == FCPARAM(isp)->isp_loopid) {
   3989  1.111    mjacob 		return (isp_nxt_handle(isp, handle));
   3990  1.111    mjacob 	}
   3991  1.111    mjacob 	for (i = 0; i < MAX_FC_TARG; i++) {
   3992  1.111    mjacob 		if (FCPARAM(isp)->portdb[i].state == FC_PORTDB_STATE_NIL) {
   3993  1.111    mjacob 			continue;
   3994  1.111    mjacob 		}
   3995  1.111    mjacob 		if (FCPARAM(isp)->portdb[i].handle == handle) {
   3996  1.111    mjacob 			return (isp_nxt_handle(isp, handle));
   3997  1.111    mjacob 		}
   3998   1.69    mjacob 	}
   3999  1.111    mjacob 	return (handle);
   4000   1.69    mjacob }
   4001   1.70    mjacob 
   4002   1.37    mjacob /*
   4003   1.23    mjacob  * Start a command. Locking is assumed done in the caller.
   4004    1.1       cgd  */
   4005   1.23    mjacob 
   4006   1.57    mjacob int
   4007   1.73    mjacob isp_start(XS_T *xs)
   4008    1.1       cgd {
   4009  1.111    mjacob 	ispsoftc_t *isp;
   4010  1.111    mjacob 	uint32_t nxti, optr, handle;
   4011  1.111    mjacob 	uint8_t local[QENTRY_LEN];
   4012   1.86    mjacob 	ispreq_t *reqp, *qep;
   4013  1.111    mjacob 	void *cdbp;
   4014  1.111    mjacob 	uint16_t *tptr;
   4015  1.111    mjacob 	int target, i, hdlidx = 0;
   4016    1.1       cgd 
   4017   1.23    mjacob 	XS_INITERR(xs);
   4018   1.23    mjacob 	isp = XS_ISP(xs);
   4019   1.70    mjacob 
   4020   1.70    mjacob 	/*
   4021   1.70    mjacob 	 * Check to make sure we're supporting initiator role.
   4022   1.70    mjacob 	 */
   4023   1.70    mjacob 	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
   4024   1.70    mjacob 		XS_SETERR(xs, HBA_SELTIMEOUT);
   4025   1.70    mjacob 		return (CMD_COMPLETE);
   4026   1.70    mjacob 	}
   4027   1.70    mjacob 
   4028   1.70    mjacob 	/*
   4029   1.70    mjacob 	 * Now make sure we're running.
   4030   1.70    mjacob 	 */
   4031   1.70    mjacob 
   4032   1.24    mjacob 	if (isp->isp_state != ISP_RUNSTATE) {
   4033   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
   4034   1.24    mjacob 		XS_SETERR(xs, HBA_BOTCH);
   4035   1.24    mjacob 		return (CMD_COMPLETE);
   4036   1.24    mjacob 	}
   4037   1.24    mjacob 
   4038   1.25    mjacob 	/*
   4039   1.50    mjacob 	 * Check command CDB length, etc.. We really are limited to 16 bytes
   4040   1.50    mjacob 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
   4041   1.50    mjacob 	 * but probably only if we're running fairly new firmware (we'll
   4042   1.50    mjacob 	 * let the old f/w choke on an extended command queue entry).
   4043   1.25    mjacob 	 */
   4044   1.33    mjacob 
   4045   1.50    mjacob 	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
   4046   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   4047   1.57    mjacob 		    "unsupported cdb length (%d, CDB[0]=0x%x)",
   4048   1.57    mjacob 		    XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
   4049   1.25    mjacob 		XS_SETERR(xs, HBA_BOTCH);
   4050   1.25    mjacob 		return (CMD_COMPLETE);
   4051   1.25    mjacob 	}
   4052   1.25    mjacob 
   4053   1.25    mjacob 	/*
   4054  1.111    mjacob 	 * Translate the target to device handle as appropriate, checking
   4055  1.111    mjacob 	 * for correct device state as well.
   4056   1.33    mjacob 	 */
   4057   1.37    mjacob 	target = XS_TGT(xs);
   4058   1.33    mjacob 	if (IS_FC(isp)) {
   4059   1.33    mjacob 		fcparam *fcp = isp->isp_param;
   4060  1.111    mjacob 
   4061  1.111    mjacob 		/*
   4062  1.111    mjacob 		 * Try again later.
   4063  1.111    mjacob 		 */
   4064   1.73    mjacob 		if (fcp->isp_fwstate != FW_READY ||
   4065   1.73    mjacob 		    fcp->isp_loopstate != LOOP_READY) {
   4066   1.73    mjacob 			return (CMD_RQLATER);
   4067   1.73    mjacob 		}
   4068   1.73    mjacob 
   4069  1.111    mjacob 		if (XS_TGT(xs) >= MAX_FC_TARG) {
   4070  1.111    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   4071  1.111    mjacob 			return (CMD_COMPLETE);
   4072   1.37    mjacob 		}
   4073   1.37    mjacob 
   4074  1.111    mjacob 		hdlidx = fcp->isp_ini_map[XS_TGT(xs)] - 1;
   4075  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- hdlidx value %d",
   4076  1.111    mjacob 		    XS_TGT(xs), hdlidx);
   4077  1.111    mjacob 		if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
   4078   1.37    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   4079  1.111    mjacob 			return (CMD_COMPLETE);
   4080   1.37    mjacob 		}
   4081  1.111    mjacob 		if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
   4082   1.70    mjacob 			return (CMD_RQLATER);
   4083   1.70    mjacob 		}
   4084  1.111    mjacob 		if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
   4085   1.37    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   4086   1.37    mjacob 			return (CMD_COMPLETE);
   4087   1.33    mjacob 		}
   4088  1.111    mjacob 		target = fcp->portdb[hdlidx].handle;
   4089   1.33    mjacob 	}
   4090   1.33    mjacob 
   4091   1.33    mjacob 	/*
   4092  1.111    mjacob 	 * Next check to see if any HBA or Device parameters need to be updated.
   4093   1.25    mjacob 	 */
   4094   1.36    mjacob 	if (isp->isp_update != 0) {
   4095   1.25    mjacob 		isp_update(isp);
   4096   1.10    mjacob 	}
   4097   1.25    mjacob 
   4098  1.111    mjacob  start_again:
   4099  1.111    mjacob 
   4100  1.100   thorpej 	if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
   4101   1.57    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
   4102   1.23    mjacob 		XS_SETERR(xs, HBA_BOTCH);
   4103   1.23    mjacob 		return (CMD_EAGAIN);
   4104    1.1       cgd 	}
   4105   1.13    mjacob 
   4106   1.36    mjacob 	/*
   4107   1.36    mjacob 	 * Now see if we need to synchronize the ISP with respect to anything.
   4108   1.36    mjacob 	 * We do dual duty here (cough) for synchronizing for busses other
   4109   1.36    mjacob 	 * than which we got here to send a command to.
   4110   1.36    mjacob 	 */
   4111   1.86    mjacob 	reqp = (ispreq_t *) local;
   4112    1.1       cgd 	if (isp->isp_sendmarker) {
   4113  1.111    mjacob 		if (IS_24XX(isp)) {
   4114  1.111    mjacob 			isp_marker_24xx_t *m = (isp_marker_24xx_t *) qep;
   4115  1.111    mjacob 			MEMZERO(m, QENTRY_LEN);
   4116  1.111    mjacob 			m->mrk_header.rqs_entry_count = 1;
   4117  1.111    mjacob 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
   4118  1.111    mjacob 			m->mrk_modifier = SYNC_ALL;
   4119  1.111    mjacob 			isp_put_marker_24xx(isp, m, (isp_marker_24xx_t *)qep);
   4120   1.86    mjacob 			ISP_ADD_REQUEST(isp, nxti);
   4121  1.111    mjacob 			isp->isp_sendmarker = 0;
   4122  1.111    mjacob 			goto start_again;
   4123  1.111    mjacob 		} else {
   4124  1.111    mjacob 			for (i = 0; i < (IS_DUALBUS(isp)? 2: 1); i++) {
   4125  1.111    mjacob 				isp_marker_t *m = (isp_marker_t *) qep;
   4126  1.111    mjacob 				if ((isp->isp_sendmarker & (1 << i)) == 0) {
   4127  1.111    mjacob 					continue;
   4128  1.111    mjacob 				}
   4129  1.111    mjacob 				MEMZERO(m, QENTRY_LEN);
   4130  1.111    mjacob 				m->mrk_header.rqs_entry_count = 1;
   4131  1.111    mjacob 				m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
   4132  1.111    mjacob 				m->mrk_target = (i << 7);	/* bus # */
   4133  1.111    mjacob 				m->mrk_modifier = SYNC_ALL;
   4134  1.111    mjacob 				isp_put_marker(isp, m, (isp_marker_t *) qep);
   4135  1.111    mjacob 				ISP_ADD_REQUEST(isp, nxti);
   4136  1.111    mjacob 				isp->isp_sendmarker &= ~(1 << i);
   4137  1.111    mjacob 				goto start_again;
   4138   1.36    mjacob 			}
   4139    1.1       cgd 		}
   4140    1.1       cgd 	}
   4141    1.1       cgd 
   4142   1.86    mjacob 	MEMZERO((void *)reqp, QENTRY_LEN);
   4143   1.10    mjacob 	reqp->req_header.rqs_entry_count = 1;
   4144  1.111    mjacob 	if (IS_24XX(isp)) {
   4145  1.111    mjacob 		reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
   4146  1.111    mjacob 	} else if (IS_FC(isp)) {
   4147   1.10    mjacob 		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
   4148   1.10    mjacob 	} else {
   4149   1.50    mjacob 		if (XS_CDBLEN(xs) > 12)
   4150   1.50    mjacob 			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
   4151   1.50    mjacob 		else
   4152   1.50    mjacob 			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
   4153   1.10    mjacob 	}
   4154   1.83    mjacob 	/* reqp->req_header.rqs_flags = 0; */
   4155   1.83    mjacob 	/* reqp->req_header.rqs_seqno = 0; */
   4156  1.111    mjacob 	if (IS_24XX(isp)) {
   4157  1.111    mjacob 		int ttype;
   4158  1.111    mjacob 		if (XS_TAG_P(xs)) {
   4159  1.111    mjacob 			ttype = XS_TAG_TYPE(xs);
   4160  1.111    mjacob 		} else {
   4161  1.111    mjacob 			if (XS_CDBP(xs)[0] == 0x3) {
   4162  1.111    mjacob 				ttype = REQFLAG_HTAG;
   4163  1.111    mjacob 			} else {
   4164  1.111    mjacob 				ttype = REQFLAG_STAG;
   4165  1.111    mjacob 			}
   4166  1.111    mjacob 		}
   4167  1.111    mjacob 		if (ttype == REQFLAG_OTAG) {
   4168  1.111    mjacob 			ttype = FCP_CMND_TASK_ATTR_ORDERED;
   4169  1.111    mjacob 		} else if (ttype == REQFLAG_HTAG) {
   4170  1.111    mjacob 			ttype = FCP_CMND_TASK_ATTR_HEAD;
   4171  1.111    mjacob 		} else {
   4172  1.111    mjacob 			ttype = FCP_CMND_TASK_ATTR_SIMPLE;
   4173  1.111    mjacob 		}
   4174  1.111    mjacob 		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
   4175  1.111    mjacob 	} else if (IS_FC(isp)) {
   4176   1.10    mjacob 		/*
   4177   1.10    mjacob 		 * See comment in isp_intr
   4178   1.10    mjacob 		 */
   4179   1.83    mjacob 		/* XS_RESID(xs) = 0; */
   4180   1.34    mjacob 
   4181   1.10    mjacob 		/*
   4182   1.42    mjacob 		 * Fibre Channel always requires some kind of tag.
   4183   1.42    mjacob 		 * The Qlogic drivers seem be happy not to use a tag,
   4184   1.42    mjacob 		 * but this breaks for some devices (IBM drives).
   4185   1.10    mjacob 		 */
   4186   1.57    mjacob 		if (XS_TAG_P(xs)) {
   4187   1.86    mjacob 			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
   4188   1.42    mjacob 		} else {
   4189   1.60    mjacob 			/*
   4190   1.60    mjacob 			 * If we don't know what tag to use, use HEAD OF QUEUE
   4191   1.79    mjacob 			 * for Request Sense or Simple.
   4192   1.60    mjacob 			 */
   4193   1.42    mjacob 			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
   4194   1.86    mjacob 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
   4195   1.42    mjacob 			else
   4196   1.86    mjacob 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
   4197   1.10    mjacob 		}
   4198   1.10    mjacob 	} else {
   4199   1.23    mjacob 		sdparam *sdp = (sdparam *)isp->isp_param;
   4200   1.78    mjacob 		sdp += XS_CHANNEL(xs);
   4201   1.79    mjacob 		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) &&
   4202   1.57    mjacob 		    XS_TAG_P(xs)) {
   4203   1.57    mjacob 			reqp->req_flags = XS_TAG_TYPE(xs);
   4204   1.10    mjacob 		}
   4205   1.10    mjacob 	}
   4206  1.111    mjacob 	cdbp = reqp->req_cdb;
   4207  1.111    mjacob 	tptr = &reqp->req_time;
   4208  1.111    mjacob 
   4209   1.38    mjacob 	if (IS_SCSI(isp)) {
   4210  1.111    mjacob 		reqp->req_target = target | (XS_CHANNEL(xs) << 7);
   4211   1.28    mjacob 		reqp->req_lun_trn = XS_LUN(xs);
   4212   1.23    mjacob 		reqp->req_cdblen = XS_CDBLEN(xs);
   4213  1.111    mjacob 	} else if (IS_24XX(isp)) {
   4214  1.111    mjacob 		fcportdb_t *lp;
   4215  1.111    mjacob 
   4216  1.111    mjacob 		lp = &FCPARAM(isp)->portdb[hdlidx];
   4217  1.111    mjacob 		((ispreqt7_t *)reqp)->req_nphdl = target;
   4218  1.111    mjacob 		((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
   4219  1.111    mjacob 		((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;
   4220  1.111    mjacob 		if (XS_LUN(xs) > 256) {
   4221  1.111    mjacob 			((ispreqt7_t *)reqp)->req_lun[0] = XS_LUN(xs) >> 8;
   4222  1.111    mjacob 			((ispreqt7_t *)reqp)->req_lun[0] |= 0x40;
   4223  1.111    mjacob 		}
   4224  1.111    mjacob 		((ispreqt7_t *)reqp)->req_lun[1] = XS_LUN(xs);
   4225  1.111    mjacob 		cdbp = ((ispreqt7_t *)reqp)->req_cdb;
   4226  1.111    mjacob 		tptr = &((ispreqt7_t *)reqp)->req_time;
   4227  1.111    mjacob 	} else if (FCPARAM(isp)->isp_2klogin) {
   4228  1.111    mjacob 		((ispreqt2e_t *)reqp)->req_target = target;
   4229  1.111    mjacob 		((ispreqt2e_t *)reqp)->req_scclun = XS_LUN(xs);
   4230  1.111    mjacob 	} else if (FCPARAM(isp)->isp_sccfw) {
   4231  1.111    mjacob 		((ispreqt2_t *)reqp)->req_target = target;
   4232  1.111    mjacob 		((ispreqt2_t *)reqp)->req_scclun = XS_LUN(xs);
   4233   1.28    mjacob 	} else {
   4234  1.111    mjacob 		((ispreqt2_t *)reqp)->req_target = target;
   4235  1.111    mjacob 		((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs);
   4236   1.10    mjacob 	}
   4237  1.111    mjacob 	MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs));
   4238    1.1       cgd 
   4239  1.111    mjacob 	*tptr = XS_TIME(xs) / 1000;
   4240  1.111    mjacob 	if (*tptr == 0 && XS_TIME(xs)) {
   4241  1.111    mjacob 		*tptr = 1;
   4242  1.111    mjacob 	}
   4243  1.111    mjacob 	if (IS_24XX(isp) && *tptr > 0x1999) {
   4244  1.111    mjacob 		*tptr = 0x1999;
   4245   1.86    mjacob 	}
   4246   1.33    mjacob 
   4247   1.73    mjacob 	if (isp_save_xs(isp, xs, &handle)) {
   4248   1.84    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
   4249   1.38    mjacob 		XS_SETERR(xs, HBA_BOTCH);
   4250   1.38    mjacob 		return (CMD_EAGAIN);
   4251   1.38    mjacob 	}
   4252  1.111    mjacob 	/* Whew. Thankfully the same for type 7 requests */
   4253   1.73    mjacob 	reqp->req_handle = handle;
   4254   1.86    mjacob 
   4255   1.38    mjacob 	/*
   4256   1.38    mjacob 	 * Set up DMA and/or do any bus swizzling of the request entry
   4257   1.38    mjacob 	 * so that the Qlogic F/W understands what is being asked of it.
   4258   1.86    mjacob 	 */
   4259   1.86    mjacob 	i = ISP_DMASETUP(isp, xs, reqp, &nxti, optr);
   4260   1.27    mjacob 	if (i != CMD_QUEUED) {
   4261   1.73    mjacob 		isp_destroy_handle(isp, handle);
   4262   1.27    mjacob 		/*
   4263   1.27    mjacob 		 * dmasetup sets actual error in packet, and
   4264   1.27    mjacob 		 * return what we were given to return.
   4265   1.27    mjacob 		 */
   4266   1.27    mjacob 		return (i);
   4267    1.1       cgd 	}
   4268   1.23    mjacob 	XS_SETERR(xs, HBA_NOERROR);
   4269  1.113    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   4270   1.70    mjacob 	    "START cmd for %d.%d.%d cmd 0x%x datalen %ld",
   4271   1.95    mjacob 	    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0],
   4272   1.70    mjacob 	    (long) XS_XFRLEN(xs));
   4273   1.86    mjacob 	ISP_ADD_REQUEST(isp, nxti);
   4274   1.23    mjacob 	isp->isp_nactive++;
   4275   1.23    mjacob 	return (CMD_QUEUED);
   4276    1.1       cgd }
   4277    1.1       cgd 
   4278    1.1       cgd /*
   4279   1.23    mjacob  * isp control
   4280   1.23    mjacob  * Locks (ints blocked) assumed held.
   4281    1.1       cgd  */
   4282    1.1       cgd 
   4283    1.1       cgd int
   4284  1.111    mjacob isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg)
   4285    1.1       cgd {
   4286   1.57    mjacob 	XS_T *xs;
   4287   1.23    mjacob 	mbreg_t mbs;
   4288   1.38    mjacob 	int bus, tgt;
   4289  1.111    mjacob 	uint32_t handle;
   4290  1.111    mjacob 
   4291  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   4292    1.3       cgd 
   4293   1.23    mjacob 	switch (ctl) {
   4294   1.23    mjacob 	default:
   4295   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
   4296   1.23    mjacob 		break;
   4297    1.3       cgd 
   4298   1.23    mjacob 	case ISPCTL_RESET_BUS:
   4299   1.33    mjacob 		/*
   4300   1.33    mjacob 		 * Issue a bus reset.
   4301   1.33    mjacob 		 */
   4302  1.111    mjacob 		if (IS_24XX(isp)) {
   4303  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
   4304  1.111    mjacob 			break;
   4305  1.111    mjacob 		} else if (IS_FC(isp)) {
   4306  1.111    mjacob 			mbs.param[1] = 10;
   4307  1.111    mjacob 			bus = 0;
   4308  1.111    mjacob 		} else {
   4309  1.111    mjacob 			mbs.param[1] = SDPARAM(isp)->isp_bus_reset_delay;
   4310  1.111    mjacob 			if (mbs.param[1] < 2) {
   4311   1.33    mjacob 				mbs.param[1] = 2;
   4312  1.111    mjacob 			}
   4313   1.38    mjacob 			bus = *((int *) arg);
   4314  1.111    mjacob 			if (IS_DUALBUS(isp)) {
   4315   1.50    mjacob 				mbs.param[2] = bus;
   4316  1.111    mjacob 			}
   4317   1.32    mjacob 		}
   4318  1.111    mjacob 		mbs.param[0] = MBOX_BUS_RESET;
   4319   1.52        he 		isp->isp_sendmarker |= (1 << bus);
   4320  1.111    mjacob 		mbs.logval = MBLOGALL;
   4321  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   4322   1.23    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   4323   1.23    mjacob 			break;
   4324   1.23    mjacob 		}
   4325   1.57    mjacob 		isp_prt(isp, ISP_LOGINFO,
   4326   1.57    mjacob 		    "driver initiated bus reset of bus %d", bus);
   4327   1.23    mjacob 		return (0);
   4328   1.23    mjacob 
   4329   1.34    mjacob 	case ISPCTL_RESET_DEV:
   4330   1.36    mjacob 		tgt = (*((int *) arg)) & 0xffff;
   4331  1.111    mjacob 		if (IS_24XX(isp)) {
   4332  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN, "RESET DEV NOT IMPLEMENTED");
   4333  1.111    mjacob 			break;
   4334  1.111    mjacob 		} else if (IS_FC(isp)) {
   4335  1.111    mjacob 			if (FCPARAM(isp)->isp_2klogin) {
   4336  1.111    mjacob 				mbs.param[1] = tgt;
   4337  1.111    mjacob 				mbs.ibits = (1 << 10);
   4338  1.111    mjacob 			} else {
   4339  1.111    mjacob 				mbs.param[1] = (tgt << 8);
   4340  1.111    mjacob 			}
   4341  1.111    mjacob 			bus = 0;
   4342  1.111    mjacob 		} else {
   4343  1.111    mjacob 			bus = (*((int *) arg)) >> 16;
   4344  1.111    mjacob 			mbs.param[1] = (bus << 15) | (tgt << 8);
   4345  1.111    mjacob 		}
   4346   1.23    mjacob 		mbs.param[0] = MBOX_ABORT_TARGET;
   4347   1.32    mjacob 		mbs.param[2] = 3;	/* 'delay', in seconds */
   4348  1.111    mjacob 		mbs.logval = MBLOGALL;
   4349  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   4350   1.23    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   4351   1.23    mjacob 			break;
   4352   1.23    mjacob 		}
   4353   1.57    mjacob 		isp_prt(isp, ISP_LOGINFO,
   4354   1.57    mjacob 		    "Target %d on Bus %d Reset Succeeded", tgt, bus);
   4355   1.52        he 		isp->isp_sendmarker |= (1 << bus);
   4356   1.23    mjacob 		return (0);
   4357   1.23    mjacob 
   4358   1.34    mjacob 	case ISPCTL_ABORT_CMD:
   4359   1.57    mjacob 		xs = (XS_T *) arg;
   4360   1.54    mjacob 		tgt = XS_TGT(xs);
   4361  1.111    mjacob 
   4362   1.38    mjacob 		handle = isp_find_handle(isp, xs);
   4363   1.38    mjacob 		if (handle == 0) {
   4364   1.57    mjacob 			isp_prt(isp, ISP_LOGWARN,
   4365   1.57    mjacob 			    "cannot find handle for command to abort");
   4366   1.23    mjacob 			break;
   4367   1.23    mjacob 		}
   4368  1.111    mjacob 		if (IS_24XX(isp)) {
   4369  1.111    mjacob 			isp_prt(isp, ISP_LOGWARN, "ABORT CMD NOT IMPLEMENTED");
   4370  1.111    mjacob 			break;
   4371  1.111    mjacob 		} else if (IS_FC(isp)) {
   4372  1.111    mjacob 			if (FCPARAM(isp)->isp_sccfw) {
   4373  1.111    mjacob 				if (FCPARAM(isp)->isp_2klogin) {
   4374  1.111    mjacob 					mbs.param[1] = tgt;
   4375  1.111    mjacob 				} else {
   4376  1.111    mjacob 					mbs.param[1] = tgt << 8;
   4377  1.111    mjacob 				}
   4378   1.54    mjacob 				mbs.param[6] = XS_LUN(xs);
   4379   1.54    mjacob 			} else {
   4380   1.54    mjacob 				mbs.param[1] = tgt << 8 | XS_LUN(xs);
   4381   1.54    mjacob 			}
   4382   1.28    mjacob 		} else {
   4383  1.111    mjacob 			bus = XS_CHANNEL(xs);
   4384  1.111    mjacob 			mbs.param[1] = (bus << 15) | (tgt << 8) | XS_LUN(xs);
   4385   1.28    mjacob 		}
   4386  1.111    mjacob 		mbs.param[0] = MBOX_ABORT;
   4387   1.73    mjacob 		mbs.param[2] = handle;
   4388  1.111    mjacob 		mbs.logval = MBLOGALL & ~MBOX_COMMAND_ERROR;
   4389  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   4390  1.111    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   4391  1.111    mjacob 			break;
   4392   1.23    mjacob 		}
   4393  1.111    mjacob 		return (0);
   4394   1.26    mjacob 
   4395   1.26    mjacob 	case ISPCTL_UPDATE_PARAMS:
   4396   1.70    mjacob 
   4397   1.26    mjacob 		isp_update(isp);
   4398   1.34    mjacob 		return (0);
   4399   1.33    mjacob 
   4400   1.33    mjacob 	case ISPCTL_FCLINK_TEST:
   4401   1.70    mjacob 
   4402   1.54    mjacob 		if (IS_FC(isp)) {
   4403  1.111    mjacob 			int usdelay = *((int *) arg);
   4404  1.111    mjacob 			if (usdelay == 0) {
   4405  1.111    mjacob 				usdelay =  250000;
   4406  1.111    mjacob 			}
   4407   1.57    mjacob 			return (isp_fclink_test(isp, usdelay));
   4408   1.54    mjacob 		}
   4409   1.54    mjacob 		break;
   4410   1.46    mjacob 
   4411   1.70    mjacob 	case ISPCTL_SCAN_FABRIC:
   4412   1.70    mjacob 
   4413   1.70    mjacob 		if (IS_FC(isp)) {
   4414  1.111    mjacob 			return (isp_scan_fabric(isp));
   4415   1.70    mjacob 		}
   4416   1.70    mjacob 		break;
   4417   1.70    mjacob 
   4418   1.70    mjacob 	case ISPCTL_SCAN_LOOP:
   4419   1.70    mjacob 
   4420   1.70    mjacob 		if (IS_FC(isp)) {
   4421   1.70    mjacob 			return (isp_scan_loop(isp));
   4422   1.70    mjacob 		}
   4423   1.70    mjacob 		break;
   4424   1.70    mjacob 
   4425   1.46    mjacob 	case ISPCTL_PDB_SYNC:
   4426   1.70    mjacob 
   4427   1.70    mjacob 		if (IS_FC(isp)) {
   4428   1.70    mjacob 			return (isp_pdb_sync(isp));
   4429   1.70    mjacob 		}
   4430   1.70    mjacob 		break;
   4431   1.70    mjacob 
   4432   1.70    mjacob 	case ISPCTL_SEND_LIP:
   4433   1.70    mjacob 
   4434  1.111    mjacob 		if (IS_FC(isp) && !IS_24XX(isp)) {
   4435   1.70    mjacob 			mbs.param[0] = MBOX_INIT_LIP;
   4436  1.111    mjacob 			if (FCPARAM(isp)->isp_2klogin) {
   4437  1.111    mjacob 				mbs.ibits = (1 << 10);
   4438  1.111    mjacob 			}
   4439  1.111    mjacob 			mbs.logval = MBLOGALL;
   4440  1.111    mjacob 			isp_mboxcmd(isp, &mbs);
   4441   1.70    mjacob 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
   4442   1.70    mjacob 				return (0);
   4443   1.70    mjacob 			}
   4444   1.70    mjacob 		}
   4445   1.70    mjacob 		break;
   4446   1.70    mjacob 
   4447  1.111    mjacob 	case ISPCTL_GET_PDB:
   4448   1.70    mjacob 		if (IS_FC(isp) && arg) {
   4449  1.111    mjacob 			int id = *((int *)arg);
   4450  1.111    mjacob 			isp_pdb_t *pdb = arg;
   4451  1.111    mjacob 			return (isp_getpdb(isp, id, pdb, 1));
   4452   1.54    mjacob 		}
   4453   1.54    mjacob 		break;
   4454   1.70    mjacob 
   4455  1.111    mjacob 	case ISPCTL_GET_PORTNAME:
   4456  1.111    mjacob 	{
   4457  1.111    mjacob 		uint64_t *wwnp = arg;
   4458  1.111    mjacob 		int loopid = *wwnp;
   4459  1.111    mjacob 		*wwnp = isp_get_portname(isp, loopid, 0);
   4460  1.111    mjacob 		if (*wwnp == (uint64_t) -1) {
   4461  1.111    mjacob 			break;
   4462  1.111    mjacob 		} else {
   4463  1.111    mjacob 			return (0);
   4464  1.111    mjacob 		}
   4465  1.111    mjacob 	}
   4466   1.71    mjacob 	case ISPCTL_RUN_MBOXCMD:
   4467   1.71    mjacob 
   4468  1.111    mjacob 		isp_mboxcmd(isp, arg);
   4469   1.71    mjacob 		return(0);
   4470   1.71    mjacob 
   4471  1.111    mjacob 	case ISPCTL_PLOGX:
   4472  1.111    mjacob 	{
   4473  1.111    mjacob 		isp_plcmd_t *p = arg;
   4474  1.111    mjacob 		int r;
   4475  1.111    mjacob 
   4476  1.111    mjacob 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI ||
   4477  1.111    mjacob 		    (p->handle != NIL_HANDLE)) {
   4478  1.111    mjacob 			return (isp_plogx(isp, p->handle, p->portid,
   4479  1.111    mjacob 			    p->flags, 0));
   4480  1.111    mjacob 		}
   4481  1.111    mjacob 		do {
   4482  1.111    mjacob 			p->handle = isp_nxt_handle(isp, p->handle);
   4483  1.111    mjacob 			r = isp_plogx(isp, p->handle, p->portid, p->flags, 0);
   4484  1.111    mjacob 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
   4485  1.111    mjacob 				p->handle = r >> 16;
   4486  1.111    mjacob 				r = 0;
   4487  1.111    mjacob 				break;
   4488  1.111    mjacob 			}
   4489  1.111    mjacob 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
   4490  1.111    mjacob 		return (r);
   4491  1.111    mjacob 	}
   4492   1.43    mjacob #ifdef	ISP_TARGET_MODE
   4493   1.46    mjacob 	case ISPCTL_TOGGLE_TMODE:
   4494   1.58    mjacob 	{
   4495   1.70    mjacob 
   4496   1.70    mjacob 		/*
   4497   1.70    mjacob 		 * We don't check/set against role here- that's the
   4498   1.70    mjacob 		 * responsibility for the outer layer to coordinate.
   4499   1.70    mjacob 		 */
   4500   1.46    mjacob 		if (IS_SCSI(isp)) {
   4501   1.74    mjacob 			int param = *(int *)arg;
   4502   1.46    mjacob 			mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
   4503   1.74    mjacob 			mbs.param[1] = param & 0xffff;
   4504   1.74    mjacob 			mbs.param[2] = param >> 16;
   4505  1.111    mjacob 			mbs.logval = MBLOGALL;
   4506  1.111    mjacob 			isp_mboxcmd(isp, &mbs);
   4507   1.46    mjacob 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   4508   1.46    mjacob 				break;
   4509   1.46    mjacob 			}
   4510   1.46    mjacob 		}
   4511   1.46    mjacob 		return (0);
   4512   1.58    mjacob 	}
   4513   1.43    mjacob #endif
   4514    1.1       cgd 	}
   4515   1.23    mjacob 	return (-1);
   4516    1.1       cgd }
   4517    1.1       cgd 
   4518   1.23    mjacob /*
   4519   1.23    mjacob  * Interrupt Service Routine(s).
   4520   1.23    mjacob  *
   4521   1.23    mjacob  * External (OS) framework has done the appropriate locking,
   4522   1.23    mjacob  * and the locking will be held throughout this function.
   4523   1.23    mjacob  */
   4524   1.23    mjacob 
   4525   1.57    mjacob /*
   4526   1.57    mjacob  * Limit our stack depth by sticking with the max likely number
   4527   1.57    mjacob  * of completions on a request queue at any one time.
   4528   1.57    mjacob  */
   4529   1.88    mjacob #ifndef	MAX_REQUESTQ_COMPLETIONS
   4530  1.111    mjacob #define	MAX_REQUESTQ_COMPLETIONS	32
   4531   1.88    mjacob #endif
   4532   1.57    mjacob 
   4533   1.79    mjacob void
   4534  1.111    mjacob isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
   4535    1.1       cgd {
   4536   1.57    mjacob 	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
   4537  1.111    mjacob 	uint32_t iptr, optr, junk;
   4538   1.32    mjacob 	int i, nlooked = 0, ndone = 0;
   4539    1.1       cgd 
   4540   1.88    mjacob again:
   4541  1.111    mjacob 	optr = isp->isp_residx;
   4542   1.79    mjacob 	/*
   4543   1.79    mjacob 	 * Is this a mailbox related interrupt?
   4544   1.79    mjacob 	 * The mailbox semaphore will be nonzero if so.
   4545   1.79    mjacob 	 */
   4546   1.36    mjacob 	if (sema) {
   4547   1.33    mjacob 		if (mbox & 0x4000) {
   4548   1.88    mjacob 			isp->isp_intmboxc++;
   4549   1.86    mjacob 			if (isp->isp_mboxbsy) {
   4550  1.111    mjacob 				int obits = isp->isp_obits;
   4551  1.111    mjacob 				isp->isp_mboxtmp[0] = mbox;
   4552  1.111    mjacob 				for (i = 1; i < MAX_MAILBOX(isp); i++) {
   4553  1.111    mjacob 					if ((obits & (1 << i)) == 0) {
   4554   1.54    mjacob 						continue;
   4555   1.54    mjacob 					}
   4556  1.111    mjacob 					isp->isp_mboxtmp[i] =
   4557  1.111    mjacob 					    ISP_READ(isp, MBOX_OFF(i));
   4558   1.54    mjacob 				}
   4559   1.88    mjacob 				if (isp->isp_mbxwrk0) {
   4560   1.88    mjacob 					if (isp_mbox_continue(isp) == 0) {
   4561   1.88    mjacob 						return;
   4562   1.88    mjacob 					}
   4563   1.88    mjacob 				}
   4564   1.54    mjacob 				MBOX_NOTIFY_COMPLETE(isp);
   4565   1.54    mjacob 			} else {
   4566   1.57    mjacob 				isp_prt(isp, ISP_LOGWARN,
   4567  1.111    mjacob 				    "mailbox cmd (0x%x) with no waiters", mbox);
   4568   1.54    mjacob 			}
   4569   1.87    mjacob 		} else if (isp_parse_async(isp, mbox) < 0) {
   4570   1.87    mjacob 			return;
   4571   1.31    mjacob 		}
   4572   1.97    mjacob 		if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) ||
   4573   1.97    mjacob 		    isp->isp_state != ISP_RUNSTATE) {
   4574  1.111    mjacob 			goto out;
   4575   1.54    mjacob 		}
   4576   1.54    mjacob 	}
   4577   1.54    mjacob 
   4578   1.54    mjacob 	/*
   4579   1.54    mjacob 	 * We can't be getting this now.
   4580   1.54    mjacob 	 */
   4581   1.54    mjacob 	if (isp->isp_state != ISP_RUNSTATE) {
   4582  1.111    mjacob 		isp_prt(isp, ISP_LOGINFO,
   4583   1.79    mjacob 		    "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
   4584   1.79    mjacob 		/*
   4585  1.111    mjacob 		 * Thank you very much!  *Burrrp*!
   4586  1.111    mjacob 		 */
   4587  1.111    mjacob 		ISP_WRITE(isp, isp->isp_respoutrp,
   4588  1.111    mjacob 		    ISP_READ(isp, isp->isp_respinrp));
   4589  1.111    mjacob 		if (IS_24XX(isp)) {
   4590  1.111    mjacob 			ISP_DISABLE_INTS(isp);
   4591  1.111    mjacob 		}
   4592  1.111    mjacob 		goto out;
   4593  1.111    mjacob 	}
   4594  1.111    mjacob 
   4595  1.111    mjacob #ifdef	ISP_TARGET_MODE
   4596  1.111    mjacob 	/*
   4597  1.111    mjacob 	 * Check for ATIO Queue entries.
   4598  1.111    mjacob 	 */
   4599  1.111    mjacob 	if (isp->isp_rspbsy == 0 && (isp->isp_role & ISP_ROLE_TARGET) &&
   4600  1.111    mjacob 	    IS_24XX(isp)) {
   4601  1.111    mjacob 		iptr = ISP_READ(isp, isp->isp_atioinrp);
   4602  1.111    mjacob 		optr = ISP_READ(isp, isp->isp_atiooutrp);
   4603  1.111    mjacob 
   4604  1.111    mjacob 		isp->isp_rspbsy = 1;
   4605  1.111    mjacob 		while (optr != iptr) {
   4606  1.111    mjacob 			uint8_t qe[QENTRY_LEN];
   4607  1.111    mjacob 			isphdr_t *hp;
   4608  1.111    mjacob 			uint32_t oop;
   4609  1.111    mjacob 			void *addr;
   4610  1.111    mjacob 
   4611  1.111    mjacob 			oop = optr;
   4612  1.111    mjacob 			MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN);
   4613  1.111    mjacob 			addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
   4614  1.111    mjacob 			isp_get_hdr(isp, addr, (isphdr_t *)qe);
   4615  1.111    mjacob 			hp = (isphdr_t *)qe;
   4616  1.111    mjacob 			switch (hp->rqs_entry_type) {
   4617  1.111    mjacob 			case RQSTYPE_NOTIFY:
   4618  1.111    mjacob 			case RQSTYPE_ATIO:
   4619  1.111    mjacob 				(void) isp_target_notify(isp, addr, &oop);
   4620  1.111    mjacob 				break;
   4621  1.111    mjacob 			default:
   4622  1.111    mjacob 				isp_print_qentry(isp, "?ATIOQ entry?",
   4623  1.111    mjacob 				    oop, addr);
   4624  1.111    mjacob 				break;
   4625  1.111    mjacob 			}
   4626  1.111    mjacob 			optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
   4627  1.111    mjacob 			ISP_WRITE(isp, isp->isp_atiooutrp, optr);
   4628  1.111    mjacob 		}
   4629  1.111    mjacob 		isp->isp_rspbsy = 0;
   4630  1.111    mjacob 		optr = isp->isp_residx;
   4631   1.79    mjacob 	}
   4632  1.111    mjacob #endif
   4633   1.79    mjacob 
   4634   1.79    mjacob 	/*
   4635   1.79    mjacob 	 * Get the current Response Queue Out Pointer.
   4636   1.79    mjacob 	 *
   4637  1.111    mjacob 	 * If we're a 2300 or 2400, we can ask what hardware what it thinks.
   4638   1.79    mjacob 	 */
   4639  1.111    mjacob 	if (IS_23XX(isp) || IS_24XX(isp)) {
   4640   1.79    mjacob 		optr = ISP_READ(isp, isp->isp_respoutrp);
   4641   1.88    mjacob 		/*
   4642   1.88    mjacob 		 * Debug: to be taken out eventually
   4643   1.88    mjacob 		 */
   4644   1.79    mjacob 		if (isp->isp_residx != optr) {
   4645  1.111    mjacob 			isp_prt(isp, ISP_LOGINFO,
   4646  1.111    mjacob 			    "isp_intr: hard optr=%x, soft optr %x",
   4647   1.79    mjacob 			    optr, isp->isp_residx);
   4648  1.111    mjacob 			isp->isp_residx = optr;
   4649   1.79    mjacob 		}
   4650   1.79    mjacob 	} else {
   4651   1.79    mjacob 		optr = isp->isp_residx;
   4652    1.1       cgd 	}
   4653   1.25    mjacob 
   4654   1.35    mjacob 	/*
   4655   1.79    mjacob 	 * You *must* read the Response Queue In Pointer
   4656   1.78    mjacob 	 * prior to clearing the RISC interrupt.
   4657   1.87    mjacob 	 *
   4658   1.87    mjacob 	 * Debounce the 2300 if revision less than 2.
   4659   1.35    mjacob 	 */
   4660   1.87    mjacob 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
   4661   1.54    mjacob 		i = 0;
   4662   1.54    mjacob 		do {
   4663  1.111    mjacob 			iptr = ISP_READ(isp, isp->isp_respinrp);
   4664  1.111    mjacob 			junk = ISP_READ(isp, isp->isp_respinrp);
   4665   1.54    mjacob 		} while (junk != iptr && ++i < 1000);
   4666   1.54    mjacob 
   4667   1.54    mjacob 		if (iptr != junk) {
   4668   1.57    mjacob 			isp_prt(isp, ISP_LOGWARN,
   4669   1.79    mjacob 			    "Response Queue Out Pointer Unstable (%x, %x)",
   4670   1.79    mjacob 			    iptr, junk);
   4671  1.111    mjacob 			goto out;
   4672   1.54    mjacob 		}
   4673   1.54    mjacob 	} else {
   4674  1.111    mjacob 		iptr = ISP_READ(isp, isp->isp_respinrp);
   4675   1.54    mjacob 	}
   4676   1.90    mjacob 	isp->isp_resodx = iptr;
   4677   1.54    mjacob 
   4678   1.54    mjacob 
   4679   1.54    mjacob 	if (optr == iptr && sema == 0) {
   4680   1.54    mjacob 		/*
   4681   1.54    mjacob 		 * There are a lot of these- reasons unknown- mostly on
   4682   1.54    mjacob 		 * faster Alpha machines.
   4683   1.54    mjacob 		 *
   4684   1.54    mjacob 		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
   4685   1.54    mjacob 		 * make sure the old interrupt went away (to avoid 'ringing'
   4686   1.54    mjacob 		 * effects), but that didn't stop this from occurring.
   4687   1.54    mjacob 		 */
   4688  1.111    mjacob 		if (IS_24XX(isp)) {
   4689  1.111    mjacob 			junk = 0;
   4690  1.111    mjacob 		} else if (IS_23XX(isp)) {
   4691   1.79    mjacob 			USEC_DELAY(100);
   4692  1.111    mjacob 			iptr = ISP_READ(isp, isp->isp_respinrp);
   4693   1.79    mjacob 			junk = ISP_READ(isp, BIU_R2HSTSLO);
   4694   1.79    mjacob 		} else {
   4695   1.79    mjacob 			junk = ISP_READ(isp, BIU_ISR);
   4696   1.79    mjacob 		}
   4697   1.79    mjacob 		if (optr == iptr) {
   4698  1.111    mjacob 			if (IS_23XX(isp) || IS_24XX(isp)) {
   4699   1.88    mjacob 				;
   4700   1.88    mjacob 			} else {
   4701   1.88    mjacob 				sema = ISP_READ(isp, BIU_SEMA);
   4702   1.88    mjacob 				mbox = ISP_READ(isp, OUTMAILBOX0);
   4703   1.88    mjacob 				if ((sema & 0x3) && (mbox & 0x8000)) {
   4704   1.88    mjacob 					goto again;
   4705   1.88    mjacob 				}
   4706   1.88    mjacob 			}
   4707   1.88    mjacob 			isp->isp_intbogus++;
   4708   1.88    mjacob 			isp_prt(isp, ISP_LOGDEBUG1,
   4709   1.79    mjacob 			    "bogus intr- isr %x (%x) iptr %x optr %x",
   4710   1.79    mjacob 			    isr, junk, iptr, optr);
   4711   1.79    mjacob 		}
   4712   1.10    mjacob 	}
   4713   1.90    mjacob 	isp->isp_resodx = iptr;
   4714  1.111    mjacob 
   4715   1.10    mjacob 
   4716   1.90    mjacob 	if (isp->isp_rspbsy) {
   4717  1.111    mjacob 		goto out;
   4718   1.90    mjacob 	}
   4719   1.90    mjacob 	isp->isp_rspbsy = 1;
   4720    1.1       cgd 	while (optr != iptr) {
   4721  1.111    mjacob 		uint8_t qe[QENTRY_LEN];
   4722  1.111    mjacob 		ispstatusreq_t *sp = (ispstatusreq_t *) qe;
   4723   1.86    mjacob 		isphdr_t *hp;
   4724  1.111    mjacob 		int buddaboom, etype, scsi_status, completion_status;
   4725  1.111    mjacob 		int req_status_flags, req_state_flags;
   4726  1.111    mjacob 		uint8_t *snsp, *resp;
   4727  1.111    mjacob 		uint32_t rlen, slen;
   4728  1.111    mjacob 		long resid;
   4729  1.111    mjacob 		uint16_t oop;
   4730    1.1       cgd 
   4731   1.86    mjacob 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
   4732   1.25    mjacob 		oop = optr;
   4733   1.57    mjacob 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
   4734   1.32    mjacob 		nlooked++;
   4735  1.111    mjacob  read_again:
   4736  1.111    mjacob 		buddaboom = req_status_flags = req_state_flags = 0;
   4737  1.111    mjacob 		resid = 0L;
   4738  1.111    mjacob 
   4739   1.38    mjacob 		/*
   4740   1.86    mjacob 		 * Synchronize our view of this response queue entry.
   4741   1.86    mjacob 		 */
   4742   1.86    mjacob 		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN);
   4743  1.111    mjacob 		isp_get_hdr(isp, hp, &sp->req_header);
   4744  1.111    mjacob 		etype = sp->req_header.rqs_entry_type;
   4745   1.86    mjacob 
   4746  1.113    mjacob 		if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
   4747  1.111    mjacob 			isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
   4748  1.111    mjacob 			isp_get_24xx_response(isp,
   4749  1.111    mjacob 			    (isp24xx_statusreq_t *)hp, sp2);
   4750  1.111    mjacob 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
   4751  1.111    mjacob 				isp_print_bytes(isp,
   4752  1.111    mjacob 				    "Response Queue Entry", QENTRY_LEN, sp2);
   4753  1.111    mjacob 			}
   4754  1.111    mjacob 			scsi_status = sp2->req_scsi_status;
   4755  1.111    mjacob 			completion_status = sp2->req_completion_status;
   4756  1.111    mjacob 			req_state_flags = 0;
   4757  1.111    mjacob 			resid = sp2->req_resid;
   4758  1.111    mjacob 		} else if (etype == RQSTYPE_RESPONSE) {
   4759   1.86    mjacob 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
   4760  1.111    mjacob 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
   4761  1.111    mjacob 				isp_print_bytes(isp,
   4762  1.111    mjacob 				    "Response Queue Entry", QENTRY_LEN, sp);
   4763  1.111    mjacob 			}
   4764  1.111    mjacob 			scsi_status = sp->req_scsi_status;
   4765  1.111    mjacob 			completion_status = sp->req_completion_status;
   4766  1.111    mjacob 			req_status_flags = sp->req_status_flags;
   4767  1.111    mjacob 			req_state_flags = sp->req_state_flags;
   4768  1.111    mjacob 			resid = sp->req_resid;
   4769  1.111    mjacob 		} else if (etype == RQSTYPE_RIO2) {
   4770  1.111    mjacob 			isp_rio2_t *rio = (isp_rio2_t *)qe;
   4771  1.111    mjacob 			isp_get_rio2(isp, (isp_rio2_t *) hp, rio);
   4772  1.111    mjacob 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
   4773  1.111    mjacob 				isp_print_bytes(isp,
   4774  1.111    mjacob 				    "Response Queue Entry", QENTRY_LEN, rio);
   4775  1.111    mjacob 			}
   4776  1.111    mjacob 			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
   4777  1.111    mjacob 				isp_fastpost_complete(isp, rio->req_handles[i]);
   4778  1.111    mjacob 			}
   4779  1.111    mjacob 			if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
   4780  1.111    mjacob 				isp->isp_fpcchiwater =
   4781  1.111    mjacob 				    rio->req_header.rqs_seqno;
   4782   1.87    mjacob 			}
   4783   1.90    mjacob 			MEMZERO(hp, QENTRY_LEN);	/* PERF */
   4784   1.87    mjacob 			continue;
   4785   1.86    mjacob 		} else {
   4786   1.89    mjacob 			/*
   4787   1.89    mjacob 			 * Somebody reachable via isp_handle_other_response
   4788   1.89    mjacob 			 * may have updated the response queue pointers for
   4789   1.90    mjacob 			 * us, so we reload our goal index.
   4790   1.89    mjacob 			 */
   4791  1.111    mjacob 			int r;
   4792  1.111    mjacob 			r = isp_handle_other_response(isp, etype, hp, &optr);
   4793  1.111    mjacob 			if (r < 0) {
   4794  1.111    mjacob 				goto read_again;
   4795  1.111    mjacob 			}
   4796  1.111    mjacob 			if (r > 0) {
   4797   1.90    mjacob 				iptr = isp->isp_resodx;
   4798   1.86    mjacob 				MEMZERO(hp, QENTRY_LEN);	/* PERF */
   4799   1.25    mjacob 				continue;
   4800   1.25    mjacob 			}
   4801   1.86    mjacob 
   4802   1.86    mjacob 			/*
   4803   1.86    mjacob 			 * After this point, we'll just look at the header as
   4804   1.86    mjacob 			 * we don't know how to deal with the rest of the
   4805   1.86    mjacob 			 * response.
   4806   1.86    mjacob 			 */
   4807   1.86    mjacob 
   4808   1.25    mjacob 			/*
   4809   1.25    mjacob 			 * It really has to be a bounced request just copied
   4810   1.36    mjacob 			 * from the request queue to the response queue. If
   4811   1.36    mjacob 			 * not, something bad has happened.
   4812   1.25    mjacob 			 */
   4813  1.111    mjacob 			if (etype != RQSTYPE_REQUEST) {
   4814   1.57    mjacob 				isp_prt(isp, ISP_LOGERR, notresp,
   4815  1.111    mjacob 				    etype, oop, optr, nlooked);
   4816  1.111    mjacob 				isp_print_bytes(isp,
   4817  1.111    mjacob 				    "Request Queue Entry", QENTRY_LEN, sp);
   4818   1.86    mjacob 				MEMZERO(hp, QENTRY_LEN);	/* PERF */
   4819    1.1       cgd 				continue;
   4820    1.1       cgd 			}
   4821    1.1       cgd 			buddaboom = 1;
   4822  1.111    mjacob 			scsi_status = sp->req_scsi_status;
   4823  1.111    mjacob 			completion_status = sp->req_completion_status;
   4824  1.111    mjacob 			req_status_flags = sp->req_status_flags;
   4825  1.111    mjacob 			req_state_flags = sp->req_state_flags;
   4826  1.111    mjacob 			resid = sp->req_resid;
   4827    1.1       cgd 		}
   4828    1.1       cgd 
   4829  1.111    mjacob 		if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
   4830    1.1       cgd 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
   4831   1.57    mjacob 				isp_prt(isp, ISP_LOGWARN,
   4832   1.57    mjacob 				    "continuation segment");
   4833  1.111    mjacob 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
   4834    1.1       cgd 				continue;
   4835    1.1       cgd 			}
   4836   1.23    mjacob 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
   4837   1.57    mjacob 				isp_prt(isp, ISP_LOGDEBUG1,
   4838   1.57    mjacob 				    "internal queues full");
   4839   1.36    mjacob 				/*
   4840   1.36    mjacob 				 * We'll synthesize a QUEUE FULL message below.
   4841   1.36    mjacob 				 */
   4842   1.23    mjacob 			}
   4843   1.23    mjacob 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
   4844  1.111    mjacob 				isp_print_bytes(isp, "bad header flag",
   4845  1.111    mjacob 				    QENTRY_LEN, sp);
   4846   1.23    mjacob 				buddaboom++;
   4847   1.23    mjacob 			}
   4848   1.23    mjacob 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
   4849  1.111    mjacob 				isp_print_bytes(isp, "bad request packet",
   4850  1.111    mjacob 				    QENTRY_LEN, sp);
   4851   1.36    mjacob 				buddaboom++;
   4852   1.36    mjacob 			}
   4853    1.1       cgd 		}
   4854  1.111    mjacob 
   4855   1.38    mjacob 		if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
   4856  1.111    mjacob 			isp_prt(isp, ISP_LOGERR,
   4857  1.111    mjacob 			    "bad request handle %d (type 0x%x)",
   4858  1.111    mjacob 			    sp->req_handle, etype);
   4859   1.86    mjacob 			MEMZERO(hp, QENTRY_LEN);	/* PERF */
   4860  1.111    mjacob 			ISP_WRITE(isp, isp->isp_respoutrp, optr);
   4861    1.1       cgd 			continue;
   4862    1.1       cgd 		}
   4863   1.38    mjacob 		xs = isp_find_xs(isp, sp->req_handle);
   4864    1.1       cgd 		if (xs == NULL) {
   4865  1.111    mjacob 			uint8_t ts = completion_status & 0xff;
   4866   1.92    mjacob 			/*
   4867   1.92    mjacob 			 * Only whine if this isn't the expected fallout of
   4868   1.92    mjacob 			 * aborting the command.
   4869   1.92    mjacob 			 */
   4870  1.111    mjacob 			if (etype != RQSTYPE_RESPONSE) {
   4871   1.92    mjacob 				isp_prt(isp, ISP_LOGERR,
   4872   1.95    mjacob 				    "cannot find handle 0x%x (type 0x%x)",
   4873  1.111    mjacob 				    sp->req_handle, etype);
   4874   1.95    mjacob 			} else if (ts != RQCS_ABORTED) {
   4875   1.95    mjacob 				isp_prt(isp, ISP_LOGERR,
   4876   1.95    mjacob 				    "cannot find handle 0x%x (status 0x%x)",
   4877   1.95    mjacob 				    sp->req_handle, ts);
   4878   1.92    mjacob 			}
   4879  1.111    mjacob 			MEMZERO(hp, QENTRY_LEN);	/* PERF */
   4880  1.111    mjacob 			ISP_WRITE(isp, isp->isp_respoutrp, optr);
   4881    1.1       cgd 			continue;
   4882    1.1       cgd 		}
   4883   1.38    mjacob 		isp_destroy_handle(isp, sp->req_handle);
   4884  1.111    mjacob 		if (req_status_flags & RQSTF_BUS_RESET) {
   4885   1.86    mjacob 			XS_SETERR(xs, HBA_BUSRESET);
   4886   1.36    mjacob 			isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
   4887    1.1       cgd 		}
   4888    1.1       cgd 		if (buddaboom) {
   4889   1.23    mjacob 			XS_SETERR(xs, HBA_BOTCH);
   4890    1.1       cgd 		}
   4891   1.61    mjacob 
   4892  1.111    mjacob 		resp = NULL;
   4893  1.111    mjacob 		rlen = 0;
   4894  1.111    mjacob 		snsp = NULL;
   4895  1.111    mjacob 		slen = 0;
   4896  1.113    mjacob 		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
   4897  1.111    mjacob 			resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
   4898  1.111    mjacob 			rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
   4899  1.111    mjacob 		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
   4900  1.111    mjacob 			resp = sp->req_response;
   4901  1.111    mjacob 			rlen = sp->req_response_len;
   4902  1.111    mjacob 		}
   4903  1.111    mjacob 		if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
   4904   1.31    mjacob 			/*
   4905   1.61    mjacob 			 * Fibre Channel F/W doesn't say we got status
   4906   1.61    mjacob 			 * if there's Sense Data instead. I guess they
   4907   1.61    mjacob 			 * think it goes w/o saying.
   4908   1.31    mjacob 			 */
   4909  1.111    mjacob 			req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
   4910  1.111    mjacob 			if (IS_24XX(isp)) {
   4911  1.111    mjacob 				snsp =
   4912  1.111    mjacob 				    ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
   4913  1.111    mjacob 				snsp += rlen;
   4914  1.111    mjacob 				slen =
   4915  1.111    mjacob 				    ((isp24xx_statusreq_t *)sp)->req_sense_len;
   4916  1.111    mjacob 			} else {
   4917  1.111    mjacob 				snsp = sp->req_sense_data;
   4918  1.111    mjacob 				slen = sp->req_sense_len;
   4919  1.111    mjacob 			}
   4920  1.111    mjacob 		} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
   4921  1.111    mjacob 			snsp = sp->req_sense_data;
   4922  1.111    mjacob 			slen = sp->req_sense_len;
   4923   1.61    mjacob 		}
   4924  1.111    mjacob 		if (req_state_flags & RQSF_GOT_STATUS) {
   4925  1.111    mjacob 			*XS_STSP(xs) = scsi_status & 0xff;
   4926    1.1       cgd 		}
   4927    1.1       cgd 
   4928  1.111    mjacob 		switch (etype) {
   4929   1.61    mjacob 		case RQSTYPE_RESPONSE:
   4930   1.57    mjacob 			XS_SET_STATE_STAT(isp, xs, sp);
   4931  1.111    mjacob 			if (resp && rlen >= 4 &&
   4932  1.111    mjacob 			    resp[FCP_RSPNS_CODE_OFFSET] != 0) {
   4933  1.111    mjacob 				isp_prt(isp, ISP_LOGWARN,
   4934  1.113    mjacob 				    "%d.%d.%d FCP RESPONSE: 0x%x",
   4935  1.113    mjacob 				    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
   4936  1.111    mjacob 				    resp[FCP_RSPNS_CODE_OFFSET]);
   4937  1.111    mjacob 				XS_SETERR(xs, HBA_BOTCH);
   4938  1.111    mjacob 			}
   4939  1.111    mjacob 			if (IS_24XX(isp)) {
   4940  1.111    mjacob 				isp_parse_status_24xx(isp,
   4941  1.111    mjacob 				    (isp24xx_statusreq_t *)sp, xs, &resid);
   4942  1.111    mjacob 			} else {
   4943  1.111    mjacob 				isp_parse_status(isp, (void *)sp, xs, &resid);
   4944  1.111    mjacob 			}
   4945   1.57    mjacob 			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
   4946   1.57    mjacob 			    (*XS_STSP(xs) == SCSI_BUSY)) {
   4947   1.57    mjacob 				XS_SETERR(xs, HBA_TGTBSY);
   4948   1.25    mjacob 			}
   4949   1.61    mjacob 			if (IS_SCSI(isp)) {
   4950  1.111    mjacob 				XS_RESID(xs) = resid;
   4951   1.61    mjacob 				/*
   4952   1.61    mjacob 				 * A new synchronous rate was negotiated for
   4953   1.61    mjacob 				 * this target. Mark state such that we'll go
   4954   1.61    mjacob 				 * look up that which has changed later.
   4955   1.61    mjacob 				 */
   4956  1.111    mjacob 				if (req_status_flags & RQSTF_NEGOTIATION) {
   4957   1.61    mjacob 					int t = XS_TGT(xs);
   4958   1.61    mjacob 					sdparam *sdp = isp->isp_param;
   4959   1.61    mjacob 					sdp += XS_CHANNEL(xs);
   4960   1.61    mjacob 					sdp->isp_devparam[t].dev_refresh = 1;
   4961   1.61    mjacob 					isp->isp_update |=
   4962   1.61    mjacob 					    (1 << XS_CHANNEL(xs));
   4963   1.61    mjacob 				}
   4964   1.61    mjacob 			} else {
   4965  1.111    mjacob 				if (req_status_flags & RQSF_XFER_COMPLETE) {
   4966   1.61    mjacob 					XS_RESID(xs) = 0;
   4967  1.111    mjacob 				} else if (scsi_status & RQCS_RESID) {
   4968  1.111    mjacob 					XS_RESID(xs) = resid;
   4969   1.61    mjacob 				} else {
   4970   1.61    mjacob 					XS_RESID(xs) = 0;
   4971   1.61    mjacob 				}
   4972  1.111    mjacob 			}
   4973  1.111    mjacob 			if (snsp && slen) {
   4974  1.111    mjacob 				XS_SAVE_SENSE(xs, snsp, slen);
   4975   1.61    mjacob 			}
   4976   1.70    mjacob 			isp_prt(isp, ISP_LOGDEBUG2,
   4977  1.111    mjacob 			   "asked for %ld got raw resid %ld settled for %ld",
   4978  1.111    mjacob 			    (long) XS_XFRLEN(xs), resid, (long) XS_RESID(xs));
   4979   1.61    mjacob 			break;
   4980   1.61    mjacob 		case RQSTYPE_REQUEST:
   4981  1.111    mjacob 		case RQSTYPE_A64:
   4982  1.111    mjacob 		case RQSTYPE_T2RQS:
   4983  1.111    mjacob 		case RQSTYPE_T3RQS:
   4984  1.111    mjacob 		case RQSTYPE_T7RQS:
   4985   1.36    mjacob 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
   4986   1.36    mjacob 				/*
   4987   1.36    mjacob 				 * Force Queue Full status.
   4988   1.36    mjacob 				 */
   4989   1.57    mjacob 				*XS_STSP(xs) = SCSI_QFULL;
   4990   1.36    mjacob 				XS_SETERR(xs, HBA_NOERROR);
   4991   1.36    mjacob 			} else if (XS_NOERR(xs)) {
   4992   1.84    mjacob 				/*
   4993   1.84    mjacob 				 * ????
   4994   1.84    mjacob 				 */
   4995  1.111    mjacob 				XS_SETERR(xs, HBA_BOTCH);
   4996   1.84    mjacob 				isp_prt(isp, ISP_LOGDEBUG0,
   4997   1.84    mjacob 				    "Request Queue Entry bounced back");
   4998  1.111    mjacob 				if ((isp->isp_dblev & ISP_LOGDEBUG1) == 0) {
   4999  1.111    mjacob 					isp_print_bytes(isp, "Bounced Request",
   5000  1.111    mjacob 					    QENTRY_LEN, qe);
   5001  1.111    mjacob 				}
   5002   1.36    mjacob 			}
   5003   1.61    mjacob 			XS_RESID(xs) = XS_XFRLEN(xs);
   5004   1.61    mjacob 			break;
   5005   1.61    mjacob 		default:
   5006  1.111    mjacob 			isp_print_bytes(isp, "Unhandled Response Type",
   5007  1.111    mjacob 			    QENTRY_LEN, qe);
   5008   1.30    mjacob 			if (XS_NOERR(xs)) {
   5009   1.23    mjacob 				XS_SETERR(xs, HBA_BOTCH);
   5010   1.30    mjacob 			}
   5011   1.61    mjacob 			break;
   5012    1.1       cgd 		}
   5013   1.61    mjacob 
   5014   1.61    mjacob 		/*
   5015  1.102       wiz 		 * Free any DMA resources. As a side effect, this may
   5016  1.113    mjacob 		 * also do any cache flushing necessary for data coherence.
   5017  1.113    mjacob 		 */
   5018   1.23    mjacob 		if (XS_XFRLEN(xs)) {
   5019   1.38    mjacob 			ISP_DMAFREE(isp, xs, sp->req_handle);
   5020    1.1       cgd 		}
   5021   1.61    mjacob 
   5022   1.57    mjacob 		if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
   5023  1.113    mjacob 		    ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) ||
   5024   1.70    mjacob 		    (*XS_STSP(xs) != SCSI_GOOD)))) {
   5025   1.57    mjacob 			char skey;
   5026  1.111    mjacob 			if (req_state_flags & RQSF_GOT_SENSE) {
   5027   1.57    mjacob 				skey = XS_SNSKEY(xs) & 0xf;
   5028   1.57    mjacob 				if (skey < 10)
   5029   1.57    mjacob 					skey += '0';
   5030   1.57    mjacob 				else
   5031   1.70    mjacob 					skey += 'a' - 10;
   5032   1.57    mjacob 			} else if (*XS_STSP(xs) == SCSI_CHECK) {
   5033   1.57    mjacob 				skey = '?';
   5034   1.57    mjacob 			} else {
   5035   1.57    mjacob 				skey = '.';
   5036    1.1       cgd 			}
   5037   1.57    mjacob 			isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs),
   5038   1.57    mjacob 			    XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs),
   5039   1.57    mjacob 			    *XS_STSP(xs), skey, XS_ERR(xs));
   5040    1.1       cgd 		}
   5041   1.23    mjacob 
   5042   1.28    mjacob 		if (isp->isp_nactive > 0)
   5043   1.28    mjacob 		    isp->isp_nactive--;
   5044   1.25    mjacob 		complist[ndone++] = xs;	/* defer completion call until later */
   5045   1.86    mjacob 		MEMZERO(hp, QENTRY_LEN);	/* PERF */
   5046   1.57    mjacob 		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
   5047   1.57    mjacob 			break;
   5048   1.57    mjacob 		}
   5049    1.1       cgd 	}
   5050   1.32    mjacob 
   5051   1.27    mjacob 	/*
   5052   1.32    mjacob 	 * If we looked at any commands, then it's valid to find out
   5053   1.32    mjacob 	 * what the outpointer is. It also is a trigger to update the
   5054   1.32    mjacob 	 * ISP's notion of what we've seen so far.
   5055   1.27    mjacob 	 */
   5056   1.33    mjacob 	if (nlooked) {
   5057  1.111    mjacob 		ISP_WRITE(isp, isp->isp_respoutrp, optr);
   5058   1.79    mjacob 		/*
   5059  1.111    mjacob 		 * While we're at it, read the requst queue out pointer.
   5060   1.79    mjacob 		 */
   5061  1.111    mjacob 		isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
   5062  1.111    mjacob 		if (isp->isp_rscchiwater < ndone) {
   5063   1.87    mjacob 			isp->isp_rscchiwater = ndone;
   5064  1.111    mjacob 		}
   5065  1.111    mjacob 	}
   5066  1.111    mjacob 
   5067  1.111    mjacob out:
   5068  1.111    mjacob 
   5069  1.111    mjacob 	if (IS_24XX(isp)) {
   5070  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
   5071  1.111    mjacob 	} else {
   5072  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
   5073  1.111    mjacob 		ISP_WRITE(isp, BIU_SEMA, 0);
   5074   1.27    mjacob 	}
   5075   1.54    mjacob 
   5076    1.1       cgd 	isp->isp_residx = optr;
   5077   1.90    mjacob 	isp->isp_rspbsy = 0;
   5078   1.25    mjacob 	for (i = 0; i < ndone; i++) {
   5079   1.25    mjacob 		xs = complist[i];
   5080   1.25    mjacob 		if (xs) {
   5081   1.87    mjacob 			isp->isp_rsltccmplt++;
   5082   1.57    mjacob 			isp_done(xs);
   5083   1.25    mjacob 		}
   5084   1.25    mjacob 	}
   5085    1.1       cgd }
   5086    1.1       cgd 
   5087    1.1       cgd /*
   5088    1.1       cgd  * Support routines.
   5089    1.1       cgd  */
   5090    1.1       cgd 
   5091   1.25    mjacob static int
   5092  1.111    mjacob isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
   5093   1.25    mjacob {
   5094   1.94    mjacob 	int rval = 0;
   5095   1.43    mjacob 	int bus;
   5096   1.31    mjacob 
   5097   1.44    mjacob 	if (IS_DUALBUS(isp)) {
   5098   1.43    mjacob 		bus = ISP_READ(isp, OUTMAILBOX6);
   5099   1.43    mjacob 	} else {
   5100   1.43    mjacob 		bus = 0;
   5101   1.43    mjacob 	}
   5102   1.87    mjacob 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
   5103   1.43    mjacob 
   5104   1.25    mjacob 	switch (mbox) {
   5105   1.25    mjacob 	case ASYNC_BUS_RESET:
   5106   1.52        he 		isp->isp_sendmarker |= (1 << bus);
   5107   1.29    mjacob #ifdef	ISP_TARGET_MODE
   5108  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5109   1.94    mjacob 			rval = -1;
   5110  1.111    mjacob 		}
   5111   1.29    mjacob #endif
   5112   1.43    mjacob 		isp_async(isp, ISPASYNC_BUS_RESET, &bus);
   5113   1.25    mjacob 		break;
   5114   1.25    mjacob 	case ASYNC_SYSTEM_ERROR:
   5115  1.111    mjacob 		isp->isp_state = ISP_CRASHED;
   5116  1.111    mjacob 		if (IS_FC(isp)) {
   5117  1.111    mjacob 			FCPARAM(isp)->isp_loopstate = LOOP_NIL;
   5118  1.111    mjacob 			FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5119  1.111    mjacob 		}
   5120  1.111    mjacob 		/*
   5121  1.111    mjacob 		 * Were we waiting for a mailbox command to complete?
   5122  1.111    mjacob 		 * If so, it's dead, so wake up the waiter.
   5123  1.111    mjacob 		 */
   5124  1.111    mjacob 		if (isp->isp_mboxbsy) {
   5125  1.111    mjacob 			isp->isp_obits = 1;
   5126  1.111    mjacob 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
   5127  1.111    mjacob 			MBOX_NOTIFY_COMPLETE(isp);
   5128  1.111    mjacob 		}
   5129   1.96    mjacob 		/*
   5130  1.111    mjacob 		 * It's up to the handler for isp_async to reinit stuff and
   5131  1.111    mjacob 		 * restart the firmware
   5132   1.96    mjacob 		 */
   5133   1.96    mjacob 		isp_async(isp, ISPASYNC_FW_CRASH, NULL);
   5134   1.94    mjacob 		rval = -1;
   5135   1.94    mjacob 		break;
   5136   1.25    mjacob 
   5137   1.25    mjacob 	case ASYNC_RQS_XFER_ERR:
   5138   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
   5139   1.25    mjacob 		break;
   5140   1.25    mjacob 
   5141   1.25    mjacob 	case ASYNC_RSP_XFER_ERR:
   5142   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
   5143   1.25    mjacob 		break;
   5144   1.25    mjacob 
   5145   1.25    mjacob 	case ASYNC_QWAKEUP:
   5146   1.43    mjacob 		/*
   5147   1.43    mjacob 		 * We've just been notified that the Queue has woken up.
   5148   1.43    mjacob 		 * We don't need to be chatty about this- just unlatch things
   5149   1.43    mjacob 		 * and move on.
   5150   1.43    mjacob 		 */
   5151  1.111    mjacob 		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
   5152   1.25    mjacob 		break;
   5153   1.25    mjacob 
   5154   1.25    mjacob 	case ASYNC_TIMEOUT_RESET:
   5155   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN,
   5156   1.73    mjacob 		    "timeout initiated SCSI bus reset of bus %d", bus);
   5157   1.52        he 		isp->isp_sendmarker |= (1 << bus);
   5158   1.29    mjacob #ifdef	ISP_TARGET_MODE
   5159  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5160   1.94    mjacob 			rval = -1;
   5161  1.111    mjacob 		}
   5162   1.29    mjacob #endif
   5163   1.25    mjacob 		break;
   5164   1.25    mjacob 
   5165   1.28    mjacob 	case ASYNC_DEVICE_RESET:
   5166   1.57    mjacob 		isp_prt(isp, ISP_LOGINFO, "device reset on bus %d", bus);
   5167   1.52        he 		isp->isp_sendmarker |= (1 << bus);
   5168   1.29    mjacob #ifdef	ISP_TARGET_MODE
   5169  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5170   1.94    mjacob 			rval = -1;
   5171  1.111    mjacob 		}
   5172   1.29    mjacob #endif
   5173   1.25    mjacob 		break;
   5174   1.25    mjacob 
   5175   1.25    mjacob 	case ASYNC_EXTMSG_UNDERRUN:
   5176   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
   5177   1.25    mjacob 		break;
   5178   1.25    mjacob 
   5179   1.25    mjacob 	case ASYNC_SCAM_INT:
   5180   1.57    mjacob 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
   5181   1.25    mjacob 		break;
   5182   1.25    mjacob 
   5183   1.25    mjacob 	case ASYNC_HUNG_SCSI:
   5184   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5185   1.57    mjacob 		    "stalled SCSI Bus after DATA Overrun");
   5186   1.25    mjacob 		/* XXX: Need to issue SCSI reset at this point */
   5187   1.25    mjacob 		break;
   5188   1.25    mjacob 
   5189   1.25    mjacob 	case ASYNC_KILLED_BUS:
   5190   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
   5191   1.25    mjacob 		break;
   5192   1.25    mjacob 
   5193   1.25    mjacob 	case ASYNC_BUS_TRANSIT:
   5194   1.34    mjacob 		mbox = ISP_READ(isp, OUTMAILBOX2);
   5195   1.34    mjacob 		switch (mbox & 0x1c00) {
   5196   1.34    mjacob 		case SXP_PINS_LVD_MODE:
   5197   1.57    mjacob 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
   5198   1.58    mjacob 			SDPARAM(isp)->isp_diffmode = 0;
   5199   1.58    mjacob 			SDPARAM(isp)->isp_ultramode = 0;
   5200   1.58    mjacob 			SDPARAM(isp)->isp_lvdmode = 1;
   5201   1.34    mjacob 			break;
   5202   1.34    mjacob 		case SXP_PINS_HVD_MODE:
   5203   1.57    mjacob 			isp_prt(isp, ISP_LOGINFO,
   5204   1.57    mjacob 			    "Transition to Differential mode");
   5205   1.58    mjacob 			SDPARAM(isp)->isp_diffmode = 1;
   5206   1.58    mjacob 			SDPARAM(isp)->isp_ultramode = 0;
   5207   1.58    mjacob 			SDPARAM(isp)->isp_lvdmode = 0;
   5208   1.34    mjacob 			break;
   5209   1.34    mjacob 		case SXP_PINS_SE_MODE:
   5210   1.57    mjacob 			isp_prt(isp, ISP_LOGINFO,
   5211   1.57    mjacob 			    "Transition to Single Ended mode");
   5212   1.58    mjacob 			SDPARAM(isp)->isp_diffmode = 0;
   5213   1.58    mjacob 			SDPARAM(isp)->isp_ultramode = 1;
   5214   1.58    mjacob 			SDPARAM(isp)->isp_lvdmode = 0;
   5215   1.34    mjacob 			break;
   5216   1.34    mjacob 		default:
   5217   1.57    mjacob 			isp_prt(isp, ISP_LOGWARN,
   5218   1.57    mjacob 			    "Transition to Unknown Mode 0x%x", mbox);
   5219   1.34    mjacob 			break;
   5220   1.34    mjacob 		}
   5221   1.34    mjacob 		/*
   5222   1.34    mjacob 		 * XXX: Set up to renegotiate again!
   5223   1.34    mjacob 		 */
   5224   1.36    mjacob 		/* Can only be for a 1080... */
   5225   1.52        he 		isp->isp_sendmarker |= (1 << bus);
   5226   1.25    mjacob 		break;
   5227   1.25    mjacob 
   5228   1.87    mjacob 	/*
   5229   1.87    mjacob 	 * We can use bus, which will always be zero for FC cards,
   5230   1.87    mjacob 	 * as a mailbox pattern accumulator to be checked below.
   5231   1.87    mjacob 	 */
   5232   1.87    mjacob 	case ASYNC_RIO5:
   5233   1.87    mjacob 		bus = 0x1ce;	/* outgoing mailbox regs 1-3, 6-7 */
   5234   1.87    mjacob 		break;
   5235   1.87    mjacob 
   5236   1.87    mjacob 	case ASYNC_RIO4:
   5237   1.87    mjacob 		bus = 0x14e;	/* outgoing mailbox regs 1-3, 6 */
   5238   1.87    mjacob 		break;
   5239   1.87    mjacob 
   5240   1.87    mjacob 	case ASYNC_RIO3:
   5241   1.87    mjacob 		bus = 0x10e;	/* outgoing mailbox regs 1-3 */
   5242   1.87    mjacob 		break;
   5243   1.87    mjacob 
   5244   1.87    mjacob 	case ASYNC_RIO2:
   5245   1.87    mjacob 		bus = 0x106;	/* outgoing mailbox regs 1-2 */
   5246   1.87    mjacob 		break;
   5247   1.87    mjacob 
   5248   1.87    mjacob 	case ASYNC_RIO1:
   5249   1.25    mjacob 	case ASYNC_CMD_CMPLT:
   5250   1.87    mjacob 		bus = 0x102;	/* outgoing mailbox regs 1 */
   5251   1.87    mjacob 		break;
   5252   1.87    mjacob 
   5253   1.87    mjacob 	case ASYNC_RIO_RESP:
   5254   1.97    mjacob 		return (rval);
   5255   1.25    mjacob 
   5256   1.25    mjacob 	case ASYNC_CTIO_DONE:
   5257   1.94    mjacob 	{
   5258   1.58    mjacob #ifdef	ISP_TARGET_MODE
   5259   1.94    mjacob 		int handle =
   5260  1.111    mjacob 		    (ISP_READ(isp, OUTMAILBOX2) << 16) |
   5261   1.94    mjacob 		    (ISP_READ(isp, OUTMAILBOX1));
   5262  1.111    mjacob 		if (isp_target_async(isp, handle, mbox)) {
   5263   1.94    mjacob 			rval = -1;
   5264  1.111    mjacob 		} else {
   5265  1.111    mjacob 			/* count it as a fast posting intr */
   5266  1.111    mjacob 			isp->isp_fphccmplt++;
   5267  1.111    mjacob 		}
   5268   1.58    mjacob #else
   5269   1.58    mjacob 		isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
   5270  1.111    mjacob 		isp->isp_fphccmplt++;	/* count it as a fast posting intr */
   5271   1.58    mjacob #endif
   5272   1.94    mjacob 		break;
   5273   1.94    mjacob 	}
   5274  1.111    mjacob 	case ASYNC_LIP_ERROR:
   5275   1.79    mjacob 	case ASYNC_LIP_F8:
   5276   1.25    mjacob 	case ASYNC_LIP_OCCURRED:
   5277   1.60    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5278   1.60    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
   5279   1.33    mjacob 		isp->isp_sendmarker = 1;
   5280  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5281   1.77    mjacob 		isp_async(isp, ISPASYNC_LIP, NULL);
   5282   1.46    mjacob #ifdef	ISP_TARGET_MODE
   5283  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5284   1.94    mjacob 			rval = -1;
   5285  1.111    mjacob 		}
   5286   1.46    mjacob #endif
   5287   1.78    mjacob 		/*
   5288  1.111    mjacob 		 * We've had problems with data corruption occuring on
   5289   1.78    mjacob 		 * commands that complete (with no apparent error) after
   5290   1.78    mjacob 		 * we receive a LIP. This has been observed mostly on
   5291   1.78    mjacob 		 * Local Loop topologies. To be safe, let's just mark
   5292   1.78    mjacob 		 * all active commands as dead.
   5293   1.78    mjacob 		 */
   5294   1.78    mjacob 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
   5295   1.78    mjacob 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
   5296   1.78    mjacob 			int i, j;
   5297   1.78    mjacob 			for (i = j = 0; i < isp->isp_maxcmds; i++) {
   5298   1.78    mjacob 				XS_T *xs;
   5299   1.78    mjacob 				xs = isp->isp_xflist[i];
   5300   1.78    mjacob 				if (xs != NULL) {
   5301   1.78    mjacob 					j++;
   5302   1.78    mjacob 					XS_SETERR(xs, HBA_BUSRESET);
   5303   1.78    mjacob 				}
   5304   1.78    mjacob 			}
   5305   1.78    mjacob 			if (j) {
   5306   1.78    mjacob 				isp_prt(isp, ISP_LOGERR,
   5307   1.78    mjacob 				    "LIP destroyed %d active commands", j);
   5308   1.78    mjacob 			}
   5309   1.78    mjacob 		}
   5310   1.25    mjacob 		break;
   5311   1.25    mjacob 
   5312   1.25    mjacob 	case ASYNC_LOOP_UP:
   5313   1.37    mjacob 		isp->isp_sendmarker = 1;
   5314   1.60    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5315   1.60    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
   5316  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5317   1.32    mjacob 		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
   5318   1.46    mjacob #ifdef	ISP_TARGET_MODE
   5319  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5320   1.94    mjacob 			rval = -1;
   5321  1.111    mjacob 		}
   5322   1.46    mjacob #endif
   5323   1.25    mjacob 		break;
   5324   1.25    mjacob 
   5325   1.25    mjacob 	case ASYNC_LOOP_DOWN:
   5326   1.37    mjacob 		isp->isp_sendmarker = 1;
   5327   1.60    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5328   1.60    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
   5329  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5330   1.32    mjacob 		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
   5331   1.46    mjacob #ifdef	ISP_TARGET_MODE
   5332  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5333   1.94    mjacob 			rval = -1;
   5334  1.111    mjacob 		}
   5335   1.46    mjacob #endif
   5336   1.25    mjacob 		break;
   5337   1.25    mjacob 
   5338   1.25    mjacob 	case ASYNC_LOOP_RESET:
   5339   1.52        he 		isp->isp_sendmarker = 1;
   5340   1.60    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5341   1.60    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
   5342  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5343   1.77    mjacob 		isp_async(isp, ISPASYNC_LOOP_RESET, NULL);
   5344   1.29    mjacob #ifdef	ISP_TARGET_MODE
   5345  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5346   1.94    mjacob 			rval = -1;
   5347  1.111    mjacob 		}
   5348   1.29    mjacob #endif
   5349   1.25    mjacob 		break;
   5350   1.25    mjacob 
   5351   1.25    mjacob 	case ASYNC_PDB_CHANGED:
   5352   1.33    mjacob 		isp->isp_sendmarker = 1;
   5353   1.60    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
   5354  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5355   1.70    mjacob 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_PDB);
   5356   1.25    mjacob 		break;
   5357   1.25    mjacob 
   5358   1.25    mjacob 	case ASYNC_CHANGE_NOTIFY:
   5359  1.111    mjacob 	    	if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
   5360  1.111    mjacob 			FCPARAM(isp)->isp_loopstate = LOOP_LSCAN_DONE;
   5361  1.111    mjacob 		} else {
   5362  1.111    mjacob 			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
   5363  1.111    mjacob 		}
   5364  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5365   1.70    mjacob 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_SNS);
   5366   1.25    mjacob 		break;
   5367   1.25    mjacob 
   5368   1.49    mjacob 	case ASYNC_PTPMODE:
   5369  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5370   1.52        he 		isp->isp_sendmarker = 1;
   5371   1.60    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5372   1.60    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
   5373   1.70    mjacob 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
   5374   1.52        he #ifdef	ISP_TARGET_MODE
   5375  1.111    mjacob 		if (isp_target_async(isp, bus, mbox)) {
   5376   1.94    mjacob 			rval = -1;
   5377  1.111    mjacob 		}
   5378   1.52        he #endif
   5379   1.57    mjacob 		isp_prt(isp, ISP_LOGINFO, "Point-to-Point mode");
   5380   1.49    mjacob 		break;
   5381   1.49    mjacob 
   5382   1.49    mjacob 	case ASYNC_CONNMODE:
   5383   1.49    mjacob 		mbox = ISP_READ(isp, OUTMAILBOX1);
   5384  1.111    mjacob 		ISP_MARK_PORTDB(isp, 1);
   5385   1.49    mjacob 		switch (mbox) {
   5386   1.49    mjacob 		case ISP_CONN_LOOP:
   5387   1.70    mjacob 			isp_prt(isp, ISP_LOGINFO,
   5388   1.70    mjacob 			    "Point-to-Point -> Loop mode");
   5389   1.49    mjacob 			break;
   5390   1.49    mjacob 		case ISP_CONN_PTP:
   5391   1.70    mjacob 			isp_prt(isp, ISP_LOGINFO,
   5392   1.70    mjacob 			    "Loop -> Point-to-Point mode");
   5393   1.49    mjacob 			break;
   5394   1.49    mjacob 		case ISP_CONN_BADLIP:
   5395   1.57    mjacob 			isp_prt(isp, ISP_LOGWARN,
   5396   1.70    mjacob 			    "Point-to-Point -> Loop mode (BAD LIP)");
   5397   1.49    mjacob 			break;
   5398   1.49    mjacob 		case ISP_CONN_FATAL:
   5399   1.57    mjacob 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
   5400   1.95    mjacob 			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
   5401   1.49    mjacob 			return (-1);
   5402   1.49    mjacob 		case ISP_CONN_LOOPBACK:
   5403   1.57    mjacob 			isp_prt(isp, ISP_LOGWARN,
   5404   1.57    mjacob 			    "Looped Back in Point-to-Point mode");
   5405   1.70    mjacob 			break;
   5406   1.70    mjacob 		default:
   5407   1.70    mjacob 			isp_prt(isp, ISP_LOGWARN,
   5408   1.70    mjacob 			    "Unknown connection mode (0x%x)", mbox);
   5409   1.70    mjacob 			break;
   5410   1.49    mjacob 		}
   5411   1.70    mjacob 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, ISPASYNC_CHANGE_OTHER);
   5412   1.70    mjacob 		isp->isp_sendmarker = 1;
   5413   1.70    mjacob 		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
   5414   1.70    mjacob 		FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
   5415   1.49    mjacob 		break;
   5416   1.49    mjacob 
   5417  1.111    mjacob 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
   5418  1.111    mjacob 		if (IS_24XX(isp)) {
   5419  1.111    mjacob 			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
   5420  1.111    mjacob 			break;
   5421  1.111    mjacob 		} else if (IS_2200(isp)) {
   5422  1.111    mjacob 			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
   5423  1.111    mjacob 			break;
   5424  1.111    mjacob 		}
   5425  1.111    mjacob 		/* FALLTHROUGH */
   5426   1.25    mjacob 	default:
   5427   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
   5428   1.25    mjacob 		break;
   5429   1.25    mjacob 	}
   5430   1.87    mjacob 
   5431   1.87    mjacob 	if (bus & 0x100) {
   5432   1.87    mjacob 		int i, nh;
   5433  1.111    mjacob 		uint16_t handles[16];
   5434   1.87    mjacob 
   5435  1.111    mjacob 		for (nh = 0, i = 1; i < MAX_MAILBOX(isp); i++) {
   5436   1.87    mjacob 			if ((bus & (1 << i)) == 0) {
   5437   1.87    mjacob 				continue;
   5438   1.87    mjacob 			}
   5439   1.87    mjacob 			handles[nh++] = ISP_READ(isp, MBOX_OFF(i));
   5440   1.87    mjacob 		}
   5441   1.87    mjacob 		for (i = 0; i < nh; i++) {
   5442   1.87    mjacob 			isp_fastpost_complete(isp, handles[i]);
   5443   1.87    mjacob 			isp_prt(isp,  ISP_LOGDEBUG3,
   5444   1.87    mjacob 			    "fast post completion of %u", handles[i]);
   5445   1.87    mjacob 		}
   5446  1.111    mjacob 		if (isp->isp_fpcchiwater < nh) {
   5447   1.87    mjacob 			isp->isp_fpcchiwater = nh;
   5448  1.111    mjacob 		}
   5449   1.87    mjacob 	} else {
   5450   1.87    mjacob 		isp->isp_intoasync++;
   5451   1.87    mjacob 	}
   5452   1.94    mjacob 	return (rval);
   5453   1.25    mjacob }
   5454   1.25    mjacob 
   5455   1.43    mjacob /*
   5456   1.43    mjacob  * Handle other response entries. A pointer to the request queue output
   5457   1.43    mjacob  * index is here in case we want to eat several entries at once, although
   5458   1.43    mjacob  * this is not used currently.
   5459   1.43    mjacob  */
   5460   1.43    mjacob 
   5461   1.25    mjacob static int
   5462  1.111    mjacob isp_handle_other_response(ispsoftc_t *isp, int type,
   5463  1.111    mjacob     isphdr_t *hp, uint32_t *optrp)
   5464   1.25    mjacob {
   5465   1.86    mjacob 	switch (type) {
   5466   1.58    mjacob 	case RQSTYPE_STATUS_CONT:
   5467  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
   5468  1.111    mjacob 		return (1);
   5469  1.111    mjacob 	case RQSTYPE_MARKER:
   5470  1.111    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
   5471   1.90    mjacob 		return (1);
   5472   1.38    mjacob 	case RQSTYPE_ATIO:
   5473   1.46    mjacob 	case RQSTYPE_CTIO:
   5474   1.29    mjacob 	case RQSTYPE_ENABLE_LUN:
   5475   1.29    mjacob 	case RQSTYPE_MODIFY_LUN:
   5476   1.38    mjacob 	case RQSTYPE_NOTIFY:
   5477   1.38    mjacob 	case RQSTYPE_NOTIFY_ACK:
   5478   1.38    mjacob 	case RQSTYPE_CTIO1:
   5479   1.29    mjacob 	case RQSTYPE_ATIO2:
   5480   1.38    mjacob 	case RQSTYPE_CTIO2:
   5481   1.38    mjacob 	case RQSTYPE_CTIO3:
   5482  1.111    mjacob 	case RQSTYPE_CTIO7:
   5483  1.111    mjacob 	case RQSTYPE_ABTS_RCVD:
   5484  1.111    mjacob 	case RQSTYPE_ABTS_RSP:
   5485   1.88    mjacob 		isp->isp_rsltccmplt++;	/* count as a response completion */
   5486   1.38    mjacob #ifdef	ISP_TARGET_MODE
   5487   1.90    mjacob 		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
   5488   1.90    mjacob 			return (1);
   5489   1.90    mjacob 		}
   5490  1.101    mjacob #endif
   5491   1.38    mjacob 		/* FALLTHROUGH */
   5492   1.38    mjacob 	case RQSTYPE_REQUEST:
   5493   1.25    mjacob 	default:
   5494  1.111    mjacob 		USEC_DELAY(100);
   5495  1.111    mjacob 		if (type != isp_get_response_type(isp, hp)) {
   5496  1.111    mjacob 			/*
   5497  1.111    mjacob 			 * This is questionable- we're just papering over
   5498  1.111    mjacob 			 * something we've seen on SMP linux in target
   5499  1.111    mjacob 			 * mode- we don't really know what's happening
   5500  1.111    mjacob 			 * here that causes us to think we've gotten
   5501  1.111    mjacob 			 * an entry, but that either the entry isn't
   5502  1.111    mjacob 			 * filled out yet or our CPU read data is stale.
   5503  1.111    mjacob 			 */
   5504  1.111    mjacob 			isp_prt(isp, ISP_LOGINFO,
   5505  1.111    mjacob 				"unstable type in response queue");
   5506  1.111    mjacob 			return (-1);
   5507  1.111    mjacob 		}
   5508  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
   5509  1.111    mjacob 		    isp_get_response_type(isp, hp));
   5510   1.86    mjacob 		if (isp_async(isp, ISPASYNC_UNHANDLED_RESPONSE, hp)) {
   5511   1.90    mjacob 			return (1);
   5512   1.71    mjacob 		}
   5513   1.90    mjacob 		return (0);
   5514   1.29    mjacob 	}
   5515   1.29    mjacob }
   5516   1.29    mjacob 
   5517   1.23    mjacob static void
   5518  1.111    mjacob isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
   5519    1.1       cgd {
   5520   1.57    mjacob 	switch (sp->req_completion_status & 0xff) {
   5521    1.1       cgd 	case RQCS_COMPLETE:
   5522   1.57    mjacob 		if (XS_NOERR(xs)) {
   5523   1.57    mjacob 			XS_SETERR(xs, HBA_NOERROR);
   5524   1.57    mjacob 		}
   5525   1.23    mjacob 		return;
   5526   1.10    mjacob 
   5527    1.1       cgd 	case RQCS_INCOMPLETE:
   5528    1.1       cgd 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
   5529   1.58    mjacob 			isp_prt(isp, ISP_LOGDEBUG1,
   5530   1.57    mjacob 			    "Selection Timeout for %d.%d.%d",
   5531   1.63    mjacob 			    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5532   1.57    mjacob 			if (XS_NOERR(xs)) {
   5533   1.57    mjacob 				XS_SETERR(xs, HBA_SELTIMEOUT);
   5534  1.111    mjacob 				*rp = XS_XFRLEN(xs);
   5535   1.57    mjacob 			}
   5536   1.23    mjacob 			return;
   5537    1.1       cgd 		}
   5538   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5539   1.57    mjacob 		    "command incomplete for %d.%d.%d, state 0x%x",
   5540   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
   5541   1.25    mjacob 		    sp->req_state_flags);
   5542   1.25    mjacob 		break;
   5543   1.25    mjacob 
   5544   1.25    mjacob 	case RQCS_DMA_ERROR:
   5545   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
   5546   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5547  1.111    mjacob 		*rp = XS_XFRLEN(xs);
   5548    1.1       cgd 		break;
   5549   1.15    mjacob 
   5550   1.15    mjacob 	case RQCS_TRANSPORT_ERROR:
   5551   1.57    mjacob 	{
   5552  1.111    mjacob 		char buf[172];
   5553  1.111    mjacob 		SNPRINTF(buf, sizeof (buf), "states=>");
   5554   1.57    mjacob 		if (sp->req_state_flags & RQSF_GOT_BUS) {
   5555  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
   5556   1.57    mjacob 		}
   5557   1.57    mjacob 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
   5558  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
   5559   1.57    mjacob 		}
   5560   1.57    mjacob 		if (sp->req_state_flags & RQSF_SENT_CDB) {
   5561  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
   5562   1.57    mjacob 		}
   5563   1.57    mjacob 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
   5564  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
   5565   1.57    mjacob 		}
   5566   1.57    mjacob 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
   5567  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
   5568   1.57    mjacob 		}
   5569   1.57    mjacob 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
   5570  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
   5571   1.57    mjacob 		}
   5572   1.57    mjacob 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
   5573  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
   5574   1.57    mjacob 		}
   5575  1.111    mjacob 		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
   5576   1.57    mjacob 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
   5577  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
   5578   1.57    mjacob 		}
   5579   1.57    mjacob 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
   5580  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
   5581   1.57    mjacob 		}
   5582   1.57    mjacob 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
   5583  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
   5584   1.57    mjacob 		}
   5585   1.57    mjacob 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
   5586  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
   5587   1.57    mjacob 		}
   5588   1.57    mjacob 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
   5589  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
   5590   1.57    mjacob 		}
   5591   1.57    mjacob 		if (sp->req_status_flags & RQSTF_ABORTED) {
   5592  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
   5593   1.57    mjacob 		}
   5594   1.57    mjacob 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
   5595  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
   5596   1.57    mjacob 		}
   5597   1.57    mjacob 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
   5598  1.111    mjacob 			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
   5599   1.57    mjacob 		}
   5600  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "%s", buf);
   5601   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
   5602  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), buf);
   5603  1.111    mjacob 		*rp = XS_XFRLEN(xs);
   5604   1.15    mjacob 		break;
   5605   1.57    mjacob 	}
   5606   1.25    mjacob 	case RQCS_RESET_OCCURRED:
   5607   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN,
   5608   1.57    mjacob 		    "bus reset destroyed command for %d.%d.%d",
   5609   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5610   1.51    mjacob 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
   5611   1.57    mjacob 		if (XS_NOERR(xs)) {
   5612   1.57    mjacob 			XS_SETERR(xs, HBA_BUSRESET);
   5613   1.57    mjacob 		}
   5614  1.111    mjacob 		*rp = XS_XFRLEN(xs);
   5615   1.25    mjacob 		return;
   5616   1.25    mjacob 
   5617   1.25    mjacob 	case RQCS_ABORTED:
   5618   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
   5619   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5620   1.51    mjacob 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
   5621   1.57    mjacob 		if (XS_NOERR(xs)) {
   5622   1.57    mjacob 			XS_SETERR(xs, HBA_ABORTED);
   5623   1.57    mjacob 		}
   5624   1.25    mjacob 		return;
   5625   1.25    mjacob 
   5626   1.25    mjacob 	case RQCS_TIMEOUT:
   5627   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
   5628   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5629   1.95    mjacob 		/*
   5630  1.111    mjacob 	 	 * XXX: Check to see if we logged out of the device.
   5631   1.95    mjacob 		 */
   5632   1.57    mjacob 		if (XS_NOERR(xs)) {
   5633   1.57    mjacob 			XS_SETERR(xs, HBA_CMDTIMEOUT);
   5634   1.57    mjacob 		}
   5635   1.25    mjacob 		return;
   5636   1.25    mjacob 
   5637   1.10    mjacob 	case RQCS_DATA_OVERRUN:
   5638   1.61    mjacob 		XS_RESID(xs) = sp->req_resid;
   5639   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
   5640   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5641   1.57    mjacob 		if (XS_NOERR(xs)) {
   5642   1.57    mjacob 			XS_SETERR(xs, HBA_DATAOVR);
   5643   1.57    mjacob 		}
   5644   1.23    mjacob 		return;
   5645   1.10    mjacob 
   5646   1.25    mjacob 	case RQCS_COMMAND_OVERRUN:
   5647   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5648   1.57    mjacob 		    "command overrun for command on %d.%d.%d",
   5649   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5650   1.25    mjacob 		break;
   5651   1.25    mjacob 
   5652   1.25    mjacob 	case RQCS_STATUS_OVERRUN:
   5653   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5654   1.57    mjacob 		    "status overrun for command on %d.%d.%d",
   5655   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5656   1.25    mjacob 		break;
   5657   1.25    mjacob 
   5658   1.25    mjacob 	case RQCS_BAD_MESSAGE:
   5659   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5660   1.57    mjacob 		    "msg not COMMAND COMPLETE after status %d.%d.%d",
   5661   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5662   1.25    mjacob 		break;
   5663   1.25    mjacob 
   5664   1.25    mjacob 	case RQCS_NO_MESSAGE_OUT:
   5665   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5666   1.57    mjacob 		    "No MESSAGE OUT phase after selection on %d.%d.%d",
   5667   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5668   1.25    mjacob 		break;
   5669   1.25    mjacob 
   5670   1.25    mjacob 	case RQCS_EXT_ID_FAILED:
   5671   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "EXTENDED IDENTIFY failed %d.%d.%d",
   5672   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5673   1.25    mjacob 		break;
   5674   1.25    mjacob 
   5675   1.25    mjacob 	case RQCS_IDE_MSG_FAILED:
   5676   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5677   1.57    mjacob 		    "INITIATOR DETECTED ERROR rejected by %d.%d.%d",
   5678   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5679   1.25    mjacob 		break;
   5680   1.25    mjacob 
   5681   1.25    mjacob 	case RQCS_ABORT_MSG_FAILED:
   5682   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "ABORT OPERATION rejected by %d.%d.%d",
   5683   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5684   1.25    mjacob 		break;
   5685   1.25    mjacob 
   5686   1.25    mjacob 	case RQCS_REJECT_MSG_FAILED:
   5687   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "MESSAGE REJECT rejected by %d.%d.%d",
   5688   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5689   1.25    mjacob 		break;
   5690   1.25    mjacob 
   5691   1.25    mjacob 	case RQCS_NOP_MSG_FAILED:
   5692   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "NOP rejected by %d.%d.%d",
   5693   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5694   1.25    mjacob 		break;
   5695   1.25    mjacob 
   5696   1.25    mjacob 	case RQCS_PARITY_ERROR_MSG_FAILED:
   5697   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5698   1.57    mjacob 		    "MESSAGE PARITY ERROR rejected by %d.%d.%d",
   5699   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5700   1.25    mjacob 		break;
   5701   1.25    mjacob 
   5702   1.25    mjacob 	case RQCS_DEVICE_RESET_MSG_FAILED:
   5703   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN,
   5704   1.57    mjacob 		    "BUS DEVICE RESET rejected by %d.%d.%d",
   5705   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5706   1.25    mjacob 		break;
   5707   1.25    mjacob 
   5708   1.25    mjacob 	case RQCS_ID_MSG_FAILED:
   5709   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "IDENTIFY rejected by %d.%d.%d",
   5710   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5711   1.25    mjacob 		break;
   5712   1.25    mjacob 
   5713   1.25    mjacob 	case RQCS_UNEXP_BUS_FREE:
   5714   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "%d.%d.%d had an unexpected bus free",
   5715   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5716   1.25    mjacob 		break;
   5717   1.25    mjacob 
   5718    1.1       cgd 	case RQCS_DATA_UNDERRUN:
   5719   1.94    mjacob 	{
   5720   1.94    mjacob 		if (IS_FC(isp)) {
   5721   1.94    mjacob 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
   5722   1.94    mjacob 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
   5723   1.94    mjacob 				isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
   5724   1.94    mjacob 				    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
   5725   1.94    mjacob 				    (ru_marked)? "marked" : "not marked");
   5726   1.94    mjacob 				if (XS_NOERR(xs)) {
   5727   1.94    mjacob 					XS_SETERR(xs, HBA_BOTCH);
   5728   1.94    mjacob 				}
   5729   1.94    mjacob 				return;
   5730   1.94    mjacob 			}
   5731   1.94    mjacob 		}
   5732   1.61    mjacob 		XS_RESID(xs) = sp->req_resid;
   5733   1.57    mjacob 		if (XS_NOERR(xs)) {
   5734   1.57    mjacob 			XS_SETERR(xs, HBA_NOERROR);
   5735   1.57    mjacob 		}
   5736   1.23    mjacob 		return;
   5737   1.94    mjacob 	}
   5738   1.10    mjacob 
   5739   1.25    mjacob 	case RQCS_XACT_ERR1:
   5740   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, xact1, XS_CHANNEL(xs),
   5741   1.51    mjacob 		    XS_TGT(xs), XS_LUN(xs));
   5742   1.25    mjacob 		break;
   5743   1.25    mjacob 
   5744   1.25    mjacob 	case RQCS_XACT_ERR2:
   5745   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, xact2,
   5746   1.51    mjacob 		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
   5747   1.25    mjacob 		break;
   5748   1.25    mjacob 
   5749   1.25    mjacob 	case RQCS_XACT_ERR3:
   5750   1.78    mjacob 		isp_prt(isp, ISP_LOGERR, xact3,
   5751   1.78    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5752   1.25    mjacob 		break;
   5753   1.25    mjacob 
   5754   1.25    mjacob 	case RQCS_BAD_ENTRY:
   5755   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
   5756   1.25    mjacob 		break;
   5757   1.25    mjacob 
   5758   1.25    mjacob 	case RQCS_QUEUE_FULL:
   5759   1.84    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   5760   1.94    mjacob 		    "internal queues full for %d.%d.%d status 0x%x",
   5761   1.94    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), *XS_STSP(xs));
   5762   1.84    mjacob 
   5763   1.30    mjacob 		/*
   5764   1.30    mjacob 		 * If QFULL or some other status byte is set, then this
   5765   1.30    mjacob 		 * isn't an error, per se.
   5766   1.84    mjacob 		 *
   5767   1.84    mjacob 		 * Unfortunately, some QLogic f/w writers have, in
   5768   1.84    mjacob 		 * some cases, ommitted to *set* status to QFULL.
   5769   1.84    mjacob 		 *
   5770   1.84    mjacob 
   5771   1.57    mjacob 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
   5772   1.30    mjacob 			XS_SETERR(xs, HBA_NOERROR);
   5773   1.30    mjacob 			return;
   5774   1.30    mjacob 		}
   5775   1.84    mjacob 
   5776   1.84    mjacob 		 *
   5777   1.84    mjacob 		 *
   5778   1.84    mjacob 		 */
   5779   1.84    mjacob 
   5780   1.84    mjacob 		*XS_STSP(xs) = SCSI_QFULL;
   5781   1.84    mjacob 		XS_SETERR(xs, HBA_NOERROR);
   5782   1.84    mjacob 		return;
   5783   1.25    mjacob 
   5784   1.25    mjacob 	case RQCS_PHASE_SKIPPED:
   5785   1.79    mjacob 		isp_prt(isp, ISP_LOGERR, pskip, XS_CHANNEL(xs),
   5786   1.79    mjacob 		    XS_TGT(xs), XS_LUN(xs));
   5787   1.25    mjacob 		break;
   5788   1.25    mjacob 
   5789   1.25    mjacob 	case RQCS_ARQS_FAILED:
   5790   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5791   1.57    mjacob 		    "Auto Request Sense failed for %d.%d.%d",
   5792   1.57    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5793   1.57    mjacob 		if (XS_NOERR(xs)) {
   5794   1.57    mjacob 			XS_SETERR(xs, HBA_ARQFAIL);
   5795   1.57    mjacob 		}
   5796   1.23    mjacob 		return;
   5797   1.10    mjacob 
   5798   1.25    mjacob 	case RQCS_WIDE_FAILED:
   5799   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5800   1.57    mjacob 		    "Wide Negotiation failed for %d.%d.%d",
   5801   1.57    mjacob 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
   5802   1.36    mjacob 		if (IS_SCSI(isp)) {
   5803   1.25    mjacob 			sdparam *sdp = isp->isp_param;
   5804   1.36    mjacob 			sdp += XS_CHANNEL(xs);
   5805   1.79    mjacob 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
   5806   1.25    mjacob 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
   5807   1.51    mjacob 			isp->isp_update |= (1 << XS_CHANNEL(xs));
   5808   1.25    mjacob 		}
   5809   1.57    mjacob 		if (XS_NOERR(xs)) {
   5810   1.57    mjacob 			XS_SETERR(xs, HBA_NOERROR);
   5811   1.57    mjacob 		}
   5812   1.23    mjacob 		return;
   5813   1.10    mjacob 
   5814   1.25    mjacob 	case RQCS_SYNCXFER_FAILED:
   5815   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5816   1.57    mjacob 		    "SDTR Message failed for target %d.%d.%d",
   5817   1.57    mjacob 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
   5818   1.36    mjacob 		if (IS_SCSI(isp)) {
   5819   1.25    mjacob 			sdparam *sdp = isp->isp_param;
   5820   1.36    mjacob 			sdp += XS_CHANNEL(xs);
   5821   1.79    mjacob 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
   5822   1.25    mjacob 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
   5823   1.51    mjacob 			isp->isp_update |= (1 << XS_CHANNEL(xs));
   5824   1.25    mjacob 		}
   5825   1.25    mjacob 		break;
   5826   1.25    mjacob 
   5827   1.25    mjacob 	case RQCS_LVD_BUSERR:
   5828   1.57    mjacob 		isp_prt(isp, ISP_LOGERR,
   5829   1.57    mjacob 		    "Bad LVD condition while talking to %d.%d.%d",
   5830   1.57    mjacob 		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
   5831   1.25    mjacob 		break;
   5832   1.10    mjacob 
   5833   1.10    mjacob 	case RQCS_PORT_UNAVAILABLE:
   5834   1.10    mjacob 		/*
   5835   1.10    mjacob 		 * No such port on the loop. Moral equivalent of SELTIMEO
   5836   1.10    mjacob 		 */
   5837   1.10    mjacob 	case RQCS_PORT_LOGGED_OUT:
   5838  1.111    mjacob 	{
   5839  1.111    mjacob 		const char *reason;
   5840  1.111    mjacob 		uint8_t sts = sp->req_completion_status & 0xff;
   5841  1.111    mjacob 
   5842   1.27    mjacob 		/*
   5843   1.27    mjacob 		 * It was there (maybe)- treat as a selection timeout.
   5844   1.27    mjacob 		 */
   5845  1.111    mjacob 		if (sts == RQCS_PORT_UNAVAILABLE) {
   5846  1.111    mjacob 			reason = "unavailable";
   5847  1.111    mjacob 		} else {
   5848  1.111    mjacob 			reason = "logout";
   5849  1.111    mjacob 		}
   5850  1.111    mjacob 
   5851  1.111    mjacob 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
   5852  1.111    mjacob 		    reason, XS_TGT(xs));
   5853  1.111    mjacob 
   5854   1.88    mjacob 		/*
   5855   1.88    mjacob 		 * If we're on a local loop, force a LIP (which is overkill)
   5856   1.94    mjacob 		 * to force a re-login of this unit. If we're on fabric,
   5857  1.111    mjacob 		 * then we'll have to log in again as a matter of course.
   5858   1.88    mjacob 		 */
   5859   1.88    mjacob 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
   5860   1.88    mjacob 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
   5861   1.88    mjacob 			mbreg_t mbs;
   5862  1.111    mjacob 			MEMZERO(&mbs, sizeof (mbs));
   5863   1.88    mjacob 			mbs.param[0] = MBOX_INIT_LIP;
   5864  1.111    mjacob 			if (FCPARAM(isp)->isp_2klogin) {
   5865  1.111    mjacob 				mbs.ibits = (1 << 10);
   5866  1.111    mjacob 			}
   5867  1.111    mjacob 			mbs.logval = MBLOGALL;
   5868   1.88    mjacob 			isp_mboxcmd_qnw(isp, &mbs, 1);
   5869   1.88    mjacob 		}
   5870  1.111    mjacob 		if (XS_NOERR(xs)) {
   5871  1.111    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   5872  1.111    mjacob 		}
   5873  1.111    mjacob 		return;
   5874  1.111    mjacob 	}
   5875  1.111    mjacob 	case RQCS_PORT_CHANGED:
   5876  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN,
   5877  1.111    mjacob 		    "port changed for target %d", XS_TGT(xs));
   5878  1.111    mjacob 		if (XS_NOERR(xs)) {
   5879  1.111    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   5880  1.111    mjacob 		}
   5881  1.111    mjacob 		return;
   5882  1.111    mjacob 
   5883  1.111    mjacob 	case RQCS_PORT_BUSY:
   5884  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN,
   5885  1.111    mjacob 		    "port busy for target %d", XS_TGT(xs));
   5886  1.111    mjacob 		if (XS_NOERR(xs)) {
   5887  1.111    mjacob 			XS_SETERR(xs, HBA_TGTBSY);
   5888  1.111    mjacob 		}
   5889  1.111    mjacob 		return;
   5890  1.111    mjacob 
   5891  1.111    mjacob 	default:
   5892  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
   5893  1.111    mjacob 		    sp->req_completion_status);
   5894  1.111    mjacob 		break;
   5895  1.111    mjacob 	}
   5896  1.111    mjacob 	if (XS_NOERR(xs)) {
   5897  1.111    mjacob 		XS_SETERR(xs, HBA_BOTCH);
   5898  1.111    mjacob 	}
   5899  1.111    mjacob }
   5900  1.111    mjacob 
   5901  1.111    mjacob static void
   5902  1.111    mjacob isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp,
   5903  1.111    mjacob     XS_T *xs, long *rp)
   5904  1.111    mjacob {
   5905  1.113    mjacob 	int ru_marked, sv_marked;
   5906  1.111    mjacob 	switch (sp->req_completion_status) {
   5907  1.111    mjacob 	case RQCS_COMPLETE:
   5908  1.111    mjacob 		if (XS_NOERR(xs)) {
   5909  1.111    mjacob 			XS_SETERR(xs, HBA_NOERROR);
   5910  1.111    mjacob 		}
   5911  1.111    mjacob 		return;
   5912  1.111    mjacob 
   5913  1.111    mjacob 	case RQCS_DMA_ERROR:
   5914  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "DMA error for command on %d.%d.%d",
   5915  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5916  1.111    mjacob 		break;
   5917  1.111    mjacob 
   5918  1.111    mjacob 	case RQCS_TRANSPORT_ERROR:
   5919  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d",
   5920  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5921  1.111    mjacob 		break;
   5922  1.111    mjacob 
   5923  1.111    mjacob 	case RQCS_RESET_OCCURRED:
   5924  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN,
   5925  1.111    mjacob 		    "bus reset destroyed command for %d.%d.%d",
   5926  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5927  1.111    mjacob 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
   5928  1.111    mjacob 		if (XS_NOERR(xs)) {
   5929  1.111    mjacob 			XS_SETERR(xs, HBA_BUSRESET);
   5930  1.111    mjacob 		}
   5931  1.111    mjacob 		return;
   5932  1.111    mjacob 
   5933  1.111    mjacob 	case RQCS_ABORTED:
   5934  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "command aborted for %d.%d.%d",
   5935  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5936  1.111    mjacob 		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
   5937  1.111    mjacob 		if (XS_NOERR(xs)) {
   5938  1.111    mjacob 			XS_SETERR(xs, HBA_ABORTED);
   5939  1.111    mjacob 		}
   5940  1.111    mjacob 		return;
   5941  1.111    mjacob 
   5942  1.111    mjacob 	case RQCS_TIMEOUT:
   5943  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "command timed out for %d.%d.%d",
   5944  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5945  1.111    mjacob 		if (XS_NOERR(xs)) {
   5946  1.111    mjacob 			XS_SETERR(xs, HBA_CMDTIMEOUT);
   5947  1.111    mjacob 		}
   5948  1.111    mjacob 		return;
   5949  1.111    mjacob 
   5950  1.111    mjacob 	case RQCS_DATA_OVERRUN:
   5951  1.111    mjacob 		XS_RESID(xs) = sp->req_resid;
   5952  1.113    mjacob 		isp_prt(isp, ISP_LOGERR,
   5953  1.113    mjacob 		    "data overrun for command on %d.%d.%d",
   5954  1.111    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
   5955  1.111    mjacob 		if (XS_NOERR(xs)) {
   5956  1.111    mjacob 			XS_SETERR(xs, HBA_DATAOVR);
   5957  1.111    mjacob 		}
   5958  1.111    mjacob 		return;
   5959  1.111    mjacob 
   5960  1.111    mjacob 	case RQCS_24XX_DRE:	/* data reassembly error */
   5961  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "data reassembly error for target %d",
   5962  1.111    mjacob 		    XS_TGT(xs));
   5963  1.111    mjacob 		if (XS_NOERR(xs)) {
   5964  1.111    mjacob 			XS_SETERR(xs, HBA_ABORTED);
   5965  1.111    mjacob 		}
   5966  1.111    mjacob 		*rp = XS_XFRLEN(xs);
   5967  1.111    mjacob 		return;
   5968  1.111    mjacob 
   5969  1.111    mjacob 	case RQCS_24XX_TABORT:	/* aborted by target */
   5970  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "target %d sent ABTS",
   5971  1.111    mjacob 		    XS_TGT(xs));
   5972  1.111    mjacob 		if (XS_NOERR(xs)) {
   5973  1.111    mjacob 			XS_SETERR(xs, HBA_ABORTED);
   5974  1.111    mjacob 		}
   5975  1.111    mjacob 		return;
   5976  1.111    mjacob 
   5977  1.111    mjacob 	case RQCS_DATA_UNDERRUN:
   5978  1.113    mjacob 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
   5979  1.113    mjacob 		/*
   5980  1.113    mjacob 		 * We can get an underrun w/o things being marked
   5981  1.113    mjacob 		 * if we got a non-zero status.
   5982  1.113    mjacob 		 */
   5983  1.113    mjacob 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
   5984  1.113    mjacob 		if ((ru_marked == 0 && sv_marked == 0) ||
   5985  1.113    mjacob 		    (sp->req_resid > XS_XFRLEN(xs))) {
   5986  1.113    mjacob 			isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs),
   5987  1.113    mjacob 			    XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid,
   5988  1.113    mjacob 			    (ru_marked)? "marked" : "not marked");
   5989  1.113    mjacob 			if (XS_NOERR(xs)) {
   5990  1.113    mjacob 				XS_SETERR(xs, HBA_BOTCH);
   5991  1.113    mjacob 			}
   5992  1.113    mjacob 			return;
   5993  1.113    mjacob 		}
   5994  1.111    mjacob 		XS_RESID(xs) = sp->req_resid;
   5995  1.113    mjacob 		isp_prt(isp, ISP_LOGDEBUG0,
   5996  1.113    mjacob 		    "%d.%d.%d data underrun (%d) for command 0x%x",
   5997  1.113    mjacob 		    XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
   5998  1.113    mjacob 		    sp->req_resid, XS_CDBP(xs)[0] & 0xff);
   5999  1.111    mjacob 		if (XS_NOERR(xs)) {
   6000  1.111    mjacob 			XS_SETERR(xs, HBA_NOERROR);
   6001  1.111    mjacob 		}
   6002  1.111    mjacob 		return;
   6003  1.111    mjacob 
   6004  1.111    mjacob 	case RQCS_PORT_UNAVAILABLE:
   6005  1.111    mjacob 		/*
   6006  1.111    mjacob 		 * No such port on the loop. Moral equivalent of SELTIMEO
   6007  1.111    mjacob 		 */
   6008  1.111    mjacob 	case RQCS_PORT_LOGGED_OUT:
   6009  1.111    mjacob 	{
   6010  1.111    mjacob 		const char *reason;
   6011  1.111    mjacob 		uint8_t sts = sp->req_completion_status & 0xff;
   6012  1.111    mjacob 
   6013  1.111    mjacob 		/*
   6014  1.111    mjacob 		 * It was there (maybe)- treat as a selection timeout.
   6015  1.111    mjacob 		 */
   6016  1.111    mjacob 		if (sts == RQCS_PORT_UNAVAILABLE) {
   6017  1.111    mjacob 			reason = "unavailable";
   6018  1.111    mjacob 		} else {
   6019  1.111    mjacob 			reason = "logout";
   6020  1.111    mjacob 		}
   6021  1.111    mjacob 
   6022  1.111    mjacob 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
   6023  1.111    mjacob 		    reason, XS_TGT(xs));
   6024   1.88    mjacob 
   6025   1.88    mjacob 		/*
   6026  1.111    mjacob 		 * If we're on a local loop, force a LIP (which is overkill)
   6027  1.111    mjacob 		 * to force a re-login of this unit. If we're on fabric,
   6028  1.111    mjacob 		 * then we'll have to log in again as a matter of course.
   6029   1.88    mjacob 		 */
   6030  1.111    mjacob 		if (FCPARAM(isp)->isp_topo == TOPO_NL_PORT ||
   6031  1.111    mjacob 		    FCPARAM(isp)->isp_topo == TOPO_FL_PORT) {
   6032  1.111    mjacob 			mbreg_t mbs;
   6033  1.111    mjacob 			MEMZERO(&mbs, sizeof (mbs));
   6034  1.111    mjacob 			mbs.param[0] = MBOX_INIT_LIP;
   6035  1.111    mjacob 			if (FCPARAM(isp)->isp_2klogin) {
   6036  1.111    mjacob 				mbs.ibits = (1 << 10);
   6037  1.111    mjacob 			}
   6038  1.111    mjacob 			mbs.logval = MBLOGALL;
   6039  1.111    mjacob 			isp_mboxcmd_qnw(isp, &mbs, 1);
   6040  1.111    mjacob 		}
   6041   1.57    mjacob 		if (XS_NOERR(xs)) {
   6042   1.57    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   6043   1.57    mjacob 		}
   6044   1.27    mjacob 		return;
   6045  1.111    mjacob 	}
   6046   1.10    mjacob 	case RQCS_PORT_CHANGED:
   6047   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN,
   6048   1.57    mjacob 		    "port changed for target %d", XS_TGT(xs));
   6049   1.57    mjacob 		if (XS_NOERR(xs)) {
   6050   1.57    mjacob 			XS_SETERR(xs, HBA_SELTIMEOUT);
   6051   1.57    mjacob 		}
   6052   1.51    mjacob 		return;
   6053   1.10    mjacob 
   6054  1.111    mjacob 
   6055  1.111    mjacob 	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
   6056  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN,
   6057  1.111    mjacob 		    "f/w resource unavailable for target %d", XS_TGT(xs));
   6058  1.111    mjacob 		if (XS_NOERR(xs)) {
   6059  1.111    mjacob 			*XS_STSP(xs) = SCSI_BUSY;
   6060  1.111    mjacob 			XS_SETERR(xs, HBA_TGTBSY);
   6061  1.111    mjacob 		}
   6062  1.111    mjacob 		return;
   6063  1.111    mjacob 
   6064  1.111    mjacob 	case RQCS_24XX_TMO:	/* task management overrun */
   6065   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN,
   6066  1.111    mjacob 		    "command for target %d overlapped task management",
   6067  1.111    mjacob 		    XS_TGT(xs));
   6068   1.57    mjacob 		if (XS_NOERR(xs)) {
   6069  1.111    mjacob 			*XS_STSP(xs) = SCSI_BUSY;
   6070   1.57    mjacob 			XS_SETERR(xs, HBA_TGTBSY);
   6071   1.57    mjacob 		}
   6072   1.23    mjacob 		return;
   6073   1.10    mjacob 
   6074    1.1       cgd 	default:
   6075   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
   6076   1.57    mjacob 		    sp->req_completion_status);
   6077    1.1       cgd 		break;
   6078    1.1       cgd 	}
   6079   1.57    mjacob 	if (XS_NOERR(xs)) {
   6080   1.57    mjacob 		XS_SETERR(xs, HBA_BOTCH);
   6081   1.57    mjacob 	}
   6082    1.1       cgd }
   6083    1.1       cgd 
   6084   1.33    mjacob static void
   6085  1.111    mjacob isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph)
   6086   1.33    mjacob {
   6087   1.57    mjacob 	XS_T *xs;
   6088   1.33    mjacob 
   6089   1.73    mjacob 	if (fph == 0) {
   6090   1.33    mjacob 		return;
   6091   1.38    mjacob 	}
   6092   1.38    mjacob 	xs = isp_find_xs(isp, fph);
   6093   1.33    mjacob 	if (xs == NULL) {
   6094  1.113    mjacob 		isp_prt(isp, ISP_LOGDEBUG1,
   6095   1.57    mjacob 		    "Command for fast post handle 0x%x not found", fph);
   6096   1.33    mjacob 		return;
   6097   1.33    mjacob 	}
   6098   1.38    mjacob 	isp_destroy_handle(isp, fph);
   6099   1.38    mjacob 
   6100   1.33    mjacob 	/*
   6101   1.33    mjacob 	 * Since we don't have a result queue entry item,
   6102   1.33    mjacob 	 * we must believe that SCSI status is zero and
   6103   1.33    mjacob 	 * that all data transferred.
   6104   1.33    mjacob 	 */
   6105   1.57    mjacob 	XS_SET_STATE_STAT(isp, xs, NULL);
   6106   1.33    mjacob 	XS_RESID(xs) = 0;
   6107   1.57    mjacob 	*XS_STSP(xs) = SCSI_GOOD;
   6108   1.33    mjacob 	if (XS_XFRLEN(xs)) {
   6109   1.38    mjacob 		ISP_DMAFREE(isp, xs, fph);
   6110   1.33    mjacob 	}
   6111   1.38    mjacob 	if (isp->isp_nactive)
   6112   1.38    mjacob 		isp->isp_nactive--;
   6113   1.87    mjacob 	isp->isp_fphccmplt++;
   6114   1.60    mjacob 	isp_done(xs);
   6115   1.33    mjacob }
   6116   1.33    mjacob 
   6117   1.88    mjacob static int
   6118  1.111    mjacob isp_mbox_continue(ispsoftc_t *isp)
   6119   1.88    mjacob {
   6120   1.88    mjacob 	mbreg_t mbs;
   6121  1.111    mjacob 	uint16_t *ptr;
   6122  1.111    mjacob 	uint32_t offset;
   6123   1.88    mjacob 
   6124   1.88    mjacob 	switch (isp->isp_lastmbxcmd) {
   6125   1.88    mjacob 	case MBOX_WRITE_RAM_WORD:
   6126   1.88    mjacob 	case MBOX_READ_RAM_WORD:
   6127  1.111    mjacob 	case MBOX_WRITE_RAM_WORD_EXTENDED:
   6128   1.88    mjacob 	case MBOX_READ_RAM_WORD_EXTENDED:
   6129   1.88    mjacob 		break;
   6130   1.88    mjacob 	default:
   6131   1.88    mjacob 		return (1);
   6132   1.88    mjacob 	}
   6133   1.88    mjacob 	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
   6134   1.88    mjacob 		isp->isp_mbxwrk0 = 0;
   6135   1.88    mjacob 		return (-1);
   6136   1.88    mjacob 	}
   6137   1.88    mjacob 
   6138   1.88    mjacob 	/*
   6139   1.88    mjacob 	 * Clear the previous interrupt.
   6140   1.88    mjacob 	 */
   6141  1.111    mjacob 	if (IS_24XX(isp)) {
   6142  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
   6143  1.111    mjacob 	} else {
   6144  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
   6145  1.111    mjacob 		ISP_WRITE(isp, BIU_SEMA, 0);
   6146  1.111    mjacob 	}
   6147   1.88    mjacob 
   6148   1.88    mjacob 	/*
   6149   1.88    mjacob 	 * Continue with next word.
   6150   1.88    mjacob 	 */
   6151  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   6152   1.88    mjacob 	ptr = isp->isp_mbxworkp;
   6153   1.88    mjacob 	switch (isp->isp_lastmbxcmd) {
   6154   1.88    mjacob 	case MBOX_WRITE_RAM_WORD:
   6155  1.111    mjacob 		mbs.param[1] = isp->isp_mbxwrk1++;;
   6156  1.111    mjacob 		mbs.param[2] = *ptr++;;
   6157  1.111    mjacob 		break;
   6158  1.111    mjacob 	case MBOX_READ_RAM_WORD:
   6159  1.111    mjacob 		*ptr++ = isp->isp_mboxtmp[2];
   6160   1.88    mjacob 		mbs.param[1] = isp->isp_mbxwrk1++;
   6161   1.88    mjacob 		break;
   6162  1.111    mjacob 	case MBOX_WRITE_RAM_WORD_EXTENDED:
   6163  1.111    mjacob 		offset = isp->isp_mbxwrk1;
   6164  1.111    mjacob 		offset |= isp->isp_mbxwrk8 << 16;
   6165  1.111    mjacob 
   6166  1.111    mjacob 		mbs.param[2] = *ptr++;;
   6167  1.111    mjacob 		mbs.param[1] = offset;
   6168  1.111    mjacob 		mbs.param[8] = offset >> 16;
   6169  1.111    mjacob 		isp->isp_mbxwrk1 = ++offset;
   6170  1.111    mjacob 		isp->isp_mbxwrk8 = offset >> 16;
   6171  1.111    mjacob 		break;
   6172   1.88    mjacob 	case MBOX_READ_RAM_WORD_EXTENDED:
   6173  1.111    mjacob 		offset = isp->isp_mbxwrk1;
   6174  1.111    mjacob 		offset |= isp->isp_mbxwrk8 << 16;
   6175  1.111    mjacob 
   6176   1.88    mjacob 		*ptr++ = isp->isp_mboxtmp[2];
   6177  1.111    mjacob 		mbs.param[1] = offset;
   6178  1.111    mjacob 		mbs.param[8] = offset >> 16;
   6179  1.111    mjacob 		isp->isp_mbxwrk1 = ++offset;
   6180  1.111    mjacob 		isp->isp_mbxwrk8 = offset >> 16;
   6181   1.88    mjacob 		break;
   6182   1.88    mjacob 	}
   6183   1.88    mjacob 	isp->isp_mbxworkp = ptr;
   6184  1.111    mjacob 	isp->isp_mbxwrk0--;
   6185   1.88    mjacob 	mbs.param[0] = isp->isp_lastmbxcmd;
   6186  1.111    mjacob 	mbs.logval = MBLOGALL;
   6187   1.88    mjacob 	isp_mboxcmd_qnw(isp, &mbs, 0);
   6188   1.88    mjacob 	return (0);
   6189   1.88    mjacob }
   6190   1.88    mjacob 
   6191  1.111    mjacob #define	HIWRD(x)			((x) >> 16)
   6192  1.111    mjacob #define	LOWRD(x)			((x)  & 0xffff)
   6193  1.111    mjacob #define	ISPOPMAP(a, b)			(((a) << 16) | (b))
   6194  1.111    mjacob static const uint32_t mbpscsi[] = {
   6195   1.54    mjacob 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
   6196   1.54    mjacob 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
   6197   1.54    mjacob 	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
   6198   1.54    mjacob 	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
   6199   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
   6200   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
   6201   1.54    mjacob 	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
   6202  1.111    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
   6203   1.80    mjacob 	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
   6204   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x09: */
   6205   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
   6206   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
   6207   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
   6208   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
   6209   1.54    mjacob 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
   6210   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
   6211   1.54    mjacob 	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
   6212   1.54    mjacob 	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
   6213   1.54    mjacob 	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
   6214   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
   6215   1.54    mjacob 	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
   6216   1.54    mjacob 	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
   6217   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
   6218   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
   6219   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
   6220   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
   6221   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
   6222   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
   6223   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
   6224   1.54    mjacob 	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
   6225   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
   6226   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
   6227   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
   6228   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
   6229   1.54    mjacob 	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
   6230   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
   6231   1.54    mjacob 	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
   6232   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
   6233   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
   6234   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
   6235   1.54    mjacob 	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
   6236   1.54    mjacob 	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
   6237   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
   6238   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
   6239   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
   6240   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
   6241   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
   6242   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
   6243   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
   6244   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
   6245   1.54    mjacob 	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
   6246   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
   6247   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
   6248   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
   6249   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
   6250   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
   6251   1.54    mjacob 	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
   6252   1.54    mjacob 	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
   6253   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
   6254   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
   6255   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
   6256   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
   6257   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
   6258   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
   6259   1.54    mjacob 	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
   6260   1.54    mjacob 	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
   6261   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
   6262   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x43: */
   6263   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
   6264   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
   6265   1.54    mjacob 	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
   6266   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x47: */
   6267   1.54    mjacob 	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
   6268   1.54    mjacob 	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
   6269   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
   6270   1.54    mjacob 	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
   6271   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
   6272   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
   6273   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
   6274   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
   6275   1.54    mjacob 	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
   6276   1.54    mjacob 	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
   6277   1.99    mjacob 	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
   6278   1.99    mjacob 	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
   6279  1.111    mjacob 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
   6280   1.74    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
   6281   1.74    mjacob 	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
   6282   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
   6283   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
   6284   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
   6285   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
   6286   1.54    mjacob 	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
   6287   1.54    mjacob 	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
   6288   1.54    mjacob 	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
   6289   1.54    mjacob };
   6290   1.54    mjacob 
   6291  1.107  christos static const char *scsi_mbcmd_names[] = {
   6292   1.57    mjacob 	"NO-OP",
   6293   1.57    mjacob 	"LOAD RAM",
   6294   1.57    mjacob 	"EXEC FIRMWARE",
   6295   1.57    mjacob 	"DUMP RAM",
   6296   1.57    mjacob 	"WRITE RAM WORD",
   6297   1.57    mjacob 	"READ RAM WORD",
   6298   1.57    mjacob 	"MAILBOX REG TEST",
   6299   1.57    mjacob 	"VERIFY CHECKSUM",
   6300   1.57    mjacob 	"ABOUT FIRMWARE",
   6301   1.57    mjacob 	NULL,
   6302   1.57    mjacob 	NULL,
   6303   1.57    mjacob 	NULL,
   6304   1.57    mjacob 	NULL,
   6305   1.57    mjacob 	NULL,
   6306   1.57    mjacob 	"CHECK FIRMWARE",
   6307   1.57    mjacob 	NULL,
   6308   1.57    mjacob 	"INIT REQUEST QUEUE",
   6309   1.57    mjacob 	"INIT RESULT QUEUE",
   6310   1.57    mjacob 	"EXECUTE IOCB",
   6311   1.57    mjacob 	"WAKE UP",
   6312   1.57    mjacob 	"STOP FIRMWARE",
   6313   1.57    mjacob 	"ABORT",
   6314   1.57    mjacob 	"ABORT DEVICE",
   6315   1.57    mjacob 	"ABORT TARGET",
   6316   1.57    mjacob 	"BUS RESET",
   6317   1.57    mjacob 	"STOP QUEUE",
   6318   1.57    mjacob 	"START QUEUE",
   6319   1.57    mjacob 	"SINGLE STEP QUEUE",
   6320   1.57    mjacob 	"ABORT QUEUE",
   6321   1.57    mjacob 	"GET DEV QUEUE STATUS",
   6322   1.57    mjacob 	NULL,
   6323   1.57    mjacob 	"GET FIRMWARE STATUS",
   6324   1.57    mjacob 	"GET INIT SCSI ID",
   6325   1.57    mjacob 	"GET SELECT TIMEOUT",
   6326   1.57    mjacob 	"GET RETRY COUNT",
   6327   1.57    mjacob 	"GET TAG AGE LIMIT",
   6328   1.57    mjacob 	"GET CLOCK RATE",
   6329   1.57    mjacob 	"GET ACT NEG STATE",
   6330   1.57    mjacob 	"GET ASYNC DATA SETUP TIME",
   6331   1.57    mjacob 	"GET PCI PARAMS",
   6332   1.57    mjacob 	"GET TARGET PARAMS",
   6333   1.57    mjacob 	"GET DEV QUEUE PARAMS",
   6334   1.57    mjacob 	"GET RESET DELAY PARAMS",
   6335   1.57    mjacob 	NULL,
   6336   1.57    mjacob 	NULL,
   6337   1.57    mjacob 	NULL,
   6338   1.57    mjacob 	NULL,
   6339   1.57    mjacob 	NULL,
   6340   1.57    mjacob 	"SET INIT SCSI ID",
   6341   1.57    mjacob 	"SET SELECT TIMEOUT",
   6342   1.57    mjacob 	"SET RETRY COUNT",
   6343   1.57    mjacob 	"SET TAG AGE LIMIT",
   6344   1.57    mjacob 	"SET CLOCK RATE",
   6345   1.57    mjacob 	"SET ACT NEG STATE",
   6346   1.57    mjacob 	"SET ASYNC DATA SETUP TIME",
   6347   1.57    mjacob 	"SET PCI CONTROL PARAMS",
   6348   1.57    mjacob 	"SET TARGET PARAMS",
   6349   1.57    mjacob 	"SET DEV QUEUE PARAMS",
   6350   1.57    mjacob 	"SET RESET DELAY PARAMS",
   6351   1.57    mjacob 	NULL,
   6352   1.57    mjacob 	NULL,
   6353   1.57    mjacob 	NULL,
   6354   1.57    mjacob 	NULL,
   6355   1.57    mjacob 	NULL,
   6356   1.57    mjacob 	"RETURN BIOS BLOCK ADDR",
   6357   1.57    mjacob 	"WRITE FOUR RAM WORDS",
   6358   1.57    mjacob 	"EXEC BIOS IOCB",
   6359   1.57    mjacob 	NULL,
   6360   1.57    mjacob 	NULL,
   6361   1.57    mjacob 	"SET SYSTEM PARAMETER",
   6362   1.57    mjacob 	"GET SYSTEM PARAMETER",
   6363   1.57    mjacob 	NULL,
   6364   1.57    mjacob 	"GET SCAM CONFIGURATION",
   6365   1.57    mjacob 	"SET SCAM CONFIGURATION",
   6366   1.57    mjacob 	"SET FIRMWARE FEATURES",
   6367   1.57    mjacob 	"GET FIRMWARE FEATURES",
   6368   1.57    mjacob 	NULL,
   6369   1.57    mjacob 	NULL,
   6370   1.57    mjacob 	NULL,
   6371   1.57    mjacob 	NULL,
   6372   1.57    mjacob 	"LOAD RAM A64",
   6373   1.57    mjacob 	"DUMP RAM A64",
   6374   1.57    mjacob 	"INITIALIZE REQUEST QUEUE A64",
   6375   1.57    mjacob 	"INITIALIZE RESPONSE QUEUE A64",
   6376   1.57    mjacob 	"EXECUTE IOCB A64",
   6377   1.57    mjacob 	"ENABLE TARGET MODE",
   6378   1.74    mjacob 	"GET TARGET MODE STATE",
   6379   1.57    mjacob 	NULL,
   6380   1.57    mjacob 	NULL,
   6381   1.57    mjacob 	NULL,
   6382   1.57    mjacob 	"SET DATA OVERRUN RECOVERY MODE",
   6383   1.57    mjacob 	"GET DATA OVERRUN RECOVERY MODE",
   6384   1.57    mjacob 	"SET HOST DATA",
   6385   1.57    mjacob 	"GET NOST DATA",
   6386   1.57    mjacob };
   6387   1.57    mjacob 
   6388  1.111    mjacob static const uint32_t mbpfc[] = {
   6389   1.54    mjacob 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
   6390   1.54    mjacob 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
   6391  1.111    mjacob 	ISPOPMAP(0x0f, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
   6392   1.71    mjacob 	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
   6393   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
   6394   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
   6395   1.54    mjacob 	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
   6396  1.111    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
   6397   1.80    mjacob 	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
   6398  1.111    mjacob 	ISPOPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
   6399   1.54    mjacob 	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
   6400  1.111    mjacob 	ISPOPMAP(0x1ff, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
   6401   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
   6402  1.111    mjacob 	ISPOPMAP(0x10f, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
   6403   1.54    mjacob 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
   6404  1.111    mjacob 	ISPOPMAP(0x10f, 0x05),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
   6405   1.54    mjacob 	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
   6406   1.54    mjacob 	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
   6407   1.54    mjacob 	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
   6408   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
   6409   1.54    mjacob 	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
   6410   1.54    mjacob 	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
   6411   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
   6412   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
   6413   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
   6414   1.54    mjacob 	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
   6415   1.54    mjacob 	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
   6416   1.54    mjacob 	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
   6417   1.54    mjacob 	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
   6418   1.54    mjacob 	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
   6419   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
   6420   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
   6421   1.54    mjacob 	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
   6422   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x21: */
   6423   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
   6424   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x23: */
   6425   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x24: */
   6426   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x25: */
   6427   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x26: */
   6428   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x27: */
   6429   1.81    mjacob 	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
   6430   1.54    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
   6431   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
   6432   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
   6433   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
   6434   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
   6435   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
   6436   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
   6437   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x30: */
   6438   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x31: */
   6439   1.54    mjacob 	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
   6440   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x33: */
   6441   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x34: */
   6442   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x35: */
   6443   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x36: */
   6444   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x37: */
   6445   1.54    mjacob 	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
   6446   1.54    mjacob 	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
   6447   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
   6448   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
   6449   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
   6450   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
   6451   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
   6452   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
   6453   1.54    mjacob 	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
   6454   1.54    mjacob 	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
   6455  1.111    mjacob 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
   6456  1.111    mjacob 	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
   6457   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
   6458   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x45: */
   6459   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x46: */
   6460   1.54    mjacob 	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
   6461   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x48: */
   6462   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x49: */
   6463   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4a: */
   6464   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
   6465   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
   6466   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
   6467   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
   6468   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
   6469   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x50: */
   6470   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x51: */
   6471   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x52: */
   6472   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x53: */
   6473   1.54    mjacob 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
   6474   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x55: */
   6475   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x56: */
   6476   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
   6477   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
   6478   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
   6479   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
   6480   1.94    mjacob 	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
   6481   1.94    mjacob 	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
   6482   1.81    mjacob 	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
   6483   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
   6484   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
   6485  1.111    mjacob 	ISPOPMAP(0xcd, 0x01),	/* 0x60: MBOX_INIT_FIRMWARE */
   6486   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x61: */
   6487   1.54    mjacob 	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
   6488   1.54    mjacob 	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
   6489   1.54    mjacob 	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
   6490   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
   6491   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
   6492   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
   6493   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
   6494   1.54    mjacob 	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
   6495   1.54    mjacob 	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
   6496   1.54    mjacob 	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
   6497   1.54    mjacob 	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
   6498   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
   6499   1.54    mjacob 	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
   6500   1.54    mjacob 	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
   6501   1.54    mjacob 	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
   6502   1.54    mjacob 	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
   6503   1.54    mjacob 	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
   6504   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x73: */
   6505   1.54    mjacob 	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
   6506   1.54    mjacob 	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
   6507   1.54    mjacob 	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
   6508   1.54    mjacob 	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
   6509   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x78: */
   6510   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x79: */
   6511   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
   6512   1.54    mjacob 	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
   6513   1.54    mjacob 	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
   6514   1.54    mjacob 	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
   6515  1.111    mjacob 	ISPOPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
   6516    1.1       cgd };
   6517   1.88    mjacob /*
   6518   1.88    mjacob  * Footnotes
   6519   1.88    mjacob  *
   6520  1.111    mjacob  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
   6521   1.88    mjacob  *	do not access at this time in the core driver. The caller is
   6522  1.111    mjacob  *	responsible for setting this register first (Gross!). The assumption
   6523  1.111    mjacob  *	is that we won't overflow.
   6524   1.88    mjacob  */
   6525    1.1       cgd 
   6526  1.107  christos static const char *fc_mbcmd_names[] = {
   6527   1.57    mjacob 	"NO-OP",
   6528   1.57    mjacob 	"LOAD RAM",
   6529   1.57    mjacob 	"EXEC FIRMWARE",
   6530   1.57    mjacob 	"DUMP RAM",
   6531   1.57    mjacob 	"WRITE RAM WORD",
   6532   1.57    mjacob 	"READ RAM WORD",
   6533   1.57    mjacob 	"MAILBOX REG TEST",
   6534   1.57    mjacob 	"VERIFY CHECKSUM",
   6535   1.57    mjacob 	"ABOUT FIRMWARE",
   6536   1.57    mjacob 	"LOAD RAM",
   6537   1.57    mjacob 	"DUMP RAM",
   6538  1.111    mjacob 	"WRITE RAM WORD EXTENDED",
   6539   1.57    mjacob 	NULL,
   6540   1.88    mjacob 	"READ RAM WORD EXTENDED",
   6541   1.57    mjacob 	"CHECK FIRMWARE",
   6542   1.57    mjacob 	NULL,
   6543   1.57    mjacob 	"INIT REQUEST QUEUE",
   6544   1.57    mjacob 	"INIT RESULT QUEUE",
   6545   1.57    mjacob 	"EXECUTE IOCB",
   6546   1.57    mjacob 	"WAKE UP",
   6547   1.57    mjacob 	"STOP FIRMWARE",
   6548   1.57    mjacob 	"ABORT",
   6549   1.57    mjacob 	"ABORT DEVICE",
   6550   1.57    mjacob 	"ABORT TARGET",
   6551   1.57    mjacob 	"BUS RESET",
   6552   1.57    mjacob 	"STOP QUEUE",
   6553   1.57    mjacob 	"START QUEUE",
   6554   1.57    mjacob 	"SINGLE STEP QUEUE",
   6555   1.57    mjacob 	"ABORT QUEUE",
   6556   1.57    mjacob 	"GET DEV QUEUE STATUS",
   6557   1.57    mjacob 	NULL,
   6558   1.57    mjacob 	"GET FIRMWARE STATUS",
   6559   1.57    mjacob 	"GET LOOP ID",
   6560   1.57    mjacob 	NULL,
   6561   1.57    mjacob 	"GET RETRY COUNT",
   6562   1.57    mjacob 	NULL,
   6563   1.57    mjacob 	NULL,
   6564   1.57    mjacob 	NULL,
   6565   1.57    mjacob 	NULL,
   6566   1.57    mjacob 	NULL,
   6567   1.57    mjacob 	"GET FIRMWARE OPTIONS",
   6568   1.57    mjacob 	"GET PORT QUEUE PARAMS",
   6569   1.57    mjacob 	NULL,
   6570   1.57    mjacob 	NULL,
   6571   1.57    mjacob 	NULL,
   6572   1.57    mjacob 	NULL,
   6573   1.57    mjacob 	NULL,
   6574   1.57    mjacob 	NULL,
   6575   1.57    mjacob 	NULL,
   6576   1.57    mjacob 	NULL,
   6577   1.57    mjacob 	"SET RETRY COUNT",
   6578   1.57    mjacob 	NULL,
   6579   1.57    mjacob 	NULL,
   6580   1.57    mjacob 	NULL,
   6581   1.57    mjacob 	NULL,
   6582   1.57    mjacob 	NULL,
   6583   1.57    mjacob 	"SET FIRMWARE OPTIONS",
   6584   1.57    mjacob 	"SET PORT QUEUE PARAMS",
   6585   1.57    mjacob 	NULL,
   6586   1.57    mjacob 	NULL,
   6587   1.57    mjacob 	NULL,
   6588   1.57    mjacob 	NULL,
   6589   1.57    mjacob 	NULL,
   6590   1.57    mjacob 	NULL,
   6591   1.57    mjacob 	"LOOP PORT BYPASS",
   6592   1.57    mjacob 	"LOOP PORT ENABLE",
   6593  1.111    mjacob 	"GET RESOURCE COUNT",
   6594   1.57    mjacob 	"REQUEST NON PARTICIPATING MODE",
   6595   1.57    mjacob 	NULL,
   6596   1.57    mjacob 	NULL,
   6597   1.57    mjacob 	NULL,
   6598  1.111    mjacob 	"GET PORT DATABASE ENHANCED",
   6599   1.57    mjacob 	NULL,
   6600   1.57    mjacob 	NULL,
   6601   1.57    mjacob 	NULL,
   6602   1.57    mjacob 	NULL,
   6603   1.57    mjacob 	NULL,
   6604   1.57    mjacob 	NULL,
   6605   1.57    mjacob 	NULL,
   6606   1.57    mjacob 	NULL,
   6607   1.57    mjacob 	NULL,
   6608   1.57    mjacob 	NULL,
   6609   1.57    mjacob 	NULL,
   6610   1.57    mjacob 	NULL,
   6611   1.57    mjacob 	"EXECUTE IOCB A64",
   6612   1.57    mjacob 	NULL,
   6613   1.57    mjacob 	NULL,
   6614   1.57    mjacob 	NULL,
   6615   1.57    mjacob 	NULL,
   6616   1.57    mjacob 	NULL,
   6617   1.57    mjacob 	NULL,
   6618  1.101    mjacob 	"DRIVER HEARTBEAT",
   6619   1.57    mjacob 	NULL,
   6620   1.81    mjacob 	"GET/SET DATA RATE",
   6621   1.57    mjacob 	NULL,
   6622   1.57    mjacob 	NULL,
   6623   1.57    mjacob 	"INIT FIRMWARE",
   6624   1.57    mjacob 	NULL,
   6625   1.57    mjacob 	"INIT LIP",
   6626   1.57    mjacob 	"GET FC-AL POSITION MAP",
   6627   1.57    mjacob 	"GET PORT DATABASE",
   6628   1.57    mjacob 	"CLEAR ACA",
   6629   1.57    mjacob 	"TARGET RESET",
   6630   1.57    mjacob 	"CLEAR TASK SET",
   6631   1.57    mjacob 	"ABORT TASK SET",
   6632   1.57    mjacob 	"GET FW STATE",
   6633   1.57    mjacob 	"GET PORT NAME",
   6634   1.57    mjacob 	"GET LINK STATUS",
   6635   1.57    mjacob 	"INIT LIP RESET",
   6636   1.57    mjacob 	NULL,
   6637   1.57    mjacob 	"SEND SNS",
   6638   1.57    mjacob 	"FABRIC LOGIN",
   6639   1.57    mjacob 	"SEND CHANGE REQUEST",
   6640   1.57    mjacob 	"FABRIC LOGOUT",
   6641   1.57    mjacob 	"INIT LIP LOGIN",
   6642   1.57    mjacob 	NULL,
   6643   1.57    mjacob 	"LOGIN LOOP PORT",
   6644   1.57    mjacob 	"GET PORT/NODE NAME LIST",
   6645   1.57    mjacob 	"SET VENDOR ID",
   6646   1.57    mjacob 	"INITIALIZE IP MAILBOX",
   6647   1.57    mjacob 	NULL,
   6648   1.57    mjacob 	NULL,
   6649   1.57    mjacob 	NULL,
   6650   1.57    mjacob 	NULL,
   6651   1.57    mjacob 	"Get ID List",
   6652   1.57    mjacob 	"SEND LFA",
   6653   1.57    mjacob 	"Lun RESET"
   6654   1.57    mjacob };
   6655   1.57    mjacob 
   6656   1.10    mjacob static void
   6657  1.111    mjacob isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
   6658   1.88    mjacob {
   6659  1.103    mjacob 	unsigned int ibits, obits, box, opcode;
   6660  1.111    mjacob 	const uint32_t *mcp;
   6661   1.88    mjacob 
   6662   1.88    mjacob 	if (IS_FC(isp)) {
   6663   1.88    mjacob 		mcp = mbpfc;
   6664   1.88    mjacob 	} else {
   6665   1.88    mjacob 		mcp = mbpscsi;
   6666   1.88    mjacob 	}
   6667   1.88    mjacob 	opcode = mbp->param[0];
   6668  1.111    mjacob 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
   6669  1.111    mjacob 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
   6670  1.111    mjacob 	ibits |= mbp->ibits;
   6671  1.111    mjacob 	obits |= mbp->obits;
   6672  1.111    mjacob 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
   6673   1.88    mjacob 		if (ibits & (1 << box)) {
   6674   1.88    mjacob 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
   6675   1.88    mjacob 		}
   6676   1.88    mjacob 		if (nodelay == 0) {
   6677   1.88    mjacob 			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
   6678   1.88    mjacob 		}
   6679   1.88    mjacob 	}
   6680   1.88    mjacob 	if (nodelay == 0) {
   6681   1.88    mjacob 		isp->isp_lastmbxcmd = opcode;
   6682   1.88    mjacob 		isp->isp_obits = obits;
   6683   1.88    mjacob 		isp->isp_mboxbsy = 1;
   6684   1.88    mjacob 	}
   6685  1.111    mjacob 	if (IS_24XX(isp)) {
   6686  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
   6687  1.111    mjacob 	} else {
   6688  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
   6689  1.111    mjacob 	}
   6690   1.88    mjacob 	/*
   6691   1.88    mjacob 	 * Oddly enough, if we're not delaying for an answer,
   6692   1.88    mjacob 	 * delay a bit to give the f/w a chance to pick up the
   6693   1.88    mjacob 	 * command.
   6694   1.88    mjacob 	 */
   6695   1.88    mjacob 	if (nodelay) {
   6696   1.88    mjacob 		USEC_DELAY(1000);
   6697   1.88    mjacob 	}
   6698   1.88    mjacob }
   6699   1.88    mjacob 
   6700   1.88    mjacob static void
   6701  1.111    mjacob isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
   6702    1.1       cgd {
   6703  1.111    mjacob 	const char *cname, *xname;
   6704  1.107  christos 	char tname[16], mname[16];
   6705   1.54    mjacob 	unsigned int lim, ibits, obits, box, opcode;
   6706  1.111    mjacob 	const uint32_t *mcp;
   6707   1.54    mjacob 
   6708   1.54    mjacob 	if (IS_FC(isp)) {
   6709   1.54    mjacob 		mcp = mbpfc;
   6710   1.54    mjacob 		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
   6711   1.54    mjacob 	} else {
   6712   1.54    mjacob 		mcp = mbpscsi;
   6713   1.54    mjacob 		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
   6714    1.1       cgd 	}
   6715    1.1       cgd 
   6716   1.54    mjacob 	if ((opcode = mbp->param[0]) >= lim) {
   6717   1.54    mjacob 		mbp->param[0] = MBOX_INVALID_COMMAND;
   6718   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
   6719   1.10    mjacob 		return;
   6720    1.1       cgd 	}
   6721    1.1       cgd 
   6722  1.111    mjacob 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
   6723  1.111    mjacob 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
   6724  1.111    mjacob 
   6725  1.111    mjacob 	/*
   6726  1.111    mjacob 	 * Pick up any additional bits that the caller might have set.
   6727  1.111    mjacob 	 */
   6728  1.111    mjacob 	ibits |= mbp->ibits;
   6729  1.111    mjacob 	obits |= mbp->obits;
   6730   1.10    mjacob 
   6731   1.54    mjacob 	if (ibits == 0 && obits == 0) {
   6732   1.54    mjacob 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
   6733   1.57    mjacob 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
   6734   1.54    mjacob 		return;
   6735   1.28    mjacob 	}
   6736   1.24    mjacob 
   6737   1.57    mjacob 	/*
   6738   1.57    mjacob 	 * Get exclusive usage of mailbox registers.
   6739   1.57    mjacob 	 */
   6740  1.111    mjacob 	if (MBOX_ACQUIRE(isp)) {
   6741  1.111    mjacob 		mbp->param[0] = MBOX_REGS_BUSY;
   6742  1.111    mjacob 		goto out;
   6743  1.111    mjacob 	}
   6744   1.57    mjacob 
   6745  1.111    mjacob 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
   6746   1.54    mjacob 		if (ibits & (1 << box)) {
   6747  1.111    mjacob 			isp_prt(isp, ISP_LOGDEBUG1, "IN mbox %d = 0x%04x", box,
   6748  1.111    mjacob 			    mbp->param[box]);
   6749   1.54    mjacob 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
   6750    1.1       cgd 		}
   6751   1.54    mjacob 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
   6752    1.1       cgd 	}
   6753    1.1       cgd 
   6754   1.70    mjacob 	isp->isp_lastmbxcmd = opcode;
   6755   1.70    mjacob 
   6756    1.1       cgd 	/*
   6757   1.54    mjacob 	 * We assume that we can't overwrite a previous command.
   6758   1.34    mjacob 	 */
   6759   1.86    mjacob 	isp->isp_obits = obits;
   6760   1.86    mjacob 	isp->isp_mboxbsy = 1;
   6761    1.1       cgd 
   6762    1.1       cgd 	/*
   6763    1.1       cgd 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
   6764    1.1       cgd 	 */
   6765  1.111    mjacob 	if (IS_24XX(isp)) {
   6766  1.111    mjacob 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
   6767  1.111    mjacob 	} else {
   6768  1.111    mjacob 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
   6769  1.111    mjacob 	}
   6770    1.1       cgd 
   6771   1.33    mjacob 	/*
   6772   1.54    mjacob 	 * While we haven't finished the command, spin our wheels here.
   6773   1.33    mjacob 	 */
   6774  1.111    mjacob 	MBOX_WAIT_COMPLETE(isp, mbp);
   6775   1.86    mjacob 
   6776  1.111    mjacob 	/*
   6777  1.111    mjacob 	 * Did the command time out?
   6778  1.111    mjacob 	 */
   6779  1.111    mjacob 	if (mbp->param[0] == MBOX_TIMEOUT) {
   6780   1.86    mjacob 		MBOX_RELEASE(isp);
   6781  1.111    mjacob 		goto out;
   6782   1.86    mjacob 	}
   6783    1.1       cgd 
   6784    1.1       cgd 	/*
   6785   1.54    mjacob 	 * Copy back output registers.
   6786    1.1       cgd 	 */
   6787  1.111    mjacob 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
   6788   1.54    mjacob 		if (obits & (1 << box)) {
   6789   1.54    mjacob 			mbp->param[box] = isp->isp_mboxtmp[box];
   6790  1.111    mjacob 			isp_prt(isp, ISP_LOGDEBUG1, "OUT mbox %d = 0x%04x", box,
   6791  1.111    mjacob 			    mbp->param[box]);
   6792   1.36    mjacob 		}
   6793   1.36    mjacob 	}
   6794   1.36    mjacob 
   6795   1.57    mjacob 	MBOX_RELEASE(isp);
   6796  1.111    mjacob  out:
   6797  1.111    mjacob 	isp->isp_mboxbsy = 0;
   6798  1.111    mjacob 	if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
   6799   1.57    mjacob 		return;
   6800   1.57    mjacob 	}
   6801   1.57    mjacob 	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
   6802   1.57    mjacob 	if (cname == NULL) {
   6803   1.74    mjacob 		cname = tname;
   6804   1.74    mjacob 		SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
   6805   1.57    mjacob 	}
   6806   1.57    mjacob 
   6807   1.10    mjacob 	/*
   6808   1.10    mjacob 	 * Just to be chatty here...
   6809   1.10    mjacob 	 */
   6810   1.57    mjacob 	xname = NULL;
   6811   1.34    mjacob 	switch (mbp->param[0]) {
   6812   1.10    mjacob 	case MBOX_COMMAND_COMPLETE:
   6813   1.10    mjacob 		break;
   6814   1.10    mjacob 	case MBOX_INVALID_COMMAND:
   6815  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
   6816   1.57    mjacob 			xname = "INVALID COMMAND";
   6817  1.111    mjacob 		}
   6818   1.10    mjacob 		break;
   6819   1.10    mjacob 	case MBOX_HOST_INTERFACE_ERROR:
   6820  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
   6821   1.57    mjacob 			xname = "HOST INTERFACE ERROR";
   6822  1.111    mjacob 		}
   6823   1.10    mjacob 		break;
   6824   1.10    mjacob 	case MBOX_TEST_FAILED:
   6825  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
   6826   1.57    mjacob 			xname = "TEST FAILED";
   6827  1.111    mjacob 		}
   6828   1.10    mjacob 		break;
   6829   1.10    mjacob 	case MBOX_COMMAND_ERROR:
   6830  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
   6831   1.57    mjacob 			xname = "COMMAND ERROR";
   6832  1.111    mjacob 		}
   6833   1.10    mjacob 		break;
   6834   1.10    mjacob 	case MBOX_COMMAND_PARAM_ERROR:
   6835  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
   6836   1.57    mjacob 			xname = "COMMAND PARAMETER ERROR";
   6837  1.111    mjacob 		}
   6838   1.10    mjacob 		break;
   6839   1.50    mjacob 	case MBOX_LOOP_ID_USED:
   6840  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
   6841   1.57    mjacob 			xname = "LOOP ID ALREADY IN USE";
   6842  1.111    mjacob 		}
   6843   1.57    mjacob 		break;
   6844   1.50    mjacob 	case MBOX_PORT_ID_USED:
   6845  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
   6846   1.57    mjacob 			xname = "PORT ID ALREADY IN USE";
   6847  1.111    mjacob 		}
   6848   1.57    mjacob 		break;
   6849   1.50    mjacob 	case MBOX_ALL_IDS_USED:
   6850  1.111    mjacob 		if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
   6851   1.57    mjacob 			xname = "ALL LOOP IDS IN USE";
   6852  1.111    mjacob 		}
   6853   1.57    mjacob 		break;
   6854  1.111    mjacob 	case MBOX_REGS_BUSY:
   6855  1.111    mjacob 		xname = "REGISTERS BUSY";
   6856  1.111    mjacob 		break;
   6857  1.111    mjacob 	case MBOX_TIMEOUT:
   6858   1.57    mjacob 		xname = "TIMEOUT";
   6859   1.50    mjacob 		break;
   6860   1.10    mjacob 	default:
   6861   1.57    mjacob 		SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
   6862   1.57    mjacob 		xname = mname;
   6863   1.10    mjacob 		break;
   6864   1.10    mjacob 	}
   6865  1.111    mjacob 	if (xname) {
   6866   1.57    mjacob 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
   6867   1.57    mjacob 		    cname, xname);
   6868  1.111    mjacob 	}
   6869   1.10    mjacob }
   6870   1.10    mjacob 
   6871   1.10    mjacob static void
   6872  1.111    mjacob isp_fw_state(ispsoftc_t *isp)
   6873   1.10    mjacob {
   6874   1.38    mjacob 	if (IS_FC(isp)) {
   6875   1.57    mjacob 		mbreg_t mbs;
   6876   1.10    mjacob 		fcparam *fcp = isp->isp_param;
   6877   1.57    mjacob 
   6878  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   6879   1.10    mjacob 		mbs.param[0] = MBOX_GET_FW_STATE;
   6880  1.111    mjacob 		mbs.logval = MBLOGALL;
   6881  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   6882   1.70    mjacob 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
   6883   1.57    mjacob 			fcp->isp_fwstate = mbs.param[1];
   6884   1.70    mjacob 		}
   6885   1.10    mjacob 	}
   6886   1.10    mjacob }
   6887   1.10    mjacob 
   6888   1.10    mjacob static void
   6889  1.111    mjacob isp_update(ispsoftc_t *isp)
   6890   1.10    mjacob {
   6891   1.58    mjacob 	int bus, upmask;
   6892   1.36    mjacob 
   6893   1.58    mjacob 	for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
   6894   1.58    mjacob 		if (upmask & (1 << bus)) {
   6895   1.36    mjacob 			isp_update_bus(isp, bus);
   6896   1.36    mjacob 		}
   6897   1.60    mjacob 		upmask &= ~(1 << bus);
   6898   1.36    mjacob 	}
   6899   1.36    mjacob }
   6900   1.36    mjacob 
   6901   1.36    mjacob static void
   6902  1.111    mjacob isp_update_bus(ispsoftc_t *isp, int bus)
   6903   1.36    mjacob {
   6904   1.25    mjacob 	int tgt;
   6905   1.10    mjacob 	mbreg_t mbs;
   6906   1.10    mjacob 	sdparam *sdp;
   6907   1.10    mjacob 
   6908   1.60    mjacob 	isp->isp_update &= ~(1 << bus);
   6909   1.38    mjacob 	if (IS_FC(isp)) {
   6910   1.58    mjacob 		/*
   6911   1.58    mjacob 		 * There are no 'per-bus' settings for Fibre Channel.
   6912   1.58    mjacob 		 */
   6913    1.4    mjacob 		return;
   6914    1.4    mjacob 	}
   6915   1.25    mjacob 	sdp = isp->isp_param;
   6916   1.36    mjacob 	sdp += bus;
   6917   1.36    mjacob 
   6918   1.25    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   6919  1.111    mjacob 		uint16_t flags, period, offset;
   6920   1.31    mjacob 		int get;
   6921   1.31    mjacob 
   6922   1.25    mjacob 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
   6923   1.60    mjacob 			sdp->isp_devparam[tgt].dev_update = 0;
   6924   1.60    mjacob 			sdp->isp_devparam[tgt].dev_refresh = 0;
   6925   1.74    mjacob 			isp_prt(isp, ISP_LOGDEBUG0,
   6926   1.57    mjacob 	 		    "skipping target %d bus %d update", tgt, bus);
   6927   1.25    mjacob 			continue;
   6928   1.25    mjacob 		}
   6929   1.34    mjacob 		/*
   6930   1.34    mjacob 		 * If the goal is to update the status of the device,
   6931   1.79    mjacob 		 * take what's in goal_flags and try and set the device
   6932   1.34    mjacob 		 * toward that. Otherwise, if we're just refreshing the
   6933   1.34    mjacob 		 * current device state, get the current parameters.
   6934   1.34    mjacob 		 */
   6935   1.58    mjacob 
   6936  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   6937  1.111    mjacob 
   6938   1.58    mjacob 		/*
   6939   1.58    mjacob 		 * Refresh overrides set
   6940   1.58    mjacob 		 */
   6941   1.58    mjacob 		if (sdp->isp_devparam[tgt].dev_refresh) {
   6942   1.58    mjacob 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
   6943   1.58    mjacob 			get = 1;
   6944   1.58    mjacob 		} else if (sdp->isp_devparam[tgt].dev_update) {
   6945   1.31    mjacob 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
   6946  1.111    mjacob 
   6947   1.58    mjacob 			/*
   6948   1.79    mjacob 			 * Make sure goal_flags has "Renegotiate on Error"
   6949   1.58    mjacob 			 * on and "Freeze Queue on Error" off.
   6950   1.58    mjacob 			 */
   6951   1.79    mjacob 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
   6952   1.79    mjacob 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
   6953   1.79    mjacob 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
   6954   1.78    mjacob 
   6955   1.36    mjacob 			/*
   6956   1.58    mjacob 			 * Insist that PARITY must be enabled
   6957   1.58    mjacob 			 * if SYNC or WIDE is enabled.
   6958   1.36    mjacob 			 */
   6959   1.58    mjacob 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
   6960   1.36    mjacob 				mbs.param[2] |= DPARM_PARITY;
   6961   1.36    mjacob 			}
   6962   1.58    mjacob 
   6963  1.111    mjacob 			if (mbs.param[2] & DPARM_SYNC) {
   6964   1.58    mjacob 				mbs.param[3] =
   6965   1.79    mjacob 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
   6966   1.79    mjacob 				    (sdp->isp_devparam[tgt].goal_period);
   6967   1.58    mjacob 			}
   6968   1.34    mjacob 			/*
   6969   1.34    mjacob 			 * A command completion later that has
   6970   1.79    mjacob 			 * RQSTF_NEGOTIATION set can cause
   6971   1.60    mjacob 			 * the dev_refresh/announce cycle also.
   6972   1.34    mjacob 			 *
   6973   1.34    mjacob 			 * Note: It is really important to update our current
   6974   1.34    mjacob 			 * flags with at least the state of TAG capabilities-
   6975   1.34    mjacob 			 * otherwise we might try and send a tagged command
   6976   1.34    mjacob 			 * when we have it all turned off. So change it here
   6977   1.34    mjacob 			 * to say that current already matches goal.
   6978   1.34    mjacob 			 */
   6979   1.79    mjacob 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
   6980   1.79    mjacob 			sdp->isp_devparam[tgt].actv_flags |=
   6981   1.79    mjacob 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
   6982   1.74    mjacob 			isp_prt(isp, ISP_LOGDEBUG0,
   6983   1.57    mjacob 			    "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
   6984   1.57    mjacob 			    bus, tgt, mbs.param[2], mbs.param[3] >> 8,
   6985   1.57    mjacob 			    mbs.param[3] & 0xff);
   6986   1.31    mjacob 			get = 0;
   6987   1.31    mjacob 		} else {
   6988   1.25    mjacob 			continue;
   6989   1.25    mjacob 		}
   6990   1.74    mjacob 		mbs.param[1] = (bus << 15) | (tgt << 8);
   6991  1.111    mjacob 		mbs.logval = MBLOGALL;
   6992  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   6993  1.111    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   6994  1.111    mjacob 			continue;
   6995  1.111    mjacob 		}
   6996   1.31    mjacob 		if (get == 0) {
   6997   1.36    mjacob 			isp->isp_sendmarker |= (1 << bus);
   6998  1.111    mjacob 			sdp->isp_devparam[tgt].dev_update = 0;
   6999  1.111    mjacob 			sdp->isp_devparam[tgt].dev_refresh = 1;
   7000  1.111    mjacob 		} else {
   7001  1.111    mjacob 			sdp->isp_devparam[tgt].dev_refresh = 0;
   7002  1.111    mjacob 			flags = mbs.param[2];
   7003  1.111    mjacob 			period = mbs.param[3] & 0xff;
   7004  1.111    mjacob 			offset = mbs.param[3] >> 8;
   7005  1.111    mjacob 			sdp->isp_devparam[tgt].actv_flags = flags;
   7006  1.111    mjacob 			sdp->isp_devparam[tgt].actv_period = period;
   7007  1.111    mjacob 			sdp->isp_devparam[tgt].actv_offset = offset;
   7008  1.111    mjacob 			get = (bus << 16) | tgt;
   7009  1.111    mjacob 			(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
   7010   1.31    mjacob 		}
   7011   1.10    mjacob 	}
   7012   1.60    mjacob 
   7013   1.60    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   7014   1.60    mjacob 		if (sdp->isp_devparam[tgt].dev_update ||
   7015   1.60    mjacob 		    sdp->isp_devparam[tgt].dev_refresh) {
   7016   1.60    mjacob 			isp->isp_update |= (1 << bus);
   7017   1.60    mjacob 			break;
   7018   1.60    mjacob 		}
   7019   1.60    mjacob 	}
   7020   1.25    mjacob }
   7021   1.10    mjacob 
   7022   1.95    mjacob #ifndef	DEFAULT_EXEC_THROTTLE
   7023   1.95    mjacob #define	DEFAULT_EXEC_THROTTLE(isp)	ISP_EXEC_THROTTLE
   7024   1.95    mjacob #endif
   7025   1.95    mjacob 
   7026   1.25    mjacob static void
   7027  1.111    mjacob isp_setdfltparm(ispsoftc_t *isp, int channel)
   7028   1.25    mjacob {
   7029   1.34    mjacob 	int tgt;
   7030   1.45    mjacob 	sdparam *sdp;
   7031   1.36    mjacob 
   7032   1.45    mjacob 	sdp = (sdparam *) isp->isp_param;
   7033   1.45    mjacob 	sdp += channel;
   7034   1.10    mjacob 
   7035   1.10    mjacob 	/*
   7036   1.25    mjacob 	 * Been there, done that, got the T-shirt...
   7037   1.10    mjacob 	 */
   7038   1.36    mjacob 	if (sdp->isp_gotdparms) {
   7039   1.25    mjacob 		return;
   7040   1.25    mjacob 	}
   7041   1.36    mjacob 	sdp->isp_gotdparms = 1;
   7042  1.111    mjacob 	sdp->isp_bad_nvram = 0;
   7043   1.34    mjacob 	/*
   7044   1.74    mjacob 	 * Establish some default parameters.
   7045   1.74    mjacob 	 */
   7046   1.79    mjacob 	sdp->isp_cmd_dma_burst_enable = 0;
   7047   1.74    mjacob 	sdp->isp_data_dma_burst_enabl = 1;
   7048   1.74    mjacob 	sdp->isp_fifo_threshold = 0;
   7049   1.74    mjacob 	sdp->isp_initiator_id = DEFAULT_IID(isp);
   7050   1.74    mjacob 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
   7051   1.74    mjacob 		sdp->isp_async_data_setup = 9;
   7052   1.74    mjacob 	} else {
   7053   1.74    mjacob 		sdp->isp_async_data_setup = 6;
   7054   1.74    mjacob 	}
   7055   1.74    mjacob 	sdp->isp_selection_timeout = 250;
   7056   1.74    mjacob 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
   7057   1.74    mjacob 	sdp->isp_tag_aging = 8;
   7058   1.79    mjacob 	sdp->isp_bus_reset_delay = 5;
   7059   1.79    mjacob 	/*
   7060   1.79    mjacob 	 * Don't retry selection, busy or queue full automatically- reflect
   7061   1.79    mjacob 	 * these back to us.
   7062   1.79    mjacob 	 */
   7063   1.79    mjacob 	sdp->isp_retry_count = 0;
   7064   1.79    mjacob 	sdp->isp_retry_delay = 0;
   7065   1.74    mjacob 
   7066   1.74    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   7067   1.74    mjacob 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
   7068   1.74    mjacob 		sdp->isp_devparam[tgt].dev_enable = 1;
   7069   1.74    mjacob 	}
   7070   1.74    mjacob 
   7071   1.74    mjacob 	/*
   7072   1.34    mjacob 	 * If we've not been told to avoid reading NVRAM, try and read it.
   7073   1.79    mjacob 	 * If we're successful reading it, we can then return because NVRAM
   7074   1.79    mjacob 	 * will tell us what the desired settings are. Otherwise, we establish
   7075   1.79    mjacob 	 * some reasonable 'fake' nvram and goal defaults.
   7076   1.34    mjacob 	 */
   7077   1.79    mjacob 
   7078   1.34    mjacob 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
   7079   1.34    mjacob 		if (isp_read_nvram(isp) == 0) {
   7080   1.34    mjacob 			return;
   7081   1.34    mjacob 		}
   7082  1.111    mjacob 		sdp->isp_bad_nvram = 1;
   7083   1.25    mjacob 	}
   7084   1.10    mjacob 
   7085   1.36    mjacob 	/*
   7086   1.36    mjacob 	 * Now try and see whether we have specific values for them.
   7087   1.36    mjacob 	 */
   7088   1.45    mjacob 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
   7089  1.111    mjacob 		mbreg_t mbs;
   7090  1.111    mjacob 
   7091  1.111    mjacob 		MEMZERO(&mbs, sizeof (mbs));
   7092   1.45    mjacob 		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
   7093  1.111    mjacob 		mbs.logval = MBLOGNONE;
   7094  1.111    mjacob 		isp_mboxcmd(isp, &mbs);
   7095   1.45    mjacob 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   7096   1.45    mjacob 			sdp->isp_req_ack_active_neg = 1;
   7097   1.45    mjacob 			sdp->isp_data_line_active_neg = 1;
   7098   1.45    mjacob 		} else {
   7099   1.45    mjacob 			sdp->isp_req_ack_active_neg =
   7100   1.45    mjacob 			    (mbs.param[1+channel] >> 4) & 0x1;
   7101   1.45    mjacob 			sdp->isp_data_line_active_neg =
   7102   1.45    mjacob 			    (mbs.param[1+channel] >> 5) & 0x1;
   7103   1.36    mjacob 		}
   7104   1.10    mjacob 	}
   7105   1.32    mjacob 
   7106   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc3,
   7107   1.79    mjacob 	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
   7108   1.79    mjacob 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
   7109   1.79    mjacob 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
   7110   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc3,
   7111   1.79    mjacob 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
   7112   1.79    mjacob 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
   7113   1.79    mjacob 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
   7114   1.45    mjacob 
   7115   1.34    mjacob 	/*
   7116   1.34    mjacob 	 * The trick here is to establish a default for the default (honk!)
   7117   1.79    mjacob 	 * state (goal_flags). Then try and get the current status from
   7118   1.34    mjacob 	 * the card to fill in the current state. We don't, in fact, set
   7119   1.34    mjacob 	 * the default to the SAFE default state- that's not the goal state.
   7120   1.34    mjacob 	 */
   7121   1.34    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   7122  1.111    mjacob 		uint8_t off, per;
   7123   1.79    mjacob 		sdp->isp_devparam[tgt].actv_offset = 0;
   7124   1.79    mjacob 		sdp->isp_devparam[tgt].actv_period = 0;
   7125   1.79    mjacob 		sdp->isp_devparam[tgt].actv_flags = 0;
   7126   1.79    mjacob 
   7127   1.79    mjacob 		sdp->isp_devparam[tgt].goal_flags =
   7128   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
   7129   1.79    mjacob 
   7130   1.48    mjacob 		/*
   7131   1.48    mjacob 		 * We default to Wide/Fast for versions less than a 1040
   7132   1.48    mjacob 		 * (unless it's SBus).
   7133   1.48    mjacob 		 */
   7134   1.79    mjacob 		if (IS_ULTRA3(isp)) {
   7135   1.79    mjacob 			off = ISP_80M_SYNCPARMS >> 8;
   7136   1.79    mjacob 			per = ISP_80M_SYNCPARMS & 0xff;
   7137   1.79    mjacob 		} else if (IS_ULTRA2(isp)) {
   7138   1.79    mjacob 			off = ISP_40M_SYNCPARMS >> 8;
   7139   1.79    mjacob 			per = ISP_40M_SYNCPARMS & 0xff;
   7140   1.79    mjacob 		} else if (IS_1240(isp)) {
   7141   1.79    mjacob 			off = ISP_20M_SYNCPARMS >> 8;
   7142   1.79    mjacob 			per = ISP_20M_SYNCPARMS & 0xff;
   7143   1.79    mjacob 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
   7144   1.48    mjacob 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
   7145   1.48    mjacob 		    (isp->isp_bustype == ISP_BT_PCI &&
   7146   1.48    mjacob 		    isp->isp_type < ISP_HA_SCSI_1040) ||
   7147   1.52        he 		    (isp->isp_clock && isp->isp_clock < 60) ||
   7148   1.52        he 		    (sdp->isp_ultramode == 0)) {
   7149   1.79    mjacob 			off = ISP_10M_SYNCPARMS >> 8;
   7150   1.79    mjacob 			per = ISP_10M_SYNCPARMS & 0xff;
   7151   1.58    mjacob 		} else {
   7152   1.79    mjacob 			off = ISP_20M_SYNCPARMS_1040 >> 8;
   7153   1.79    mjacob 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
   7154   1.10    mjacob 		}
   7155   1.79    mjacob 		sdp->isp_devparam[tgt].goal_offset =
   7156   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset = off;
   7157   1.79    mjacob 		sdp->isp_devparam[tgt].goal_period =
   7158   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period = per;
   7159   1.79    mjacob 
   7160   1.79    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc3,
   7161   1.79    mjacob 		    channel, tgt, sdp->isp_devparam[tgt].nvrm_flags,
   7162   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset,
   7163   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period);
   7164   1.10    mjacob 	}
   7165   1.10    mjacob }
   7166   1.10    mjacob 
   7167  1.111    mjacob #ifndef	DEFAULT_FRAMESIZE
   7168  1.111    mjacob #define	DEFAULT_FRAMESIZE(isp)		ICB_DFLT_FRMLEN
   7169  1.111    mjacob #endif
   7170  1.111    mjacob static void
   7171  1.111    mjacob isp_setdfltfcparm(ispsoftc_t *isp)
   7172  1.111    mjacob {
   7173  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   7174  1.111    mjacob 
   7175  1.111    mjacob 	if (fcp->isp_gotdparms) {
   7176  1.111    mjacob 		return;
   7177  1.111    mjacob 	}
   7178  1.111    mjacob 	fcp->isp_gotdparms = 1;
   7179  1.111    mjacob 	fcp->isp_bad_nvram = 0;
   7180  1.111    mjacob 	fcp->isp_maxfrmlen = DEFAULT_FRAMESIZE(isp);
   7181  1.111    mjacob 	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
   7182  1.111    mjacob 	fcp->isp_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
   7183  1.111    mjacob 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
   7184  1.111    mjacob 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
   7185  1.111    mjacob 	/* Platform specific.... */
   7186  1.111    mjacob 	fcp->isp_loopid = DEFAULT_LOOPID(isp);
   7187  1.111    mjacob 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp);
   7188  1.111    mjacob 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp);
   7189  1.111    mjacob 	fcp->isp_fwoptions = 0;
   7190  1.111    mjacob 	fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
   7191  1.111    mjacob 	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
   7192  1.111    mjacob 	fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
   7193  1.111    mjacob 	fcp->isp_fwoptions |= ICBOPT_FAST_POST;
   7194  1.111    mjacob 	if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
   7195  1.111    mjacob 		fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
   7196  1.111    mjacob 	}
   7197  1.111    mjacob 
   7198  1.111    mjacob 	/*
   7199  1.111    mjacob 	 * Make sure this is turned off now until we get
   7200  1.111    mjacob 	 * extended options from NVRAM
   7201  1.111    mjacob 	 */
   7202  1.111    mjacob 	fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
   7203  1.111    mjacob 
   7204  1.111    mjacob 	/*
   7205  1.111    mjacob 	 * Now try and read NVRAM unless told to not do so.
   7206  1.111    mjacob 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
   7207  1.111    mjacob 	 */
   7208  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
   7209  1.111    mjacob 		int i, j = 0;
   7210  1.111    mjacob 		/*
   7211  1.111    mjacob 		 * Give a couple of tries at reading NVRAM.
   7212  1.111    mjacob 		 */
   7213  1.111    mjacob 		for (i = 0; i < 2; i++) {
   7214  1.111    mjacob 			j = isp_read_nvram(isp);
   7215  1.111    mjacob 			if (j == 0) {
   7216  1.111    mjacob 				break;
   7217  1.111    mjacob 			}
   7218  1.111    mjacob 		}
   7219  1.111    mjacob 		if (j) {
   7220  1.111    mjacob 			fcp->isp_bad_nvram = 1;
   7221  1.111    mjacob 			isp->isp_confopts |= ISP_CFG_NONVRAM;
   7222  1.111    mjacob 			isp->isp_confopts |= ISP_CFG_OWNWWPN;
   7223  1.111    mjacob 			isp->isp_confopts |= ISP_CFG_OWNWWNN;
   7224  1.111    mjacob 		}
   7225  1.111    mjacob 	} else {
   7226  1.111    mjacob 		isp->isp_confopts |= ISP_CFG_OWNWWPN|ISP_CFG_OWNWWNN;
   7227  1.111    mjacob 	}
   7228  1.111    mjacob 
   7229  1.111    mjacob 	/*
   7230  1.111    mjacob 	 * Set node && port to override platform set defaults
   7231  1.111    mjacob 	 * unless the nvram read failed (or none was done),
   7232  1.111    mjacob 	 * or the platform code wants to use what had been
   7233  1.111    mjacob 	 * set in the defaults.
   7234  1.111    mjacob 	 */
   7235  1.111    mjacob 	if (isp->isp_confopts & ISP_CFG_OWNWWNN) {
   7236  1.111    mjacob 		isp_prt(isp, ISP_LOGCONFIG, "Using Node WWN 0x%08x%08x",
   7237  1.111    mjacob 		    (uint32_t) (DEFAULT_NODEWWN(isp) >> 32),
   7238  1.111    mjacob 		    (uint32_t) (DEFAULT_NODEWWN(isp) & 0xffffffff));
   7239  1.111    mjacob 		ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
   7240  1.111    mjacob 	} else {
   7241  1.111    mjacob 		/*
   7242  1.111    mjacob 		 * We always start out with values derived
   7243  1.111    mjacob 		 * from NVRAM or our platform default.
   7244  1.111    mjacob 		 */
   7245  1.111    mjacob 		ISP_NODEWWN(isp) = fcp->isp_wwnn_nvram;
   7246  1.111    mjacob 		if (fcp->isp_wwnn_nvram == 0) {
   7247  1.111    mjacob 			isp_prt(isp, ISP_LOGCONFIG,
   7248  1.111    mjacob 			    "bad WWNN- using default");
   7249  1.111    mjacob 			ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp);
   7250  1.111    mjacob 		}
   7251  1.111    mjacob 	}
   7252  1.111    mjacob 	if (isp->isp_confopts & ISP_CFG_OWNWWPN) {
   7253  1.111    mjacob 		isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x",
   7254  1.111    mjacob 		    (uint32_t) (DEFAULT_PORTWWN(isp) >> 32),
   7255  1.111    mjacob 		    (uint32_t) (DEFAULT_PORTWWN(isp) & 0xffffffff));
   7256  1.111    mjacob 		ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
   7257  1.111    mjacob 	} else {
   7258  1.111    mjacob 		/*
   7259  1.111    mjacob 		 * We always start out with values derived
   7260  1.111    mjacob 		 * from NVRAM or our platform default.
   7261  1.111    mjacob 		 */
   7262  1.111    mjacob 		ISP_PORTWWN(isp) = fcp->isp_wwpn_nvram;
   7263  1.111    mjacob 		if (fcp->isp_wwpn_nvram == 0) {
   7264  1.111    mjacob 			isp_prt(isp, ISP_LOGCONFIG,
   7265  1.111    mjacob 			    "bad WWPN- using default");
   7266  1.111    mjacob 			ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp);
   7267  1.111    mjacob 		}
   7268  1.111    mjacob 	}
   7269  1.111    mjacob }
   7270  1.111    mjacob 
   7271   1.34    mjacob /*
   7272   1.24    mjacob  * Re-initialize the ISP and complete all orphaned commands
   7273   1.38    mjacob  * with a 'botched' notice. The reset/init routines should
   7274   1.38    mjacob  * not disturb an already active list of commands.
   7275   1.24    mjacob  */
   7276   1.24    mjacob 
   7277   1.24    mjacob void
   7278  1.111    mjacob isp_reinit(ispsoftc_t *isp)
   7279   1.10    mjacob {
   7280   1.57    mjacob 	XS_T *xs;
   7281  1.111    mjacob 	uint32_t tmp;
   7282   1.10    mjacob 
   7283  1.103    mjacob 	if (IS_FC(isp)) {
   7284  1.111    mjacob 		ISP_MARK_PORTDB(isp, 0);
   7285  1.103    mjacob 	}
   7286   1.10    mjacob 	isp_reset(isp);
   7287   1.70    mjacob 	if (isp->isp_state != ISP_RESETSTATE) {
   7288   1.70    mjacob 		isp_prt(isp, ISP_LOGERR, "isp_reinit cannot reset card");
   7289   1.95    mjacob 	} else if (isp->isp_role != ISP_ROLE_NONE) {
   7290   1.95    mjacob 		isp_init(isp);
   7291   1.95    mjacob 		if (isp->isp_state == ISP_INITSTATE) {
   7292   1.95    mjacob 			isp->isp_state = ISP_RUNSTATE;
   7293   1.95    mjacob 		}
   7294   1.95    mjacob 		if (isp->isp_state != ISP_RUNSTATE) {
   7295   1.95    mjacob 			isp_prt(isp, ISP_LOGERR,
   7296   1.95    mjacob 			    "isp_reinit cannot restart card");
   7297  1.111    mjacob 			ISP_DISABLE_INTS(isp);
   7298  1.111    mjacob 		}
   7299  1.111    mjacob 	} else {
   7300  1.111    mjacob 		ISP_DISABLE_INTS(isp);
   7301  1.111    mjacob 		if (IS_FC(isp)) {
   7302  1.111    mjacob 			/*
   7303  1.111    mjacob 			 * If we're in ISP_ROLE_NONE, turn off the lasers.
   7304  1.111    mjacob 			 */
   7305  1.111    mjacob 			if (!IS_24XX(isp)) {
   7306  1.111    mjacob 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
   7307  1.111    mjacob 				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
   7308  1.111    mjacob 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
   7309  1.111    mjacob 				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
   7310  1.111    mjacob 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
   7311  1.111    mjacob 			}
   7312   1.95    mjacob 		}
   7313  1.111    mjacob  	}
   7314   1.38    mjacob 	isp->isp_nactive = 0;
   7315   1.10    mjacob 
   7316  1.111    mjacob 	for (tmp = 0; tmp < isp->isp_maxcmds; tmp++) {
   7317  1.111    mjacob 		uint32_t handle;
   7318  1.111    mjacob 
   7319  1.111    mjacob 		xs = isp->isp_xflist[tmp];
   7320   1.38    mjacob 		if (xs == NULL) {
   7321   1.10    mjacob 			continue;
   7322   1.27    mjacob 		}
   7323  1.111    mjacob 		handle = isp_find_handle(isp, xs);
   7324  1.111    mjacob 		if (handle == 0) {
   7325  1.111    mjacob 			continue;
   7326  1.111    mjacob 		}
   7327   1.38    mjacob 		isp_destroy_handle(isp, handle);
   7328   1.38    mjacob 		if (XS_XFRLEN(xs)) {
   7329   1.38    mjacob 			ISP_DMAFREE(isp, xs, handle);
   7330   1.38    mjacob 			XS_RESID(xs) = XS_XFRLEN(xs);
   7331   1.38    mjacob 		} else {
   7332   1.38    mjacob 			XS_RESID(xs) = 0;
   7333   1.38    mjacob 		}
   7334   1.27    mjacob 		XS_SETERR(xs, HBA_BUSRESET);
   7335   1.57    mjacob 		isp_done(xs);
   7336   1.10    mjacob 	}
   7337  1.111    mjacob #ifdef	ISP_TARGET_MODE
   7338  1.111    mjacob 	MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **));
   7339  1.111    mjacob #endif
   7340   1.15    mjacob }
   7341   1.15    mjacob 
   7342   1.28    mjacob /*
   7343   1.25    mjacob  * NVRAM Routines
   7344   1.25    mjacob  */
   7345   1.25    mjacob static int
   7346  1.111    mjacob isp_read_nvram(ispsoftc_t *isp)
   7347   1.25    mjacob {
   7348  1.111    mjacob 	int i, amt, retval;
   7349  1.111    mjacob 	uint8_t csum, minversion;
   7350   1.25    mjacob 	union {
   7351  1.111    mjacob 		uint8_t _x[ISP2100_NVRAM_SIZE];
   7352  1.111    mjacob 		uint16_t _s[ISP2100_NVRAM_SIZE>>1];
   7353   1.25    mjacob 	} _n;
   7354   1.25    mjacob #define	nvram_data	_n._x
   7355   1.25    mjacob #define	nvram_words	_n._s
   7356   1.25    mjacob 
   7357  1.111    mjacob 	if (IS_24XX(isp)) {
   7358  1.111    mjacob 		return (isp_read_nvram_2400(isp));
   7359  1.111    mjacob 	} else if (IS_FC(isp)) {
   7360   1.25    mjacob 		amt = ISP2100_NVRAM_SIZE;
   7361   1.25    mjacob 		minversion = 1;
   7362   1.44    mjacob 	} else if (IS_ULTRA2(isp)) {
   7363   1.36    mjacob 		amt = ISP1080_NVRAM_SIZE;
   7364   1.36    mjacob 		minversion = 0;
   7365   1.25    mjacob 	} else {
   7366   1.25    mjacob 		amt = ISP_NVRAM_SIZE;
   7367   1.25    mjacob 		minversion = 2;
   7368   1.25    mjacob 	}
   7369   1.25    mjacob 
   7370  1.111    mjacob 	for (i = 0; i < amt>>1; i++) {
   7371   1.25    mjacob 		isp_rdnvram_word(isp, i, &nvram_words[i]);
   7372   1.25    mjacob 	}
   7373  1.111    mjacob 
   7374   1.25    mjacob 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
   7375   1.25    mjacob 	    nvram_data[2] != 'P') {
   7376   1.25    mjacob 		if (isp->isp_bustype != ISP_BT_SBUS) {
   7377   1.57    mjacob 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
   7378   1.57    mjacob 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x",
   7379   1.57    mjacob 			    nvram_data[0], nvram_data[1], nvram_data[2]);
   7380   1.25    mjacob 		}
   7381  1.111    mjacob 		retval = -1;
   7382  1.111    mjacob 		goto out;
   7383   1.25    mjacob 	}
   7384  1.111    mjacob 
   7385   1.25    mjacob 	for (csum = 0, i = 0; i < amt; i++) {
   7386   1.25    mjacob 		csum += nvram_data[i];
   7387   1.25    mjacob 	}
   7388   1.25    mjacob 	if (csum != 0) {
   7389   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
   7390  1.111    mjacob 		retval = -1;
   7391  1.111    mjacob 		goto out;
   7392   1.25    mjacob 	}
   7393  1.111    mjacob 
   7394   1.25    mjacob 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
   7395   1.57    mjacob 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
   7396   1.25    mjacob 		    ISP_NVRAM_VERSION(nvram_data));
   7397  1.111    mjacob 		retval = -1;
   7398  1.111    mjacob 		goto out;
   7399   1.25    mjacob 	}
   7400   1.25    mjacob 
   7401   1.49    mjacob 	if (IS_ULTRA3(isp)) {
   7402   1.49    mjacob 		isp_parse_nvram_12160(isp, 0, nvram_data);
   7403   1.99    mjacob 		if (IS_12160(isp))
   7404   1.99    mjacob 			isp_parse_nvram_12160(isp, 1, nvram_data);
   7405   1.49    mjacob 	} else if (IS_1080(isp)) {
   7406   1.49    mjacob 		isp_parse_nvram_1080(isp, 0, nvram_data);
   7407   1.49    mjacob 	} else if (IS_1280(isp) || IS_1240(isp)) {
   7408   1.49    mjacob 		isp_parse_nvram_1080(isp, 0, nvram_data);
   7409   1.49    mjacob 		isp_parse_nvram_1080(isp, 1, nvram_data);
   7410   1.36    mjacob 	} else if (IS_SCSI(isp)) {
   7411   1.49    mjacob 		isp_parse_nvram_1020(isp, nvram_data);
   7412   1.25    mjacob 	} else {
   7413   1.49    mjacob 		isp_parse_nvram_2100(isp, nvram_data);
   7414   1.25    mjacob 	}
   7415  1.111    mjacob 	retval = 0;
   7416  1.111    mjacob out:
   7417  1.111    mjacob 	return (retval);
   7418   1.49    mjacob #undef	nvram_data
   7419   1.49    mjacob #undef	nvram_words
   7420   1.25    mjacob }
   7421   1.25    mjacob 
   7422  1.111    mjacob static int
   7423  1.111    mjacob isp_read_nvram_2400(ispsoftc_t *isp)
   7424  1.111    mjacob {
   7425  1.111    mjacob 	uint8_t *nvram_data = FCPARAM(isp)->isp_scratch;
   7426  1.111    mjacob 	int retval = 0;
   7427  1.111    mjacob 	uint32_t addr, csum, lwrds, *dptr;
   7428  1.111    mjacob 
   7429  1.111    mjacob 	if (isp->isp_port) {
   7430  1.111    mjacob 		addr = ISP2400_NVRAM_PORT1_ADDR;
   7431  1.111    mjacob 	} else {
   7432  1.111    mjacob 		addr = ISP2400_NVRAM_PORT0_ADDR;
   7433  1.111    mjacob 	}
   7434  1.111    mjacob 
   7435  1.111    mjacob 	dptr = (uint32_t *) nvram_data;
   7436  1.111    mjacob 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
   7437  1.111    mjacob 		isp_rd_2400_nvram(isp, addr++, dptr++);
   7438  1.111    mjacob 	}
   7439  1.111    mjacob 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
   7440  1.111    mjacob 	    nvram_data[2] != 'P') {
   7441  1.113    mjacob 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
   7442  1.113    mjacob 		    nvram_data[0], nvram_data[1], nvram_data[2]);
   7443  1.111    mjacob 		retval = -1;
   7444  1.111    mjacob 		goto out;
   7445  1.111    mjacob 	}
   7446  1.111    mjacob 	dptr = (uint32_t *) nvram_data;
   7447  1.111    mjacob 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
   7448  1.113    mjacob 		uint32_t tmp;
   7449  1.113    mjacob 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
   7450  1.113    mjacob 		csum += tmp;
   7451  1.111    mjacob 	}
   7452  1.111    mjacob 	if (csum != 0) {
   7453  1.111    mjacob 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
   7454  1.111    mjacob 		retval = -1;
   7455  1.111    mjacob 		goto out;
   7456  1.111    mjacob 	}
   7457  1.111    mjacob 	isp_parse_nvram_2400(isp, nvram_data);
   7458  1.111    mjacob out:
   7459  1.111    mjacob 	return (retval);
   7460  1.111    mjacob }
   7461  1.111    mjacob 
   7462   1.25    mjacob static void
   7463  1.111    mjacob isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
   7464   1.25    mjacob {
   7465   1.25    mjacob 	int i, cbits;
   7466  1.111    mjacob 	uint16_t bit, rqst, junk;
   7467   1.25    mjacob 
   7468   1.25    mjacob 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
   7469  1.111    mjacob 	USEC_DELAY(10);
   7470   1.25    mjacob 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
   7471  1.111    mjacob 	USEC_DELAY(10);
   7472   1.25    mjacob 
   7473   1.36    mjacob 	if (IS_FC(isp)) {
   7474  1.111    mjacob 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
   7475   1.88    mjacob 		if (IS_2312(isp) && isp->isp_port) {
   7476   1.88    mjacob 			wo += 128;
   7477   1.88    mjacob 		}
   7478   1.36    mjacob 		rqst = (ISP_NVRAM_READ << 8) | wo;
   7479   1.36    mjacob 		cbits = 10;
   7480   1.44    mjacob 	} else if (IS_ULTRA2(isp)) {
   7481   1.36    mjacob 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
   7482   1.25    mjacob 		rqst = (ISP_NVRAM_READ << 8) | wo;
   7483   1.25    mjacob 		cbits = 10;
   7484   1.25    mjacob 	} else {
   7485   1.25    mjacob 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
   7486   1.25    mjacob 		rqst = (ISP_NVRAM_READ << 6) | wo;
   7487   1.25    mjacob 		cbits = 8;
   7488   1.25    mjacob 	}
   7489   1.25    mjacob 
   7490   1.25    mjacob 	/*
   7491   1.25    mjacob 	 * Clock the word select request out...
   7492   1.25    mjacob 	 */
   7493   1.25    mjacob 	for (i = cbits; i >= 0; i--) {
   7494   1.25    mjacob 		if ((rqst >> i) & 1) {
   7495   1.25    mjacob 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
   7496   1.25    mjacob 		} else {
   7497   1.25    mjacob 			bit = BIU_NVRAM_SELECT;
   7498   1.25    mjacob 		}
   7499   1.25    mjacob 		ISP_WRITE(isp, BIU_NVRAM, bit);
   7500  1.111    mjacob 		USEC_DELAY(10);
   7501  1.111    mjacob 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
   7502   1.25    mjacob 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
   7503  1.111    mjacob 		USEC_DELAY(10);
   7504  1.111    mjacob 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
   7505   1.25    mjacob 		ISP_WRITE(isp, BIU_NVRAM, bit);
   7506  1.111    mjacob 		USEC_DELAY(10);
   7507  1.111    mjacob 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
   7508   1.25    mjacob 	}
   7509   1.25    mjacob 	/*
   7510   1.25    mjacob 	 * Now read the result back in (bits come back in MSB format).
   7511   1.25    mjacob 	 */
   7512   1.25    mjacob 	*rp = 0;
   7513   1.25    mjacob 	for (i = 0; i < 16; i++) {
   7514  1.111    mjacob 		uint16_t rv;
   7515   1.25    mjacob 		*rp <<= 1;
   7516   1.25    mjacob 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
   7517  1.111    mjacob 		USEC_DELAY(10);
   7518   1.25    mjacob 		rv = ISP_READ(isp, BIU_NVRAM);
   7519   1.25    mjacob 		if (rv & BIU_NVRAM_DATAIN) {
   7520   1.25    mjacob 			*rp |= 1;
   7521   1.25    mjacob 		}
   7522  1.111    mjacob 		USEC_DELAY(10);
   7523   1.25    mjacob 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
   7524  1.111    mjacob 		USEC_DELAY(10);
   7525  1.111    mjacob 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
   7526   1.25    mjacob 	}
   7527   1.25    mjacob 	ISP_WRITE(isp, BIU_NVRAM, 0);
   7528  1.111    mjacob 	USEC_DELAY(10);
   7529  1.111    mjacob 	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
   7530   1.57    mjacob 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
   7531   1.49    mjacob }
   7532   1.49    mjacob 
   7533   1.49    mjacob static void
   7534  1.111    mjacob isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
   7535  1.111    mjacob {
   7536  1.111    mjacob 	int loops = 0;
   7537  1.111    mjacob 	const uint32_t base = 0x7ffe0000;
   7538  1.111    mjacob 	uint32_t tmp = 0;
   7539  1.111    mjacob 
   7540  1.111    mjacob 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
   7541  1.111    mjacob 	for (loops = 0; loops < 5000; loops++) {
   7542  1.111    mjacob 		USEC_DELAY(10);
   7543  1.111    mjacob 		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
   7544  1.111    mjacob 		if ((tmp & (1U << 31)) != 0) {
   7545  1.111    mjacob 			break;
   7546  1.111    mjacob 		}
   7547  1.111    mjacob 	}
   7548  1.111    mjacob 	if (tmp & (1U << 31)) {
   7549  1.113    mjacob 		*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
   7550  1.113    mjacob 		ISP_SWIZZLE_NVRAM_LONG(isp, rp);
   7551  1.111    mjacob 	} else {
   7552  1.111    mjacob 		*rp = 0xffffffff;
   7553  1.111    mjacob 	}
   7554  1.111    mjacob }
   7555  1.111    mjacob 
   7556  1.111    mjacob static void
   7557  1.111    mjacob isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
   7558   1.49    mjacob {
   7559   1.49    mjacob 	sdparam *sdp = (sdparam *) isp->isp_param;
   7560   1.79    mjacob 	int tgt;
   7561   1.49    mjacob 
   7562   1.49    mjacob 	sdp->isp_fifo_threshold =
   7563   1.49    mjacob 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
   7564   1.49    mjacob 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
   7565   1.49    mjacob 
   7566   1.96    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
   7567   1.96    mjacob 		sdp->isp_initiator_id =
   7568   1.96    mjacob 			ISP_NVRAM_INITIATOR_ID(nvram_data);
   7569   1.49    mjacob 
   7570   1.49    mjacob 	sdp->isp_bus_reset_delay =
   7571   1.49    mjacob 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
   7572   1.49    mjacob 
   7573   1.49    mjacob 	sdp->isp_retry_count =
   7574   1.49    mjacob 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
   7575   1.49    mjacob 
   7576   1.49    mjacob 	sdp->isp_retry_delay =
   7577   1.49    mjacob 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
   7578   1.49    mjacob 
   7579   1.49    mjacob 	sdp->isp_async_data_setup =
   7580   1.49    mjacob 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
   7581   1.49    mjacob 
   7582   1.49    mjacob 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
   7583   1.49    mjacob 		if (sdp->isp_async_data_setup < 9) {
   7584   1.49    mjacob 			sdp->isp_async_data_setup = 9;
   7585   1.49    mjacob 		}
   7586   1.49    mjacob 	} else {
   7587   1.49    mjacob 		if (sdp->isp_async_data_setup != 6) {
   7588   1.49    mjacob 			sdp->isp_async_data_setup = 6;
   7589   1.49    mjacob 		}
   7590   1.49    mjacob 	}
   7591   1.49    mjacob 
   7592   1.49    mjacob 	sdp->isp_req_ack_active_neg =
   7593   1.49    mjacob 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
   7594   1.49    mjacob 
   7595   1.49    mjacob 	sdp->isp_data_line_active_neg =
   7596   1.49    mjacob 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
   7597   1.49    mjacob 
   7598   1.49    mjacob 	sdp->isp_data_dma_burst_enabl =
   7599   1.49    mjacob 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
   7600   1.49    mjacob 
   7601   1.49    mjacob 	sdp->isp_cmd_dma_burst_enable =
   7602   1.49    mjacob 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
   7603   1.49    mjacob 
   7604   1.49    mjacob 	sdp->isp_tag_aging =
   7605   1.49    mjacob 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
   7606   1.49    mjacob 
   7607   1.49    mjacob 	sdp->isp_selection_timeout =
   7608   1.49    mjacob 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
   7609   1.49    mjacob 
   7610   1.49    mjacob 	sdp->isp_max_queue_depth =
   7611   1.49    mjacob 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
   7612   1.49    mjacob 
   7613   1.58    mjacob 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
   7614   1.49    mjacob 
   7615   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
   7616   1.79    mjacob 	    0, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
   7617   1.79    mjacob 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
   7618   1.79    mjacob 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
   7619   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
   7620   1.79    mjacob 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
   7621   1.79    mjacob 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
   7622   1.79    mjacob 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
   7623   1.79    mjacob 
   7624   1.79    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   7625   1.79    mjacob 		sdp->isp_devparam[tgt].dev_enable =
   7626   1.79    mjacob 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
   7627   1.79    mjacob 		sdp->isp_devparam[tgt].exc_throttle =
   7628   1.79    mjacob 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
   7629   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_offset =
   7630   1.79    mjacob 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
   7631   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_period =
   7632   1.79    mjacob 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
   7633   1.79    mjacob 		/*
   7634   1.79    mjacob 		 * We probably shouldn't lie about this, but it
   7635   1.79    mjacob 		 * it makes it much safer if we limit NVRAM values
   7636   1.79    mjacob 		 * to sanity.
   7637   1.79    mjacob 		 */
   7638   1.49    mjacob 		if (isp->isp_type < ISP_HA_SCSI_1040) {
   7639   1.49    mjacob 			/*
   7640   1.49    mjacob 			 * If we're not ultra, we can't possibly
   7641   1.49    mjacob 			 * be a shorter period than this.
   7642   1.49    mjacob 			 */
   7643   1.79    mjacob 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
   7644   1.79    mjacob 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
   7645   1.49    mjacob 			}
   7646   1.79    mjacob 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
   7647   1.79    mjacob 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
   7648   1.49    mjacob 			}
   7649   1.49    mjacob 		} else {
   7650   1.79    mjacob 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
   7651   1.79    mjacob 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
   7652   1.49    mjacob 			}
   7653   1.49    mjacob 		}
   7654   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_flags = 0;
   7655   1.79    mjacob 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
   7656   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
   7657   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
   7658   1.79    mjacob 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
   7659   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
   7660   1.79    mjacob 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
   7661   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
   7662   1.79    mjacob 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
   7663   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
   7664   1.79    mjacob 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
   7665   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
   7666   1.79    mjacob 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
   7667   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
   7668   1.79    mjacob 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
   7669   1.79    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
   7670   1.79    mjacob 		    0, tgt, sdp->isp_devparam[tgt].nvrm_flags,
   7671   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset,
   7672   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period);
   7673   1.79    mjacob 		sdp->isp_devparam[tgt].goal_offset =
   7674   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset;
   7675   1.79    mjacob 		sdp->isp_devparam[tgt].goal_period =
   7676   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period;
   7677   1.79    mjacob 		sdp->isp_devparam[tgt].goal_flags =
   7678   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_flags;
   7679   1.49    mjacob 	}
   7680   1.49    mjacob }
   7681   1.49    mjacob 
   7682   1.49    mjacob static void
   7683  1.111    mjacob isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
   7684   1.49    mjacob {
   7685   1.49    mjacob 	sdparam *sdp = (sdparam *) isp->isp_param;
   7686   1.79    mjacob 	int tgt;
   7687   1.79    mjacob 
   7688   1.49    mjacob 	sdp += bus;
   7689   1.49    mjacob 
   7690   1.78    mjacob 	sdp->isp_fifo_threshold =
   7691   1.49    mjacob 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
   7692   1.49    mjacob 
   7693   1.96    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
   7694   1.96    mjacob 		sdp->isp_initiator_id =
   7695   1.96    mjacob 		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
   7696   1.49    mjacob 
   7697   1.49    mjacob 	sdp->isp_bus_reset_delay =
   7698   1.49    mjacob 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
   7699   1.49    mjacob 
   7700   1.49    mjacob 	sdp->isp_retry_count =
   7701   1.49    mjacob 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
   7702   1.49    mjacob 
   7703   1.49    mjacob 	sdp->isp_retry_delay =
   7704   1.49    mjacob 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
   7705   1.49    mjacob 
   7706   1.49    mjacob 	sdp->isp_async_data_setup =
   7707   1.79    mjacob 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
   7708   1.49    mjacob 
   7709   1.49    mjacob 	sdp->isp_req_ack_active_neg =
   7710   1.79    mjacob 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
   7711   1.49    mjacob 
   7712   1.49    mjacob 	sdp->isp_data_line_active_neg =
   7713   1.79    mjacob 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
   7714   1.49    mjacob 
   7715   1.49    mjacob 	sdp->isp_data_dma_burst_enabl =
   7716   1.49    mjacob 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
   7717   1.49    mjacob 
   7718   1.49    mjacob 	sdp->isp_cmd_dma_burst_enable =
   7719   1.49    mjacob 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
   7720   1.49    mjacob 
   7721   1.49    mjacob 	sdp->isp_selection_timeout =
   7722   1.49    mjacob 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
   7723   1.49    mjacob 
   7724   1.49    mjacob 	sdp->isp_max_queue_depth =
   7725   1.49    mjacob 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
   7726   1.49    mjacob 
   7727   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
   7728   1.79    mjacob 	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
   7729   1.79    mjacob 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
   7730   1.79    mjacob 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
   7731   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
   7732   1.79    mjacob 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
   7733   1.79    mjacob 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
   7734   1.79    mjacob 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
   7735   1.79    mjacob 
   7736   1.79    mjacob 
   7737   1.79    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   7738   1.79    mjacob 		sdp->isp_devparam[tgt].dev_enable =
   7739   1.79    mjacob 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
   7740   1.79    mjacob 		sdp->isp_devparam[tgt].exc_throttle =
   7741   1.79    mjacob 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
   7742   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_offset =
   7743   1.79    mjacob 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
   7744   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_period =
   7745   1.79    mjacob 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
   7746   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_flags = 0;
   7747   1.79    mjacob 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
   7748   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
   7749   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
   7750   1.79    mjacob 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
   7751   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
   7752   1.79    mjacob 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
   7753   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
   7754   1.79    mjacob 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
   7755   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
   7756   1.79    mjacob 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
   7757   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
   7758   1.79    mjacob 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
   7759   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
   7760   1.79    mjacob 		sdp->isp_devparam[tgt].actv_flags = 0;
   7761   1.79    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
   7762   1.79    mjacob 		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
   7763   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset,
   7764   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period);
   7765   1.79    mjacob 		sdp->isp_devparam[tgt].goal_offset =
   7766   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset;
   7767   1.79    mjacob 		sdp->isp_devparam[tgt].goal_period =
   7768   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period;
   7769   1.79    mjacob 		sdp->isp_devparam[tgt].goal_flags =
   7770   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_flags;
   7771   1.49    mjacob 	}
   7772   1.49    mjacob }
   7773   1.49    mjacob 
   7774   1.49    mjacob static void
   7775  1.111    mjacob isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
   7776   1.49    mjacob {
   7777   1.49    mjacob 	sdparam *sdp = (sdparam *) isp->isp_param;
   7778   1.79    mjacob 	int tgt;
   7779   1.49    mjacob 
   7780   1.49    mjacob 	sdp += bus;
   7781   1.49    mjacob 
   7782   1.49    mjacob 	sdp->isp_fifo_threshold =
   7783   1.49    mjacob 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
   7784   1.49    mjacob 
   7785   1.96    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
   7786   1.96    mjacob 		sdp->isp_initiator_id =
   7787   1.96    mjacob 		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
   7788   1.49    mjacob 
   7789   1.49    mjacob 	sdp->isp_bus_reset_delay =
   7790   1.49    mjacob 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
   7791   1.49    mjacob 
   7792   1.49    mjacob 	sdp->isp_retry_count =
   7793   1.49    mjacob 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
   7794   1.49    mjacob 
   7795   1.49    mjacob 	sdp->isp_retry_delay =
   7796   1.49    mjacob 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
   7797   1.49    mjacob 
   7798   1.49    mjacob 	sdp->isp_async_data_setup =
   7799   1.79    mjacob 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
   7800   1.49    mjacob 
   7801   1.49    mjacob 	sdp->isp_req_ack_active_neg =
   7802   1.79    mjacob 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
   7803   1.49    mjacob 
   7804   1.49    mjacob 	sdp->isp_data_line_active_neg =
   7805   1.79    mjacob 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
   7806   1.49    mjacob 
   7807   1.49    mjacob 	sdp->isp_data_dma_burst_enabl =
   7808   1.49    mjacob 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
   7809   1.49    mjacob 
   7810   1.49    mjacob 	sdp->isp_cmd_dma_burst_enable =
   7811   1.49    mjacob 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
   7812   1.49    mjacob 
   7813   1.49    mjacob 	sdp->isp_selection_timeout =
   7814   1.49    mjacob 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
   7815   1.49    mjacob 
   7816   1.49    mjacob 	sdp->isp_max_queue_depth =
   7817   1.49    mjacob 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
   7818   1.49    mjacob 
   7819   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc0, sc4,
   7820   1.79    mjacob 	    bus, sdp->isp_fifo_threshold, sdp->isp_initiator_id,
   7821   1.79    mjacob 	    sdp->isp_bus_reset_delay, sdp->isp_retry_count,
   7822   1.79    mjacob 	    sdp->isp_retry_delay, sdp->isp_async_data_setup);
   7823   1.79    mjacob 	isp_prt(isp, ISP_LOGDEBUG0, sc1, sc4,
   7824   1.79    mjacob 	    sdp->isp_req_ack_active_neg, sdp->isp_data_line_active_neg,
   7825   1.79    mjacob 	    sdp->isp_data_dma_burst_enabl, sdp->isp_cmd_dma_burst_enable,
   7826   1.79    mjacob 	    sdp->isp_selection_timeout, sdp->isp_max_queue_depth);
   7827   1.79    mjacob 
   7828   1.79    mjacob 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
   7829   1.79    mjacob 		sdp->isp_devparam[tgt].dev_enable =
   7830   1.79    mjacob 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
   7831   1.79    mjacob 		sdp->isp_devparam[tgt].exc_throttle =
   7832   1.79    mjacob 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
   7833   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_offset =
   7834   1.79    mjacob 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
   7835   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_period =
   7836   1.79    mjacob 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
   7837   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_flags = 0;
   7838   1.79    mjacob 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
   7839   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
   7840   1.79    mjacob 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
   7841   1.79    mjacob 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
   7842   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
   7843   1.79    mjacob 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
   7844   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
   7845   1.79    mjacob 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
   7846   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
   7847   1.79    mjacob 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
   7848   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
   7849   1.79    mjacob 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
   7850   1.79    mjacob 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
   7851   1.79    mjacob 		sdp->isp_devparam[tgt].actv_flags = 0;
   7852   1.79    mjacob 		isp_prt(isp, ISP_LOGDEBUG0, sc2, sc4,
   7853   1.79    mjacob 		    bus, tgt, sdp->isp_devparam[tgt].nvrm_flags,
   7854   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset,
   7855   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period);
   7856   1.79    mjacob 		sdp->isp_devparam[tgt].goal_offset =
   7857   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_offset;
   7858   1.79    mjacob 		sdp->isp_devparam[tgt].goal_period =
   7859   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_period;
   7860   1.79    mjacob 		sdp->isp_devparam[tgt].goal_flags =
   7861   1.79    mjacob 		    sdp->isp_devparam[tgt].nvrm_flags;
   7862   1.49    mjacob 	}
   7863   1.49    mjacob }
   7864   1.49    mjacob 
   7865   1.49    mjacob static void
   7866  1.111    mjacob isp_fix_nvram_wwns(ispsoftc_t *isp)
   7867  1.111    mjacob {
   7868  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   7869  1.111    mjacob 
   7870  1.111    mjacob 	/*
   7871  1.111    mjacob 	 * Make sure we have both Node and Port as non-zero values.
   7872  1.111    mjacob 	 */
   7873  1.111    mjacob 	if (fcp->isp_wwnn_nvram != 0 && fcp->isp_wwpn_nvram == 0) {
   7874  1.111    mjacob 		fcp->isp_wwpn_nvram = fcp->isp_wwnn_nvram;
   7875  1.111    mjacob 	} else if (fcp->isp_wwnn_nvram == 0 && fcp->isp_wwpn_nvram != 0) {
   7876  1.111    mjacob 		fcp->isp_wwnn_nvram = fcp->isp_wwpn_nvram;
   7877  1.111    mjacob 	}
   7878  1.111    mjacob 
   7879  1.111    mjacob 	/*
   7880  1.111    mjacob 	 * Make the Node and Port values sane if they're NAA == 2.
   7881  1.111    mjacob 	 * This means to clear bits 48..56 for the Node WWN and
   7882  1.111    mjacob 	 * make sure that there's some non-zero value in 48..56
   7883  1.111    mjacob 	 * for the Port WWN.
   7884  1.111    mjacob 	 */
   7885  1.111    mjacob 	if (fcp->isp_wwnn_nvram && fcp->isp_wwpn_nvram) {
   7886  1.111    mjacob 		if ((fcp->isp_wwnn_nvram & (((uint64_t) 0xfff) << 48)) != 0 &&
   7887  1.111    mjacob 		    (fcp->isp_wwnn_nvram >> 60) == 2) {
   7888  1.111    mjacob 			fcp->isp_wwnn_nvram &= ~((uint64_t) 0xfff << 48);
   7889  1.111    mjacob 		}
   7890  1.111    mjacob 		if ((fcp->isp_wwpn_nvram & (((uint64_t) 0xfff) << 48)) == 0 &&
   7891  1.111    mjacob 		    (fcp->isp_wwpn_nvram >> 60) == 2) {
   7892  1.111    mjacob 			fcp->isp_wwpn_nvram |= ((uint64_t) 1 << 56);
   7893  1.111    mjacob 		}
   7894  1.111    mjacob 	}
   7895  1.111    mjacob }
   7896  1.111    mjacob 
   7897  1.111    mjacob static void
   7898  1.111    mjacob isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
   7899   1.49    mjacob {
   7900  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   7901  1.111    mjacob 	uint64_t wwn;
   7902   1.49    mjacob 
   7903   1.49    mjacob 	/*
   7904   1.62    mjacob 	 * There is NVRAM storage for both Port and Node entities-
   7905   1.62    mjacob 	 * but the Node entity appears to be unused on all the cards
   7906   1.62    mjacob 	 * I can find. However, we should account for this being set
   7907   1.62    mjacob 	 * at some point in the future.
   7908   1.62    mjacob 	 *
   7909   1.62    mjacob 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
   7910   1.62    mjacob 	 * bits 48..60. In the case of the 2202, it appears that they do
   7911   1.62    mjacob 	 * use bit 48 to distinguish between the two instances on the card.
   7912   1.62    mjacob 	 * The 2204, which I've never seen, *probably* extends this method.
   7913   1.62    mjacob 	 */
   7914   1.62    mjacob 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
   7915   1.62    mjacob 	if (wwn) {
   7916   1.62    mjacob 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
   7917  1.111    mjacob 		    (uint32_t) (wwn >> 32), (uint32_t) (wwn & 0xffffffff));
   7918   1.62    mjacob 		if ((wwn >> 60) == 0) {
   7919  1.111    mjacob 			wwn |= (((uint64_t) 2)<< 60);
   7920   1.62    mjacob 		}
   7921   1.62    mjacob 	}
   7922  1.111    mjacob 	fcp->isp_wwpn_nvram = wwn;
   7923   1.88    mjacob 	if (IS_2200(isp) || IS_23XX(isp)) {
   7924  1.111    mjacob 		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
   7925   1.88    mjacob 		if (wwn) {
   7926   1.88    mjacob 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
   7927  1.111    mjacob 			    (uint32_t) (wwn >> 32),
   7928  1.111    mjacob 			    (uint32_t) (wwn & 0xffffffff));
   7929   1.88    mjacob 			if ((wwn >> 60) == 0) {
   7930  1.111    mjacob 				wwn |= (((uint64_t) 2)<< 60);
   7931   1.88    mjacob 			}
   7932   1.62    mjacob 		}
   7933   1.88    mjacob 	} else {
   7934  1.111    mjacob 		wwn &= ~((uint64_t) 0xfff << 48);
   7935  1.111    mjacob 	}
   7936  1.111    mjacob 	fcp->isp_wwnn_nvram = wwn;
   7937  1.111    mjacob 
   7938  1.111    mjacob 	isp_fix_nvram_wwns(isp);
   7939  1.111    mjacob 
   7940  1.111    mjacob 	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
   7941  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
   7942  1.111    mjacob 		fcp->isp_maxfrmlen = ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
   7943  1.111    mjacob 	}
   7944  1.111    mjacob 	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
   7945  1.111    mjacob 	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
   7946  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
   7947  1.111    mjacob 		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
   7948  1.111    mjacob 	}
   7949  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
   7950  1.111    mjacob 		fcp->isp_execthrottle =
   7951  1.111    mjacob 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
   7952   1.62    mjacob 	}
   7953  1.111    mjacob 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
   7954  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   7955  1.111    mjacob 	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
   7956  1.111    mjacob 	    (uint32_t) (fcp->isp_wwnn_nvram >> 32), (uint32_t) fcp->isp_wwnn_nvram,
   7957  1.111    mjacob 	    (uint32_t) (fcp->isp_wwpn_nvram >> 32), (uint32_t) fcp->isp_wwpn_nvram,
   7958  1.111    mjacob 	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
   7959  1.111    mjacob 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
   7960  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   7961  1.111    mjacob 	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
   7962  1.111    mjacob 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
   7963  1.111    mjacob 	    ISP2100_NVRAM_OPTIONS(nvram_data),
   7964  1.111    mjacob 	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
   7965  1.111    mjacob 	    ISP2100_NVRAM_TOV(nvram_data));
   7966  1.111    mjacob 	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
   7967  1.111    mjacob 	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
   7968  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   7969  1.111    mjacob 	    "xfwoptions 0x%x zfw options 0x%x",
   7970  1.111    mjacob 	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
   7971  1.111    mjacob }
   7972  1.111    mjacob 
   7973  1.111    mjacob static void
   7974  1.111    mjacob isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
   7975  1.111    mjacob {
   7976  1.111    mjacob 	fcparam *fcp = FCPARAM(isp);
   7977  1.111    mjacob 	uint64_t wwn;
   7978  1.111    mjacob 
   7979  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   7980  1.111    mjacob 	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
   7981  1.111    mjacob 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
   7982  1.111    mjacob 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
   7983  1.111    mjacob 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
   7984  1.111    mjacob 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
   7985  1.111    mjacob 	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
   7986  1.111    mjacob 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
   7987  1.111    mjacob 	isp_prt(isp, ISP_LOGDEBUG0,
   7988  1.111    mjacob 	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
   7989  1.111    mjacob 	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
   7990  1.111    mjacob 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
   7991  1.111    mjacob 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
   7992  1.111    mjacob 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
   7993  1.111    mjacob 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
   7994   1.62    mjacob 
   7995  1.111    mjacob 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
   7996  1.111    mjacob 	if (wwn) {
   7997  1.111    mjacob 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
   7998  1.111    mjacob 			wwn = 0;
   7999  1.111    mjacob 		}
   8000   1.62    mjacob 	}
   8001  1.111    mjacob 	fcp->isp_wwpn_nvram = wwn;
   8002   1.52        he 
   8003  1.111    mjacob 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
   8004  1.111    mjacob 	if (wwn) {
   8005  1.111    mjacob 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
   8006  1.111    mjacob 			wwn = 0;
   8007   1.52        he 		}
   8008   1.49    mjacob 	}
   8009  1.111    mjacob 	fcp->isp_wwnn_nvram = wwn;
   8010   1.62    mjacob 
   8011  1.111    mjacob 	isp_fix_nvram_wwns(isp);
   8012   1.95    mjacob 
   8013  1.111    mjacob 	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
   8014  1.111    mjacob 		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
   8015  1.111    mjacob 	}
   8016  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
   8017  1.111    mjacob 		fcp->isp_maxfrmlen = ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
   8018  1.111    mjacob 	}
   8019  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
   8020  1.111    mjacob 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
   8021  1.111    mjacob 	}
   8022  1.111    mjacob 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
   8023   1.95    mjacob 		fcp->isp_execthrottle =
   8024  1.111    mjacob 			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
   8025  1.111    mjacob 	}
   8026  1.111    mjacob 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
   8027  1.111    mjacob 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
   8028  1.111    mjacob 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
   8029    1.1       cgd }
   8030   1.88    mjacob 
   8031   1.88    mjacob #ifdef	ISP_FW_CRASH_DUMP
   8032  1.111    mjacob static void isp2200_fw_dump(ispsoftc_t *);
   8033  1.111    mjacob static void isp2300_fw_dump(ispsoftc_t *);
   8034   1.88    mjacob 
   8035   1.88    mjacob static void
   8036  1.111    mjacob isp2200_fw_dump(ispsoftc_t *isp)
   8037   1.88    mjacob {
   8038   1.88    mjacob 	int i, j;
   8039   1.88    mjacob 	mbreg_t mbs;
   8040  1.111    mjacob 	uint16_t *ptr;
   8041   1.88    mjacob 
   8042  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   8043   1.88    mjacob 	ptr = FCPARAM(isp)->isp_dump_data;
   8044   1.88    mjacob 	if (ptr == NULL) {
   8045   1.88    mjacob 		isp_prt(isp, ISP_LOGERR,
   8046   1.88    mjacob 		   "No place to dump RISC registers and SRAM");
   8047   1.88    mjacob 		return;
   8048   1.88    mjacob 	}
   8049   1.88    mjacob 	if (*ptr++) {
   8050   1.88    mjacob 		isp_prt(isp, ISP_LOGERR,
   8051   1.88    mjacob 		   "dump area for RISC registers and SRAM already used");
   8052   1.88    mjacob 		return;
   8053   1.88    mjacob 	}
   8054   1.88    mjacob 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
   8055   1.88    mjacob 	for (i = 0; i < 100; i++) {
   8056   1.88    mjacob 		USEC_DELAY(100);
   8057   1.88    mjacob 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
   8058   1.88    mjacob 			break;
   8059   1.88    mjacob 		}
   8060   1.88    mjacob 	}
   8061   1.88    mjacob 	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
   8062   1.88    mjacob 		/*
   8063   1.88    mjacob 		 * PBIU Registers
   8064   1.88    mjacob 		 */
   8065   1.88    mjacob 		for (i = 0; i < 8; i++) {
   8066   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
   8067   1.88    mjacob 		}
   8068   1.88    mjacob 
   8069   1.88    mjacob 		/*
   8070   1.88    mjacob 		 * Mailbox Registers
   8071   1.88    mjacob 		 */
   8072   1.88    mjacob 		for (i = 0; i < 8; i++) {
   8073   1.88    mjacob 			*ptr++ = ISP_READ(isp, MBOX_BLOCK + (i << 1));
   8074   1.88    mjacob 		}
   8075   1.88    mjacob 
   8076   1.88    mjacob 		/*
   8077   1.88    mjacob 		 * DMA Registers
   8078   1.88    mjacob 		 */
   8079   1.88    mjacob 		for (i = 0; i < 48; i++) {
   8080   1.88    mjacob 			*ptr++ = ISP_READ(isp, DMA_BLOCK + 0x20 + (i << 1));
   8081   1.88    mjacob 		}
   8082   1.88    mjacob 
   8083   1.88    mjacob 		/*
   8084   1.88    mjacob 		 * RISC H/W Registers
   8085   1.88    mjacob 		 */
   8086   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0);
   8087   1.88    mjacob 		for (i = 0; i < 16; i++) {
   8088   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
   8089   1.88    mjacob 		}
   8090   1.88    mjacob 
   8091   1.88    mjacob 		/*
   8092   1.88    mjacob 		 * RISC GP Registers
   8093   1.88    mjacob 		 */
   8094   1.88    mjacob 		for (j = 0; j < 8; j++) {
   8095   1.88    mjacob 			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 8));
   8096   1.88    mjacob 			for (i = 0; i < 16; i++) {
   8097   1.88    mjacob 				*ptr++ =
   8098   1.88    mjacob 				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8099   1.88    mjacob 			}
   8100   1.88    mjacob 		}
   8101   1.88    mjacob 
   8102   1.88    mjacob 		/*
   8103   1.88    mjacob 		 * Frame Buffer Hardware Registers
   8104   1.88    mjacob 		 */
   8105   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x10);
   8106   1.88    mjacob 		for (i = 0; i < 16; i++) {
   8107   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8108   1.88    mjacob 		}
   8109   1.88    mjacob 
   8110   1.88    mjacob 		/*
   8111   1.88    mjacob 		 * Fibre Protocol Module 0 Hardware Registers
   8112   1.88    mjacob 		 */
   8113   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x20);
   8114   1.88    mjacob 		for (i = 0; i < 64; i++) {
   8115   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8116   1.88    mjacob 		}
   8117   1.88    mjacob 
   8118   1.88    mjacob 		/*
   8119   1.88    mjacob 		 * Fibre Protocol Module 1 Hardware Registers
   8120   1.88    mjacob 		 */
   8121   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x30);
   8122   1.88    mjacob 		for (i = 0; i < 64; i++) {
   8123   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8124   1.88    mjacob 		}
   8125   1.88    mjacob 	} else {
   8126   1.88    mjacob 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
   8127   1.88    mjacob 		return;
   8128   1.88    mjacob 	}
   8129   1.88    mjacob 	isp_prt(isp, ISP_LOGALL,
   8130   1.88    mjacob 	   "isp_fw_dump: RISC registers dumped successfully");
   8131   1.88    mjacob 	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
   8132   1.88    mjacob 	for (i = 0; i < 100; i++) {
   8133   1.88    mjacob 		USEC_DELAY(100);
   8134   1.88    mjacob 		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
   8135   1.88    mjacob 			break;
   8136   1.88    mjacob 		}
   8137   1.88    mjacob 	}
   8138   1.88    mjacob 	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
   8139   1.88    mjacob 		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
   8140   1.88    mjacob 		return;
   8141   1.88    mjacob 	}
   8142   1.88    mjacob 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
   8143   1.88    mjacob 	for (i = 0; i < 100; i++) {
   8144   1.88    mjacob 		USEC_DELAY(100);
   8145   1.88    mjacob 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
   8146   1.88    mjacob 			break;
   8147   1.88    mjacob 		}
   8148   1.88    mjacob 	}
   8149   1.88    mjacob 	if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
   8150   1.88    mjacob 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause After Reset");
   8151   1.88    mjacob 		return;
   8152   1.88    mjacob 	}
   8153   1.88    mjacob 	ISP_WRITE(isp, RISC_EMB, 0xf2);
   8154   1.88    mjacob 	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
   8155   1.88    mjacob 	for (i = 0; i < 100; i++) {
   8156   1.88    mjacob 		USEC_DELAY(100);
   8157   1.88    mjacob 		if ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) {
   8158   1.88    mjacob 			break;
   8159   1.88    mjacob 		}
   8160   1.88    mjacob 	}
   8161  1.111    mjacob 	ISP_ENABLE_INTS(isp);
   8162   1.88    mjacob 	mbs.param[0] = MBOX_READ_RAM_WORD;
   8163   1.88    mjacob 	mbs.param[1] = 0x1000;
   8164   1.88    mjacob 	isp->isp_mbxworkp = (void *) ptr;
   8165   1.88    mjacob 	isp->isp_mbxwrk0 = 0xefff;	/* continuation count */
   8166   1.88    mjacob 	isp->isp_mbxwrk1 = 0x1001;	/* next SRAM address */
   8167   1.88    mjacob 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
   8168   1.88    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   8169   1.88    mjacob 		isp_prt(isp, ISP_LOGWARN,
   8170   1.88    mjacob 		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
   8171   1.88    mjacob 		return;
   8172   1.88    mjacob 	}
   8173   1.88    mjacob 	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
   8174   1.88    mjacob 	*ptr++ = isp->isp_mboxtmp[2];
   8175  1.101    mjacob 	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
   8176   1.88    mjacob 	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
   8177   1.96    mjacob 	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
   8178   1.88    mjacob }
   8179   1.88    mjacob 
   8180   1.88    mjacob static void
   8181  1.111    mjacob isp2300_fw_dump(ispsoftc_t *isp)
   8182   1.88    mjacob {
   8183   1.88    mjacob 	int i, j;
   8184   1.88    mjacob 	mbreg_t mbs;
   8185  1.111    mjacob 	uint16_t *ptr;
   8186   1.88    mjacob 
   8187  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   8188   1.88    mjacob 	ptr = FCPARAM(isp)->isp_dump_data;
   8189   1.88    mjacob 	if (ptr == NULL) {
   8190   1.88    mjacob 		isp_prt(isp, ISP_LOGERR,
   8191   1.88    mjacob 		   "No place to dump RISC registers and SRAM");
   8192   1.88    mjacob 		return;
   8193   1.88    mjacob 	}
   8194   1.88    mjacob 	if (*ptr++) {
   8195   1.88    mjacob 		isp_prt(isp, ISP_LOGERR,
   8196   1.88    mjacob 		   "dump area for RISC registers and SRAM already used");
   8197   1.88    mjacob 		return;
   8198   1.88    mjacob 	}
   8199   1.88    mjacob 	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
   8200   1.88    mjacob 	for (i = 0; i < 100; i++) {
   8201   1.88    mjacob 		USEC_DELAY(100);
   8202   1.88    mjacob 		if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
   8203   1.88    mjacob 			break;
   8204   1.88    mjacob 		}
   8205   1.88    mjacob 	}
   8206   1.88    mjacob 	if (ISP_READ(isp, HCCR) & HCCR_PAUSE) {
   8207   1.88    mjacob 		/*
   8208   1.88    mjacob 		 * PBIU registers
   8209   1.88    mjacob 		 */
   8210   1.88    mjacob 		for (i = 0; i < 8; i++) {
   8211   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + (i << 1));
   8212   1.88    mjacob 		}
   8213   1.88    mjacob 
   8214   1.88    mjacob 		/*
   8215   1.88    mjacob 		 * ReqQ-RspQ-Risc2Host Status registers
   8216   1.88    mjacob 		 */
   8217   1.88    mjacob 		for (i = 0; i < 8; i++) {
   8218   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x10 + (i << 1));
   8219   1.88    mjacob 		}
   8220   1.88    mjacob 
   8221   1.88    mjacob 		/*
   8222   1.88    mjacob 		 * Mailbox Registers
   8223   1.88    mjacob 		 */
   8224   1.88    mjacob 		for (i = 0; i < 32; i++) {
   8225   1.88    mjacob 			*ptr++ =
   8226   1.88    mjacob 			    ISP_READ(isp, PCI_MBOX_REGS2300_OFF + (i << 1));
   8227   1.88    mjacob 		}
   8228   1.88    mjacob 
   8229   1.88    mjacob 		/*
   8230   1.88    mjacob 		 * Auto Request Response DMA registers
   8231   1.88    mjacob 		 */
   8232   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x40);
   8233   1.88    mjacob 		for (i = 0; i < 32; i++) {
   8234   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8235   1.88    mjacob 		}
   8236   1.88    mjacob 
   8237   1.88    mjacob 		/*
   8238   1.88    mjacob 		 * DMA registers
   8239   1.88    mjacob 		 */
   8240   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x50);
   8241   1.88    mjacob 		for (i = 0; i < 48; i++) {
   8242   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8243   1.88    mjacob 		}
   8244   1.88    mjacob 
   8245   1.88    mjacob 		/*
   8246   1.88    mjacob 		 * RISC hardware registers
   8247   1.88    mjacob 		 */
   8248   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0);
   8249   1.88    mjacob 		for (i = 0; i < 16; i++) {
   8250   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0xA0 + (i << 1));
   8251   1.88    mjacob 		}
   8252   1.88    mjacob 
   8253   1.88    mjacob 		/*
   8254   1.88    mjacob 		 * RISC GP? registers
   8255   1.88    mjacob 		 */
   8256   1.88    mjacob 		for (j = 0; j < 8; j++) {
   8257   1.88    mjacob 			ISP_WRITE(isp, BIU_BLOCK + 0xA4, 0x2000 + (j << 9));
   8258   1.88    mjacob 			for (i = 0; i < 16; i++) {
   8259   1.88    mjacob 				*ptr++ =
   8260   1.88    mjacob 				    ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8261   1.88    mjacob 			}
   8262   1.88    mjacob 		}
   8263   1.88    mjacob 
   8264   1.88    mjacob 		/*
   8265   1.88    mjacob 		 * frame buffer hardware registers
   8266   1.88    mjacob 		 */
   8267   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x10);
   8268   1.88    mjacob 		for (i = 0; i < 64; i++) {
   8269   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8270   1.88    mjacob 		}
   8271   1.88    mjacob 
   8272   1.88    mjacob 		/*
   8273   1.88    mjacob 		 * FPM B0 hardware registers
   8274   1.88    mjacob 		 */
   8275   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x20);
   8276   1.88    mjacob 		for (i = 0; i < 64; i++) {
   8277   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8278   1.88    mjacob 		}
   8279   1.88    mjacob 
   8280   1.88    mjacob 		/*
   8281   1.88    mjacob 		 * FPM B1 hardware registers
   8282   1.88    mjacob 		 */
   8283   1.88    mjacob 		ISP_WRITE(isp, BIU2100_CSR, 0x30);
   8284   1.88    mjacob 		for (i = 0; i < 64; i++) {
   8285   1.88    mjacob 			*ptr++ = ISP_READ(isp, BIU_BLOCK + 0x80 + (i << 1));
   8286   1.88    mjacob 		}
   8287   1.88    mjacob 	} else {
   8288   1.88    mjacob 		isp_prt(isp, ISP_LOGERR, "RISC Would Not Pause");
   8289   1.88    mjacob 		return;
   8290   1.88    mjacob 	}
   8291   1.88    mjacob 	isp_prt(isp, ISP_LOGALL,
   8292   1.88    mjacob 	   "isp_fw_dump: RISC registers dumped successfully");
   8293   1.88    mjacob 	ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
   8294   1.88    mjacob 	for (i = 0; i < 100; i++) {
   8295   1.88    mjacob 		USEC_DELAY(100);
   8296   1.88    mjacob 		if (ISP_READ(isp, OUTMAILBOX0) == 0) {
   8297   1.88    mjacob 			break;
   8298   1.88    mjacob 		}
   8299   1.88    mjacob 	}
   8300   1.88    mjacob 	if (ISP_READ(isp, OUTMAILBOX0) != 0) {
   8301   1.88    mjacob 		isp_prt(isp, ISP_LOGERR, "Board Would Not Reset");
   8302   1.88    mjacob 		return;
   8303   1.88    mjacob 	}
   8304  1.111    mjacob 	ISP_ENABLE_INTS(isp);
   8305  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   8306   1.88    mjacob 	mbs.param[0] = MBOX_READ_RAM_WORD;
   8307   1.88    mjacob 	mbs.param[1] = 0x800;
   8308   1.88    mjacob 	isp->isp_mbxworkp = (void *) ptr;
   8309   1.88    mjacob 	isp->isp_mbxwrk0 = 0xf7ff;	/* continuation count */
   8310   1.88    mjacob 	isp->isp_mbxwrk1 = 0x801;	/* next SRAM address */
   8311   1.88    mjacob 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
   8312   1.88    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   8313   1.88    mjacob 		isp_prt(isp, ISP_LOGWARN,
   8314   1.88    mjacob 		    "RAM DUMP FAILED @ WORD %x", isp->isp_mbxwrk1);
   8315   1.88    mjacob 		return;
   8316   1.88    mjacob 	}
   8317   1.88    mjacob 	ptr = isp->isp_mbxworkp;	/* finish fetch of final word */
   8318   1.88    mjacob 	*ptr++ = isp->isp_mboxtmp[2];
   8319  1.111    mjacob 	MEMZERO(&mbs, sizeof (mbs));
   8320   1.88    mjacob 	mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED;
   8321  1.111    mjacob 	mbs.param[8] = 1;
   8322   1.88    mjacob 	isp->isp_mbxworkp = (void *) ptr;
   8323   1.88    mjacob 	isp->isp_mbxwrk0 = 0xffff;	/* continuation count */
   8324   1.88    mjacob 	isp->isp_mbxwrk1 = 0x1;		/* next SRAM address */
   8325  1.111    mjacob 	isp->isp_mbxwrk8 = 0x1;
   8326   1.88    mjacob 	isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
   8327   1.88    mjacob 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
   8328   1.88    mjacob 		isp_prt(isp, ISP_LOGWARN,
   8329   1.88    mjacob 		    "RAM DUMP FAILED @ WORD %x", 0x10000 + isp->isp_mbxwrk1);
   8330   1.88    mjacob 		return;
   8331   1.88    mjacob 	}
   8332   1.88    mjacob 	ptr = isp->isp_mbxworkp;	/* finish final word */
   8333   1.88    mjacob 	*ptr++ = mbs.param[2];
   8334  1.101    mjacob 	isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped successfully");
   8335   1.88    mjacob 	FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */
   8336   1.96    mjacob 	(void) isp_async(isp, ISPASYNC_FW_DUMPED, 0);
   8337   1.88    mjacob }
   8338   1.88    mjacob 
   8339   1.88    mjacob void
   8340  1.111    mjacob isp_fw_dump(ispsoftc_t *isp)
   8341   1.88    mjacob {
   8342   1.88    mjacob 	if (IS_2200(isp))
   8343   1.88    mjacob 		isp2200_fw_dump(isp);
   8344   1.88    mjacob 	else if (IS_23XX(isp))
   8345   1.88    mjacob 		isp2300_fw_dump(isp);
   8346  1.111    mjacob 	else if (IS_24XX(isp))
   8347  1.111    mjacob 		isp_prt(isp, ISP_LOGERR, "24XX dump method undefined");
   8348  1.111    mjacob 
   8349   1.88    mjacob }
   8350   1.88    mjacob #endif
   8351