Commit a6cdc35f authored by Damien Le Moal's avatar Damien Le Moal Committed by Martin K. Petersen
Browse files

scsi: core: Support retrieving sub-pages of mode pages



Allow scsi_mode_sense() to retrieve sub-pages of mode pages by adding the
subpage argument. Change all the current caller sites to specify the
subpage 0.

Signed-off-by: default avatarDamien Le Moal <dlemoal@kernel.org>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarNiklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-7-nks@flawful.org


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 73432693
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2144,6 +2144,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select);
 *	@sdev:	SCSI device to be queried
 *	@dbd:	set to prevent mode sense from returning block descriptors
 *	@modepage: mode page being requested
 *	@subpage: sub-page of the mode page being requested
 *	@buffer: request buffer (may not be smaller than eight bytes)
 *	@len:	length of request buffer.
 *	@timeout: command timeout
@@ -2155,7 +2156,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select);
 *	Returns zero if successful, or a negative error number on failure
 */
int
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, int subpage,
		  unsigned char *buffer, int len, int timeout, int retries,
		  struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr)
{
@@ -2175,6 +2176,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
	dbd = sdev->set_dbd_for_ms ? 8 : dbd;
	cmd[1] = dbd & 0x18;	/* allows DBD and LLBA bits */
	cmd[2] = modepage;
	cmd[3] = subpage;

	sshdr = exec_args.sshdr;

+1 −1
Original line number Diff line number Diff line
@@ -1245,7 +1245,7 @@ int sas_read_port_mode_page(struct scsi_device *sdev)
	if (!buffer)
		return -ENOMEM;

	error = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
	error = scsi_mode_sense(sdev, 1, 0x19, 0, buffer, BUF_SIZE, 30*HZ, 3,
				&mode_data, NULL);

	if (error)
+4 −5
Original line number Diff line number Diff line
@@ -183,7 +183,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
		return count;
	}

	if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT,
	if (scsi_mode_sense(sdp, 0x08, 8, 0, buffer, sizeof(buffer), SD_TIMEOUT,
			    sdkp->max_retries, &data, NULL))
		return -EINVAL;
	len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
@@ -2609,9 +2609,8 @@ sd_do_mode_sense(struct scsi_disk *sdkp, int dbd, int modepage,
	if (sdkp->device->use_10_for_ms && len < 8)
		len = 8;

	return scsi_mode_sense(sdkp->device, dbd, modepage, buffer, len,
			       SD_TIMEOUT, sdkp->max_retries, data,
			       sshdr);
	return scsi_mode_sense(sdkp->device, dbd, modepage, 0, buffer, len,
			       SD_TIMEOUT, sdkp->max_retries, data, sshdr);
}

/*
@@ -2868,7 +2867,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
	if (sdkp->protection_type == 0)
		return;

	res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT,
	res = scsi_mode_sense(sdp, 1, 0x0a, 0, buffer, 36, SD_TIMEOUT,
			      sdkp->max_retries, &data, &sshdr);

	if (res < 0 || !data.header_length ||
+1 −1
Original line number Diff line number Diff line
@@ -825,7 +825,7 @@ static int get_capabilities(struct scsi_cd *cd)
	scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);

	/* ask for mode page 0x2a */
	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
	rc = scsi_mode_sense(cd->device, 0, 0x2a, 0, buffer, ms_len,
			     SR_TIMEOUT, 3, &data, NULL);

	if (rc < 0 || data.length > ms_len ||
+4 −4
Original line number Diff line number Diff line
@@ -421,8 +421,8 @@ extern int scsi_track_queue_full(struct scsi_device *, int);

extern int scsi_set_medium_removal(struct scsi_device *, char);

extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
			   unsigned char *buffer, int len, int timeout,
int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
		    int subpage, unsigned char *buffer, int len, int timeout,
		    int retries, struct scsi_mode_data *data,
		    struct scsi_sense_hdr *);
extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp,