Exemple #1
0
/*
 * Decodes the SCSI sense byte to a string.
 *
 * RETURNS:
 *	character string
 */
static char *
decode_sense_byte(uchar_t status)
{
	switch (status & STATUS_MASK) {
		case STATUS_GOOD:
			return (MSGSTR(10000, "Good status"));

		case STATUS_CHECK:
			return (MSGSTR(128, "Check condition"));

		case STATUS_MET:
			return (MSGSTR(124, "Condition met"));

		case STATUS_BUSY:
			return (MSGSTR(37, "Busy"));

		case STATUS_INTERMEDIATE:
			return (MSGSTR(10001, "Intermediate"));

		case STATUS_INTERMEDIATE_MET:
			return (MSGSTR(10002, "Intermediate - condition met"));

		case STATUS_RESERVATION_CONFLICT:
			return (MSGSTR(10003, "Reservation_conflict"));

		case STATUS_TERMINATED:
			return (MSGSTR(126, "Command terminated"));

		case STATUS_QFULL:
			return (MSGSTR(83, "Queue full"));

		default:
			return (MSGSTR(4, "Unknown status"));
	}
}
Exemple #2
0
printprof()
{
    register nltype	*np;
    nltype		**sortednlp;
    int			index, timecmp();
    int			i;

    actime = 0.0;
    printf( "\f\n" );
    flatprofheader();
	/*
	 *	Sort the symbol table in by time
	 */
    sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
    if ( sortednlp == (nltype **) 0 ) {
	fprintf(stderr,
		MSGSTR(MEMSORT,
		       "[printprof] ran out of memory for time sorting\n"));
    }
    for ( index = 0 ; index < nname ; index += 1 ) {
	sortednlp[ index ] = &nl[ index ];
    }
    qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
    for ( index = 0 ; index < nname ; index += 1 ) {
	np = sortednlp[ index ];
	/* Don't print routines excluded by default, e.g. _mcount */
        for(i = 0; defaultEnl[i] && np != defaultEnl[i]; i++)
		;
	if(np == defaultEnl[i])
           continue;
	flatprofline( np );
    }
    actime = 0.0;
    cfree( sortednlp );
}
Exemple #3
0
/*
 * Read the mnttab and resolve the special device of the fs we are
 * interested in, into an absolute pathname
 */
static int
getbootdevname(char *bootfs, char *bdev)
{
	FILE *f;
	char *fname;
	char *devname;
	struct mnttab m;
	struct stat sbuf;
	int mountpt = 0;
	int found = 0;

	devname = bootfs;

	if (stat(bootfs, &sbuf) < 0) {
		perror(MSGSTR(6001, "stat"));
		return (0);
	}

	switch (sbuf.st_mode & S_IFMT) {
		case S_IFBLK:
			break;
		default:
			mountpt = 1;
			break;
	}

	if (mountpt) {
		fname = MNTTAB;
		f = fopen(fname, "r");
		if (f == NULL) {
			perror(fname);
			return (0);
		}

		while (getmntent(f, &m) == 0) {
			if (strcmp(m.mnt_mountp, bootfs))
				continue;
			else {
				found = 1;
				break;
			}
		}

		(void) fclose(f);

		if (!found) {
			return (0);
		}
		devname = m.mnt_special;
	}

	if (devfs_dev_to_prom_name(devname, bdev) != 0) {
		perror(devname);
		return (0);
	}

	return (1);
}
Exemple #4
0
/*
 * error handling routine to handle emulex error conditions
 */
static void
handle_emulex_error(int fcio_errno, char *phys_path) {
	if (fcio_errno == EMLX_IMAGE_BAD) {
		fprintf(stderr, MSGSTR(21119,
			    "Error: Fcode download failed.  "
			    "Bad fcode image.\n"));
	} else if (fcio_errno == EMLX_IMAGE_INCOMPATIBLE) {
		fprintf(stderr, MSGSTR(21120,
			    "Error: Fcode download failed.  Fcode is not "
			    "compatible with card.\n"));
	} else {
		(void) fprintf(stderr, MSGSTR(21036,
		    "Error: Driver interface FCIO_DOWNLOAD_FCODE failed\n"));
		(void) fprintf(stderr,
			MSGSTR(21113,
				"Error: FCode download failed: %s\n"),
				phys_path);
	}
}
Exemple #5
0
/*
 * Find if the FCode file is a ISP2200 SBUS Fcode file
 */
static int
q_findSbusfile(int fd, int *sbus_offset)
{
	static int file_size;
	char *sbus_info;
	struct stat statinfo;

	if (lseek(fd, 0, SEEK_SET) == -1) {
		perror(MSGSTR(21022, "seek"));
		return (-1);
	}
	if (fstat(fd, &statinfo)) {
		perror(MSGSTR(21023, "fstat"));
		return (-1);
	}
	file_size = statinfo.st_size;

	if ((sbus_info = (char *)malloc(file_size)) == NULL) {
		(void) fprintf(stderr,
		    MSGSTR(21013, "Error: Memory allocation failed\n"));
		return (-1);
	}

	if (read(fd, sbus_info, file_size) < 0) {
		perror(MSGSTR(21001, "read"));
		free(sbus_info);
		return (-1);
	}

	/*
	 * Search for the version string in the whole file
	 */
	if ((*sbus_offset = memstrstr((char *)sbus_info, qlgc2200Sbus,
			    file_size, strlen(qlgc2200Sbus))) != -1) {
		free(sbus_info);
		return (1);
	} else {
		free(sbus_info);
		return (0);
	}
}
Exemple #6
0
/*
 * Call getbootdevname() to get the absolute pathname of boot device
 * and call setprom() to set the boot-device variable.
 */
int
setboot(unsigned int yes, unsigned int verbose, char *fname)
{
	char	bdev[MAXPATHLEN];

	if (!getbootdevname(fname, bdev)) {
		(void) fprintf(stderr, MSGSTR(6000,
			"Cannot determine device name for %s\n"),
			fname);
		return (errno);
	}

	return (setprom(yes, verbose, bdev));
}
Exemple #7
0
/*
 * setprom() - use /dev/openprom to read the "boot_device" variable and set
 * it to the new value.
 */
static int
setprom(unsigned yes, unsigned verbose, char *bdev)
{
	struct openpromio	*pio;
	int			fd;
	char			save_bootdev[MAXVALSIZE];

	if ((fd = open("/dev/openprom", O_RDWR)) < 0) {
		perror(MSGSTR(6002, "Could not open openprom dev"));
		return (errno);
	}

	pio = (struct openpromio *)malloc(sizeof (struct openpromio) +
					MAXVALSIZE + MAXPROPSIZE);

	if (pio == (struct openpromio *)NULL) {
		perror(MSGSTR(6003, " Error: Unable to allocate memory."));
		return (errno);
	}

	pio->oprom_size = MAXVALSIZE;
	(void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME);

	if (ioctl(fd, OPROMGETOPT, pio) < 0) {
		perror(MSGSTR(6004, "openprom getopt ioctl"));
		return (errno);
	}

	/*
	 * save the existing boot-device, so we can use it if setting
	 * to new value fails.
	 */
	(void) strcpy(save_bootdev, pio->oprom_array);

	if (verbose) {
		(void) fprintf(stdout,
			MSGSTR(6005,
			"Current boot-device = %s\n"), pio->oprom_array);
		(void) fprintf(stdout, MSGSTR(6006,
			"New boot-device = %s\n"), bdev);
	}

	if (!yes) {
		(void) fprintf(stdout, MSGSTR(6007,
			"Do you want to change boot-device "
			"to the new setting? (y/n) "));
		switch (getchar()) {
			case 'Y':
			case 'y':
				break;
			default:
				return (0);
		}
	}

	/* set the new value for boot-device */

	pio->oprom_size = (int)strlen(BOOTDEV_PROP_NAME) + 1 +
				(int)strlen(bdev);

	(void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME);
	(void) strcpy(pio->oprom_array + (int)strlen(BOOTDEV_PROP_NAME) + 1,
					bdev);

	if (ioctl(fd, OPROMSETOPT, pio) < 0) {
		perror(MSGSTR(6008, "openprom setopt ioctl"));
		return (errno);
	}

	/* read back the value that was set */

	pio->oprom_size = MAXVALSIZE;
	(void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME);

	if (ioctl(fd, OPROMGETOPT, pio) < 0) {
		perror(MSGSTR(6009, "openprom getopt ioctl"));
		return (errno);
	}

	if (strcmp(bdev, pio->oprom_array)) {

		/* could not  set the new device name, set the old one back */

		perror(MSGSTR(6010,
			"Could not set boot-device, reverting to old value"));
		pio->oprom_size = (int)strlen(BOOTDEV_PROP_NAME) + 1 +
			(int)strlen(save_bootdev);

		(void) strcpy(pio->oprom_array, BOOTDEV_PROP_NAME);
			(void) strcpy(pio->oprom_array +
				(int)strlen(BOOTDEV_PROP_NAME) + 1,
				save_bootdev);

		if (ioctl(fd, OPROMSETOPT, pio) < 0) {
			perror(MSGSTR(6011, "openprom setopt ioctl"));
			return (errno);
		}

	}

	(void) close(fd);

	return (0);
}
Exemple #8
0
/*
 * generic fcode load file routine.  given a file descriptor to a fcode file
 * this routine will issue the FCIO_DOWNLOAD_FCODE ioctl to the given
 * device.  Any ioctl errors will be returned in fcio_errno
 *
 * Arguments:
 *	fcode_fd    file descriptor to a fcode file
 *	device	    path to the device we will be downloading the fcode onto
 *	fcio_errno  pointer to an int that will be used to return any errors
 *			back to the caller
 * Retrurn Values:
 *	0	    successful download
 *	>0	    otherwise
 */
static int
fcode_load_file(int fcode_fd, char *device, int *fcio_errno)
{

	fcio_t		fcio;
	static int	dev_fd, fcode_size;
	uchar_t		*bin;
	struct stat	stat;

	if (device == NULL || fcio_errno == NULL) {
		return (FCODE_LOAD_FAILURE);
	}

	*fcio_errno = 0;
	if (lseek(fcode_fd, 0, SEEK_SET) == -1) {
		perror(MSGSTR(21022, "seek"));
		return (FCODE_LOAD_FAILURE);
	}

	if (fstat(fcode_fd, &stat) == -1) {
		perror(MSGSTR(21023, "fstat"));
		return (FCODE_LOAD_FAILURE);
	}

	fcode_size = stat.st_size;

	if ((bin = (uchar_t *)malloc(fcode_size)) == NULL) {
		(void) fprintf(stderr,
		    MSGSTR(21013, "Error: Memory allocation failed\n"));
		return (FCODE_LOAD_FAILURE);
	}

	if (read(fcode_fd, bin, fcode_size)
	    != fcode_size) {
		perror(MSGSTR(21001, "read"));
		free(bin);
		return (FCODE_LOAD_FAILURE);
	}

	if ((dev_fd = open(device, O_RDWR|O_EXCL)) < 0) {
		(void) fprintf(stderr,
		    MSGSTR(21122, "Error: Could not open %s, failed "
			    "with errno %d\n"), device, errno);
		free(bin);
		return (FCODE_LOAD_FAILURE);
	}

	fcio.fcio_cmd = FCIO_DOWNLOAD_FCODE;
	fcio.fcio_xfer = FCIO_XFER_WRITE;
	fcio.fcio_ibuf = (caddr_t)bin;
	fcio.fcio_ilen = fcode_size;

	if (ioctl(dev_fd, FCIO_CMD, &fcio) != 0) {
		(void) close(dev_fd);
		*fcio_errno = fcio.fcio_errno;
		free(bin);
		return (FCODE_IOCTL_FAILURE);
	}

	free(bin);
	(void) close(dev_fd);
	return (FCODE_SUCCESS);
}
Exemple #9
0
/*
 * Issue warning strings and loop for Yes/No user interaction
 *    err# 0 -- we're ok, warn for pending FCode load
 *	   1 -- not in single user mode
 *	   2 -- can't get chip_id
 *	   3 -- card and file do not have same type (2100/2200)
 */
