#include <stdlib.h>
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/dklabel.h>
#include <sys/autoconf.h>
#include <sys/utsname.h>
#include <sys/ddi.h>
#include <ctype.h>
#include <sys/scsi/scsi.h>
#include <dirent.h>
#include <nl_types.h>
#include <locale.h>
#include <thread.h>
#include <synch.h>
#include <l_common.h>
#include <stgcom.h>
#include <l_error.h>
#include <g_state.h>
#include <libdevinfo.h>
#define BYTES_PER_LINE 16
#define SCMD_UNKNOWN 0xff
#define PCI_BUS 1
#define SBUS 2
#define FCOE 3
struct str_type {
char *string;
uint_t type;
};
static struct str_type ValidBusStrings[] = {
{"pci@", PCI_BUS},
{"sbus@", SBUS},
{"fcoe", FCOE},
{NULL, 0}
};
static struct str_type ValidFCAstrings[] = {
{"SUNW,ifp@", FC4_PCI_FCA | FC4_IFP_XPORT},
{"SUNW,socal@", FC4_SOCAL_FCA},
{NULL, 0}
};
static struct str_type ValidXportStrings[] = {
{"/sf@", FC4_SF_XPORT},
{"/fp@", FC_GEN_XPORT},
{NULL, 0}
};
struct _enclDisk {
char *vid;
char *pid;
};
static struct _enclDisk enclDiskTbl[] = {
{"SUN", "SENA"},
{"SUN", "SUNWGS"},
{"FUJITSU", "MA"},
{"HITACHI", "DK"},
{"HITACHI", "HU"},
{"SEAGATE", "ST"},
{NULL, NULL}
};
nl_catd l_catd;
static void string_dump(char *, uchar_t *, int, int, char msg_string[]);
char *
g_alloc_string(char *s)
{
char *ns;
if (s == (char *)NULL) {
ns = (char *)g_zalloc(1);
} else {
ns = (char *)g_zalloc(strlen(s) + 1);
if (ns != NULL) {
(void) strncpy(ns, s, (strlen(s) + 1));
}
}
return (ns);
}
void
g_destroy_data(void *data)
{
A_DPRINTF(" g_destroy_data: Free\'ed buffer at 0x%x\n",
data);
free((void *)data);
}
void
g_dump(char *hdr, uchar_t *src, int nbytes, int format)
{
int i;
int n;
char *p;
char s[256];
assert(format == HEX_ONLY || format == HEX_ASCII);
(void) strcpy(s, hdr);
for (p = s; *p; p++) {
*p = ' ';
}
p = hdr;
while (nbytes > 0) {
(void) fprintf(stdout, "%s", p);
p = s;
n = min(nbytes, BYTES_PER_LINE);
for (i = 0; i < n; i++) {
(void) fprintf(stdout, "%02x ", src[i] & 0xff);
}
if (format == HEX_ASCII) {
for (i = BYTES_PER_LINE-n; i > 0; i--) {
(void) fprintf(stdout, " ");
}
(void) fprintf(stdout, " ");
for (i = 0; i < n; i++) {
(void) fprintf(stdout, "%c",
isprint(src[i]) ? src[i] : '.');
}
}
(void) fprintf(stdout, "\n");
nbytes -= n;
src += n;
}
}
static int
cleanup_dotdot_path(char *path)
{
char holder[MAXPATHLEN];
char *dotdot;
char *previous_slash;
dotdot = strstr(path, "/../");
if (dotdot == NULL) {
return (0);
}
if (dotdot == path) {
strcpy(holder, &path[3]);
strcpy(path, holder);
return (1);
}
*dotdot = '\0';
previous_slash = strrchr(path, '/');
if (previous_slash == NULL) {
return (0);
}
*(previous_slash+1) = '\0';
strcat(path, dotdot+4);
return (1);
}
char *
g_get_physical_name_from_link(char *path)
{
struct stat stbuf;
char source[MAXPATHLEN];
char scratch[MAXPATHLEN];
char pwd[MAXPATHLEN];
char *tmp;
int cnt;
if (path == NULL) {
return (NULL);
}
strcpy(source, path);
for (;;) {
if (source[0] != '/') {
tmp = getcwd(pwd, MAXPATHLEN);
if (tmp == NULL) {
O_DPRINTF("getcwd() failed - %s\n",
strerror(errno));
return (NULL);
}
if (source[0] == '.' && source[1] == '/') {
strcpy(scratch, source+2);
} else {
strcpy(scratch, source);
}
strcpy(source, pwd);
strcat(source, "/");
strcat(source, scratch);
}
while (cleanup_dotdot_path(source));
if (stat(source, &stbuf) == -1) {
O_DPRINTF("stat() failed for %s- %s\n",
source, strerror(errno));
return (NULL);
}
if (lstat(source, &stbuf) == -1) {
O_DPRINTF("lstat() failed for - %s\n",
source, strerror(errno));
return (NULL);
}
if (!S_ISLNK(stbuf.st_mode)) {
return (g_alloc_string(source));
}
cnt = readlink(source, scratch, sizeof (scratch));
if (cnt < 0) {
O_DPRINTF("readlink() failed - %s\n",
strerror(errno));
return (NULL);
}
scratch[cnt] = '\0';
if (scratch[0] != '/') {
tmp = strrchr(source, '/');
if (tmp == NULL) {
O_DPRINTF("Internal error... corrupt path.\n");
return (NULL);
}
*(tmp+1) = '\0';
strcat(source, scratch);
} else {
strcpy(source, scratch);
}
}
}
char *
g_get_physical_name(char *path)
{
struct stat stbuf;
char s[MAXPATHLEN];
char namebuf[MAXPATHLEN];
char savedir[MAXPATHLEN];
char *result = NULL;
DIR *dirp;
struct dirent *entp;
char *dev_name, *char_ptr;
struct stat sb;
int found_flag = 0;
int status = 0;
int i;
if (path == NULL) {
return (NULL);
}
(void) strcpy(s, path);
status = stat(s, &stbuf);
if (((status == -1) && (errno == ENOENT)) ||
((s[0] == 'c') && ((int)strlen(s) > 1) && ((int)strlen(s) < 5))) {
if ((s[0] != 'c') || ((int)strlen(s) <= 1) ||
((int)strlen(s) >= 5)) {
goto exit;
}
for (i = 1; i < (int)strlen(s); i++) {
if ((s[i] < '0') || (s[i] > '9')) {
goto exit;
}
}
P_DPRINTF(" g_get_physical_name: "
"Found entry of the form cN n=%s len=%d\n",
&s[1], strlen(s));
dev_name = g_zalloc(sizeof ("/dev/rdsk"));
sprintf((char *)dev_name, "/dev/rdsk");
if ((dirp = opendir(dev_name)) == NULL) {
g_destroy_data(dev_name);
goto exit;
}
while ((entp = readdir(dirp)) != NULL) {
if (strcmp(entp->d_name, ".") == 0 ||
strcmp(entp->d_name, "..") == 0)
continue;
if (entp->d_name[0] != 'c')
continue;
sprintf(namebuf, "%s/%s", dev_name, entp->d_name);
if ((lstat(namebuf, &sb)) < 0) {
L_WARNINGS(MSGSTR(55,
"Warning: Cannot stat %s\n"),
namebuf);
continue;
}
if (!S_ISLNK(sb.st_mode)) {
L_WARNINGS(MSGSTR(56,
"Warning: %s is not a symbolic link\n"),
namebuf);
continue;
}
if (strstr(entp->d_name, s) != NULL) {
if (atoi(&s[1]) == atoi(&entp->d_name[1])) {
P_DPRINTF(" g_get_physical_name: "
"Found entry in /dev/rdsk matching %s: %s\n",
s, entp->d_name);
found_flag = 1;
break;
}
}
}
closedir(dirp);
g_destroy_data(dev_name);
if (found_flag) {
result = g_get_physical_name_from_link(namebuf);
if (result == NULL) {
goto exit;
}
char_ptr = strrchr(result, '/');
*char_ptr = '\0';
(void) strcat(result, CTLR_POSTFIX);
}
goto exit;
}
if (status == -1)
goto exit;
if (lstat(s, &stbuf) == -1) {
L_WARNINGS(MSGSTR(134,
"%s: lstat() failed - %s\n"),
s, strerror(errno));
goto exit;
}
if (!S_ISLNK(stbuf.st_mode)) {
if (S_ISCHR(stbuf.st_mode) || S_ISDIR(stbuf.st_mode)) {
if (strstr(s, "/devices")) {
result = g_alloc_string(s);
} else {
if (getcwd(savedir,
sizeof (savedir)) == NULL) {
return (NULL);
}
if (s[0] == '.') {
strcat(savedir, &s[1]);
} else {
strcat(savedir, "/");
strcat(savedir, s);
}
result = g_alloc_string(savedir);
}
}
} else {
result = g_get_physical_name_from_link(path);
}
exit:
return (result);
}
int
g_object_open(char *path, int flag)
{
int fd = -1, retry = 0;
if (getenv("_LUX_O_DEBUG") != NULL) {
(void) printf(" Object_open:%s ", path);
if (flag & O_WRONLY) {
(void) printf("O_WRONLY,");
} else if (flag & O_RDWR) {
(void) printf("O_RDWR,");
} else {
(void) printf("O_RDONLY,");
}
if (flag & O_NDELAY) {
(void) printf("O_NDELAY,");
}
if (flag & O_APPEND) {
(void) printf("O_APPEND,");
}
if (flag & O_DSYNC) {
(void) printf("O_DSYNC,");
}
if (flag & O_RSYNC) {
(void) printf("O_RSYNC,");
}
if (flag & O_SYNC) {
(void) printf("O_SYNC,");
}
if (flag & O_NOCTTY) {
(void) printf("O_NOCTTY,");
}
if (flag & O_CREAT) {
(void) printf("O_CREAT,");
}
if (flag & O_EXCL) {
(void) printf("O_EXCL,");
}
if (flag & O_TRUNC) {
(void) printf("O_TRUNC,");
}
(void) printf("\n");
}
errno = 0;
fd = open(path, flag);
while (fd < 0 && retry++ < RETRY_OBJECT_OPEN && (
errno == EBUSY || errno == EAGAIN)) {
O_DPRINTF(" Object_open: Retried:%d %d %s\n",
retry, errno, path);
(void) usleep(WAIT_OBJECT_OPEN);
fd = open(path, flag);
}
if (fd < 0) {
O_DPRINTF(" Object_open: Open failed:%s\n", path);
}
return (fd);
}
char *
g_scsi_find_command_name(int cmd)
{
struct scsi_command_name {
int command;
char *name;
} scsi_command_names[29];
register struct scsi_command_name *c;
scsi_command_names[0].command = SCMD_TEST_UNIT_READY;
scsi_command_names[0].name = MSGSTR(61, "Test Unit Ready");
scsi_command_names[1].command = SCMD_FORMAT;
scsi_command_names[1].name = MSGSTR(110, "Format");
scsi_command_names[2].command = SCMD_REASSIGN_BLOCK;
scsi_command_names[2].name = MSGSTR(77, "Reassign Block");
scsi_command_names[3].command = SCMD_READ;
scsi_command_names[3].name = MSGSTR(27, "Read");
scsi_command_names[4].command = SCMD_WRITE;
scsi_command_names[4].name = MSGSTR(54, "Write");
scsi_command_names[5].command = SCMD_READ_G1;
scsi_command_names[5].name = MSGSTR(79, "Read(10 Byte)");
scsi_command_names[6].command = SCMD_WRITE_G1;
scsi_command_names[6].name = MSGSTR(51, "Write(10 Byte)");
scsi_command_names[7].command = SCMD_MODE_SELECT;
scsi_command_names[7].name = MSGSTR(97, "Mode Select");
scsi_command_names[8].command = SCMD_MODE_SENSE;
scsi_command_names[8].name = MSGSTR(95, "Mode Sense");
scsi_command_names[9].command = SCMD_REASSIGN_BLOCK;
scsi_command_names[9].name = MSGSTR(77, "Reassign Block");
scsi_command_names[10].command = SCMD_REQUEST_SENSE;
scsi_command_names[10].name = MSGSTR(74, "Request Sense");
scsi_command_names[11].command = SCMD_READ_DEFECT_LIST;
scsi_command_names[11].name = MSGSTR(80, "Read Defect List");
scsi_command_names[12].command = SCMD_INQUIRY;
scsi_command_names[12].name = MSGSTR(102, "Inquiry");
scsi_command_names[13].command = SCMD_WRITE_BUFFER;
scsi_command_names[13].name = MSGSTR(53, "Write Buffer");
scsi_command_names[14].command = SCMD_READ_BUFFER;
scsi_command_names[14].name = MSGSTR(82, "Read Buffer");
scsi_command_names[15].command = SCMD_START_STOP;
scsi_command_names[15].name = MSGSTR(67, "Start/Stop");
scsi_command_names[16].command = SCMD_RESERVE;
scsi_command_names[16].name = MSGSTR(72, "Reserve");
scsi_command_names[17].command = SCMD_RELEASE;
scsi_command_names[17].name = MSGSTR(75, "Release");
scsi_command_names[18].command = SCMD_MODE_SENSE_G1;
scsi_command_names[18].name = MSGSTR(94, "Mode Sense(10 Byte)");
scsi_command_names[19].command = SCMD_MODE_SELECT_G1;
scsi_command_names[19].name = MSGSTR(96, "Mode Select(10 Byte)");
scsi_command_names[20].command = SCMD_READ_CAPACITY;
scsi_command_names[20].name = MSGSTR(81, "Read Capacity");
scsi_command_names[21].command = SCMD_SYNC_CACHE;
scsi_command_names[21].name = MSGSTR(64, "Synchronize Cache");
scsi_command_names[22].command = SCMD_READ_DEFECT_LIST;
scsi_command_names[22].name = MSGSTR(80, "Read Defect List");
scsi_command_names[23].command = SCMD_GDIAG;
scsi_command_names[23].name = MSGSTR(108, "Get Diagnostic");
scsi_command_names[24].command = SCMD_SDIAG;
scsi_command_names[24].name = MSGSTR(69, "Set Diagnostic");
scsi_command_names[25].command = SCMD_PERS_RESERV_IN;
scsi_command_names[25].name = MSGSTR(10500, "Persistent Reserve In");
scsi_command_names[26].command = SCMD_PERS_RESERV_OUT;
scsi_command_names[26].name = MSGSTR(10501, "Persistent Reserve out");
scsi_command_names[27].command = SCMD_LOG_SENSE;
scsi_command_names[27].name = MSGSTR(10502, "Log Sense");
scsi_command_names[28].command = SCMD_UNKNOWN;
scsi_command_names[28].name = MSGSTR(25, "Unknown");
for (c = scsi_command_names; c->command != SCMD_UNKNOWN; c++)
if (c->command == cmd)
break;
return (c->name);
}
void
g_scsi_printerr(struct uscsi_cmd *ucmd, struct scsi_extended_sense *rq,
int rqlen, char msg_string[], char *err_string)
{
int blkno;
switch (rq->es_key) {
case KEY_NO_SENSE:
(void) sprintf(msg_string, MSGSTR(91, "No sense error"));
break;
case KEY_RECOVERABLE_ERROR:
(void) sprintf(msg_string, MSGSTR(76, "Recoverable error"));
break;
case KEY_NOT_READY:
(void) sprintf(msg_string,
MSGSTR(10503,
"Device Not ready."
" Error: Random Retry Failed: %s\n."),
err_string);
break;
case KEY_MEDIUM_ERROR:
(void) sprintf(msg_string, MSGSTR(99, "Medium error"));
break;
case KEY_HARDWARE_ERROR:
(void) sprintf(msg_string, MSGSTR(106, "Hardware error"));
break;
case KEY_ILLEGAL_REQUEST:
(void) sprintf(msg_string, MSGSTR(103, "Illegal request"));
break;
case KEY_UNIT_ATTENTION:
(void) sprintf(msg_string,
MSGSTR(10504,
"Unit attention."
"Error: Random Retry Failed.\n"));
break;
case KEY_WRITE_PROTECT:
(void) sprintf(msg_string, MSGSTR(52, "Write protect error"));
break;
case KEY_BLANK_CHECK:
(void) sprintf(msg_string, MSGSTR(131, "Blank check error"));
break;
case KEY_VENDOR_UNIQUE:
(void) sprintf(msg_string, MSGSTR(58, "Vendor unique error"));
break;
case KEY_COPY_ABORTED:
(void) sprintf(msg_string, MSGSTR(123, "Copy aborted error"));
break;
case KEY_ABORTED_COMMAND:
(void) sprintf(msg_string,
MSGSTR(10505,
"Aborted command."
" Error: Random Retry Failed.\n"));
break;
case KEY_EQUAL:
(void) sprintf(msg_string, MSGSTR(117, "Equal error"));
break;
case KEY_VOLUME_OVERFLOW:
(void) sprintf(msg_string, MSGSTR(57, "Volume overflow"));
break;
case KEY_MISCOMPARE:
(void) sprintf(msg_string, MSGSTR(98, "Miscompare error"));
break;
case KEY_RESERVED:
(void) sprintf(msg_string, MSGSTR(10506,
"Reserved value found"));
break;
default:
(void) sprintf(msg_string, MSGSTR(59, "Unknown error"));
break;
}
(void) sprintf(&msg_string[strlen(msg_string)],
MSGSTR(10507, " during: %s"),
g_scsi_find_command_name(ucmd->uscsi_cdb[0]));
if (rq->es_valid) {
blkno = (rq->es_info_1 << 24) | (rq->es_info_2 << 16) |
(rq->es_info_3 << 8) | rq->es_info_4;
(void) sprintf(&msg_string[strlen(msg_string)],
MSGSTR(49, ": block %d (0x%x)"), blkno, blkno);
}
(void) sprintf(&msg_string[strlen(msg_string)], "\n");
if (rq->es_add_len >= 6) {
(void) sprintf(&msg_string[strlen(msg_string)],
MSGSTR(132, " Additional sense: 0x%x ASC Qualifier: 0x%x\n"),
rq->es_add_code, rq->es_qual_code);
}
if (rq->es_key == KEY_ILLEGAL_REQUEST) {
string_dump(MSGSTR(47, " cmd: "), (uchar_t *)ucmd,
sizeof (struct uscsi_cmd), HEX_ONLY, msg_string);
string_dump(MSGSTR(48, " cdb: "),
(uchar_t *)ucmd->uscsi_cdb,
ucmd->uscsi_cdblen, HEX_ONLY, msg_string);
}
string_dump(MSGSTR(43, " sense: "),
(uchar_t *)rq, 8 + rq->es_add_len, HEX_ONLY,
msg_string);
rqlen = rqlen;
}
static void
string_dump(char *hdr, uchar_t *src, int nbytes, int format, char msg_string[])
{
int i;
int n;
char *p;
char s[256];
assert(format == HEX_ONLY || format == HEX_ASCII);
(void) strcpy(s, hdr);
for (p = s; *p; p++) {
*p = ' ';
}
p = hdr;
while (nbytes > 0) {
(void) sprintf(&msg_string[strlen(msg_string)],
"%s", p);
p = s;
n = min(nbytes, BYTES_PER_LINE);
for (i = 0; i < n; i++) {
(void) sprintf(&msg_string[strlen(msg_string)],
"%02x ",
src[i] & 0xff);
}
if (format == HEX_ASCII) {
for (i = BYTES_PER_LINE-n; i > 0; i--) {
(void) sprintf(&msg_string[strlen(msg_string)],
" ");
}
(void) sprintf(&msg_string[strlen(msg_string)],
" ");
for (i = 0; i < n; i++) {
(void) sprintf(&msg_string[strlen(msg_string)],
"%c",
isprint(src[i]) ? src[i] : '.');
}
}
(void) sprintf(&msg_string[strlen(msg_string)], "\n");
nbytes -= n;
src += n;
}
}
void *
g_zalloc(int count)
{
void *ptr;
ptr = (void *) calloc(1, (unsigned)count);
A_DPRINTF(" g_zalloc: Allocated 0x%x bytes "
"at 0x%x\n", count, ptr);
return (ptr);
}
int
g_i18n_catopen(void)
{
static int fileopen = 0;
static mutex_t mp;
if (setlocale(LC_ALL, "") == NULL) {
(void) fprintf(stderr,
"Cannot operate in the locale requested. "
"Continuing in the default C locale\n");
}
if (mutex_lock(&mp) != 0) {
return (-1);
}
if (!fileopen) {
l_catd = catopen("a5k_g_fc_i18n_cat", NL_CAT_LOCALE);
if (l_catd == (nl_catd)-1) {
(void) mutex_unlock(&mp);
return (-1);
}
fileopen = 1;
}
(void) mutex_unlock(&mp);
return (0);
}
#define GetMatch(s_ptr) \
for (found = 0, search_arr_ptr = s_ptr; \
search_arr_ptr->string != NULL; \
search_arr_ptr++) {\
if (strstr(path_ptr, search_arr_ptr->string) != NULL) {\
found = 1;\
break;\
}\
}
uint_t
g_get_path_type(char *path)
{
uint_t path_type = 0;
int i = 0, pathcnt = 1;
char *path_ptr = path;
struct str_type *search_arr_ptr;
char found;
char drvr_path1[MAXPATHLEN];
mp_pathlist_t pathlist;
int p_on = 0, p_st = 0;
if (strncmp(path_ptr, DEV_PREFIX, DEV_PREFIX_LEN) ||
(strlen(path_ptr) == DEV_PREFIX_LEN)) {
return (0);
}
if (strstr(path, SCSI_VHCI)) {
(void) strcpy(drvr_path1, path);
if (g_get_pathlist(drvr_path1, &pathlist)) {
return (0);
}
pathcnt = pathlist.path_count;
p_on = p_st = 0;
for (i = 0; i < pathcnt; i++) {
if (pathlist.path_info[i].path_state < MAXPATHSTATE) {
if (pathlist.path_info[i].path_state ==
MDI_PATHINFO_STATE_ONLINE) {
p_on = i;
break;
} else if (pathlist.path_info[i].path_state ==
MDI_PATHINFO_STATE_STANDBY) {
p_st = i;
}
}
}
if (pathlist.path_info[p_on].path_state ==
MDI_PATHINFO_STATE_ONLINE) {
(void) strcpy(drvr_path1,
pathlist.path_info[p_on].path_hba);
} else {
(void) strcpy(drvr_path1,
pathlist.path_info[p_st].path_hba);
}
free(pathlist.path_info);
path_ptr = drvr_path1;
}
GetMatch(ValidBusStrings);
if (found == 0) {
return (0);
}
GetMatch(ValidFCAstrings);
if (found != 0) {
path_type |= search_arr_ptr->type;
}
GetMatch(ValidXportStrings);
if (found == 0) {
return (path_type);
} else {
if ((search_arr_ptr->type == FC_GEN_XPORT) &&
(!(path_type & FC_FCA_MASK))) {
path_type |= FC_FCA_MASK;
}
}
path_type |= search_arr_ptr->type;
if (((path_type & (FC4_FCA_MASK | FC_XPORT_MASK)) ==
path_type) ||
((path_type & (FC_FCA_MASK | FC4_XPORT_MASK)) ==
path_type)) {
path_type = 0;
}
return (path_type);
}
int
g_get_port_path(char *portdrvr, portlist_t *portlist)
{
di_node_t root;
di_node_t node;
di_minor_t minor_node;
char hbapathfound[MAXPATHLEN];
char *tmppath;
struct stat buf;
if ((portdrvr == NULL) || (portlist == NULL)) {
return (L_INVALID_ARG);
}
root = di_init("/", DINFOCPYALL);
if (root == DI_NODE_NIL) {
return (L_DEV_SNAPSHOT_FAILED);
}
node = di_drv_first_node(portdrvr, root);
if (node == DI_NODE_NIL) {
(void) di_fini(root);
if (errno == EINVAL)
return (L_PORT_DRIVER_NOT_FOUND);
else
return (L_PHYS_PATH_NOT_FOUND);
}
while (node) {
minor_node = di_minor_next(node, DI_MINOR_NIL);
while (minor_node) {
if (di_minor_nodetype(minor_node) &&
(strcmp(di_minor_nodetype(minor_node),
DDI_NT_NEXUS) &&
strcmp(di_minor_nodetype(minor_node),
DDI_PSEUDO))) {
minor_node = di_minor_next(node, minor_node);
continue;
}
strcpy(hbapathfound, "/devices");
tmppath = di_devfs_path(node);
strcat(hbapathfound, tmppath);
(void) free(tmppath);
strcat(hbapathfound, ":");
strcat(hbapathfound, di_minor_name(minor_node));
if ((stat(hbapathfound, (struct stat *)&buf)) < 0) {
(void) di_fini(root);
return (L_STAT_ERROR);
}
if ((portlist->hbacnt > MAX_HBA_PORT - 1) ||
((portlist->physpath[portlist->hbacnt] =
(char *)malloc(MAXPATHLEN)) == NULL)) {
(void) di_fini(root);
return (L_MALLOC_FAILED);
}
strcpy(portlist->physpath[portlist->hbacnt],
hbapathfound);
portlist->hbacnt++;
minor_node = di_minor_next(node, minor_node);
}
node = di_drv_next_node(node);
}
(void) di_fini(root);
return (0);
}
void
g_free_portlist(portlist_t *portlist)
{
int x = 0;
if (portlist == NULL) {
return;
}
for (x = 0; x < portlist->hbacnt; x++) {
if (portlist->physpath[x] != NULL) {
free(portlist->physpath[x]);
}
}
}
boolean_t
g_enclDiskChk(char *vid, char *pid)
{
int i;
for (i = 0; enclDiskTbl[i].vid; i++) {
if ((strncmp(vid, enclDiskTbl[i].vid,
strlen(enclDiskTbl[i].vid)) == 0) &&
(strncmp(pid, enclDiskTbl[i].pid,
strlen(enclDiskTbl[i].pid)) == 0)) {
return (B_TRUE);
}
}
return (B_FALSE);
}