diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/cciss.c | 43 | ||||
-rw-r--r-- | drivers/block/cciss.h | 4 |
2 files changed, 39 insertions, 8 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f09e6df15aa7..fd08644bf2a0 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -4006,18 +4006,31 @@ static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, | |||
4006 | return -ENODEV; | 4006 | return -ENODEV; |
4007 | } | 4007 | } |
4008 | 4008 | ||
4009 | static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) | 4009 | static int __devinit cciss_wait_for_board_state(struct pci_dev *pdev, |
4010 | void __iomem *vaddr, int wait_for_ready) | ||
4011 | #define BOARD_READY 1 | ||
4012 | #define BOARD_NOT_READY 0 | ||
4010 | { | 4013 | { |
4011 | int i; | 4014 | int i, iterations; |
4012 | u32 scratchpad; | 4015 | u32 scratchpad; |
4013 | 4016 | ||
4014 | for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) { | 4017 | if (wait_for_ready) |
4015 | scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); | 4018 | iterations = CCISS_BOARD_READY_ITERATIONS; |
4016 | if (scratchpad == CCISS_FIRMWARE_READY) | 4019 | else |
4017 | return 0; | 4020 | iterations = CCISS_BOARD_NOT_READY_ITERATIONS; |
4021 | |||
4022 | for (i = 0; i < iterations; i++) { | ||
4023 | scratchpad = readl(vaddr + SA5_SCRATCHPAD_OFFSET); | ||
4024 | if (wait_for_ready) { | ||
4025 | if (scratchpad == CCISS_FIRMWARE_READY) | ||
4026 | return 0; | ||
4027 | } else { | ||
4028 | if (scratchpad != CCISS_FIRMWARE_READY) | ||
4029 | return 0; | ||
4030 | } | ||
4018 | msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); | 4031 | msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); |
4019 | } | 4032 | } |
4020 | dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); | 4033 | dev_warn(&pdev->dev, "board not ready, timed out.\n"); |
4021 | return -ENODEV; | 4034 | return -ENODEV; |
4022 | } | 4035 | } |
4023 | 4036 | ||
@@ -4183,7 +4196,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h) | |||
4183 | err = -ENOMEM; | 4196 | err = -ENOMEM; |
4184 | goto err_out_free_res; | 4197 | goto err_out_free_res; |
4185 | } | 4198 | } |
4186 | err = cciss_wait_for_board_ready(h); | 4199 | err = cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY); |
4187 | if (err) | 4200 | if (err) |
4188 | goto err_out_free_res; | 4201 | goto err_out_free_res; |
4189 | err = cciss_find_cfgtables(h); | 4202 | err = cciss_find_cfgtables(h); |
@@ -4534,6 +4547,20 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
4534 | need a little pause here */ | 4547 | need a little pause here */ |
4535 | msleep(CCISS_POST_RESET_PAUSE_MSECS); | 4548 | msleep(CCISS_POST_RESET_PAUSE_MSECS); |
4536 | 4549 | ||
4550 | /* Wait for board to become not ready, then ready. */ | ||
4551 | dev_info(&pdev->dev, "Waiting for board to become ready.\n"); | ||
4552 | rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY); | ||
4553 | if (rc) /* Don't bail, might be E500, etc. which can't be reset */ | ||
4554 | dev_warn(&pdev->dev, | ||
4555 | "failed waiting for board to become not ready\n"); | ||
4556 | rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_READY); | ||
4557 | if (rc) { | ||
4558 | dev_warn(&pdev->dev, | ||
4559 | "failed waiting for board to become ready\n"); | ||
4560 | goto unmap_cfgtable; | ||
4561 | } | ||
4562 | dev_info(&pdev->dev, "board ready.\n"); | ||
4563 | |||
4537 | /* Controller should be in simple mode at this point. If it's not, | 4564 | /* Controller should be in simple mode at this point. If it's not, |
4538 | * It means we're on one of those controllers which doesn't support | 4565 | * It means we're on one of those controllers which doesn't support |
4539 | * the doorbell reset method and on which the PCI power management reset | 4566 | * the doorbell reset method and on which the PCI power management reset |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index ae340ffc8f81..4b8933d778f1 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -200,10 +200,14 @@ struct ctlr_info | |||
200 | * the above. | 200 | * the above. |
201 | */ | 201 | */ |
202 | #define CCISS_BOARD_READY_WAIT_SECS (120) | 202 | #define CCISS_BOARD_READY_WAIT_SECS (120) |
203 | #define CCISS_BOARD_NOT_READY_WAIT_SECS (10) | ||
203 | #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) | 204 | #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) |
204 | #define CCISS_BOARD_READY_ITERATIONS \ | 205 | #define CCISS_BOARD_READY_ITERATIONS \ |
205 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ | 206 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ |
206 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | 207 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) |
208 | #define CCISS_BOARD_NOT_READY_ITERATIONS \ | ||
209 | ((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \ | ||
210 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | ||
207 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) | 211 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) |
208 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) | 212 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) |
209 | #define CCISS_POST_RESET_NOOP_RETRIES (12) | 213 | #define CCISS_POST_RESET_NOOP_RETRIES (12) |