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

cciss: 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: Jens Axboe <jaxboe@fusionio.com>

authored by

Stephen M. Cameron and committed by
Jens Axboe
ec52d5f1 93c46c2f

+31 -5
+31 -5
drivers/block/cciss.c
··· 558 558 #define to_hba(n) container_of(n, struct ctlr_info, dev) 559 559 #define to_drv(n) container_of(n, drive_info_struct, dev) 560 560 561 - /* List of controllers which cannot be reset on kexec with reset_devices */ 561 + /* List of controllers which cannot be hard reset on kexec with reset_devices */ 562 562 static u32 unresettable_controller[] = { 563 563 0x324a103C, /* Smart Array P712m */ 564 564 0x324b103C, /* SmartArray P711m */ ··· 576 576 0x409D0E11, /* Smart Array 6400 EM */ 577 577 }; 578 578 579 - static int ctlr_is_resettable(struct ctlr_info *h) 579 + /* List of controllers which cannot even be soft reset */ 580 + static u32 soft_unresettable_controller[] = { 581 + 0x409C0E11, /* Smart Array 6400 */ 582 + 0x409D0E11, /* Smart Array 6400 EM */ 583 + }; 584 + 585 + static int ctlr_is_hard_resettable(u32 board_id) 580 586 { 581 587 int i; 582 588 583 589 for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++) 584 - if (unresettable_controller[i] == h->board_id) 590 + if (unresettable_controller[i] == board_id) 585 591 return 0; 586 592 return 1; 593 + } 594 + 595 + static int ctlr_is_soft_resettable(u32 board_id) 596 + { 597 + int i; 598 + 599 + for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++) 600 + if (soft_unresettable_controller[i] == board_id) 601 + return 0; 602 + return 1; 603 + } 604 + 605 + static int ctlr_is_resettable(u32 board_id) 606 + { 607 + return ctlr_is_hard_resettable(board_id) || 608 + ctlr_is_soft_resettable(board_id); 587 609 } 588 610 589 611 static ssize_t host_show_resettable(struct device *dev, ··· 614 592 { 615 593 struct ctlr_info *h = to_hba(dev); 616 594 617 - return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h)); 595 + return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h->board_id)); 618 596 } 619 597 static DEVICE_ATTR(resettable, S_IRUGO, host_show_resettable, NULL); 620 598 ··· 4623 4601 * likely not be happy. Just forbid resetting this conjoined mess. 4624 4602 */ 4625 4603 cciss_lookup_board_id(pdev, &board_id); 4626 - if (board_id == 0x409C0E11 || board_id == 0x409D0E11) { 4604 + if (!ctlr_is_resettable(board_id)) { 4627 4605 dev_warn(&pdev->dev, "Cannot reset Smart Array 640x " 4628 4606 "due to shared cache module."); 4629 4607 return -ENODEV; 4630 4608 } 4609 + 4610 + /* if controller is soft- but not hard resettable... */ 4611 + if (!ctlr_is_hard_resettable(board_id)) 4612 + return -ENOTSUPP; /* try soft reset later. */ 4631 4613 4632 4614 /* Save the PCI command register */ 4633 4615 pci_read_config_word(pdev, 4, &command_register);