[RFC/PATCH, 2/4] readX_check() performance evaluation

From: Hironobu Ishii
Date: Tue Jan 27 2004 - 21:01:21 EST


This is a readX_check() prototype patch to evaluate
the performance disadvantage.

Thanks,
Hironobu Ishii
--------------------
diff -prN linux-2.6.1/drivers/message/fusion/Makefile linux-2.6.1.modified/drivers/message/fusion/Makefile
*** linux-2.6.1/drivers/message/fusion/Makefile 2004-01-09 15:59:45.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/Makefile 2004-01-26 20:25:21.691512363 +0900
***************
*** 15,20 ****
--- 15,23 ----

EXTRA_CFLAGS += ${MPT_CFLAGS}

+ # for PCI_RECOVERY
+ EXTRA_CFLAGS += -DCONFIG_PCI_RECOVERY
+
# Fusion MPT drivers; recognized debug defines...
# MPT general:
#EXTRA_CFLAGS += -DDEBUG
*************** obj-$(CONFIG_FUSION) += mptbase.o mptsc
*** 50,52 ****
--- 53,60 ----
obj-$(CONFIG_FUSION_ISENSE) += isense.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o
+
+ # for PCI error recovery
+ mptbase-objs := mptbase_main.o read_check.o
+
+
diff -prN linux-2.6.1/drivers/message/fusion/mptbase.c linux-2.6.1.modified/drivers/message/fusion/mptbase.c
*** linux-2.6.1/drivers/message/fusion/mptbase.c 2004-01-09 15:59:18.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/mptbase.c 2004-01-26 22:29:18.185561891 +0900
*************** struct _mpt_ioc_proc_list {
*** 260,265 ****
--- 260,305 ----

#endif

+
+ #ifdef CONFIG_PCI_RECOVERY
+ /*
+ * Try to recover from PCI intermittent read errors
+ */
+ #define REG_READ_SUCCESS 0
+
+ #define REG_READ_OK 0
+ #define REG_READ_RETRY_OK 1
+ #define REG_READ_NG -1
+
+ #define REG_READ_RETRY 5 /* retry limit */
+
+ extern inline int readl_check(volatile u32 *d, volatile u32 *a);
+
+ static inline int do_readl(volatile u32 *d, volatile u32 *a)
+ {
+ int retry ;
+ int fail = 0;
+
+ for (retry = REG_READ_RETRY; retry; retry--) {
+ if (readl_check(d, a) == REG_READ_SUCCESS) {
+ return (fail ? REG_READ_RETRY_OK : REG_READ_OK);
+ }
+ fail++;
+ }
+ /* retry out */
+ /* PCI reset? */
+ return REG_READ_NG;
+ }
+
+ static inline int CHIPREG_READ32(volatile u32 *d, volatile u32 *a)
+ {
+ if (PortIo) {
+ *d =inl((unsigned long)a);
+ return REG_READ_OK;
+ } else
+ return do_readl(d, a);
+ }
+ #else
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* 20000207 -sralston
* GRRRRR... IOSpace (port i/o) register access (for the 909) is back!
*************** static inline u32 CHIPREG_READ32(volatil
*** 274,279 ****
--- 314,320 ----
else
return readl(a);
}
+ #endif

static inline void CHIPREG_WRITE32(volatile u32 *a, u32 v)
{
*************** mpt_interrupt(int irq, void *bus_id, str
*** 352,360 ****
*/
while (1) {

if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
return IRQ_HANDLED;
!
cb_idx = 0;
freeme = 0;

--- 393,413 ----
*/
while (1) {

+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&pa, &ioc->chip->ReplyFifo);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ if (pa == 0xFFFFFFFF)
+ return IRQ_HANDLED;
+ }
+ #else
if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
return IRQ_HANDLED;
! #endif
cb_idx = 0;
freeme = 0;

*************** mpt_send_handshake_request(int handle, i
*** 1066,1073 ****
--- 1119,1140 ----
}

/* Read doorbell and check for active bit */
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ u32 dummy;
+ read_fail = CHIPREG_READ32(&dummy, &iocp->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ if (!(dummy & MPI_DOORBELL_ACTIVE))
+ return -5;
+ }
+ #else
if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
return -5;
+ #endif

dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
iocp->name, ii));
*************** mpt_GetIocState(MPT_ADAPTER *ioc, int co
*** 2170,2176 ****
--- 2237,2255 ----
u32 s, sc;

/* Get! */
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&s, &ioc->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
s = CHIPREG_READ32(&ioc->chip->Doorbell);
+ #endif
+
// dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
sc = s & MPI_IOC_STATE_MASK;

*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2871,2879 ****
--- 2950,2981 ----
ddlprintk((MYIOC_s_INFO_FMT "DbGb0: downloadboot entered.\n",
ioc->name));
#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail ;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery codes */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail ;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
ddlprintk((MYIOC_s_INFO_FMT "DbGb1: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2903,2909 ****
--- 3005,3023 ----
/* Write magic sequence to WriteSequence register
* until enter diagnostic mode
*/
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
while ((diag0val & MPI_DIAG_DRWE) == 0) {
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2928,2937 ****
--- 3042,3075 ----

}

+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail ;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+
ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 2944,2951 ****
--- 3082,3100 ----
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);

#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif

ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
*************** mpt_downloadboot(MPT_ADAPTER *ioc, int s
*** 3097,3103 ****
--- 3246,3265 ----
CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);

/* clear the RW enable and DISARM bits */
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail ;
+
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_FLASH_BAD_SIG);
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);

*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3215,3225 ****
--- 3377,3410 ----
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);

