diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2006-12-21 20:01:09 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 18:50:05 -0500 |
commit | 44ef4cefb0168740184ee3d7d18254339741e9d5 (patch) | |
tree | 9ae7d2d94c6bec9fe1b6c0a9ddf7e78994ea4dc9 /drivers/pci/hotplug/pciehp_hpc.c | |
parent | 75e13178af33e20b5802885f637af2a82c64ac2c (diff) |
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>
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index d8f4f1241b56..9fbd9b9f9824 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -249,6 +249,24 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) | |||
249 | add_timer(&ctrl->poll_timer); | 249 | add_timer(&ctrl->poll_timer); |
250 | } | 250 | } |
251 | 251 | ||
252 | static inline int pcie_wait_cmd(struct controller *ctrl) | ||
253 | { | ||
254 | DECLARE_WAITQUEUE(wait, current); | ||
255 | |||
256 | add_wait_queue(&ctrl->queue, &wait); | ||
257 | if (!pciehp_poll_mode) | ||
258 | /* Sleep for up to 1 second */ | ||
259 | msleep_interruptible(1000); | ||
260 | else | ||
261 | msleep_interruptible(2500); | ||
262 | |||
263 | remove_wait_queue(&ctrl->queue, &wait); | ||
264 | if (signal_pending(current)) | ||
265 | return -EINTR; | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
252 | static int pcie_write_cmd(struct slot *slot, u16 cmd) | 270 | static int pcie_write_cmd(struct slot *slot, u16 cmd) |
253 | { | 271 | { |
254 | struct controller *ctrl = slot->ctrl; | 272 | struct controller *ctrl = slot->ctrl; |
@@ -257,24 +275,34 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
257 | 275 | ||
258 | DBG_ENTER_ROUTINE | 276 | DBG_ENTER_ROUTINE |
259 | 277 | ||
278 | mutex_lock(&ctrl->ctrl_lock); | ||
279 | |||
260 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 280 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
261 | if (retval) { | 281 | if (retval) { |
262 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | 282 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
263 | return retval; | 283 | goto out; |
264 | } | 284 | } |
265 | 285 | ||
266 | if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { | 286 | if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { |
267 | /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue | 287 | /* After 1 sec and CMD_COMPLETED still not set, just |
268 | the next command according to spec. Just print out the error message */ | 288 | proceed forward to issue the next command according |
269 | dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); | 289 | to spec. Just print out the error message */ |
290 | dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", | ||
291 | __FUNCTION__); | ||
270 | } | 292 | } |
271 | 293 | ||
272 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); | 294 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); |
273 | if (retval) { | 295 | if (retval) { |
274 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | 296 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); |
275 | return retval; | 297 | goto out; |
276 | } | 298 | } |
277 | 299 | ||
300 | /* | ||
301 | * Wait for command completion. | ||
302 | */ | ||
303 | retval = pcie_wait_cmd(ctrl); | ||
304 | out: | ||
305 | mutex_unlock(&ctrl->ctrl_lock); | ||
278 | DBG_LEAVE_ROUTINE | 306 | DBG_LEAVE_ROUTINE |
279 | return retval; | 307 | return retval; |
280 | } | 308 | } |