[PATCH] shpchp - cleanup check command status
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Thu, 26 Jan 2006 00:59:24 +0000 (09:59 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 23 Mar 2006 22:35:11 +0000 (14:35 -0800)
This patch cleanups codes that check the command status. For this, it
introduces a new semaphore "cmd_sem" for each controller.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/hotplug/shpchp_hpc.c

index f6d606dde6916c8d3f3478759208d23e80cc7765..b1e2a7705835891b9d5f19842441c1b4a82c925c 100644 (file)
@@ -80,6 +80,7 @@ struct event_info {
 struct controller {
        struct list_head ctrl_list;
        struct mutex crit_sect;         /* critical section mutex */
+       struct mutex cmd_lock;          /* command lock */
        struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
        int num_slots;                  /* Number of slots on ctlr */
        int slot_num_inc;               /* 1 or -1 */
index 3a8e733aead5b0f42e3df35bfbc49cf5490f82b0..802c4c48d1862dad639d4ec69793352ac95eb27c 100644 (file)
@@ -242,21 +242,10 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
        int rc = 0;
 
        dbg("%s: change to speed %d\n", __FUNCTION__, speed);
-       mutex_lock(&ctrl->crit_sect);
        if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
                err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-               mutex_unlock(&ctrl->crit_sect);
-               return WRONG_BUS_FREQUENCY;
-       }
-               
-       if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-               err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-                         __FUNCTION__);
-               err("%s: Error code (%d)\n", __FUNCTION__, rc);
-               mutex_unlock(&ctrl->crit_sect);
                return WRONG_BUS_FREQUENCY;
        }
-       mutex_unlock(&ctrl->crit_sect);
        return rc;
 }
 
@@ -330,15 +319,6 @@ static int board_added(struct slot *p_slot)
                return -1;
        }
        
-       rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-       if (rc) {
-               err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc);
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
-               return -1;
-       }
-
-       
        if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
                if (slots_not_empty)
                        return WRONG_BUS_FREQUENCY;
@@ -349,25 +329,12 @@ static int board_added(struct slot *p_slot)
                        return WRONG_BUS_FREQUENCY;
                }
                
-               if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-                       err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-                                 __FUNCTION__);
-                       err("%s: Error code (%d)\n", __FUNCTION__, rc);
-                       mutex_unlock(&ctrl->crit_sect);
-                       return WRONG_BUS_FREQUENCY;
-               }
                /* turn on board, blink green LED, turn off Amber LED */
                if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
                        err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
                        mutex_unlock(&ctrl->crit_sect);
                        return rc;
                }
-
-               if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-                       err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
-                       mutex_unlock(&ctrl->crit_sect);
-                       return rc;  
-               }
        }
  
        rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
@@ -481,22 +448,12 @@ static int board_added(struct slot *p_slot)
                                return rc;
        }
 
-       mutex_lock(&ctrl->crit_sect);
        /* turn on board, blink green LED, turn off Amber LED */
        if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
                err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
-               mutex_unlock(&ctrl->crit_sect);
                return rc;
        }
 
-       if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-               err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
-               mutex_unlock(&ctrl->crit_sect);
-               return rc;  
-       }
-
-       mutex_unlock(&ctrl->crit_sect);
-
        /* Wait for ~1 second */
        wait_for_ctrl_irq (ctrl);
 
@@ -520,40 +477,18 @@ static int board_added(struct slot *p_slot)
        p_slot->is_a_board = 0x01;
        p_slot->pwr_save = 1;
 
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
-
        p_slot->hpc_ops->green_led_on(p_slot);
 
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
-
        return 0;
 
 err_exit:
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
-
        /* turn off slot, turn on Amber LED, turn off Green LED */
        rc = p_slot->hpc_ops->slot_disable(p_slot);
        if (rc) {
                err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
                return rc;
        }
 
-       rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-       if (rc) {
-               err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
-               return rc;
-       }
-
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
-
        return(rc);
 }
 
@@ -580,37 +515,19 @@ static int remove_board(struct slot *p_slot)
        if (p_slot->is_a_board)
                p_slot->status = 0x01;
 
-       /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
-
        /* turn off slot, turn on Amber LED, turn off Green LED */
        rc = p_slot->hpc_ops->slot_disable(p_slot);
        if (rc) {
                err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
                return rc;
        }
-
-       rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-       if (rc) {
-               err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
-               return rc;  
-       }
        
        rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
        if (rc) {
                err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
                return rc;
        }
 
-       /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
-
        p_slot->pwr_save = 0;
        p_slot->is_a_board = 0;
 
