From owner-svn-src-stable@FreeBSD.ORG Tue Feb 23 18:37:22 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 35C8C106568B; Tue, 23 Feb 2010 18:37:22 +0000 (UTC) (envelope-from mjacob@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 239918FC13; Tue, 23 Feb 2010 18:37:22 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o1NIbMCi046639; Tue, 23 Feb 2010 18:37:22 GMT (envelope-from mjacob@svn.freebsd.org) Received: (from mjacob@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o1NIbL6D046634; Tue, 23 Feb 2010 18:37:21 GMT (envelope-from mjacob@svn.freebsd.org) Message-Id: <201002231837.o1NIbL6D046634@svn.freebsd.org> From: Matt Jacob Date: Tue, 23 Feb 2010 18:37:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r204252 - in stable/7/sys: cam dev/isp X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Feb 2010 18:37:22 -0000 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@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 +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 ***