|
@@ -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)
|