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

scsi: smartpqi: add kdump support

Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Kevin Barnett and committed by
Martin K. Petersen
ff6abb73 14bb215d

+57 -3
+10 -3
drivers/scsi/smartpqi/smartpqi.h
··· 79 79 __le32 sis_ctrl_to_host_doorbell; /* 9Ch */ 80 80 u8 reserved3[0xa0 - (0x9c + sizeof(__le32))]; 81 81 __le32 sis_ctrl_to_host_doorbell_clear; /* A0h */ 82 - u8 reserved4[0xbc - (0xa0 + sizeof(__le32))]; 82 + u8 reserved4[0xb0 - (0xa0 + sizeof(__le32))]; 83 + __le32 sis_driver_scratch; /* B0h */ 84 + u8 reserved5[0xbc - (0xb0 + sizeof(__le32))]; 83 85 __le32 sis_firmware_status; /* BCh */ 84 - u8 reserved5[0x1000 - (0xbc + sizeof(__le32))]; 86 + u8 reserved6[0x1000 - (0xbc + sizeof(__le32))]; 85 87 __le32 sis_mailbox[8]; /* 1000h */ 86 - u8 reserved6[0x4000 - (0x1000 + (sizeof(__le32) * 8))]; 88 + u8 reserved7[0x4000 - (0x1000 + (sizeof(__le32) * 8))]; 87 89 /* 88 90 * The PQI spec states that the PQI registers should be at 89 91 * offset 0 from the PCIe BAR 0. However, we can't map ··· 963 961 964 962 struct semaphore sync_request_sem; 965 963 struct semaphore lun_reset_sem; 964 + }; 965 + 966 + enum pqi_ctrl_mode { 967 + UNKNOWN, 968 + PQI_MODE 966 969 }; 967 970 968 971 /*
+35
drivers/scsi/smartpqi/smartpqi_init.c
··· 153 153 return pqi_scsi3addr_equal(scsi3addr, RAID_CTLR_LUNID); 154 154 } 155 155 156 + static inline enum pqi_ctrl_mode pqi_get_ctrl_mode( 157 + struct pqi_ctrl_info *ctrl_info) 158 + { 159 + return sis_read_driver_scratch(ctrl_info); 160 + } 161 + 162 + static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info, 163 + enum pqi_ctrl_mode mode) 164 + { 165 + sis_write_driver_scratch(ctrl_info, mode); 166 + } 167 + 156 168 #define PQI_RESCAN_WORK_INTERVAL (10 * HZ) 157 169 158 170 static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info) ··· 5278 5266 return rc; 5279 5267 } 5280 5268 5269 + static int pqi_kdump_init(struct pqi_ctrl_info *ctrl_info) 5270 + { 5271 + if (!sis_is_firmware_running(ctrl_info)) 5272 + return -ENXIO; 5273 + 5274 + if (pqi_get_ctrl_mode(ctrl_info) == PQI_MODE) { 5275 + sis_disable_msix(ctrl_info); 5276 + if (pqi_reset(ctrl_info) == 0) 5277 + sis_reenable_sis_mode(ctrl_info); 5278 + } 5279 + 5280 + return 0; 5281 + } 5282 + 5281 5283 static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) 5282 5284 { 5283 5285 int rc; 5286 + 5287 + if (reset_devices) { 5288 + rc = pqi_kdump_init(ctrl_info); 5289 + if (rc) 5290 + return rc; 5291 + } 5284 5292 5285 5293 /* 5286 5294 * When the controller comes out of reset, it is always running ··· 5375 5343 5376 5344 /* From here on, we are running in PQI mode. */ 5377 5345 ctrl_info->pqi_mode_enabled = true; 5346 + pqi_save_ctrl_mode(ctrl_info, PQI_MODE); 5378 5347 5379 5348 rc = pqi_alloc_admin_queues(ctrl_info); 5380 5349 if (rc) { ··· 5911 5878 sis_ctrl_to_host_doorbell) != 0x9c); 5912 5879 BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, 5913 5880 sis_ctrl_to_host_doorbell_clear) != 0xa0); 5881 + BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, 5882 + sis_driver_scratch) != 0xb0); 5914 5883 BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, 5915 5884 sis_firmware_status) != 0xbc); 5916 5885 BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers,
+10
drivers/scsi/smartpqi/smartpqi_sis.c
··· 376 376 return rc; 377 377 } 378 378 379 + void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value) 380 + { 381 + writel(value, &ctrl_info->registers->sis_driver_scratch); 382 + } 383 + 384 + u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info) 385 + { 386 + return readl(&ctrl_info->registers->sis_driver_scratch); 387 + } 388 + 379 389 static void __attribute__((unused)) verify_structures(void) 380 390 { 381 391 BUILD_BUG_ON(offsetof(struct sis_base_struct,
+2
drivers/scsi/smartpqi/smartpqi_sis.h
··· 28 28 void sis_disable_msix(struct pqi_ctrl_info *ctrl_info); 29 29 void sis_soft_reset(struct pqi_ctrl_info *ctrl_info); 30 30 int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info); 31 + void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value); 32 + u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info); 31 33 32 34 #endif /* _SMARTPQI_SIS_H */