/* Use "Diagnostic reset" method! (only thing available!) */
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif

#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+
dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3255,3269 ****
--- 3440,3477 ----

}

+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif

dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
ioc->name, diag0val));
}

#ifdef MPT_DEBUG
+ #ifndef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+
dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3320,3329 ****
--- 3528,3561 ----
* case. _diag_reset will return < 0
*/
for (count = 0; count < 30; count ++) {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+
dprintk((MYIOC_s_INFO_FMT
"DbG2b: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3353,3359 ****
--- 3585,3603 ----
* with calling program.
*/
for (count = 0; count < 30; count ++) {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&doorbell, &ioc->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
+ #endif
+
doorbell &= MPI_IOC_STATE_MASK;

if (doorbell == MPI_IOC_STATE_READY) {
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3371,3380 ****
--- 3615,3648 ----
}
}

+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->alt_ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+
dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3382,3388 ****
--- 3650,3668 ----
/* Clear RESET_HISTORY bit! Place board in the
* diagnostic mode to update the diag register.
*/
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
count = 0;
while ((diag0val & MPI_DIAG_DRWE) == 0) {
/* Write magic sequence to WriteSequence register
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3408,3418 ****
--- 3688,3722 ----
ioc->name, diag0val);
break;
}
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
}
diag0val &= ~MPI_DIAG_RESET_HISTORY;
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
if (diag0val & MPI_DIAG_RESET_HISTORY) {
printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
ioc->name);
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3424,3430 ****
--- 3728,3746 ----

/* Check FW reload status flags.
*/
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag0val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+ #endif
+
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);
*************** mpt_diag_reset(MPT_ADAPTER *ioc, int ign
*** 3432,3439 ****
--- 3748,3767 ----
}

#ifdef MPT_DEBUG
+ #ifdef CONFIG_PCI_RECOVERY
+ if (ioc->alt_ioc) {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&diag1val, &ioc->chip->Diagnostic);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
if (ioc->alt_ioc)
diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ #endif
+
dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
ioc->name, diag0val, diag1val));
#endif
*************** mpt_handshake_req_reply_wait(MPT_ADAPTER
*** 3743,3750 ****
--- 4071,4092 ----
ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));

/* Read doorbell and check for active bit */
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ u32 dummy;
+ read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ if (!(dummy & MPI_DOORBELL_ACTIVE))
+ return -1;
+ }
+ #else
if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
return -1;
+ #endif

/*
* Clear doorbell int (WRITE 0 to IntStatus reg),
*************** WaitForDoorbellAck(MPT_ADAPTER *ioc, int
*** 3822,3828 ****
--- 4164,4182 ----

if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
set_current_state(TASK_INTERRUPTIBLE);
*************** WaitForDoorbellAck(MPT_ADAPTER *ioc, int
*** 3831,3837 ****
--- 4185,4203 ----
}
} else {
while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
mdelay (1);
*************** WaitForDoorbellInt(MPT_ADAPTER *ioc, int
*** 3872,3878 ****
--- 4238,4256 ----
cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
set_current_state(TASK_INTERRUPTIBLE);
*************** WaitForDoorbellInt(MPT_ADAPTER *ioc, int
*** 3881,3887 ****
--- 4259,4277 ----
}
} else {
while (--cntdn) {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ read_fail = CHIPREG_READ32(&intstat, &ioc->chip->IntStatus);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
+ #endif
+
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
mdelay(1);
*************** WaitForDoorbellReply(MPT_ADAPTER *ioc, i
*** 3932,3943 ****
--- 4322,4361 ----
if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
failcnt++;
} else {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ u32 dummy;
+ read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ hs_reply[u16cnt++] = le16_to_cpu(dummy & 0x0000FFFF);
+ }
+ #else
hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
failcnt++;
else {
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ u32 dummy;
+ read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ hs_reply[u16cnt++] = le16_to_cpu(dummy & 0x0000FFFF);
+ }
+ #else
hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
}
}
*************** WaitForDoorbellReply(MPT_ADAPTER *ioc, i
*** 3953,3959 ****
--- 4371,4391 ----
for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
if ((t = WaitForDoorbellInt(ioc, 2, sleepFlag)) < 0)
failcnt++;
+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ u32 dummy;
+ read_fail = CHIPREG_READ32(&dummy, &ioc->chip->Doorbell);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ hword = le16_to_cpu(dummy & 0x0000FFFF);
+ }
+ #else
hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ #endif
+
/* don't overflow our IOC hs_reply[] buffer! */
if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
hs_reply[u16cnt] = hword;
*************** fusion_init(void)
*** 5896,5901 ****
--- 6328,6339 ----
show_mptmod_ver(my_NAME, my_VERSION);
printk(KERN_INFO COPYRIGHT "\n");

