Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Stephen M. Cameron and committed by
James Bottomley
cf0b08d0 9a41338e

+22 -5
+20 -5
drivers/scsi/hpsa.c
··· 3128 3128 #define hpsa_noop(p) hpsa_message(p, 3, 0) 3129 3129 3130 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 3133 u16 pmcsr; 3134 3134 int pos; ··· 3139 3139 * other way using the doorbell register. 3140 3140 */ 3141 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 3143 msleep(1000); 3144 3144 } else { /* Try to do it the PCI power state way */ 3145 3145 ··· 3243 3243 u32 misc_fw_support; 3244 3244 int rc; 3245 3245 struct CfgTable __iomem *cfgtable; 3246 - bool use_doorbell; 3246 + u32 use_doorbell; 3247 3247 u32 board_id; 3248 3248 u16 command_register; 3249 3249 ··· 3306 3306 if (rc) 3307 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 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 3328 rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell); 3314 3329 if (rc)
+2
drivers/scsi/hpsa_cmd.h
··· 101 101 #define CFGTBL_ChangeReq 0x00000001l 102 102 #define CFGTBL_AccCmds 0x00000001l 103 103 #define DOORBELL_CTLR_RESET 0x00000004l 104 + #define DOORBELL_CTLR_RESET2 0x00000020l 104 105 105 106 #define CFGTBL_Trans_Simple 0x00000002l 106 107 #define CFGTBL_Trans_Performant 0x00000004l ··· 338 337 u8 reserved[0x78 - 0x58]; 339 338 u32 misc_fw_support; /* offset 0x78 */ 340 339 #define MISC_FW_DOORBELL_RESET (0x02) 340 + #define MISC_FW_DOORBELL_RESET2 (0x010) 341 341 u8 driver_version[32]; 342 342 }; 343 343