qlgcupdate.c revision fcf3ce441efd61da9bb2884968af01cb7c1452cc
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * CDDL HEADER START
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *
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 *
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * or http://www.opensolaris.org/os/licensing.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * See the License for the specific language governing permissions
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * and limitations under the License.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *
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 *
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * CDDL HEADER END
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
0dcc71495bad040a0c83830efc85acf8d897350dnw * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Use is subject to license terms.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * I18N message number ranges
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * This file: 21000 - 21499
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Shared common messages: 1 - 1999
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
479ac37569625bae44ffb80071d4bc865fc710eddm
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
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
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#include <errno.h>
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#include <ctype.h>
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#include <fcntl.h>
d3a612ca42c17c3baa6c96ded00f98db349cc881nw#include <stdio.h>
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#include <string.h>
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen#include <strings.h>
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#include <unistd.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <stdlib.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/stat.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <limits.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <signal.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <dirent.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <nl_types.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <utmpx.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/mnttab.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/file.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/mtio.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/scsi/impl/uscsi.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/fibre-channel/fcio.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <stgcom.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <sys/scsi/adapters/ifpio.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include <libdevinfo.h>
479ac37569625bae44ffb80071d4bc865fc710eddm#include "luxadm.h"
479ac37569625bae44ffb80071d4bc865fc710eddm
479ac37569625bae44ffb80071d4bc865fc710eddm/* Error codes - used by the fcode_load_file routine */
479ac37569625bae44ffb80071d4bc865fc710eddm#define FCODE_SUCCESS 0 /* successful completion */
479ac37569625bae44ffb80071d4bc865fc710eddm#define FCODE_LOAD_FAILURE 1 /* general failure */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define FCODE_IOCTL_FAILURE 2 /* FCODE ioctl download failure */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define HBA_MAX 128
479ac37569625bae44ffb80071d4bc865fc710eddm#define FCODE_HDR 200
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define MAX_RETRIES 3
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define MAX_WAIT_TIME 30
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * EMULEX Fcode attributes
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMULEX_FCODE_VERSION_LENGTH 16
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMULEX_READ_BUFFER_SIZE 128
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Emulex specific error codes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMLX_ERRNO_START 0x100
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Diagnostic error codes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMLX_TEST_FAILED (EMLX_ERRNO_START + 0)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Download image contains bad data */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMLX_IMAGE_BAD (EMLX_ERRNO_START + 1)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Download image not compatible with current hardware */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMLX_IMAGE_INCOMPATIBLE (EMLX_ERRNO_START + 2)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Unable to take adapter offline */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMLX_IMAGE_FAILED (EMLX_ERRNO_START + 3)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Image download failed */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define EMLX_OFFLINE_FAILED (EMLX_ERRNO_START + 4)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define SBUS_CHIP_ID 0x1969
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define IVORY_BUS "/sbus@"
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw#define IVORY_DRVR "/SUNW,qlc@"
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
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/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * The variable qlgc2200Sbus represents the string which is always the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * starting string of the version information in an ISP2200 Sbus Fcode.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char qlgc2200Sbus[] = "ISP2200 Sbus FC-AL Host Adapter Driver";
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic char pcibus_list[HBA_MAX][PATH_MAX];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/* Internal functions */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int q_load_file(int, char *);
cd37da7426f0c49c14ad9a8a07638ca971477566nwstatic int q_getbootdev(uchar_t *);
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
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Functions to support Fcode download for Emulex HBAs
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int emulex_fcodeversion(di_node_t, uchar_t *);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic void handle_emulex_error(int, char *);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw/*
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
d3a612ca42c17c3baa6c96ded00f98db349cc881nw */
d3a612ca42c17c3baa6c96ded00f98db349cc881nwint
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwq_qlgc_update(unsigned int verbose, char *file)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*ARGSUSED*/
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int fd, fcode_fd = -1, errnum = 0, devcnt = 0, retval = 0, isSbus = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int sbus_off;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uint_t i, fflag = 0;
d3a612ca42c17c3baa6c96ded00f98db349cc881nw uint16_t chip_id = 0, file_id = 0;
d3a612ca42c17c3baa6c96ded00f98db349cc881nw uchar_t fcode_buf[FCODE_HDR];
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static uchar_t bootpath[PATH_MAX];
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static uchar_t version[MAXNAMELEN], version_file[MAXNAMELEN];
d3a612ca42c17c3baa6c96ded00f98db349cc881nw char devpath[PATH_MAX], tmppath[PATH_MAX];
d3a612ca42c17c3baa6c96ded00f98db349cc881nw void (*sigint)(); /* to store default SIGTERM setting */
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static struct utmpx *utmpp = NULL; /* pointer for getutxent() */
d3a612ca42c17c3baa6c96ded00f98db349cc881nw char *ptr1, *ptr2;
d3a612ca42c17c3baa6c96ded00f98db349cc881nw char phys_path[PATH_MAX];
d3a612ca42c17c3baa6c96ded00f98db349cc881nw /*
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.
d3a612ca42c17c3baa6c96ded00f98db349cc881nw */
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static char port1[MAXNAMELEN] = {NULL};
d3a612ca42c17c3baa6c96ded00f98db349cc881nw static char port2[MAXNAMELEN] = {NULL};
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre
d3a612ca42c17c3baa6c96ded00f98db349cc881nw if (file) {
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre fflag++;
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre /* check for a valid file */
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre if ((fcode_fd = open(file, O_RDONLY)) < 0) {
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre (void) fprintf(stderr,
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre MSGSTR(21000, "Error: Could not open %s\n"), file);
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre return (1);
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre }
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre if (read(fcode_fd, fcode_buf, FCODE_HDR) != FCODE_HDR) {
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre perror(MSGSTR(21001, "read"));
2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1fBaban Kenkre (void) close(fcode_fd);
d3a612ca42c17c3baa6c96ded00f98db349cc881nw return (1);
d3a612ca42c17c3baa6c96ded00f98db349cc881nw }
d3a612ca42c17c3baa6c96ded00f98db349cc881nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw isSbus = q_findSbusfile(fcode_fd, &sbus_off);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (isSbus == -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
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 * OR
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (!(((fcode_buf[0x00] == 0x55) &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x01] == 0xaa) &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x1c] == 'P') &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x1d] == 'C') &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x1e] == 'I') &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x1f] == 'R')) ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw ((fcode_buf[0x20] == 0x55) &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x21] == 0xaa) &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x3c] == 'P') &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x3d] == 'C') &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x3e] == 'I') &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (fcode_buf[0x3f] == 'R')) ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (isSbus))) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21002,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: %s is not a valid FC100/P, "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "ISP2200, ISP23xx FCode file.\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw file);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
4d61c878ad5fbf36c5338bef5994cc5fe88a589aJulian Pullen }
479ac37569625bae44ffb80071d4bc865fc710eddm
479ac37569625bae44ffb80071d4bc865fc710eddm /* check for single user mode */
479ac37569625bae44ffb80071d4bc865fc710eddm while ((utmpp = getutxent()) != NULL) {
479ac37569625bae44ffb80071d4bc865fc710eddm if (strstr(utmpp->ut_line, "run-level") &&
479ac37569625bae44ffb80071d4bc865fc710eddm (strcmp(utmpp->ut_line, "run-level S") &&
479ac37569625bae44ffb80071d4bc865fc710eddm strcmp(utmpp->ut_line, "run-level 1"))) {
479ac37569625bae44ffb80071d4bc865fc710eddm if (q_warn(1)) {
479ac37569625bae44ffb80071d4bc865fc710eddm (void) endutxent();
479ac37569625bae44ffb80071d4bc865fc710eddm (void) close(fcode_fd);
479ac37569625bae44ffb80071d4bc865fc710eddm return (1);
479ac37569625bae44ffb80071d4bc865fc710eddm }
479ac37569625bae44ffb80071d4bc865fc710eddm break;
479ac37569625bae44ffb80071d4bc865fc710eddm }
479ac37569625bae44ffb80071d4bc865fc710eddm }
479ac37569625bae44ffb80071d4bc865fc710eddm (void) endutxent();
479ac37569625bae44ffb80071d4bc865fc710eddm
479ac37569625bae44ffb80071d4bc865fc710eddm /* get bootpath */
479ac37569625bae44ffb80071d4bc865fc710eddm if (!q_getbootdev((uchar_t *)&bootpath[0]) &&
479ac37569625bae44ffb80071d4bc865fc710eddm getenv("_LUX_D_DEBUG") != NULL) {
479ac37569625bae44ffb80071d4bc865fc710eddm (void) fprintf(stdout, " Bootpath: %s\n", bootpath);
4d61c878ad5fbf36c5338bef5994cc5fe88a589aJulian Pullen }
479ac37569625bae44ffb80071d4bc865fc710eddm }
479ac37569625bae44ffb80071d4bc865fc710eddm /*
479ac37569625bae44ffb80071d4bc865fc710eddm * Get count of, and names of PCI slots with ifp device control
479ac37569625bae44ffb80071d4bc865fc710eddm * (devctl) nodes. Search /devices.
479ac37569625bae44ffb80071d4bc865fc710eddm */
479ac37569625bae44ffb80071d4bc865fc710eddm (void) strcpy(devpath, "/devices");
479ac37569625bae44ffb80071d4bc865fc710eddm if (q_getdevctlpath(devpath, (int *)&devcnt) == 0) {
479ac37569625bae44ffb80071d4bc865fc710eddm (void) fprintf(stdout, MSGSTR(21003,
479ac37569625bae44ffb80071d4bc865fc710eddm "\n Found Path to %d FC100/P, ISP2200, ISP23xx Devices\n"),
479ac37569625bae44ffb80071d4bc865fc710eddm devcnt);
479ac37569625bae44ffb80071d4bc865fc710eddm } else {
479ac37569625bae44ffb80071d4bc865fc710eddm (void) fprintf(stderr, MSGSTR(21004,
479ac37569625bae44ffb80071d4bc865fc710eddm "Error: Could not get /devices path to FC100/P,"
479ac37569625bae44ffb80071d4bc865fc710eddm "ISP2200, ISP23xx Cards.\n"));
479ac37569625bae44ffb80071d4bc865fc710eddm retval++;
479ac37569625bae44ffb80071d4bc865fc710eddm }
479ac37569625bae44ffb80071d4bc865fc710eddm
479ac37569625bae44ffb80071d4bc865fc710eddm for (i = 0; i < devcnt; i++) {
479ac37569625bae44ffb80071d4bc865fc710eddm
479ac37569625bae44ffb80071d4bc865fc710eddm (void) strncpy((char *)phys_path, &pcibus_list[i][0],
479ac37569625bae44ffb80071d4bc865fc710eddm strlen(&pcibus_list[i][0]));
479ac37569625bae44ffb80071d4bc865fc710eddm if (fflag && (strstr((char *)bootpath,
479ac37569625bae44ffb80071d4bc865fc710eddm strtok((char *)phys_path, ":")) != NULL)) {
479ac37569625bae44ffb80071d4bc865fc710eddm (void) fprintf(stderr,
479ac37569625bae44ffb80071d4bc865fc710eddm MSGSTR(21005, "Ignoring %s (bootpath)\n"),
479ac37569625bae44ffb80071d4bc865fc710eddm &pcibus_list[i][0]);
479ac37569625bae44ffb80071d4bc865fc710eddm continue;
479ac37569625bae44ffb80071d4bc865fc710eddm }
479ac37569625bae44ffb80071d4bc865fc710eddm
479ac37569625bae44ffb80071d4bc865fc710eddm (void) fprintf(stdout,
479ac37569625bae44ffb80071d4bc865fc710eddm MSGSTR(21006, "\n Opening Device: %s\n"), &pcibus_list[i][0]);
479ac37569625bae44ffb80071d4bc865fc710eddm /* Check if the device is valid */
479ac37569625bae44ffb80071d4bc865fc710eddm if ((fd = open(&pcibus_list[i][0], O_RDWR)) < 0) {
479ac37569625bae44ffb80071d4bc865fc710eddm (void) fprintf(stderr,
479ac37569625bae44ffb80071d4bc865fc710eddm MSGSTR(21000, "Error: Could not open %s\n"),
479ac37569625bae44ffb80071d4bc865fc710eddm &pcibus_list[i][0]);
479ac37569625bae44ffb80071d4bc865fc710eddm retval++;
479ac37569625bae44ffb80071d4bc865fc710eddm continue;
479ac37569625bae44ffb80071d4bc865fc710eddm }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Check FCode version present on the adapter (at last boot)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (q_findversion(verbose, i, (uchar_t *)&version[0],
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw &chip_id) == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strlen((char *)version) == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, MSGSTR(21007,
cd37da7426f0c49c14ad9a8a07638ca971477566nw " Detected FCode Version:\tNo version available for this FCode\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, MSGSTR(21008,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Detected FCode Version:\t%s\n"), version);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw chip_id = 0x0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (fflag) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strcpy(tmppath, pcibus_list[i]);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (ptr1 = strstr(tmppath, IVORY_BUS)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (ptr2 = strstr(ptr1, IVORY_DRVR)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw ptr2 = strchr(ptr2, ',');
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (ptr2 = strchr(++ptr2, ',')) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *ptr2 = '\0';
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strcpy(port2, ptr1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strcmp(port1, port2) == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, MSGSTR(21037,
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 continue;
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Check version of the supplied FCode file (once)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((file_id != 0 && version_file != NULL) ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (q_findfileversion((char *)
8e22821528b08c6dba4e8176351560f316f6d0dedm &fcode_buf[0], (uchar_t *)&version_file[0],
8e22821528b08c6dba4e8176351560f316f6d0dedm &file_id, isSbus, &sbus_off) == 0)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, MSGSTR(21009,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " New FCode Version:\t\t%s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw version_file);
cd37da7426f0c49c14ad9a8a07638ca971477566nw } else {
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) close(fcode_fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm /*
8e22821528b08c6dba4e8176351560f316f6d0dedm * Load the New FCode
8e22821528b08c6dba4e8176351560f316f6d0dedm * Give warning if file doesn't appear to be correct
8e22821528b08c6dba4e8176351560f316f6d0dedm *
8e22821528b08c6dba4e8176351560f316f6d0dedm */
8e22821528b08c6dba4e8176351560f316f6d0dedm if (chip_id == 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm errnum = 2; /* can't get chip_id */
8e22821528b08c6dba4e8176351560f316f6d0dedm retval++;
8e22821528b08c6dba4e8176351560f316f6d0dedm } else if (chip_id - file_id != 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm errnum = 3; /* file/card mismatch */
8e22821528b08c6dba4e8176351560f316f6d0dedm retval++;
8e22821528b08c6dba4e8176351560f316f6d0dedm } else {
8e22821528b08c6dba4e8176351560f316f6d0dedm errnum = 0; /* everything is ok */
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if (!q_warn(errnum)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Disable user-interrupt Control-C */
8e22821528b08c6dba4e8176351560f316f6d0dedm sigint =
8e22821528b08c6dba4e8176351560f316f6d0dedm (void (*)(int)) signal(SIGINT, SIG_IGN);
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Load FCode */
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, MSGSTR(21010,
8e22821528b08c6dba4e8176351560f316f6d0dedm " Loading FCode: %s\n"), file);
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if (q_load_file(fcode_fd,
8e22821528b08c6dba4e8176351560f316f6d0dedm &pcibus_list[i][0]) == 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, MSGSTR(21011,
8e22821528b08c6dba4e8176351560f316f6d0dedm " Successful FCode download: %s\n"),
8e22821528b08c6dba4e8176351560f316f6d0dedm &pcibus_list[i][0]);
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) strcpy(port1, port2);
8e22821528b08c6dba4e8176351560f316f6d0dedm } else {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban (void) fprintf(stderr, MSGSTR(21012,
8e22821528b08c6dba4e8176351560f316f6d0dedm "Error: FCode download failed: %s\n"),
8e22821528b08c6dba4e8176351560f316f6d0dedm &pcibus_list[i][0]);
8e22821528b08c6dba4e8176351560f316f6d0dedm retval++;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Restore SIGINT (user interrupt) setting */
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) signal(SIGINT, sigint);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, " ");
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, MSGSTR(125, "Complete\n"));
8e22821528b08c6dba4e8176351560f316f6d0dedm if (fcode_fd != -1)
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) close(fcode_fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (retval);
cd37da7426f0c49c14ad9a8a07638ca971477566nw}
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm/*
8e22821528b08c6dba4e8176351560f316f6d0dedm * Retrieve the version banner from the card
8e22821528b08c6dba4e8176351560f316f6d0dedm * uses ioctl: FCIO_FCODE_MCODE_VERSION FCode revision
8e22821528b08c6dba4e8176351560f316f6d0dedm */
8e22821528b08c6dba4e8176351560f316f6d0dedmstatic int
8e22821528b08c6dba4e8176351560f316f6d0dedmq_findversion(int verbose, int index, uchar_t *version, uint16_t *chip_id)
8e22821528b08c6dba4e8176351560f316f6d0dedm/*ARGSUSED*/
8e22821528b08c6dba4e8176351560f316f6d0dedm{
8e22821528b08c6dba4e8176351560f316f6d0dedm int fd, ntries;
cd37da7426f0c49c14ad9a8a07638ca971477566nw struct ifp_fm_version *version_buffer = NULL;
cd37da7426f0c49c14ad9a8a07638ca971477566nw char prom_ver[100] = {NULL};
8e22821528b08c6dba4e8176351560f316f6d0dedm char mcode_ver[100] = {NULL};
8e22821528b08c6dba4e8176351560f316f6d0dedm fcio_t fcio;
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if (strstr(&pcibus_list[index][0], fc_trans)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm
cd37da7426f0c49c14ad9a8a07638ca971477566nw if ((fd = open(&pcibus_list[index][0], O_RDWR)) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr,
cd37da7426f0c49c14ad9a8a07638ca971477566nw MSGSTR(21000, "Error: Could not open %s\n"),
cd37da7426f0c49c14ad9a8a07638ca971477566nw &pcibus_list[index][0]);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((version_buffer = (struct ifp_fm_version *)malloc(
8e22821528b08c6dba4e8176351560f316f6d0dedm sizeof (struct ifp_fm_version))) == NULL) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr,
8e22821528b08c6dba4e8176351560f316f6d0dedm MSGSTR(21013, "Error: Memory allocation failed\n"));
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) close(fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm version_buffer->fcode_ver = (char *)version;
8e22821528b08c6dba4e8176351560f316f6d0dedm version_buffer->mcode_ver = mcode_ver;
8e22821528b08c6dba4e8176351560f316f6d0dedm version_buffer->prom_ver = prom_ver;
8e22821528b08c6dba4e8176351560f316f6d0dedm version_buffer->fcode_ver_len = MAXNAMELEN - 1;
8e22821528b08c6dba4e8176351560f316f6d0dedm version_buffer->mcode_ver_len = 100;
8e22821528b08c6dba4e8176351560f316f6d0dedm version_buffer->prom_ver_len = 100;
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if (ioctl(fd, FCIO_FCODE_MCODE_VERSION, version_buffer) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr, MSGSTR(21014,
8e22821528b08c6dba4e8176351560f316f6d0dedm "Error: Driver interface FCIO_FCODE_MCODE_VERSION failed\n"));
8e22821528b08c6dba4e8176351560f316f6d0dedm free(version_buffer);
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) close(fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm version[version_buffer->fcode_ver_len] = '\0';
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Need a way to get card MCODE (firmware) to track certain HW bugs */
8e22821528b08c6dba4e8176351560f316f6d0dedm if (getenv("_LUX_D_DEBUG") != NULL) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, " Device %i: QLGC chip_id %x\n",
8e22821528b08c6dba4e8176351560f316f6d0dedm index+1, *chip_id);
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stdout, " FCode:%s\n MCODE:%s\n PROM:%s\n",
8e22821528b08c6dba4e8176351560f316f6d0dedm (char *)version, mcode_ver, prom_ver);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm free(version_buffer);
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm } else if (strstr(&pcibus_list[index][0], fp_trans)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm /*
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).
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((fd = open(&pcibus_list[index][0], O_RDWR)) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr,
8e22821528b08c6dba4e8176351560f316f6d0dedm MSGSTR(4511, "Could not open %s\n"),
8e22821528b08c6dba4e8176351560f316f6d0dedm &pcibus_list[index][0]);
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) close(fd);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Get the fcode version */
8e22821528b08c6dba4e8176351560f316f6d0dedm bzero(version, sizeof (version));
8e22821528b08c6dba4e8176351560f316f6d0dedm fcio.fcio_cmd = FCIO_GET_FCODE_REV;
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Information read operation */
8e22821528b08c6dba4e8176351560f316f6d0dedm fcio.fcio_xfer = FCIO_XFER_READ;
8e22821528b08c6dba4e8176351560f316f6d0dedm fcio.fcio_obuf = (caddr_t)version;
8e22821528b08c6dba4e8176351560f316f6d0dedm fcio.fcio_olen = MAXNAMELEN;
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw for (ntries = 0; ntries < MAX_RETRIES; ntries++) {
8e22821528b08c6dba4e8176351560f316f6d0dedm if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((errno == EAGAIN) &&
8e22821528b08c6dba4e8176351560f316f6d0dedm (ntries+1 < MAX_RETRIES)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm /* wait 30 secs */
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) sleep(MAX_WAIT_TIME);
8e22821528b08c6dba4e8176351560f316f6d0dedm continue;
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) close(fd);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (L_FCIO_GET_FCODE_REV_FAIL);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm break;
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm version[MAXNAMELEN-1] = '\0';
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Get type of card from product name in FCode version banner */
8e22821528b08c6dba4e8176351560f316f6d0dedm if (strstr((char *)version, qlgc2100)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm *chip_id = 0x2100;
8e22821528b08c6dba4e8176351560f316f6d0dedm } else if (strstr((char *)version, qlgc2200)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm *chip_id = 0x2200;
8e22821528b08c6dba4e8176351560f316f6d0dedm if (strstr((char *)version, "Sbus")) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw *chip_id = SBUS_CHIP_ID;
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw } else if (strstr((char *)version, qlgc2300)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm *chip_id = 0x2300;
cd37da7426f0c49c14ad9a8a07638ca971477566nw } else if (strstr((char *)version, qlgc2312)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm *chip_id = 0x2312;
8e22821528b08c6dba4e8176351560f316f6d0dedm } else {
8e22821528b08c6dba4e8176351560f316f6d0dedm *chip_id = 0x0;
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) close(fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (0);
cd37da7426f0c49c14ad9a8a07638ca971477566nw}
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw/*
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Retrieve the version banner and file type (2100 or 2200) from the file
cd37da7426f0c49c14ad9a8a07638ca971477566nw */
cd37da7426f0c49c14ad9a8a07638ca971477566nwstatic int
cd37da7426f0c49c14ad9a8a07638ca971477566nwq_findfileversion(char *dl_fcode, uchar_t *version_file, uint16_t *file_id,
8e22821528b08c6dba4e8176351560f316f6d0dedm int isSbus, int *sbus_offset)
8e22821528b08c6dba4e8176351560f316f6d0dedm{
8e22821528b08c6dba4e8176351560f316f6d0dedm int mark;
8e22821528b08c6dba4e8176351560f316f6d0dedm int qlc_offset = 0;
8e22821528b08c6dba4e8176351560f316f6d0dedm char temp[4] = {NULL};
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm /*
8e22821528b08c6dba4e8176351560f316f6d0dedm * Get file version from FCode for 2100 or 2202
8e22821528b08c6dba4e8176351560f316f6d0dedm */
8e22821528b08c6dba4e8176351560f316f6d0dedm if (isSbus) {
8e22821528b08c6dba4e8176351560f316f6d0dedm *file_id = SBUS_CHIP_ID;
8e22821528b08c6dba4e8176351560f316f6d0dedm } else {
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((dl_fcode[0x23] == 0x22) ||
8e22821528b08c6dba4e8176351560f316f6d0dedm (dl_fcode[0x23] == 0x23)) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw *file_id = dl_fcode[0x22] & 0xff;
cd37da7426f0c49c14ad9a8a07638ca971477566nw *file_id |= (dl_fcode[0x23] << 8) & 0xff00;
cd37da7426f0c49c14ad9a8a07638ca971477566nw } else {
8e22821528b08c6dba4e8176351560f316f6d0dedm *file_id = dl_fcode[0x42] & 0xff;
cd37da7426f0c49c14ad9a8a07638ca971477566nw *file_id |= (dl_fcode[0x43] << 8) & 0xff00;
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
cd37da7426f0c49c14ad9a8a07638ca971477566nw /*
8e22821528b08c6dba4e8176351560f316f6d0dedm * Ok, we're just checking for 2200 here. If it is we need
8e22821528b08c6dba4e8176351560f316f6d0dedm * to offset to find the banner.
8e22821528b08c6dba4e8176351560f316f6d0dedm */
cd37da7426f0c49c14ad9a8a07638ca971477566nw if ((*file_id == 0x2200) ||
cd37da7426f0c49c14ad9a8a07638ca971477566nw (*file_id == 0x2300) ||
cd37da7426f0c49c14ad9a8a07638ca971477566nw (*file_id == 0x2312)) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw qlc_offset = -32;
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw /*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (isSbus) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *file_id = SBUS_CHIP_ID;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw qlc_offset = *sbus_offset;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Subtract 111 from the offset we add below for PCI Fcodes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw qlc_offset -= 111;
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Banner length varies; grab banner to end of date marker yr/mo/da */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw version_file[0] = '\0';
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (mark = (111 + qlc_offset); mark < (191 + qlc_offset); mark++) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) strncpy(temp, (char *)&dl_fcode[mark], 4);
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((strncmp(&temp[0], "/", 1) == 0) &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (strncmp(&temp[3], "/", 1) == 0)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strncat((char *)version_file,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (char *)&dl_fcode[mark], 6);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw break;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strncat((char *)version_file, temp, 1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (0);
cd37da7426f0c49c14ad9a8a07638ca971477566nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Find if the FCode file is a ISP2200 SBUS Fcode file
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwq_findSbusfile(int fd, int *sbus_offset)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static int file_size;
cd37da7426f0c49c14ad9a8a07638ca971477566nw char *sbus_info;
cd37da7426f0c49c14ad9a8a07638ca971477566nw struct stat statinfo;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (lseek(fd, 0, SEEK_SET) == -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw perror(MSGSTR(21022, "seek"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm if (fstat(fd, &statinfo)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm perror(MSGSTR(21023, "fstat"));
8e22821528b08c6dba4e8176351560f316f6d0dedm return (-1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm file_size = statinfo.st_size;
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((sbus_info = (char *)malloc(file_size)) == NULL) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr,
8e22821528b08c6dba4e8176351560f316f6d0dedm MSGSTR(21013, "Error: Memory allocation failed\n"));
8e22821528b08c6dba4e8176351560f316f6d0dedm return (-1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban if (read(fd, sbus_info, file_size) < 0) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban perror(MSGSTR(21001, "read"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(sbus_info);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban /*
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban * Search for the version string in the whole file
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((*sbus_offset = memstrstr((char *)sbus_info, qlgc2200Sbus,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw file_size, strlen(qlgc2200Sbus))) != -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(sbus_info);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(sbus_info);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw}
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban * Build a list of all the devctl entries for all the 2100/2200 based adapters
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
651c0131ccc65381cbda174bee44a4fd7a518d6bbabanstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwq_getdevctlpath(char *devpath, int *devcnt)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw struct stat statbuf;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw struct dirent *dirp = NULL;
cd37da7426f0c49c14ad9a8a07638ca971477566nw DIR *dp = NULL;
cd37da7426f0c49c14ad9a8a07638ca971477566nw char *ptr = NULL;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int err;
cd37da7426f0c49c14ad9a8a07638ca971477566nw int testopen;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
8e22821528b08c6dba4e8176351560f316f6d0dedm if (lstat(devpath, &statbuf) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr,
8e22821528b08c6dba4e8176351560f316f6d0dedm MSGSTR(21016, "Error: %s lstat() error\n"), devpath);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((strstr(devpath, fc_trans) ||
8e22821528b08c6dba4e8176351560f316f6d0dedm (strstr(devpath, fp_trans_id) && strstr(devpath, fp_trans))) &&
8e22821528b08c6dba4e8176351560f316f6d0dedm strstr(devpath, "devctl")) {
8e22821528b08c6dba4e8176351560f316f6d0dedm /* Verify the path is valid */
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((testopen = open(devpath, O_RDONLY)) >= 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) close(testopen);
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) strcpy(pcibus_list[*devcnt], devpath);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban *devcnt += 1;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (S_ISDIR(statbuf.st_mode) == 0) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban /*
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban * not a directory so
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * we don't care about it - return
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * It's a directory. Call ourself to
cd37da7426f0c49c14ad9a8a07638ca971477566nw * traverse the path(s)
cd37da7426f0c49c14ad9a8a07638ca971477566nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw ptr = devpath + strlen(devpath);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *ptr++ = '/';
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban *ptr = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Forget the /devices/pseudo/ directory */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strcmp(devpath, "/devices/pseudo/") == 0) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (0);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((dp = opendir(devpath)) == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21017, "Error: %s Can't read directory\n"), devpath);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw while ((dirp = readdir(dp)) != NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strcmp(dirp->d_name, ".") == 0 ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw strcmp(dirp->d_name, "..") == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw continue;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strcpy(ptr, dirp->d_name); /* append name */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw err = q_getdevctlpath(devpath, devcnt);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (closedir(dp) < 0) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21018, "Error: Can't close directory %s\n"), devpath);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (err);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Get the boot device. Cannot load FCode to current boot device.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Boot devices under volume management will prompt a warning.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwq_getbootdev(uchar_t *bootpath)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw struct mnttab mp;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw struct mnttab mpref;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw FILE *fp = NULL;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static char buf[BUFSIZ];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char *p = NULL, *p1 = NULL; /* p = full device, p1 = chunk to rm */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char *slot = ":devctl";
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char *root = "/";
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((fp = fopen(MNTTAB, "r")) == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
cd37da7426f0c49c14ad9a8a07638ca971477566nw MSGSTR(21000, "Error: Could not open %s\n"), MNTTAB);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw mntnull(&mpref);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw mpref.mnt_mountp = (char *)root;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (getmntany(fp, &mp, &mpref) != 0 ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw mpref.mnt_mountp == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21019,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Cannot get boot device, check %s.\n"), MNTTAB);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fclose(fp);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban (void) fclose(fp);
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm /*
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 */
8e22821528b08c6dba4e8176351560f316f6d0dedm if (readlink(mp.mnt_special, buf, BUFSIZ) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm if (strstr(mp.mnt_special, ":") == NULL) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr, MSGSTR(21020,
8e22821528b08c6dba4e8176351560f316f6d0dedm "\nWarning: Cannot read boot device link, check %s.\n"), MNTTAB);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21021,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Do not upgrade FCode on adapters controlling the boot device.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (p = strstr(buf, "/devices")) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strstr(buf, fc_trans) != NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw p1 = strrchr(p, '/');
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *p1 = '\0';
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strcpy((char *)bootpath, (char *)p);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (p1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strcat((char *)bootpath, slot);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Load FCode to card.
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * uses ioctl: IFPIO_FCODE_DOWNLOAD
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwq_load_file(int fcode_fd, char *device)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
cd37da7426f0c49c14ad9a8a07638ca971477566nw static int dev_fd, fcode_size;
cd37da7426f0c49c14ad9a8a07638ca971477566nw struct stat stat;
cd37da7426f0c49c14ad9a8a07638ca971477566nw ifp_download_t *download_p = NULL;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio_t fcio;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uint16_t file_id = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uchar_t *bin;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (lseek(fcode_fd, 0, SEEK_SET) == -1) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw perror(MSGSTR(21022, "seek"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (fstat(fcode_fd, &stat) == -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw perror(MSGSTR(21023, "fstat"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcode_size = stat.st_size;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strstr(device, fc_trans)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((download_p = (ifp_download_t *)malloc(
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw sizeof (ifp_download_t) + fcode_size)) == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
cd37da7426f0c49c14ad9a8a07638ca971477566nw MSGSTR(21013, "Error: Memory allocation failed\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) close(fcode_fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (1);
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((bin = (uchar_t *)malloc(fcode_size)) == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21013, "Error: Memory allocation failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strstr(device, fc_trans)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (read(fcode_fd, download_p->dl_fcode, fcode_size)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw != fcode_size) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw perror(MSGSTR(21001, "read"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(download_p);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (read(fcode_fd, bin, fcode_size)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw != fcode_size) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw perror(MSGSTR(21001, "read"));
8e22821528b08c6dba4e8176351560f316f6d0dedm free(bin);
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) close(fcode_fd);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if ((dev_fd = open(device, O_RDWR|O_EXCL)) < 0) {
8e22821528b08c6dba4e8176351560f316f6d0dedm (void) fprintf(stderr,
8e22821528b08c6dba4e8176351560f316f6d0dedm MSGSTR(21000, "Error: Could not open %s\n"), device);
8e22821528b08c6dba4e8176351560f316f6d0dedm free(download_p);
8e22821528b08c6dba4e8176351560f316f6d0dedm return (1);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm if (strstr(device, fc_trans)) {
8e22821528b08c6dba4e8176351560f316f6d0dedm download_p->dl_fcode_len = fcode_size;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw file_id = download_p->dl_fcode[0x42] & 0xff;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw file_id |= (download_p->dl_fcode[0x43] << 8) & 0xff00;
cd37da7426f0c49c14ad9a8a07638ca971477566nw download_p->dl_chip_id = file_id;
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (ioctl(dev_fd, IFPIO_FCODE_DOWNLOAD, download_p) < 0) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) fprintf(stderr, MSGSTR(21024,
cd37da7426f0c49c14ad9a8a07638ca971477566nw "Error: Driver interface IFPIO_FCODE_DOWNLOAD failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(download_p);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(dev_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(download_p);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else if (strstr(device, fp_trans)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_cmd = FCIO_DOWNLOAD_FCODE;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Information read operation */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_xfer = FCIO_XFER_WRITE;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_ibuf = (caddr_t)bin;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_ilen = fcode_size;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (ioctl(dev_fd, FCIO_CMD, &fcio) != 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21036,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Driver interface FCIO_DOWNLOAD_FCODE failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(download_p);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(dev_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(bin);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(dev_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwq_warn(int errnum)
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char input[1024];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw input[0] = '\0';
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (errnum == 1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21025,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "\nWarning: System is not in single-user mode.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21026,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Loading FCode will reset the adapter and terminate I/O activity\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (errnum == 2) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21027,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Warning: FCode is missing or existing FCode has"
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " unrecognized version.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else if (errnum == 3) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21028,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Warning: New FCode file version does not match this"
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " board type. Skipping...\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21029,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "\nWARNING!! This program will update the FCode in this"
cd37da7426f0c49c14ad9a8a07638ca971477566nw " FC100/PCI, ISP2200/PCI, ISP23xx/PCI "
cd37da7426f0c49c14ad9a8a07638ca971477566nw " and Emulex devices.\n"));
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) fprintf(stderr, MSGSTR(21030,
cd37da7426f0c49c14ad9a8a07638ca971477566nw "This may take a few (5) minutes. Please be patient.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwloop1:
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21031,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Do you wish to continue ? (y/n) "));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) gets(input);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((strcmp(input, MSGSTR(21032, "y")) == 0) ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (strcmp(input, MSGSTR(40, "yes")) == 0)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else if ((strcmp(input, MSGSTR(21033, "n")) == 0) ||
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (strcmp(input, MSGSTR(45, "no")) == 0)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21034, "Not Downloading FCode\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) fprintf(stderr, MSGSTR(21035, "Invalid input\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw goto loop1;
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban/*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwmemstrstr(char *s1, char *s2, int size1, int size2)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int count1, count2;
cd37da7426f0c49c14ad9a8a07638ca971477566nw char *s1_ptr, *s2_ptr;
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw count1 = size1; count2 = size2;
cd37da7426f0c49c14ad9a8a07638ca971477566nw s1_ptr = s1; s2_ptr = s2;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((size2 == 0)||(size1 == 0))
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (count1 = 0; count1 < (size1 - size2 + 1); count1++) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (*s1_ptr++ == *s2_ptr++) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (--count2 == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (count1 - size2 + 1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw continue;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw count2 = size2;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw s2_ptr = s2;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (-1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
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
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *
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
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwfcode_load_file(int fcode_fd, char *device, int *fcio_errno)
cd37da7426f0c49c14ad9a8a07638ca971477566nw{
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm fcio_t fcio;
8e22821528b08c6dba4e8176351560f316f6d0dedm static int dev_fd, fcode_size;
8e22821528b08c6dba4e8176351560f316f6d0dedm uchar_t *bin;
8e22821528b08c6dba4e8176351560f316f6d0dedm struct stat stat;
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if (device == NULL || fcio_errno == NULL) {
8e22821528b08c6dba4e8176351560f316f6d0dedm return (FCODE_LOAD_FAILURE);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm *fcio_errno = 0;
8e22821528b08c6dba4e8176351560f316f6d0dedm if (lseek(fcode_fd, 0, SEEK_SET) == -1) {
8e22821528b08c6dba4e8176351560f316f6d0dedm perror(MSGSTR(21022, "seek"));
8e22821528b08c6dba4e8176351560f316f6d0dedm return (FCODE_LOAD_FAILURE);
8e22821528b08c6dba4e8176351560f316f6d0dedm }
8e22821528b08c6dba4e8176351560f316f6d0dedm
8e22821528b08c6dba4e8176351560f316f6d0dedm if (fstat(fcode_fd, &stat) == -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw perror(MSGSTR(21023, "fstat"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (FCODE_LOAD_FAILURE);
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcode_size = stat.st_size;
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw if ((bin = (uchar_t *)malloc(fcode_size)) == NULL) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) fprintf(stderr,
cd37da7426f0c49c14ad9a8a07638ca971477566nw MSGSTR(21013, "Error: Memory allocation failed\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw return (FCODE_LOAD_FAILURE);
cd37da7426f0c49c14ad9a8a07638ca971477566nw }
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (read(fcode_fd, bin, fcode_size)
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp != fcode_size) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp perror(MSGSTR(21001, "read"));
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp free(bin);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp return (FCODE_LOAD_FAILURE);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((dev_fd = open(device, O_RDWR|O_EXCL)) < 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21122, "Error: Could not open %s, failed "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "with errno %d\n"), device, errno);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(bin);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (FCODE_LOAD_FAILURE);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_cmd = FCIO_DOWNLOAD_FCODE;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_xfer = FCIO_XFER_WRITE;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_ibuf = (caddr_t)bin;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fcio.fcio_ilen = fcode_size;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (ioctl(dev_fd, FCIO_CMD, &fcio) != 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(dev_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw *fcio_errno = fcio.fcio_errno;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(bin);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (FCODE_IOCTL_FAILURE);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(bin);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(dev_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (FCODE_SUCCESS);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
cd37da7426f0c49c14ad9a8a07638ca971477566nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw/*
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 */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwint
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwemulex_update(char *file)
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw{
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int fd, retval = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int devcnt = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uint_t state = 0, fflag = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static uchar_t bootpath[PATH_MAX];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int fcode_fd = -1;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static struct utmpx *utmpp = NULL;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_node_t root;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_node_t node, sib_node, count_node;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_minor_t minor_node;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char phys_path[PATH_MAX], *path;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int errnum = 0, fcio_errno = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static uchar_t prom_ver_data[MAXNAMELEN];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw static char ver_file[EMULEX_FCODE_VERSION_LENGTH];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw void (*sigint)();
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int prop_entries = -1;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int *port_data = NULL;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (file) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* set the fcode download flag */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fflag++;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* check for a valid file */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((fcode_fd = open(file, O_RDONLY)) < 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21118, "Error: Could not open %s, failed "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "with errno %d\n"), file, errno);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw /* check for single user mode */
cd37da7426f0c49c14ad9a8a07638ca971477566nw while ((utmpp = getutxent()) != NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (strstr(utmpp->ut_line, "run-level") &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (strcmp(utmpp->ut_line, "run-level S") &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw strcmp(utmpp->ut_line, "run-level 1"))) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (q_warn(1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) endutxent();
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw break;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) endutxent();
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* get bootpath */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (!q_getbootdev((uchar_t *)&bootpath[0]) &&
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw getenv("_LUX_D_DEBUG") != NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, " Bootpath: %s\n", bootpath);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Download the Fcode to all the emulex cards found
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Create a snapshot of the kernel device tree */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((root = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21114,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Could not get /devices path to "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Emulex Devices.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw retval++;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* point to first node which matches emulex driver */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw node = di_drv_first_node("emlxs", root);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (node == DI_NODE_NIL) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw /*
cd37da7426f0c49c14ad9a8a07638ca971477566nw * Could not find any emulex cards
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) di_fini(root);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) fprintf(stderr, MSGSTR(21115,
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp "\n Found Path to %d Emulex Devices.\n"), devcnt);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp retval++;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp count_node = node;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp while (count_node != DI_NODE_NIL) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp state = di_state(count_node);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if ((state & DI_DRIVER_DETACHED)
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp != DI_DRIVER_DETACHED) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp devcnt++;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp count_node = di_drv_next_node(count_node);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) fprintf(stdout, MSGSTR(21116,
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp "\n Found Path to %d Emulex Devices.\n"), devcnt);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /*
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Traverse device tree to find all emulex cards
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw while (node != DI_NODE_NIL) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw state = di_state(node);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw node = di_drv_next_node(node);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw continue;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw sib_node = di_child_node(node);
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen while (sib_node != DI_NODE_NIL) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen state = di_state(sib_node);
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if ((state & DI_DRIVER_DETACHED) !=
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen DI_DRIVER_DETACHED) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Found an attached node */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen prop_entries = di_prop_lookup_ints(
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen DDI_DEV_T_ANY, sib_node,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "port", &port_data);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (prop_entries != -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Found a node with "port" property */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw minor_node = di_minor_next(sib_node,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw DI_MINOR_NIL);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw break;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw sib_node = di_sibling_node(sib_node);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (sib_node == DI_NODE_NIL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw path = di_devfs_path(sib_node);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strcpy(phys_path, "/devices");
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strncat(phys_path, path, strlen(path));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_devfs_path_free(path);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if (fflag && (strstr((char *)bootpath,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (char *)phys_path) != NULL)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21117, "Ignoring %s (bootpath)\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw phys_path);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw node = di_drv_next_node(node);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban continue;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (minor_node) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strncat(phys_path, ":", 1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) strncat(phys_path,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_minor_name(minor_node),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw strlen(di_minor_name(minor_node)));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21107, "\n Opening Device: %s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw phys_path);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check if the device is valid */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((fd = open(phys_path, O_RDWR)) < 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21121, "Error: Could not open %s, failed "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "with errno %d\n"), phys_path, errno);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw retval++;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw node = di_drv_next_node(node);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw continue;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw (void) close(fd);
cd37da7426f0c49c14ad9a8a07638ca971477566nw
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /*
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Check FCode version present on the adapter
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * (at last boot)
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp memset(prom_ver_data, 0, sizeof (prom_ver_data));
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (emulex_fcodeversion(node, (uchar_t *)&prom_ver_data[0])
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp == 0) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp errnum = 0;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (strlen((char *)prom_ver_data) == 0) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) fprintf(stdout, MSGSTR(21108,
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp " Detected FCode Version:\tNo version available for this FCode\n"));
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) fprintf(stdout, MSGSTR(21109,
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp " Detected FCode Version:\t%s\n"),
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp prom_ver_data);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp errnum = 2; /* can't get prom properties */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp retval++;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (fflag) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp memset(ver_file, 0, sizeof (ver_file));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (emulex_fcode_reader(fcode_fd, "fcode-version",
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw ver_file, sizeof (ver_file)) == 0) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban (void) fprintf(stdout, MSGSTR(21110,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " New FCode Version:\t\t%s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw ver_file);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_fini(root);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) close(fcode_fd);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /*
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen * Load the New FCode
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen * Give warning if file doesn't appear to be correct
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if (!q_warn(errnum)) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Disable user-interrupt Control-C */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen sigint =
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen (void (*)(int)) signal(SIGINT, SIG_IGN);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Load FCode */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, MSGSTR(21111,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Loading FCode: %s\n"), file);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (fcode_load_file(fcode_fd, phys_path,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw &fcio_errno) == FCODE_SUCCESS) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, MSGSTR(21112,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw " Successful FCode download: %s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw phys_path);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw handle_emulex_error(fcio_errno,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw phys_path);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw retval++;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Restore SIGINT (user interrupt) setting */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) signal(SIGINT, sigint);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp node = di_drv_next_node(node);
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_fini(root);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, " ");
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stdout, MSGSTR(125, "Complete\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (fcode_fd != -1)
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban (void) close(fcode_fd);
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (retval);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Retrieve the version from the card.
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * uses PROM properties
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic int
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwemulex_fcodeversion(di_node_t node, uchar_t *ver) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_prom_prop_t promprop;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw di_prom_handle_t ph;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char *promname;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uchar_t *ver_data = NULL;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int size, found = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* check to make sure ver is not NULL */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (ver == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((ph = di_prom_init()) == DI_PROM_HANDLE_NIL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
cd37da7426f0c49c14ad9a8a07638ca971477566nw for (promprop = di_prom_prop_next(ph, node,
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp DI_PROM_PROP_NIL);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp promprop != DI_PROM_PROP_NIL;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp promprop = di_prom_prop_next(ph, node, promprop)) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (((promname = di_prom_prop_name(
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp promprop)) != NULL) &&
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (strcmp(promname, "fcode-version") == 0)) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp size = di_prom_prop_data(promprop, &ver_data);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) memset(ver, NULL, size);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp (void) memcpy(ver, ver_data, size);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp found = 1;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (found) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp return (0);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp return (1);
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp}
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp/*
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * Retrieves information from the Emulex fcode
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp *
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 *
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * possible patterns are manufacturer and fcode-version
cd37da7426f0c49c14ad9a8a07638ca971477566nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwint
651c0131ccc65381cbda174bee44a4fd7a518d6bbabanemulex_fcode_reader(int fcode_fd, char *pattern, char *pattern_value,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uint32_t pattern_value_size) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw int32_t i = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uint32_t n = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw uint32_t b = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char byte1;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char byte2;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw char byte3;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen char byte4;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen char buffer1[EMULEX_READ_BUFFER_SIZE];
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen char buffer2[EMULEX_READ_BUFFER_SIZE];
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen uint32_t plen, image_size;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen struct stat stat;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen uchar_t *image;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Check the arguments */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if (!fcode_fd || !pattern_value || pattern_value_size < 8) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (fstat(fcode_fd, &stat) == -1) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw perror(MSGSTR(21023, "fstat"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw image_size = stat.st_size;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (image_size < 2) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if ((image = (uchar_t *)calloc(image_size, 1)) == NULL) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw MSGSTR(21013, "Error: Memory allocation failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Read the fcode image file */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw lseek(fcode_fd, 0, SEEK_SET);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw read(fcode_fd, image, image_size);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Initialize */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp bzero(buffer1, sizeof (buffer1));
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen bzero(buffer2, sizeof (buffer2));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Default pattern_value string */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw strcpy((char *)pattern_value, "<unknown>");
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw plen = strlen(pattern);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw n = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw b = 0;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban i = 0;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Search entire image for pattern string */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw while (i <= (image_size - 2)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Read next two bytes */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw byte1 = image[i++];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw byte2 = image[i++];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check second byte first due to endianness */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw buffer1[b++] = byte2;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw b = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (pattern[n++] != byte2) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* If no match, then reset pattern */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw n = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If complete pattern has been matched then
cd37da7426f0c49c14ad9a8a07638ca971477566nw * exit loop
cd37da7426f0c49c14ad9a8a07638ca971477566nw */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (n == plen) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp goto found;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Check first byte second due to endianness */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Save byte in circular buffer */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp buffer1[b++] = byte1;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (b == sizeof (buffer1)) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp b = 0;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Check byte for pattern match */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (pattern[n++] != byte1) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* If no match, then reset pattern */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp n = 0;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /*
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * If complete pattern has been matched
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * then exit loop
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (n == plen) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp goto found;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Not found. Try again with different endianess */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Initialize */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw bzero(buffer1, sizeof (buffer1));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw bzero(buffer2, sizeof (buffer2));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw n = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw b = 0;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen i = 0;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Search entire 32bit endian image for pattern string */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen while (i <= (image_size - 4)) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Read next four bytes */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen byte1 = image[i++];
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen byte2 = image[i++];
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen byte3 = image[i++];
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen byte4 = image[i++];
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw buffer1[b++] = byte4;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw b = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (pattern[n++] != byte4) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* If no match, then reset pattern */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw n = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If complete pattern has been matched then exit loop
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (n == plen) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp goto found;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw buffer1[b++] = byte3;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban b = 0;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (pattern[n++] != byte3) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* If no match, then reset pattern */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw n = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * If complete pattern has been matched then exit loop
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (n == plen) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw goto found;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Save byte in circular buffer */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw buffer1[b++] = byte2;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (b == sizeof (buffer1)) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw b = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /* Check byte for pattern match */
cd37da7426f0c49c14ad9a8a07638ca971477566nw if (pattern[n++] != byte2) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw /* If no match, then reset pattern */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp n = 0;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /*
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * If complete pattern has been matched then exit loop
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (n == plen) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp goto found;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Save byte in circular buffer */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp buffer1[b++] = byte1;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (b == sizeof (buffer1)) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp b = 0;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp }
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* Check byte for pattern match */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp if (pattern[n++] != byte1) {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /* If no match, then reset pattern */
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp n = 0;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp } else {
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp /*
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp * If complete pattern has been matched then exit loop
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (n == plen) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw goto found;
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw free(image);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw return (1);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwfound:
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen free(image);
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Align buffer and eliminate non-printable characters */
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen for (i = 0; i < (sizeof (buffer1)-plen); i++) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen byte1 = buffer1[b++];
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen if (b == sizeof (buffer1)) {
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen b = 0;
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen }
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen /* Zero any non-printable characters */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (byte1 >= 33 && byte1 <= 126) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw buffer2[i] = byte1;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw buffer2[i] = 0;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw /*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * Scan backwards for first non-zero string. This will be the
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * version string
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (i = sizeof (buffer1)-plen-1; i >= 0; i--) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (buffer2[i] != 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw for (; i >= 0; i--) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (buffer2[i] == 0) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw i++;
48258c6b4e17f36ab09fba0bd6307d1fec9dcbcejp strncpy((char *)pattern_value,
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen &buffer2[i], pattern_value_size);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw break;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw break;
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban }
651c0131ccc65381cbda174bee44a4fd7a518d6bbaban return (0);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw/*
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw * error handling routine to handle emulex error conditions
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw */
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwstatic void
c5c4113dfcabb1eed3d4bdf7609de5170027a794nwhandle_emulex_error(int fcio_errno, char *phys_path) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw if (fcio_errno == EMLX_IMAGE_BAD) {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw fprintf(stderr, MSGSTR(21119,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Fcode download failed. "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Bad fcode image.\n"));
cd37da7426f0c49c14ad9a8a07638ca971477566nw } else if (fcio_errno == EMLX_IMAGE_INCOMPATIBLE) {
cd37da7426f0c49c14ad9a8a07638ca971477566nw fprintf(stderr, MSGSTR(21120,
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "Error: Fcode download failed. Fcode is not "
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw "compatible with card.\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw } else {
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr, MSGSTR(21036,
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen "Error: Driver interface FCIO_DOWNLOAD_FCODE failed\n"));
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw (void) fprintf(stderr,
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen MSGSTR(21113,
3ee87bca47e74aa2719352485b80973ca6e079b7Julian Pullen "Error: FCode download failed: %s\n"),
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw phys_path);
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw }
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw}
c5c4113dfcabb1eed3d4bdf7609de5170027a794nw