diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2011-05-03 16:00:01 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-17 03:08:09 -0400 |
commit | 4638078697574be43816779845e26bf05ae70d9d (patch) | |
tree | 456d5301babd7f2a50bafffc1e741d91327241e4 /drivers/scsi/hpsa.c | |
parent | dfc2224828c5fc4ec7e11587b9d6b97283aa2d01 (diff) |
[SCSI] hpsa: do not attempt PCI power management reset method if we know it won't work.
Just go straight to the soft-reset method instead.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: James Bottomley <jbottomley@parallels.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ca8ee9220db0..5c03cb5e93b0 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -273,7 +273,7 @@ static ssize_t host_show_transport_mode(struct device *dev, | |||
273 | "performant" : "simple"); | 273 | "performant" : "simple"); |
274 | } | 274 | } |
275 | 275 | ||
276 | /* List of controllers which cannot be reset on kexec with reset_devices */ | 276 | /* List of controllers which cannot be hard reset on kexec with reset_devices */ |
277 | static u32 unresettable_controller[] = { | 277 | static u32 unresettable_controller[] = { |
278 | 0x324a103C, /* Smart Array P712m */ | 278 | 0x324a103C, /* Smart Array P712m */ |
279 | 0x324b103C, /* SmartArray P711m */ | 279 | 0x324b103C, /* SmartArray P711m */ |
@@ -291,16 +291,45 @@ static u32 unresettable_controller[] = { | |||
291 | 0x409D0E11, /* Smart Array 6400 EM */ | 291 | 0x409D0E11, /* Smart Array 6400 EM */ |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static int ctlr_is_resettable(struct ctlr_info *h) | 294 | /* List of controllers which cannot even be soft reset */ |
295 | static u32 soft_unresettable_controller[] = { | ||
296 | /* Exclude 640x boards. These are two pci devices in one slot | ||
297 | * which share a battery backed cache module. One controls the | ||
298 | * cache, the other accesses the cache through the one that controls | ||
299 | * it. If we reset the one controlling the cache, the other will | ||
300 | * likely not be happy. Just forbid resetting this conjoined mess. | ||
301 | * The 640x isn't really supported by hpsa anyway. | ||
302 | */ | ||
303 | 0x409C0E11, /* Smart Array 6400 */ | ||
304 | 0x409D0E11, /* Smart Array 6400 EM */ | ||
305 | }; | ||
306 | |||
307 | static int ctlr_is_hard_resettable(u32 board_id) | ||
295 | { | 308 | { |
296 | int i; | 309 | int i; |
297 | 310 | ||
298 | for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++) | 311 | for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++) |
299 | if (unresettable_controller[i] == h->board_id) | 312 | if (unresettable_controller[i] == board_id) |
313 | return 0; | ||
314 | return 1; | ||
315 | } | ||
316 | |||
317 | static int ctlr_is_soft_resettable(u32 board_id) | ||
318 | { | ||
319 | int i; | ||
320 | |||
321 | for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++) | ||
322 | if (soft_unresettable_controller[i] == board_id) | ||
300 | return 0; | 323 | return 0; |
301 | return 1; | 324 | return 1; |
302 | } | 325 | } |
303 | 326 | ||
327 | static int ctlr_is_resettable(u32 board_id) | ||
328 | { | ||
329 | return ctlr_is_hard_resettable(board_id) || | ||
330 | ctlr_is_soft_resettable(board_id); | ||
331 | } | ||
332 | |||
304 | static ssize_t host_show_resettable(struct device *dev, | 333 | static ssize_t host_show_resettable(struct device *dev, |
305 | struct device_attribute *attr, char *buf) | 334 | struct device_attribute *attr, char *buf) |
306 | { | 335 | { |
@@ -308,7 +337,7 @@ static ssize_t host_show_resettable(struct device *dev, | |||
308 | struct Scsi_Host *shost = class_to_shost(dev); | 337 | struct Scsi_Host *shost = class_to_shost(dev); |
309 | 338 | ||
310 | h = shost_to_hba(shost); | 339 | h = shost_to_hba(shost); |
311 | return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h)); | 340 | return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h->board_id)); |
312 | } | 341 | } |
313 | 342 | ||
314 | static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) | 343 | static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[]) |
@@ -3334,20 +3363,15 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
3334 | * using the doorbell register. | 3363 | * using the doorbell register. |
3335 | */ | 3364 | */ |
3336 | 3365 | ||
3337 | /* Exclude 640x boards. These are two pci devices in one slot | ||
3338 | * which share a battery backed cache module. One controls the | ||
3339 | * cache, the other accesses the cache through the one that controls | ||
3340 | * it. If we reset the one controlling the cache, the other will | ||
3341 | * likely not be happy. Just forbid resetting this conjoined mess. | ||
3342 | * The 640x isn't really supported by hpsa anyway. | ||
3343 | */ | ||
3344 | rc = hpsa_lookup_board_id(pdev, &board_id); | 3366 | rc = hpsa_lookup_board_id(pdev, &board_id); |
3345 | if (rc < 0) { | 3367 | if (rc < 0 || !ctlr_is_resettable(board_id)) { |
3346 | dev_warn(&pdev->dev, "Not resetting device.\n"); | 3368 | dev_warn(&pdev->dev, "Not resetting device.\n"); |
3347 | return -ENODEV; | 3369 | return -ENODEV; |
3348 | } | 3370 | } |
3349 | if (board_id == 0x409C0E11 || board_id == 0x409D0E11) | 3371 | |
3350 | return -ENOTSUPP; | 3372 | /* if controller is soft- but not hard resettable... */ |
3373 | if (!ctlr_is_hard_resettable(board_id)) | ||
3374 | return -ENOTSUPP; /* try soft reset later. */ | ||
3351 | 3375 | ||
3352 | /* Save the PCI command register */ | 3376 | /* Save the PCI command register */ |
3353 | pci_read_config_word(pdev, 4, &command_register); | 3377 | pci_read_config_word(pdev, 4, &command_register); |