summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNattuvetty Bhavyan <Nattuvetty.Bhavyan@Sun.COM>2009-07-17 11:20:16 -0700
committerNattuvetty Bhavyan <Nattuvetty.Bhavyan@Sun.COM>2009-07-17 11:20:16 -0700
commit2f624233c43c1f4fe0d930648d6ece6fffe7aa49 (patch)
treeacf41e00b0b469235feff513fbd6f68acd96fb3e
parentccd826d5ed39105e7097be686438edfdba1506be (diff)
downloadillumos-gate-2f624233c43c1f4fe0d930648d6ece6fffe7aa49.tar.gz
6812611 Add Management Network Address VPD (85h) support to sbd
6856759 groupMemberListIoctl() frees memory it hasn't allocated 6855914 fw_63 iSCSI failing SCSI compliance WHQL test 6840755 page_length for VPD page 80 isn't set for all conditions in sbd inquiry handler
-rw-r--r--usr/src/cmd/stmfadm/stmfadm.c72
-rw-r--r--usr/src/lib/libstmf/common/libstmf.h1
-rw-r--r--usr/src/lib/libstmf/common/libstmf_impl.h2
-rw-r--r--usr/src/lib/libstmf/common/stmf.c67
-rw-r--r--usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c75
-rw-r--r--usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c217
-rw-r--r--usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h8
-rw-r--r--usr/src/uts/common/sys/stmf_sbd_ioctl.h10
8 files changed, 388 insertions, 64 deletions
diff --git a/usr/src/cmd/stmfadm/stmfadm.c b/usr/src/cmd/stmfadm/stmfadm.c
index f102aa47b2..c08394124f 100644
--- a/usr/src/cmd/stmfadm/stmfadm.c
+++ b/usr/src/cmd/stmfadm/stmfadm.c
@@ -126,13 +126,15 @@ static int convertCharToPropId(char *, uint32_t *);
#define COMPANY_ID "OUI"
#define BLOCK_SIZE "BLK"
#define SERIAL_NUMBER "SERIAL"
+#define MGMT_URL "MGMT-URL"
#define MODIFY_HELP "\n"\
"Description: Modify properties of a logical unit. \n" \
"Valid properties for -p, --lu-prop are: \n" \
-" alias - alias for logical unit (up to 255 chars)\n" \
-" wcd - write cache disabled (true, false)\n" \
-" wp - write protect (true, false)\n\n" \
+" alias - alias for logical unit (up to 255 chars)\n" \
+" mgmt-url - Management URL address\n" \
+" wcd - write cache disabled (true, false)\n" \
+" wp - write protect (true, false)\n\n" \
"-f alters the meaning of the operand to be a file name\n" \
"rather than a LU name. This allows for modification\n" \
"of a logical unit that is not yet imported into stmf\n"
@@ -140,17 +142,18 @@ static int convertCharToPropId(char *, uint32_t *);
#define CREATE_HELP "\n"\
"Description: Create a logical unit. \n" \
"Valid properties for -p, --lu-prop are: \n" \
-" alias - alias for logical unit (up to 255 chars)\n" \
-" blk - block size in bytes in 2^n\n" \
-" guid - 32 ascii hex characters in NAA format \n" \
-" meta - separate meta data file name\n" \
-" oui - organizational unique identifier\n" \
-" 6 ascii hex characters of valid format\n" \
-" pid - product identifier (up to 16 chars)\n" \
-" serial- serial number (up to 252 chars)\n" \
-" vid - vendor identifier (up to 8 chars)\n" \
-" wp - write protect (true, false)\n" \
-" wcd - write cache disabled (true, false)\n"
+" alias - alias for logical unit (up to 255 chars)\n" \
+" blk - block size in bytes in 2^n\n" \
+" guid - 32 ascii hex characters in NAA format \n" \
+" meta - separate meta data file name\n" \
+" mgmt-url - Management URL address\n" \
+" oui - organizational unique identifier\n" \
+" 6 ascii hex characters of valid format\n" \
+" pid - product identifier (up to 16 chars)\n" \
+" serial - serial number (up to 252 chars)\n" \
+" vid - vendor identifier (up to 8 chars)\n" \
+" wcd - write cache disabled (true, false)\n" \
+" wp - write protect (true, false)\n"
#define ADD_VIEW_HELP "\n"\
"Description: Add a view entry to a logical unit. \n" \
"A view entry is comprised of three elements; the \n" \
@@ -991,14 +994,7 @@ modifyLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
switch (options->optval) {
case 'p':
prop = strtok_r(options->optarg, "=", &lasts);
- if ((propVal = strtok_r(NULL, "=", &lasts))
- == NULL) {
- (void) fprintf(stderr, "%s: %s: %s\n",
- cmdName, options->optarg,
- gettext("invalid property specifier"
- "- prop=val\n"));
- return (1);
- }
+ propVal = strtok_r(NULL, "=", &lasts);
ret = convertCharToPropId(prop, &propId);
if (ret != 0) {
(void) fprintf(stderr, "%s: %s: %s\n",
@@ -1007,8 +1003,22 @@ modifyLuFunc(int operandLen, char *operands[], cmdOptions_t *options,
prop);
return (1);
}
- if (callModify(fname, &inGuid, propId, propVal,
- prop) != 0) {
+ if (propVal == NULL &&
+ propId != STMF_LU_PROP_MGMT_URL) {
+ (void) fprintf(stderr, "%s: %s: %s\n",
+ cmdName, options->optarg,
+ gettext("invalid property specifier"
+ "- prop=val\n"));
+ return (1);
+ }
+ if (propVal == NULL) {
+ ret = callModify(fname, &inGuid, propId,
+ "", prop);
+ } else {
+ ret = callModify(fname, &inGuid, propId,
+ propVal, prop);
+ }
+ if (ret != 0) {
return (1);
}
break;
@@ -1270,6 +1280,8 @@ convertCharToPropId(char *prop, uint32_t *propId)
*propId = STMF_LU_PROP_COMPANY_ID;
} else if (strcasecmp(prop, META_FILE) == 0) {
*propId = STMF_LU_PROP_META_FILENAME;
+ } else if (strcasecmp(prop, MGMT_URL) == 0) {
+ *propId = STMF_LU_PROP_MGMT_URL;
} else {
return (1);
}
@@ -2092,6 +2104,18 @@ printExtLuProps(stmfGuid *guid)
ret++;
}
+ stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_MGMT_URL, propVal,
+ &propValSize);
+ (void) printf(PROPS_FORMAT, "Management URL");
+ if (stmfRet == STMF_STATUS_SUCCESS) {
+ (void) printf("%s\n", propVal);
+ } else if (stmfRet == STMF_ERROR_NO_PROP) {
+ (void) printf("not set\n");
+ } else {
+ (void) printf("<error retrieving property>\n");
+ ret++;
+ }
+
stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_VID, propVal,
&propValSize);
(void) printf(PROPS_FORMAT, "Vendor ID");
diff --git a/usr/src/lib/libstmf/common/libstmf.h b/usr/src/lib/libstmf/common/libstmf.h
index 7394e00490..cf926e637b 100644
--- a/usr/src/lib/libstmf/common/libstmf.h
+++ b/usr/src/lib/libstmf/common/libstmf.h
@@ -129,6 +129,7 @@ enum {
STMF_LU_PROP_FILENAME,
STMF_LU_PROP_GUID,
STMF_LU_PROP_META_FILENAME,
+ STMF_LU_PROP_MGMT_URL,
STMF_LU_PROP_NEW,
STMF_LU_PROP_SIZE,
STMF_LU_PROP_WRITE_PROTECT,
diff --git a/usr/src/lib/libstmf/common/libstmf_impl.h b/usr/src/lib/libstmf/common/libstmf_impl.h
index cd32c932e4..5c6e0ae9b3 100644
--- a/usr/src/lib/libstmf/common/libstmf_impl.h
+++ b/usr/src/lib/libstmf/common/libstmf_impl.h
@@ -55,6 +55,8 @@ typedef struct _diskResource {
uint32_t companyId;
boolean_t luAliasValid;
char luAlias[256];
+ boolean_t luMgmtUrlValid;
+ char luMgmtUrl[1024];
boolean_t vidValid;
char vid[8];
boolean_t pidValid;
diff --git a/usr/src/lib/libstmf/common/stmf.c b/usr/src/lib/libstmf/common/stmf.c
index b75fdd4e38..7e8fa6c083 100644
--- a/usr/src/lib/libstmf/common/stmf.c
+++ b/usr/src/lib/libstmf/common/stmf.c
@@ -1078,6 +1078,7 @@ createDiskLu(diskResource *disk, stmfGuid *createdGuid)
int metaFileNameLen = 0;
int serialNumLen = 0;
int luAliasLen = 0;
+ int luMgmtUrlLen = 0;
int sluBufSize = 0;
int bufOffset = 0;
int fd = 0;
@@ -1117,6 +1118,11 @@ createDiskLu(diskResource *disk, stmfGuid *createdGuid)
sluBufSize += luAliasLen + 1;
}
+ if (disk->luMgmtUrlValid) {
+ luMgmtUrlLen = strlen(disk->luMgmtUrl);
+ sluBufSize += luMgmtUrlLen + 1;
+ }
+
/*
* 8 is the size of the buffer set aside for
* concatenation of variable length fields
@@ -1161,6 +1167,14 @@ createDiskLu(diskResource *disk, stmfGuid *createdGuid)
bufOffset += luAliasLen + 1;
}
+ if (disk->luMgmtUrlValid) {
+ sbdLu->slu_mgmt_url_valid = 1;
+ sbdLu->slu_mgmt_url_off = bufOffset;
+ bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]),
+ luMgmtUrlLen + 1);
+ bufOffset += luMgmtUrlLen + 1;
+ }
+
if (disk->luSizeValid) {
sbdLu->slu_lu_size_valid = 1;
sbdLu->slu_lu_size = disk->luSize;
@@ -1665,6 +1679,7 @@ validateModifyDiskProp(uint32_t prop)
switch (prop) {
case STMF_LU_PROP_ALIAS:
case STMF_LU_PROP_SIZE:
+ case STMF_LU_PROP_MGMT_URL:
case STMF_LU_PROP_WRITE_PROTECT:
case STMF_LU_PROP_WRITE_CACHE_DISABLE:
return (STMF_STATUS_SUCCESS);
@@ -1680,6 +1695,7 @@ modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
{
int ret = STMF_STATUS_SUCCESS;
int luAliasLen = 0;
+ int luMgmtUrlLen = 0;
int mluBufSize = 0;
int bufOffset = 0;
int fd = 0;
@@ -1710,6 +1726,11 @@ modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
mluBufSize += luAliasLen + 1;
}
+ if (disk->luMgmtUrlValid) {
+ luMgmtUrlLen = strlen(disk->luMgmtUrl);
+ mluBufSize += luMgmtUrlLen + 1;
+ }
+
/*
* 8 is the size of the buffer set aside for
* concatenation of variable length fields
@@ -1732,6 +1753,14 @@ modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
bufOffset += luAliasLen + 1;
}
+ if (disk->luMgmtUrlValid) {
+ sbdLu->mlu_mgmt_url_valid = 1;
+ sbdLu->mlu_mgmt_url_off = bufOffset;
+ bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
+ luMgmtUrlLen + 1);
+ bufOffset += luMgmtUrlLen + 1;
+ }
+
if (disk->luSizeValid) {
sbdLu->mlu_lu_size_valid = 1;
sbdLu->mlu_lu_size = disk->luSize;
@@ -2123,6 +2152,16 @@ loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
diskLu->serialNum, sbdProps->slp_serial_size);
}
+ if (sbdProps->slp_mgmt_url_valid) {
+ diskLu->luMgmtUrlValid = B_TRUE;
+ if (strlcpy(diskLu->luMgmtUrl,
+ (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
+ sizeof (diskLu->luMgmtUrl)) >=
+ sizeof (diskLu->luMgmtUrl)) {
+ return (STMF_STATUS_ERROR);
+ }
+ }
+
if (sbdProps->slp_alias_valid) {
diskLu->luAliasValid = B_TRUE;
if (strlcpy(diskLu->luAlias,
@@ -2250,6 +2289,16 @@ getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
return (STMF_ERROR_INVALID_ARG);
}
break;
+ case STMF_LU_PROP_MGMT_URL:
+ if (diskLu->luMgmtUrlValid == B_FALSE) {
+ return (STMF_ERROR_NO_PROP);
+ }
+ if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
+ *propLen)) >= *propLen) {
+ *propLen = reqLen + 1;
+ return (STMF_ERROR_INVALID_ARG);
+ }
+ break;
case STMF_LU_PROP_GUID:
if (diskLu->luGuidValid == B_FALSE) {
return (STMF_ERROR_NO_PROP);
@@ -2463,6 +2512,14 @@ setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
}
diskLu->luMetaFileNameValid = B_TRUE;
break;
+ case STMF_LU_PROP_MGMT_URL:
+ if ((strlcpy(diskLu->luMgmtUrl, propVal,
+ sizeof (diskLu->luMgmtUrl))) >=
+ sizeof (diskLu->luMgmtUrl)) {
+ return (STMF_ERROR_INVALID_PROPSIZE);
+ }
+ diskLu->luMgmtUrlValid = B_TRUE;
+ break;
case STMF_LU_PROP_PID:
if ((propSize = strlen(propVal)) >
sizeof (diskLu->pid)) {
@@ -3076,9 +3133,8 @@ groupListIoctl(stmfGroupList **groupList, int groupType)
}
(*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
- bcopy(iGroupList->name, (*groupList)->name[i],
+ bcopy(iGroupList[i].name, (*groupList)->name[i],
sizeof (stmfGroupName));
- iGroupList++;
}
done:
@@ -3224,10 +3280,9 @@ groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
(*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
(*groupProps)->name[i].identLength =
- iGroupMembers->ident_size;
- bcopy(iGroupMembers->ident, (*groupProps)->name[i].ident,
- iGroupMembers->ident_size);
- iGroupMembers++;
+ iGroupMembers[i].ident_size;
+ bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
+ iGroupMembers[i].ident_size);
}
done:
diff --git a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
index dbcf057abb..a837923a9e 100644
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c
@@ -1066,6 +1066,9 @@ sbd_write_lu_info(sbd_lu_t *sl)
if (sl->sl_alias) {
s += strlen(sl->sl_alias) + 1;
}
+ if (sl->sl_mgmt_url) {
+ s += strlen(sl->sl_mgmt_url) + 1;
+ }
sli = (sbd_lu_info_1_1_t *)kmem_zalloc(sizeof (*sli) + s, KM_SLEEP);
p = sli->sli_buf;
if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) {
@@ -1092,6 +1095,13 @@ sbd_write_lu_info(sbd_lu_t *sl)
sli->sli_flags |= SLI_ALIAS_VALID;
p += strlen(sl->sl_alias) + 1;
}
+ if (sl->sl_mgmt_url) {
+ (void) strcpy((char *)p, sl->sl_mgmt_url);
+ sli->sli_mgmt_url_offset =
+ (uintptr_t)p - (uintptr_t)sli->sli_buf;
+ sli->sli_flags |= SLI_MGMT_URL_VALID;
+ p += strlen(sl->sl_mgmt_url) + 1;
+ }
if (sl->sl_flags & SL_WRITE_PROTECTED) {
sli->sli_flags |= SLI_WRITE_PROTECTED;
}
@@ -1338,6 +1348,9 @@ sbd_close_delete_lu(sbd_lu_t *sl, int ret)
if (sl->sl_alias_alloc_size) {
kmem_free(sl->sl_alias, sl->sl_alias_alloc_size);
}
+ if (sl->sl_mgmt_url_alloc_size) {
+ kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size);
+ }
stmf_free(sl->sl_lu);
return (ret);
}
@@ -1368,6 +1381,8 @@ sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
(slu->slu_data_fname_off >= sz) ||
((slu->slu_alias_valid) &&
(slu->slu_alias_off >= sz)) ||
+ ((slu->slu_mgmt_url_valid) &&
+ (slu->slu_mgmt_url_off >= sz)) ||
((slu->slu_serial_valid) &&
((slu->slu_serial_off + slu->slu_serial_size) >= sz))) {
return (EINVAL);
@@ -1385,6 +1400,9 @@ sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
if (slu->slu_alias_valid) {
alloc_sz += strlen(namebuf + slu->slu_alias_off) + 1;
}
+ if (slu->slu_mgmt_url_valid) {
+ alloc_sz += strlen(namebuf + slu->slu_mgmt_url_off) + 1;
+ }
if (slu->slu_serial_valid) {
alloc_sz += slu->slu_serial_size;
}
@@ -1428,6 +1446,11 @@ sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz,
(void) strcpy(p, namebuf + slu->slu_alias_off);
p += strlen(sl->sl_alias) + 1;
}
+ if (slu->slu_mgmt_url_valid) {
+ sl->sl_mgmt_url = p;
+ (void) strcpy(p, namebuf + slu->slu_mgmt_url_off);
+ p += strlen(sl->sl_mgmt_url) + 1;
+ }
if (slu->slu_serial_valid) {
sl->sl_serial_no = (uint8_t *)p;
bcopy(namebuf + slu->slu_serial_off, sl->sl_serial_no,
@@ -1784,6 +1807,8 @@ sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret,
(sli->sli_meta_fname_offset > sli_buf_sz)) ||
((sli->sli_flags & SLI_DATA_FNAME_VALID) &&
(sli->sli_data_fname_offset > sli_buf_sz)) ||
+ ((sli->sli_flags & SLI_MGMT_URL_VALID) &&
+ (sli->sli_mgmt_url_offset > sli_buf_sz)) ||
((sli->sli_flags & SLI_SERIAL_VALID) &&
((sli->sli_serial_offset + sli->sli_serial_size) > sli_buf_sz)) ||
((sli->sli_flags & SLI_ALIAS_VALID) &&
@@ -1855,6 +1880,14 @@ sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret,
(void) strcpy(sl->sl_alias, (char *)sli_buf_copy +
sli->sli_alias_offset);
}
+ if (sli->sli_flags & SLI_MGMT_URL_VALID) {
+ sl->sl_mgmt_url_alloc_size = strlen((char *)sli_buf_copy +
+ sli->sli_mgmt_url_offset) + 1;
+ sl->sl_mgmt_url = kmem_alloc(sl->sl_mgmt_url_alloc_size,
+ KM_SLEEP);
+ (void) strcpy(sl->sl_mgmt_url, (char *)sli_buf_copy +
+ sli->sli_mgmt_url_offset);
+ }
if (sli->sli_flags & SLI_WRITE_PROTECTED) {
sl->sl_flags |= SL_WRITE_PROTECTED;
}
@@ -1958,7 +1991,7 @@ int
sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret)
{
sbd_lu_t *sl = NULL;
- int alias_sz;
+ uint16_t alias_sz;
int ret = 0;
sbd_it_data_t *it;
sbd_status_t sret;
@@ -1982,6 +2015,8 @@ sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret)
/* Lets validate offsets */
if (((mlu->mlu_alias_valid) &&
(mlu->mlu_alias_off >= sz)) ||
+ ((mlu->mlu_mgmt_url_valid) &&
+ (mlu->mlu_mgmt_url_off >= sz)) ||
(mlu->mlu_by_fname) &&
(mlu->mlu_fname_off >= sz)) {
return (EINVAL);
@@ -2088,6 +2123,35 @@ sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret)
mutex_exit(&sl->sl_lock);
}
+ if (mlu->mlu_mgmt_url_valid) {
+ uint16_t url_sz;
+
+ url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off);
+ if (url_sz > 0)
+ url_sz++;
+
+ mutex_enter(&sl->sl_lock);
+ if (sl->sl_mgmt_url_alloc_size > 0 &&
+ (url_sz == 0 || sl->sl_mgmt_url_alloc_size < url_sz)) {
+ kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size);
+ sl->sl_mgmt_url = NULL;
+ sl->sl_mgmt_url_alloc_size = 0;
+ }
+ if (url_sz > 0) {
+ if (sl->sl_mgmt_url_alloc_size == 0) {
+ sl->sl_mgmt_url = kmem_alloc(url_sz, KM_SLEEP);
+ sl->sl_mgmt_url_alloc_size = url_sz;
+ }
+ (void) strcpy(sl->sl_mgmt_url, (char *)mlu->mlu_buf +
+ mlu->mlu_mgmt_url_off);
+ }
+ for (it = sl->sl_it_list; it != NULL;
+ it = it->sbd_it_next) {
+ it->sbd_it_ua_conditions |=
+ SBD_UA_MODE_PARAMETERS_CHANGED;
+ }
+ mutex_exit(&sl->sl_lock);
+ }
if (mlu->mlu_write_protected_valid) {
mutex_enter(&sl->sl_lock);
@@ -2368,6 +2432,9 @@ sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
sz += strlen(sl->sl_alias) + 1;
}
+ if (sl->sl_mgmt_url) {
+ sz += strlen(sl->sl_mgmt_url) + 1;
+ }
bzero(oslp, sizeof (*oslp) - 8);
oslp->slp_buf_size_needed = sz;
@@ -2404,6 +2471,12 @@ sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz,
(void) strcpy((char *)&oslp->slp_buf[off], sl->sl_alias);
off += strlen(sl->sl_alias) + 1;
}
+ if (sl->sl_mgmt_url) {
+ oslp->slp_mgmt_url_valid = 1;
+ oslp->slp_mgmt_url_off = off;
+ (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_mgmt_url);
+ off += strlen(sl->sl_mgmt_url) + 1;
+ }
if (sl->sl_serial_no_size) {
oslp->slp_serial_off = off;
bcopy(sl->sl_serial_no, &oslp->slp_buf[off],
diff --git a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c
index 35f1847b96..76c8a8e7bf 100644
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c
@@ -1070,15 +1070,56 @@ mode_sel_param_field_err:
STMF_SAA_INVALID_FIELD_IN_PARAM_LIST);
}
+/*
+ * This function parse through a string, passed to it as a pointer to a string,
+ * by adjusting the pointer to the first non-space character and returns
+ * the count/length of the first bunch of non-space characters. Multiple
+ * Management URLs are stored as a space delimited string in sl_mgmt_url
+ * field of sbd_lu_t. This function is used to retrieve one url at a time.
+ *
+ * i/p : pointer to pointer to a url string
+ * o/p : Adjust the pointer to the url to the first non white character
+ * and returns the length of the URL
+ */
+uint16_t
+sbd_parse_mgmt_url(char **url_addr) {
+ uint16_t url_length = 0;
+ char *url;
+ url = *url_addr;
+
+ while (*url != '\0') {
+ if (*url == ' ' || *url == '\t' || *url == '\n') {
+ (*url_addr)++;
+ url = *url_addr;
+ } else {
+ break;
+ }
+ }
+
+ while (*url != '\0') {
+ if (*url == ' ' || *url == '\t' ||
+ *url == '\n' || *url == '\0') {
+ break;
+ }
+ url++;
+ url_length++;
+ }
+ return (url_length);
+}
+
void
-sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
- uint8_t *p, int bsize)
+sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
{
sbd_lu_t *sl = (sbd_lu_t *)task->task_lu->lu_provider_private;
uint8_t *cdbp = (uint8_t *)&task->task_cdb[0];
- uint32_t cmd_size;
- uint8_t page_length;
+ uint8_t *p;
uint8_t byte0;
+ uint8_t page_length;
+ uint16_t bsize = 512;
+ uint16_t cmd_size;
+ uint32_t xfer_size = 4;
+ uint32_t mgmt_url_size = 0;
+
byte0 = DTYPE_DIRECT;
/*
@@ -1096,7 +1137,7 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
* return success.
*/
- cmd_size = (((uint32_t)cdbp[3]) << 8) | cdbp[4];
+ cmd_size = (((uint16_t)cdbp[3]) << 8) | cdbp[4];
if (cmd_size == 0) {
task->task_cmd_xfer_length = 0;
@@ -1108,15 +1149,23 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
return;
}
+ if (sl->sl_mgmt_url) {
+ mgmt_url_size = strlen(sl->sl_mgmt_url);
+ }
+
/*
* Standard inquiry
*/
if ((cdbp[1] & 1) == 0) {
- struct scsi_inquiry *inq = (struct scsi_inquiry *)p;
+ int i;
+ struct scsi_inquiry *inq;
+
+ p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP);
+ inq = (struct scsi_inquiry *)p;
- page_length = 31;
- bzero(inq, page_length + 5);
+ page_length = 69;
+ xfer_size = page_length + 5;
inq->inq_dtype = DTYPE_DIRECT;
inq->inq_ansi = 5; /* SPC-3 */
@@ -1124,7 +1173,7 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
inq->inq_rdf = 2; /* Response data format for SPC-3 */
inq->inq_len = page_length;
- inq->inq_tpgs = 1;
+ inq->inq_tpgs = TPGS_FAILOVER_IMPLICIT;
inq->inq_cmdque = 1;
if (sl->sl_flags & SL_VID_VALID) {
@@ -1145,8 +1194,59 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
bcopy(sbd_revision, inq->inq_revision, 4);
}
+ /* Adding Version Descriptors */
+ i = 0;
+ /* SAM-3 no version */
+ inq->inq_vd[i].inq_vd_msb = 0x00;
+ inq->inq_vd[i].inq_vd_lsb = 0x60;
+ i++;
+
+ /* transport */
+ switch (task->task_lport->lport_id->protocol_id) {
+ case PROTOCOL_FIBRE_CHANNEL:
+ inq->inq_vd[i].inq_vd_msb = 0x09;
+ inq->inq_vd[i].inq_vd_lsb = 0x00;
+ i++;
+ break;
+
+ case PROTOCOL_PARALLEL_SCSI:
+ case PROTOCOL_SSA:
+ case PROTOCOL_IEEE_1394:
+ /* Currently no claims of conformance */
+ break;
+
+ case PROTOCOL_SRP:
+ inq->inq_vd[i].inq_vd_msb = 0x09;
+ inq->inq_vd[i].inq_vd_lsb = 0x40;
+ i++;
+ break;
+
+ case PROTOCOL_iSCSI:
+ inq->inq_vd[i].inq_vd_msb = 0x09;
+ inq->inq_vd[i].inq_vd_lsb = 0x60;
+ i++;
+ break;
+
+ case PROTOCOL_SAS:
+ case PROTOCOL_ADT:
+ case PROTOCOL_ATAPI:
+ default:
+ /* Currently no claims of conformance */
+ break;
+ }
+
+ /* SPC-3 no version */
+ inq->inq_vd[i].inq_vd_msb = 0x03;
+ inq->inq_vd[i].inq_vd_lsb = 0x00;
+ i++;
+
+ /* SBC-2 no version */
+ inq->inq_vd[i].inq_vd_msb = 0x03;
+ inq->inq_vd[i].inq_vd_lsb = 0x20;
+
sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
- min(cmd_size, page_length + 5));
+ min(cmd_size, xfer_size));
+ kmem_free(p, bsize);
return;
}
@@ -1155,18 +1255,30 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
* EVPD handling
*/
+ /* Default 512 bytes may not be enough, increase bsize if necessary */
+ if (cdbp[2] == 0x83 || cdbp[2] == 0x85) {
+ if (bsize < cmd_size)
+ bsize = cmd_size;
+ }
+ p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP);
+
switch (cdbp[2]) {
case 0x00:
- page_length = 4;
-
- bzero(p, page_length + 4);
+ page_length = 4 + (mgmt_url_size ? 1 : 0);
p[0] = byte0;
p[3] = page_length;
- p[5] = 0x80;
- p[6] = 0x83;
- p[7] = 0x86;
-
+ /* Supported VPD pages in ascending order */
+ {
+ uint8_t i = 5;
+
+ p[i++] = 0x80;
+ p[i++] = 0x83;
+ if (mgmt_url_size != 0)
+ p[i++] = 0x85;
+ p[i++] = 0x86;
+ }
+ xfer_size = page_length + 4;
break;
case 0x80:
@@ -1174,25 +1286,74 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
page_length = sl->sl_serial_no_size;
bcopy(sl->sl_serial_no, p + 4, sl->sl_serial_no_size);
} else {
+ /* if no serial num is specified set 4 spaces */
+ page_length = 4;
bcopy(" ", p + 4, 4);
}
p[0] = byte0;
p[1] = 0x80;
p[3] = page_length;
+ xfer_size = page_length + 4;
break;
case 0x83:
-
- page_length = stmf_scsilib_prepare_vpd_page83(task, p,
+ xfer_size = stmf_scsilib_prepare_vpd_page83(task, p,
bsize, byte0, STMF_VPD_LU_ID|STMF_VPD_TARGET_ID|
- STMF_VPD_TP_GROUP|STMF_VPD_RELATIVE_TP_ID) - 4;
+ STMF_VPD_TP_GROUP|STMF_VPD_RELATIVE_TP_ID);
break;
+ case 0x85:
+ if (mgmt_url_size == 0) {
+ stmf_scsilib_send_status(task, STATUS_CHECK,
+ STMF_SAA_INVALID_FIELD_IN_CDB);
+ kmem_free(p, bsize);
+ return;
+ }
+ {
+ uint16_t idx, newidx, sz, url_size;
+ char *url;
+
+ p[0] = byte0;
+ p[1] = 0x85;
+
+ idx = 4;
+ url = sl->sl_mgmt_url;
+ url_size = sbd_parse_mgmt_url(&url);
+ /* Creating Network Service Descriptors */
+ while (url_size != 0) {
+ /* Null terminated and 4 Byte aligned */
+ sz = url_size + 1;
+ sz += (sz % 4) ? 4 - (sz % 4) : 0;
+ newidx = idx + sz + 4;
+
+ if (newidx < bsize) {
+ /*
+ * SPC-3r23 : Table 320 (Sec 7.6.5)
+ * (Network service descriptor format
+ *
+ * Note: Hard coding service type as
+ * "Storage Configuration Service".
+ */
+ p[idx] = 1;
+ SCSI_WRITE16(p + idx + 2, sz);
+ bcopy(url, p + idx + 4, url_size);
+ xfer_size = newidx + 4;
+ }
+ idx = newidx;
+
+ /* skip to next mgmt url if any */
+ url += url_size;
+ url_size = sbd_parse_mgmt_url(&url);
+ }
+
+ /* Total descriptor length */
+ SCSI_WRITE16(p + 2, idx - 4);
+ break;
+ }
+
case 0x86:
page_length = 0x3c;
- bzero(p, page_length + 4);
-
p[0] = byte0;
p[1] = 0x86; /* Page 86 response */
p[3] = page_length;
@@ -1204,17 +1365,19 @@ sbd_handle_inquiry(struct scsi_task *task, struct stmf_data_buf *initial_dbuf,
* to claim support only for Simple TA.
*/
p[5] = 1;
-
+ xfer_size = page_length + 4;
break;
default:
stmf_scsilib_send_status(task, STATUS_CHECK,
STMF_SAA_INVALID_FIELD_IN_CDB);
+ kmem_free(p, bsize);
return;
}
sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size,
- min(cmd_size, page_length + 4));
+ min(cmd_size, xfer_size));
+ kmem_free(p, bsize);
}
stmf_status_t
@@ -1424,11 +1587,7 @@ sbd_new_task(struct scsi_task *task, struct stmf_data_buf *initial_dbuf)
cdb1 = task->task_cdb[1];
if (cdb0 == SCMD_INQUIRY) { /* Inquiry */
- uint8_t *p;
-
- p = (uint8_t *)kmem_zalloc(512, KM_SLEEP);
- sbd_handle_inquiry(task, initial_dbuf, p, 512);
- kmem_free(p, 512);
+ sbd_handle_inquiry(task, initial_dbuf);
return;
}
diff --git a/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h b/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h
index af5eb2657b..1c98521986 100644
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h
@@ -145,7 +145,8 @@ typedef struct sbd_lu_info_1_1 {
uint8_t sli_serial_size;
uint8_t sli_rsvd1;
uint8_t sli_device_id[20];
- uint8_t sli_rsvd2[256];
+ uint64_t sli_mgmt_url_offset;
+ uint8_t sli_rsvd2[248];
/*
* In case there is no separate meta, sli_meta_fname_offset wont
@@ -169,6 +170,7 @@ typedef struct sbd_lu_info_1_1 {
#define SLI_ALIAS_VALID 0x0100
#define SLI_WRITEBACK_CACHE_DISABLE 0x0200
#define SLI_ZFS_META 0x0400
+#define SLI_MGMT_URL_VALID 0x0800
struct sbd_it_data;
@@ -189,6 +191,7 @@ typedef struct sbd_lu {
/* Metadata */
char *sl_alias;
char *sl_meta_filename; /* If applicable */
+ char *sl_mgmt_url;
vnode_t *sl_meta_vp;
vtype_t sl_meta_vtype;
uint8_t sl_device_id[20]; /* 4(hdr) + 16(GUID) */
@@ -203,7 +206,8 @@ typedef struct sbd_lu {
char sl_product_id[16];
char sl_revision[4];
uint32_t sl_data_fname_alloc_size; /* for an explicit alloc */
- uint32_t sl_alias_alloc_size;
+ uint16_t sl_alias_alloc_size;
+ uint16_t sl_mgmt_url_alloc_size;
uint8_t sl_serial_no_alloc_size;
uint64_t sl_meta_offset;
diff --git a/usr/src/uts/common/sys/stmf_sbd_ioctl.h b/usr/src/uts/common/sys/stmf_sbd_ioctl.h
index 214994502b..0aedc342ed 100644
--- a/usr/src/uts/common/sys/stmf_sbd_ioctl.h
+++ b/usr/src/uts/common/sys/stmf_sbd_ioctl.h
@@ -83,6 +83,7 @@ typedef struct sbd_create_and_reg_lu {
slu_rev_valid:1,
slu_serial_valid:1,
slu_alias_valid:1,
+ slu_mgmt_url_valid:1,
slu_guid_valid:1,
slu_company_id_valid:1,
slu_writeback_cache_disable_valid:1,
@@ -98,8 +99,7 @@ typedef struct sbd_create_and_reg_lu {
uint16_t slu_blksize;
uint32_t slu_company_id;
uint16_t slu_alias_off;
- uint8_t slu_rsvd2;
- uint8_t slu_rsvd;
+ uint16_t slu_mgmt_url_off;
uint32_t slu_rsvd1;
char slu_rev[4];
char slu_vid[8];
@@ -120,6 +120,7 @@ typedef struct sbd_modify_lu {
uint32_t mlu_lu_size_valid:1,
mlu_serial_valid:1,
mlu_alias_valid:1,
+ mlu_mgmt_url_valid:1,
mlu_writeback_cache_disable_valid:1,
mlu_writeback_cache_disable:1,
mlu_write_protected_valid:1,
@@ -128,9 +129,12 @@ typedef struct sbd_modify_lu {
mlu_by_fname:1;
uint64_t mlu_lu_size;
uint16_t mlu_alias_off;
+ uint16_t mlu_mgmt_url_off;
uint16_t mlu_serial_off;
uint16_t mlu_serial_size;
uint16_t mlu_fname_off;
+ uint16_t mlu_rsvd1;
+ uint32_t mlu_rsvd2;
uint8_t mlu_input_guid[16];
char mlu_buf[8]; /* can be more than 8 */
} sbd_modify_lu_t;
@@ -151,6 +155,7 @@ typedef struct sbd_lu_props {
slp_data_fname_valid:1,
slp_zfs_meta:1,
slp_alias_valid:1,
+ slp_mgmt_url_valid:1,
slp_lu_vid:1,
slp_lu_pid:1,
slp_lu_rev:1,
@@ -165,6 +170,7 @@ typedef struct sbd_lu_props {
uint16_t slp_serial_off;
uint16_t slp_blksize;
uint16_t slp_alias_off;
+ uint16_t slp_mgmt_url_off;
uint32_t slp_buf_size_needed; /* Upon return */
uint16_t slp_serial_size;
uint16_t slp_rsvd;