Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Aug 2009 01:04:26 +0000 (UTC)
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r196008 - in head/sys: cam dev/isp
Message-ID:  <200908010104.n7114Qxa085932@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjacob
Date: Sat Aug  1 01:04:26 2009
New Revision: 196008
URL: http://svn.freebsd.org/changeset/base/196008

Log:
  Add 8Gb support (isp_2500). Fix a fair number of configuration and
  firmware loading bugs.
  
  Target mode support has received some serious attention to make it
  more usable and stable.
  
  Some backward compatible additions to CAM have been made that make
  target mode async events easier to deal with have also been put
  into place.
  
  Further refinement and better support for NP-IV (N-port Virtualization)
  is now in place.
  
  Code for release prior to RELENG_7 has been stripped away for code clarity.
  
  Sponsored by: Copan Systems
  
  Reviewed by:    scottl, ken, jung-uk kim
  Approved by:    re

Modified:
  head/sys/cam/cam_ccb.h
  head/sys/cam/cam_xpt.c
  head/sys/dev/isp/isp.c
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_freebsd.h
  head/sys/dev/isp/isp_ioctl.h
  head/sys/dev/isp/isp_library.c
  head/sys/dev/isp/isp_library.h
  head/sys/dev/isp/isp_pci.c
  head/sys/dev/isp/isp_sbus.c
  head/sys/dev/isp/isp_stds.h
  head/sys/dev/isp/isp_target.c
  head/sys/dev/isp/isp_target.h
  head/sys/dev/isp/ispmbox.h
  head/sys/dev/isp/ispreg.h
  head/sys/dev/isp/ispvar.h

