Add support for SITUA bit in Logical Block Provisioning mode page.

VMware tries to enable this bit to avoid multiple threshold notifications
in case of multiple initiators connected to the same LUN.  Unfortunately
their code sends MODE SELECT(6) request with parameter length hardcoded
for the page without any thresholds.  Since we have four threshold and our
page is bigger, this attempt fails, that is correct in my understanding.
So all we can do about this now is to report proper error code and hope
VMware fix their code one day.

MFC after:	2 weeks
This commit is contained in:
Alexander Motin 2016-12-21 15:17:47 +00:00
parent 77ac8927fd
commit 33e7ba9cf9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=310366
3 changed files with 21 additions and 14 deletions

View File

@ -332,7 +332,7 @@ const static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{
/*page_code*/SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF,
/*subpage_code*/0x02,
/*page_length*/{CTL_LBPM_LEN >> 8, CTL_LBPM_LEN},
/*flags*/0,
/*flags*/SLBPP_SITUA,
/*reserved*/{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/*descr*/{}},
{{/*flags*/0,
@ -6075,11 +6075,7 @@ ctl_do_mode_select(union ctl_io *io)
* the mode page header, or if they didn't specify enough data in
* the CDB to avoid truncating this page, kick out the request.
*/
if ((page_len != (page_index->page_len - page_len_offset -
page_len_size))
|| (*len_left < page_index->page_len)) {
if (page_len != page_index->page_len - page_len_offset - page_len_size) {
ctl_set_invalid_field(ctsio,
/*sks_valid*/ 1,
/*command*/ 0,
@ -6090,6 +6086,12 @@ ctl_do_mode_select(union ctl_io *io)
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
if (*len_left < page_index->page_len) {
free(ctsio->kern_data_ptr, M_CTL);
ctl_set_param_len_error(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
}
/*
* Run through the mode page, checking to make sure that the bits
@ -9326,13 +9328,6 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
ua_type = ctl_build_ua(lun, initidx, sense_ptr, sense_format);
if (ua_type != CTL_UA_NONE)
have_error = 1;
if (ua_type == CTL_UA_LUN_CHANGE) {
mtx_unlock(&lun->lun_lock);
mtx_lock(&softc->ctl_lock);
ctl_clr_ua_allluns(softc, initidx, ua_type);
mtx_unlock(&softc->ctl_lock);
mtx_lock(&lun->lun_lock);
}
}
if (have_error == 0) {
/*

View File

@ -515,6 +515,7 @@ ctl_build_ua(struct ctl_lun *lun, uint32_t initidx,
uint32_t p, i;
mtx_assert(&lun->lun_lock, MA_OWNED);
mtx_assert(&lun->ctl_softc->ctl_lock, MA_NOTOWNED);
p = initidx / CTL_MAX_INIT_PER_PORT;
if ((ua = lun->pending_ua[p]) == NULL) {
mtx_unlock(&lun->lun_lock);
@ -547,6 +548,17 @@ ctl_build_ua(struct ctl_lun *lun, uint32_t initidx,
/* We're reporting this UA, so clear it */
ua[i] &= ~ua_to_clear;
if (ua_to_build == CTL_UA_LUN_CHANGE) {
mtx_unlock(&lun->lun_lock);
mtx_lock(&lun->ctl_softc->ctl_lock);
ctl_clr_ua_allluns(lun->ctl_softc, initidx, ua_to_build);
mtx_unlock(&lun->ctl_softc->ctl_lock);
mtx_lock(&lun->lun_lock);
} else if (ua_to_build == CTL_UA_THIN_PROV_THRES &&
(lun->MODE_LBP.main.flags & SLBPP_SITUA) != 0) {
ctl_clr_ua_all(lun, -1, ua_to_build);
}
return (ua_to_build);
}

View File

@ -290,7 +290,7 @@ static const struct ctl_page_index page_index_template[] = {
CTL_PAGE_FLAG_ALL, NULL, ctl_ie_page_handler},
{SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF, 0x02,
sizeof(struct ctl_logical_block_provisioning_page), NULL,
CTL_PAGE_FLAG_DIRECT, NULL, NULL},
CTL_PAGE_FLAG_DIRECT, NULL, ctl_default_page_handler},
{SMS_CDDVD_CAPS_PAGE, 0,
sizeof(struct scsi_cddvd_capabilities_page), NULL,
CTL_PAGE_FLAG_CDROM, NULL, NULL},