pciehp: cleanup wait command completion
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Fri, 22 Dec 2006 01:01:09 +0000 (17:01 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Feb 2007 23:50:05 +0000 (15:50 -0800)
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>
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c

index e4524cf0242742f68e70db5d30305f507483d9d9..17167d594472878312cde638cdf32ba1f5e52518 100644 (file)
@@ -173,24 +173,6 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
        return NULL;
 }
 
-static inline int wait_for_ctrl_irq(struct controller *ctrl)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       add_wait_queue(&ctrl->queue, &wait);
-       if (!pciehp_poll_mode)
-               /* Sleep for up to 1 second */
-               msleep_interruptible(1000);
-       else
-               msleep_interruptible(2500);
-       
-       remove_wait_queue(&ctrl->queue, &wait);
-       if (signal_pending(current))
-               return -EINTR;
-
-       return 0;
-}
-
 struct hpc_ops {
        int (*power_on_slot)(struct slot *slot);
        int (*power_off_slot)(struct slot *slot);
index e2d45662bdbf89e0daaf0bbfc9b7571792d4b865..f7b8e0504fec81c988b05a1c3995b7228d7cd15c 100644 (file)
@@ -374,25 +374,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
                pciehp_ctrl_list = ctrl;
        }
 
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->ctrl_lock);
-
        t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
-       
        if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
                rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
-               if (rc) {
-                       /* Done with exclusive hardware access */
-                       mutex_unlock(&ctrl->ctrl_lock);
+               if (rc)
                        goto err_out_free_ctrl_slot;
-               } else
-                       /* Wait for the command to complete */
-                       wait_for_ctrl_irq (ctrl);
        }
 
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->ctrl_lock);
-
        return 0;
 
 err_out_free_ctrl_slot:
index 072befa345a7519138df15ec4d9b72eb1a62ce96..4283ef56dbd977509ba6ab8567d91f1b7bbdc712 100644 (file)
@@ -229,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
 
 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 {
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->ctrl_lock);
-
        /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
        if (POWER_CTRL(ctrl->ctrlcap)) {
                if (pslot->hpc_ops->power_off_slot(pslot)) {   
-                       err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
-                       mutex_unlock(&ctrl->ctrl_lock);
+                       err("%s: Issue of Slot Power Off command failed\n",
+                           __FUNCTION__);
                        return;
                }
-               wait_for_ctrl_irq (ctrl);
        }
 
-       if (PWR_LED(ctrl->ctrlcap)) {
+       if (PWR_LED(ctrl->ctrlcap))
                pslot->hpc_ops->green_led_off(pslot);   
-               wait_for_ctrl_irq (ctrl);
-       }
 
-       if (ATTN_LED(ctrl->ctrlcap)) { 
-               if (pslot->hpc_ops->set_attention_status(pslot, 1)) {   
-                       err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
-                       mutex_unlock(&ctrl->ctrl_lock);
+       if (ATTN_LED(ctrl->ctrlcap)) {
+               if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
+                       err("%s: Issue of Set Attention Led command failed\n",
+                           __FUNCTION__);
                        return;
                }
-               wait_for_ctrl_irq (ctrl);
        }
-
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->ctrl_lock);
 }
 
 /**
@@ -270,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 static int board_added(struct slot *p_slot)
 {
        u8 hp_slot;
-       int rc = 0;
+       int retval = 0;
        struct controller *ctrl = p_slot->ctrl;
 
        hp_slot = p_slot->device - ctrl->slot_device_offset;
@@ -279,53 +269,38 @@ static int board_added(struct slot *p_slot)
                        __FUNCTION__, p_slot->device,
                        ctrl->slot_device_offset, hp_slot);
 
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->ctrl_lock);
-
        if (POWER_CTRL(ctrl->ctrlcap)) {
                /* Power on slot */
-               rc = p_slot->hpc_ops->power_on_slot(p_slot);
-               if (rc) {
-                       mutex_unlock(&ctrl->ctrl_lock);
-                       return -1;
-               }
-
-               /* Wait for the command to complete */
-               wait_for_ctrl_irq (ctrl);
+               retval = p_slot->hpc_ops->power_on_slot(p_slot);
+               if (retval)
+                       return retval;
        }
        
-       if (PWR_LED(ctrl->ctrlcap)) {
+       if (PWR_LED(ctrl->ctrlcap))
                p_slot->hpc_ops->green_led_blink(p_slot);
-                       
-               /* Wait for the command to complete */
-               wait_for_ctrl_irq (ctrl);
-       }
-
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->ctrl_lock);
 
        /* Wait for ~1 second */
-       wait_for_ctrl_irq (ctrl);
+       msleep(1000);
 