static int
q_warn(int errnum)
{
	char input[1024];
	input[0] = '\0';

	if (errnum == 1) {
		(void) fprintf(stderr, MSGSTR(21025,
		    "\nWarning: System is not in single-user mode.\n"));
		(void) fprintf(stderr, MSGSTR(21026,
	"Loading FCode will reset the adapter and terminate I/O activity\n"));
	} else {
		if (errnum == 2) {
			(void) fprintf(stderr, MSGSTR(21027,
			"  Warning: FCode is missing or existing FCode has"
			" unrecognized version.\n"));
			return (1);
		} else if (errnum == 3) {
			(void) fprintf(stderr, MSGSTR(21028,
			"  Warning: New FCode file version does not match this"
			" board type. Skipping...\n"));
			return (1);
		}
		(void) fprintf(stderr, MSGSTR(21029,
		"\nWARNING!! This program will update the FCode in this"
		" FC100/PCI, ISP2200/PCI, ISP23xx/PCI "
		" and Emulex devices.\n"));
		(void) fprintf(stderr, MSGSTR(21030,
		"This may take a few (5) minutes. Please be patient.\n"));
	}

loop1:
	(void) fprintf(stderr, MSGSTR(21031,
		"Do you wish to continue ? (y/n) "));

	(void) gets(input);

	if ((strcmp(input, MSGSTR(21032, "y")) == 0) ||
			(strcmp(input, MSGSTR(40, "yes")) == 0)) {
		return (0);
	} else if ((strcmp(input, MSGSTR(21033, "n")) == 0) ||
			(strcmp(input, MSGSTR(45, "no")) == 0)) {
		(void) fprintf(stderr,
		    MSGSTR(21034, "Not Downloading FCode\n"));
		return (1);
	} else {
		(void) fprintf(stderr, MSGSTR(21035, "Invalid input\n"));
		goto loop1;
	}
}
Exemple #10
0
/*
 * Load FCode to card.
 *    uses ioctl: IFPIO_FCODE_DOWNLOAD
 */
static int
q_load_file(int fcode_fd, char *device)
{
	static int	dev_fd, fcode_size;
	struct stat	stat;
	ifp_download_t	*download_p = NULL;
	fcio_t		fcio;
	uint16_t	file_id = 0;
	uchar_t		*bin;

	if (lseek(fcode_fd, 0, SEEK_SET) == -1) {
		perror(MSGSTR(21022, "seek"));
		(void) close(fcode_fd);
		return (1);
	}
	if (fstat(fcode_fd, &stat) == -1) {
		perror(MSGSTR(21023, "fstat"));
		(void) close(fcode_fd);
		return (1);
	}

	fcode_size = stat.st_size;

	if (strstr(device, fc_trans)) {
		if ((download_p = (ifp_download_t *)malloc(
			sizeof (ifp_download_t) + fcode_size)) == NULL) {
			(void) fprintf(stderr,
			    MSGSTR(21013, "Error: Memory allocation failed\n"));
			(void) close(fcode_fd);
			return (1);
		}
	} else {
		if ((bin = (uchar_t *)malloc(fcode_size)) == NULL) {
			(void) fprintf(stderr,
			    MSGSTR(21013, "Error: Memory allocation failed\n"));
			(void) close(fcode_fd);
			return (1);
		}
	}

	if (strstr(device, fc_trans)) {
		if (read(fcode_fd, download_p->dl_fcode, fcode_size)
		    != fcode_size) {
			perror(MSGSTR(21001, "read"));
			free(download_p);
			(void) close(fcode_fd);
			return (1);
		}
	} else {
		if (read(fcode_fd, bin, fcode_size)
		    != fcode_size) {
			perror(MSGSTR(21001, "read"));
			free(bin);
			(void) close(fcode_fd);
			return (1);
		}
	}


	if ((dev_fd = open(device, O_RDWR|O_EXCL)) < 0) {
		(void) fprintf(stderr,
		    MSGSTR(21000, "Error: Could not open %s\n"), device);
		free(download_p);
		return (1);
	}
	if (strstr(device, fc_trans)) {
		download_p->dl_fcode_len = fcode_size;
		file_id = download_p->dl_fcode[0x42] & 0xff;
		file_id |= (download_p->dl_fcode[0x43] << 8) & 0xff00;
		download_p->dl_chip_id = file_id;
		if (ioctl(dev_fd, IFPIO_FCODE_DOWNLOAD, download_p) < 0) {
			(void) fprintf(stderr, MSGSTR(21024,
		    "Error: Driver interface IFPIO_FCODE_DOWNLOAD failed\n"));
			free(download_p);
			(void) close(dev_fd);
			return (1);
		}
		free(download_p);
	} else if (strstr(device, fp_trans)) {
		fcio.fcio_cmd = FCIO_DOWNLOAD_FCODE;
		/* Information read operation */
		fcio.fcio_xfer = FCIO_XFER_WRITE;
		fcio.fcio_ibuf = (caddr_t)bin;
		fcio.fcio_ilen = fcode_size;

		if (ioctl(dev_fd, FCIO_CMD, &fcio) != 0) {
			(void) fprintf(stderr, MSGSTR(21036,
		    "Error: Driver interface FCIO_DOWNLOAD_FCODE failed\n"));
			free(download_p);
			(void) close(dev_fd);
			return (1);
		}
		free(bin);
	}
	(void) close(dev_fd);
	return (0);
}
Exemple #11
0
/*
 * Get the boot device.	 Cannot load FCode to current boot device.
 * Boot devices under volume management will prompt a warning.
 */
static int
q_getbootdev(uchar_t *bootpath)
{
	struct mnttab mp;
	struct mnttab mpref;
	FILE *fp = NULL;
	static char buf[BUFSIZ];
	char *p = NULL, *p1 = NULL;  /* p = full device, p1 = chunk to rm */
	char *slot = ":devctl";
	char *root = "/";

	if ((fp = fopen(MNTTAB, "r")) == NULL) {
		(void) fprintf(stderr,
		    MSGSTR(21000, "Error: Could not open %s\n"), MNTTAB);
		return (1);
	}

	mntnull(&mpref);
	mpref.mnt_mountp = (char *)root;

	if (getmntany(fp, &mp, &mpref) != 0 ||
	    mpref.mnt_mountp == NULL) {
		(void) fprintf(stderr, MSGSTR(21019,
		    "Error: Cannot get boot device, check %s.\n"), MNTTAB);
		(void) fclose(fp);
		return (1);
	}
	(void) fclose(fp);

	/*
	 * If we can't get a link, we may be dealing with a volume mgr
	 * so give a warning.  If a colon is present, we likely have a
	 * non-local disk or cd-rom, so no warning is necessary.
	 * e.g. /devices/pci@1f,4000/scsi@3/sd@6,0:b (cdrom, no link) or
	 *	storage-e4:/blah/blah remote boot server
	 */
	if (readlink(mp.mnt_special, buf, BUFSIZ) < 0) {
		if (strstr(mp.mnt_special, ":") == NULL) {
			(void) fprintf(stderr, MSGSTR(21020,
	"\nWarning: Cannot read boot device link, check %s.\n"), MNTTAB);
			(void) fprintf(stderr, MSGSTR(21021,
	"Do not upgrade FCode on adapters controlling the boot device.\n"));
		}
		return (1);
	}
	/*
	 * Copy boot device path to bootpath.  First remove leading
	 * path junk (../../..) then if it's an ifp device, chop off
	 * the disk and add the devctl to the end of the path.
	 */
	if (p = strstr(buf, "/devices")) {
		if (strstr(buf, fc_trans) != NULL) {
			p1 = strrchr(p, '/');
			*p1 = '\0';
		}
	}
	(void) strcpy((char *)bootpath, (char *)p);
	if (p1) {
		(void) strcat((char *)bootpath, slot);
	}
	return (0);
}
Exemple #12
0
/*
 * Build a list of all the devctl entries for all the 2100/2200 based adapters
 */
