diff options
-rw-r--r-- | drivers/block/cciss.c | 51 | ||||
-rw-r--r-- | drivers/block/cciss.h | 3 |
2 files changed, 34 insertions, 20 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 3cd8397f82bd..f49dcd734d1b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4486,6 +4486,34 @@ static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) return 0; } +static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) +{ + int i; + + if (!reset_devices) + return 0; + + /* Reset the controller with a PCI power-cycle */ + if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) + return -ENODEV; + + /* Some devices (notably the HP Smart Array 5i Controller) + need a little pause here */ + msleep(CCISS_POST_RESET_PAUSE_MSECS); + + /* Now try to get the controller to respond to a no-op */ + for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { + if (cciss_noop(pdev) == 0) + break; + else + dev_warn(&pdev->dev, "no-op failed%s\n", + (i < CCISS_POST_RESET_NOOP_RETRIES - 1 ? + "; re-trying" : "")); + msleep(CCISS_POST_RESET_NOOP_INTERVAL_MSECS); + } + return 0; +} + /* * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. @@ -4501,26 +4529,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int dac, return_code; InquiryData_struct *inq_buff; - if (reset_devices) { - /* Reset the controller with a PCI power-cycle */ - if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) - return -ENODEV; - - /* Now try to get the controller to respond to a no-op. Some - devices (notably the HP Smart Array 5i Controller) need - up to 30 seconds to respond. */ - for (i=0; i<30; i++) { - if (cciss_noop(pdev) == 0) - break; - - schedule_timeout_uninterruptible(HZ); - } - if (i == 30) { - printk(KERN_ERR "cciss: controller seems dead\n"); - return -EBUSY; - } - } - + rc = cciss_init_reset_devices(pdev); + if (rc) + return rc; i = alloc_cciss_hba(); if (i < 0) return -1; diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index c2ef9dd56c45..4290b7f0f639 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -204,6 +204,9 @@ struct ctlr_info #define CCISS_BOARD_READY_ITERATIONS \ ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ CCISS_BOARD_READY_POLL_INTERVAL_MSECS) +#define CCISS_POST_RESET_PAUSE_MSECS (3000) +#define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) +#define CCISS_POST_RESET_NOOP_RETRIES (12) /* Send the command to the hardware |