diff options
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 9acfce3bbe78..9fbc6f9120ac 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -3483,9 +3483,11 @@ static void start_io(struct ctlr_info *h) | |||
3483 | c = list_entry(h->reqQ.next, struct CommandList, list); | 3483 | c = list_entry(h->reqQ.next, struct CommandList, list); |
3484 | /* can't do anything if fifo is full */ | 3484 | /* can't do anything if fifo is full */ |
3485 | if ((h->access.fifo_full(h))) { | 3485 | if ((h->access.fifo_full(h))) { |
3486 | h->fifo_recently_full = 1; | ||
3486 | dev_warn(&h->pdev->dev, "fifo full\n"); | 3487 | dev_warn(&h->pdev->dev, "fifo full\n"); |
3487 | break; | 3488 | break; |
3488 | } | 3489 | } |
3490 | h->fifo_recently_full = 0; | ||
3489 | 3491 | ||
3490 | /* Get the first entry from the Request Q */ | 3492 | /* Get the first entry from the Request Q */ |
3491 | removeQ(c); | 3493 | removeQ(c); |
@@ -3539,15 +3541,41 @@ static inline int bad_tag(struct ctlr_info *h, u32 tag_index, | |||
3539 | static inline void finish_cmd(struct CommandList *c) | 3541 | static inline void finish_cmd(struct CommandList *c) |
3540 | { | 3542 | { |
3541 | unsigned long flags; | 3543 | unsigned long flags; |
3544 | int io_may_be_stalled = 0; | ||
3545 | struct ctlr_info *h = c->h; | ||
3542 | 3546 | ||
3543 | spin_lock_irqsave(&c->h->lock, flags); | 3547 | spin_lock_irqsave(&h->lock, flags); |
3544 | removeQ(c); | 3548 | removeQ(c); |
3545 | spin_unlock_irqrestore(&c->h->lock, flags); | 3549 | |
3550 | /* | ||
3551 | * Check for possibly stalled i/o. | ||
3552 | * | ||
3553 | * If a fifo_full condition is encountered, requests will back up | ||
3554 | * in h->reqQ. This queue is only emptied out by start_io which is | ||
3555 | * only called when a new i/o request comes in. If no i/o's are | ||
3556 | * forthcoming, the i/o's in h->reqQ can get stuck. So we call | ||
3557 | * start_io from here if we detect such a danger. | ||
3558 | * | ||
3559 | * Normally, we shouldn't hit this case, but pounding on the | ||
3560 | * CCISS_PASSTHRU ioctl can provoke it. Only call start_io if | ||
3561 | * commands_outstanding is low. We want to avoid calling | ||
3562 | * start_io from in here as much as possible, and esp. don't | ||
3563 | * want to get in a cycle where we call start_io every time | ||
3564 | * through here. | ||
3565 | */ | ||
3566 | if (unlikely(h->fifo_recently_full) && | ||
3567 | h->commands_outstanding < 5) | ||
3568 | io_may_be_stalled = 1; | ||
3569 | |||
3570 | spin_unlock_irqrestore(&h->lock, flags); | ||
3571 | |||
3546 | dial_up_lockup_detection_on_fw_flash_complete(c->h, c); | 3572 | dial_up_lockup_detection_on_fw_flash_complete(c->h, c); |
3547 | if (likely(c->cmd_type == CMD_SCSI)) | 3573 | if (likely(c->cmd_type == CMD_SCSI)) |
3548 | complete_scsi_command(c); | 3574 | complete_scsi_command(c); |
3549 | else if (c->cmd_type == CMD_IOCTL_PEND) | 3575 | else if (c->cmd_type == CMD_IOCTL_PEND) |
3550 | complete(c->waiting); | 3576 | complete(c->waiting); |
3577 | if (unlikely(io_may_be_stalled)) | ||
3578 | start_io(h); | ||
3551 | } | 3579 | } |
3552 | 3580 | ||
3553 | static inline u32 hpsa_tag_contains_index(u32 tag) | 3581 | static inline u32 hpsa_tag_contains_index(u32 tag) |