Commit 9879b507 authored by Tomasz Zawadzki's avatar Tomasz Zawadzki Committed by Daniel Verkamp
Browse files

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: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I41378c96b1e8c716b5d0ce4b72777065fb122228
parent 30c849c1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ enum spdk_scsi_asc {
	SPDK_SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED = 0x25,
	SPDK_SCSI_ASC_WRITE_PROTECTED = 0x27,
	SPDK_SCSI_ASC_FORMAT_COMMAND_FAILED = 0x31,
	SPDK_SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39,
	SPDK_SCSI_ASC_INTERNAL_TARGET_FAILURE = 0x44,
};

+20 −15
Original line number Diff line number Diff line
@@ -794,7 +794,7 @@ mode_sense_page_init(uint8_t *buf, int len, int page, int subpage)
static int
spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
			       uint8_t *cdb, int pc, int page, int subpage,
			       uint8_t *data)
			       uint8_t *data, struct spdk_scsi_task *task)
{
	uint8_t *cp = data;
	int len = 0;
@@ -804,12 +804,17 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
	if (pc == 0x00) {
		/* Current values */
	} else if (pc == 0x01) {
		/* Changeable values not supported */
		return -1;
		/* Changeable values */
		/* As we currently do not support changeable values,
		   all parameters are reported as zero. */
	} else if (pc == 0x02) {
		/* Default values */
	} else {
		/* 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;
	}

@@ -870,11 +875,11 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
		plen = 0x12 + 2;
		mode_sense_page_init(cp, plen, page, subpage);

		if (cp && bdev->write_cache)
		if (cp && bdev->write_cache && pc != 0x01)
			cp[2] |= 0x4; /* WCE */

		/* Read Cache Disable (RCD) = 1 */
		if (cp)
		if (cp && pc != 0x01)
			cp[2] |= 0x1;

		len += plen;
@@ -906,11 +911,11 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
			len += spdk_bdev_scsi_mode_sense_page(bdev,
							      cdb, pc, page,
							      0x00,
							      cp ? &cp[len] : NULL);
							      cp ? &cp[len] : NULL, task);
			len += spdk_bdev_scsi_mode_sense_page(bdev,
							      cdb, pc, page,
							      0x01,
							      cp ? &cp[len] : NULL);
							      cp ? &cp[len] : NULL, task);
			break;
		default:
			/* 0x02-0x3e: Reserved */
@@ -1027,7 +1032,7 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
			for (i = 0x00; i < 0x3e; i ++) {
				len += spdk_bdev_scsi_mode_sense_page(
					       bdev, cdb, pc, i, 0x00,
					       cp ? &cp[len] : NULL);
					       cp ? &cp[len] : NULL, task);
			}
			break;
		case 0xff:
@@ -1035,12 +1040,12 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
			for (i = 0x00; i < 0x3e; i ++) {
				len += spdk_bdev_scsi_mode_sense_page(
					       bdev, cdb, pc, i, 0x00,
					       cp ? &cp[len] : NULL);
					       cp ? &cp[len] : NULL, task);
			}
			for (i = 0x00; i < 0x3e; i ++) {
				len += spdk_bdev_scsi_mode_sense_page(
					       bdev, cdb, pc, i, 0xff,
					       cp ? &cp[len] : NULL);
					       cp ? &cp[len] : NULL, task);
			}
			break;
		default:
@@ -1055,7 +1060,7 @@ spdk_bdev_scsi_mode_sense_page(struct spdk_bdev *bdev,
static int
spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md,
			  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;
	int hlen;
@@ -1079,7 +1084,7 @@ spdk_bdev_scsi_mode_sense(struct spdk_bdev *bdev, int md,
	pages = data ? &data[hlen + blen] : NULL;
	plen = spdk_bdev_scsi_mode_sense_page(bdev, cdb, pc, page,
					      subpage,
					      pages);
					      pages, task);
	if (plen < 0) {
		return -1;
	}
@@ -1831,7 +1836,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
		}

		dbd = !!(cdb[1] & 0x8);
		pc = (cdb[2] & 0xc) >> 6;
		pc = (cdb[2] & 0xc0) >> 6;
		page = cdb[2] & 0x3f;
		subpage = cdb[3];

@@ -1839,7 +1844,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
		rc = spdk_bdev_scsi_mode_sense(bdev, md,
					       cdb, dbd, llba, pc,
					       page, subpage,
					       NULL);
					       NULL, task);
		if (rc < 0) {
			break;
		}
@@ -1852,7 +1857,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
		rc = spdk_bdev_scsi_mode_sense(bdev, md,
					       cdb, dbd, llba, pc,
					       page, subpage,
					       data);
					       data, task);
		if (rc < 0) {
			/* INVALID FIELD IN CDB */
			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,