static int
q_getdevctlpath(char *devpath, int *devcnt)
{
	struct stat	statbuf;
	struct dirent	*dirp = NULL;
	DIR		*dp = NULL;
	char		*ptr = NULL;
	int		err = 0;
	int		testopen;

	if (lstat(devpath, &statbuf) < 0) {
		(void) fprintf(stderr,
		    MSGSTR(21016, "Error: %s lstat() error\n"), devpath);
		return (1);
	}

	if ((strstr(devpath, fc_trans) ||
	    (strstr(devpath, fp_trans_id) && strstr(devpath, fp_trans))) &&
	    strstr(devpath, "devctl")) {
		/* Verify the path is valid */
		if ((testopen = open(devpath, O_RDONLY)) >= 0) {
			(void) close(testopen);
			(void) strcpy(pcibus_list[*devcnt], devpath);
			*devcnt += 1;
			return (0);
		}
	}

	if (S_ISDIR(statbuf.st_mode) == 0) {
		/*
		 * not a directory so
		 * we don't care about it - return
		 */
		return (0);
	}

	/*
	 * It's a directory. Call ourself to
	 * traverse the path(s)
	 */
	ptr = devpath + strlen(devpath);
	*ptr++ = '/';
	*ptr = 0;

	/* Forget the /devices/pseudo/ directory */
	if (strcmp(devpath, "/devices/pseudo/") == 0) {
		return (0);
	}

	if ((dp = opendir(devpath)) == NULL) {
		(void) fprintf(stderr,
		    MSGSTR(21017, "Error: %s Can't read directory\n"), devpath);
		return (1);
	}

	while ((dirp = readdir(dp)) != NULL) {

		if (strcmp(dirp->d_name, ".") == 0 ||
		    strcmp(dirp->d_name, "..") == 0) {
			continue;
		}
		(void) strcpy(ptr, dirp->d_name); /* append name */
		err = q_getdevctlpath(devpath, devcnt);
	}

	if (closedir(dp) < 0) {
		(void) fprintf(stderr,
		MSGSTR(21018, "Error: Can't close directory %s\n"), devpath);
		return (1);
	}
	return (err);
}
Exemple #13
0
/* main functions. */
int
main(int argc, char **argv)
{
register int 	c;
/* getopt varbs */
extern char *optarg;
char		*optstring = NULL;
int		path_index, err = 0;
int		cmd = 0;		/* Cmd verb from cmd line */
int		exit_code = 0;		/* exit code for program */
int		temp_fd;		/* For -f option */
char		*file_name = NULL;
int		option_t_input;
char		*path_phys = NULL;
int		USE_FCHBA = 0;

	whoami = argv[0];


	/*
	 * Enable locale announcement
	 */
	i18n_catopen();

	while ((c = getopt(argc, argv, "ve"))
	    != EOF) {
	    switch (c) {
		case 'v':
		    Options |= PVERBOSE;
		    break;
		case 'e':
		    Options |= EXPERT;
		    break;
		default:
		    /* Note: getopt prints an error if invalid option */
		    USEAGE()
		    exit(-1);
	    } /* End of switch(c) */
	}
	setbuf(stdout, NULL);	/* set stdout unbuffered. */

	/*
	 * Build any i18n global variables
	 */
	dtype[0] = MSGSTR(2192, "Disk device");
	dtype[1] = MSGSTR(2193, "Tape device");
	dtype[2] = MSGSTR(2194, "Printer device");
	dtype[3] = MSGSTR(2195, "Processor device");
	dtype[4] = MSGSTR(2196, "WORM device");
	dtype[5] = MSGSTR(2197, "CD-ROM device");
	dtype[6] = MSGSTR(2198, "Scanner device");
	dtype[7] = MSGSTR(2199, "Optical memory device");
	dtype[8] = MSGSTR(2200, "Medium changer device");
	dtype[9] = MSGSTR(2201, "Communications device");
	dtype[10] = MSGSTR(107, "Graphic arts device");
	dtype[11] = MSGSTR(107, "Graphic arts device");
	dtype[12] = MSGSTR(2202, "Array controller device");
	dtype[13] = MSGSTR(2203, "SES device");
	dtype[14] = MSGSTR(71, "Reserved");
	dtype[15] = MSGSTR(71, "Reserved");



	/*
	 * Get subcommand.
	 */
	if ((getaction(argv[optind], Keywords, &cmd)) == EOK) {
		optind++;
		if ((cmd != PROBE) && (cmd != FCAL_UPDATE) &&
		(cmd != QLGC_UPDATE) && (cmd != FCODE_UPDATE) &&
		(cmd != INSERT_DEVICE) && (cmd != SYSDUMP) && (cmd != AU) &&
		(cmd != PORT) && (cmd != CREATE_FAB) && (optind >= argc)) {
			(void) fprintf(stderr,
			MSGSTR(2204,
			"Error: enclosure or pathname not specified.\n"));
			USEAGE();
			exit(-1);
		}
	} else {
		(void) fprintf(stderr,
		MSGSTR(2205, "%s: subcommand not specified.\n"),
		whoami);
		USEAGE();
		exit(-1);
	}

	/* Extract & Save subcommand options */
	if ((cmd == ENABLE) || (cmd == BYPASS)) {
		optstring = "Ffrab";
	} else if (cmd == FCODE_UPDATE) {
		optstring = "pd:";
	} else if (cmd == REMOVE_DEVICE) {
		optstring = "F";
	} else if (cmd == CREATE_FAB) {
		optstring = "f:";
	} else {
		optstring = "Fryszabepcdlvt:f:w:";
	}
	while ((c = getopt(argc, argv, optstring)) != EOF) {
	    switch (c) {
		case 'a':
			Options |= OPTION_A;
			break;
	    case 'b':
			Options |= OPTION_B;
			break;
		case 'c':
			Options |= OPTION_C;
			break;
		case 'd':
			Options |= OPTION_D;
			if (cmd == FCODE_UPDATE) {
			    file_name = optarg;
			}
			break;
		case 'e':
			Options |= OPTION_E;
			break;
		case 'f':
			Options |= OPTION_F;
			if (!((cmd == ENABLE) || (cmd == BYPASS))) {
				file_name = optarg;
			}
			break;
		case 'F':
			Options |= OPTION_CAPF;
			break;
		case 'l':
		    Options |= OPTION_L;
		    break;
		case 'p':
		    Options |= OPTION_P;
		    break;
		case 'r':
		    Options |= OPTION_R;
		    break;
		case 's':
		    Options |= SAVE;
		    break;
		case 't':
		    Options |= OPTION_T;
		    option_t_input = atoi(optarg);
		    break;
		case 'v':
		    Options |= OPTION_V;
		    break;
		case 'z':
		    Options |= OPTION_Z;
		    break;
		case 'y':
		    Options |= OPTION_Y;
		    break;
		default:
		    /* Note: getopt prints an error if invalid option */
		    USEAGE()
		    exit(-1);
	    } /* End of switch(c) */
	}
	if ((cmd != PROBE) && (cmd != FCAL_UPDATE) &&
	    (cmd != QLGC_UPDATE) && (cmd != FCODE_UPDATE) &&
	    (cmd != INSERT_DEVICE) && (cmd != SYSDUMP) &&
	    (cmd != AU) && (cmd != PORT) &&
	    (cmd != CREATE_FAB) && (optind >= argc)) {
	    (void) fprintf(stderr,
		MSGSTR(2206,
		"Error: enclosure or pathname not specified.\n"));
	    USEAGE();
	    exit(-1);
	}
	path_index = optind;

	/*
	 * Check if the file supplied with the -f option is valid
	 * Some sub commands (bypass for example) use the -f option
	 * for other reasons. In such cases, "file_name" should be
	 * NULL.
	 */
	if ((file_name != NULL) && (Options & OPTION_F)) {
		if ((temp_fd = open(file_name, O_RDONLY)) == -1) {
			perror(file_name);
			exit(-1);
		} else {
			close(temp_fd);
		}
	}

	/* Determine which mode to operate in (FC-HBA or original) */
	USE_FCHBA = use_fchba();

	switch (cmd)	{
	    case	DISPLAY:
		if (Options &
		    ~(PVERBOSE | OPTION_A | OPTION_Z | OPTION_R |
		    OPTION_P | OPTION_V | OPTION_L | OPTION_E | OPTION_T)) {
		    USEAGE();
		    exit(-1);
		}
		/* Display object(s) */
		if (USE_FCHBA) {
		    exit_code = fchba_display_config(&argv[path_index],
			    option_t_input, argc - path_index);
		} else {
		    exit_code = adm_display_config(&argv[path_index]);
		}
		break;

	    case	DOWNLOAD:
		    if (Options &
			~(PVERBOSE | OPTION_F | SAVE)) {
			USEAGE();
			exit(-1);
		    }
		    adm_download(&argv[path_index], file_name);
		    break;

	    case	ENCLOSURE_NAMES:
		    if (Options & ~PVERBOSE) {
			USEAGE();
			exit(-1);
		    }
		    up_encl_name(&argv[path_index], argc);
		    break;

	    case	FAILOVER:
		    if (Options & ~PVERBOSE) {
			USEAGE();
			exit(-1);
		    }
		    adm_failover(&argv[path_index]);
		    break;

	    case	INQUIRY:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		if (USE_FCHBA) {
		    exit_code = fchba_inquiry(&argv[path_index]);
		} else {
		    exit_code = adm_inquiry(&argv[path_index]);
		}
		break;

	    case	PROBE:
		if (Options & ~(PVERBOSE | OPTION_P)) {
			USEAGE();
			exit(-1);
		}
		/*
		 * A special check just in case someone entered
		 * any characters after the -p or the probe.
		 *
		 * (I know, a nit.)
		 */
		if (((Options & PVERBOSE) && (Options & OPTION_P) &&
			(argc != 4)) ||
			(!(Options & PVERBOSE) && (Options & OPTION_P) &&
			(argc != 3)) ||
			((Options & PVERBOSE) && (!(Options & OPTION_P)) &&
			(argc != 3)) ||
			(!(Options & PVERBOSE) && (!(Options & OPTION_P)) &&
			(argc != 2))) {
			(void) fprintf(stderr,
			MSGSTR(114, "Error: Incorrect number of arguments.\n"));
			(void) fprintf(stderr,  MSGSTR(2208,
			"Usage: %s [-v] subcommand [option]\n"), whoami);
			exit(-1);
		}
		if (USE_FCHBA) {
		    exit_code = fchba_non_encl_probe();
		} else {
		    pho_probe();
		    non_encl_probe();
		}
		break;

	    case	FCODE_UPDATE:	/* Update Fcode in all cards */
			if ((Options & ~(PVERBOSE)) &
			    ~(OPTION_P | OPTION_D) || argv[path_index]) {
				USEAGE();
				exit(-1);
			}
			if (!((Options & (OPTION_P | OPTION_D)) &&
			    !((Options & OPTION_P) && (Options & OPTION_D)))) {
				USEAGE();
				exit(-1);
			}
			if (adm_fcode(Options & PVERBOSE, file_name) != 0) {
				exit(-1);
			}
			break;

	    case	QLGC_UPDATE:	/* Update Fcode in PCI HBA card(s) */
			if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
			    argv[path_index]) {
				USEAGE();
				exit(-1);
			}
			if (q_qlgc_update(Options & PVERBOSE, file_name) != 0) {
				exit(-1);
			}
			break;

	    case	FCAL_UPDATE:	/* Update Fcode in Sbus soc+ card */
			if ((Options & ~(PVERBOSE)) & ~(OPTION_F) ||
			    argv[path_index]) {
				USEAGE();
				exit(-1);
			}
			exit_code = fcal_update(Options & PVERBOSE, file_name);
			break;

	    case	SET_BOOT_DEV:   /* Set boot-device variable in nvram */
			exit_code = setboot(Options & OPTION_Y,
				Options & PVERBOSE, argv[path_index]);
		break;

	    case	LED:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		adm_led(&argv[path_index], L_LED_STATUS);
		break;
	    case	LED_ON:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		adm_led(&argv[path_index], L_LED_ON);
		break;
	    case	LED_OFF:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		adm_led(&argv[path_index], L_LED_OFF);
		break;
	    case	LED_BLINK:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		adm_led(&argv[path_index], L_LED_RQST_IDENTIFY);
		break;
	    case	PASSWORD:
		if (Options & ~(PVERBOSE))  {
			USEAGE();
			exit(-1);
		}
		up_password(&argv[path_index]);
		break;

	    case	RESERVE:

		if (Options & (~PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		VERBPRINT(MSGSTR(2209,
			"  Reserving: \n %s\n"), argv[path_index]);
		if (USE_FCHBA) {
		    struct stat sbuf;
		    /* Just stat the argument and make sure it exists */
		    if (stat(argv[path_index], &sbuf) < 0) {
			(void) fprintf(stderr, "%s: ", whoami);
			(void) fprintf(stderr,
				MSGSTR(112, "Error: Invalid pathname (%s)"),
				argv[path_index]);
			(void) fprintf(stderr, "\n");
			exit(-1);
		    }
		    path_phys = argv[path_index];
		    if (err = scsi_reserve(path_phys)) {
			(void) print_errString(err, argv[path_index]);
			exit(-1);
		    }
		} else {
		    exit_code = adm_reserve(argv[path_index]);
		}
		break;

	    case	RELEASE:
		if (Options & (~PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		VERBPRINT(MSGSTR(2210, "  Canceling Reservation for:\n %s\n"),
		    argv[path_index]);
		if (USE_FCHBA) {
		    struct stat sbuf;
		    /* Just stat the argument and make sure it exists */
		    if (stat(argv[path_index], &sbuf) < 0) {
			(void) fprintf(stderr, "%s: ", whoami);
			(void) fprintf(stderr,
				MSGSTR(112, "Error: Invalid pathname (%s)"),
				argv[path_index]);
			(void) fprintf(stderr, "\n");
			exit(-1);
		    }
		    path_phys = argv[path_index];
		    if (err = scsi_release(path_phys)) {
			(void) print_errString(err, argv[path_index]);
			exit(-1);
		    }
		} else {
		    exit_code = adm_release(argv[path_index]);
		}
		break;

	    case	START:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		exit_code = adm_start(&argv[path_index]);
		break;

	    case	STOP:
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		exit_code = adm_stop(&argv[path_index]);
		break;

	    case	POWER_OFF:
		if (Options & ~(PVERBOSE | OPTION_CAPF)) {
			USEAGE();
			exit(-1);
		}
		exit_code = adm_power_off(&argv[path_index], 1);
		break;

	    case	POWER_ON:
		if (Options & (~PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		exit_code = adm_power_off(&argv[path_index], 0);
		break;

	/*
	 * EXPERT commands.
	 */

	    case	FORCELIP:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			E_USEAGE();
			exit(-1);
		}
		exit_code = adm_forcelip(&argv[path_index]);
		break;

	    case	BYPASS:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT |
			OPTION_CAPF | OPTION_A | OPTION_B | OPTION_F |
			OPTION_R)) || !(Options & (OPTION_A | OPTION_B)) ||
			((Options & OPTION_A) && (Options & OPTION_B))) {
			E_USEAGE();
			exit(-1);
		}
		adm_bypass_enable(&argv[path_index], 1);
		break;

	    case	ENABLE:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT |
			OPTION_CAPF | OPTION_A | OPTION_B | OPTION_F |
			OPTION_R)) || !(Options & (OPTION_A | OPTION_B)) ||
			((Options & OPTION_A) && (Options & OPTION_B))) {
			E_USEAGE();
			exit(-1);
		}
		adm_bypass_enable(&argv[path_index], 0);
		break;
	    case	LUX_P_OFFLINE:	/* Offline a port */
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			E_USEAGE();
			exit(-1);
		}
		exit_code = adm_port_offline_online(&argv[path_index],
		    LUX_P_OFFLINE);
		break;

	    case	LUX_P_ONLINE:	/* Online a port */
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			E_USEAGE();
			exit(-1);
		}
		exit_code = adm_port_offline_online(&argv[path_index],
		    LUX_P_ONLINE);
		break;

	    case	RDLS:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			E_USEAGE();
			exit(-1);
		}
		if (USE_FCHBA) {
		    exit_code = fchba_display_link_status(&argv[path_index]);
		} else {
		    display_link_status(&argv[path_index]);
		}
		break;

	    case	CREATE_FAB:
		if (!(Options & (EXPERT | OPTION_F)) ||
			(Options & ~(PVERBOSE | EXPERT | OPTION_F))) {
			E_USEAGE();
			exit(-1);
		}
		if (read_repos_file(file_name) != 0) {
			exit(-1);
		}
		break;

	/*
	 * Undocumented commands.
	 */

	    case	CHECK_FILE:	/* Undocumented Cmd */
		if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		exit_code = adm_check_file(&argv[path_index],
		    (Options & PVERBOSE));
		break;

	    case	DUMP:		/* Undocumented Cmd */
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		dump(&argv[path_index]);
		break;

	    case	DUMP_MAP:	/* Undocumented Cmd */
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		if (USE_FCHBA) {
		    exit_code = fchba_dump_map(&argv[path_index]);
		} else {
		    dump_map(&argv[path_index]);
		}
		break;

	    case	SYSDUMP:
			if (Options & ~(PVERBOSE)) {
			USEAGE();
			exit(-1);
		}
		if (err = sysdump(Options & PVERBOSE)) {
		    (void) print_errString(err, NULL);
		    exit(-1);
		}
		break;

	    case	PORT: /* Undocumented command */
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		if (USE_FCHBA) {
		    exit_code = fchba_display_port(Options & PVERBOSE);
		} else {
		    exit_code = adm_display_port(Options & PVERBOSE);
		}
		break;

	    case	EXT_LOOPBACK:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		if (adm_port_loopback(argv[path_index], EXT_LOOPBACK) < 0) {
			exit(-1);
		}
		break;

	    case	INT_LOOPBACK:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		if (adm_port_loopback(argv[path_index], INT_LOOPBACK) < 0) {
			exit(-1);
		}
		break;

	    case	NO_LOOPBACK:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			USEAGE();
			exit(-1);
		}
		if (adm_port_loopback(argv[path_index], NO_LOOPBACK) < 0) {
			exit(-1);
		}
		break;

	    case	VERSION:
		break;


	    case	INSERT_DEVICE:
			if (argv[path_index] == NULL) {
				if ((err = h_insertSena_fcdev()) != 0) {
					(void) print_errString(err, NULL);
					exit(-1);
				}
			} else if ((err = hotplug(INSERT_DEVICE,
					&argv[path_index],
					Options & PVERBOSE,
					Options & OPTION_CAPF)) != 0) {
				(void) print_errString(err, argv[path_index]);
				exit(-1);
			}
			break;
	    case	REMOVE_DEVICE:
			if (err = hotplug(REMOVE_DEVICE, &argv[path_index],
			    Options & PVERBOSE, Options & OPTION_CAPF)) {
			    (void) print_errString(err, argv[path_index]);
			    exit(-1);
			}
			break;

	/* for hotplug device operations */
	    case	DEV_ONLINE:
	    case	DEV_OFFLINE:
	    case	DEV_GETSTATE:
	    case	DEV_RESET:
	    case	BUS_QUIESCE:
	    case	BUS_UNQUIESCE:
	    case	BUS_GETSTATE:
	    case	BUS_RESET:
	    case	BUS_RESETALL:
		if (!(Options & EXPERT) || (Options & ~(PVERBOSE | EXPERT))) {
			E_USEAGE();
			exit(-1);
		}
		if (USE_FCHBA) {
		    if (fchba_hotplug_e(cmd, &argv[path_index],
			    Options & PVERBOSE, Options & OPTION_CAPF) != 0) {
			exit(-1);
		    }
		} else {
		    if (hotplug_e(cmd, &argv[path_index],
			    Options & PVERBOSE, Options & OPTION_CAPF) != 0) {
			exit(-1);
		    }
		}
		break;

	    default:
		(void) fprintf(stderr,
		    MSGSTR(2213, "%s: subcommand decode failed.\n"),
		    whoami);
		USEAGE();
		exit(-1);
	}
	return (exit_code);
}
Exemple #14
0
/*
 * Searches for and updates the cards.	This is the "main" function
 * and will give the output to the user by calling the subfunctions.
 * args: FCode file; if NULL only the current FCode version is printed
 */