-       /*  Check link training status */
-       rc = p_slot->hpc_ops->check_lnk_status(ctrl);  
-       if (rc) {
+       /* Check link training status */
+       retval = p_slot->hpc_ops->check_lnk_status(ctrl);
+       if (retval) {
                err("%s: Failed to check link status\n", __FUNCTION__);
                set_slot_off(ctrl, p_slot);
-               return rc;
+               return retval;
        }
 
        /* Check for a power fault */
        if (p_slot->hpc_ops->query_power_fault(p_slot)) {
                dbg("%s: power fault detected\n", __FUNCTION__);
-               rc = POWER_FAILURE;
+               retval = POWER_FAILURE;
                goto err_exit;
        }
 
-       rc = pciehp_configure_device(p_slot);
-       if (rc) {
+       retval = pciehp_configure_device(p_slot);
+       if (retval) {
                err("Cannot add device 0x%x:%x\n", p_slot->bus,
-                               p_slot->device);
+                   p_slot->device);
                goto err_exit;
        }
 
@@ -334,26 +309,16 @@ static int board_added(struct slot *p_slot)
         */
        if (pcie_mch_quirk)
                pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
-       if (PWR_LED(ctrl->ctrlcap)) {
-               /* Wait for exclusive access to hardware */
-               mutex_lock(&ctrl->ctrl_lock);
-
+       if (PWR_LED(ctrl->ctrlcap))
                p_slot->hpc_ops->green_led_on(p_slot);
-  
-               /* Wait for the command to complete */
-               wait_for_ctrl_irq (ctrl);
-       
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->ctrl_lock);
-       }
+
        return 0;
 
 err_exit:
        set_slot_off(ctrl, p_slot);
-       return -1;
+       return retval;
 }
 
-
 /**
  * remove_board - Turns off slot and LED's
  *
@@ -362,44 +327,32 @@ static int remove_board(struct slot *p_slot)
 {
        u8 device;
        u8 hp_slot;
-       int rc;
+       int retval = 0;
        struct controller *ctrl = p_slot->ctrl;
 
-       if (pciehp_unconfigure_device(p_slot))
-               return 1;
+       retval = pciehp_unconfigure_device(p_slot);
+       if (retval)
+               return retval;
 
        device = p_slot->device;
-
        hp_slot = p_slot->device - ctrl->slot_device_offset;
        p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
        dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
 
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->ctrl_lock);
-
        if (POWER_CTRL(ctrl->ctrlcap)) {
                /* power off slot */
-               rc = p_slot->hpc_ops->power_off_slot(p_slot);
-               if (rc) {
-                       err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-                       mutex_unlock(&ctrl->ctrl_lock);
-                       return rc;
+               retval = p_slot->hpc_ops->power_off_slot(p_slot);
+               if (retval) {
+                       err("%s: Issue of Slot Disable command failed\n",
+                           __FUNCTION__);
+                       return retval;
                }
-               /* Wait for the command to complete */
-               wait_for_ctrl_irq (ctrl);
        }
 
-       if (PWR_LED(ctrl->ctrlcap)) {
+       if (PWR_LED(ctrl->ctrlcap))
                /* turn off Green LED */
                p_slot->hpc_ops->green_led_off(p_slot);
-       
-               /* Wait for the command to complete */
-               wait_for_ctrl_irq (ctrl);
-       }
-
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->ctrl_lock);
 
        return 0;
 }
@@ -444,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot)
                dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
                                p_slot->bus, p_slot->device);
 
-               if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
-                       /* Wait for exclusive access to hardware */
-                       mutex_lock(&p_slot->ctrl->ctrl_lock);
-
+               if (pciehp_enable_slot(p_slot) &&
+                   PWR_LED(p_slot->ctrl->ctrlcap))
                        p_slot->hpc_ops->green_led_off(p_slot);
 
-                       /* Wait for the command to complete */
-                       wait_for_ctrl_irq (p_slot->ctrl);
-
-                       /* Done with exclusive hardware access */
-                       mutex_unlock(&p_slot->ctrl->ctrl_lock);
-               }
                p_slot->state = STATIC_STATE;
        }
 
@@ -494,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
                dbg("%s: adding bus:device(%x:%x)\n",
                                __FUNCTION__, p_slot->bus, p_slot->device);
 
-               if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
-                       /* Wait for exclusive access to hardware */
-                       mutex_lock(&p_slot->ctrl->ctrl_lock);
-
+               if (pciehp_enable_slot(p_slot) &&
+                   PWR_LED(p_slot->ctrl->ctrlcap))
                        p_slot->hpc_ops->green_led_off(p_slot);
 
-                       /* Wait for the command to complete */
-                       wait_for_ctrl_irq (p_slot->ctrl);
-
-                       /* Done with exclusive hardware access */
-                       mutex_unlock(&p_slot->ctrl->ctrl_lock);
-               }
                p_slot->state = STATIC_STATE;
        }
 
