diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2006-12-21 20:01:10 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 18:50:05 -0500 |
commit | 262303fe329a51463925f3749aafc358a4201397 (patch) | |
tree | f9b82b164c8a25d94c9602d640f1b853e7633295 /drivers/pci/hotplug/pciehp_hpc.c | |
parent | 44ef4cefb0168740184ee3d7d18254339741e9d5 (diff) |
pciehp: fix wait command completion
This patch fixes this problem that pciehp driver will sleep
unnecessarily long when waiting for command completion. With this
patch, modprobe pciehp driver becomes very faster as follows for
instance.
o Without this patch
# time /sbin/modprobe pciehp
real 0m4.976s
user 0m0.000s
sys 0m0.004s
o With this patch
# time /sbin/modprobe pciehp
real 0m0.640s
user 0m0.000s
sys 0m0.004s
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 | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9fbd9b9f9824..eb1862b50bb1 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -251,20 +251,21 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) | |||
251 | 251 | ||
252 | static inline int pcie_wait_cmd(struct controller *ctrl) | 252 | static inline int pcie_wait_cmd(struct controller *ctrl) |
253 | { | 253 | { |
254 | DECLARE_WAITQUEUE(wait, current); | 254 | int retval = 0; |
255 | 255 | unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; | |
256 | add_wait_queue(&ctrl->queue, &wait); | 256 | unsigned long timeout = msecs_to_jiffies(msecs); |
257 | if (!pciehp_poll_mode) | 257 | int rc; |
258 | /* Sleep for up to 1 second */ | ||
259 | msleep_interruptible(1000); | ||
260 | else | ||
261 | msleep_interruptible(2500); | ||
262 | 258 | ||
263 | remove_wait_queue(&ctrl->queue, &wait); | 259 | rc = wait_event_interruptible_timeout(ctrl->queue, |
264 | if (signal_pending(current)) | 260 | !ctrl->cmd_busy, timeout); |
265 | return -EINTR; | 261 | if (!rc) |
262 | dbg("Command not completed in 1000 msec\n"); | ||
263 | else if (rc < 0) { | ||
264 | retval = -EINTR; | ||
265 | info("Command was interrupted by a signal\n"); | ||
266 | } | ||
266 | 267 | ||
267 | return 0; | 268 | return retval; |
268 | } | 269 | } |
269 | 270 | ||
270 | static int pcie_write_cmd(struct slot *slot, u16 cmd) | 271 | static int pcie_write_cmd(struct slot *slot, u16 cmd) |
@@ -291,6 +292,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
291 | __FUNCTION__); | 292 | __FUNCTION__); |
292 | } | 293 | } |
293 | 294 | ||
295 | ctrl->cmd_busy = 1; | ||
294 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); | 296 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); |
295 | if (retval) { | 297 | if (retval) { |
296 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | 298 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); |
@@ -773,6 +775,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
773 | /* | 775 | /* |
774 | * Command Complete Interrupt Pending | 776 | * Command Complete Interrupt Pending |
775 | */ | 777 | */ |
778 | ctrl->cmd_busy = 0; | ||
776 | wake_up_interruptible(&ctrl->queue); | 779 | wake_up_interruptible(&ctrl->queue); |
777 | } | 780 | } |
778 | 781 | ||