scsi: fix page control page field in MODE SENSE
This patch assigns correct value to page control. Now that page control value is correctly taken from CDB, error via sense data is reported when processing "saved values". "Changeable values" are not supported, so all parameters are reported as not changeable when requested. Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Change-Id: I41378c96b1e8c716b5d0ce4b72777065fb122228
This commit is contained in:
parent
30c849c1a5
commit
9879b50769
@ -102,6 +102,7 @@ enum spdk_scsi_asc {
|
|||||||
SPDK_SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED = 0x25,
|
SPDK_SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED = 0x25,
|
||||||
SPDK_SCSI_ASC_WRITE_PROTECTED = 0x27,
|
SPDK_SCSI_ASC_WRITE_PROTECTED = 0x27,
|
||||||
SPDK_SCSI_ASC_FORMAT_COMMAND_FAILED = 0x31,
|
SPDK_SCSI_ASC_FORMAT_COMMAND_FAILED = 0x31,
|
||||||
|
SPDK_SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39,
|
||||||
SPDK_SCSI_ASC_INTERNAL_TARGET_FAILURE = 0x44,
|
SPDK_SCSI_ASC_INTERNAL_TARGET_FAILURE = 0x44,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ mode_sense_page_init(uint8_t *buf, int len, int page, int subpage)
|
|||||||
static int
|
static int
|
||||||
spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
||||||
uint8_t *cdb, int pc, int page, int subpage,
|
uint8_t *cdb, int pc, int page, int subpage,
|
||||||
uint8_t *data)
|
uint8_t *data, struct spdk_scsi_task *task)
|
||||||
{
|
{
|
||||||
uint8_t *cp = data;
|
uint8_t *cp = data;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@ -804,12 +804,17 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
|||||||
if (pc == 0x00) {
|
if (pc == 0x00) {
|
||||||
/* Current values */
|
/* Current values */
|
||||||
} else if (pc == 0x01) {
|
} else if (pc == 0x01) {
|
||||||
/* Changeable values not supported */
|
/* Changeable values */
|
||||||
return -1;
|
/* As we currently do not support changeable values,
|
||||||
|
all parameters are reported as zero. */
|
||||||
} else if (pc == 0x02) {
|
} else if (pc == 0x02) {
|
||||||
/* Default values */
|
/* Default values */
|
||||||
} else {
|
} else {
|
||||||
/* Saved values not supported */
|
/* Saved values not supported */
|
||||||
|
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
|
||||||
|
SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
|
||||||
|
SPDK_SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED,
|
||||||
|
SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,11 +875,11 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
|||||||
plen = 0x12 + 2;
|
plen = 0x12 + 2;
|
||||||
mode_sense_page_init(cp, plen, page, subpage);
|
mode_sense_page_init(cp, plen, page, subpage);
|
||||||
|
|
||||||
if (cp && bdev->write_cache)
|
if (cp && bdev->write_cache && pc != 0x01)
|
||||||
cp[2] |= 0x4; /* WCE */
|
cp[2] |= 0x4; /* WCE */
|
||||||
|
|
||||||
/* Read Cache Disable (RCD) = 1 */
|
/* Read Cache Disable (RCD) = 1 */
|
||||||
if (cp)
|
if (cp && pc != 0x01)
|
||||||
cp[2] |= 0x1;
|
cp[2] |= 0x1;
|
||||||
|
|
||||||
len += plen;
|
len += plen;
|
||||||
@ -906,11 +911,11 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
|||||||
len += spdk_bdev_scsi_mode_sense_page(bdev,
|
len += spdk_bdev_scsi_mode_sense_page(bdev,
|
||||||
cdb, pc, page,
|
cdb, pc, page,
|
||||||
0x00,
|
0x00,
|
||||||
cp ? &cp[len] : NULL);
|
cp ? &cp[len] : NULL, task);
|
||||||
len += spdk_bdev_scsi_mode_sense_page(bdev,
|
len += spdk_bdev_scsi_mode_sense_page(bdev,
|
||||||
cdb, pc, page,
|
cdb, pc, page,
|
||||||
0x01,
|
0x01,
|
||||||
cp ? &cp[len] : NULL);
|
cp ? &cp[len] : NULL, task);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* 0x02-0x3e: Reserved */
|
/* 0x02-0x3e: Reserved */
|
||||||
@ -1027,7 +1032,7 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
|||||||
for (i = 0x00; i < 0x3e; i ++) {
|
for (i = 0x00; i < 0x3e; i ++) {
|
||||||
len += spdk_bdev_scsi_mode_sense_page(
|
len += spdk_bdev_scsi_mode_sense_page(
|
||||||
bdev, cdb, pc, i, 0x00,
|
bdev, cdb, pc, i, 0x00,
|
||||||
cp ? &cp[len] : NULL);
|
cp ? &cp[len] : NULL, task);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xff:
|
case 0xff:
|
||||||
@ -1035,12 +1040,12 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
|||||||
for (i = 0x00; i < 0x3e; i ++) {
|
for (i = 0x00; i < 0x3e; i ++) {
|
||||||
len += spdk_bdev_scsi_mode_sense_page(
|
len += spdk_bdev_scsi_mode_sense_page(
|
||||||
bdev, cdb, pc, i, 0x00,
|
bdev, cdb, pc, i, 0x00,
|
||||||
cp ? &cp[len] : NULL);
|
cp ? &cp[len] : NULL, task);
|
||||||
}
|
}
|
||||||
for (i = 0x00; i < 0x3e; i ++) {
|
for (i = 0x00; i < 0x3e; i ++) {
|
||||||
len += spdk_bdev_scsi_mode_sense_page(
|
len += spdk_bdev_scsi_mode_sense_page(
|
||||||
bdev, cdb, pc, i, 0xff,
|
bdev, cdb, pc, i, 0xff,
|
||||||
cp ? &cp[len] : NULL);
|
cp ? &cp[len] : NULL, task);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1055,7 +1060,7 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
|
|||||||
static int
|
static int
|
||||||
spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md,
|
spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md,
|
||||||
uint8_t *cdb, int dbd, int llbaa, int pc,
|
uint8_t *cdb, int dbd, int llbaa, int pc,
|
||||||
int page, int subpage, uint8_t *data)
|
int page, int subpage, uint8_t *data, struct spdk_scsi_task *task)
|
||||||
{
|
{
|
||||||
uint8_t *hdr, *bdesc, *pages;
|
uint8_t *hdr, *bdesc, *pages;
|
||||||
int hlen;
|
int hlen;
|
||||||
@ -1079,7 +1084,7 @@ spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md,
|
|||||||
pages = data ? &data[hlen + blen] : NULL;
|
pages = data ? &data[hlen + blen] : NULL;
|
||||||
plen = spdk_bdev_scsi_mode_sense_page(bdev, cdb, pc, page,
|
plen = spdk_bdev_scsi_mode_sense_page(bdev, cdb, pc, page,
|
||||||
subpage,
|
subpage,
|
||||||
pages);
|
pages, task);
|
||||||
if (plen < 0) {
|
if (plen < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1831,7 +1836,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbd = !!(cdb[1] & 0x8);
|
dbd = !!(cdb[1] & 0x8);
|
||||||
pc = (cdb[2] & 0xc) >> 6;
|
pc = (cdb[2] & 0xc0) >> 6;
|
||||||
page = cdb[2] & 0x3f;
|
page = cdb[2] & 0x3f;
|
||||||
subpage = cdb[3];
|
subpage = cdb[3];
|
||||||
|
|
||||||
@ -1839,7 +1844,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
|
|||||||
rc = spdk_bdev_scsi_mode_sense(bdev, md,
|
rc = spdk_bdev_scsi_mode_sense(bdev, md,
|
||||||
cdb, dbd, llba, pc,
|
cdb, dbd, llba, pc,
|
||||||
page, subpage,
|
page, subpage,
|
||||||
NULL);
|
NULL, task);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1852,7 +1857,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
|
|||||||
rc = spdk_bdev_scsi_mode_sense(bdev, md,
|
rc = spdk_bdev_scsi_mode_sense(bdev, md,
|
||||||
cdb, dbd, llba, pc,
|
cdb, dbd, llba, pc,
|
||||||
page, subpage,
|
page, subpage,
|
||||||
data);
|
data, task);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
/* INVALID FIELD IN CDB */
|
/* INVALID FIELD IN CDB */
|
||||||
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
|
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
|
||||||
|
Loading…
Reference in New Issue
Block a user