diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 4d8aee119134..446e9beff046 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -302,16 +302,43 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) | |||
302 | add_timer(&php_ctlr->int_poll_timer); | 302 | add_timer(&php_ctlr->int_poll_timer); |
303 | } | 303 | } |
304 | 304 | ||
305 | /* | ||
306 | * Returns 1 if SHPC finishes executing a command within 1 sec, | ||
307 | * otherwise returns 0. | ||
308 | */ | ||
309 | static inline int shpc_poll_ctrl_busy(struct controller *ctrl) | ||
310 | { | ||
311 | int i; | ||
312 | u16 cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
313 | |||
314 | if (!(cmd_status & 0x1)) | ||
315 | return 1; | ||
316 | |||
317 | /* Check every 0.1 sec for a total of 1 sec */ | ||
318 | for (i = 0; i < 10; i++) { | ||
319 | msleep(100); | ||
320 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
321 | if (!(cmd_status & 0x1)) | ||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
305 | static inline int shpc_wait_cmd(struct controller *ctrl) | 328 | static inline int shpc_wait_cmd(struct controller *ctrl) |
306 | { | 329 | { |
307 | int retval = 0; | 330 | int retval = 0; |
308 | unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000; | 331 | unsigned long timeout = msecs_to_jiffies(1000); |
309 | unsigned long timeout = msecs_to_jiffies(timeout_msec); | 332 | int rc; |
310 | int rc = wait_event_interruptible_timeout(ctrl->queue, | 333 | |
311 | !ctrl->cmd_busy, timeout); | 334 | if (shpchp_poll_mode) |
335 | rc = shpc_poll_ctrl_busy(ctrl); | ||
336 | else | ||
337 | rc = wait_event_interruptible_timeout(ctrl->queue, | ||
338 | !ctrl->cmd_busy, timeout); | ||
312 | if (!rc) { | 339 | if (!rc) { |
313 | retval = -EIO; | 340 | retval = -EIO; |
314 | err("Command not completed in %d msec\n", timeout_msec); | 341 | err("Command not completed in 1000 msec\n"); |
315 | } else if (rc < 0) { | 342 | } else if (rc < 0) { |
316 | retval = -EINTR; | 343 | retval = -EINTR; |
317 | info("Command was interrupted by a signal\n"); | 344 | info("Command was interrupted by a signal\n"); |
@@ -327,26 +354,15 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
327 | u16 cmd_status; | 354 | u16 cmd_status; |
328 | int retval = 0; | 355 | int retval = 0; |
329 | u16 temp_word; | 356 | u16 temp_word; |
330 | int i; | ||
331 | 357 | ||
332 | DBG_ENTER_ROUTINE | 358 | DBG_ENTER_ROUTINE |
333 | 359 | ||
334 | mutex_lock(&slot->ctrl->cmd_lock); | 360 | mutex_lock(&slot->ctrl->cmd_lock); |
335 | 361 | ||
336 | for (i = 0; i < 10; i++) { | 362 | if (!shpc_poll_ctrl_busy(ctrl)) { |
337 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
338 | |||
339 | if (!(cmd_status & 0x1)) | ||
340 | break; | ||
341 | /* Check every 0.1 sec for a total of 1 sec*/ | ||
342 | msleep(100); | ||
343 | } | ||
344 | |||
345 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
346 | |||
347 | if (cmd_status & 0x1) { | ||
348 | /* After 1 sec and and the controller is still busy */ | 363 | /* After 1 sec and and the controller is still busy */ |
349 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); | 364 | err("%s : Controller is still busy after 1 sec.\n", |
365 | __FUNCTION__); | ||
350 | retval = -EBUSY; | 366 | retval = -EBUSY; |
351 | goto out; | 367 | goto out; |
352 | } | 368 | } |