Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf2e2e6b authored by Stephen M. Cameron's avatar Stephen M. Cameron Committed by Jens Axboe
Browse files

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: default avatarStephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: default avatarJens Axboe <jaxboe@fusionio.com>
parent 3e28601f
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -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. */
	/* If reset via doorbell register is supported, use that.
	 * There are two such methods.  Favor the newest method.
	 */
	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;

	/* 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.
	 */
	use_doorbell = 0;
		if (use_doorbell)
			use_doorbell = DOORBELL_CTLR_RESET;
	}

	rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
	if (rc)
+2 −0
Original line number Diff line number Diff line
@@ -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;