int
q_qlgc_update(unsigned int verbose, char *file)
/*ARGSUSED*/
{
	int fd, fcode_fd = -1, errnum = 0, devcnt = 0, retval = 0, isSbus = 0;
	int sbus_off;
	uint_t i, fflag = 0;
	uint16_t chip_id = 0, file_id = 0;
	uchar_t fcode_buf[FCODE_HDR];
	static uchar_t	bootpath[PATH_MAX];
	static uchar_t	version[MAXNAMELEN], version_file[MAXNAMELEN];
	char devpath[PATH_MAX], tmppath[PATH_MAX];
	void	(*sigint)(); /* to store default SIGTERM setting */
	static struct	utmpx *utmpp = NULL; /* pointer for getutxent() */
	char *ptr1, *ptr2;
	char phys_path[PATH_MAX];
	/*
	 * The variables port1 and port2 are used to store the bus id
	 * e.g. the bus id for this path:
	 * /devices/sbus@12,0/SUNW,qlc@2,30000/fp@0,0:devctl
	 * is "sbus@12". They are initialized to a random value and are
	 * set such that they are not equal initially.
	 */
	static char port1[MAXNAMELEN] = {NULL};
	static char port2[MAXNAMELEN] = {NULL};

	if (file) {
		fflag++;

		/* check for a valid file */
		if ((fcode_fd = open(file, O_RDONLY)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(21000, "Error: Could not open %s\n"), file);
			return (1);
		}
		if (read(fcode_fd, fcode_buf, FCODE_HDR) != FCODE_HDR) {
			perror(MSGSTR(21001, "read"));
			(void) close(fcode_fd);
			return (1);
		}

		/*
		 * Check if it's SBUS FCode by calling q_findSbusfile
		 * if it is then isSbus will be 1, if not it will be 0
		 * in case of an error, it will be -1
		 */
		isSbus = q_findSbusfile(fcode_fd, &sbus_off);
		if (isSbus == -1) {
			(void) close(fcode_fd);
			return (1);
		}

		/*
		 * FCode header check - make sure it's PCI FCode
		 * Structure of FCode header (byte# refers to byte numbering
		 * in FCode spec, not the byte# of our fcode_buf buffer):
		 * header	byte 00	   0x55	 prom signature byte one
		 *		byte 01	   0xaa	 prom signature byte two
		 * data		byte 00-03 P C I R
		 * OR
		 * header	byte 32	   0x55
		 *		byte 33	   0xaa
		 * data		byte 60-63 P C I R
		 * The second format with an offset of 32 is used for ifp prom
		 */
		if (!(((fcode_buf[0x00] == 0x55) &&
		    (fcode_buf[0x01] == 0xaa) &&
		    (fcode_buf[0x1c] == 'P') &&
		    (fcode_buf[0x1d] == 'C') &&
		    (fcode_buf[0x1e] == 'I') &&
		    (fcode_buf[0x1f] == 'R')) ||

		    ((fcode_buf[0x20] == 0x55) &&
		    (fcode_buf[0x21] == 0xaa) &&
		    (fcode_buf[0x3c] == 'P') &&
		    (fcode_buf[0x3d] == 'C') &&
		    (fcode_buf[0x3e] == 'I') &&
		    (fcode_buf[0x3f] == 'R')) ||

		    (isSbus))) {
			(void) fprintf(stderr, MSGSTR(21002,
			    "Error: %s is not a valid FC100/P, "
			    "ISP2200, ISP23xx FCode file.\n"),
			    file);
			(void) close(fcode_fd);
			return (1);
		}

		/* check for single user mode */
		while ((utmpp = getutxent()) != NULL) {
			if (strstr(utmpp->ut_line, "run-level") &&
			    (strcmp(utmpp->ut_line, "run-level S") &&
				strcmp(utmpp->ut_line, "run-level 1"))) {
				if (q_warn(1)) {
					(void) endutxent();
					(void) close(fcode_fd);
					return (1);
				}
				break;
			}
		}
		(void) endutxent();

		/* get bootpath */
		if (!q_getbootdev((uchar_t *)&bootpath[0]) &&
		    getenv("_LUX_D_DEBUG") != NULL) {
			(void) fprintf(stdout, "  Bootpath: %s\n", bootpath);
		}
	}
	/*
	 * Get count of, and names of PCI slots with ifp device control
	 * (devctl) nodes.  Search /devices.
	 */
	(void) strcpy(devpath, "/devices");
	if (q_getdevctlpath(devpath, (int *)&devcnt) == 0) {
		(void) fprintf(stdout, MSGSTR(21003,
		"\n  Found Path to %d FC100/P, ISP2200, ISP23xx Devices\n"),
			devcnt);
	} else {
		(void) fprintf(stderr, MSGSTR(21004,
		"Error: Could not get /devices path to FC100/P,"
		"ISP2200, ISP23xx Cards.\n"));
		retval++;
	}

	for (i = 0; i < devcnt; i++) {

		(void) strncpy((char *)phys_path, &pcibus_list[i][0],
				strlen(&pcibus_list[i][0]));
		if (fflag && (strstr((char *)bootpath,
		    strtok((char *)phys_path, ":")) != NULL)) {
			(void) fprintf(stderr,
			    MSGSTR(21005, "Ignoring %s (bootpath)\n"),
			    &pcibus_list[i][0]);
			continue;
		}

		(void) fprintf(stdout,
		MSGSTR(21006, "\n  Opening Device: %s\n"), &pcibus_list[i][0]);
		/* Check if the device is valid */
		if ((fd = open(&pcibus_list[i][0], O_RDWR)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(21000, "Error: Could not open %s\n"),
			    &pcibus_list[i][0]);
			retval++;
			continue;
		}
		(void) close(fd);
		/*
		 * Check FCode version present on the adapter (at last boot)
		 */
		if (q_findversion(verbose, i, (uchar_t *)&version[0],
		    &chip_id) == 0) {
			if (strlen((char *)version) == 0) {
				(void) fprintf(stdout, MSGSTR(21007,
	"  Detected FCode Version:\tNo version available for this FCode\n"));
			} else {
			(void) fprintf(stdout, MSGSTR(21008,
			    "  Detected FCode Version:\t%s\n"), version);
			}
		} else {
			chip_id = 0x0;
		}

		if (fflag) {
			/*
			 * For ISP2200, Sbus HBA, do just 1 download
			 * for both the ports (dual port HBA)
			 * Here it is assumed that readdir() always
			 * returns the paths in pcibus_list[] in the
			 * sorted order.
			 */
			(void) strcpy(tmppath, pcibus_list[i]);
			if (ptr1 = strstr(tmppath, IVORY_BUS)) {
				if (ptr2 = strstr(ptr1, IVORY_DRVR)) {
					ptr2 = strchr(ptr2, ',');
					if (ptr2 = strchr(++ptr2, ',')) {
						*ptr2 = '\0';
					}
				}
				(void) strcpy(port2, ptr1);
				if (strcmp(port1, port2) == 0) {
				    (void) fprintf(stdout, MSGSTR(21037,
				    "/n New FCode has already been downloaded "
				    "to this ISP2200 SBus HBA Card.\n"
				    "It is sufficient to download to one "
				    "port of the ISP2200 SBus HBA Card. "
				    "Moving on...\n"));
					continue;
				}
			}
			/*
			 * Check version of the supplied FCode file (once)
			 */
			if ((file_id != 0 && version_file != NULL) ||
			    (q_findfileversion((char *)
			    &fcode_buf[0], (uchar_t *)&version_file[0],
			    &file_id, isSbus, &sbus_off) == 0)) {
				(void) fprintf(stdout, MSGSTR(21009,
				    "  New FCode Version:\t\t%s\n"),
				    version_file);
			} else {
				(void) close(fcode_fd);
				return (1);
			}

			/*
			 * Load the New FCode
			 * Give warning if file doesn't appear to be correct
			 *
			 */
			if (chip_id == 0) {
				errnum = 2; /* can't get chip_id */
				retval++;
			} else if (chip_id - file_id != 0) {
				errnum = 3; /* file/card mismatch */
				retval++;
			} else {
				errnum = 0; /* everything is ok */
			}

			if (!q_warn(errnum)) {
				/* Disable user-interrupt Control-C */
				sigint =
				    (void (*)(int)) signal(SIGINT, SIG_IGN);

				/* Load FCode */
				(void) fprintf(stdout, MSGSTR(21010,
				    "  Loading FCode: %s\n"), file);

				if (q_load_file(fcode_fd,
				    &pcibus_list[i][0]) == 0) {
					(void) fprintf(stdout, MSGSTR(21011,
					"  Successful FCode download: %s\n"),
					    &pcibus_list[i][0]);
					(void) strcpy(port1, port2);
				} else {
					(void) fprintf(stderr, MSGSTR(21012,
					"Error: FCode download failed: %s\n"),
							&pcibus_list[i][0]);
					retval++;
				}
				/* Restore SIGINT (user interrupt) setting */
				(void) signal(SIGINT, sigint);
			}
		}
	}
	(void) fprintf(stdout, "  ");
	(void) fprintf(stdout, MSGSTR(125, "Complete\n"));
	if (fcode_fd != -1)
		(void) close(fcode_fd);
	return (retval);
}
Exemple #15
0
/*
 * Retrieves information from the Emulex fcode
 *
 * Given a pattern, this routine will look for this pattern in the fcode
 * file and if found will return the pattern value
 *
 * possible patterns are manufacturer and fcode-version
 */
