Skip to content

Commit

Permalink
[SCSI] ipr: Driver initialization fix for kexec/kdump
Browse files Browse the repository at this point in the history
When kexec booting a kernel when the previous kernel did not
call ipr's shutdown method, the ipr adapter does not get
properly initialized, which can result in the ipr adapter
completing commands issued by the previous kernel. Fix ipr
to detect this scenario by reading the adapter's interrupt
mask register and the microprocessor interrupt register.
If the interrupt mask register indicates that interrupts
are enabled or the reset alert bit is set when the card is
probed, this means the card is in an unknown state and we
hard reset the card.

Signed-off-by: Brian King <brking@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
brking@us.ibm.com authored and James Bottomley committed Dec 14, 2005
1 parent ed7e8ef commit ce155cc
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
17 changes: 16 additions & 1 deletion drivers/scsi/ipr.c
Original file line number Diff line number Diff line change
Expand Up @@ -5887,7 +5887,12 @@ static int __devinit ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
ENTER;
spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg);
_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE);
if (ioa_cfg->needs_hard_reset) {
ioa_cfg->needs_hard_reset = 0;
ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
} else
_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa,
IPR_SHUTDOWN_NONE);

spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
Expand Down Expand Up @@ -6264,6 +6269,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
unsigned long ipr_regs_pci;
void __iomem *ipr_regs;
u32 rc = PCIBIOS_SUCCESSFUL;
volatile u32 mask, uproc;

ENTER;

Expand Down Expand Up @@ -6356,6 +6362,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
goto cleanup_nomem;
}

/*
* If HRRQ updated interrupt is not masked, or reset alert is set,
* the card is in an unknown state and needs a hard reset
*/
mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
ioa_cfg->needs_hard_reset = 1;

ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
rc = request_irq(pdev->irq, ipr_isr, SA_SHIRQ, IPR_NAME, ioa_cfg);

Expand Down
5 changes: 3 additions & 2 deletions drivers/scsi/ipr.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
/*
* Literals
*/
#define IPR_DRIVER_VERSION "2.1.0"
#define IPR_DRIVER_DATE "(October 31, 2005)"
#define IPR_DRIVER_VERSION "2.1.1"
#define IPR_DRIVER_DATE "(November 15, 2005)"

/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
Expand Down Expand Up @@ -922,6 +922,7 @@ struct ipr_ioa_cfg {
u8 dump_taken:1;
u8 allow_cmds:1;
u8 allow_ml_add_del:1;
u8 needs_hard_reset:1;

enum ipr_cache_state cache_state;
u16 type; /* CCIN of the card */
Expand Down

0 comments on commit ce155cc

Please sign in to comment.