From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
To: Greg KH <greg@kroah.com>
Cc: Linux Kernel list <linux-kernel@vger.kernel.org>,
linux-ia64@vger.kernel.org, linux-pci@atrey.karlin.mff.cuni.cz
Subject: [PATCH 6/6] PCIERR : interfaces for synchronous I/O error detection
Date: Fri, 24 Mar 2006 07:52:02 +0000 [thread overview]
Message-ID: <4423A522.4050902@jp.fujitsu.com> (raw)
In-Reply-To: <20060322210157.GH12335@kroah.com>
This is a sample of how to use.
This patch includes following changes:
1:
Change CHIPREG_READ32 & CHIPREG_WRITE32 to take three args,
pointer to adapter, and two memory addresses. And change
them to return the result of memory access.
2:
Set proper args to every CHIPREG_{READ,WRITE}32 call, and
also put error code that returns if the access failed.
3:
Declare a task that resets adapter. Schedule it if an error
is detected and reset is required. Using CHIPREG_*HR call is
convenient to require such reset on an error.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
-----
drivers/message/fusion/mptbase.c | 477 +++++++++++++++++++++++++++++----------
1 files changed, 359 insertions(+), 118 deletions(-)
Index: linux-2.6.16_WORK/drivers/message/fusion/mptbase.c
=================================--- linux-2.6.16_WORK.orig/drivers/message/fusion/mptbase.c
+++ linux-2.6.16_WORK/drivers/message/fusion/mptbase.c
@@ -181,16 +181,124 @@
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
+#ifdef CONFIG_PCIERR_CHECK
+static void mptbase_schedule_reset(void *ioc);
+static struct work_struct mptbase_rstTask;
+#endif
+
/* module entry point */
static int __init fusion_init (void);
static void __exit fusion_exit (void);
-#define CHIPREG_READ32(addr) readl_relaxed(addr)
-#define CHIPREG_READ32_dmasync(addr) readl(addr)
-#define CHIPREG_WRITE32(addr,val) writel(val, addr)
+#define CHIPREG_READ32HR(ioc,addr,val) pciras_readl(ioc,val,addr,1)
+#define CHIPREG_WRITE32HR(ioc,addr,val) pciras_writel(ioc,val,addr,1)
+#define CHIPREG_READ32(ioc,addr,val) pciras_readl(ioc,val,addr,0)
+#define CHIPREG_WRITE32(ioc,addr,val) pciras_writel(ioc,val,addr,0)
#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
+#ifdef CONFIG_PCIERR_CHECK
+#define PCI_ERR_RETRIES 2
+int
+pciras_readl(MPT_ADAPTER *ioc, u32 *regval, u32 *addr, int hres)
+{
+ u32 val;
+ u16 status;
+ iocookie cookie;
+ int retries = PCI_ERR_RETRIES;
+
+ do {
+ pcierr_clear(&cookie, ioc->pcidev);
+ val = ioread32(addr);
+ status = pcierr_read(&cookie);
+ if ((status) && (retries = PCI_ERR_RETRIES))
+ printk(MYIOC_s_WARN_FMT "pciras_readl(), "
+ "detects pci parity error, do retry.\n", ioc->name);
+ } while(status && (--retries > 0));
+
+ if (status) {
+ printk(MYIOC_s_WARN_FMT "pciras_readl(), detects pci parity "
+ "error, retries exhausted.\n", ioc->name);
+ if (hres)
+ schedule_work(&mptbase_rstTask);
+ return 1; /* Error */
+ }
+
+ if (regval)
+ *regval = val;
+ return 0; /* Success */
+}
+
+int
+pciras_writel(MPT_ADAPTER *ioc, u32 regval, u32 *addr, int hres)
+{
+ u16 status;
+ u16 perror;
+ int retries = PCI_ERR_RETRIES;
+
+ do {
+ perror = 0;
+ writel(regval, addr);
+ pci_read_config_word(ioc->pcidev, PCI_STATUS, &status);
+ if (status = 0xffff) {
+ if (retries = PCI_ERR_RETRIES)
+ printk(MYIOC_s_WARN_FMT "pciras_writel(), "
+ "couldn't read pci register.\n", ioc->name);
+ } else if (status & PCI_STATUS_DETECTED_PARITY) {
+ if (retries = PCI_ERR_RETRIES)
+ printk(MYIOC_s_WARN_FMT "pciras_writel(), "
+ "detects pci parity error, do retry.\n",
+ ioc->name);
+ perror = 1;
+ }
+ pci_write_config_word(ioc->pcidev, PCI_STATUS, status);
+ } while (perror && (--retries > 0));
+
+ if (perror) {
+ printk(MYIOC_s_WARN_FMT "pciras_writel(), detects pci "
+ "parity error, retries exhausted.\n", ioc->name);
+
+ if (hres)
+ schedule_work(&mptbase_rstTask);
+ return 1; /* Error */
+ }
+
+ return 0; /* Success */
+}
+
+static void
+mptbase_schedule_reset(void *arg)
+{
+ MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+
+ mpt_HardResetHandler(ioc, CAN_SLEEP);
+
+ return;
+}
+
+#else /* CONFIG_PCIERR_CHECK */
+
+static inline int
+pciras_readl(MPT_ADAPTER *ioc, u32 *regval, u32 *addr, int hres)
+{
+ u32 val;
+
+ val = ioread32(addr);
+ if (regval)
+ *regval = val;
+ return 0; /* Success */
+}
+
+static inline int
+pciras_writel(MPT_ADAPTER *ioc, u32 regval, u32 *addr, int hres)
+{
+ writel(regval, addr);
+
+ return 0; /* Success */
+}
+
+#endif
+
static void
pci_disable_io_access(struct pci_dev *pdev)
{
@@ -342,7 +450,7 @@
out:
/* Flush (non-TURBO) reply with a WRITE! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
+ CHIPREG_WRITE32HR(ioc, &ioc->chip->ReplyFifo, pa);
if (freeme)
mpt_free_msg_frame(ioc, mf);
@@ -373,12 +481,27 @@
MPT_ADAPTER *ioc = bus_id;
u32 pa;
+#ifdef CONFIG_PCIERR_CHECK
+ {
+ u16 status;
+
+ /* read status register to check whether DMA transfer was failed. */
+ pci_read_config_word(ioc->pcidev, PCI_STATUS, &status);
+ if (status & (PCI_STATUS_DETECTED_PARITY | PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT)) {
+ printk(MYIOC_s_WARN_FMT "mpt_interrupt(), detects pci parity error.\n", ioc->name);
+ pci_write_config_word(ioc->pcidev, PCI_STATUS, status);
+ schedule_work(&mptbase_rstTask);
+ return IRQ_HANDLED;
+ }
+ }
+#endif
/*
* Drain the reply FIFO!
*/
while (1) {
- pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
- if (pa = 0xFFFFFFFF)
+ u16 status;
+ status = CHIPREG_READ32HR(ioc, &ioc->chip->ReplyFifo, &pa);
+ if (status || (pa = 0xFFFFFFFF))
return IRQ_HANDLED;
else if (pa & MPI_ADDRESS_REPLY_A_BIT)
mpt_reply(ioc, pa);
@@ -833,7 +956,7 @@
mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
ioc->RequestNB[req_idx]));
- CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
+ CHIPREG_WRITE32HR(ioc, &ioc->chip->RequestFifo, mf_dma_addr);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -933,11 +1056,11 @@
}
/* Make sure there are no doorbells */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
- ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
- ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell,
+ ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
+ ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))))
+ return -6;
/* Wait for IOC doorbell int */
if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
@@ -945,13 +1068,18 @@
}
/* Read doorbell and check for active bit */
- if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
- return -5;
-
+ {
+ u32 pa;
+ u16 status;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ if (status || !(pa & MPI_DOORBELL_ACTIVE))
+ return -5;
+ }
dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
ioc->name, ii));
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -8;
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
return -2;
@@ -966,7 +1094,8 @@
(req_as_bytes[(ii*4) + 1] << 8) |
(req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24));
- CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell, word))
+ return -9;
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
r = -3;
break;
@@ -979,7 +1108,8 @@
r = -4;
/* Make sure there are no doorbells */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -10;
return r;
}
@@ -1006,16 +1136,20 @@
int r = 0;
/* return if in use */
- if (CHIPREG_READ32(&ioc->chip->Doorbell)
- & MPI_DOORBELL_ACTIVE)
- return -1;
-
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ {
+ u32 pa;
+ u16 status;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ if (status || (pa & MPI_DOORBELL_ACTIVE))
+ return -1;
+ }
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0) ||
+ CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell,
((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
<<MPI_DOORBELL_FUNCTION_SHIFT) |
- (access_control_value<<12)));
+ (access_control_value<<12))))
+ return -3;
/* Wait for IOC to clear Doorbell Status bit */
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
@@ -1209,6 +1343,9 @@
int r = -ENODEV;
u8 revision;
u8 pcixcmd;
+#ifdef CONFIG_PCIERR_CHECK
+ u16 pcicmd;
+#endif
static int mpt_ids = 0;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dent, *ent;
@@ -1329,6 +1466,10 @@
ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
}
+#ifdef CONFIG_PCIERR_CHECK
+ INIT_WORK(&mptbase_rstTask, mptbase_schedule_reset, (void *)ioc);
+#endif
+
if (pdev->device = MPI_MANUFACTPAGE_DEVICEID_FC909) {
ioc->prod_name = "LSIFC909";
ioc->bus_type = FC;
@@ -1397,6 +1538,17 @@
pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
}
+#ifdef CONFIG_PCIERR_CHECK
+ /* set PER(0040) and SERR_EN(0100) for PCI command register */
+ /* set DPER(0001) for PCI-X command register */
+ pci_read_config_word(pdev, PCI_COMMAND, &pcicmd);
+ pcicmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ pci_write_config_word(pdev, PCI_COMMAND, pcicmd);
+
+ pci_read_config_byte(pdev, 0x6a, &pcixcmd);
+ pcixcmd |= 0x0001; /* set DPER */
+ pci_write_config_byte(pdev, 0x6a, pcixcmd);
+#endif
}
else if (pdev->device = MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
ioc->prod_name = "LSI53C1035";
@@ -1438,9 +1590,11 @@
spin_lock_init(&ioc->FreeQlock);
/* Disable all! */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return -EIO;
ioc->active = 0;
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -EIO;
/* Set lookup ptr. */
list_add_tail(&ioc->list, &ioc_list);
@@ -1559,19 +1713,23 @@
}
/* Disable interrupts! */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return;
ioc->active = 0;
synchronize_irq(pdev->irq);
/* Clear any lingering interrupt */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return;
- CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, NULL))
+ return;
mpt_adapter_dispose(ioc);
pci_set_drvdata(pdev, NULL);
+
}
/**************************************************************************
@@ -1605,11 +1763,13 @@
}
/* disable interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return -EIO;
ioc->active = 0;
/* Clear any lingering interrupt */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -EIO;
pci_disable_device(pdev);
pci_set_power_state(pdev, device_state);
@@ -1630,6 +1790,7 @@
u32 device_state = pdev->current_state;
int recovery_state;
int ii;
+ u32 pa;
printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
@@ -1640,11 +1801,16 @@
pci_enable_device(pdev);
/* enable interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
+ CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, MPI_HIM_DIM);
ioc->active = 1;
/* F/W not running */
- if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
+ {
+ u16 status;
+ pa = 0;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ }
+ if (!pa) {
/* enable domain validation flags */
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
@@ -1655,7 +1821,7 @@
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
ioc->name,
(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
- CHIPREG_READ32(&ioc->chip->Doorbell));
+ pa);
/* bring ioc to operational state */
if ((recovery_state = mpt_do_ioc_recovery(ioc,
@@ -1708,7 +1874,8 @@
ioc->name, reason=MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
/* Disable reply interrupts (also blocks FreeQ) */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return -5;
ioc->active = 0;
if (ioc->alt_ioc) {
@@ -1716,7 +1883,9 @@
reset_alt_ioc_active = 1;
/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc->alt_ioc, &ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF))
+ ret = -6;
+
ioc->alt_ioc->active = 0;
}
@@ -1733,7 +1902,9 @@
/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name));
- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
+ if (CHIPREG_WRITE32(ioc->alt_ioc, &ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM))
+ ret = -7;
+
ioc->alt_ioc->active = 1;
}
@@ -1849,7 +2020,8 @@
if (ret = 0) {
/* Enable! (reply interrupt) */
- CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, MPI_HIM_DIM))
+ ret = -8;
ioc->active = 1;
}
@@ -1857,7 +2029,8 @@
/* (re)Enable alt-IOC! (reply interrupt) */
dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name));
- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
+ if (CHIPREG_WRITE32(ioc->alt_ioc, &ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM))
+ ret = -9;
ioc->alt_ioc->active = 1;
}
@@ -2042,10 +2215,12 @@
}
/* Disable adapter interrupts! */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return;
ioc->active = 0;
/* Clear any lingering interrupt */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return;
if (ioc->alloc != NULL) {
sz = ioc->alloc_sz;
@@ -2371,7 +2546,8 @@
u32 s, sc;
/* Get! */
- s = CHIPREG_READ32(&ioc->chip->Doorbell);
+ CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &s);
+
// dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
sc = s & MPI_IOC_STATE_MASK;
@@ -2968,15 +3144,14 @@
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
-
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
-
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM)))
+ return EFAULT;
/* wait 1 msec */
if (sleepFlag = CAN_SLEEP) {
@@ -2985,11 +3160,15 @@
mdelay (1);
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -EFAULT;
+
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER))
+ return -EFAULT;
for (count = 0; count < 30; count ++) {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -EFAULT;
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
ioc->name, count));
@@ -3010,15 +3189,17 @@
return -3;
}
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ if(CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE))
+ return -EFAULT;
/* Set the DiagRwEn and Disable ARM bits */
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)))
+ return -EFAULT;
fwSize = (pFwHeader->ImageSize + 3)/4;
ptrFw = (u32 *) pFwHeader;
@@ -3081,10 +3262,10 @@
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
} else /* if((ioc->bus_type = SAS) || (ioc->bus_type = FC)) */ {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
- MPI_DIAG_CLEAR_FLASH_BAD_SIG);
-
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic,
+ diag0val | MPI_DIAG_CLEAR_FLASH_BAD_SIG))
+ return -EFAULT;
/* wait 1 msec */
if (sleepFlag = CAN_SLEEP) {
msleep_interruptible (1);
@@ -3096,17 +3277,20 @@
if (ioc->errata_flag_1064)
pci_disable_io_access(ioc->pcidev);
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -EFAULT;
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val))
+ return -EFAULT;
/* Write 0xFF to reset the sequencer */
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF))
+ return -EFAULT;
if (ioc->bus_type = SAS) {
ioc_state = mpt_GetIocState(ioc, 0);
@@ -3250,14 +3434,17 @@
#endif
/* Clear any existing interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
/* Use "Diagnostic reset" method! (only thing available!) */
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3270,12 +3457,13 @@
/* Write magic sequence to WriteSequence register
* Loop until in diagnostic mode
*/
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE))
+ return -1;
/* wait 100 msec */
if (sleepFlag = CAN_SLEEP) {
@@ -3292,7 +3480,8 @@
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
ioc->name, diag0val));
@@ -3300,7 +3489,8 @@
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3308,14 +3498,16 @@
* Disable the ARM (Bug fix)
*
*/
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM))
+ return -1;
mdelay(1);
/*
* Now hit the reset bit in the Diagnostic register
* (THE BIG HAMMER!) (Clears DRWE bit).
*/
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER))
+ return -1;
hard_reset_done = 1;
dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
ioc->name));
@@ -3351,7 +3543,8 @@
* case. _diag_reset will return < 0
*/
for (count = 0; count < 30; count ++) {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
break;
}
@@ -3377,7 +3570,8 @@
* with calling program.
*/
for (count = 0; count < 60; count ++) {
- doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &doorbell))
+ return -1;
doorbell &= MPI_IOC_STATE_MASK;
if (doorbell = MPI_IOC_STATE_READY) {
@@ -3394,10 +3588,12 @@
}
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3405,18 +3601,20 @@
/* Clear RESET_HISTORY bit! Place board in the
* diagnostic mode to update the diag register.
*/
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
count = 0;
while ((diag0val & MPI_DIAG_DRWE) = 0) {
/* Write magic sequence to WriteSequence register
* Loop until in diagnostic mode
*/
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE))
+ return -1;
/* wait 100 msec */
if (sleepFlag = CAN_SLEEP) {
@@ -3431,11 +3629,15 @@
ioc->name, diag0val);
break;
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
}
diag0val &= ~MPI_DIAG_RESET_HISTORY;
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val))
+ return -1;
+
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
if (diag0val & MPI_DIAG_RESET_HISTORY) {
printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
ioc->name);
@@ -3443,11 +3645,13 @@
/* Disable Diagnostic Mode
*/
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFFFFFFFF))
+ return -1;
/* Check FW reload status flags.
*/
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
ioc->name, diag0val);
@@ -3456,7 +3660,8 @@
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3492,7 +3697,8 @@
drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
ioc->name, reset_type));
- CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT))
+ return -EFAULT;
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
return r;
@@ -3789,7 +3995,9 @@
for (i = 0; i < ioc->reply_depth; i++) {
/* Write each address to the IOC! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->ReplyFifo, alloc_dma))
+ goto out_fail;
+
alloc_dma += ioc->reply_sz;
}
@@ -3854,10 +4062,11 @@
* then tell IOC that we want to handshake a request of N words.
* (WRITE u32val to Doorbell reg).
*/
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell,
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
- ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
+ ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))))
+ return -1;
/*
* Wait for IOC's doorbell handshake int
@@ -3869,15 +4078,21 @@
ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
/* Read doorbell and check for active bit */
- if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
+ {
+ u32 pa;
+ u16 status;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ if (status || !(pa & MPI_DOORBELL_ACTIVE))
return -1;
+ }
/*
* Clear doorbell int (WRITE 0 to IntStatus reg),
* then wait for IOC to ACKnowledge that it's ready for
* our handshake request.
*/
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
failcnt++;
@@ -3895,7 +4110,8 @@
(req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24));
- CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell, word))
+ return -1;
if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
failcnt++;
}
@@ -3951,7 +4167,8 @@
if (sleepFlag = CAN_SLEEP) {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
msleep_interruptible (1);
@@ -3959,7 +4176,8 @@
}
} else {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
mdelay (1);
@@ -4000,7 +4218,8 @@
cntdn = 1000 * howlong;
if (sleepFlag = CAN_SLEEP) {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
msleep_interruptible(1);
@@ -4008,7 +4227,8 @@
}
} else {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
mdelay(1);
@@ -4059,13 +4279,27 @@
if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
failcnt++;
} else {
- hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ {
+ u32 pa;
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa))
+ return -1;
+ hs_reply[u16cnt++] = le16_to_cpu(pa & 0x0000FFFF);
+ }
+
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
else {
- hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ {
+ u32 pa;
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa))
+ return -1;
+ hs_reply[u16cnt++] = le16_to_cpu(pa & 0x0000FFFF);
+ }
+
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
}
}
@@ -4080,16 +4314,23 @@
for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
- hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ {
+ u32 pa;
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa))
+ return -1;
+ hword = le16_to_cpu(pa & 0x0000FFFF);
+ }
/* don't overflow our IOC hs_reply[] buffer! */
if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
hs_reply[u16cnt] = hword;
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
}
if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
if (failcnt) {
printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
WARNING: multiple messages have this Message-ID (diff)
From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
To: Greg KH <greg@kroah.com>
Cc: Linux Kernel list <linux-kernel@vger.kernel.org>,
linux-ia64@vger.kernel.org, linux-pci@atrey.karlin.mff.cuni.cz
Subject: [PATCH 6/6] PCIERR : interfaces for synchronous I/O error detection on driver (sample: Fusion MPT)
Date: Fri, 24 Mar 2006 16:52:02 +0900 [thread overview]
Message-ID: <4423A522.4050902@jp.fujitsu.com> (raw)
In-Reply-To: <20060322210157.GH12335@kroah.com>
This is a sample of how to use.
This patch includes following changes:
1:
Change CHIPREG_READ32 & CHIPREG_WRITE32 to take three args,
pointer to adapter, and two memory addresses. And change
them to return the result of memory access.
2:
Set proper args to every CHIPREG_{READ,WRITE}32 call, and
also put error code that returns if the access failed.
3:
Declare a task that resets adapter. Schedule it if an error
is detected and reset is required. Using CHIPREG_*HR call is
convenient to require such reset on an error.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
-----
drivers/message/fusion/mptbase.c | 477 +++++++++++++++++++++++++++++----------
1 files changed, 359 insertions(+), 118 deletions(-)
Index: linux-2.6.16_WORK/drivers/message/fusion/mptbase.c
===================================================================
--- linux-2.6.16_WORK.orig/drivers/message/fusion/mptbase.c
+++ linux-2.6.16_WORK/drivers/message/fusion/mptbase.c
@@ -181,16 +181,124 @@
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
+#ifdef CONFIG_PCIERR_CHECK
+static void mptbase_schedule_reset(void *ioc);
+static struct work_struct mptbase_rstTask;
+#endif
+
/* module entry point */
static int __init fusion_init (void);
static void __exit fusion_exit (void);
-#define CHIPREG_READ32(addr) readl_relaxed(addr)
-#define CHIPREG_READ32_dmasync(addr) readl(addr)
-#define CHIPREG_WRITE32(addr,val) writel(val, addr)
+#define CHIPREG_READ32HR(ioc,addr,val) pciras_readl(ioc,val,addr,1)
+#define CHIPREG_WRITE32HR(ioc,addr,val) pciras_writel(ioc,val,addr,1)
+#define CHIPREG_READ32(ioc,addr,val) pciras_readl(ioc,val,addr,0)
+#define CHIPREG_WRITE32(ioc,addr,val) pciras_writel(ioc,val,addr,0)
#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
+#ifdef CONFIG_PCIERR_CHECK
+#define PCI_ERR_RETRIES 2
+int
+pciras_readl(MPT_ADAPTER *ioc, u32 *regval, u32 *addr, int hres)
+{
+ u32 val;
+ u16 status;
+ iocookie cookie;
+ int retries = PCI_ERR_RETRIES;
+
+ do {
+ pcierr_clear(&cookie, ioc->pcidev);
+ val = ioread32(addr);
+ status = pcierr_read(&cookie);
+ if ((status) && (retries == PCI_ERR_RETRIES))
+ printk(MYIOC_s_WARN_FMT "pciras_readl(), "
+ "detects pci parity error, do retry.\n", ioc->name);
+ } while(status && (--retries > 0));
+
+ if (status) {
+ printk(MYIOC_s_WARN_FMT "pciras_readl(), detects pci parity "
+ "error, retries exhausted.\n", ioc->name);
+ if (hres)
+ schedule_work(&mptbase_rstTask);
+ return 1; /* Error */
+ }
+
+ if (regval)
+ *regval = val;
+ return 0; /* Success */
+}
+
+int
+pciras_writel(MPT_ADAPTER *ioc, u32 regval, u32 *addr, int hres)
+{
+ u16 status;
+ u16 perror;
+ int retries = PCI_ERR_RETRIES;
+
+ do {
+ perror = 0;
+ writel(regval, addr);
+ pci_read_config_word(ioc->pcidev, PCI_STATUS, &status);
+ if (status == 0xffff) {
+ if (retries == PCI_ERR_RETRIES)
+ printk(MYIOC_s_WARN_FMT "pciras_writel(), "
+ "couldn't read pci register.\n", ioc->name);
+ } else if (status & PCI_STATUS_DETECTED_PARITY) {
+ if (retries == PCI_ERR_RETRIES)
+ printk(MYIOC_s_WARN_FMT "pciras_writel(), "
+ "detects pci parity error, do retry.\n",
+ ioc->name);
+ perror = 1;
+ }
+ pci_write_config_word(ioc->pcidev, PCI_STATUS, status);
+ } while (perror && (--retries > 0));
+
+ if (perror) {
+ printk(MYIOC_s_WARN_FMT "pciras_writel(), detects pci "
+ "parity error, retries exhausted.\n", ioc->name);
+
+ if (hres)
+ schedule_work(&mptbase_rstTask);
+ return 1; /* Error */
+ }
+
+ return 0; /* Success */
+}
+
+static void
+mptbase_schedule_reset(void *arg)
+{
+ MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
+
+ mpt_HardResetHandler(ioc, CAN_SLEEP);
+
+ return;
+}
+
+#else /* CONFIG_PCIERR_CHECK */
+
+static inline int
+pciras_readl(MPT_ADAPTER *ioc, u32 *regval, u32 *addr, int hres)
+{
+ u32 val;
+
+ val = ioread32(addr);
+ if (regval)
+ *regval = val;
+ return 0; /* Success */
+}
+
+static inline int
+pciras_writel(MPT_ADAPTER *ioc, u32 regval, u32 *addr, int hres)
+{
+ writel(regval, addr);
+
+ return 0; /* Success */
+}
+
+#endif
+
static void
pci_disable_io_access(struct pci_dev *pdev)
{
@@ -342,7 +450,7 @@
out:
/* Flush (non-TURBO) reply with a WRITE! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
+ CHIPREG_WRITE32HR(ioc, &ioc->chip->ReplyFifo, pa);
if (freeme)
mpt_free_msg_frame(ioc, mf);
@@ -373,12 +481,27 @@
MPT_ADAPTER *ioc = bus_id;
u32 pa;
+#ifdef CONFIG_PCIERR_CHECK
+ {
+ u16 status;
+
+ /* read status register to check whether DMA transfer was failed. */
+ pci_read_config_word(ioc->pcidev, PCI_STATUS, &status);
+ if (status & (PCI_STATUS_DETECTED_PARITY | PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT)) {
+ printk(MYIOC_s_WARN_FMT "mpt_interrupt(), detects pci parity error.\n", ioc->name);
+ pci_write_config_word(ioc->pcidev, PCI_STATUS, status);
+ schedule_work(&mptbase_rstTask);
+ return IRQ_HANDLED;
+ }
+ }
+#endif
/*
* Drain the reply FIFO!
*/
while (1) {
- pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
- if (pa == 0xFFFFFFFF)
+ u16 status;
+ status = CHIPREG_READ32HR(ioc, &ioc->chip->ReplyFifo, &pa);
+ if (status || (pa == 0xFFFFFFFF))
return IRQ_HANDLED;
else if (pa & MPI_ADDRESS_REPLY_A_BIT)
mpt_reply(ioc, pa);
@@ -833,7 +956,7 @@
mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
ioc->RequestNB[req_idx]));
- CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
+ CHIPREG_WRITE32HR(ioc, &ioc->chip->RequestFifo, mf_dma_addr);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -933,11 +1056,11 @@
}
/* Make sure there are no doorbells */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
- ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
- ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell,
+ ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
+ ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))))
+ return -6;
/* Wait for IOC doorbell int */
if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
@@ -945,13 +1068,18 @@
}
/* Read doorbell and check for active bit */
- if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
- return -5;
-
+ {
+ u32 pa;
+ u16 status;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ if (status || !(pa & MPI_DOORBELL_ACTIVE))
+ return -5;
+ }
dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
ioc->name, ii));
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -8;
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
return -2;
@@ -966,7 +1094,8 @@
(req_as_bytes[(ii*4) + 1] << 8) |
(req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24));
- CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell, word))
+ return -9;
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
r = -3;
break;
@@ -979,7 +1108,8 @@
r = -4;
/* Make sure there are no doorbells */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -10;
return r;
}
@@ -1006,16 +1136,20 @@
int r = 0;
/* return if in use */
- if (CHIPREG_READ32(&ioc->chip->Doorbell)
- & MPI_DOORBELL_ACTIVE)
- return -1;
-
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ {
+ u32 pa;
+ u16 status;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ if (status || (pa & MPI_DOORBELL_ACTIVE))
+ return -1;
+ }
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0) ||
+ CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell,
((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
<<MPI_DOORBELL_FUNCTION_SHIFT) |
- (access_control_value<<12)));
+ (access_control_value<<12))))
+ return -3;
/* Wait for IOC to clear Doorbell Status bit */
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
@@ -1209,6 +1343,9 @@
int r = -ENODEV;
u8 revision;
u8 pcixcmd;
+#ifdef CONFIG_PCIERR_CHECK
+ u16 pcicmd;
+#endif
static int mpt_ids = 0;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dent, *ent;
@@ -1329,6 +1466,10 @@
ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
}
+#ifdef CONFIG_PCIERR_CHECK
+ INIT_WORK(&mptbase_rstTask, mptbase_schedule_reset, (void *)ioc);
+#endif
+
if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
ioc->prod_name = "LSIFC909";
ioc->bus_type = FC;
@@ -1397,6 +1538,17 @@
pcixcmd &= 0x8F;
pci_write_config_byte(pdev, 0x6a, pcixcmd);
}
+#ifdef CONFIG_PCIERR_CHECK
+ /* set PER(0040) and SERR_EN(0100) for PCI command register */
+ /* set DPER(0001) for PCI-X command register */
+ pci_read_config_word(pdev, PCI_COMMAND, &pcicmd);
+ pcicmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ pci_write_config_word(pdev, PCI_COMMAND, pcicmd);
+
+ pci_read_config_byte(pdev, 0x6a, &pcixcmd);
+ pcixcmd |= 0x0001; /* set DPER */
+ pci_write_config_byte(pdev, 0x6a, pcixcmd);
+#endif
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
ioc->prod_name = "LSI53C1035";
@@ -1438,9 +1590,11 @@
spin_lock_init(&ioc->FreeQlock);
/* Disable all! */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return -EIO;
ioc->active = 0;
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -EIO;
/* Set lookup ptr. */
list_add_tail(&ioc->list, &ioc_list);
@@ -1559,19 +1713,23 @@
}
/* Disable interrupts! */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return;
ioc->active = 0;
synchronize_irq(pdev->irq);
/* Clear any lingering interrupt */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return;
- CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, NULL))
+ return;
mpt_adapter_dispose(ioc);
pci_set_drvdata(pdev, NULL);
+
}
/**************************************************************************
@@ -1605,11 +1763,13 @@
}
/* disable interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return -EIO;
ioc->active = 0;
/* Clear any lingering interrupt */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -EIO;
pci_disable_device(pdev);
pci_set_power_state(pdev, device_state);
@@ -1630,6 +1790,7 @@
u32 device_state = pdev->current_state;
int recovery_state;
int ii;
+ u32 pa;
printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
@@ -1640,11 +1801,16 @@
pci_enable_device(pdev);
/* enable interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
+ CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, MPI_HIM_DIM);
ioc->active = 1;
/* F/W not running */
- if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
+ {
+ u16 status;
+ pa = 0;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ }
+ if (!pa) {
/* enable domain validation flags */
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
@@ -1655,7 +1821,7 @@
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
ioc->name,
(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
- CHIPREG_READ32(&ioc->chip->Doorbell));
+ pa);
/* bring ioc to operational state */
if ((recovery_state = mpt_do_ioc_recovery(ioc,
@@ -1708,7 +1874,8 @@
ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
/* Disable reply interrupts (also blocks FreeQ) */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return -5;
ioc->active = 0;
if (ioc->alt_ioc) {
@@ -1716,7 +1883,9 @@
reset_alt_ioc_active = 1;
/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc->alt_ioc, &ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF))
+ ret = -6;
+
ioc->alt_ioc->active = 0;
}
@@ -1733,7 +1902,9 @@
/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name));
- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
+ if (CHIPREG_WRITE32(ioc->alt_ioc, &ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM))
+ ret = -7;
+
ioc->alt_ioc->active = 1;
}
@@ -1849,7 +2020,8 @@
if (ret == 0) {
/* Enable! (reply interrupt) */
- CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, MPI_HIM_DIM))
+ ret = -8;
ioc->active = 1;
}
@@ -1857,7 +2029,8 @@
/* (re)Enable alt-IOC! (reply interrupt) */
dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name));
- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
+ if (CHIPREG_WRITE32(ioc->alt_ioc, &ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM))
+ ret = -9;
ioc->alt_ioc->active = 1;
}
@@ -2042,10 +2215,12 @@
}
/* Disable adapter interrupts! */
- CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntMask, 0xFFFFFFFF))
+ return;
ioc->active = 0;
/* Clear any lingering interrupt */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return;
if (ioc->alloc != NULL) {
sz = ioc->alloc_sz;
@@ -2371,7 +2546,8 @@
u32 s, sc;
/* Get! */
- s = CHIPREG_READ32(&ioc->chip->Doorbell);
+ CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &s);
+
// dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
sc = s & MPI_IOC_STATE_MASK;
@@ -2968,15 +3144,14 @@
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
-
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
-
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM)))
+ return EFAULT;
/* wait 1 msec */
if (sleepFlag == CAN_SLEEP) {
@@ -2985,11 +3160,15 @@
mdelay (1);
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -EFAULT;
+
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER))
+ return -EFAULT;
for (count = 0; count < 30; count ++) {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -EFAULT;
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
ioc->name, count));
@@ -3010,15 +3189,17 @@
return -3;
}
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ if(CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE))
+ return -EFAULT;
/* Set the DiagRwEn and Disable ARM bits */
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)))
+ return -EFAULT;
fwSize = (pFwHeader->ImageSize + 3)/4;
ptrFw = (u32 *) pFwHeader;
@@ -3081,10 +3262,10 @@
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
} else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
- MPI_DIAG_CLEAR_FLASH_BAD_SIG);
-
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic,
+ diag0val | MPI_DIAG_CLEAR_FLASH_BAD_SIG))
+ return -EFAULT;
/* wait 1 msec */
if (sleepFlag == CAN_SLEEP) {
msleep_interruptible (1);
@@ -3096,17 +3277,20 @@
if (ioc->errata_flag_1064)
pci_disable_io_access(ioc->pcidev);
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -EFAULT;
ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
ioc->name, diag0val));
diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val))
+ return -EFAULT;
/* Write 0xFF to reset the sequencer */
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF))
+ return -EFAULT;
if (ioc->bus_type == SAS) {
ioc_state = mpt_GetIocState(ioc, 0);
@@ -3250,14 +3434,17 @@
#endif
/* Clear any existing interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
/* Use "Diagnostic reset" method! (only thing available!) */
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3270,12 +3457,13 @@
/* Write magic sequence to WriteSequence register
* Loop until in diagnostic mode
*/
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE))
+ return -1;
/* wait 100 msec */
if (sleepFlag == CAN_SLEEP) {
@@ -3292,7 +3480,8 @@
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
ioc->name, diag0val));
@@ -3300,7 +3489,8 @@
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3308,14 +3498,16 @@
* Disable the ARM (Bug fix)
*
*/
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM))
+ return -1;
mdelay(1);
/*
* Now hit the reset bit in the Diagnostic register
* (THE BIG HAMMER!) (Clears DRWE bit).
*/
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER))
+ return -1;
hard_reset_done = 1;
dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
ioc->name));
@@ -3351,7 +3543,8 @@
* case. _diag_reset will return < 0
*/
for (count = 0; count < 30; count ++) {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
break;
}
@@ -3377,7 +3570,8 @@
* with calling program.
*/
for (count = 0; count < 60; count ++) {
- doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &doorbell))
+ return -1;
doorbell &= MPI_IOC_STATE_MASK;
if (doorbell == MPI_IOC_STATE_READY) {
@@ -3394,10 +3588,12 @@
}
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3405,18 +3601,20 @@
/* Clear RESET_HISTORY bit! Place board in the
* diagnostic mode to update the diag register.
*/
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
count = 0;
while ((diag0val & MPI_DIAG_DRWE) == 0) {
/* Write magic sequence to WriteSequence register
* Loop until in diagnostic mode
*/
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFF)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE))
+ return -1;
/* wait 100 msec */
if (sleepFlag == CAN_SLEEP) {
@@ -3431,11 +3629,15 @@
ioc->name, diag0val);
break;
}
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
}
diag0val &= ~MPI_DIAG_RESET_HISTORY;
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Diagnostic, diag0val))
+ return -1;
+
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
if (diag0val & MPI_DIAG_RESET_HISTORY) {
printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
ioc->name);
@@ -3443,11 +3645,13 @@
/* Disable Diagnostic Mode
*/
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->WriteSequence, 0xFFFFFFFF))
+ return -1;
/* Check FW reload status flags.
*/
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc, &ioc->chip->Diagnostic, &diag0val))
+ return -1;
if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
ioc->name, diag0val);
@@ -3456,7 +3660,8 @@
#ifdef MPT_DEBUG
if (ioc->alt_ioc)
- diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ if (CHIPREG_READ32(ioc->alt_ioc, &ioc->alt_ioc->chip->Diagnostic, &diag1val))
+ return -1;
dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
@@ -3492,7 +3697,8 @@
drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
ioc->name, reset_type));
- CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT))
+ return -EFAULT;
if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
return r;
@@ -3789,7 +3995,9 @@
for (i = 0; i < ioc->reply_depth; i++) {
/* Write each address to the IOC! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->ReplyFifo, alloc_dma))
+ goto out_fail;
+
alloc_dma += ioc->reply_sz;
}
@@ -3854,10 +4062,11 @@
* then tell IOC that we want to handshake a request of N words.
* (WRITE u32val to Doorbell reg).
*/
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0)
+ || CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell,
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
- ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
+ ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))))
+ return -1;
/*
* Wait for IOC's doorbell handshake int
@@ -3869,15 +4078,21 @@
ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
/* Read doorbell and check for active bit */
- if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
+ {
+ u32 pa;
+ u16 status;
+ status = CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa);
+ if (status || !(pa & MPI_DOORBELL_ACTIVE))
return -1;
+ }
/*
* Clear doorbell int (WRITE 0 to IntStatus reg),
* then wait for IOC to ACKnowledge that it's ready for
* our handshake request.
*/
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
failcnt++;
@@ -3895,7 +4110,8 @@
(req_as_bytes[(ii*4) + 2] << 16) |
(req_as_bytes[(ii*4) + 3] << 24));
- CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->Doorbell, word))
+ return -1;
if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
failcnt++;
}
@@ -3951,7 +4167,8 @@
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
msleep_interruptible (1);
@@ -3959,7 +4176,8 @@
}
} else {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
mdelay (1);
@@ -4000,7 +4218,8 @@
cntdn = 1000 * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
msleep_interruptible(1);
@@ -4008,7 +4227,8 @@
}
} else {
while (--cntdn) {
- intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ if (CHIPREG_READ32(ioc, &ioc->chip->IntStatus, &intstat))
+ return -1;
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
mdelay(1);
@@ -4059,13 +4279,27 @@
if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
failcnt++;
} else {
- hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ {
+ u32 pa;
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa))
+ return -1;
+ hs_reply[u16cnt++] = le16_to_cpu(pa & 0x0000FFFF);
+ }
+
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
else {
- hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ {
+ u32 pa;
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa))
+ return -1;
+ hs_reply[u16cnt++] = le16_to_cpu(pa & 0x0000FFFF);
+ }
+
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
}
}
@@ -4080,16 +4314,23 @@
for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
- hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ {
+ u32 pa;
+ if (CHIPREG_READ32(ioc, &ioc->chip->Doorbell, &pa))
+ return -1;
+ hword = le16_to_cpu(pa & 0x0000FFFF);
+ }
/* don't overflow our IOC hs_reply[] buffer! */
if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
hs_reply[u16cnt] = hword;
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
}
if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
failcnt++;
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if (CHIPREG_WRITE32(ioc, &ioc->chip->IntStatus, 0))
+ return -1;
if (failcnt) {
printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
next prev parent reply other threads:[~2006-03-24 7:52 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-22 8:38 [PATCH] PCIERR : interfaces for synchronous I/O error detection on Hidetoshi Seto
2006-03-22 8:38 ` [PATCH] PCIERR : interfaces for synchronous I/O error detection on driver Hidetoshi Seto
2006-03-22 21:01 ` Greg KH
2006-03-22 21:01 ` Greg KH
2006-03-24 7:47 ` [PATCH 1/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-03-24 7:47 ` [PATCH 1/6] PCIERR : interfaces for synchronous I/O error detection on driver Hidetoshi Seto
2006-03-24 23:43 ` Linas Vepstas
2006-03-24 23:43 ` Linas Vepstas
2006-03-27 2:37 ` [PATCH 1/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-03-27 2:37 ` [PATCH 1/6] PCIERR : interfaces for synchronous I/O error detection on driver Hidetoshi Seto
2006-03-31 22:01 ` Linas Vepstas
2006-03-31 22:01 ` Linas Vepstas
2006-04-03 4:54 ` [PATCH 1/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-04-03 4:54 ` [PATCH 1/6] PCIERR : interfaces for synchronous I/O error detection on driver Hidetoshi Seto
2006-03-24 7:48 ` [PATCH 2/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-03-24 7:48 ` [PATCH 2/6] PCIERR : interfaces for synchronous I/O error detection on driver (config) Hidetoshi Seto
2006-03-24 7:49 ` [PATCH 3/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-03-24 7:49 ` [PATCH 3/6] PCIERR : interfaces for synchronous I/O error detection on driver (base) Hidetoshi Seto
2006-03-24 7:50 ` [PATCH 4/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-03-24 7:50 ` [PATCH 4/6] PCIERR : interfaces for synchronous I/O error detection on driver (mcadrv) Hidetoshi Seto
2006-03-24 7:51 ` [PATCH 5/6] PCIERR : interfaces for synchronous I/O error detection Hidetoshi Seto
2006-03-24 7:51 ` [PATCH 5/6] PCIERR : interfaces for synchronous I/O error detection on driver (poison) Hidetoshi Seto
2006-03-24 7:52 ` Hidetoshi Seto [this message]
2006-03-24 7:52 ` [PATCH 6/6] PCIERR : interfaces for synchronous I/O error detection on driver (sample: Fusion MPT) Hidetoshi Seto
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4423A522.4050902@jp.fujitsu.com \
--to=seto.hidetoshi@jp.fujitsu.com \
--cc=greg@kroah.com \
--cc=linux-ia64@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@atrey.karlin.mff.cuni.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.