@@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (unsigned long slot)
        } else {
                p_slot->state = POWERON_STATE;
 
-               if (shpchp_enable_slot(p_slot)) {
-                       /* Wait for exclusive access to hardware */
-                       mutex_lock(&p_slot->ctrl->crit_sect);
-
+               if (shpchp_enable_slot(p_slot))
                        p_slot->hpc_ops->green_led_off(p_slot);
 
-                       /* Done with exclusive hardware access */
-                       mutex_unlock(&p_slot->ctrl->crit_sect);
-               }
                p_slot->state = STATIC_STATE;
        }
 
@@ -767,27 +678,12 @@ static void interrupt_event_handler(struct controller *ctrl)
 
                                        switch (p_slot->state) {
                                        case BLINKINGOFF_STATE:
-                                               /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->crit_sect);
-
                                                p_slot->hpc_ops->green_led_on(p_slot);
-
                                                p_slot->hpc_ops->set_attention_status(p_slot, 0);
-
-                                               /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->crit_sect);
                                                break;
                                        case BLINKINGON_STATE:
-                                               /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->crit_sect);
-
                                                p_slot->hpc_ops->green_led_off(p_slot);
-
                                                p_slot->hpc_ops->set_attention_status(p_slot, 0);
-
-                                               /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->crit_sect);
-
                                                break;
                                        default:
                                                warn("Not a valid state\n");
@@ -812,17 +708,10 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                info(msg_button_on, p_slot->number);
                                        }
 
-                                       /* Wait for exclusive access to hardware */
-                                       mutex_lock(&ctrl->crit_sect);
-
                                        /* blink green LED and turn off amber */
                                        p_slot->hpc_ops->green_led_blink(p_slot);
-                                       
                                        p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-                                       /* Done with exclusive hardware access */
-                                       mutex_unlock(&ctrl->crit_sect);
-
                                        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;
@@ -833,15 +722,8 @@ static void interrupt_event_handler(struct controller *ctrl)
                                } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
                                        /***********POWER FAULT********************/
                                        dbg("%s: power fault\n", __FUNCTION__);
-                                       /* Wait for exclusive access to hardware */
-                                       mutex_lock(&ctrl->crit_sect);
-
                                        p_slot->hpc_ops->set_attention_status(p_slot, 1);
-                                       
                                        p_slot->hpc_ops->green_led_off(p_slot);
-
-                                       /* Done with exclusive hardware access */
-                                       mutex_unlock(&ctrl->crit_sect);
                                } else {
                                        /* refresh notification */
                                        if (p_slot)
index ae81427e42b1adaca7765c3ad654fb99d384a186..c32a1b16704fc4fdbf59caf1dc29977f3e434554 100644 (file)
@@ -231,6 +231,7 @@ static spinlock_t list_lock;
 static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
 
 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
+static int hpc_check_cmd_status(struct controller *ctrl);
 
 /* This is the interrupt polling timeout function. */
 static void int_poll_timeout(unsigned long lphp_ctlr)
@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
        int i;
 
        DBG_ENTER_ROUTINE 
-       
+
+       mutex_lock(&slot->ctrl->cmd_lock);
+
        if (!php_ctlr) {
                err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-               return -1;
+               retval = -EINVAL;
+               goto out;
        }
 
        for (i = 0; i < 10; i++) {
@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
        if (cmd_status & 0x1) { 
                /* After 1 sec and and the controller is still busy */
                err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
-               return -1;
+               retval = -EBUSY;
+               goto out;
        }
 
        ++t_slot;
@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
         * Wait for command completion.
         */
        retval = shpc_wait_cmd(slot->ctrl);
+       if (retval)
+               goto out;
+
+       cmd_status = hpc_check_cmd_status(slot->ctrl);
+       if (cmd_status) {
+               err("%s: Failed to issued command 0x%x (error code = %d)\n",
+                   __FUNCTION__, cmd, cmd_status);
+               retval = -EIO;
+       }
+ out:
+       mutex_unlock(&slot->ctrl->cmd_lock);
 
        DBG_LEAVE_ROUTINE 
        return retval;
@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
        .green_led_blink                = hpc_set_green_led_blink,
        
        .release_ctlr                   = hpc_release_ctlr,
-       .check_cmd_status               = hpc_check_cmd_status,
 };
 
 inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
 
        mutex_init(&ctrl->crit_sect);
+       mutex_init(&ctrl->cmd_lock);
+
        /* Setup wait queue */
        init_waitqueue_head(&ctrl->queue);