Commit 58322fe0 authored by Kevin Barnett's avatar Kevin Barnett Committed by Martin K. Petersen

scsi: smartpqi: enhance BMIC cache flush

 - distinguish between shutdown and non-shutdown.
Reviewed-by: default avatarScott Benesh <scott.benesh@microsemi.com>
Signed-off-by: default avatarKevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 336b6819
...@@ -1079,9 +1079,9 @@ enum pqi_ctrl_mode { ...@@ -1079,9 +1079,9 @@ enum pqi_ctrl_mode {
#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64 #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
#define BMIC_WRITE_HOST_WELLNESS 0xa5 #define BMIC_WRITE_HOST_WELLNESS 0xa5
#define BMIC_CACHE_FLUSH 0xc2 #define BMIC_FLUSH_CACHE 0xc2
#define SA_CACHE_FLUSH 0x1 #define SA_FLUSH_CACHE 0x1
#define MASKED_DEVICE(lunid) ((lunid)[3] & 0xc0) #define MASKED_DEVICE(lunid) ((lunid)[3] & 0xc0)
#define CISS_GET_LEVEL_2_BUS(lunid) ((lunid)[7] & 0x3f) #define CISS_GET_LEVEL_2_BUS(lunid) ((lunid)[7] & 0x3f)
...@@ -1187,6 +1187,23 @@ struct bmic_identify_physical_device { ...@@ -1187,6 +1187,23 @@ struct bmic_identify_physical_device {
u8 padding_to_multiple_of_512[9]; u8 padding_to_multiple_of_512[9];
}; };
struct bmic_flush_cache {
u8 disable_flag;
u8 system_power_action;
u8 ndu_flush;
u8 shutdown_event;
u8 reserved[28];
};
/* for shutdown_event member of struct bmic_flush_cache */
enum bmic_flush_cache_shutdown_event {
NONE_CACHE_FLUSH_ONLY = 0,
SHUTDOWN = 1,
HIBERNATE = 2,
SUSPEND = 3,
RESTART = 4
};
#pragma pack() #pragma pack()
int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info); int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info);
......
...@@ -431,10 +431,10 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, ...@@ -431,10 +431,10 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
cdb[1] = CISS_GET_RAID_MAP; cdb[1] = CISS_GET_RAID_MAP;
put_unaligned_be32(buffer_length, &cdb[6]); put_unaligned_be32(buffer_length, &cdb[6]);
break; break;
case SA_CACHE_FLUSH: case SA_FLUSH_CACHE:
request->data_direction = SOP_WRITE_FLAG; request->data_direction = SOP_WRITE_FLAG;
cdb[0] = BMIC_WRITE; cdb[0] = BMIC_WRITE;
cdb[6] = BMIC_CACHE_FLUSH; cdb[6] = BMIC_FLUSH_CACHE;
put_unaligned_be16(buffer_length, &cdb[7]); put_unaligned_be16(buffer_length, &cdb[7]);
break; break;
case BMIC_IDENTIFY_CONTROLLER: case BMIC_IDENTIFY_CONTROLLER:
...@@ -585,14 +585,13 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, ...@@ -585,14 +585,13 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
return rc; return rc;
} }
#define SA_CACHE_FLUSH_BUFFER_LENGTH 4 static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
enum bmic_flush_cache_shutdown_event shutdown_event)
static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info)
{ {
int rc; int rc;
struct pqi_raid_path_request request; struct pqi_raid_path_request request;
int pci_direction; int pci_direction;
u8 *buffer; struct bmic_flush_cache *flush_cache;
/* /*
* Don't bother trying to flush the cache if the controller is * Don't bother trying to flush the cache if the controller is
...@@ -601,13 +600,15 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info) ...@@ -601,13 +600,15 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info)
if (pqi_ctrl_offline(ctrl_info)) if (pqi_ctrl_offline(ctrl_info))
return -ENXIO; return -ENXIO;
buffer = kzalloc(SA_CACHE_FLUSH_BUFFER_LENGTH, GFP_KERNEL); flush_cache = kzalloc(sizeof(*flush_cache), GFP_KERNEL);
if (!buffer) if (!flush_cache)
return -ENOMEM; return -ENOMEM;
flush_cache->shutdown_event = shutdown_event;
rc = pqi_build_raid_path_request(ctrl_info, &request, rc = pqi_build_raid_path_request(ctrl_info, &request,
SA_CACHE_FLUSH, RAID_CTLR_LUNID, buffer, SA_FLUSH_CACHE, RAID_CTLR_LUNID, flush_cache,
SA_CACHE_FLUSH_BUFFER_LENGTH, 0, &pci_direction); sizeof(*flush_cache), 0, &pci_direction);
if (rc) if (rc)
goto out; goto out;
...@@ -618,7 +619,7 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info) ...@@ -618,7 +619,7 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info)
pci_direction); pci_direction);
out: out:
kfree(buffer); kfree(flush_cache);
return rc; return rc;
} }
...@@ -6693,7 +6694,7 @@ static void pqi_shutdown(struct pci_dev *pci_dev) ...@@ -6693,7 +6694,7 @@ static void pqi_shutdown(struct pci_dev *pci_dev)
* Write all data in the controller's battery-backed cache to * Write all data in the controller's battery-backed cache to
* storage. * storage.
*/ */
rc = pqi_flush_cache(ctrl_info); rc = pqi_flush_cache(ctrl_info, SHUTDOWN);
if (rc == 0) if (rc == 0)
return; return;
...@@ -6737,7 +6738,7 @@ static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t stat ...@@ -6737,7 +6738,7 @@ static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t stat
pqi_cancel_rescan_worker(ctrl_info); pqi_cancel_rescan_worker(ctrl_info);
pqi_wait_until_scan_finished(ctrl_info); pqi_wait_until_scan_finished(ctrl_info);
pqi_wait_until_lun_reset_finished(ctrl_info); pqi_wait_until_lun_reset_finished(ctrl_info);
pqi_flush_cache(ctrl_info); pqi_flush_cache(ctrl_info, SUSPEND);
pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_block_requests(ctrl_info);
pqi_ctrl_wait_until_quiesced(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info);
pqi_wait_until_inbound_queues_empty(ctrl_info); pqi_wait_until_inbound_queues_empty(ctrl_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment