]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: megaraid_sas: Send SYNCHRONIZE_CACHE for VD to firmware
authorKashyap Desai <kashyap.desai@broadcom.com>
Fri, 21 Oct 2016 13:33:33 +0000 (06:33 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Tue, 28 Feb 2017 04:40:09 +0000 (20:40 -0800)
Orabug: 25568930

Until now the megaraid_sas driver has reported successful completion on
SYNCHRONIZE_CACHE commands without sending them down to the controller.
The controller firmware has been responsible for taking care of flushing
disk caches for all drives that belong to a Virtual Disk at the time of
system reboot/shutdown.

There may have been a reason to avoid sending SYNCHRONIZE_CACHE to a VD
in the past but that no longer appears to be valid.

Older versions of MegaRaid firmware (Gen2 and Gen2.5) set the WCE bit
for Virtual Disks but the firmware does not report correct completion
status for a SYNCHRONIZE_CACHE command. As a result, we must use another
method to identify whether it is safe to send the command to the
controller. We use the canHandleSyncCache firmware flag in the scratch
pad register at offset 0xB4.

New SYNCHRONIZE_CACHE behavior:

IF 'JBOD'

Driver sends SYNCHRONIZE_CACHE command to the firmware
Firmware sends SYNCHRONIZE_CACHE to drive
Firmware obtains status from drive and returns same status back to driver

ELSEIF 'VirtualDisk'

IF firmware supports new API bit called canHandleSyncCache
Driver sends SYNCHRONIZE_CACHE command to the firmware
Firmware does not send SYNCHRONIZE_CACHE to drives
Firmware returns SUCCESS
ELSE
Driver does not send SYNCHRONIZE_CACHE command to the firmware
Driver return SUCCESS for that command
ENDIF
ENDIF

[mkp: edited patch description]

Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit d0fc91d67c59068ce6d42e41ce66a4c471e5bc74)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fusion.c

index ca86c885dfaab4f0fb6ae3595922d6f1a77974be..43fd14fad1a6214cf6fc4c2b82f0a996f5bc9021 100644 (file)
@@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT {
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
 #define MR_MAX_MSIX_REG_ARRAY                   16
 #define MR_RDPQ_MODE_OFFSET                    0X00800000
+#define MR_CAN_HANDLE_SYNC_CACHE_OFFSET                0X01000000
+
 /*
 * register set for both 1068 and 1078 controllers
 * structure extended for 1078 registers
@@ -2140,6 +2142,7 @@ struct megasas_instance {
        u8 is_imr;
        u8 is_rdpq;
        bool dev_handle;
+       bool fw_sync_cache_support;
 };
 struct MR_LD_VF_MAP {
        u32 size;
index e442f7ff534e2d5bfa5cb098ab2b8e87ef110fcc..07e71915a5e60f7a663028de273a7c2a8b6972da 100644 (file)
@@ -1701,11 +1701,8 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
                goto out_done;
        }
 
-       /*
-        * FW takes care of flush cache on its own for Virtual Disk.
-        * No need to send it down for VD. For JBOD send SYNCHRONIZE_CACHE to FW.
-        */
-       if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd)) {
+       if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd) &&
+               (!instance->fw_sync_cache_support)) {
                scmd->result = DID_OK << 16;
                goto out_done;
        }
index c6b74fde3e4b513291ada958265ba99e2c47e0cb..6a88afedbde595c962d50d1140ae1f2c50200991 100644 (file)
@@ -748,6 +748,11 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
                goto fail_fw_init;
        }
 
+       instance->fw_sync_cache_support = (scratch_pad_2 &
+               MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0;
+       dev_info(&instance->pdev->dev, "FW supports sync cache\t: %s\n",
+                instance->fw_sync_cache_support ? "Yes" : "No");
+
        IOCInitMessage =
          dma_alloc_coherent(&instance->pdev->dev,
                             sizeof(struct MPI2_IOC_INIT_REQUEST),