diff mbox series

[04/39] scsi: Fixup calling convention for scsi_mode_sense()

Message ID 20210423113944.42672-5-hare@suse.de
State Superseded
Headers show
Series SCSI result cleanup, part 2 | expand

Commit Message

Hannes Reinecke April 23, 2021, 11:39 a.m. UTC
The description for scsi_mode_sense() claims to return the number
of valid bytes on success, which is not what the code does.
Additionally there is no gain in returning the scsi status, as
everything the callers do is to check against scsi_result_is_good(),
which is what scsi_mode_sense() does already.
So change the calling convention to return a standard error code
on failure, and 0 on success, and adapt the description and all
callers.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/scsi_lib.c           | 10 ++++++----
 drivers/scsi/scsi_transport_sas.c |  9 ++++-----
 drivers/scsi/sd.c                 | 12 ++++++------
 drivers/scsi/sr.c                 |  2 +-
 4 files changed, 17 insertions(+), 16 deletions(-)

Comments

Bart Van Assche April 26, 2021, 3:21 a.m. UTC | #1
On 4/23/21 4:39 AM, Hannes Reinecke wrote:
> The description for scsi_mode_sense() claims to return the number

> of valid bytes on success, which is not what the code does.

> Additionally there is no gain in returning the scsi status, as

> everything the callers do is to check against scsi_result_is_good(),

> which is what scsi_mode_sense() does already.

> So change the calling convention to return a standard error code

> on failure, and 0 on success, and adapt the description and all

> callers.


Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Christoph Hellwig April 26, 2021, 2:57 p.m. UTC | #2
On Fri, Apr 23, 2021 at 01:39:09PM +0200, Hannes Reinecke wrote:
> The description for scsi_mode_sense() claims to return the number

> of valid bytes on success, which is not what the code does.

> Additionally there is no gain in returning the scsi status, as

> everything the callers do is to check against scsi_result_is_good(),

> which is what scsi_mode_sense() does already.

> So change the calling convention to return a standard error code

> on failure, and 0 on success, and adapt the description and all

> callers.

> 

> Signed-off-by: Hannes Reinecke <hare@suse.de>

> ---

>  drivers/scsi/scsi_lib.c           | 10 ++++++----

>  drivers/scsi/scsi_transport_sas.c |  9 ++++-----

>  drivers/scsi/sd.c                 | 12 ++++++------

>  drivers/scsi/sr.c                 |  2 +-

>  4 files changed, 17 insertions(+), 16 deletions(-)

> 

> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c

> index d7c0d5a5f263..c532f9390ae3 100644

> --- a/drivers/scsi/scsi_lib.c

> +++ b/drivers/scsi/scsi_lib.c

> @@ -2135,9 +2135,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select);

>   *	@sshdr: place to put sense data (or NULL if no sense to be collected).

>   *		must be SCSI_SENSE_BUFFERSIZE big.

>   *

> - *	Returns zero if unsuccessful, or the header offset (either 4

> - *	or 8 depending on whether a six or ten byte command was

> - *	issued) if successful.

> + *	Returns zero if successful, or a negative error number on failure

>   */

>  int

>  scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,

> @@ -2190,6 +2188,8 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,

>  	 * byte as the problem.  MODE_SENSE commands can return

>  	 * ILLEGAL REQUEST if the code page isn't supported */

>  

> +	if (result < 0)

> +		return result;


The return would be much easier to read if it was just below the call to
scsi_execute_req that assigns result than under the comment
describing the code below.

>  	if (use_10_for_ms && !scsi_status_is_good(result) &&

>  	    driver_byte(result) == DRIVER_SENSE) {

>  		if (scsi_sense_valid(sshdr)) {

> @@ -2228,13 +2228,15 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,

>  			data->block_descriptor_length = buffer[3];

>  		}

>  		data->header_length = header_length;

> +		result = 0;

>  	} else if ((status_byte(result) == CHECK_CONDITION) &&

>  		   scsi_sense_valid(sshdr) &&

>  		   sshdr->sense_key == UNIT_ATTENTION && retry_count) {

>  		retry_count--;

>  		goto retry;

>  	}

> -

> +	if (result > 0)

> +		result = -EIO;


