diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 120 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 25 |
3 files changed, 23 insertions, 123 deletions
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index f6d606dde691..b1e2a7705835 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -80,6 +80,7 @@ struct event_info { struct controller { struct list_head ctrl_list; struct mutex crit_sect; /* critical section mutex */ + struct mutex cmd_lock; /* command lock */ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 3a8e733aead5..802c4c48d186 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -242,21 +242,10 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, int rc = 0; dbg("%s: change to speed %d\n", __FUNCTION__, speed); - mutex_lock(&ctrl->crit_sect); if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } - - if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { - err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", - __FUNCTION__); - err("%s: Error code (%d)\n", __FUNCTION__, rc); - mutex_unlock(&ctrl->crit_sect); return WRONG_BUS_FREQUENCY; } - mutex_unlock(&ctrl->crit_sect); return rc; } @@ -330,15 +319,6 @@ static int board_added(struct slot *p_slot) return -1; } - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - return -1; - } - - if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { if (slots_not_empty) return WRONG_BUS_FREQUENCY; @@ -349,25 +329,12 @@ static int board_added(struct slot *p_slot) return WRONG_BUS_FREQUENCY; } - if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { - err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", - __FUNCTION__); - err("%s: Error code (%d)\n", __FUNCTION__, rc); - mutex_unlock(&ctrl->crit_sect); - return WRONG_BUS_FREQUENCY; - } /* turn on board, blink green LED, turn off Amber LED */ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); mutex_unlock(&ctrl->crit_sect); return rc; } - - if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { - err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); - mutex_unlock(&ctrl->crit_sect); - return rc; - } } rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed); @@ -481,22 +448,12 @@ static int board_added(struct slot *p_slot) return rc; } - mutex_lock(&ctrl->crit_sect); /* turn on board, blink green LED, turn off Amber LED */ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); - mutex_unlock(&ctrl->crit_sect); return rc; } - if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { - err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); - mutex_unlock(&ctrl->crit_sect); - return rc; - } - - mutex_unlock(&ctrl->crit_sect); - /* Wait for ~1 second */ wait_for_ctrl_irq (ctrl); @@ -520,40 +477,18 @@ static int board_added(struct slot *p_slot) p_slot->is_a_board = 0x01; p_slot->pwr_save = 1; - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - p_slot->hpc_ops->green_led_on(p_slot); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - return 0; err_exit: - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - /* turn off slot, turn on Amber LED, turn off Green LED */ rc = p_slot->hpc_ops->slot_disable(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); return rc; } - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - return rc; - } - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - return(rc); } @@ -580,37 +515,19 @@ static int remove_board(struct slot *p_slot) if (p_slot->is_a_board) p_slot->status = 0x01; - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - /* turn off slot, turn on Amber LED, turn off Green LED */ rc = p_slot->hpc_ops->slot_disable(p_slot); if (rc) { err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); return rc; } - - rc = p_slot->hpc_ops->check_cmd_status(ctrl); - if (rc) { - err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - return rc; - } rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); if (rc) { err("%s: Issue of Set Attention command failed\n", __FUNCTION__); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); return rc; } - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - p_slot->pwr_save = 0; p_slot->is_a_board = 0; @@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (unsigned long slot) } else { p_slot->state = POWERON_STATE; - if (shpchp_enable_slot(p_slot)) { - /* Wait for exclusive access to hardware */ - mutex_lock(&p_slot->ctrl->crit_sect); - + if (shpchp_enable_slot(p_slot)) p_slot->hpc_ops->green_led_off(p_slot); - /* Done with exclusive hardware access */ - mutex_unlock(&p_slot->ctrl->crit_sect); - } p_slot->state = STATIC_STATE; } @@ -767,27 +678,12 @@ static void interrupt_event_handler(struct controller *ctrl) switch (p_slot->state) { case BLINKINGOFF_STATE: - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - p_slot->hpc_ops->green_led_on(p_slot); - p_slot->hpc_ops->set_attention_status(p_slot, 0); - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); break; case BLINKINGON_STATE: - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - p_slot->hpc_ops->green_led_off(p_slot); - p_slot->hpc_ops->set_attention_status(p_slot, 0); - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - break; default: warn("Not a valid state\n"); @@ -812,17 +708,10 @@ static void interrupt_event_handler(struct controller *ctrl) info(msg_button_on, p_slot->number); } - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - /* blink green LED and turn off amber */ p_slot->hpc_ops->green_led_blink(p_slot); - p_slot->hpc_ops->set_attention_status(p_slot, 0); - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); - init_timer(&p_slot->task_event); p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; @@ -833,15 +722,8 @@ static void interrupt_event_handler(struct controller *ctrl) } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { /***********POWER FAULT********************/ dbg("%s: power fault\n", __FUNCTION__); - /* Wait for exclusive access to hardware */ - mutex_lock(&ctrl->crit_sect); - p_slot->hpc_ops->set_attention_status(p_slot, 1); - p_slot->hpc_ops->green_led_off(p_slot); - - /* Done with exclusive hardware access */ - mutex_unlock(&ctrl->crit_sect); } else { /* refresh notification */ if (p_slot) diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index ae81427e42b1..c32a1b16704f 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -231,6 +231,7 @@ static spinlock_t list_lock; static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); +static int hpc_check_cmd_status(struct controller *ctrl); /* This is the interrupt polling timeout function. */ static void int_poll_timeout(unsigned long lphp_ctlr) @@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) int i; DBG_ENTER_ROUTINE - + + mutex_lock(&slot->ctrl->cmd_lock); + if (!php_ctlr) { err("%s: Invalid HPC controller handle!\n", __FUNCTION__); - return -1; + retval = -EINVAL; + goto out; } for (i = 0; i < 10; i++) { @@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) if (cmd_status & 0x1) { /* After 1 sec and and the controller is still busy */ err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); - return -1; + retval = -EBUSY; + goto out; } ++t_slot; @@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) * Wait for command completion. */ retval = shpc_wait_cmd(slot->ctrl); + if (retval) + goto out; + + cmd_status = hpc_check_cmd_status(slot->ctrl); + if (cmd_status) { + err("%s: Failed to issued command 0x%x (error code = %d)\n", + __FUNCTION__, cmd, cmd_status); + retval = -EIO; + } + out: + mutex_unlock(&slot->ctrl->cmd_lock); DBG_LEAVE_ROUTINE return retval; @@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = { .green_led_blink = hpc_set_green_led_blink, .release_ctlr = hpc_release_ctlr, - .check_cmd_status = hpc_check_cmd_status, }; inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, @@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); mutex_init(&ctrl->crit_sect); + mutex_init(&ctrl->cmd_lock); + /* Setup wait queue */ init_waitqueue_head(&ctrl->queue); |