提交 d29aadda 编写于 作者: K Kenji Kaneshige 提交者: Greg Kroah-Hartman

[PATCH] shpchp - cleanup check command status

This patch cleanups codes that check the command status. For this, it
introduces a new semaphore "cmd_sem" for each controller.
Signed-off-by: NKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 a4534560
...@@ -80,6 +80,7 @@ struct event_info { ...@@ -80,6 +80,7 @@ struct event_info {
struct controller { struct controller {
struct list_head ctrl_list; struct list_head ctrl_list;
struct mutex crit_sect; /* critical section mutex */ struct mutex crit_sect; /* critical section mutex */
struct mutex cmd_lock; /* command lock */
struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */ int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */ int slot_num_inc; /* 1 or -1 */
......
...@@ -242,21 +242,10 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, ...@@ -242,21 +242,10 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
int rc = 0; int rc = 0;
dbg("%s: change to speed %d\n", __FUNCTION__, speed); 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))) { 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__); 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; return WRONG_BUS_FREQUENCY;
} }
mutex_unlock(&ctrl->crit_sect);
return rc; return rc;
} }
...@@ -330,15 +319,6 @@ static int board_added(struct slot *p_slot) ...@@ -330,15 +319,6 @@ static int board_added(struct slot *p_slot)
return -1; 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 ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
if (slots_not_empty) if (slots_not_empty)
return WRONG_BUS_FREQUENCY; return WRONG_BUS_FREQUENCY;
...@@ -349,25 +329,12 @@ static int board_added(struct slot *p_slot) ...@@ -349,25 +329,12 @@ static int board_added(struct slot *p_slot)
return WRONG_BUS_FREQUENCY; 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 */ /* turn on board, blink green LED, turn off Amber LED */
if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
mutex_unlock(&ctrl->crit_sect); mutex_unlock(&ctrl->crit_sect);
return rc; 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); rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
...@@ -481,22 +448,12 @@ static int board_added(struct slot *p_slot) ...@@ -481,22 +448,12 @@ static int board_added(struct slot *p_slot)
return rc; return rc;
} }
mutex_lock(&ctrl->crit_sect);
/* turn on board, blink green LED, turn off Amber LED */ /* turn on board, blink green LED, turn off Amber LED */
if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
mutex_unlock(&ctrl->crit_sect);
return rc; 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 ~1 second */
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
...@@ -520,40 +477,18 @@ static int board_added(struct slot *p_slot) ...@@ -520,40 +477,18 @@ static int board_added(struct slot *p_slot)
p_slot->is_a_board = 0x01; p_slot->is_a_board = 0x01;
p_slot->pwr_save = 1; 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); p_slot->hpc_ops->green_led_on(p_slot);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
return 0; return 0;
err_exit: err_exit:
/* Wait for exclusive access to hardware */
mutex_lock(&ctrl->crit_sect);
/* turn off slot, turn on Amber LED, turn off Green LED */ /* turn off slot, turn on Amber LED, turn off Green LED */
rc = p_slot->hpc_ops->slot_disable(p_slot); rc = p_slot->hpc_ops->slot_disable(p_slot);
if (rc) { if (rc) {
err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
return rc; 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); return(rc);
} }
...@@ -580,37 +515,19 @@ static int remove_board(struct slot *p_slot) ...@@ -580,37 +515,19 @@ static int remove_board(struct slot *p_slot)
if (p_slot->is_a_board) if (p_slot->is_a_board)
p_slot->status = 0x01; 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 */ /* turn off slot, turn on Amber LED, turn off Green LED */
rc = p_slot->hpc_ops->slot_disable(p_slot); rc = p_slot->hpc_ops->slot_disable(p_slot);
if (rc) { if (rc) {
err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
return rc; 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); rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
if (rc) { if (rc) {
err("%s: Issue of Set Attention command failed\n", __FUNCTION__); err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
return rc; return rc;
} }
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
p_slot->pwr_save = 0; p_slot->pwr_save = 0;
p_slot->is_a_board = 0; p_slot->is_a_board = 0;
...@@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (unsigned long slot) ...@@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (unsigned long slot)
} else { } else {
p_slot->state = POWERON_STATE; p_slot->state = POWERON_STATE;
if (shpchp_enable_slot(p_slot)) { if (shpchp_enable_slot(p_slot))
/* Wait for exclusive access to hardware */
mutex_lock(&p_slot->ctrl->crit_sect);
p_slot->hpc_ops->green_led_off(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; p_slot->state = STATIC_STATE;
} }
...@@ -767,27 +678,12 @@ static void interrupt_event_handler(struct controller *ctrl) ...@@ -767,27 +678,12 @@ 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 */
mutex_lock(&ctrl->crit_sect);
p_slot->hpc_ops->green_led_on(p_slot); p_slot->hpc_ops->green_led_on(p_slot);
p_slot->hpc_ops->set_attention_status(p_slot, 0); p_slot->hpc_ops->set_attention_status(p_slot, 0);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
break; break;
case BLINKINGON_STATE: 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->green_led_off(p_slot);
p_slot->hpc_ops->set_attention_status(p_slot, 0); p_slot->hpc_ops->set_attention_status(p_slot, 0);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
break; break;
default: default:
warn("Not a valid state\n"); warn("Not a valid state\n");
...@@ -812,17 +708,10 @@ static void interrupt_event_handler(struct controller *ctrl) ...@@ -812,17 +708,10 @@ static void interrupt_event_handler(struct controller *ctrl)
info(msg_button_on, p_slot->number); 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 */ /* blink green LED and turn off amber */
p_slot->hpc_ops->green_led_blink(p_slot); p_slot->hpc_ops->green_led_blink(p_slot);
p_slot->hpc_ops->set_attention_status(p_slot, 0); 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); 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;
...@@ -833,15 +722,8 @@ static void interrupt_event_handler(struct controller *ctrl) ...@@ -833,15 +722,8 @@ 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) {
/***********POWER FAULT********************/ /***********POWER FAULT********************/
dbg("%s: power fault\n", __FUNCTION__); 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->set_attention_status(p_slot, 1);
p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->green_led_off(p_slot);
/* Done with exclusive hardware access */
mutex_unlock(&ctrl->crit_sect);
} else { } else {
/* refresh notification */ /* refresh notification */
if (p_slot) if (p_slot)
......
...@@ -231,6 +231,7 @@ static spinlock_t list_lock; ...@@ -231,6 +231,7 @@ static spinlock_t list_lock;
static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); 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 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. */ /* This is the interrupt polling timeout function. */
static void int_poll_timeout(unsigned long lphp_ctlr) 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) ...@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
int i; int i;
DBG_ENTER_ROUTINE DBG_ENTER_ROUTINE
mutex_lock(&slot->ctrl->cmd_lock);
if (!php_ctlr) { if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__); err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1; retval = -EINVAL;
goto out;
} }
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
...@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) ...@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
if (cmd_status & 0x1) { if (cmd_status & 0x1) {
/* After 1 sec and and the controller is still busy */ /* After 1 sec and and the controller is still busy */
err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
return -1; retval = -EBUSY;
goto out;
} }
++t_slot; ++t_slot;
...@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) ...@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
* Wait for command completion. * Wait for command completion.
*/ */
retval = shpc_wait_cmd(slot->ctrl); 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 DBG_LEAVE_ROUTINE
return retval; return retval;
...@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = { ...@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
.green_led_blink = hpc_set_green_led_blink, .green_led_blink = hpc_set_green_led_blink,
.release_ctlr = hpc_release_ctlr, .release_ctlr = hpc_release_ctlr,
.check_cmd_status = hpc_check_cmd_status,
}; };
inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, 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) ...@@ -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); dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
mutex_init(&ctrl->crit_sect); mutex_init(&ctrl->crit_sect);
mutex_init(&ctrl->cmd_lock);
/* Setup wait queue */ /* Setup wait queue */
init_waitqueue_head(&ctrl->queue); init_waitqueue_head(&ctrl->queue);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册