diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2006-05-01 22:12:37 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-19 17:13:23 -0400 |
commit | e7138723692e43b7d43578746ad21bf194847527 (patch) | |
tree | 7d8e769c25324381708536e9fbcadfb2f4754622 /drivers/pci/hotplug/shpchp_hpc.c | |
parent | 795eb5c4a73bee30e8c2dbb29174b329da56051c (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>
Diffstat (limited to 'drivers/pci/hotplug/shpchp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 25 |
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); |