Modified: head/sys/cam/cam_ccb.h
==============================================================================
--- head/sys/cam/cam_ccb.h	Sat Aug  1 00:57:34 2009	(r196007)
+++ head/sys/cam/cam_ccb.h	Sat Aug  1 01:04:26 2009	(r196008)
@@ -173,6 +173,15 @@ typedef enum {
 	XPT_ATA_IO		= 0x18 | XPT_FC_DEV_QUEUED,
 				/* Execute the requested ATA I/O operation */
 
+	XPT_GET_SIM_KNOB	= 0x18,
+				/*
+				 * Get SIM specific knob values.
+				 */
+
+	XPT_SET_SIM_KNOB	= 0x19,
+				/*
+				 * Set SIM specific knob values.
+				 */
 /* HBA engine commands 0x20->0x2F */
 	XPT_ENG_INQ		= 0x20 | XPT_FC_XPT_ONLY,
 				/* HBA engine feature inquiry */
@@ -189,8 +198,12 @@ typedef enum {
 	XPT_CONT_TARGET_IO	= 0x33 | XPT_FC_DEV_QUEUED,
 				/* Continue Host Target I/O Connection */
 	XPT_IMMED_NOTIFY	= 0x34 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
-				/* Notify Host Target driver of event */
+				/* Notify Host Target driver of event (obsolete) */
 	XPT_NOTIFY_ACK		= 0x35,
+				/* Acknowledgement of event (obsolete) */
+	XPT_IMMEDIATE_NOTIFY	= 0x36 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
+				/* Notify Host Target driver of event */
+	XPT_NOTIFY_ACKNOWLEDGE	= 0x37 | XPT_FC_QUEUED | XPT_FC_USER_CCB,
 				/* Acknowledgement of event */
 
 /* Vendor Unique codes: 0x80->0x8F */
@@ -531,12 +544,14 @@ typedef enum {
 struct ccb_pathinq_settings_spi {
 	u_int8_t ppr_options;
 };
+
 struct ccb_pathinq_settings_fc {
 	u_int64_t wwnn;		/* world wide node name */
 	u_int64_t wwpn;		/* world wide port name */
 	u_int32_t port;		/* 24 bit port id, if known */
 	u_int32_t bitrate;	/* Mbps */
 };
+
 struct ccb_pathinq_settings_sas {
 	u_int32_t bitrate;	/* Mbps */
 };
@@ -678,6 +693,7 @@ struct ccb_relsim {
  * Definitions for the asynchronous callback CCB fields.
  */
 typedef enum {
+	AC_CONTRACT		= 0x1000,/* A contractual callback */
 	AC_GETDEV_CHANGED	= 0x800,/* Getdev info might have changed */
 	AC_INQ_CHANGED		= 0x400,/* Inquiry info might have changed */
 	AC_TRANSFER_NEG		= 0x200,/* New transfer settings in effect */
@@ -694,6 +710,26 @@ typedef enum {
 typedef void ac_callback_t (void *softc, u_int32_t code,
 			    struct cam_path *path, void *args);
 
+/*
+ * Generic Asynchronous callbacks.
+ *
+ * Generic arguments passed bac which are then interpreted between a per-system
+ * contract number.
+ */
+#define	AC_CONTRACT_DATA_MAX (128 - sizeof (u_int64_t))
+struct ac_contract {
+	u_int64_t	contract_number;
+	u_int8_t	contract_data[AC_CONTRACT_DATA_MAX];
+};
+
+#define	AC_CONTRACT_DEV_CHG	1
+struct ac_device_changed {
+	u_int64_t	wwpn;
+	u_int32_t	port;
+	target_id_t	target;
+	u_int8_t	arrived;
+};
+
 /* Set Asynchronous Callback CCB */
 struct ccb_setasync {
 	struct ccb_hdr	 ccb_h;
@@ -823,6 +859,50 @@ struct ccb_calc_geometry {
 };
 
 /*
+ * Set or get SIM (and transport) specific knobs
+ */
+
+#define	KNOB_VALID_ADDRESS	0x1
+#define	KNOB_VALID_ROLE		0x2
+
+
+#define	KNOB_ROLE_NONE		0x0
+#define	KNOB_ROLE_INITIATOR	0x1
+#define	KNOB_ROLE_TARGET	0x2
+#define	KNOB_ROLE_BOTH		0x3
+
+struct ccb_sim_knob_settings_spi {
+	u_int		valid;
+	u_int		initiator_id;
+	u_int		role;
+};
+
+struct ccb_sim_knob_settings_fc {
+	u_int		valid;
+	u_int64_t	wwnn;		/* world wide node name */
+	u_int64_t 	wwpn;		/* world wide port name */
+	u_int		role;
+};
+
+struct ccb_sim_knob_settings_sas {
+	u_int		valid;
+	u_int64_t	wwnn;		/* world wide node name */
+	u_int		role;
+};
+#define	KNOB_SETTINGS_SIZE	128
+
+struct ccb_sim_knob {
+	struct	  ccb_hdr ccb_h;
+	union {
+		u_int  valid;	/* Which fields to honor */
+		struct ccb_sim_knob_settings_spi spi;
+		struct ccb_sim_knob_settings_fc fc;
+		struct ccb_sim_knob_settings_sas sas;
+		char pad[KNOB_SETTINGS_SIZE];
+	} xport_specific;
+};
+
+/*
  * Rescan the given bus, or bus/target/lun
  */
 struct ccb_rescan {
@@ -847,6 +927,7 @@ struct ccb_en_lun {
 	u_int8_t  enable;
 };
 
+/* old, barely used immediate notify, binary compatibility */
 struct ccb_immed_notify {
 	struct	  ccb_hdr ccb_h;
 	struct    scsi_sense_data sense_data;
@@ -861,6 +942,22 @@ struct ccb_notify_ack {
 	u_int8_t  event;		/* Event flags */
 };
 
+struct ccb_immediate_notify {
+	struct    ccb_hdr ccb_h;
+	u_int     tag_id;		/* Tag for immediate notify */
+	u_int     seq_id;		/* Tag for target of notify */
+	u_int     initiator_id;		/* Initiator Identifier */
+	u_int     arg;			/* Function specific */
+};
+
+struct ccb_notify_acknowledge {
+	struct    ccb_hdr ccb_h;
+	u_int     tag_id;		/* Tag for immediate notify */
+	u_int     seq_id;		/* Tar for target of notify */
+	u_int     initiator_id;		/* Initiator Identifier */
+	u_int     arg;			/* Function specific */
+};
+
 /* HBA engine structures. */
 
 typedef enum {
@@ -935,6 +1032,7 @@ union ccb {
 	struct	ccb_dev_match		cdm;
 	struct	ccb_trans_settings	cts;
 	struct	ccb_calc_geometry	ccg;	
+	struct	ccb_sim_knob		knob;	
 	struct	ccb_abort		cab;
 	struct	ccb_resetbus		crb;
 	struct	ccb_resetdev		crd;
@@ -944,6 +1042,8 @@ union ccb {
 	struct	ccb_en_lun		cel;
 	struct	ccb_immed_notify	cin;
 	struct	ccb_notify_ack		cna;
+	struct	ccb_immediate_notify	cin1;
+	struct	ccb_notify_acknowledge	cna2;
 	struct	ccb_eng_inq		cei;
 	struct	ccb_eng_exec		cee;
 	struct 	ccb_rescan		crcn;

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Sat Aug  1 00:57:34 2009	(r196007)
+++ head/sys/cam/cam_xpt.c	Sat Aug  1 01:04:26 2009	(r196008)
@@ -2565,6 +2565,10 @@ xpt_action_default(union ccb *start_ccb)
 	case XPT_IMMED_NOTIFY:
 	case XPT_NOTIFY_ACK:
 	case XPT_RESET_BUS:
+	case XPT_IMMEDIATE_NOTIFY:
+	case XPT_NOTIFY_ACKNOWLEDGE:
+	case XPT_GET_SIM_KNOB:
+	case XPT_SET_SIM_KNOB:
 	{
 		struct cam_sim *sim;
 

Modified: head/sys/dev/isp/isp.c
==============================================================================
--- head/sys/dev/isp/isp.c	Sat Aug  1 00:57:34 2009	(r196007)
+++ head/sys/dev/isp/isp.c	Sat Aug  1 01:04:26 2009	(r196008)
@@ -1,17 +1,17 @@
 /*-
- *  Copyright (c) 1997-2007 by Matthew Jacob
+ *  Copyright (c) 1997-2009 by Matthew Jacob
  *  All rights reserved.
- * 
+ *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions
  *  are met:
- * 
+ *
  *  1. Redistributions of source code must retain the above copyright
  *     notice, this list of conditions and the following disclaimer.
  *  2. Redistributions in binary form must reproduce the above copyright
  *     notice, this list of conditions and the following disclaimer in the
  *     documentation and/or other materials provided with the distribution.
- * 
+ *
  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -23,6 +23,7 @@
  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  *  SUCH DAMAGE.
+ *
  */
 
 /*
@@ -64,51 +65,52 @@ __FBSDID("$FreeBSD$");
  */
 
 #define	MBOX_DELAY_COUNT	1000000 / 100
-#define	ISP_MARK_PORTDB(a, b)	\
-    isp_prt(isp, ISP_LOGSANCFG, "line %d: markportdb", __LINE__); \
-    isp_mark_portdb(a, b)
+#define	ISP_MARK_PORTDB(a, b, c)				\
+    isp_prt(isp, ISP_LOGSANCFG, 				\
+	"Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);	\
+    isp_mark_portdb(a, b, c)
 
 /*
  * Local static data
  */
-static const char fconf[] =
-    "PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n"
-    " database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
-static const char notresp[] =
-  "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
-static const char xact1[] =
-    "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
-static const char xact2[] =
-    "HBA attempted queued transaction to target routine %d on target %d bus %d";
-static const char xact3[] =
-    "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
-static const char pskip[] =
-    "SCSI phase skipped for target %d.%d.%d";
-static const char topology[] =
-    "HBA PortID 0x%06x N-Port Handle %d, Connection Topology '%s'";
-static const char ourwwn[] =
-    "HBA WWNN 0x%08x%08x HBA WWPN 0x%08x%08x";
-static const char finmsg[] =
-    "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
-static const char sc0[] =
-    "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x";
-static const char sc1[] =
-    "%s RAAN 0x%x DLAN 0x%x DDMAB 0x%x CDMAB 0x%x SELTIME %d MQD %d";
-static const char sc2[] = "%s CHAN %d TGT %d FLAGS 0x%x 0x%x/0x%x";
-static const char sc3[] = "Generated";
+static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
+static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
+static const char xact1[] = "HBA attempted queued transaction with disconnect not set for %d.%d.%d";
+static const char xact2[] = "HBA attempted queued transaction to target routine %d on target %d bus %d";
+static const char xact3[] = "HBA attempted queued cmd for %d.%d.%d when queueing disabled";
+static const char pskip[] = "SCSI phase skipped for target %d.%d.%d";
+static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
+static const char finmsg[] = "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x";
 static const char sc4[] = "NVRAM";
-static const char bun[] =
-    "bad underrun for %d.%d (count %d, resid %d, status %s)";
+static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)";
+static const char lipd[] = "Chan %d LIP destroyed %d active commands";
+static const char sacq[] = "unable to acquire scratch area";
+
+static const uint8_t alpa_map[] = {
+	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
+	0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
+	0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
+	0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
+	0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
+	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
+	0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
+	0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
+	0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
+	0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
+	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
+	0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
+	0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
+	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
+	0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
+	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
+};
 
 /*
  * Local function prototypes.
  */
 static int isp_parse_async(ispsoftc_t *, uint16_t);
-static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *,
-    uint32_t *);
-static void
-isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *);
-static void
+static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
+static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
 isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
 static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
 static int isp_mbox_continue(ispsoftc_t *);
@@ -116,39 +118,37 @@ static void isp_scsi_init(ispsoftc_t *);
 static void isp_scsi_channel_init(ispsoftc_t *, int);
 static void isp_fibre_init(ispsoftc_t *);
 static void isp_fibre_init_2400(ispsoftc_t *);
-static void isp_mark_portdb(ispsoftc_t *, int);
-static int isp_plogx(ispsoftc_t *, uint16_t, uint32_t, int, int);
+static void isp_mark_portdb(ispsoftc_t *, int, int);
+static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
-static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int);
-static uint64_t isp_get_portname(ispsoftc_t *, int, int);
-static int isp_fclink_test(ispsoftc_t *, int);
-static const char *ispfc_fw_statename(int);
-static int isp_pdb_sync(ispsoftc_t *);
-static int isp_scan_loop(ispsoftc_t *);
-static int isp_gid_ft_sns(ispsoftc_t *);
-static int isp_gid_ft_ct_passthru(ispsoftc_t *);
-static int isp_scan_fabric(ispsoftc_t *);
-static int isp_login_device(ispsoftc_t *, uint32_t, isp_pdb_t *, uint16_t *);
-static int isp_register_fc4_type(ispsoftc_t *);
-static int isp_register_fc4_type_24xx(ispsoftc_t *);
-static uint16_t isp_nxt_handle(ispsoftc_t *, uint16_t);
-static void isp_fw_state(ispsoftc_t *);
+static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
+static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
+static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
+static int isp_fclink_test(ispsoftc_t *, int, int);
+static int isp_pdb_sync(ispsoftc_t *, int);
+static int isp_scan_loop(ispsoftc_t *, int);
+static int isp_gid_ft_sns(ispsoftc_t *, int);
+static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
+static int isp_scan_fabric(ispsoftc_t *, int);
+static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
+static int isp_register_fc4_type(ispsoftc_t *, int);
+static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
+static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
+static void isp_fw_state(ispsoftc_t *, int);
 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
 
-static void isp_update(ispsoftc_t *);
-static void isp_update_bus(ispsoftc_t *, int);
-static void isp_setdfltparm(ispsoftc_t *, int);
-static void isp_setdfltfcparm(ispsoftc_t *);
-static int isp_read_nvram(ispsoftc_t *);
-static int isp_read_nvram_2400(ispsoftc_t *);
+static void isp_spi_update(ispsoftc_t *, int);
+static void isp_setdfltsdparm(ispsoftc_t *);
+static void isp_setdfltfcparm(ispsoftc_t *, int);
+static int isp_read_nvram(ispsoftc_t *, int);
+static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
-static void isp_fix_nvram_wwns(ispsoftc_t *);
 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
 
@@ -161,15 +161,20 @@ static void isp_parse_nvram_2400(ispsoft
  */
 
 void
-isp_reset(ispsoftc_t *isp)
+isp_reset(ispsoftc_t *isp, int do_load_defaults)
 {
 	mbreg_t mbs;
 	uint32_t code_org, val;
 	int loops, i, dodnld = 1;
-	static const char *btype = "????";
+	const char *btype = "????";
 	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
 
 	isp->isp_state = ISP_NILSTATE;
+	if (isp->isp_dead) {
+		isp_shutdown(isp);
+		ISP_DISABLE_INTS(isp);
+		return;
+	}
 
 	/*
 	 * Basic types (SCSI, FibreChannel and PCI or SBus)
@@ -181,51 +186,6 @@ isp_reset(ispsoftc_t *isp)
 	 * for SCSI adapters and do other settings for the 2100.
 	 */
 
-	/*
-	 * Get the current running firmware revision out of the
-	 * chip before we hit it over the head (if this is our
-	 * first time through). Note that we store this as the
-	 * 'ROM' firmware revision- which it may not be. In any
-	 * case, we don't really use this yet, but we may in
-	 * the future.
-	 */
-	if (isp->isp_touched == 0) {
-		/*
-		 * First see whether or not we're sitting in the ISP PROM.
-		 * If we've just been reset, we'll have the string "ISP   "
-		 * spread through outgoing mailbox registers 1-3. We do
-		 * this for PCI cards because otherwise we really don't
-		 * know what state the card is in and we could hang if
-		 * we try this command otherwise.
-		 *
-		 * For SBus cards, we just do this because they almost
-		 * certainly will be running firmware by now.
-		 */
-		if (ISP_READ(isp, OUTMAILBOX1) != 0x4953 ||
-		    ISP_READ(isp, OUTMAILBOX2) != 0x5020 ||
-		    ISP_READ(isp, OUTMAILBOX3) != 0x2020) {
-			/*
-			 * Just in case it was paused...
-			 */
-			if (IS_24XX(isp)) {
-				ISP_WRITE(isp, BIU2400_HCCR,
-				    HCCR_2400_CMD_RELEASE);
-			} else {
-				ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
-			}
-			MEMZERO(&mbs, sizeof (mbs));
-			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
-			mbs.logval = MBLOGNONE;
-			isp_mboxcmd(isp, &mbs);
-			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
-				isp->isp_romfw_rev[0] = mbs.param[1];
-				isp->isp_romfw_rev[1] = mbs.param[2];
-				isp->isp_romfw_rev[2] = mbs.param[3];
-			}
-		}
-		isp->isp_touched = 1;
-	}
-
 	ISP_DISABLE_INTS(isp);
 
 	/*
@@ -244,17 +204,16 @@ isp_reset(ispsoftc_t *isp)
 	}
 
 	/*
-	 * Set up DMA for the request and result queues.
+	 * Set up DMA for the request and response queues.
 	 *
 	 * We do this now so we can use the request queue
-	 * for a dma
+	 * for dma to load firmware from.
 	 */
 	if (ISP_MBOXDMASETUP(isp) != 0) {
 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
 		return;
 	}
 
-
 	/*
 	 * Set up default request/response queue in-pointer/out-pointer
 	 * register indices.
@@ -264,8 +223,6 @@ isp_reset(ispsoftc_t *isp)
 		isp->isp_rqstoutrp = BIU2400_REQOUTP;
 		isp->isp_respinrp = BIU2400_RSPINP;
 		isp->isp_respoutrp = BIU2400_RSPOUTP;
-		isp->isp_atioinrp = BIU2400_ATIO_RSPINP;
-		isp->isp_atiooutrp = BIU2400_ATIO_REQINP;
 	} else if (IS_23XX(isp)) {
 		isp->isp_rqstinrp = BIU_REQINP;
 		isp->isp_rqstoutrp = BIU_REQOUTP;
@@ -310,6 +267,9 @@ isp_reset(ispsoftc_t *isp)
 		case ISP_HA_FC_2400:
 			btype = "2422";
 			break;
+		case ISP_HA_FC_2500:
+			btype = "2532";
+			break;
 		default:
 			break;
 		}
@@ -326,11 +286,13 @@ isp_reset(ispsoftc_t *isp)
 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
 		}
 	} else if (IS_1240(isp)) {
-		sdparam *sdp = isp->isp_param;
+		sdparam *sdp;
+
 		btype = "1240";
 		isp->isp_clock = 60;
+		sdp = SDPARAM(isp, 0);
 		sdp->isp_ultramode = 1;
-		sdp++;
+		sdp = SDPARAM(isp, 1);
 		sdp->isp_ultramode = 1;
 		/*
 		 * XXX: Should probably do some bus sensing.
@@ -355,7 +317,7 @@ isp_reset(ispsoftc_t *isp)
 	} else if (IS_ULTRA2(isp)) {
 		static const char m[] = "bus %d is in %s Mode";
 		uint16_t l;
-		sdparam *sdp = isp->isp_param;
+		sdparam *sdp = SDPARAM(isp, 0);
 
 		isp->isp_clock = 100;
 
@@ -387,10 +349,10 @@ isp_reset(ispsoftc_t *isp)
 		}
 
 		if (IS_DUALBUS(isp)) {
-			sdp++;
+			sdp = SDPARAM(isp, 1);
 			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
 			l &= ISP1080_MODE_MASK;
-			switch(l) {
+			switch (l) {
 			case ISP1080_LVD_MODE:
 				sdp->isp_lvdmode = 1;
 				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
@@ -412,7 +374,7 @@ isp_reset(ispsoftc_t *isp)
 			}
 		}
 	} else {
-		sdparam *sdp = isp->isp_param;
+		sdparam *sdp = SDPARAM(isp, 0);
 		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
 		switch (i) {
 		default:
@@ -509,7 +471,7 @@ isp_reset(ispsoftc_t *isp)
 
 	/*
 	 * Hit the chip over the head with hammer,
-	 * and give the ISP a chance to recover.
+	 * and give it a chance to recover.
 	 */
 
 	if (IS_SCSI(isp)) {
@@ -517,15 +479,13 @@ isp_reset(ispsoftc_t *isp)
 		/*
 		 * A slight delay...
 		 */
-		USEC_DELAY(100);
+		ISP_DELAY(100);
 
 		/*
 		 * Clear data && control DMA engines.
 		 */
-		ISP_WRITE(isp, CDMA_CONTROL,
-		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
-		ISP_WRITE(isp, DDMA_CONTROL,
-		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
+		ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
+		ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
 
 
 	} else if (IS_24XX(isp)) {
@@ -534,12 +494,12 @@ isp_reset(ispsoftc_t *isp)
 		 */
 		ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
 		for (val = loops = 0; loops < 30000; loops++) {
-			USEC_DELAY(10);
+			ISP_DELAY(10);
 			val = ISP_READ(isp, BIU2400_CSR);
 			if ((val & BIU2400_DMA_ACTIVE) == 0) {
 				break;
 			}
-		} 
+		}
 		if (val & BIU2400_DMA_ACTIVE) {
 			ISP_RESET0(isp);
 			isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
@@ -548,11 +508,10 @@ isp_reset(ispsoftc_t *isp)
 		/*
 		 * Hold it in SOFT_RESET and STOP state for 100us.
 		 */
-		ISP_WRITE(isp, BIU2400_CSR,
-		    BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
-		USEC_DELAY(100);
+		ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
+		ISP_DELAY(100);
 		for (loops = 0; loops < 10000; loops++) {
-			USEC_DELAY(5);
+			ISP_DELAY(5);
 			val = ISP_READ(isp, OUTMAILBOX0);
 		}
 		for (val = loops = 0; loops < 500000; loops ++) {
@@ -571,17 +530,14 @@ isp_reset(ispsoftc_t *isp)
 		/*
 		 * A slight delay...
 		 */
-		USEC_DELAY(100);
+		ISP_DELAY(100);
 
 		/*
 		 * Clear data && control DMA engines.
 		 */
-		ISP_WRITE(isp, CDMA2100_CONTROL,
-			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
-		ISP_WRITE(isp, TDMA2100_CONTROL,
-			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
-		ISP_WRITE(isp, RDMA2100_CONTROL,
-			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
+		ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
+		ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
+		ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
 	}
 
 	/*
@@ -601,7 +557,7 @@ isp_reset(ispsoftc_t *isp)
 			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
 				break;
 		}
-		USEC_DELAY(100);
+		ISP_DELAY(100);
 		if (--loops < 0) {
 			ISP_DUMPREGS(isp, "chip reset timed out");
 			ISP_RESET0(isp);
@@ -629,17 +585,16 @@ isp_reset(ispsoftc_t *isp)
 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
 	} else {
 		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
-		USEC_DELAY(100);
+		ISP_DELAY(100);
 		ISP_WRITE(isp, BIU_SEMA, 0);
 	}
 
-	
 	/*
 	 * Post-RISC Reset stuff.
 	 */
 	if (IS_24XX(isp)) {
 		for (val = loops = 0; loops < 5000000; loops++) {
-			USEC_DELAY(5);
+			ISP_DELAY(5);
 			val = ISP_READ(isp, OUTMAILBOX0);
 			if (val == 0) {
 				break;
@@ -663,8 +618,8 @@ isp_reset(ispsoftc_t *isp)
 			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
 		}
-		if (SDPARAM(isp)->isp_ptisp) {
-			if (SDPARAM(isp)->isp_ultramode) {
+		if (SDPARAM(isp, 0)->isp_ptisp) {
+			if (SDPARAM(isp, 0)->isp_ultramode) {
 				while (ISP_READ(isp, RISC_MTR) != 0x1313) {
 					ISP_WRITE(isp, RISC_MTR, 0x1313);
 					ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
@@ -692,7 +647,12 @@ isp_reset(ispsoftc_t *isp)
 	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
 	ISP_WRITE(isp, isp->isp_respinrp, 0);
 	ISP_WRITE(isp, isp->isp_respoutrp, 0);
-
+	if (IS_24XX(isp)) {
+		ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
+		ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
+		ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
+		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
+	}
 
 	/*
 	 * Do MD specific post initialization
@@ -702,15 +662,15 @@ isp_reset(ispsoftc_t *isp)
 	/*
 	 * Wait for everything to finish firing up.
 	 *
-	 * Avoid doing this on the 2312 because you can generate a PCI
+	 * Avoid doing this on early 2312s because you can generate a PCI
 	 * parity error (chip breakage).
 	 */
-	if (IS_2312(isp)) {
-		USEC_DELAY(100);
+	if (IS_2312(isp) && isp->isp_revision < 2) {
+		ISP_DELAY(100);
 	} else {
 		loops = MBOX_DELAY_COUNT;
 		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
-			USEC_DELAY(100);
+			ISP_DELAY(100);
 			if (--loops < 0) {
 				ISP_RESET0(isp);
 				isp_prt(isp, ISP_LOGERR,
@@ -727,19 +687,25 @@ isp_reset(ispsoftc_t *isp)
 	 */
 
 	/*
-	 * Do some sanity checking.
+	 * Do some sanity checking by running a NOP command.
+	 * If it succeeds, the ROM firmware is now running.
 	 */
-	MEMZERO(&mbs, sizeof (mbs));
+	ISP_MEMZERO(&mbs, sizeof (mbs));
 	mbs.param[0] = MBOX_NO_OP;
 	mbs.logval = MBLOGALL;
 	isp_mboxcmd(isp, &mbs);
 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+		isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", mbs.param[0]);
 		ISP_RESET0(isp);
 		return;
 	}
 
+	/*
+	 * Do some operational tests
+	 */
+
 	if (IS_SCSI(isp) || IS_24XX(isp)) {
-		MEMZERO(&mbs, sizeof (mbs));
+		ISP_MEMZERO(&mbs, sizeof (mbs));
 		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
 		mbs.param[1] = 0xdead;
 		mbs.param[2] = 0xbeef;
@@ -758,10 +724,7 @@ isp_reset(ispsoftc_t *isp)
 		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
 		    mbs.param[5] != 0xa5a5) {
 			ISP_RESET0(isp);
-			isp_prt(isp, ISP_LOGERR,
-			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
-			    mbs.param[1], mbs.param[2], mbs.param[3],
-			    mbs.param[4], mbs.param[5]);
+			isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
 			return;
 		}
 
@@ -776,8 +739,7 @@ isp_reset(ispsoftc_t *isp)
 	 * whether we have f/w at all and whether a config flag
 	 * has disabled our download.
 	 */
-	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
-	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
+	if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
 		dodnld = 0;
 	}
 
@@ -793,13 +755,6 @@ isp_reset(ispsoftc_t *isp)
 		const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
 
 		/*
-		 * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE
-		 * NB: command to the 2400 while loading new firmware. This
-		 * NB: causes the new f/w to start and immediately crash back
-		 * NB: to the ROM.
-		 */
-
-		/*
 		 * Keep loading until we run out of f/w.
 		 */
 		code_org = ptr[2];	/* 1st load address is our start addr */
@@ -807,9 +762,7 @@ isp_reset(ispsoftc_t *isp)
 		for (;;) {
 			uint32_t la, wi, wl;
 
-			isp_prt(isp, ISP_LOGDEBUG0,
-			    "load 0x%x words of code at load address 0x%x",
-			    ptr[3], ptr[2]);
+			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
 
 			wi = 0;
 			la = ptr[2];
@@ -828,23 +781,31 @@ isp_reset(ispsoftc_t *isp)
 					ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
 					wl--;
 				}
-				MEMORYBARRIER(isp, SYNC_REQUEST,
-				    0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
-				MEMZERO(&mbs, sizeof (mbs));
-				mbs.param[0] = MBOX_LOAD_RISC_RAM;
-				mbs.param[1] = la;
-				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
-				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
-				mbs.param[4] = nw >> 16;
-				mbs.param[5] = nw;
-				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
-				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
-				mbs.param[8] = la >> 16;
+				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+				ISP_MEMZERO(&mbs, sizeof (mbs));
+				if (la < 0x10000 && nw < 0x10000) {
+					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
+					mbs.param[1] = la;
+					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+					mbs.param[4] = nw;
+					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+				} else {
+					mbs.param[0] = MBOX_LOAD_RISC_RAM;
+					mbs.param[1] = la;
+					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+					mbs.param[4] = nw >> 16;
+					mbs.param[5] = nw;
+					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+					mbs.param[8] = la >> 16;
+				}
 				mbs.logval = MBLOGALL;
 				isp_mboxcmd(isp, &mbs);
 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-					isp_prt(isp, ISP_LOGERR,
-					    "F/W Risc Ram Load Failed");
+					isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
 					ISP_RESET0(isp);
 					return;
 				}
@@ -855,7 +816,7 @@ isp_reset(ispsoftc_t *isp)
 				break;
 			}
 			ptr += ptr[3];
-		} 
+		}
 		isp->isp_loaded_fw = 1;
 	} else if (dodnld && IS_23XX(isp)) {
 		const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
@@ -868,17 +829,15 @@ isp_reset(ispsoftc_t *isp)
 		for (;;) {
 			uint32_t nxtaddr;
 
-			isp_prt(isp, ISP_LOGDEBUG0,
-			    "load 0x%x words of code at load address 0x%x",
-			    ptr[3], la);
+			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
 
 			wi = 0;
 			wl = ptr[3];
 
 			while (wi < ptr[3]) {
 				uint16_t *cp;
-				uint32_t nw;
-				
+				uint16_t nw;
+
 				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
 				if (nw > wl) {
 					nw = wl;
@@ -891,22 +850,30 @@ isp_reset(ispsoftc_t *isp)
 					ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
 					wl--;
 				}
-				MEMORYBARRIER(isp, SYNC_REQUEST,
-				    0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
-				MEMZERO(&mbs, sizeof (mbs));
-				mbs.param[0] = MBOX_LOAD_RISC_RAM;
-				mbs.param[1] = la;
-				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
-				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
-				mbs.param[4] = nw;
-				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
-				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
-				mbs.param[8] = la >> 16;
+				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+				ISP_MEMZERO(&mbs, sizeof (mbs));
+				if (la < 0x10000) {
+					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
+					mbs.param[1] = la;
+					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+					mbs.param[4] = nw;
+					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+				} else {
+					mbs.param[0] = MBOX_LOAD_RISC_RAM;
+					mbs.param[1] = la;
+					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+					mbs.param[4] = nw;
+					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+					mbs.param[8] = la >> 16;
+				}
 				mbs.logval = MBLOGALL;
 				isp_mboxcmd(isp, &mbs);
 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-					isp_prt(isp, ISP_LOGERR,
-					    "F/W Risc Ram Load Failed");
+					isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
 					ISP_RESET0(isp);
 					return;
 				}
@@ -914,19 +881,6 @@ isp_reset(ispsoftc_t *isp)
 			}
 
 			if (!IS_2322(isp)) {
-				/*
-				 * Verify that it downloaded correctly.
-				 */
-				MEMZERO(&mbs, sizeof (mbs));
-				mbs.param[0] = MBOX_VERIFY_CHECKSUM;
-				mbs.param[1] = code_org;
-				mbs.logval = MBLOGNONE;
-				isp_mboxcmd(isp, &mbs);
-				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-					isp_prt(isp, ISP_LOGERR, dcrc);
-					ISP_RESET0(isp);
-					return;
-				}
 				break;
 			}
 
@@ -951,41 +905,45 @@ isp_reset(ispsoftc_t *isp)
 		union {
 			const uint16_t *cp;
 			uint16_t *np;
-		} u;
-		u.cp = isp->isp_mdvec->dv_ispfw;
-		isp->isp_mbxworkp = &u.np[1];
-		isp->isp_mbxwrk0 = u.np[3] - 1;
+		} ucd;
+		ucd.cp = isp->isp_mdvec->dv_ispfw;
+		isp->isp_mbxworkp = &ucd.np[1];
+		isp->isp_mbxwrk0 = ucd.np[3] - 1;
 		isp->isp_mbxwrk1 = code_org + 1;
-		MEMZERO(&mbs, sizeof (mbs));
+		ISP_MEMZERO(&mbs, sizeof (mbs));
 		mbs.param[0] = MBOX_WRITE_RAM_WORD;
 		mbs.param[1] = code_org;
-		mbs.param[2] = u.np[0];
+		mbs.param[2] = ucd.np[0];
 		mbs.logval = MBLOGNONE;
 		isp_mboxcmd(isp, &mbs);
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-			isp_prt(isp, ISP_LOGERR,
-			    "F/W download failed at word %d",
-			    isp->isp_mbxwrk1 - code_org);
+			isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
 			ISP_RESET0(isp);
 			return;
 		}
-		/*
-		 * Verify that it downloaded correctly.
-		 */
-		MEMZERO(&mbs, sizeof (mbs));
+	} else {
+		isp->isp_loaded_fw = 0;
+		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
+	}
+
+	/*
+	 * If we loaded firmware, verify its checksum
+	 */
+	if (isp->isp_loaded_fw) {
+		ISP_MEMZERO(&mbs, sizeof (mbs));
 		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
-		mbs.param[1] = code_org;
-		mbs.logval = MBLOGNONE;
+		if (IS_24XX(isp)) {
+			mbs.param[1] = code_org >> 16;
+			mbs.param[2] = code_org;
+		} else {
+			mbs.param[1] = code_org;
+		}
 		isp_mboxcmd(isp, &mbs);
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 			isp_prt(isp, ISP_LOGERR, dcrc);
 			ISP_RESET0(isp);
 			return;
 		}
-		isp->isp_loaded_fw = 1;
-	} else {
-		isp->isp_loaded_fw = 0;
-		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
 	}
 
 	/*
@@ -996,9 +954,7 @@ isp_reset(ispsoftc_t *isp)
 	 */
 
 
-	MEMZERO(&mbs, sizeof (mbs));
-	mbs.timeout = 1000000;
-	mbs.param[0] = MBOX_EXEC_FIRMWARE;
+	MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
 	if (IS_24XX(isp)) {
 		mbs.param[1] = code_org >> 16;
 		mbs.param[2] = code_org;
@@ -1007,6 +963,9 @@ isp_reset(ispsoftc_t *isp)
 		} else {
 			mbs.param[3] = 1;
 		}
+		if (IS_25XX(isp)) {
+			mbs.ibits |= 0x10;
+		}
 	} else if (IS_2322(isp)) {
 		mbs.param[1] = code_org;
 		if (isp->isp_loaded_fw) {
@@ -1017,8 +976,6 @@ isp_reset(ispsoftc_t *isp)
 	} else {
 		mbs.param[1] = code_org;
 	}
-
-	mbs.logval = MBLOGALL;
 	isp_mboxcmd(isp, &mbs);
 	if (IS_2322(isp) || IS_24XX(isp)) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908010104.n7114Qxa085932>