@@ -616,40 +553,18 @@ static void interrupt_event_handler(struct controller *ctrl)
 
                                        switch (p_slot->state) {
                                        case BLINKINGOFF_STATE:
-                                               /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->ctrl_lock);
-                                               
-                                               if (PWR_LED(ctrl->ctrlcap)) {
+                                               if (PWR_LED(ctrl->ctrlcap))
                                                        p_slot->hpc_ops->green_led_on(p_slot);
-                                                       /* Wait for the command to complete */
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
-                                               if (ATTN_LED(ctrl->ctrlcap)) {
-                                                       p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-                                                       /* Wait for the command to complete */
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
-                                               /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->ctrl_lock);
+                                               if (ATTN_LED(ctrl->ctrlcap))
+                                                       p_slot->hpc_ops->set_attention_status(p_slot, 0);
                                                break;
                                        case BLINKINGON_STATE:
-                                               /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->ctrl_lock);
-
-                                               if (PWR_LED(ctrl->ctrlcap)) {
+                                               if (PWR_LED(ctrl->ctrlcap))
                                                        p_slot->hpc_ops->green_led_off(p_slot);
-                                                       /* Wait for the command to complete */
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
-                                               if (ATTN_LED(ctrl->ctrlcap)){
-                                                       p_slot->hpc_ops->set_attention_status(p_slot, 0);
-                                                       /* Wait for the command to complete */
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
-                                               /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->ctrl_lock);
 
+                                               if (ATTN_LED(ctrl->ctrlcap))
+                                                       p_slot->hpc_ops->set_attention_status(p_slot, 0);
                                                break;
                                        default:
                                                warn("Not a valid state\n");
@@ -676,26 +591,13 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                        info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot));
                                                }
 
-                                               /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->ctrl_lock);
-
                                                /* blink green LED and turn off amber */
-                                               if (PWR_LED(ctrl->ctrlcap)) {
+                                               if (PWR_LED(ctrl->ctrlcap))
                                                        p_slot->hpc_ops->green_led_blink(p_slot);
-                                                       /* Wait for the command to complete */
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
 
-                                               if (ATTN_LED(ctrl->ctrlcap)) {
+                                               if (ATTN_LED(ctrl->ctrlcap))
                                                        p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-                                                       /* Wait for the command to complete */
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
-
-                                               /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->ctrl_lock);
-
                                                init_timer(&p_slot->task_event);
                                                p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
                                                p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
@@ -708,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl)
                                else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
                                        if (POWER_CTRL(ctrl->ctrlcap)) {
                                                dbg("power fault\n");
-                                               /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->ctrl_lock);
-
-                                               if (ATTN_LED(ctrl->ctrlcap)) {
+                                               if (ATTN_LED(ctrl->ctrlcap))
                                                        p_slot->hpc_ops->set_attention_status(p_slot, 1);
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
 
-                                               if (PWR_LED(ctrl->ctrlcap)) {
+                                               if (PWR_LED(ctrl->ctrlcap))
                                                        p_slot->hpc_ops->green_led_off(p_slot);
-                                                       wait_for_ctrl_irq (ctrl);
-                                               }
-
-                                               /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->ctrl_lock);
                                        }
                                }
                                /***********SURPRISE REMOVAL********************/
@@ -750,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl)
        }
 }
 
-
 int pciehp_enable_slot(struct slot *p_slot)
 {
        u8 getstatus = 0;
index d8f4f1241b56a9880798723821581755f721391e..9fbd9b9f98248948c81ffd0a6835074fb1f9c87c 100644 (file)
@@ -249,6 +249,24 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
        add_timer(&ctrl->poll_timer);
 }
 
+static inline int pcie_wait_cmd(struct controller *ctrl)
+{
+       DECLARE_WAITQUEUE(wait, current);
+
+       add_wait_queue(&ctrl->queue, &wait);
+       if (!pciehp_poll_mode)
+               /* Sleep for up to 1 second */
+               msleep_interruptible(1000);
+       else
+               msleep_interruptible(2500);
+
+       remove_wait_queue(&ctrl->queue, &wait);
+       if (signal_pending(current))
+               return -EINTR;
+
+       return 0;
+}
+
 static int pcie_write_cmd(struct slot *slot, u16 cmd)
 {
        struct controller *ctrl = slot->ctrl;
@@ -257,24 +275,34 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
 
        DBG_ENTER_ROUTINE 
 
+       mutex_lock(&ctrl->ctrl_lock);
+
        retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
        if (retval) {
                err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
-               return retval;
+               goto out;
        }
 
        if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { 
-               /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue 
-                  the next command according to spec.  Just print out the error message */
-               dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
+               /* After 1 sec and CMD_COMPLETED still not set, just
+                  proceed forward to issue the next command according
+                  to spec.  Just print out the error message */
+               dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
+                   __FUNCTION__);
        }
 
        retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
        if (retval) {
                err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
-               return retval;
+               goto out;
        }
 
+       /*
+        * Wait for command completion.
+        */
+       retval = pcie_wait_cmd(ctrl);
+ out:
+       mutex_unlock(&ctrl->ctrl_lock);
        DBG_LEAVE_ROUTINE 
        return retval;
 }