aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2006-05-01 22:12:37 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-19 17:13:23 -0400
commite7138723692e43b7d43578746ad21bf194847527 (patch)
tree7d8e769c25324381708536e9fbcadfb2f4754622
parent795eb5c4a73bee30e8c2dbb29174b329da56051c (diff)
[PATCH] SHPC: Fix SHPC Contoller SERR-INT Register bits access
Current SHPCHP driver doesn't take care of RsvdP/RsvdZ[*] bits in controller SERR-INT register. This might cause unpredicable results. This patch fixes this bug. [*] RsvdP and RsvdZ are defined in SHPC spec as follows: RsvdP - Reserved and Preserved. Register bits of this type are reserved for future use as R/W bits. The value read is undefined. Writes are ignored. Software must follow These rules when accessing RsvdP bits: - Software must ignore RsvdP bits when testing values read from these registers. - Software must not depend on RsvdP bit's ability to retain information when written - Software must always write back the value read in the RsvdP bits when writing one of these registers. RsvdZ - Reserved and Zero. Register bits of this type are reserved for future use as R/WC bits. The value read is undefined. Writes are ignored. Software must follow these rules when accessing RsvdZ bits: - Software must ignore RsvdZ bits when testing values read from these registers. - Software must not depends on a RsvdZ bit's ability to retain information when written. - Software must always write 0 to RsvdZ bits when writing one of these register. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Cc: Kristen Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 285a21d36524..e2a8671545f2 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -91,6 +91,17 @@
91#define ATTN_BUTTON 0x80000000 91#define ATTN_BUTTON 0x80000000
92 92
93/* 93/*
94 * Controller SERR-INT Register
95 */
96#define GLOBAL_INTR_MASK (1 << 0)
97#define GLOBAL_SERR_MASK (1 << 1)
98#define COMMAND_INTR_MASK (1 << 2)
99#define ARBITER_SERR_MASK (1 << 3)
100#define COMMAND_DETECTED (1 << 16)
101#define ARBITER_DETECTED (1 << 17)
102#define SERR_INTR_RSVDZ_MASK 0xfffc0000
103
104/*
94 * Logical Slot Register definitions 105 * Logical Slot Register definitions
95 */ 106 */
96#define SLOT_REG(i) (SLOT1 + (4 * i)) 107#define SLOT_REG(i) (SLOT1 + (4 * i))
@@ -1047,7 +1058,8 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1047 /* Mask Global Interrupt Mask - see implementation note on p. 139 */ 1058 /* Mask Global Interrupt Mask - see implementation note on p. 139 */
1048 /* of SHPC spec rev 1.0*/ 1059 /* of SHPC spec rev 1.0*/
1049 temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1060 temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1050 temp_dword |= 0x00000001; 1061 temp_dword |= GLOBAL_INTR_MASK;
1062 temp_dword &= ~SERR_INTR_RSVDZ_MASK;
1051 shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); 1063 shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
1052 1064
1053 intr_loc2 = shpc_readl(ctrl, INTR_LOC); 1065 intr_loc2 = shpc_readl(ctrl, INTR_LOC);
@@ -1061,7 +1073,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1061 * Detect bit in Controller SERR-INT register 1073 * Detect bit in Controller SERR-INT register
1062 */ 1074 */
1063 temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1075 temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1064 temp_dword &= 0xfffdffff; 1076 temp_dword &= ~SERR_INTR_RSVDZ_MASK;
1065 shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); 1077 shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
1066 ctrl->cmd_busy = 0; 1078 ctrl->cmd_busy = 0;
1067 wake_up_interruptible(&ctrl->queue); 1079 wake_up_interruptible(&ctrl->queue);
@@ -1105,7 +1117,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1105 if (!shpchp_poll_mode) { 1117 if (!shpchp_poll_mode) {
1106 /* Unmask Global Interrupt Mask */ 1118 /* Unmask Global Interrupt Mask */
1107 temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1119 temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1108 temp_dword &= 0xfffffffe; 1120 temp_dword &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
1109 shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword); 1121 shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
1110 } 1122 }
1111 1123
@@ -1374,7 +1386,9 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1374 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ 1386 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
1375 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1387 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1376 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1388 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1377 tempdword = 0x0003000f; 1389 tempdword |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |
1390 COMMAND_INTR_MASK | ARBITER_SERR_MASK);
1391 tempdword &= ~SERR_INTR_RSVDZ_MASK;
1378 shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); 1392 shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
1379 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1393 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1380 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1394 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
@@ -1452,7 +1466,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1452 if (!shpchp_poll_mode) { 1466 if (!shpchp_poll_mode) {
1453 /* Unmask all general input interrupts and SERR */ 1467 /* Unmask all general input interrupts and SERR */
1454 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1468 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1455 tempdword = 0x0000000a; 1469 tempdword &= ~(GLOBAL_INTR_MASK | COMMAND_INTR_MASK |
1470 SERR_INTR_RSVDZ_MASK);
1456 shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword); 1471 shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
1457 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); 1472 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1458 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1473 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);