aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2006-12-21 20:01:09 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:50:05 -0500
commit44ef4cefb0168740184ee3d7d18254339741e9d5 (patch)
tree9ae7d2d94c6bec9fe1b6c0a9ddf7e78994ea4dc9 /drivers/pci/hotplug
parent75e13178af33e20b5802885f637af2a82c64ac2c (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')
-rw-r--r--drivers/pci/hotplug/pciehp.h18
-rw-r--r--drivers/pci/hotplug/pciehp_core.c14
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c205
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c38
4 files changed, 82 insertions, 193 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e4524cf02427..17167d594472 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -173,24 +173,6 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
173 return NULL; 173 return NULL;
174} 174}
175 175
176static inline int wait_for_ctrl_irq(struct controller *ctrl)
177{
178 DECLARE_WAITQUEUE(wait, current);
179
180 add_wait_queue(&ctrl->queue, &wait);
181 if (!pciehp_poll_mode)
182 /* Sleep for up to 1 second */
183 msleep_interruptible(1000);
184 else
185 msleep_interruptible(2500);
186
187 remove_wait_queue(&ctrl->queue, &wait);
188 if (signal_pending(current))
189 return -EINTR;
190
191 return 0;
192}
193
194struct hpc_ops { 176struct hpc_ops {
195 int (*power_on_slot)(struct slot *slot); 177 int (*power_on_slot)(struct slot *slot);
196 int (*power_off_slot)(struct slot *slot); 178 int (*power_off_slot)(struct slot *slot);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index e2d45662bdbf..f7b8e0504fec 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -374,25 +374,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
374 pciehp_ctrl_list = ctrl; 374 pciehp_ctrl_list = ctrl;
375 } 375 }
376 376
377 /* Wait for exclusive access to hardware */
378 mutex_lock(&ctrl->ctrl_lock);
379
380 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ 377 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
381
382 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { 378 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
383 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ 379 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
384 if (rc) { 380 if (rc)
385 /* Done with exclusive hardware access */
386 mutex_unlock(&ctrl->ctrl_lock);
387 goto err_out_free_ctrl_slot; 381 goto err_out_free_ctrl_slot;
388 } else
389 /* Wait for the command to complete */
390 wait_for_ctrl_irq (ctrl);
391 } 382 }
392 383
393 /* Done with exclusive hardware access */
394 mutex_unlock(&ctrl->ctrl_lock);
395
396 return 0; 384 return 0;
397 385
398err_out_free_ctrl_slot: 386err_out_free_ctrl_slot:
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 072befa345a7..4283ef56dbd9 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -229,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
229 229
230static void set_slot_off(struct controller *ctrl, struct slot * pslot) 230static void set_slot_off(struct controller *ctrl, struct slot * pslot)
231{ 231{
232 /* Wait for exclusive access to hardware */
233 mutex_lock(&ctrl->ctrl_lock);
234
235 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ 232 /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
236 if (POWER_CTRL(ctrl->ctrlcap)) { 233 if (POWER_CTRL(ctrl->ctrlcap)) {
237 if (pslot->hpc_ops->power_off_slot(pslot)) { 234 if (pslot->hpc_ops->power_off_slot(pslot)) {
238 err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); 235 err("%s: Issue of Slot Power Off command failed\n",
239 mutex_unlock(&ctrl->ctrl_lock); 236 __FUNCTION__);
240 return; 237 return;
241 } 238 }
242 wait_for_ctrl_irq (ctrl);
243 } 239 }
244 240
245 if (PWR_LED(ctrl->ctrlcap)) { 241 if (PWR_LED(ctrl->ctrlcap))
246 pslot->hpc_ops->green_led_off(pslot); 242 pslot->hpc_ops->green_led_off(pslot);
247 wait_for_ctrl_irq (ctrl);
248 }
249 243
250 if (ATTN_LED(ctrl->ctrlcap)) { 244 if (ATTN_LED(ctrl->ctrlcap)) {
251 if (pslot->hpc_ops->set_attention_status(pslot, 1)) { 245 if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
252 err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); 246 err("%s: Issue of Set Attention Led command failed\n",
253 mutex_unlock(&ctrl->ctrl_lock); 247 __FUNCTION__);
254 return; 248 return;
255 } 249 }
256 wait_for_ctrl_irq (ctrl);
257 } 250 }
258
259 /* Done with exclusive hardware access */
260 mutex_unlock(&ctrl->ctrl_lock);
261} 251}
262 252
263/** 253/**
@@ -270,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
270static int board_added(struct slot *p_slot) 260static int board_added(struct slot *p_slot)
271{ 261{
272 u8 hp_slot; 262 u8 hp_slot;
273 int rc = 0; 263 int retval = 0;
274 struct controller *ctrl = p_slot->ctrl; 264 struct controller *ctrl = p_slot->ctrl;
275 265
276 hp_slot = p_slot->device - ctrl->slot_device_offset; 266 hp_slot = p_slot->device - ctrl->slot_device_offset;
@@ -279,53 +269,38 @@ static int board_added(struct slot *p_slot)
279 __FUNCTION__, p_slot->device, 269 __FUNCTION__, p_slot->device,
280 ctrl->slot_device_offset, hp_slot); 270 ctrl->slot_device_offset, hp_slot);
281 271
282 /* Wait for exclusive access to hardware */
283 mutex_lock(&ctrl->ctrl_lock);
284
285 if (POWER_CTRL(ctrl->ctrlcap)) { 272 if (POWER_CTRL(ctrl->ctrlcap)) {
286 /* Power on slot */ 273 /* Power on slot */
287 rc = p_slot->hpc_ops->power_on_slot(p_slot); 274 retval = p_slot->hpc_ops->power_on_slot(p_slot);
288 if (rc) { 275 if (retval)
289 mutex_unlock(&ctrl->ctrl_lock); 276 return retval;
290 return -1;
291 }
292
293 /* Wait for the command to complete */
294 wait_for_ctrl_irq (ctrl);
295 } 277 }
296 278
297 if (PWR_LED(ctrl->ctrlcap)) { 279 if (PWR_LED(ctrl->ctrlcap))
298 p_slot->hpc_ops->green_led_blink(p_slot); 280 p_slot->hpc_ops->green_led_blink(p_slot);
299
300 /* Wait for the command to complete */
301 wait_for_ctrl_irq (ctrl);
302 }
303
304 /* Done with exclusive hardware access */
305 mutex_unlock(&ctrl->ctrl_lock);
306 281
307 /* Wait for ~1 second */ 282 /* Wait for ~1 second */
308 wait_for_ctrl_irq (ctrl); 283 msleep(1000);
309 284
310 /* Check link training status */ 285 /* Check link training status */
311 rc = p_slot->hpc_ops->check_lnk_status(ctrl); 286 retval = p_slot->hpc_ops->check_lnk_status(ctrl);
312 if (rc) { 287 if (retval) {
313 err("%s: Failed to check link status\n", __FUNCTION__); 288 err("%s: Failed to check link status\n", __FUNCTION__);
314 set_slot_off(ctrl, p_slot); 289 set_slot_off(ctrl, p_slot);
315 return rc; 290 return retval;
316 } 291 }
317 292
318 /* Check for a power fault */ 293 /* Check for a power fault */
319 if (p_slot->hpc_ops->query_power_fault(p_slot)) { 294 if (p_slot->hpc_ops->query_power_fault(p_slot)) {
320 dbg("%s: power fault detected\n", __FUNCTION__); 295 dbg("%s: power fault detected\n", __FUNCTION__);
321 rc = POWER_FAILURE; 296 retval = POWER_FAILURE;
322 goto err_exit; 297 goto err_exit;
323 } 298 }
324 299
325 rc = pciehp_configure_device(p_slot); 300 retval = pciehp_configure_device(p_slot);
326 if (rc) { 301 if (retval) {
327 err("Cannot add device 0x%x:%x\n", p_slot->bus, 302 err("Cannot add device 0x%x:%x\n", p_slot->bus,
328 p_slot->device); 303 p_slot->device);
329 goto err_exit; 304 goto err_exit;
330 } 305 }
331 306
@@ -334,26 +309,16 @@ static int board_added(struct slot *p_slot)
334 */ 309 */
335 if (pcie_mch_quirk) 310 if (pcie_mch_quirk)
336 pci_fixup_device(pci_fixup_final, ctrl->pci_dev); 311 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
337 if (PWR_LED(ctrl->ctrlcap)) { 312 if (PWR_LED(ctrl->ctrlcap))
338 /* Wait for exclusive access to hardware */
339 mutex_lock(&ctrl->ctrl_lock);
340
341 p_slot->hpc_ops->green_led_on(p_slot); 313 p_slot->hpc_ops->green_led_on(p_slot);
342 314
343 /* Wait for the command to complete */
344 wait_for_ctrl_irq (ctrl);
345
346 /* Done with exclusive hardware access */
347 mutex_unlock(&ctrl->ctrl_lock);
348 }
349 return 0; 315 return 0;
350 316
351err_exit: 317err_exit:
352 set_slot_off(ctrl, p_slot); 318 set_slot_off(ctrl, p_slot);
353 return -1; 319 return retval;
354} 320}
355 321
356
357/** 322/**
358 * remove_board - Turns off slot and LED's 323 * remove_board - Turns off slot and LED's
359 * 324 *
@@ -362,44 +327,32 @@ static int remove_board(struct slot *p_slot)
362{ 327{
363 u8 device; 328 u8 device;
364 u8 hp_slot; 329 u8 hp_slot;
365 int rc; 330 int retval = 0;
366 struct controller *ctrl = p_slot->ctrl; 331 struct controller *ctrl = p_slot->ctrl;
367 332
368 if (pciehp_unconfigure_device(p_slot)) 333 retval = pciehp_unconfigure_device(p_slot);
369 return 1; 334 if (retval)
335 return retval;
370 336
371 device = p_slot->device; 337 device = p_slot->device;
372
373 hp_slot = p_slot->device - ctrl->slot_device_offset; 338 hp_slot = p_slot->device - ctrl->slot_device_offset;
374 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 339 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
375 340
376 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); 341 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
377 342
378 /* Wait for exclusive access to hardware */
379 mutex_lock(&ctrl->ctrl_lock);
380
381 if (POWER_CTRL(ctrl->ctrlcap)) { 343 if (POWER_CTRL(ctrl->ctrlcap)) {
382 /* power off slot */ 344 /* power off slot */
383 rc = p_slot->hpc_ops->power_off_slot(p_slot); 345 retval = p_slot->hpc_ops->power_off_slot(p_slot);
384 if (rc) { 346 if (retval) {
385 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); 347 err("%s: Issue of Slot Disable command failed\n",
386 mutex_unlock(&ctrl->ctrl_lock); 348 __FUNCTION__);
387 return rc; 349 return retval;
388 } 350 }
389 /* Wait for the command to complete */
390 wait_for_ctrl_irq (ctrl);
391 } 351 }
392 352
393 if (PWR_LED(ctrl->ctrlcap)) { 353 if (PWR_LED(ctrl->ctrlcap))
394 /* turn off Green LED */ 354 /* turn off Green LED */
395 p_slot->hpc_ops->green_led_off(p_slot); 355 p_slot->hpc_ops->green_led_off(p_slot);
396
397 /* Wait for the command to complete */
398 wait_for_ctrl_irq (ctrl);
399 }
400
401 /* Done with exclusive hardware access */
402 mutex_unlock(&ctrl->ctrl_lock);
403 356
404 return 0; 357 return 0;
405} 358}
@@ -444,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot)
444 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, 397 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
445 p_slot->bus, p_slot->device); 398 p_slot->bus, p_slot->device);
446 399
447 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 400 if (pciehp_enable_slot(p_slot) &&
448 /* Wait for exclusive access to hardware */ 401 PWR_LED(p_slot->ctrl->ctrlcap))
449 mutex_lock(&p_slot->ctrl->ctrl_lock);
450
451 p_slot->hpc_ops->green_led_off(p_slot); 402 p_slot->hpc_ops->green_led_off(p_slot);
452 403
453 /* Wait for the command to complete */
454 wait_for_ctrl_irq (p_slot->ctrl);
455
456 /* Done with exclusive hardware access */
457 mutex_unlock(&p_slot->ctrl->ctrl_lock);
458 }
459 p_slot->state = STATIC_STATE; 404 p_slot->state = STATIC_STATE;
460 } 405 }
461 406
@@ -494,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
494 dbg("%s: adding bus:device(%x:%x)\n", 439 dbg("%s: adding bus:device(%x:%x)\n",
495 __FUNCTION__, p_slot->bus, p_slot->device); 440 __FUNCTION__, p_slot->bus, p_slot->device);
496 441
497 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 442 if (pciehp_enable_slot(p_slot) &&
498 /* Wait for exclusive access to hardware */ 443 PWR_LED(p_slot->ctrl->ctrlcap))
499 mutex_lock(&p_slot->ctrl->ctrl_lock);
500
501 p_slot->hpc_ops->green_led_off(p_slot); 444 p_slot->hpc_ops->green_led_off(p_slot);
502 445
503 /* Wait for the command to complete */
504 wait_for_ctrl_irq (p_slot->ctrl);
505
506 /* Done with exclusive hardware access */
507 mutex_unlock(&p_slot->ctrl->ctrl_lock);
508 }
509 p_slot->state = STATIC_STATE; 446 p_slot->state = STATIC_STATE;
510 } 447 }
511 448
@@ -616,40 +553,18 @@ static void interrupt_event_handler(struct controller *ctrl)
616 553
617 switch (p_slot->state) { 554 switch (p_slot->state) {
618 case BLINKINGOFF_STATE: 555 case BLINKINGOFF_STATE:
619 /* Wait for exclusive access to hardware */ 556 if (PWR_LED(ctrl->ctrlcap))
620 mutex_lock(&ctrl->ctrl_lock);
621
622 if (PWR_LED(ctrl->ctrlcap)) {
623 p_slot->hpc_ops->green_led_on(p_slot); 557 p_slot->hpc_ops->green_led_on(p_slot);
624 /* Wait for the command to complete */
625 wait_for_ctrl_irq (ctrl);
626 }
627 if (ATTN_LED(ctrl->ctrlcap)) {
628 p_slot->hpc_ops->set_attention_status(p_slot, 0);
629 558
630 /* Wait for the command to complete */ 559 if (ATTN_LED(ctrl->ctrlcap))
631 wait_for_ctrl_irq (ctrl); 560 p_slot->hpc_ops->set_attention_status(p_slot, 0);
632 }
633 /* Done with exclusive hardware access */
634 mutex_unlock(&ctrl->ctrl_lock);
635 break; 561 break;
636 case BLINKINGON_STATE: 562 case BLINKINGON_STATE:
637 /* Wait for exclusive access to hardware */ 563 if (PWR_LED(ctrl->ctrlcap))
638 mutex_lock(&ctrl->ctrl_lock);
639
640 if (PWR_LED(ctrl->ctrlcap)) {
641 p_slot->hpc_ops->green_led_off(p_slot); 564 p_slot->hpc_ops->green_led_off(p_slot);
642 /* Wait for the command to complete */
643 wait_for_ctrl_irq (ctrl);
644 }
645 if (ATTN_LED(ctrl->ctrlcap)){
646 p_slot->hpc_ops->set_attention_status(p_slot, 0);
647 /* Wait for the command to complete */
648 wait_for_ctrl_irq (ctrl);
649 }
650 /* Done with exclusive hardware access */
651 mutex_unlock(&ctrl->ctrl_lock);
652 565
566 if (ATTN_LED(ctrl->ctrlcap))
567 p_slot->hpc_ops->set_attention_status(p_slot, 0);
653 break; 568 break;
654 default: 569 default:
655 warn("Not a valid state\n"); 570 warn("Not a valid state\n");
@@ -676,26 +591,13 @@ static void interrupt_event_handler(struct controller *ctrl)
676 info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); 591 info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot));
677 } 592 }
678 593
679 /* Wait for exclusive access to hardware */
680 mutex_lock(&ctrl->ctrl_lock);
681
682 /* blink green LED and turn off amber */ 594 /* blink green LED and turn off amber */
683 if (PWR_LED(ctrl->ctrlcap)) { 595 if (PWR_LED(ctrl->ctrlcap))
684 p_slot->hpc_ops->green_led_blink(p_slot); 596 p_slot->hpc_ops->green_led_blink(p_slot);
685 /* Wait for the command to complete */
686 wait_for_ctrl_irq (ctrl);
687 }
688 597
689 if (ATTN_LED(ctrl->ctrlcap)) { 598 if (ATTN_LED(ctrl->ctrlcap))
690 p_slot->hpc_ops->set_attention_status(p_slot, 0); 599 p_slot->hpc_ops->set_attention_status(p_slot, 0);
691 600
692 /* Wait for the command to complete */
693 wait_for_ctrl_irq (ctrl);
694 }
695
696 /* Done with exclusive hardware access */
697 mutex_unlock(&ctrl->ctrl_lock);
698
699 init_timer(&p_slot->task_event); 601 init_timer(&p_slot->task_event);
700 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ 602 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
701 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; 603 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
@@ -708,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl)
708 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { 610 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
709 if (POWER_CTRL(ctrl->ctrlcap)) { 611 if (POWER_CTRL(ctrl->ctrlcap)) {
710 dbg("power fault\n"); 612 dbg("power fault\n");
711 /* Wait for exclusive access to hardware */ 613 if (ATTN_LED(ctrl->ctrlcap))
712 mutex_lock(&ctrl->ctrl_lock);
713
714 if (ATTN_LED(ctrl->ctrlcap)) {
715 p_slot->hpc_ops->set_attention_status(p_slot, 1); 614 p_slot->hpc_ops->set_attention_status(p_slot, 1);
716 wait_for_ctrl_irq (ctrl);
717 }
718 615
719 if (PWR_LED(ctrl->ctrlcap)) { 616 if (PWR_LED(ctrl->ctrlcap))
720 p_slot->hpc_ops->green_led_off(p_slot); 617 p_slot->hpc_ops->green_led_off(p_slot);
721 wait_for_ctrl_irq (ctrl);
722 }
723
724 /* Done with exclusive hardware access */
725 mutex_unlock(&ctrl->ctrl_lock);
726 } 618 }
727 } 619 }
728 /***********SURPRISE REMOVAL********************/ 620 /***********SURPRISE REMOVAL********************/
@@ -750,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl)
750 } 642 }
751} 643}
752 644
753
754int pciehp_enable_slot(struct slot *p_slot) 645int pciehp_enable_slot(struct slot *p_slot)
755{ 646{
756 u8 getstatus = 0; 647 u8 getstatus = 0;
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
252static 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
252static int pcie_write_cmd(struct slot *slot, u16 cmd) 270static 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}