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 | |
| 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>
| -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); |
