svn commit: r204252 - in stable/7/sys: cam dev/isp
Matt Jacob
mjacob at FreeBSD.org
Tue Feb 23 18:37:22 UTC 2010
Author: mjacob
Date: Tue Feb 23 18:37:21 2010
New Revision: 204252
URL: http://svn.freebsd.org/changeset/base/204252
Log:
MFC 196008 196162 197214 197372 197373
MFC 198822 200089 201325 201408 202418
MFC 203444 203463 203478 204050
Move back into RELENG_7 the current state of isp.
Deleted:
stable/7/sys/dev/isp/isp_tpublic.h
Modified:
stable/7/sys/cam/cam_ccb.h
stable/7/sys/cam/cam_xpt.c
stable/7/sys/dev/isp/isp.c
stable/7/sys/dev/isp/isp_freebsd.c
stable/7/sys/dev/isp/isp_freebsd.h
stable/7/sys/dev/isp/isp_ioctl.h
stable/7/sys/dev/isp/isp_library.c
stable/7/sys/dev/isp/isp_library.h
stable/7/sys/dev/isp/isp_pci.c
stable/7/sys/dev/isp/isp_sbus.c
stable/7/sys/dev/isp/isp_stds.h
stable/7/sys/dev/isp/isp_target.c
stable/7/sys/dev/isp/isp_target.h
stable/7/sys/dev/isp/ispmbox.h
stable/7/sys/dev/isp/ispreg.h
stable/7/sys/dev/isp/ispvar.h
Directory Properties:
stable/7/sbin/geom/ (props changed)
stable/7/sbin/geom/class/label/ (props changed)
stable/7/sbin/geom/class/part/ (props changed)
stable/7/sbin/geom/class/stripe/ (props changed)
stable/7/sbin/geom/misc/ (props changed)
stable/7/sys/ (props changed)
stable/7/sys/cddl/contrib/opensolaris/ (props changed)
stable/7/sys/contrib/dev/acpica/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
Modified: stable/7/sys/cam/cam_ccb.h
==============================================================================
--- stable/7/sys/cam/cam_ccb.h Tue Feb 23 16:46:34 2010 (r204251)
+++ stable/7/sys/cam/cam_ccb.h Tue Feb 23 18:37:21 2010 (r204252)
@@ -170,6 +170,15 @@ typedef enum {
* volume size.
*/
+ 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 */
@@ -186,8 +195,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 */
@@ -521,12 +534,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 */
};
@@ -645,6 +660,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 */
@@ -661,6 +677,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;
@@ -782,6 +818,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 {
@@ -806,6 +886,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;
@@ -820,6 +901,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 {
@@ -894,6 +991,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;
@@ -903,6 +1001,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: stable/7/sys/cam/cam_xpt.c
==============================================================================
--- stable/7/sys/cam/cam_xpt.c Tue Feb 23 16:46:34 2010 (r204251)
+++ stable/7/sys/cam/cam_xpt.c Tue Feb 23 18:37:21 2010 (r204252)
@@ -3150,6 +3150,10 @@ xpt_action(union ccb *start_ccb)
case XPT_NOTIFY_ACK:
case XPT_GET_TRAN_SETTINGS:
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: stable/7/sys/dev/isp/isp.c
==============================================================================
--- stable/7/sys/dev/isp/isp.c Tue Feb 23 16:46:34 2010 (r204251)
+++ stable/7/sys/dev/isp/isp.c Tue Feb 23 18:37:21 2010 (r204252)
@@ -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.
+ *
*/
/*
@@ -62,53 +63,53 @@ __FBSDID("$FreeBSD$");
/*
* General defines
*/
-
#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 at LINE %d", b, __LINE__); \
+ isp_mark_portdb(a, b, c)
/*
* Local static data
*/
-static const char fconf[] =
- "PortDB[%d] changed:\n current =(0x%x at 0x%06x 0x%08x%08x 0x%08x%08x)\n"
- " database=(0x%x at 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 at 0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x at 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 +117,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 +160,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 +185,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 +203,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 +222,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 +266,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 +285,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 +316,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 +348,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 +373,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 +470,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 +478,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 +493,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 +507,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 +529,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 +556,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 +584,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 +617,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 +646,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 +661,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 +686,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 command 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 +723,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 +738,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 +754,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 +761,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 +780,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 +815,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 +828,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 +849,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 +880,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 +904,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 +953,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 +962,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 +975,6 @@ isp_reset(ispsoftc_t *isp)
} else {
mbs.param[1] = code_org;
}
-
- mbs.logval = MBLOGALL;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-7
mailing list