Mercurial > illumos > illumos-gate
changeset 10113:045148591643
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
author | Nattuvetty Bhavyan <Nattuvetty.Bhavyan@Sun.COM> |
---|---|
date | Fri, 17 Jul 2009 11:20:16 -0700 |
parents | ca9cb52b0505 |
children | 023993413f11 |
files | usr/src/cmd/stmfadm/stmfadm.c usr/src/lib/libstmf/common/libstmf.h usr/src/lib/libstmf/common/libstmf_impl.h usr/src/lib/libstmf/common/stmf.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h usr/src/uts/common/sys/stmf_sbd_ioctl.h |
diffstat | 8 files changed, 387 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/stmfadm/stmfadm.c Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/cmd/stmfadm/stmfadm.c Fri Jul 17 11:20:16 2009 -0700 @@ -126,13 +126,15 @@ #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 @@ #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 @@ 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 @@ 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 @@ *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 @@ 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");
--- a/usr/src/lib/libstmf/common/libstmf.h Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/lib/libstmf/common/libstmf.h Fri Jul 17 11:20:16 2009 -0700 @@ -129,6 +129,7 @@ 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,
--- a/usr/src/lib/libstmf/common/libstmf_impl.h Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/lib/libstmf/common/libstmf_impl.h Fri Jul 17 11:20:16 2009 -0700 @@ -55,6 +55,8 @@ uint32_t companyId; boolean_t luAliasValid; char luAlias[256]; + boolean_t luMgmtUrlValid; + char luMgmtUrl[1024]; boolean_t vidValid; char vid[8]; boolean_t pidValid;
--- a/usr/src/lib/libstmf/common/stmf.c Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/lib/libstmf/common/stmf.c Fri Jul 17 11:20:16 2009 -0700 @@ -1078,6 +1078,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ { int ret = STMF_STATUS_SUCCESS; int luAliasLen = 0; + int luMgmtUrlLen = 0; int mluBufSize = 0; int bufOffset = 0; int fd = 0; @@ -1710,6 +1726,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ } (*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 @@ (*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:
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c Fri Jul 17 11:20:16 2009 -0700 @@ -1066,6 +1066,9 @@ 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 @@ 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 @@ 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 @@ (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 @@ 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 @@ (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 @@ (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 @@ (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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ (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],
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c Fri Jul 17 11:20:16 2009 -0700 @@ -1070,15 +1070,56 @@ 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 *p; + uint8_t byte0; uint8_t page_length; - uint8_t byte0; + 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 @@ * 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 @@ 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; - page_length = 31; - bzero(inq, page_length + 5); + p = (uint8_t *)kmem_zalloc(bsize, KM_SLEEP); + inq = (struct scsi_inquiry *)p; + + page_length = 69; + xfer_size = page_length + 5; inq->inq_dtype = DTYPE_DIRECT; inq->inq_ansi = 5; /* SPC-3 */ @@ -1124,7 +1173,7 @@ 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 @@ 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 @@ * 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 @@ 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 @@ * 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 @@ 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; }
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h Fri Jul 17 11:20:16 2009 -0700 @@ -145,7 +145,8 @@ 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 @@ #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 @@ /* 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 @@ 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;
--- a/usr/src/uts/common/sys/stmf_sbd_ioctl.h Fri Jul 17 12:06:50 2009 -0500 +++ b/usr/src/uts/common/sys/stmf_sbd_ioctl.h Fri Jul 17 11:20:16 2009 -0700 @@ -83,6 +83,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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;