diff options
Diffstat (limited to 'drivers/pci/hotplug/shpchp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 25 |
1 files changed, 21 insertions, 4 deletions
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; | |||
231 | static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); | 231 | static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); |
232 | 232 | ||
233 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); | 233 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); |
234 | static int hpc_check_cmd_status(struct controller *ctrl); | ||
234 | 235 | ||
235 | /* This is the interrupt polling timeout function. */ | 236 | /* This is the interrupt polling timeout function. */ |
236 | static void int_poll_timeout(unsigned long lphp_ctlr) | 237 | 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 | int i; | 304 | int i; |
304 | 305 | ||
305 | DBG_ENTER_ROUTINE | 306 | DBG_ENTER_ROUTINE |
306 | 307 | ||
308 | mutex_lock(&slot->ctrl->cmd_lock); | ||
309 | |||
307 | if (!php_ctlr) { | 310 | if (!php_ctlr) { |
308 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 311 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); |
309 | return -1; | 312 | retval = -EINVAL; |
313 | goto out; | ||
310 | } | 314 | } |
311 | 315 | ||
312 | for (i = 0; i < 10; i++) { | 316 | for (i = 0; i < 10; i++) { |
@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
323 | if (cmd_status & 0x1) { | 327 | if (cmd_status & 0x1) { |
324 | /* After 1 sec and and the controller is still busy */ | 328 | /* After 1 sec and and the controller is still busy */ |
325 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); | 329 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); |
326 | return -1; | 330 | retval = -EBUSY; |
331 | goto out; | ||
327 | } | 332 | } |
328 | 333 | ||
329 | ++t_slot; | 334 | ++t_slot; |
@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
340 | * Wait for command completion. | 345 | * Wait for command completion. |
341 | */ | 346 | */ |
342 | retval = shpc_wait_cmd(slot->ctrl); | 347 | retval = shpc_wait_cmd(slot->ctrl); |
348 | if (retval) | ||
349 | goto out; | ||
350 | |||
351 | cmd_status = hpc_check_cmd_status(slot->ctrl); | ||
352 | if (cmd_status) { | ||
353 | err("%s: Failed to issued command 0x%x (error code = %d)\n", | ||
354 | __FUNCTION__, cmd, cmd_status); | ||
355 | retval = -EIO; | ||
356 | } | ||
357 | out: | ||
358 | mutex_unlock(&slot->ctrl->cmd_lock); | ||
343 | 359 | ||
344 | DBG_LEAVE_ROUTINE | 360 | DBG_LEAVE_ROUTINE |
345 | return retval; | 361 | return retval; |
@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
1343 | .green_led_blink = hpc_set_green_led_blink, | 1359 | .green_led_blink = hpc_set_green_led_blink, |
1344 | 1360 | ||
1345 | .release_ctlr = hpc_release_ctlr, | 1361 | .release_ctlr = hpc_release_ctlr, |
1346 | .check_cmd_status = hpc_check_cmd_status, | ||
1347 | }; | 1362 | }; |
1348 | 1363 | ||
1349 | inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, | 1364 | 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 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); | 1470 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); |
1456 | 1471 | ||
1457 | mutex_init(&ctrl->crit_sect); | 1472 | mutex_init(&ctrl->crit_sect); |
1473 | mutex_init(&ctrl->cmd_lock); | ||
1474 | |||
1458 | /* Setup wait queue */ | 1475 | /* Setup wait queue */ |
1459 | init_waitqueue_head(&ctrl->queue); | 1476 | init_waitqueue_head(&ctrl->queue); |
1460 | 1477 | ||