int
emulex_fcode_reader(int fcode_fd, char *pattern, char *pattern_value,
    uint32_t pattern_value_size) {
	int32_t i = 0;
	uint32_t n = 0;
	uint32_t b = 0;
	char byte1;
	char byte2;
	char byte3;
	char byte4;
	char buffer1[EMULEX_READ_BUFFER_SIZE];
	char buffer2[EMULEX_READ_BUFFER_SIZE];
	uint32_t plen, image_size;
	struct stat	stat;
	uchar_t		*image;

	/* Check the arguments */
	if (!fcode_fd || !pattern_value || pattern_value_size < 8) {
		return (1);
	}

	if (fstat(fcode_fd, &stat) == -1) {
		perror(MSGSTR(21023, "fstat"));
		return (1);
	}
	image_size = stat.st_size;
	if (image_size < 2) {
		return (1);
	}
	if ((image = (uchar_t *)calloc(image_size, 1)) == NULL) {
		(void) fprintf(stderr,
		    MSGSTR(21013, "Error: Memory allocation failed\n"));
		return (1);
	}

	/* Read the fcode image file */
	lseek(fcode_fd, 0, SEEK_SET);
	read(fcode_fd, image, image_size);

	/* Initialize */
	bzero(buffer1, sizeof (buffer1));
	bzero(buffer2, sizeof (buffer2));
	/* Default pattern_value string */
	strcpy((char *)pattern_value, "<unknown>");
	plen = strlen(pattern);
	n = 0;
	b = 0;
	i = 0;

	/* Search entire image for pattern string */
	while (i <= (image_size - 2)) {
		/* Read next two bytes */
		byte1 = image[i++];
		byte2 = image[i++];

		/* Check second byte first due to endianness */

		/* Save byte in circular buffer */
		buffer1[b++] = byte2;
		if (b == sizeof (buffer1)) {
			b = 0;
		}

		/* Check byte for pattern match */
		if (pattern[n++] != byte2) {
			/* If no match, then reset pattern */
			n = 0;
		} else {
			/*
			 * If complete pattern has been matched then
			 * exit loop
			 */
			if (n == plen) {
				goto found;
			}
		}


		/* Check first byte second due to endianness */
		/* Save byte in circular buffer */
		buffer1[b++] = byte1;
		if (b == sizeof (buffer1)) {
			b = 0;
		}
		/* Check byte for pattern match */
		if (pattern[n++] != byte1) {
			/* If no match, then reset pattern */
			n = 0;
		} else {
			/*
			 * If complete pattern has been matched
			 * then exit loop
			 */
			if (n == plen) {
				goto found;
			}
		}
	}

	/* Not found.  Try again with different endianess */

	/* Initialize */
	bzero(buffer1, sizeof (buffer1));
	bzero(buffer2, sizeof (buffer2));
	n = 0;
	b = 0;
	i = 0;

	/* Search entire 32bit endian image for pattern string */
	while (i <= (image_size - 4)) {
		/* Read next four bytes */
		byte1 = image[i++];
		byte2 = image[i++];
		byte3 = image[i++];
		byte4 = image[i++];

		/* Save byte in circular buffer */
		buffer1[b++] = byte4;
		if (b == sizeof (buffer1)) {
			b = 0;
		}

		/* Check byte for pattern match */
		if (pattern[n++] != byte4) {
			/* If no match, then reset pattern */
			n = 0;
		} else {
			/*
			 * If complete pattern has been matched then exit loop
			 */
			if (n == plen) {
				goto found;
			}
		}

		/* Save byte in circular buffer */
		buffer1[b++] = byte3;
		if (b == sizeof (buffer1)) {
			b = 0;
		}

		/* Check byte for pattern match */
		if (pattern[n++] != byte3) {
			/* If no match, then reset pattern */
			n = 0;
		} else {
			/*
			 * If complete pattern has been matched then exit loop
			 */
			if (n == plen) {
				goto found;
			}
		}

		/* Save byte in circular buffer */
		buffer1[b++] = byte2;
		if (b == sizeof (buffer1)) {
			b = 0;
		}

		/* Check byte for pattern match */
		if (pattern[n++] != byte2) {
			/* If no match, then reset pattern */
			n = 0;
		} else {
			/*
			 * If complete pattern has been matched then exit loop
			 */
			if (n == plen) {
				goto found;
			}
		}

		/* Save byte in circular buffer */
		buffer1[b++] = byte1;
		if (b == sizeof (buffer1)) {
			b = 0;
		}

		/* Check byte for pattern match */
		if (pattern[n++] != byte1) {
			/* If no match, then reset pattern */
			n = 0;
		} else {
			/*
			 * If complete pattern has been matched then exit loop
			 */
			if (n == plen) {
				goto found;
			}
		}
	}

	free(image);
	return (1);

found:
	free(image);

	/* Align buffer and eliminate non-printable characters */
	for (i = 0; i < (sizeof (buffer1)-plen); i++) {
		byte1 = buffer1[b++];
		if (b == sizeof (buffer1)) {
			b = 0;
		}
		/* Zero any non-printable characters */
		if (byte1 >= 33 && byte1 <= 126) {
			buffer2[i] = byte1;
		} else {
			buffer2[i] = 0;
		}
	}

	/*
	 *  Scan backwards for first non-zero string. This will be the
	 *  version string
	 */
	for (i = sizeof (buffer1)-plen-1; i >= 0; i--) {
		if (buffer2[i] != 0) {
			for (; i >= 0; i--) {
				if (buffer2[i] == 0) {
					i++;
					strncpy((char *)pattern_value,
					    &buffer2[i], pattern_value_size);
					break;
				}
			}
			break;
		}
	}
	return (0);
}
Exemple #16
0
int
emulex_update(char *file)
{

	int		fd, retval = 0;
	int		devcnt = 0;
	uint_t		state = 0, fflag = 0;
	static uchar_t	bootpath[PATH_MAX];
	int		fcode_fd = -1;
	static struct	utmpx *utmpp = NULL;
	di_node_t	root;
	di_node_t	node, sib_node, count_node;
	di_minor_t	minor_node;
	char		phys_path[PATH_MAX], *path;
	int		errnum = 0, fcio_errno = 0;
	static uchar_t	prom_ver_data[MAXNAMELEN];
	static char	ver_file[EMULEX_FCODE_VERSION_LENGTH];
	void		(*sigint)();
	int		prop_entries = -1;
	int		*port_data = NULL;

	if (file) {
		/* set the fcode download flag */
		fflag++;

		/* check for a valid file */
		if ((fcode_fd = open(file, O_RDONLY)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(21118, "Error: Could not open %s, failed "
				    "with errno %d\n"), file, errno);
			return (1);
		}

		/* check for single user mode */
		while ((utmpp = getutxent()) != NULL) {
			if (strstr(utmpp->ut_line, "run-level") &&
				(strcmp(utmpp->ut_line, "run-level S") &&
				strcmp(utmpp->ut_line, "run-level 1"))) {
				if (q_warn(1)) {
					(void) endutxent();
					(void) close(fcode_fd);
					return (1);
				}
				break;
			}
		}
		(void) endutxent();

		/* get bootpath */
		if (!q_getbootdev((uchar_t *)&bootpath[0]) &&
		    getenv("_LUX_D_DEBUG") != NULL) {
			(void) fprintf(stdout, "  Bootpath: %s\n", bootpath);
		}
	}

	/*
	 * Download the Fcode to all the emulex cards found
	 */

	/* Create a snapshot of the kernel device tree */
	if ((root = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
		(void) fprintf(stderr, MSGSTR(21114,
		"Error: Could not get /devices path to "
		"Emulex Devices.\n"));
		retval++;
	}

	/* point to first node which matches emulex driver */
	node = di_drv_first_node("emlxs", root);

	if (node == DI_NODE_NIL) {
		/*
		 * Could not find any emulex cards
		 */
		(void) di_fini(root);
		(void) fprintf(stderr, MSGSTR(21115,
		"\n  Found Path to %d Emulex Devices.\n"), devcnt);
		retval++;
	} else {
		count_node = node;
		while (count_node != DI_NODE_NIL) {
			state = di_state(count_node);
			if ((state & DI_DRIVER_DETACHED)
			    != DI_DRIVER_DETACHED) {
				sib_node = di_child_node(count_node);
				while (sib_node != DI_NODE_NIL) {
					state = di_state(sib_node);
					if ((state & DI_DRIVER_DETACHED) !=
					    DI_DRIVER_DETACHED) {
						/* Found an attached node */
						prop_entries =
						    di_prop_lookup_ints(
						    DDI_DEV_T_ANY, sib_node,
						    "port", &port_data);
						if (prop_entries != -1) {
							devcnt++;
							break;
						}
					}

					sib_node = di_sibling_node(sib_node);
				}
			}
			count_node = di_drv_next_node(count_node);
		}
		(void) fprintf(stdout, MSGSTR(21116,
		"\n  Found Path to %d Emulex Devices.\n"), devcnt);
	}


	/*
	 * Traverse device tree to find all emulex cards
	 */
	while (node != DI_NODE_NIL) {

		state = di_state(node);
		if ((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) {
			node = di_drv_next_node(node);
			continue;
		}

		sib_node = di_child_node(node);
		while (sib_node != DI_NODE_NIL) {
			state = di_state(sib_node);
			if ((state & DI_DRIVER_DETACHED) !=
			    DI_DRIVER_DETACHED) {

				/* Found an attached node */
				prop_entries = di_prop_lookup_ints(
				    DDI_DEV_T_ANY, sib_node,
				    "port", &port_data);
				if (prop_entries != -1) {

					/* Found a node with "port" property */
					minor_node = di_minor_next(sib_node,
					    DI_MINOR_NIL);
					break;
				}
			}
			sib_node = di_sibling_node(sib_node);
		}

		if (sib_node == DI_NODE_NIL) {
			goto try_next;
		}

		path = di_devfs_path(sib_node);
		(void) strcpy(phys_path, "/devices");
		(void) strncat(phys_path, path, strlen(path));
		di_devfs_path_free(path);

		if (fflag && (strstr((char *)bootpath,
		    (char *)phys_path) != NULL)) {
			(void) fprintf(stderr,
			    MSGSTR(21117, "Ignoring %s (bootpath)\n"),
			    phys_path);
			node = di_drv_next_node(node);
			continue;
		}

		if (minor_node) {
			(void) strncat(phys_path, ":", 1);
			(void) strncat(phys_path,
				di_minor_name(minor_node),
				strlen(di_minor_name(minor_node)));
		}

		(void) fprintf(stdout,
				MSGSTR(21107, "\n  Opening Device: %s\n"),
				phys_path);

		/* Check if the device is valid */
		if ((fd = open(phys_path, O_RDWR)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(21121, "Error: Could not open %s, failed "
				    "with errno %d\n"), phys_path, errno);
			retval++;
			node = di_drv_next_node(node);
			continue;
		}

		(void) close(fd);

		/*
		 * Check FCode version present on the adapter
		 * (at last boot)
		 */
		memset(prom_ver_data, 0, sizeof (prom_ver_data));
		if (emulex_fcodeversion(node, (uchar_t *)&prom_ver_data[0])
		    == 0) {
			errnum = 0;
			if (strlen((char *)prom_ver_data) == 0) {
				(void) fprintf(stdout, MSGSTR(21108,
	"  Detected FCode Version:\tNo version available for this FCode\n"));
			} else {
				(void) fprintf(stdout, MSGSTR(21109,
				    "  Detected FCode Version:\t%s\n"),
				    prom_ver_data);
			}
		} else {
			errnum = 2; /* can't get prom properties */
			retval++;
		}

		if (fflag) {

			memset(ver_file, 0, sizeof (ver_file));
			if (emulex_fcode_reader(fcode_fd, "fcode-version",
				    ver_file, sizeof (ver_file)) == 0) {
				(void) fprintf(stdout, MSGSTR(21110,
					    "  New FCode Version:\t\t%s\n"),
					    ver_file);
			} else {
				di_fini(root);
				(void) close(fcode_fd);
				return (1);
			}

			/*
			 * Load the New FCode
			 * Give warning if file doesn't appear to be correct
			 */
			if (!q_warn(errnum)) {
				/* Disable user-interrupt Control-C */
				sigint =
				    (void (*)(int)) signal(SIGINT, SIG_IGN);
				/* Load FCode */
				(void) fprintf(stdout, MSGSTR(21111,
					"  Loading FCode: %s\n"), file);
				if (fcode_load_file(fcode_fd, phys_path,
					    &fcio_errno) == FCODE_SUCCESS) {
					(void) fprintf(stdout, MSGSTR(21112,
					"  Successful FCode download: %s\n"),
					phys_path);
				} else {
					handle_emulex_error(fcio_errno,
					    phys_path);
					retval++;
				}

				/* Restore SIGINT (user interrupt) setting */
				(void) signal(SIGINT, sigint);
			}
		}

	try_next:
		node = di_drv_next_node(node);
	}

	di_fini(root);
	(void) fprintf(stdout, "  ");
	(void) fprintf(stdout, MSGSTR(125, "Complete\n"));
	if (fcode_fd != -1)
		(void) close(fcode_fd);
	return (retval);

}
Exemple #17
0
/*
 * This function finds a predefined error string to a given
 * error number (errornum), allocates memory for the string
 * and returns the corresponding error message to the caller.
 *
 * RETURNS
 *	error string	if O.K.
 *	NULL		otherwise
 */
char
*get_errString(int errornum)
{
char	err_msg[MAXLEN], *errStrg;

	err_msg[0] = '\0'; /* Just in case */
	if (errornum < L_BASE) {
			/* Some sort of random system error most likely */
			errStrg = strerror(errno);
			if (errStrg != NULL) {
				(void) strcpy(err_msg, errStrg);
			} else { /* Something's _really_ messed up */
				(void) sprintf(err_msg,
					MSGSTR(10081,
					" Error: could not decode the"
					" error message.\n"
					" The given error message is not"
					" defined in the library.\n"
					" Message number: %d.\n"), errornum);
			}

	/* Make sure ALL CASES set err_msg to something */
	} else switch (errornum) {
		case L_SCSI_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10096,
				" Error: SCSI failure."));
			break;

		case L_PR_INVLD_TRNSFR_LEN:
			(void) sprintf(err_msg,
				MSGSTR(10005,
				" Error: Persistant Reserve command"
				" transfer length not word aligned."));
			break;

		case L_RD_NO_DISK_ELEM:
			(void) sprintf(err_msg,
				MSGSTR(10006,
				" Error: Could not find the disk elements"
				" in the Receive Diagnostic pages."));
			break;

		case L_RD_INVLD_TRNSFR_LEN:
			(void) sprintf(err_msg,
				MSGSTR(10007,
				" Error: Receive Diagnostic command"
				" transfer length not word aligned."));
			break;

		case L_ILLEGAL_MODE_SENSE_PAGE:
			(void) sprintf(err_msg,
				MSGSTR(10008,
				" Error: Programming error - "
				"illegal Mode Sense parameter."));
			break;

		case L_INVALID_NO_OF_ENVSEN_PAGES:
			(void) sprintf(err_msg,
				MSGSTR(10009,
				" Error: Invalid no. of sense pages.\n"
				" Could not get valid sense page"
				" information from the device."));
			break;

		case L_INVALID_BUF_LEN:
			(void) sprintf(err_msg,
				MSGSTR(10010,
				" Error: Invalid buffer length.\n"
				" Could not get diagnostic "
				" information from the device."));
			break;

		case L_INVALID_PATH:
			(void) sprintf(err_msg,
				MSGSTR(113,
				" Error: Invalid pathname"));
			break;

		case L_NO_PHYS_PATH:
			(void) sprintf(err_msg,
				MSGSTR(10011,
				" Error: Could not get"
				" physical path to the device."));
			break;

		case L_NO_SES_PATH:
			(void) sprintf(err_msg,
				MSGSTR(10098,
				" Error: No SES found"
				" for the device path."));
			break;

		case L_INVLD_PATH_NO_SLASH_FND:
			(void) sprintf(err_msg,
				MSGSTR(10012,
				"Error in the device physical path."));
			break;

		case L_INVLD_PATH_NO_ATSIGN_FND:
			(void) sprintf(err_msg,
				MSGSTR(10013,
				" Error in the device physical path:"
				" no @ found."));
			break;

		case L_INVALID_SLOT:
			(void) sprintf(err_msg,
				MSGSTR(10014,
				" Error: Invalid path format."
				" Invalid slot."));
			break;

		case L_INVALID_LED_RQST:
			(void) sprintf(err_msg,
				MSGSTR(10015,
				" Error: Invalid LED request."));
			break;

		case L_INVALID_PATH_FORMAT:
			(void) sprintf(err_msg,
				MSGSTR(10016,
				" Error: Invalid path format."));
			break;

		case L_OPEN_PATH_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10017,
				" Error opening the path."));
			break;

		case L_INVALID_PASSWORD_LEN:
			(void) sprintf(err_msg,
				MSGSTR(10018,
				"Error: Invalid password length."));
			break;

		case L_INVLD_PHYS_PATH_TO_DISK:
			(void) sprintf(err_msg,
				MSGSTR(10019,
				" Error: Physical path not of a disk."));
			break;

		case L_INVLD_ID_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10020,
				" Error in the device physical path:"
				" Invalid ID found in the path."));
			break;

		case L_INVLD_WWN_FORMAT:
			(void) sprintf(err_msg,
				MSGSTR(10021,
				" Error in the device physical path:"
				" Invalid wwn format."));

			break;

		case L_NO_VALID_PATH:
			(void) sprintf(err_msg,
				MSGSTR(10022,
				" Error: Could not find valid path to"
				" the device."));
			break;

		case L_NO_WWN_FOUND_IN_PATH:
			(void) sprintf(err_msg,
				MSGSTR(10023,
				" Error in the device physical path:"
				" No WWN found."));

			break;

		case L_NO_NODE_WWN_IN_WWNLIST:
			(void) sprintf(err_msg,
				MSGSTR(10024,
				" Error: Device's Node WWN is not"
				" found in the WWN list.\n"));
			break;

		case L_NO_NODE_WWN_IN_BOXLIST:
			(void) sprintf(err_msg,
				MSGSTR(10025,
				" Error: Device's Node WWN is not"
				" found in the Box list.\n"));
			break;

		case L_NULL_WWN_LIST:
			(void) sprintf(err_msg,
				MSGSTR(10026,
				" Error: Null WWN list found."));
			break;

		case L_NO_LOOP_ADDRS_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10027,
				" Error: Could not find the loop address for "
				" the device at physical path."));

			break;

		case L_INVLD_PORT_IN_PATH:
			(void) sprintf(err_msg,
				MSGSTR(10028,
				"Error in the device physical path:"
				" Invalid port number found."
				" (Should be 0 or 1)."));

			break;

		case L_INVALID_LOOP_MAP:
			(void) sprintf(err_msg,
				MSGSTR(10029,
				"Error: Invalid loop map found."));
			break;

		case L_SFIOCGMAP_IOCTL_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10030,
				" Error: SFIOCGMAP ioctl failed."
				" Cannot read loop map."));
			break;

		case L_FCIO_GETMAP_IOCTL_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10031,
				" Error: FCIO_GETMAP ioctl failed."
				" Cannot read loop map."));
			break;

		case L_FCIO_LINKSTATUS_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10032,
				" Error: FCIO_LINKSTATUS ioctl failed."
				" Cannot read loop map."));
			break;

		case L_FCIOGETMAP_INVLD_LEN:
			(void) sprintf(err_msg,
				MSGSTR(10033,
				" Error: FCIO_GETMAP ioctl returned"
				" an invalid parameter:"
				" # entries to large."));
			break;

		case L_FCIO_FORCE_LIP_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10034,
				" Error: FCIO_FORCE_LIP ioctl failed."));
			break;

		case L_FCIO_FORCE_LIP_PARTIAL_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10115,
				" Error: FCIO_FORCE_LIP ioctl failed on one"
				" or more (but not all) of the paths."));
			break;

		case L_DWNLD_CHKSUM_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10035,
				"Error: Download file checksum failed."));

			break;

		case L_DWNLD_READ_HEADER_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10036,
				" Error: Reading download file exec"
				" header failed."));
			break;

		case L_DWNLD_READ_INCORRECT_BYTES:
			(void) sprintf(err_msg,
				MSGSTR(10037,
				" Error: Incorrect number of bytes read."));
			break;

		case L_DWNLD_INVALID_TEXT_SIZE:
			(void) sprintf(err_msg,
				MSGSTR(10038,
				" Error: Reading text segment: "
				" Found wrong size."));
			break;

		case L_DWNLD_READ_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10039,
				" Error: Failed to read download file."));
			break;

		case L_DWNLD_BAD_FRMWARE:
			(void) sprintf(err_msg,
				MSGSTR(10040,
				" Error: Bad Firmware MAGIC."));
			break;

		case L_DWNLD_TIMED_OUT:
			(void) sprintf(err_msg,
				MSGSTR(10041,
				" Error: Timed out in 5 minutes"
				" waiting for the"
				" IB to become available."));
			break;

		case L_REC_DIAG_PG1:
			(void) sprintf(err_msg,
				MSGSTR(10042,
				" Error parsing the Receive"
				" diagnostic page."));
			break;

		case L_TRANSFER_LEN:
			(void) sprintf(err_msg,
				MSGSTR(10043, "  "));
			break;

		case L_REQUIRE_FILE:
			(void) sprintf(err_msg,
				MSGSTR(10109,
				" Error: No default file.  You must specify"
				" the filename path."));
			break;

		case L_MALLOC_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10,
				" Error: Unable to allocate memory."));
			break;

		case L_LOCALTIME_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10044,
				" Error: Could not convert time"
				" to broken-down time: Hrs/Mins/Secs."));
			break;

		case L_SELECT_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10045,
				" select() error during retry:"
				" Could not wait for"
				" specified time."));
			break;

		case L_NO_DISK_DEV_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10046,
				" Error: No disk devices found"
				" in the /dev/rdsk"
				" directory."));
			break;

		case L_NO_TAPE_DEV_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10047,
				" Error: No tape devices found"
				" in the /dev/rmt"
				" directory."));
			break;

		case L_LSTAT_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10048,
				" lstat() error: Cannot obtain status"
				" for the device."));
			break;

		case L_SYMLINK_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10049,
				" Error: Could not read the symbolic link."));
			break;

		case L_UNAME_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10050,
				" uname() error: Could not obtain the"
				" architeture of the host machine."));
			break;

		case L_DRVCONFIG_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10051,
				" Error: Could not run drvconfig."));
			break;

		case L_DISKS_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10052,
				" Error: Could not run disks."));
			break;

		case L_DEVLINKS_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10053,
				" Error: Could not run devlinks."));
			break;

		case L_READ_DEV_DIR_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10054,
				" Error: Could not read /dev/rdsk"
				" directory."));
			break;

		case L_OPEN_ES_DIR_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10055,
				" Error: Could not open /dev/es"
				" directory."));
			break;

		case L_LSTAT_ES_DIR_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10056,
				" lstat() error: Could not get status"
				" for /dev/es directory."));
			break;

		case L_DEV_BUSY:
			(void) sprintf(err_msg,
				MSGSTR(10057,
				" Error: Could not offline the device\n"
				" May be Busy."));
			break;

		case L_EXCL_OPEN_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10058,
				" Error: Could not open device in"
				" exclusive mode."
				"  May already be open."));
			break;

		case L_DEVICE_RESERVED:
			(void) sprintf(err_msg,
				MSGSTR(10059,
				" Error: Disk is reserved."));
			break;

		case L_DISKS_RESERVED:
			(void) sprintf(err_msg,
				MSGSTR(10060,
				" Error: One or more disks in"
				" SENA are reserved."));
			break;

		case L_SLOT_EMPTY:
			(void) sprintf(err_msg,
				MSGSTR(10061,
				" Error: Slot is empty."));
			break;

		case L_ACQUIRE_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10062,
				" Error: Could not acquire"
				" the device."));
			break;

		case L_POWER_OFF_FAIL_BUSY:
			(void) sprintf(err_msg,
				MSGSTR(10063,
				" Error: Could not power off the device.\n"
				" May be Busy."));
			break;

		case L_ENCL_NAME_CHANGE_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10064,
				" Error: The Enclosure name change failed."));
			break;

		case L_DUPLICATE_ENCLOSURES:
			(void) sprintf(err_msg,
				MSGSTR(10065,
				" Error: There are two or more enclosures"
				" with the same name."
				" Please use a logical or physical"
				" pathname."));
			break;

		case L_INVALID_NUM_DISKS_ENCL:
			(void) sprintf(err_msg,
				MSGSTR(10066,
				" Error: The number of disks in the"
				" front & rear of the enclosure are"
				" different."
				" This is not a supported configuration."));
			break;

		case L_ENCL_INVALID_PATH:
			(void) sprintf(err_msg,
				MSGSTR(10067,
				" Error: Invalid path."
				" Device is not a SENA subsystem."));
			break;

		case L_NO_ENCL_LIST_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10068,
				" Error: Cannot get the Box list."));
			break;

		case L_IB_NO_ELEM_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10069,
				" Error: No elements returned from"
				" enclosure (IB)."));
			break;

		case L_GET_STATUS_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10070,
				" Error: Get status failed."));
			break;

		case L_RD_PG_MIN_BUFF:
			(void) sprintf(err_msg,
				MSGSTR(10071,
				" Error: Reading page from IB.\n"
				" Buffer size too small."));
			break;

		case L_RD_PG_INVLD_CODE:
			(void) sprintf(err_msg,
				MSGSTR(10072,
				" Error: Reading page from IB\n"
				" Invalid page code or page len found."));
			break;

		case L_BP_BUSY_RESERVED:
			(void) sprintf(err_msg,
				MSGSTR(10073,
				" Error: There is a busy or reserved disk"
				" attached to this backplane.\n"
				" You must close the disk,\n"
				" or release the disk,\n"
				" or resubmit the command using"
				" the Force option."));
			break;

		case L_BP_BUSY:
			(void) sprintf(err_msg,
				MSGSTR(10074,
				" Error: There is a busy disk"
				" attached to this backplane.\n"
				" You must close the disk,\n"
				" or resubmit the command using"
				" the Force option."));
			break;

		case L_BP_RESERVED:
			(void) sprintf(err_msg,
				MSGSTR(10075,
				" Error: There is a reserved disk"
				" attached to this backplane.\n"
				" You must release the disk,\n"
				" or resubmit the subcommand using"
				" the Force option."));
			break;

		case L_NO_BP_ELEM_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10076,
				" Error: No Back plane elements found"
				" in the enclosure."));
			break;

		case L_SSA_CONFLICT:
			(void) sprintf(err_msg,
				MSGSTR(10077,
				" There is a conflict between the "
				"enclosure name and an SSA name of "
				"same form, cN.\n"
				" Please use a logical or physical "
				"pathname."));
			break;

		case L_WARNING:
			(void) sprintf(err_msg,
				MSGSTR(10078, " Warning:"));

			break;

		case L_TH_JOIN:
			(void) sprintf(err_msg,
				MSGSTR(10079,
				" Error: Thread join failed."));
			break;

		case L_FCIO_RESET_LINK_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10082,
				" Error: FCIO_RESET_LINK ioctl failed.\n"
				" Could not reset the loop."));
			break;

		case L_FCIO_GET_FCODE_REV_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10083,
				" Error: FCIO_GET_FCODE_REV ioctl failed.\n"
				" Could not get the fcode version."));
			break;

		case L_FCIO_GET_FW_REV_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10084,
				" Error: FCIO_GET_FW_REV ioctl failed.\n"
				" Could not get the firmware revision."));
			break;

		case L_NO_DEVICES_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10085,
				" No FC devices found."));
			break;

		case L_INVALID_DEVICE_COUNT:
			(void) sprintf(err_msg,
				MSGSTR(10086,
				" Error: FCIO_GET_DEV_LIST ioctl returned"
				" an invalid device count."));
			break;

		case L_FCIO_GET_NUM_DEVS_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10087,
				" Error: FCIO_GET_NUM_DEVS ioctl failed.\n"
				" Could not get the number of devices."));
			break;

		case L_FCIO_GET_DEV_LIST_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10088,
				" Error: FCIO_GET_DEV_LIST ioctl failed.\n"
				" Could not get the device list."));
			break;

		case L_FCIO_GET_LINK_STATUS_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10089,
				" Error: FCIO_GET_LINK_STATUS ioctl failed.\n"
				" Could not get the link status."));
			break;

		case L_PORT_OFFLINE_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10090,
				" Error: ioctl to offline the port failed."));
			break;

		case L_PORT_OFFLINE_UNSUPPORTED:
			(void) sprintf(err_msg,
				MSGSTR(10091,
				" Error: The driver does not support ioctl to"
				" disable the FCA port."));
			break;

		case L_PORT_ONLINE_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10092,
				" Error: ioctl to online the port failed."));
			break;

		case L_PORT_ONLINE_UNSUPPORTED:
			(void) sprintf(err_msg,
				MSGSTR(10093,
				" Error: The driver does not support ioctl to"
				" enable the FCA port."));
			break;

		case L_FCP_TGT_INQUIRY_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10094,
				" Error: FCP_TGT_INQUIRY ioctl failed.\n"
				" Could not get the target inquiry data"
				" from FCP."));
			break;

		case L_FSTAT_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10095,
				" fstat() error: Cannot obtain status"
				" for the device."));
			break;

		case L_FCIO_GET_HOST_PARAMS_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10097,
				" Error: FCIO_GET_HOST_PARAMS ioctl failed.\n"
				" Could not get the host parameters."));
			break;

		case L_STAT_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10099,
				" stat() error: Cannot obtain status"
				" for the device."));
			break;

		case L_DEV_SNAPSHOT_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10100,
				" Error: Could not retrieve device tree"
				" snapshot."));
			break;

		case L_LOOPBACK_UNSUPPORTED:
			(void) sprintf(err_msg,
				MSGSTR(10101,
				" Error: Loopback mode is unsupported for this"
				" device."));
			break;

		case L_LOOPBACK_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10102,
				" Error: Error occurred during loopback mode"
				" set."));
			break;

		case L_FCIO_GET_TOPOLOGY_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10103,
				" Error: FCIO_GET_TOPOLOGY ioctl failed.\n"
				" Could not get the fca port topology."));
			break;

		case L_UNEXPECTED_FC_TOPOLOGY:
			(void) sprintf(err_msg,
				MSGSTR(10104,
				" Error: Unexpected Fibre Channel topology"
				" found."));
			break;

		case L_INVALID_PRIVATE_LOOP_ADDRESS:
			(void) sprintf(err_msg,
				MSGSTR(10105,
				" Error: AL_PA is not a valid private loop"
				" address."));
			break;

		case L_NO_FABRIC_ADDR_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10106,
				" Error: Could not find the fabric address"
				" for the device at physical path."));
			break;

		case L_INVALID_FABRIC_ADDRESS:
			(void) sprintf(err_msg,
				MSGSTR(10107,
				" Error: Device port address on the Fabric"
				" topology is not valid."));
			break;

		case L_PT_PT_FC_TOP_NOT_SUPPORTED:
			(void) sprintf(err_msg,
				MSGSTR(10108,
				" Error: Point to Point Fibre Channel "
				"topology is currently not supported."));
			break;

		case L_FCIO_DEV_LOGIN_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10310,
				" Error: FCIO_DEV_LOGIN ioctl failed."));
			break;

		case L_FCIO_DEV_LOGOUT_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10311,
				" Error: FCIO_DEV_LOGOUT ioctl failed."));
			break;

		case L_OPNOSUPP_ON_TOPOLOGY:
			(void) sprintf(err_msg,
				MSGSTR(10312,
				" Error: operation not supported "
				"on connected topology."));
			break;

		case L_INVALID_PATH_TYPE:
			(void) sprintf(err_msg,
				MSGSTR(10313,
				" Error: operation not supported "
				"on the path."));
			break;

		case L_FCIO_GET_STATE_FAIL:
			(void) sprintf(err_msg,
				MSGSTR(10314,
				" Error: FCIO_GET_STATE ioctl failed."));
			break;

		case L_WWN_NOT_FOUND_IN_DEV_LIST:
			(void) sprintf(err_msg,
				MSGSTR(10315,
				" Error: device WWN not found in "
				"device list."));
			break;

		case L_STAT_RMT_DIR_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10110,
				" stat() error: Could not get status"
				" for /dev/rmt directory."));
			break;

		case L_STAT_DEV_DIR_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10111,
				" stat() error: Could not get status"
				" for /dev/dsk directory."));
			break;

		case L_PROM_INIT_FAILED:
			(void) sprintf(err_msg,
				MSGSTR(10234,
				" Error: di_prom_init failure"));
			break;

		case L_PORT_DRIVER_NOT_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10113,
				" Error: requested port driver"
				" does not exist"));
			break;

		case L_PHYS_PATH_NOT_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10114,
				" Error: requested phys path does not exist"));
			break;

		case L_GET_DEV_LIST_ULP_FAILURE:
			(void) sprintf(err_msg,
				MSGSTR(10150,
				" Error: g_get_dev_list failed on ULP "
				"processing of target device(s)"));
			break;

		case L_SCSI_VHCI_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10230,
				" Error: Unable to perform failover"));
			break;

		case L_SCSI_VHCI_ALREADY_ACTIVE:
			(void) sprintf(err_msg,
				MSGSTR(10231,
				" Error: Pathclass already active"));
			break;

		case L_NO_DEVID:
			(void) sprintf(err_msg,
				MSGSTR(10232,
				" Error: No device identifier found"));
			break;

		case L_DRIVER_NOTSUPP:
			(void) sprintf(err_msg,
				MSGSTR(10233,
				" Error: Driver not supported"));
			break;

		case L_PROC_WWN_ARG_ERROR:
			(void) sprintf(err_msg,
				MSGSTR(10235,
				" Error: process WWN argument"));
			break;

		case L_NO_WWN_PROP_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10236,
				" Error: WWN prop not found"));
			break;

		case L_NO_DRIVER_NODES_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10237,
				" Error: Requested driver nodes not found"));
			break;

		case L_INVALID_MAP_DEV_ADDR:
			(void) sprintf(err_msg,
				MSGSTR(10330,
				" Error: Invalid map device handle found"));
			break;

		case L_INVALID_MAP_DEV_PROP_TYPE:
			(void) sprintf(err_msg,
				MSGSTR(10331,
				" Error: Invalid device property type found"));
			break;

		case L_INVALID_MAP_DEV_PROP_NAME:
			(void) sprintf(err_msg,
				MSGSTR(10332,
				" Error: Invalid device property name found"));
			break;

		case L_INVALID_MAP_DEV_PROP:
			(void) sprintf(err_msg,
				MSGSTR(10333,
				" Error: Invalid device property handle "
				"found"));
			break;

		case L_SCSI_VHCI_NO_STANDBY:
			(void) sprintf(err_msg,
				MSGSTR(10334,
				" Error: Unable to perform failover, "
				"standby path unavailable"));
			break;

		case L_SCSI_VHCI_FAILOVER_NOTSUP:
			(void) sprintf(err_msg,
				MSGSTR(10335,
				" Error: Device does not support failover"));
			break;

		case L_SCSI_VHCI_FAILOVER_BUSY:
			(void) sprintf(err_msg,
				MSGSTR(10336,
				" Error: Failover currently in progress"));
			break;

		case L_NO_SUCH_DEV_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10337,
				" Error: No such device found"));
			break;

		case L_NO_SUCH_PROP_FOUND:
			(void) sprintf(err_msg,
				MSGSTR(10338,
				" Error: No such property found"));
			break;

		case L_INVALID_ARG:
			(void) sprintf(err_msg,
				MSGSTR(10339,
				" Error: Invalid argument found"));
			break;

		default:

			if (((L_SCSI_ERROR ^ errornum) == STATUS_GOOD) ||
			((L_SCSI_ERROR ^ errornum) == STATUS_BUSY) ||
			((L_SCSI_ERROR ^ errornum) == STATUS_CHECK) ||
			((L_SCSI_ERROR ^ errornum) == STATUS_MET) ||
			((L_SCSI_ERROR ^ errornum) == STATUS_INTERMEDIATE) ||
		((L_SCSI_ERROR ^ errornum) == STATUS_INTERMEDIATE_MET) ||
		((L_SCSI_ERROR ^ errornum) == STATUS_RESERVATION_CONFLICT) ||
			((L_SCSI_ERROR ^ errornum) == STATUS_TERMINATED) ||
			((L_SCSI_ERROR ^ errornum) == STATUS_QFULL)) {
				(void) sprintf(err_msg,
					MSGSTR(10080,
					" SCSI Error - Sense Byte:(0x%x) %s \n"
					" Error: Retry failed."),
				(L_SCSI_ERROR ^ errornum) & STATUS_MASK,
			decode_sense_byte((uchar_t)L_SCSI_ERROR ^ errornum));
			} else {
				(void) sprintf(err_msg,
					MSGSTR(10081,
					" Error: could not decode the"
					" error message.\n"
					" The given error message is not"
					" defined in the library.\n"
					" Message number: %d.\n"), errornum);
			}

	} /* end of switch */

	errStrg = alloc_string(err_msg);

	return (errStrg);
}
Exemple #18
0
/*
 * Retrieve the version banner from the card
 *    uses ioctl: FCIO_FCODE_MCODE_VERSION	FCode revision
 */
