diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2010-07-19 13:46:17 -0500 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 18:52:12 +0200 |
commit | 83123cb11b5a5205233c59357da2c8d9a8dc9d24 (patch) | |
tree | 6f74b67b9de4e59223efdeeb774ce17a1e7bf5d7 /drivers/block | |
parent | 8e93bf6d6c9c6d864c17b7743f2cc5f2e052fe46 (diff) | |
download | linux-83123cb11b5a5205233c59357da2c8d9a8dc9d24.tar.bz2 |
cciss: factor out cciss_reset_devices()
cciss: factor out cciss_reset_devices()
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block')
-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 |