diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2011-05-03 15:59:46 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-17 03:07:01 -0400 |
commit | cf0b08d0cd87ada9d284925834d08fb8026da888 (patch) | |
tree | 41c1c9facfd1daa5d848e07904c377be350bf831 /drivers/scsi/hpsa.c | |
parent | 9a41338e5b474add499a7ca2a5a76148e5076805 (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.c | 25 |
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 | ||
3130 | static int hpsa_controller_hard_reset(struct pci_dev *pdev, | 3130 | static 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) |