pciehp: cleanup wait command completion
This patch cleans up the code to wait for command completion. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
75e13178af
commit
44ef4cefb0
@ -173,24 +173,6 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int wait_for_ctrl_irq(struct controller *ctrl)
|
|
||||||
{
|
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
|
||||||
|
|
||||||
add_wait_queue(&ctrl->queue, &wait);
|
|
||||||
if (!pciehp_poll_mode)
|
|
||||||
/* Sleep for up to 1 second */
|
|
||||||
msleep_interruptible(1000);
|
|
||||||
else
|
|
||||||
msleep_interruptible(2500);
|
|
||||||
|
|
||||||
remove_wait_queue(&ctrl->queue, &wait);
|
|
||||||
if (signal_pending(current))
|
|
||||||
return -EINTR;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct hpc_ops {
|
struct hpc_ops {
|
||||||
int (*power_on_slot)(struct slot *slot);
|
int (*power_on_slot)(struct slot *slot);
|
||||||
int (*power_off_slot)(struct slot *slot);
|
int (*power_off_slot)(struct slot *slot);
|
||||||
|
@ -374,25 +374,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
|
|||||||
pciehp_ctrl_list = ctrl;
|
pciehp_ctrl_list = ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for exclusive access to hardware */
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
|
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
|
||||||
|
|
||||||
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
|
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
|
||||||
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
|
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
|
||||||
if (rc) {
|
if (rc)
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
goto err_out_free_ctrl_slot;
|
goto err_out_free_ctrl_slot;
|
||||||
} else
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_out_free_ctrl_slot:
|
err_out_free_ctrl_slot:
|
||||||
|
@ -229,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
|
|||||||
|
|
||||||
static void set_slot_off(struct controller *ctrl, struct slot * pslot)
|
static void set_slot_off(struct controller *ctrl, struct slot * pslot)
|
||||||
{
|
{
|
||||||
/* Wait for exclusive access to hardware */
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
|
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
|
||||||
if (POWER_CTRL(ctrl->ctrlcap)) {
|
if (POWER_CTRL(ctrl->ctrlcap)) {
|
||||||
if (pslot->hpc_ops->power_off_slot(pslot)) {
|
if (pslot->hpc_ops->power_off_slot(pslot)) {
|
||||||
err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
|
err("%s: Issue of Slot Power Off command failed\n",
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
__FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
pslot->hpc_ops->green_led_off(pslot);
|
pslot->hpc_ops->green_led_off(pslot);
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ATTN_LED(ctrl->ctrlcap)) {
|
if (ATTN_LED(ctrl->ctrlcap)) {
|
||||||
if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
|
if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
|
||||||
err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
|
err("%s: Issue of Set Attention Led command failed\n",
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
__FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
|
|||||||
static int board_added(struct slot *p_slot)
|
static int board_added(struct slot *p_slot)
|
||||||
{
|
{
|
||||||
u8 hp_slot;
|
u8 hp_slot;
|
||||||
int rc = 0;
|
int retval = 0;
|
||||||
struct controller *ctrl = p_slot->ctrl;
|
struct controller *ctrl = p_slot->ctrl;
|
||||||
|
|
||||||
hp_slot = p_slot->device - ctrl->slot_device_offset;
|
hp_slot = p_slot->device - ctrl->slot_device_offset;
|
||||||
@ -279,53 +269,38 @@ static int board_added(struct slot *p_slot)
|
|||||||
__FUNCTION__, p_slot->device,
|
__FUNCTION__, p_slot->device,
|
||||||
ctrl->slot_device_offset, hp_slot);
|
ctrl->slot_device_offset, hp_slot);
|
||||||
|
|
||||||
/* Wait for exclusive access to hardware */
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
if (POWER_CTRL(ctrl->ctrlcap)) {
|
if (POWER_CTRL(ctrl->ctrlcap)) {
|
||||||
/* Power on slot */
|
/* Power on slot */
|
||||||
rc = p_slot->hpc_ops->power_on_slot(p_slot);
|
retval = p_slot->hpc_ops->power_on_slot(p_slot);
|
||||||
if (rc) {
|
if (retval)
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
return retval;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
p_slot->hpc_ops->green_led_blink(p_slot);
|
p_slot->hpc_ops->green_led_blink(p_slot);
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
/* Wait for ~1 second */
|
/* Wait for ~1 second */
|
||||||
wait_for_ctrl_irq (ctrl);
|
msleep(1000);
|
||||||
|
|
||||||
/* Check link training status */
|
/* Check link training status */
|
||||||
rc = p_slot->hpc_ops->check_lnk_status(ctrl);
|
retval = p_slot->hpc_ops->check_lnk_status(ctrl);
|
||||||
if (rc) {
|
if (retval) {
|
||||||
err("%s: Failed to check link status\n", __FUNCTION__);
|
err("%s: Failed to check link status\n", __FUNCTION__);
|
||||||
set_slot_off(ctrl, p_slot);
|
set_slot_off(ctrl, p_slot);
|
||||||
return rc;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a power fault */
|
/* Check for a power fault */
|
||||||
if (p_slot->hpc_ops->query_power_fault(p_slot)) {
|
if (p_slot->hpc_ops->query_power_fault(p_slot)) {
|
||||||
dbg("%s: power fault detected\n", __FUNCTION__);
|
dbg("%s: power fault detected\n", __FUNCTION__);
|
||||||
rc = POWER_FAILURE;
|
retval = POWER_FAILURE;
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = pciehp_configure_device(p_slot);
|
retval = pciehp_configure_device(p_slot);
|
||||||
if (rc) {
|
if (retval) {
|
||||||
err("Cannot add device 0x%x:%x\n", p_slot->bus,
|
err("Cannot add device 0x%x:%x\n", p_slot->bus,
|
||||||
p_slot->device);
|
p_slot->device);
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,26 +309,16 @@ static int board_added(struct slot *p_slot)
|
|||||||
*/
|
*/
|
||||||
if (pcie_mch_quirk)
|
if (pcie_mch_quirk)
|
||||||
pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
|
pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
/* Wait for exclusive access to hardware */
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
p_slot->hpc_ops->green_led_on(p_slot);
|
p_slot->hpc_ops->green_led_on(p_slot);
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
set_slot_off(ctrl, p_slot);
|
set_slot_off(ctrl, p_slot);
|
||||||
return -1;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove_board - Turns off slot and LED's
|
* remove_board - Turns off slot and LED's
|
||||||
*
|
*
|
||||||
@ -362,44 +327,32 @@ static int remove_board(struct slot *p_slot)
|
|||||||
{
|
{
|
||||||
u8 device;
|
u8 device;
|
||||||
u8 hp_slot;
|
u8 hp_slot;
|
||||||
int rc;
|
int retval = 0;
|
||||||
struct controller *ctrl = p_slot->ctrl;
|
struct controller *ctrl = p_slot->ctrl;
|
||||||
|
|
||||||
if (pciehp_unconfigure_device(p_slot))
|
retval = pciehp_unconfigure_device(p_slot);
|
||||||
return 1;
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
device = p_slot->device;
|
device = p_slot->device;
|
||||||
|
|
||||||
hp_slot = p_slot->device - ctrl->slot_device_offset;
|
hp_slot = p_slot->device - ctrl->slot_device_offset;
|
||||||
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
|
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
|
||||||
|
|
||||||
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
|
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
|
||||||
|
|
||||||
/* Wait for exclusive access to hardware */
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
if (POWER_CTRL(ctrl->ctrlcap)) {
|
if (POWER_CTRL(ctrl->ctrlcap)) {
|
||||||
/* power off slot */
|
/* power off slot */
|
||||||
rc = p_slot->hpc_ops->power_off_slot(p_slot);
|
retval = p_slot->hpc_ops->power_off_slot(p_slot);
|
||||||
if (rc) {
|
if (retval) {
|
||||||
err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
|
err("%s: Issue of Slot Disable command failed\n",
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
__FUNCTION__);
|
||||||
return rc;
|
return retval;
|
||||||
}
|
}
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
/* turn off Green LED */
|
/* turn off Green LED */
|
||||||
p_slot->hpc_ops->green_led_off(p_slot);
|
p_slot->hpc_ops->green_led_off(p_slot);
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -444,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot)
|
|||||||
dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
|
dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
|
||||||
p_slot->bus, p_slot->device);
|
p_slot->bus, p_slot->device);
|
||||||
|
|
||||||
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
|
if (pciehp_enable_slot(p_slot) &&
|
||||||
/* Wait for exclusive access to hardware */
|
PWR_LED(p_slot->ctrl->ctrlcap))
|
||||||
mutex_lock(&p_slot->ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
p_slot->hpc_ops->green_led_off(p_slot);
|
p_slot->hpc_ops->green_led_off(p_slot);
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (p_slot->ctrl);
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&p_slot->ctrl->ctrl_lock);
|
|
||||||
}
|
|
||||||
p_slot->state = STATIC_STATE;
|
p_slot->state = STATIC_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
|
|||||||
dbg("%s: adding bus:device(%x:%x)\n",
|
dbg("%s: adding bus:device(%x:%x)\n",
|
||||||
__FUNCTION__, p_slot->bus, p_slot->device);
|
__FUNCTION__, p_slot->bus, p_slot->device);
|
||||||
|
|
||||||
if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
|
if (pciehp_enable_slot(p_slot) &&
|
||||||
/* Wait for exclusive access to hardware */
|
PWR_LED(p_slot->ctrl->ctrlcap))
|
||||||
mutex_lock(&p_slot->ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
p_slot->hpc_ops->green_led_off(p_slot);
|
p_slot->hpc_ops->green_led_off(p_slot);
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (p_slot->ctrl);
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&p_slot->ctrl->ctrl_lock);
|
|
||||||
}
|
|
||||||
p_slot->state = STATIC_STATE;
|
p_slot->state = STATIC_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,40 +553,18 @@ static void interrupt_event_handler(struct controller *ctrl)
|
|||||||
|
|
||||||
switch (p_slot->state) {
|
switch (p_slot->state) {
|
||||||
case BLINKINGOFF_STATE:
|
case BLINKINGOFF_STATE:
|
||||||
/* Wait for exclusive access to hardware */
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
|
||||||
p_slot->hpc_ops->green_led_on(p_slot);
|
p_slot->hpc_ops->green_led_on(p_slot);
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
if (ATTN_LED(ctrl->ctrlcap)) {
|
|
||||||
p_slot->hpc_ops->set_attention_status(p_slot, 0);
|
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
if (ATTN_LED(ctrl->ctrlcap))
|
||||||
wait_for_ctrl_irq (ctrl);
|
p_slot->hpc_ops->set_attention_status(p_slot, 0);
|
||||||
}
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
break;
|
break;
|
||||||
case BLINKINGON_STATE:
|
case BLINKINGON_STATE:
|
||||||
/* Wait for exclusive access to hardware */
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
|
||||||
p_slot->hpc_ops->green_led_off(p_slot);
|
p_slot->hpc_ops->green_led_off(p_slot);
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
if (ATTN_LED(ctrl->ctrlcap)){
|
|
||||||
p_slot->hpc_ops->set_attention_status(p_slot, 0);
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
|
if (ATTN_LED(ctrl->ctrlcap))
|
||||||
|
p_slot->hpc_ops->set_attention_status(p_slot, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warn("Not a valid state\n");
|
warn("Not a valid state\n");
|
||||||
@ -676,26 +591,13 @@ static void interrupt_event_handler(struct controller *ctrl)
|
|||||||
info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot));
|
info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for exclusive access to hardware */
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
/* blink green LED and turn off amber */
|
/* blink green LED and turn off amber */
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
p_slot->hpc_ops->green_led_blink(p_slot);
|
p_slot->hpc_ops->green_led_blink(p_slot);
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ATTN_LED(ctrl->ctrlcap)) {
|
if (ATTN_LED(ctrl->ctrlcap))
|
||||||
p_slot->hpc_ops->set_attention_status(p_slot, 0);
|
p_slot->hpc_ops->set_attention_status(p_slot, 0);
|
||||||
|
|
||||||
/* Wait for the command to complete */
|
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
init_timer(&p_slot->task_event);
|
init_timer(&p_slot->task_event);
|
||||||
p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
|
p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
|
||||||
p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
|
p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
|
||||||
@ -708,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl)
|
|||||||
else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
|
else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
|
||||||
if (POWER_CTRL(ctrl->ctrlcap)) {
|
if (POWER_CTRL(ctrl->ctrlcap)) {
|
||||||
dbg("power fault\n");
|
dbg("power fault\n");
|
||||||
/* Wait for exclusive access to hardware */
|
if (ATTN_LED(ctrl->ctrlcap))
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
|
||||||
|
|
||||||
if (ATTN_LED(ctrl->ctrlcap)) {
|
|
||||||
p_slot->hpc_ops->set_attention_status(p_slot, 1);
|
p_slot->hpc_ops->set_attention_status(p_slot, 1);
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PWR_LED(ctrl->ctrlcap)) {
|
if (PWR_LED(ctrl->ctrlcap))
|
||||||
p_slot->hpc_ops->green_led_off(p_slot);
|
p_slot->hpc_ops->green_led_off(p_slot);
|
||||||
wait_for_ctrl_irq (ctrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Done with exclusive hardware access */
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/***********SURPRISE REMOVAL********************/
|
/***********SURPRISE REMOVAL********************/
|
||||||
@ -750,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pciehp_enable_slot(struct slot *p_slot)
|
int pciehp_enable_slot(struct slot *p_slot)
|
||||||
{
|
{
|
||||||
u8 getstatus = 0;
|
u8 getstatus = 0;
|
||||||
|
@ -249,6 +249,24 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
|
|||||||
add_timer(&ctrl->poll_timer);
|
add_timer(&ctrl->poll_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int pcie_wait_cmd(struct controller *ctrl)
|
||||||
|
{
|
||||||
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
|
|
||||||
|
add_wait_queue(&ctrl->queue, &wait);
|
||||||
|
if (!pciehp_poll_mode)
|
||||||
|
/* Sleep for up to 1 second */
|
||||||
|
msleep_interruptible(1000);
|
||||||
|
else
|
||||||
|
msleep_interruptible(2500);
|
||||||
|
|
||||||
|
remove_wait_queue(&ctrl->queue, &wait);
|
||||||
|
if (signal_pending(current))
|
||||||
|
return -EINTR;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int pcie_write_cmd(struct slot *slot, u16 cmd)
|
static int pcie_write_cmd(struct slot *slot, u16 cmd)
|
||||||
{
|
{
|
||||||
struct controller *ctrl = slot->ctrl;
|
struct controller *ctrl = slot->ctrl;
|
||||||
@ -257,24 +275,34 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
|
|||||||
|
|
||||||
DBG_ENTER_ROUTINE
|
DBG_ENTER_ROUTINE
|
||||||
|
|
||||||
|
mutex_lock(&ctrl->ctrl_lock);
|
||||||
|
|
||||||
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
|
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
|
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
|
||||||
return retval;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
|
if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
|
||||||
/* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
|
/* After 1 sec and CMD_COMPLETED still not set, just
|
||||||
the next command according to spec. Just print out the error message */
|
proceed forward to issue the next command according
|
||||||
dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
|
to spec. Just print out the error message */
|
||||||
|
dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
|
||||||
|
__FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
|
retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
|
||||||
if (retval) {
|
if (retval) {
|
||||||
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
|
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
|
||||||
return retval;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for command completion.
|
||||||
|
*/
|
||||||
|
retval = pcie_wait_cmd(ctrl);
|
||||||
|
out:
|
||||||
|
mutex_unlock(&ctrl->ctrl_lock);
|
||||||
DBG_LEAVE_ROUTINE
|
DBG_LEAVE_ROUTINE
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user