Merge branch '6.7/scsi-staging' into 6.7/scsi-fixes
[sfrench/cifs-2.6.git] / drivers / scsi / sd.c
index 530918cbfce2d1840feec8dcca2dcc7479257452..fa00dd503cbf618b066eac2001d60a3dc59fd1ed 100644 (file)
@@ -1643,24 +1643,21 @@ out:
        return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
 }
 
-static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
+static int sd_sync_cache(struct scsi_disk *sdkp)
 {
        int retries, res;
        struct scsi_device *sdp = sdkp->device;
        const int timeout = sdp->request_queue->rq_timeout
                * SD_FLUSH_TIMEOUT_MULTIPLIER;
-       struct scsi_sense_hdr my_sshdr;
+       struct scsi_sense_hdr sshdr;
        const struct scsi_exec_args exec_args = {
                .req_flags = BLK_MQ_REQ_PM,
-               /* caller might not be interested in sense, but we need it */
-               .sshdr = sshdr ? : &my_sshdr,
+               .sshdr = &sshdr,
        };
 
        if (!scsi_device_online(sdp))
                return -ENODEV;
 
-       sshdr = exec_args.sshdr;
-
        for (retries = 3; retries > 0; --retries) {
                unsigned char cmd[16] = { 0 };
 
@@ -1685,15 +1682,23 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
                        return res;
 
                if (scsi_status_is_check_condition(res) &&
-                   scsi_sense_valid(sshdr)) {
-                       sd_print_sense_hdr(sdkp, sshdr);
+                   scsi_sense_valid(&sshdr)) {
+                       sd_print_sense_hdr(sdkp, &sshdr);
 
                        /* we need to evaluate the error return  */
-                       if (sshdr->asc == 0x3a ||       /* medium not present */
-                           sshdr->asc == 0x20 ||       /* invalid command */
-                           (sshdr->asc == 0x74 && sshdr->ascq == 0x71))        /* drive is password locked */
+                       if (sshdr.asc == 0x3a ||        /* medium not present */
+                           sshdr.asc == 0x20 ||        /* invalid command */
+                           (sshdr.asc == 0x74 && sshdr.ascq == 0x71))  /* drive is password locked */
                                /* this is no error here */
                                return 0;
+                       /*
+                        * This drive doesn't support sync and there's not much
+                        * we can do because this is called during shutdown
+                        * or suspend so just return success so those operations
+                        * can proceed.
+                        */
+                       if (sshdr.sense_key == ILLEGAL_REQUEST)
+                               return 0;
                }
 
                switch (host_byte(res)) {
@@ -3853,7 +3858,7 @@ static void sd_shutdown(struct device *dev)
 
        if (sdkp->WCE && sdkp->media_present) {
                sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
-               sd_sync_cache(sdkp, NULL);
+               sd_sync_cache(sdkp);
        }
 
        if ((system_state != SYSTEM_RESTART &&
@@ -3874,7 +3879,6 @@ static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime)
 static int sd_suspend_common(struct device *dev, bool runtime)
 {
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
-       struct scsi_sense_hdr sshdr;
        int ret = 0;
 
        if (!sdkp)      /* E.g.: runtime suspend following sd_remove() */
@@ -3883,24 +3887,13 @@ static int sd_suspend_common(struct device *dev, bool runtime)
        if (sdkp->WCE && sdkp->media_present) {
                if (!sdkp->device->silence_suspend)
                        sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
-               ret = sd_sync_cache(sdkp, &sshdr);
-
-               if (ret) {
-                       /* ignore OFFLINE device */
-                       if (ret == -ENODEV)
-                               return 0;
-
-                       if (!scsi_sense_valid(&sshdr) ||
-                           sshdr.sense_key != ILLEGAL_REQUEST)
-                               return ret;
+               ret = sd_sync_cache(sdkp);
+               /* ignore OFFLINE device */
+               if (ret == -ENODEV)
+                       return 0;
 
-                       /*
-                        * sshdr.sense_key == ILLEGAL_REQUEST means this drive
-                        * doesn't support sync. There's not much to do and
-                        * suspend shouldn't fail.
-                        */
-                       ret = 0;
-               }
+               if (ret)
+                       return ret;
        }
 
        if (sd_do_start_stop(sdkp->device, runtime)) {