static int
q_findversion(int verbose, int index, uchar_t *version, uint16_t *chip_id)
/*ARGSUSED*/
{
	int fd, ntries;
	struct	ifp_fm_version *version_buffer = NULL;
	char	prom_ver[100] = {NULL};
	char	mcode_ver[100] = {NULL};
	fcio_t	fcio;

	if (strstr(&pcibus_list[index][0], fc_trans)) {

	if ((fd = open(&pcibus_list[index][0], O_RDWR)) < 0) {
		(void) fprintf(stderr,
		    MSGSTR(21000, "Error: Could not open %s\n"),
		    &pcibus_list[index][0]);
		return (1);
	}

	if ((version_buffer = (struct ifp_fm_version *)malloc(
		sizeof (struct ifp_fm_version))) == NULL) {
		(void) fprintf(stderr,
		    MSGSTR(21013, "Error: Memory allocation failed\n"));
		(void) close(fd);
		return (1);
	}

	version_buffer->fcode_ver = (char *)version;
	version_buffer->mcode_ver = mcode_ver;
	version_buffer->prom_ver = prom_ver;
	version_buffer->fcode_ver_len = MAXNAMELEN - 1;
	version_buffer->mcode_ver_len = 100;
	version_buffer->prom_ver_len = 100;

	if (ioctl(fd, FCIO_FCODE_MCODE_VERSION, version_buffer) < 0) {
		(void) fprintf(stderr, MSGSTR(21014,
		"Error: Driver interface FCIO_FCODE_MCODE_VERSION failed\n"));
		free(version_buffer);
		(void) close(fd);
		return (1);
	}
	version[version_buffer->fcode_ver_len] = '\0';

	/* Need a way to get card MCODE (firmware) to track certain HW bugs */
	if (getenv("_LUX_D_DEBUG") != NULL) {
		(void) fprintf(stdout, "  Device %i: QLGC chip_id %x\n",
		    index+1, *chip_id);
		(void) fprintf(stdout, "  FCode:%s\n  MCODE:%s\n  PROM:%s\n",
		    (char *)version, mcode_ver, prom_ver);
	}
	free(version_buffer);

	} else if (strstr(&pcibus_list[index][0], fp_trans)) {
		/*
		 * Get the fcode and prom's fw version
		 * using the fp ioctls. Currently, we pass
		 * only the fcode version to the calling function
		 * and ignore the FW version (using the existing
		 * implementation).
		 */

		if ((fd = open(&pcibus_list[index][0], O_RDWR)) < 0) {
			(void) fprintf(stderr,
			    MSGSTR(4511, "Could not open %s\n"),
			    &pcibus_list[index][0]);
			(void) close(fd);
			return (1);
		}
		/* Get the fcode version */
		bzero(version, sizeof (version));
		fcio.fcio_cmd = FCIO_GET_FCODE_REV;
		/* Information read operation */
		fcio.fcio_xfer = FCIO_XFER_READ;
		fcio.fcio_obuf = (caddr_t)version;
		fcio.fcio_olen = MAXNAMELEN;

		for (ntries = 0; ntries < MAX_RETRIES; ntries++) {
			if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
				if ((errno == EAGAIN) &&
				    (ntries+1 < MAX_RETRIES)) {
					/* wait 30 secs */
					(void) sleep(MAX_WAIT_TIME);
					continue;
				}
				(void) close(fd);
				return (L_FCIO_GET_FCODE_REV_FAIL);
			}
			break;
		}
		version[MAXNAMELEN-1] = '\0';
	}

	/* Get type of card from product name in FCode version banner */
	if (strstr((char *)version, qlgc2100)) {
		*chip_id = 0x2100;
	} else if (strstr((char *)version, qlgc2200)) {
		*chip_id = 0x2200;
		if (strstr((char *)version, "Sbus")) {
			*chip_id = SBUS_CHIP_ID;
		}
	} else if (strstr((char *)version, qlgc2300)) {
		*chip_id = 0x2300;
	} else if (strstr((char *)version, qlgc2312)) {
		*chip_id = 0x2312;
	} else {
		*chip_id = 0x0;
	}

	(void) close(fd);
	return (0);
}
Exemple #19
0
/*
 *	Download host bus adapter FCode to all supported cards.
 *
 *	Specify a directory that holds the FCode files, or
 *	it will use the default dir.  Each file is dealt to
 *	the appropriate function.
 *
 *	-p prints current versions only, -d specifies a directory to load
 */
