diff options
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) | |||
4486 | return 0; | 4486 | return 0; |
4487 | } | 4487 | } |
4488 | 4488 | ||
4489 | static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) | ||
4490 | { | ||
4491 | int i; | ||
4492 | |||
4493 | if (!reset_devices) | ||
4494 | return 0; | ||
4495 | |||
4496 | /* Reset the controller with a PCI power-cycle */ | ||
4497 | if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) | ||
4498 | return -ENODEV; | ||
4499 | |||
4500 | /* Some devices (notably the HP Smart Array 5i Controller) | ||
4501 | need a little pause here */ | ||
4502 | msleep(CCISS_POST_RESET_PAUSE_MSECS); | ||
4503 | |||
4504 | /* Now try to get the controller to respond to a no-op */ | ||
4505 | for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { | ||
4506 | if (cciss_noop(pdev) == 0) | ||
4507 | break; | ||
4508 | else | ||
4509 | dev_warn(&pdev->dev, "no-op failed%s\n", | ||
4510 | (i < CCISS_POST_RESET_NOOP_RETRIES - 1 ? | ||
4511 | "; re-trying" : "")); | ||
4512 | msleep(CCISS_POST_RESET_NOOP_INTERVAL_MSECS); | ||
4513 | } | ||
4514 | return 0; | ||
4515 | } | ||
4516 | |||
4489 | /* | 4517 | /* |
4490 | * This is it. Find all the controllers and register them. I really hate | 4518 | * This is it. Find all the controllers and register them. I really hate |
4491 | * stealing all these major device numbers. | 4519 | * stealing all these major device numbers. |
@@ -4501,26 +4529,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4501 | int dac, return_code; | 4529 | int dac, return_code; |
4502 | InquiryData_struct *inq_buff; | 4530 | InquiryData_struct *inq_buff; |
4503 | 4531 | ||
4504 | if (reset_devices) { | 4532 | rc = cciss_init_reset_devices(pdev); |
4505 | /* Reset the controller with a PCI power-cycle */ | 4533 | if (rc) |
4506 | if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) | 4534 | return rc; |
4507 | return -ENODEV; | ||
4508 | |||
4509 | /* Now try to get the controller to respond to a no-op. Some | ||
4510 | devices (notably the HP Smart Array 5i Controller) need | ||
4511 | up to 30 seconds to respond. */ | ||
4512 | for (i=0; i<30; i++) { | ||
4513 | if (cciss_noop(pdev) == 0) | ||
4514 | break; | ||
4515 | |||
4516 | schedule_timeout_uninterruptible(HZ); | ||
4517 | } | ||
4518 | if (i == 30) { | ||
4519 | printk(KERN_ERR "cciss: controller seems dead\n"); | ||
4520 | return -EBUSY; | ||
4521 | } | ||
4522 | } | ||
4523 | |||
4524 | i = alloc_cciss_hba(); | 4535 | i = alloc_cciss_hba(); |
4525 | if (i < 0) | 4536 | if (i < 0) |
4526 | return -1; | 4537 | 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 | |||
204 | #define CCISS_BOARD_READY_ITERATIONS \ | 204 | #define CCISS_BOARD_READY_ITERATIONS \ |
205 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ | 205 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ |
206 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | 206 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) |
207 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) | ||
208 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) | ||
209 | #define CCISS_POST_RESET_NOOP_RETRIES (12) | ||
207 | 210 | ||
208 | /* | 211 | /* |
209 | Send the command to the hardware | 212 | Send the command to the hardware |