+ #ifdef CONFIG_PCI_RECOVERY
+ printk(KERN_INFO "Enable PCI PIO read error recovery\n");
+ #else
+ printk(KERN_INFO "Disable PCI PIO read error recovery\n");
+ #endif
+
Q_INIT(&MptAdapters, MPT_ADAPTER); /* set to empty */
for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
MptCallbacks[i] = NULL;
*************** fusion_exit(void)
*** 5962,5968 ****
--- 6400,6418 ----
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&this->chip->IntStatus, 0);

+ #ifdef CONFIG_PCI_RECOVERY
+ {
+ int read_fail;
+ u32 dummy;
+ read_fail = CHIPREG_READ32(&dummy, &this->chip->IntStatus);
+ if (read_fail) {
+ printk("PCI PIO read error:%d\n", read_fail);
+ /* recovery code */
+ }
+ }
+ #else
CHIPREG_READ32(&this->chip->IntStatus);
+ #endif

Q_DEL_ITEM(this);
mpt_adapter_dispose(this);
diff -prN linux-2.6.1/drivers/message/fusion/mptbase.h linux-2.6.1.modified/drivers/message/fusion/mptbase.h
*** linux-2.6.1/drivers/message/fusion/mptbase.h 2004-01-09 15:59:10.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/mptbase.h 2004-01-26 16:41:43.394801737 +0900
***************
*** 80,87 ****
#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
#endif

! #define MPT_LINUX_VERSION_COMMON "2.05.00.05"
! #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.00.05"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"

#define show_mptmod_ver(s,ver) \
--- 80,87 ----
#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
#endif

! #define MPT_LINUX_VERSION_COMMON "2.05.00.05PCI"
! #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.00.05PCI"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"

#define show_mptmod_ver(s,ver) \
diff -prN linux-2.6.1/drivers/message/fusion/read_check.S linux-2.6.1.modified/drivers/message/fusion/read_check.S
*** linux-2.6.1/drivers/message/fusion/read_check.S 1970-01-01 09:00:00.000000000 +0900
--- linux-2.6.1.modified/drivers/message/fusion/read_check.S 2004-01-26 22:19:20.426780151 +0900
***************
*** 0 ****
--- 1,69 ----
+ #define ENTRY(name) \
+ .align 32; \
+ .global name; \
+ .proc name; \
+ name:
+ #define END(name) \
+ .endp name
+
+ /****************************************************************************/
+ .rodata
+ .align 8
+ .global readchk_addrs
+ readchk_addrs:
+ data8 .readl_start#
+ data8 .readl_end#
+
+ /* This should be per CPU data */
+ .global readl_mca#
+ .sbss
+ .align 4
+ .type readl_mca#,@object
+ .size readl_mca#,4
+ readl_mca:
+ .skip 4
+ /*
+ *
+ * int readl_check( __u32 *valp, __u32 *addr ) ;
+ * in0, in1
+ */
+ .text
+ .align 16
+ ENTRY(readl_check)
+ .prologue
+ .body
+ {.mmi addl r15 = @ltoffx(readl_mca#), r1
+ ;;
+ ld8.mov r14 = [r15], readl_mca# /* r14 = &readl_mca */
+ nop.i 0
+ ;;
+ }
+ .readl_start:
+ {.mmi ld4.acq r15 = [r14] /* r15 = readl_mca */
+ ld4 r33 = [r33] /* r33 = *addr(r33) */
+ nop.i 0
+ ;;
+ }
+ {.mmi add r16 =1, r33 /* consume r33 */
+ nop.m 0
+ nop.i 0
+ ;;
+ }
+ .readl_end:
+ {.mmi ld4.acq r14 = [r14] /* r14 = readl_mca */
+ ;;
+ cmp4.ne p6, p7 = r14, r15 /* old readl_mca == readl_mca? */
+ nop.i 0
+ ;;
+ }
+ {.mmi (p7) st4 [r32] = r33 /* if (old==new) *valp(r32) = r33 */
+ (p7) mov r8 = r0 /* if (old==new) ret = 0 */
+ nop.i 0
+ }
+ {.mmb (p6) addl r8 = 1, r0 /* if (old!=new) ret = 1 */
+ nop.m 0
+ br.ret.sptk.many rp
+ ;;
+ }
+
+ END(readl_check)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/