static	int
adm_fcode(int verbose, char *dir)
{
	struct stat statbuf;
	struct dirent *dirp;
	DIR	*dp;
	int	fp;
	char	fbuf[BUFSIZ];
	char	file[MAXPATHLEN];
	int	retval = 0, strfound = 0;
	char	manf[BUFSIZ];

	/* Find all adapters and print the current FCode version */
	if (Options & OPTION_P) {

/* SOCAL (SBus) adapters are not supported on x86 */
#ifndef __x86
		if (verbose) {
			(void) fprintf(stdout,
			    MSGSTR(2215, "\n  Searching for FC100/S cards:\n"));
		}
		retval += fcal_update(Options & PVERBOSE, NULL);
#endif

		if (verbose) {
			(void) fprintf(stdout,
		MSGSTR(2216, "\n  Searching for FC100/P, FC100/2P cards:\n"));
		}
		retval += q_qlgc_update(Options & PVERBOSE, NULL);
		if (verbose) {
			(void) fprintf(stdout,
			    MSGSTR(2503, "\n  Searching for Emulex cards:\n"));
		}
		retval += emulex_update(NULL);

	/* Send files to the correct function for loading to the HBA */
	} else {

		if (!dir) {
			(void) fprintf(stdout, MSGSTR(2251,
			    "  Location of Fcode not specified.\n"));
			return (1);

		} else if (verbose) {
			(void) fprintf(stdout, MSGSTR(2217,
			    "  Using directory %s"), dir);
		}
		if (lstat(dir, &statbuf) < 0) {
			(void) fprintf(stderr, MSGSTR(134,
			    "%s: lstat() failed - %s\n"),
			    dir, strerror(errno));
			return (1);
		}
		if (S_ISDIR(statbuf.st_mode) == 0) {
		(void) fprintf(stderr,
		    MSGSTR(2218, "Error: %s is not a directory.\n"), dir);
			return (1);
		}
		if ((dp = opendir(dir)) == NULL) {
			(void) fprintf(stderr, MSGSTR(2219,
			    "  Error Cannot open directory %s\n"), dir);
			return (1);
		}

		while ((dirp = readdir(dp)) != NULL) {
			if (strcmp(dirp->d_name, ".") == 0 ||
			    strcmp(dirp->d_name, "..") == 0) {
				continue;
			}
			sprintf(file, "%s/%s", dir, dirp->d_name);

			if ((fp = open(file, O_RDONLY)) < 0) {
				(void) fprintf(stderr,
				    MSGSTR(2220,
					"Error: open() failed to open file "
					"%s\n"), file);
				/*
				 * We should just issue an error message and
				 * make an attempt on the next file,
				 * and the open error is still an error
				 * so the retval should be incremented
				 */
				retval++;
				continue;
			}
			while ((read(fp, fbuf, BUFSIZ)) > 0) {
				if (memstrstr(fbuf, "SUNW,socal",
					BUFSIZ, strlen("SUNW,socal"))
								!= NULL) {
					(void) fprintf(stdout, MSGSTR(2221,
					    "\n  Using file: %s\n"), file);
					retval += fcal_update(
						Options & PVERBOSE, file);
					strfound++;
					break;
				} else if ((memstrstr(fbuf, "SUNW,ifp",
						BUFSIZ, strlen("SUNW,ifp"))
								!= NULL) ||
				    (memstrstr(fbuf, "SUNW,qlc",
					    BUFSIZ, strlen("SUNW,qlc"))
								    != NULL)) {
					(void) fprintf(stdout, MSGSTR(2221,
					    "\n  Using file: %s\n"), file);
					retval += q_qlgc_update(
						Options & PVERBOSE, file);
					strfound++;
					break;
				}
			}
			if (!strfound) {
				/* check to see if this is an emulex fcode */
				memset(manf, 0, sizeof (manf));
				if ((emulex_fcode_reader(fp, "manufacturer",
						    manf,
						    sizeof (manf)) == 0) &&
				    (strncmp(manf, "Emulex", sizeof (manf))
									== 0)) {
					retval += emulex_update(file);
					strfound = 0;
				} else {
					(void) fprintf(stderr, MSGSTR(2222,
					    "\nError: %s is not a valid Fcode "
					    "file.\n"), file);
					retval++;
				}
			} else {
				strfound = 0;
			}
			close(fp);
		}
		closedir(dp);
	}
	return (retval);
}