cciss: use new doorbell-bit-5 reset method
The bit-2-doorbell reset method seemed to cause (survivable) NMIs on some systems and (unsurvivable) IOCK NMIs on some G7 servers. Firmware guys implemented a new doorbell method to alleviate these problems triggered by bit 5 of the doorbell register. We want to use it if it's available. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
This commit is contained in:
parent
3e28601fdf
commit
bf2e2e6b87
|
@ -4384,7 +4384,7 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u
|
|||
#define cciss_noop(p) cciss_message(p, 3, 0)
|
||||
|
||||
static int cciss_controller_hard_reset(struct pci_dev *pdev,
|
||||
void * __iomem vaddr, bool use_doorbell)
|
||||
void * __iomem vaddr, u32 use_doorbell)
|
||||
{
|
||||
u16 pmcsr;
|
||||
int pos;
|
||||
|
@ -4395,7 +4395,7 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev,
|
|||
* other way using the doorbell register.
|
||||
*/
|
||||
dev_info(&pdev->dev, "using doorbell to reset controller\n");
|
||||
writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL);
|
||||
writel(use_doorbell, vaddr + SA5_DOORBELL);
|
||||
msleep(1000);
|
||||
} else { /* Try to do it the PCI power state way */
|
||||
|
||||
|
@ -4499,7 +4499,7 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
|
|||
u32 misc_fw_support;
|
||||
int rc;
|
||||
CfgTable_struct __iomem *cfgtable;
|
||||
bool use_doorbell;
|
||||
u32 use_doorbell;
|
||||
u32 board_id;
|
||||
u16 command_register;
|
||||
|
||||
|
@ -4560,15 +4560,18 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
|
|||
if (rc)
|
||||
goto unmap_vaddr;
|
||||
|
||||
/* If reset via doorbell register is supported, use that. */
|
||||
misc_fw_support = readl(&cfgtable->misc_fw_support);
|
||||
use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
|
||||
|
||||
/* The doorbell reset seems to cause lockups on some Smart
|
||||
* Arrays (e.g. P410, P410i, maybe others). Until this is
|
||||
* fixed or at least isolated, avoid the doorbell reset.
|
||||
/* If reset via doorbell register is supported, use that.
|
||||
* There are two such methods. Favor the newest method.
|
||||
*/
|
||||
use_doorbell = 0;
|
||||
misc_fw_support = readl(&cfgtable->misc_fw_support);
|
||||
use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET2;
|
||||
if (use_doorbell) {
|
||||
use_doorbell = DOORBELL_CTLR_RESET2;
|
||||
} else {
|
||||
use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
|
||||
if (use_doorbell)
|
||||
use_doorbell = DOORBELL_CTLR_RESET;
|
||||
}
|
||||
|
||||
rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
|
||||
if (rc)
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#define CFGTBL_ChangeReq 0x00000001l
|
||||
#define CFGTBL_AccCmds 0x00000001l
|
||||
#define DOORBELL_CTLR_RESET 0x00000004l
|
||||
#define DOORBELL_CTLR_RESET2 0x00000020l
|
||||
|
||||
#define CFGTBL_Trans_Simple 0x00000002l
|
||||
#define CFGTBL_Trans_Performant 0x00000004l
|
||||
|
@ -243,6 +244,7 @@ typedef struct _CfgTable_struct {
|
|||
u8 reserved[0x78 - 0x58];
|
||||
u32 misc_fw_support; /* offset 0x78 */
|
||||
#define MISC_FW_DOORBELL_RESET (0x02)
|
||||
#define MISC_FW_DOORBELL_RESET2 (0x10)
|
||||
u8 driver_version[32];
|
||||
} CfgTable_struct;
|
||||
|
||||
|
|
Loading…
Reference in New Issue