qlgcupdate.c revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * CDDL HEADER START
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * The contents of this file are subject to the terms of the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Common Development and Distribution License (the "License").
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * You may not use this file except in compliance with the License.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * See the License for the specific language governing permissions
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * and limitations under the License.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * When distributing Covered Code, include this CDDL HEADER in each
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If applicable, add the following below this CDDL HEADER, with the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * fields enclosed by brackets "[]" replaced with your own identifying
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * information: Portions Copyright [yyyy] [name of copyright owner]
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * CDDL HEADER END
0dcc71495bad040a0c83830efc85acf8d897350dnw * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Use is subject to license terms.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * I18N message number ranges
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * This file: 21000 - 21499
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Shared common messages: 1 - 1999
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Functions to support the download of FCode to PCI HBAs
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Qlogic ISP21XX/22XX boards: FC100/P single port, ISP2200 dual port
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * and Emulex cards
479ac37569625bae44ffb80071d4bc865fc710eddm/* Error codes - used by the fcode_load_file routine */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define FCODE_IOCTL_FAILURE 2 /* FCODE ioctl download failure */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * EMULEX Fcode attributes
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Emulex specific error codes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Diagnostic error codes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Download image contains bad data */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Download image not compatible with current hardware */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Unable to take adapter offline */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Image download failed */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * This is just a random value chosen to identify Sbus Fcodes. Sbus FCode
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * for Ivory is based on a 2200 chip but this value does not reflect that.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Global variables */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char fc_trans[] = "SUNW,ifp"; /* fibre channel transport */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char fp_trans[] = "SUNW,qlc"; /* fca layer driver */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char fp_trans_id[] = "fp@"; /* transport layer id */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char qlgc2100[] = "FC100/P"; /* product name for 2100 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char qlgc2200[] = "ISP2200"; /* product name for 2200 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char qlgc2300[] = "ISP2300"; /* product name for 2300 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char qlgc2312[] = "ISP2312"; /* product name for 2312 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * The variable qlgc2200Sbus represents the string which is always the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * starting string of the version information in an ISP2200 Sbus Fcode.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char qlgc2200Sbus[] = "ISP2200 Sbus FC-AL Host Adapter Driver";
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Internal functions */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int q_load_file(int, char *);
cd37da7426f0c49c14ad9a8a07638ca971477566nwstatic int q_getdevctlpath(char *, int *);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int q_warn(int);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int q_findversion(int, int, uchar_t *, uint16_t *);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int q_findfileversion(char *, uchar_t *, uint16_t *, int, int *);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int q_findSbusfile(int, int *);
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkrestatic int memstrstr(char *, char *, int, int);
d3a612ca42c17c3baa6c96ded00f98db349cc881nwstatic int fcode_load_file(int, char *, int *);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Functions to support Fcode download for Emulex HBAs
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic void handle_emulex_error(int, char *);
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Searches for and updates the cards. This is the "main" function
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * and will give the output to the user by calling the subfunctions.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * args: FCode file; if NULL only the current FCode version is printed
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*ARGSUSED*/
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int fd, fcode_fd = -1, errnum = 0, devcnt = 0, retval = 0, isSbus = 0;
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static uchar_t version[MAXNAMELEN], version_file[MAXNAMELEN];
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static struct utmpx *utmpp = NULL; /* pointer for getutxent() */
d3a612ca42c17c3baa6c96ded00f98db349cc881nw * The variables port1 and port2 are used to store the bus id
d3a612ca42c17c3baa6c96ded00f98db349cc881nw * e.g. the bus id for this path:
d3a612ca42c17c3baa6c96ded00f98db349cc881nw * /devices/sbus@12,0/SUNW,qlc@2,30000/fp@0,0:devctl
d3a612ca42c17c3baa6c96ded00f98db349cc881nw * is "sbus@12". They are initialized to a random value and are
d3a612ca42c17c3baa6c96ded00f98db349cc881nw * set such that they are not equal initially.
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre /* check for a valid file */
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre MSGSTR(21000, "Error: Could not open %s\n"), file);
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre if (read(fcode_fd, fcode_buf, FCODE_HDR) != FCODE_HDR) {
d3a612ca42c17c3baa6c96ded00f98db349cc881nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Check if it's SBUS FCode by calling q_findSbusfile
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * if it is then isSbus will be 1, if not it will be 0
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * in case of an error, it will be -1
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * FCode header check - make sure it's PCI FCode
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Structure of FCode header (byte# refers to byte numbering
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * in FCode spec, not the byte# of our fcode_buf buffer):
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * header byte 00 0x55 prom signature byte one
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * byte 01 0xaa prom signature byte two
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * data byte 00-03 P C I R
cd37da7426f0c49c14ad9a8a07638ca971477566nw * header byte 32 0x55
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * byte 33 0xaa
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * data byte 60-63 P C I R
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * The second format with an offset of 32 is used for ifp prom
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: %s is not a valid FC100/P, "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "ISP2200, ISP23xx FCode file.\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
479ac37569625bae44ffb80071d4bc865fc710eddm /* check for single user mode */
479ac37569625bae44ffb80071d4bc865fc710eddm return (1);
479ac37569625bae44ffb80071d4bc865fc710eddm /* get bootpath */
479ac37569625bae44ffb80071d4bc865fc710eddm * Get count of, and names of PCI slots with ifp device control
479ac37569625bae44ffb80071d4bc865fc710eddm * (devctl) nodes. Search /devices.
479ac37569625bae44ffb80071d4bc865fc710eddm "\n Found Path to %d FC100/P, ISP2200, ISP23xx Devices\n"),
479ac37569625bae44ffb80071d4bc865fc710eddm "Error: Could not get /devices path to FC100/P,"
479ac37569625bae44ffb80071d4bc865fc710eddm "ISP2200, ISP23xx Cards.\n"));
479ac37569625bae44ffb80071d4bc865fc710eddm for (i = 0; i < devcnt; i++) {
479ac37569625bae44ffb80071d4bc865fc710eddm MSGSTR(21006, "\n Opening Device: %s\n"), &pcibus_list[i][0]);
479ac37569625bae44ffb80071d4bc865fc710eddm /* Check if the device is valid */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Check FCode version present on the adapter (at last boot)
cd37da7426f0c49c14ad9a8a07638ca971477566nw " Detected FCode Version:\tNo version available for this FCode\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * For ISP2200, Sbus HBA, do just 1 download
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * for both the ports (dual port HBA)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Here it is assumed that readdir() always
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * returns the paths in pcibus_list[] in the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * sorted order.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "/n New FCode has already been downloaded "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "to this ISP2200 SBus HBA Card.\n"
cd37da7426f0c49c14ad9a8a07638ca971477566nw "It is sufficient to download to one "
cd37da7426f0c49c14ad9a8a07638ca971477566nw "port of the ISP2200 SBus HBA Card. "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Moving on...\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Check version of the supplied FCode file (once)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " New FCode Version:\t\t%s\n"),
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm * Load the New FCode
8e22821528b08c6dba4e8176351560f316f6d0dedm * Give warning if file doesn't appear to be correct
8e22821528b08c6dba4e8176351560f316f6d0dedm if (chip_id == 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Disable user-interrupt Control-C */
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Load FCode */
8e22821528b08c6dba4e8176351560f316f6d0dedm &pcibus_list[i][0]) == 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm " Successful FCode download: %s\n"),
8e22821528b08c6dba4e8176351560f316f6d0dedm "Error: FCode download failed: %s\n"),
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Restore SIGINT (user interrupt) setting */
8e22821528b08c6dba4e8176351560f316f6d0dedm * Retrieve the version banner from the card
8e22821528b08c6dba4e8176351560f316f6d0dedm * uses ioctl: FCIO_FCODE_MCODE_VERSION FCode revision
8e22821528b08c6dba4e8176351560f316f6d0dedmq_findversion(int verbose, int index, uchar_t *version, uint16_t *chip_id)
8e22821528b08c6dba4e8176351560f316f6d0dedm/*ARGSUSED*/
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm if (ioctl(fd, FCIO_FCODE_MCODE_VERSION, version_buffer) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm "Error: Driver interface FCIO_FCODE_MCODE_VERSION failed\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Need a way to get card MCODE (firmware) to track certain HW bugs */
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, " FCode:%s\n MCODE:%s\n PROM:%s\n",
8e22821528b08c6dba4e8176351560f316f6d0dedm * Get the fcode and prom's fw version
8e22821528b08c6dba4e8176351560f316f6d0dedm * using the fp ioctls. Currently, we pass
8e22821528b08c6dba4e8176351560f316f6d0dedm * only the fcode version to the calling function
cd37da7426f0c49c14ad9a8a07638ca971477566nw * and ignore the FW version (using the existing
8e22821528b08c6dba4e8176351560f316f6d0dedm * implementation).
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Get the fcode version */
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Information read operation */
8e22821528b08c6dba4e8176351560f316f6d0dedm /* wait 30 secs */
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Get type of card from product name in FCode version banner */
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (0);
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Retrieve the version banner and file type (2100 or 2200) from the file
cd37da7426f0c49c14ad9a8a07638ca971477566nwq_findfileversion(char *dl_fcode, uchar_t *version_file, uint16_t *file_id,
8e22821528b08c6dba4e8176351560f316f6d0dedm * Get file version from FCode for 2100 or 2202
8e22821528b08c6dba4e8176351560f316f6d0dedm * Ok, we're just checking for 2200 here. If it is we need
8e22821528b08c6dba4e8176351560f316f6d0dedm * to offset to find the banner.
cd37da7426f0c49c14ad9a8a07638ca971477566nw * If this is an ISP2200 Sbus Fcode file, then search for the string
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * "ISP2200 FC-AL Host Adapter Driver" in the whole fcode file
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Subtract 111 from the offset we add below for PCI Fcodes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Banner length varies; grab banner to end of date marker yr/mo/da */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (mark = (111 + qlc_offset); mark < (191 + qlc_offset); mark++) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Find if the FCode file is a ISP2200 SBUS Fcode file
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static int file_size;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (-1);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (-1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban * Search for the version string in the whole file
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((*sbus_offset = memstrstr((char *)sbus_info, qlgc2200Sbus,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban * Build a list of all the devctl entries for all the 2100/2200 based adapters
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm (strstr(devpath, fp_trans_id) && strstr(devpath, fp_trans))) &&
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Verify the path is valid */
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (0);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban * not a directory so
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * we don't care about it - return
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * It's a directory. Call ourself to
cd37da7426f0c49c14ad9a8a07638ca971477566nw * traverse the path(s)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Forget the /devices/pseudo/ directory */
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21017, "Error: %s Can't read directory\n"), devpath);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21018, "Error: Can't close directory %s\n"), devpath);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Get the boot device. Cannot load FCode to current boot device.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Boot devices under volume management will prompt a warning.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char *p = NULL, *p1 = NULL; /* p = full device, p1 = chunk to rm */
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm * If we can't get a link, we may be dealing with a volume mgr
8e22821528b08c6dba4e8176351560f316f6d0dedm * so give a warning. If a colon is present, we likely have a
8e22821528b08c6dba4e8176351560f316f6d0dedm * non-local disk or cd-rom, so no warning is necessary.
8e22821528b08c6dba4e8176351560f316f6d0dedm * e.g. /devices/pci@1f,4000/scsi@3/sd@6,0:b (cdrom, no link) or
8e22821528b08c6dba4e8176351560f316f6d0dedm * storage-e4:/blah/blah remote boot server
8e22821528b08c6dba4e8176351560f316f6d0dedm "\nWarning: Cannot read boot device link, check %s.\n"), MNTTAB);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Do not upgrade FCode on adapters controlling the boot device.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Copy boot device path to bootpath. First remove leading
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * path junk (../../..) then if it's an ifp device, chop off
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * the disk and add the devctl to the end of the path.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Load FCode to card.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * uses ioctl: IFPIO_FCODE_DOWNLOAD
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (ioctl(dev_fd, IFPIO_FCODE_DOWNLOAD, download_p) < 0) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw "Error: Driver interface IFPIO_FCODE_DOWNLOAD failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Information read operation */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Driver interface FCIO_DOWNLOAD_FCODE failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Issue warning strings and loop for Yes/No user interaction
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * err# 0 -- we're ok, warn for pending FCode load
cd37da7426f0c49c14ad9a8a07638ca971477566nw * 1 -- not in single user mode
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * 2 -- can't get chip_id
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * 3 -- card and file do not have same type (2100/2200)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "\nWarning: System is not in single-user mode.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Loading FCode will reset the adapter and terminate I/O activity\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Warning: FCode is missing or existing FCode has"
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " unrecognized version.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Warning: New FCode file version does not match this"
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " board type. Skipping...\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "\nWARNING!! This program will update the FCode in this"
cd37da7426f0c49c14ad9a8a07638ca971477566nw " and Emulex devices.\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw "This may take a few (5) minutes. Please be patient.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Do you wish to continue ? (y/n) "));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) fprintf(stderr, MSGSTR(21035, "Invalid input\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Name : memstrstr
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Input : pointer to buf1, pointer to buf2, size of buf1, size of buf2
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Returns :
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Offset of the start of contents-of-buf2 in buf1 if it is found
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * -1 if buf1 does not contain contents of buf2
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Synopsis:
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * This function works similar to strstr(). The difference is that null
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * characters in the buffer are treated like any other character. So, buf1
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * and buf2 can have embedded null characters in them.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (count1 = 0; count1 < (size1 - size2 + 1); count1++) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (--count2 == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * generic fcode load file routine. given a file descriptor to a fcode file
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * this routine will issue the FCIO_DOWNLOAD_FCODE ioctl to the given
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * device. Any ioctl errors will be returned in fcio_errno
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Arguments:
8edda6281c84e0632a22f9c8dbf0d6f1558878ebbaban * fcode_fd file descriptor to a fcode file
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * device path to the device we will be downloading the fcode onto
9581d9f4f3b1515f88149f920c7e786b4fb901d4baban * fcio_errno pointer to an int that will be used to return any errors
9581d9f4f3b1515f88149f920c7e786b4fb901d4baban * back to the caller
9581d9f4f3b1515f88149f920c7e786b4fb901d4baban * Retrurn Values:
9581d9f4f3b1515f88149f920c7e786b4fb901d4baban * 0 successful download
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * >0 otherwise
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwfcode_load_file(int fcode_fd, char *device, int *fcio_errno)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Searches for and updates the fcode for Emulex HBA cards
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * args: FCode file; if NULL only the current FCode
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * version is printed
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw void (*sigint)();
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* set the fcode download flag */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* check for a valid file */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw /* check for single user mode */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* get bootpath */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Download the Fcode to all the emulex cards found
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Create a snapshot of the kernel device tree */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Could not get /devices path to "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Emulex Devices.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* point to first node which matches emulex driver */
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Could not find any emulex cards
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Traverse device tree to find all emulex cards
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Found an attached node */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Found a node with "port" property */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check if the device is valid */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Check FCode version present on the adapter
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * (at last boot)
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (emulex_fcodeversion(node, (uchar_t *)&prom_ver_data[0])
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp " Detected FCode Version:\tNo version available for this FCode\n"));
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp " Detected FCode Version:\t%s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " New FCode Version:\t\t%s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen * Load the New FCode
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen * Give warning if file doesn't appear to be correct
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Disable user-interrupt Control-C */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Load FCode */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Successful FCode download: %s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Restore SIGINT (user interrupt) setting */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Retrieve the version from the card.
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * uses PROM properties
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* check to make sure ver is not NULL */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp return (0);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp return (1);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Retrieves information from the Emulex fcode
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Given a pattern, this routine will look for this pattern in the fcode
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * file and if found will return the pattern value
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * possible patterns are manufacturer and fcode-version
651c0131ccc65381cbda174bee44a4fd7a518d6bbabanemulex_fcode_reader(int fcode_fd, char *pattern, char *pattern_value,
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Check the arguments */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if (!fcode_fd || !pattern_value || pattern_value_size < 8) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((image = (uchar_t *)calloc(image_size, 1)) == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Read the fcode image file */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Initialize */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Default pattern_value string */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Search entire image for pattern string */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Read next two bytes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check second byte first due to endianness */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* If no match, then reset pattern */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If complete pattern has been matched then
cd37da7426f0c49c14ad9a8a07638ca971477566nw * exit loop
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (n == plen) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Check first byte second due to endianness */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Save byte in circular buffer */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (b == sizeof (buffer1)) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Check byte for pattern match */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* If no match, then reset pattern */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * If complete pattern has been matched
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * then exit loop
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (n == plen) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Not found. Try again with different endianess */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Initialize */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Search entire 32bit endian image for pattern string */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Read next four bytes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* If no match, then reset pattern */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If complete pattern has been matched then exit loop
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (n == plen) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* If no match, then reset pattern */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If complete pattern has been matched then exit loop
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (n == plen) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
cd37da7426f0c49c14ad9a8a07638ca971477566nw /* If no match, then reset pattern */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * If complete pattern has been matched then exit loop
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (n == plen) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Save byte in circular buffer */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (b == sizeof (buffer1)) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Check byte for pattern match */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* If no match, then reset pattern */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * If complete pattern has been matched then exit loop
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (n == plen) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Align buffer and eliminate non-printable characters */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen for (i = 0; i < (sizeof (buffer1)-plen); i++) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if (b == sizeof (buffer1)) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Zero any non-printable characters */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Scan backwards for first non-zero string. This will be the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * version string
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (buffer2[i] != 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (; i >= 0; i--) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (buffer2[i] == 0) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * error handling routine to handle emulex error conditions
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic void
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Fcode download failed. "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Bad fcode image.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Fcode download failed. Fcode is not "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "compatible with card.\n"));
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen "Error: Driver interface FCIO_DOWNLOAD_FCODE failed\n"));
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen "Error: FCode download failed: %s\n"),