aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hpsa.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2011-05-03 15:59:46 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-17 03:07:01 -0400
commitcf0b08d0cd87ada9d284925834d08fb8026da888 (patch)
tree41c1c9facfd1daa5d848e07904c377be350bf831 /drivers/scsi/hpsa.c
parent9a41338e5b474add499a7ca2a5a76148e5076805 (diff)
[SCSI] hpsa: 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: James Bottomley <jbottomley@parallels.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r--drivers/scsi/hpsa.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index ca92141b7736..c096cda3a6f4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3128,7 +3128,7 @@ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode,
3128#define hpsa_noop(p) hpsa_message(p, 3, 0) 3128#define hpsa_noop(p) hpsa_message(p, 3, 0)
3129 3129
3130static int hpsa_controller_hard_reset(struct pci_dev *pdev, 3130static int hpsa_controller_hard_reset(struct pci_dev *pdev,
3131 void * __iomem vaddr, bool use_doorbell) 3131 void * __iomem vaddr, u32 use_doorbell)
3132{ 3132{
3133 u16 pmcsr; 3133 u16 pmcsr;
3134 int pos; 3134 int pos;
@@ -3139,7 +3139,7 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
3139 * other way using the doorbell register. 3139 * other way using the doorbell register.
3140 */ 3140 */
3141 dev_info(&pdev->dev, "using doorbell to reset controller\n"); 3141 dev_info(&pdev->dev, "using doorbell to reset controller\n");
3142 writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL); 3142 writel(use_doorbell, vaddr + SA5_DOORBELL);
3143 msleep(1000); 3143 msleep(1000);
3144 } else { /* Try to do it the PCI power state way */ 3144 } else { /* Try to do it the PCI power state way */
3145 3145
@@ -3243,7 +3243,7 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3243 u32 misc_fw_support; 3243 u32 misc_fw_support;
3244 int rc; 3244 int rc;
3245 struct CfgTable __iomem *cfgtable; 3245 struct CfgTable __iomem *cfgtable;
3246 bool use_doorbell; 3246 u32 use_doorbell;
3247 u32 board_id; 3247 u32 board_id;
3248 u16 command_register; 3248 u16 command_register;
3249 3249
@@ -3306,9 +3306,24 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
3306 if (rc) 3306 if (rc)
3307 goto unmap_vaddr; 3307 goto unmap_vaddr;
3308 3308
3309 /* If reset via doorbell register is supported, use that. */ 3309 /* If reset via doorbell register is supported, use that.
3310 * There are two such methods. Favor the newest method.
3311 */
3310 misc_fw_support = readl(&cfgtable->misc_fw_support); 3312 misc_fw_support = readl(&cfgtable->misc_fw_support);
3311 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; 3313 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET2;
3314 if (use_doorbell) {
3315 use_doorbell = DOORBELL_CTLR_RESET2;
3316 } else {
3317 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
3318 if (use_doorbell) {
3319 dev_warn(&pdev->dev, "Controller claims that "
3320 "'Bit 2 doorbell reset' is "
3321 "supported, but not 'bit 5 doorbell reset'. "
3322 "Firmware update is recommended.\n");
3323 rc = -ENODEV;
3324 goto unmap_cfgtable;
3325 }
3326 }
3312 3327
3313 rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell); 3328 rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
3314 if (rc) 3329 if (rc)