aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index d40d5c79fff1..206c2fa8c1ba 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4194,6 +4194,25 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
4194} 4194}
4195 4195
4196/** 4196/**
4197 * ipr_isr_eh - Interrupt service routine error handler
4198 * @ioa_cfg: ioa config struct
4199 * @msg: message to log
4200 *
4201 * Return value:
4202 * none
4203 **/
4204static void ipr_isr_eh(struct ipr_ioa_cfg *ioa_cfg, char *msg)
4205{
4206 ioa_cfg->errors_logged++;
4207 dev_err(&ioa_cfg->pdev->dev, "%s\n", msg);
4208
4209 if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
4210 ioa_cfg->sdt_state = GET_DUMP;
4211
4212 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
4213}
4214
4215/**
4197 * ipr_isr - Interrupt service routine 4216 * ipr_isr - Interrupt service routine
4198 * @irq: irq number 4217 * @irq: irq number
4199 * @devp: pointer to ioa config struct 4218 * @devp: pointer to ioa config struct
@@ -4208,6 +4227,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4208 volatile u32 int_reg, int_mask_reg; 4227 volatile u32 int_reg, int_mask_reg;
4209 u32 ioasc; 4228 u32 ioasc;
4210 u16 cmd_index; 4229 u16 cmd_index;
4230 int num_hrrq = 0;
4211 struct ipr_cmnd *ipr_cmd; 4231 struct ipr_cmnd *ipr_cmd;
4212 irqreturn_t rc = IRQ_NONE; 4232 irqreturn_t rc = IRQ_NONE;
4213 4233
@@ -4238,13 +4258,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4238 IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT; 4258 IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT;
4239 4259
4240 if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) { 4260 if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) {
4241 ioa_cfg->errors_logged++; 4261 ipr_isr_eh(ioa_cfg, "Invalid response handle from IOA");
4242 dev_err(&ioa_cfg->pdev->dev, "Invalid response handle from IOA\n");
4243
4244 if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
4245 ioa_cfg->sdt_state = GET_DUMP;
4246
4247 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
4248 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 4262 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4249 return IRQ_HANDLED; 4263 return IRQ_HANDLED;
4250 } 4264 }
@@ -4271,8 +4285,18 @@ static irqreturn_t ipr_isr(int irq, void *devp)
4271 4285
4272 if (ipr_cmd != NULL) { 4286 if (ipr_cmd != NULL) {
4273 /* Clear the PCI interrupt */ 4287 /* Clear the PCI interrupt */
4274 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); 4288 do {
4275 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; 4289 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
4290 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
4291 } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
4292 num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
4293
4294 if (int_reg & IPR_PCII_HRRQ_UPDATED) {
4295 ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
4296 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
4297 return IRQ_HANDLED;
4298 }
4299
4276 } else 4300 } else
4277 break; 4301 break;
4278 } 4302 }