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