Per the PCI Express spec, the power-fault-detected bit in the
slot status register can be set anytime hardware detects a power
fault, regardless of whether the slot has a device populated in
it or not. This bit is sticky and must be explicitly cleared.
This patch is needed to allow hot-add after such a power fault
has been detected.
Signed-off-by: Rajesh Shah <rajesh.shah@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
struct slot *next;
u8 bus;
u8 device;
struct slot *next;
u8 bus;
u8 device;
u32 number;
u8 state;
struct timer_list task_event;
u32 number;
u8 state;
struct timer_list task_event;
* power fault Cleared
*/
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
* power fault Cleared
*/
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
*/
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT;
*/
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT;
- /* set power fault status for this board */
- p_slot->status = 0xFF;
info("power fault bit %x set\n", hp_slot);
}
if (rc)
info("power fault bit %x set\n", hp_slot);
}
if (rc)
- dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
-
/* Check for a power fault */
/* Check for a power fault */
- if (p_slot->status == 0xFF) {
- /* power fault occurred, but it was benign */
+ if (p_slot->hpc_ops->query_power_fault(p_slot)) {
+ dbg("%s: power fault detected\n", __FUNCTION__);
/*
* Some PCI Express root ports require fixup after hot-plug operation.
*/
/*
* Some PCI Express root ports require fixup after hot-plug operation.
*/
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
- /* Change status to shutdown */
- p_slot->status = 0x01;
-
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
/* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
{
struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
{
struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
+ u16 slot_ctrl, slot_status;
+ /* Clear sticky power-fault bit from previous power failures */
+ hp_register_read_word(php_ctlr->pci_dev,
+ SLOT_STATUS(slot->ctrl->cap_base), slot_status);
+ slot_status &= PWR_FAULT_DETECTED;
+ if (slot_status)
+ hp_register_write_word(php_ctlr->pci_dev,
+ SLOT_STATUS(slot->ctrl->cap_base), slot_status);
+
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) {
retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) {