Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pciehp: Fix wrong slot capability check

Current pciehp saves only 8bits of Slot Capability registers in
ctrl->ctrlcap. But it refers more than 8bit for checking EMI capability.
It is clearly a bug and EMI would never work. To fix this problem,
this patch saves full Slot Capability contens in ctrl->slot_cap. It also
reduce the redundant reads of Slot Capability register. And this pach
also cleans up the macros to check the slot capabilitys (e.g. MRL_SENS(),
and so on).

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

authored by

Kenji Kaneshige and committed by
Jesse Barnes
ae416e6b c27fb883

+39 -39
+8 -8
drivers/pci/hotplug/pciehp.h
··· 93 93 u8 slot_device_offset; 94 94 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ 95 95 u8 slot_bus; /* Bus where the slots handled by this controller sit */ 96 - u8 ctrlcap; 96 + u32 slot_cap; 97 97 u8 cap_base; 98 98 struct timer_list poll_timer; 99 99 volatile int cmd_busy; ··· 136 136 #define HP_SUPR_RM_SUP 0x00000020 137 137 #define EMI_PRSN 0x00020000 138 138 139 - #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) 140 - #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) 141 - #define MRL_SENS(cap) (cap & MRL_SENS_PRSN) 142 - #define ATTN_LED(cap) (cap & ATTN_LED_PRSN) 143 - #define PWR_LED(cap) (cap & PWR_LED_PRSN) 144 - #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) 145 - #define EMI(cap) (cap & EMI_PRSN) 139 + #define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & ATTN_BUTTN_PRSN) 140 + #define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PWR_CTRL_PRSN) 141 + #define MRL_SENS(ctrl) ((ctrl)->slot_cap & MRL_SENS_PRSN) 142 + #define ATTN_LED(ctrl) ((ctrl)->slot_cap & ATTN_LED_PRSN) 143 + #define PWR_LED(ctrl) ((ctrl)->slot_cap & PWR_LED_PRSN) 144 + #define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & HP_SUPR_RM_SUP) 145 + #define EMI(ctrl) ((ctrl)->slot_cap & EMI_PRSN) 146 146 147 147 extern int pciehp_sysfs_enable_slot(struct slot *slot); 148 148 extern int pciehp_sysfs_disable_slot(struct slot *slot);
+4 -4
drivers/pci/hotplug/pciehp_core.c
··· 258 258 goto error_info; 259 259 } 260 260 /* create additional sysfs entries */ 261 - if (EMI(ctrl->ctrlcap)) { 261 + if (EMI(ctrl)) { 262 262 retval = sysfs_create_file(&hotplug_slot->kobj, 263 263 &hotplug_slot_attr_lock.attr); 264 264 if (retval) { ··· 291 291 list_for_each_safe(tmp, next, &ctrl->slot_list) { 292 292 slot = list_entry(tmp, struct slot, slot_list); 293 293 list_del(&slot->slot_list); 294 - if (EMI(ctrl->ctrlcap)) 294 + if (EMI(ctrl)) 295 295 sysfs_remove_file(&slot->hotplug_slot->kobj, 296 296 &hotplug_slot_attr_lock.attr); 297 297 cancel_delayed_work(&slot->work); ··· 312 312 313 313 hotplug_slot->info->attention_status = status; 314 314 315 - if (ATTN_LED(slot->ctrl->ctrlcap)) 315 + if (ATTN_LED(slot->ctrl)) 316 316 slot->hpc_ops->set_attention_status(slot, status); 317 317 318 318 return 0; ··· 479 479 if (rc) /* -ENODEV: shouldn't happen, but deal with it */ 480 480 value = 0; 481 481 } 482 - if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { 482 + if ((POWER_CTRL(ctrl)) && !value) { 483 483 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ 484 484 if (rc) 485 485 goto err_out_free_ctrl_slot;
+23 -23
drivers/pci/hotplug/pciehp_ctrl.c
··· 178 178 static void set_slot_off(struct controller *ctrl, struct slot * pslot) 179 179 { 180 180 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ 181 - if (POWER_CTRL(ctrl->ctrlcap)) { 181 + if (POWER_CTRL(ctrl)) { 182 182 if (pslot->hpc_ops->power_off_slot(pslot)) { 183 183 err("%s: Issue of Slot Power Off command failed\n", 184 184 __func__); ··· 186 186 } 187 187 } 188 188 189 - if (PWR_LED(ctrl->ctrlcap)) 189 + if (PWR_LED(ctrl)) 190 190 pslot->hpc_ops->green_led_off(pslot); 191 191 192 - if (ATTN_LED(ctrl->ctrlcap)) { 192 + if (ATTN_LED(ctrl)) { 193 193 if (pslot->hpc_ops->set_attention_status(pslot, 1)) { 194 194 err("%s: Issue of Set Attention Led command failed\n", 195 195 __func__); ··· 214 214 __func__, p_slot->device, 215 215 ctrl->slot_device_offset, p_slot->hp_slot); 216 216 217 - if (POWER_CTRL(ctrl->ctrlcap)) { 217 + if (POWER_CTRL(ctrl)) { 218 218 /* Power on slot */ 219 219 retval = p_slot->hpc_ops->power_on_slot(p_slot); 220 220 if (retval) 221 221 return retval; 222 222 } 223 223 224 - if (PWR_LED(ctrl->ctrlcap)) 224 + if (PWR_LED(ctrl)) 225 225 p_slot->hpc_ops->green_led_blink(p_slot); 226 226 227 227 /* Wait for ~1 second */ ··· 254 254 */ 255 255 if (pcie_mch_quirk) 256 256 pci_fixup_device(pci_fixup_final, ctrl->pci_dev); 257 - if (PWR_LED(ctrl->ctrlcap)) 257 + if (PWR_LED(ctrl)) 258 258 p_slot->hpc_ops->green_led_on(p_slot); 259 259 260 260 return 0; ··· 279 279 280 280 dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); 281 281 282 - if (POWER_CTRL(ctrl->ctrlcap)) { 282 + if (POWER_CTRL(ctrl)) { 283 283 /* power off slot */ 284 284 retval = p_slot->hpc_ops->power_off_slot(p_slot); 285 285 if (retval) { ··· 289 289 } 290 290 } 291 291 292 - if (PWR_LED(ctrl->ctrlcap)) 292 + if (PWR_LED(ctrl)) 293 293 /* turn off Green LED */ 294 294 p_slot->hpc_ops->green_led_off(p_slot); 295 295 ··· 327 327 case POWERON_STATE: 328 328 mutex_unlock(&p_slot->lock); 329 329 if (pciehp_enable_slot(p_slot) && 330 - PWR_LED(p_slot->ctrl->ctrlcap)) 330 + PWR_LED(p_slot->ctrl)) 331 331 p_slot->hpc_ops->green_led_off(p_slot); 332 332 mutex_lock(&p_slot->lock); 333 333 p_slot->state = STATIC_STATE; ··· 409 409 "press.\n", p_slot->name); 410 410 } 411 411 /* blink green LED and turn off amber */ 412 - if (PWR_LED(ctrl->ctrlcap)) 412 + if (PWR_LED(ctrl)) 413 413 p_slot->hpc_ops->green_led_blink(p_slot); 414 - if (ATTN_LED(ctrl->ctrlcap)) 414 + if (ATTN_LED(ctrl)) 415 415 p_slot->hpc_ops->set_attention_status(p_slot, 0); 416 416 417 417 schedule_delayed_work(&p_slot->work, 5*HZ); ··· 427 427 dbg("%s: button cancel\n", __func__); 428 428 cancel_delayed_work(&p_slot->work); 429 429 if (p_slot->state == BLINKINGOFF_STATE) { 430 - if (PWR_LED(ctrl->ctrlcap)) 430 + if (PWR_LED(ctrl)) 431 431 p_slot->hpc_ops->green_led_on(p_slot); 432 432 } else { 433 - if (PWR_LED(ctrl->ctrlcap)) 433 + if (PWR_LED(ctrl)) 434 434 p_slot->hpc_ops->green_led_off(p_slot); 435 435 } 436 - if (ATTN_LED(ctrl->ctrlcap)) 436 + if (ATTN_LED(ctrl)) 437 437 p_slot->hpc_ops->set_attention_status(p_slot, 0); 438 438 info("PCI slot #%s - action canceled due to button press\n", 439 439 p_slot->name); ··· 492 492 handle_button_press_event(p_slot); 493 493 break; 494 494 case INT_POWER_FAULT: 495 - if (!POWER_CTRL(ctrl->ctrlcap)) 495 + if (!POWER_CTRL(ctrl)) 496 496 break; 497 - if (ATTN_LED(ctrl->ctrlcap)) 497 + if (ATTN_LED(ctrl)) 498 498 p_slot->hpc_ops->set_attention_status(p_slot, 1); 499 - if (PWR_LED(ctrl->ctrlcap)) 499 + if (PWR_LED(ctrl)) 500 500 p_slot->hpc_ops->green_led_off(p_slot); 501 501 break; 502 502 case INT_PRESENCE_ON: 503 503 case INT_PRESENCE_OFF: 504 - if (!HP_SUPR_RM(ctrl->ctrlcap)) 504 + if (!HP_SUPR_RM(ctrl)) 505 505 break; 506 506 dbg("Surprise Removal\n"); 507 507 update_slot_info(p_slot); ··· 531 531 mutex_unlock(&p_slot->ctrl->crit_sect); 532 532 return -ENODEV; 533 533 } 534 - if (MRL_SENS(p_slot->ctrl->ctrlcap)) { 534 + if (MRL_SENS(p_slot->ctrl)) { 535 535 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 536 536 if (rc || getstatus) { 537 537 info("%s: latch open on slot(%s)\n", __func__, ··· 541 541 } 542 542 } 543 543 544 - if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { 544 + if (POWER_CTRL(p_slot->ctrl)) { 545 545 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 546 546 if (rc || getstatus) { 547 547 info("%s: already enabled on slot(%s)\n", __func__, ··· 576 576 /* Check to see if (latch closed, card present, power on) */ 577 577 mutex_lock(&p_slot->ctrl->crit_sect); 578 578 579 - if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { 579 + if (!HP_SUPR_RM(p_slot->ctrl)) { 580 580 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 581 581 if (ret || !getstatus) { 582 582 info("%s: no adapter on slot(%s)\n", __func__, ··· 586 586 } 587 587 } 588 588 589 - if (MRL_SENS(p_slot->ctrl->ctrlcap)) { 589 + if (MRL_SENS(p_slot->ctrl)) { 590 590 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 591 591 if (ret || getstatus) { 592 592 info("%s: latch open on slot(%s)\n", __func__, ··· 596 596 } 597 597 } 598 598 599 - if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { 599 + if (POWER_CTRL(p_slot->ctrl)) { 600 600 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 601 601 if (ret || !getstatus) { 602 602 info("%s: already disabled slot(%s)\n", __func__,
+4 -4
drivers/pci/hotplug/pciehp_hpc.c
··· 1058 1058 } 1059 1059 1060 1060 cmd = PRSN_DETECT_ENABLE; 1061 - if (ATTN_BUTTN(ctrl->ctrlcap)) 1061 + if (ATTN_BUTTN(ctrl)) 1062 1062 cmd |= ATTN_BUTTN_ENABLE; 1063 - if (POWER_CTRL(ctrl->ctrlcap)) 1063 + if (POWER_CTRL(ctrl)) 1064 1064 cmd |= PWR_FAULT_DETECT_ENABLE; 1065 - if (MRL_SENS(ctrl->ctrlcap)) 1065 + if (MRL_SENS(ctrl)) 1066 1066 cmd |= MRL_DETECT_ENABLE; 1067 1067 if (!pciehp_poll_mode) 1068 1068 cmd |= HP_INTR_ENABLE; ··· 1181 1181 ctrl->slot_device_offset = 0; 1182 1182 ctrl->num_slots = 1; 1183 1183 ctrl->first_slot = slot_cap >> 19; 1184 - ctrl->ctrlcap = slot_cap & 0x0000007f; 1184 + ctrl->slot_cap = slot_cap; 1185 1185 1186 1186 rc = pcie_init_hardware_part1(ctrl, dev); 1187 1187 if (rc)