summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2017-01-05 11:45:36 +0000
committermav <mav@FreeBSD.org>2017-01-05 11:45:36 +0000
commit72dae226f530f3e39c4646d39463f30a0abc0a46 (patch)
tree974916633df1cd74c2ebf8cae43e5bb8157650b4
parent25ed58e17f528f9408bef469ea813292be541b72 (diff)
downloadFreeBSD-src-72dae226f530f3e39c4646d39463f30a0abc0a46.zip
FreeBSD-src-72dae226f530f3e39c4646d39463f30a0abc0a46.tar.gz
MFC r310366: 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.
-rw-r--r--sys/cam/ctl/ctl.c21
-rw-r--r--sys/cam/ctl/ctl_error.c12
-rw-r--r--sys/cam/ctl/ctl_private.h2
3 files changed, 21 insertions, 14 deletions
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 9cb5199..1335ca9 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -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,
@@ -6066,11 +6066,7 @@ do_next_page:
* 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,
@@ -6081,6 +6077,12 @@ do_next_page:
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
@@ -9317,13 +9319,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) {
/*
diff --git a/sys/cam/ctl/ctl_error.c b/sys/cam/ctl/ctl_error.c
index 4f839db..4e75a5c 100644
--- a/sys/cam/ctl/ctl_error.c
+++ b/sys/cam/ctl/ctl_error.c
@@ -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);
}
diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h
index 6b5f04e..b8ad726 100644
--- a/sys/cam/ctl/ctl_private.h
+++ b/sys/cam/ctl/ctl_private.h
@@ -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},
OpenPOWER on IntegriCloud