IMHO it would be nice to restructure the end of the function to do
something like:

	if (!scsi_status_is_good(result)) {
		if (status_byte(result) == CHECK_CONDITION &&
		    scsi_sense_valid(sshdr) &&
		    sshdr->sense_key == UNIT_ATTENTION &&
		    retry_count) {
			retry_count--;
			goto retry;
		}
		return -EIO;
	}

	// various data fixups here

	return 0;
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index d7c0d5a5f263..c532f9390ae3 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2135,9 +2135,7 @@  EXPORT_SYMBOL_GPL(scsi_mode_select);
  *	@sshdr: place to put sense data (or NULL if no sense to be collected).
  *		must be SCSI_SENSE_BUFFERSIZE big.
  *
- *	Returns zero if unsuccessful, or the header offset (either 4
- *	or 8 depending on whether a six or ten byte command was
- *	issued) if successful.
+ *	Returns zero if successful, or a negative error number on failure
  */
 int
 scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
@@ -2190,6 +2188,8 @@  scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
 	 * byte as the problem.  MODE_SENSE commands can return
 	 * ILLEGAL REQUEST if the code page isn't supported */
 
+	if (result < 0)
+		return result;
 	if (use_10_for_ms && !scsi_status_is_good(result) &&
 	    driver_byte(result) == DRIVER_SENSE) {
 		if (scsi_sense_valid(sshdr)) {
@@ -2228,13 +2228,15 @@  scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
 			data->block_descriptor_length = buffer[3];
 		}
 		data->header_length = header_length;
+		result = 0;
 	} else if ((status_byte(result) == CHECK_CONDITION) &&
 		   scsi_sense_valid(sshdr) &&
 		   sshdr->sense_key == UNIT_ATTENTION && retry_count) {
 		retry_count--;
 		goto retry;
 	}
-
+	if (result > 0)
+		result = -EIO;
 	return result;
 }
 EXPORT_SYMBOL(scsi_mode_sense);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index c9abed8429c9..4a96fb05731d 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -1229,16 +1229,15 @@  int sas_read_port_mode_page(struct scsi_device *sdev)
 	char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata;
 	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
 	struct scsi_mode_data mode_data;
-	int res, error;
+	int error;
 
 	if (!buffer)
 		return -ENOMEM;
 
-	res = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
-			      &mode_data, NULL);
+	error = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
+				&mode_data, NULL);
 
-	error = -EINVAL;
-	if (!scsi_status_is_good(res))
+	if (error)
 		goto out;
 
 	msdata = buffer +  mode_data.header_length +
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index cb3c37d1e009..2ef2954375f4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2670,18 +2670,18 @@  sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
 		 * 5: Illegal Request, Sense Code 24: Invalid field in
 		 * CDB.
 		 */
-		if (!scsi_status_is_good(res))
+		if (res < 0)
 			res = sd_do_mode_sense(sdkp, 0, 0, buffer, 4, &data, NULL);
 
 		/*
 		 * Third attempt: ask 255 bytes, as we did earlier.
 		 */
-		if (!scsi_status_is_good(res))
+		if (res < 0)
 			res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 255,
 					       &data, NULL);
 	}
 
-	if (!scsi_status_is_good(res)) {
+	if (res < 0) {
 		sd_first_printk(KERN_WARNING, sdkp,
 			  "Test WP failed, assume Write Enabled\n");
 	} else {
@@ -2742,7 +2742,7 @@  sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
 	res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, first_len,
 			&data, &sshdr);
 
-	if (!scsi_status_is_good(res))
+	if (res < 0)
 		goto bad_sense;
 
 	if (!data.header_length) {
@@ -2774,7 +2774,7 @@  sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
 		res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, len,
 				&data, &sshdr);
 
-	if (scsi_status_is_good(res)) {
+	if (!res) {
 		int offset = data.header_length + data.block_descriptor_length;
 
 		while (offset < len) {
@@ -2892,7 +2892,7 @@  static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
 	res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT,
 			      sdkp->max_retries, &data, &sshdr);
 
-	if (!scsi_status_is_good(res) || !data.header_length ||
+	if (res < 0 || !data.header_length ||
 	    data.length < 6) {
 		sd_first_printk(KERN_WARNING, sdkp,
 			  "getting Control mode page failed, assume no ATO\n");
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index e4633b84c556..9b2ccf0c9a8c 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -911,7 +911,7 @@  static void get_capabilities(struct scsi_cd *cd)
 	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
 			     SR_TIMEOUT, 3, &data, NULL);
 
-	if (!scsi_status_is_good(rc) || data.length > ms_len ||
+	if (rc < 0 || data.length > ms_len ||
 	    data.header_length + data.block_descriptor_length > data.length) {
 		/* failed, drive doesn't have capabilities mode page */
 		cd->cdi.speed = 1;