Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-7-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Damien Le Moal and committed by
Martin K. Petersen
a6cdc35f 73432693

+13 -12
+3 -1
drivers/scsi/scsi_lib.c
··· 2144 2144 * @sdev: SCSI device to be queried 2145 2145 * @dbd: set to prevent mode sense from returning block descriptors 2146 2146 * @modepage: mode page being requested 2147 + * @subpage: sub-page of the mode page being requested 2147 2148 * @buffer: request buffer (may not be smaller than eight bytes) 2148 2149 * @len: length of request buffer. 2149 2150 * @timeout: command timeout ··· 2156 2155 * Returns zero if successful, or a negative error number on failure 2157 2156 */ 2158 2157 int 2159 - scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, 2158 + scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, int subpage, 2160 2159 unsigned char *buffer, int len, int timeout, int retries, 2161 2160 struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) 2162 2161 { ··· 2176 2175 dbd = sdev->set_dbd_for_ms ? 8 : dbd; 2177 2176 cmd[1] = dbd & 0x18; /* allows DBD and LLBA bits */ 2178 2177 cmd[2] = modepage; 2178 + cmd[3] = subpage; 2179 2179 2180 2180 sshdr = exec_args.sshdr; 2181 2181
+1 -1
drivers/scsi/scsi_transport_sas.c
··· 1245 1245 if (!buffer) 1246 1246 return -ENOMEM; 1247 1247 1248 - error = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3, 1248 + error = scsi_mode_sense(sdev, 1, 0x19, 0, buffer, BUF_SIZE, 30*HZ, 3, 1249 1249 &mode_data, NULL); 1250 1250 1251 1251 if (error)
+4 -5
drivers/scsi/sd.c
··· 183 183 return count; 184 184 } 185 185 186 - if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, 186 + if (scsi_mode_sense(sdp, 0x08, 8, 0, buffer, sizeof(buffer), SD_TIMEOUT, 187 187 sdkp->max_retries, &data, NULL)) 188 188 return -EINVAL; 189 189 len = min_t(size_t, sizeof(buffer), data.length - data.header_length - ··· 2609 2609 if (sdkp->device->use_10_for_ms && len < 8) 2610 2610 len = 8; 2611 2611 2612 - return scsi_mode_sense(sdkp->device, dbd, modepage, buffer, len, 2613 - SD_TIMEOUT, sdkp->max_retries, data, 2614 - sshdr); 2612 + return scsi_mode_sense(sdkp->device, dbd, modepage, 0, buffer, len, 2613 + SD_TIMEOUT, sdkp->max_retries, data, sshdr); 2615 2614 } 2616 2615 2617 2616 /* ··· 2867 2868 if (sdkp->protection_type == 0) 2868 2869 return; 2869 2870 2870 - res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, 2871 + res = scsi_mode_sense(sdp, 1, 0x0a, 0, buffer, 36, SD_TIMEOUT, 2871 2872 sdkp->max_retries, &data, &sshdr); 2872 2873 2873 2874 if (res < 0 || !data.header_length ||
+1 -1
drivers/scsi/sr.c
··· 825 825 scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); 826 826 827 827 /* ask for mode page 0x2a */ 828 - rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, 828 + rc = scsi_mode_sense(cd->device, 0, 0x2a, 0, buffer, ms_len, 829 829 SR_TIMEOUT, 3, &data, NULL); 830 830 831 831 if (rc < 0 || data.length > ms_len ||
+4 -4
include/scsi/scsi_device.h
··· 421 421 422 422 extern int scsi_set_medium_removal(struct scsi_device *, char); 423 423 424 - extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, 425 - unsigned char *buffer, int len, int timeout, 426 - int retries, struct scsi_mode_data *data, 427 - struct scsi_sense_hdr *); 424 + int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, 425 + int subpage, unsigned char *buffer, int len, int timeout, 426 + int retries, struct scsi_mode_data *data, 427 + struct scsi_sense_hdr *); 428 428 extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, 429 429 unsigned char *buffer, int len, int timeout, 430 430 int retries, struct scsi_mode_data *data,