linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / pci / hotplug / cpqphp_ctrl.c
index ae2dd36..771ed34 100644 (file)
@@ -26,6 +26,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -1281,7 +1282,9 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
        u8 hp_slot;
        u8 temp_byte;
        u8 adapter_speed;
+       u32 index;
        u32 rc = 0;
+       u32 src = 8;
 
        hp_slot = func->device - ctrl->slot_device_offset;
 
@@ -1296,7 +1299,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                 **********************************/
                rc = CARD_FUNCTIONING;
        } else {
-               mutex_lock(&ctrl->crit_sect);
+               down(&ctrl->crit_sect);
 
                /* turn on board without attaching to the bus */
                enable_slot_power (ctrl, hp_slot);
@@ -1330,12 +1333,12 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               mutex_unlock(&ctrl->crit_sect);
+               up(&ctrl->crit_sect);
 
                if (rc)
                        return rc;
 
-               mutex_lock(&ctrl->crit_sect);
+               down(&ctrl->crit_sect);
 
                slot_enable (ctrl, hp_slot);
                green_LED_blink (ctrl, hp_slot);
@@ -1347,7 +1350,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               mutex_unlock(&ctrl->crit_sect);
+               up(&ctrl->crit_sect);
 
                /* Wait for ~1 second because of hot plug spec */
                long_delay(1*HZ);
@@ -1365,30 +1368,76 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
                        rc = cpqhp_configure_board(ctrl, func);
 
-                       /* If configuration fails, turn it off
-                        * Get slot won't work for devices behind
-                        * bridges, but in this case it will always be
-                        * called for the "base" bus/dev/func of an
-                        * adapter. */
+                       if (rc || src) {
+                               /* If configuration fails, turn it off
+                                * Get slot won't work for devices behind
+                                * bridges, but in this case it will always be
+                                * called for the "base" bus/dev/func of an
+                                * adapter. */
 
-                       mutex_lock(&ctrl->crit_sect);
+                               down(&ctrl->crit_sect);
 
-                       amber_LED_on (ctrl, hp_slot);
-                       green_LED_off (ctrl, hp_slot);
-                       slot_disable (ctrl, hp_slot);
+                               amber_LED_on (ctrl, hp_slot);
+                               green_LED_off (ctrl, hp_slot);
+                               slot_disable (ctrl, hp_slot);
 
-                       set_SOGO(ctrl);
+                               set_SOGO(ctrl);
 
-                       /* Wait for SOBS to be unset */
-                       wait_for_ctrl_irq (ctrl);
+                               /* Wait for SOBS to be unset */
+                               wait_for_ctrl_irq (ctrl);
 
-                       mutex_unlock(&ctrl->crit_sect);
+                               up(&ctrl->crit_sect);
+
+                               if (rc)
+                                       return rc;
+                               else
+                                       return 1;
+                       }
+
+                       func->status = 0;
+                       func->switch_save = 0x10;
+
+                       index = 1;
+                       while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
+                               rc |= cpqhp_configure_board(ctrl, func);
+                               index++;
+                       }
+
+                       if (rc) {
+                               /* If configuration fails, turn it off
+                                * Get slot won't work for devices behind
+                                * bridges, but in this case it will always be
+                                * called for the "base" bus/dev/func of an
+                                * adapter. */
+
+                               down(&ctrl->crit_sect);
+
+                               amber_LED_on (ctrl, hp_slot);
+                               green_LED_off (ctrl, hp_slot);
+                               slot_disable (ctrl, hp_slot);
+
+                               set_SOGO(ctrl);
+
+                               /* Wait for SOBS to be unset */
+                               wait_for_ctrl_irq (ctrl);
+
+                               up(&ctrl->crit_sect);
 
-                       if (rc)
                                return rc;
-                       else
-                               return 1;
+                       }
+                       /* Done configuring so turn LED on full time */
+
+                       down(&ctrl->crit_sect);
+
+                       green_LED_on (ctrl, hp_slot);
+
+                       set_SOGO(ctrl);
+
+                       /* Wait for SOBS to be unset */
+                       wait_for_ctrl_irq (ctrl);
 
+                       up(&ctrl->crit_sect);
+                       rc = 0;
                } else {
                        /* Something is wrong
 
@@ -1396,7 +1445,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                         * in this case it will always be called for the "base"
                         * bus/dev/func of an adapter. */
 
-                       mutex_lock(&ctrl->crit_sect);
+                       down(&ctrl->crit_sect);
 
                        amber_LED_on (ctrl, hp_slot);
                        green_LED_off (ctrl, hp_slot);
@@ -1407,7 +1456,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                        /* Wait for SOBS to be unset */
                        wait_for_ctrl_irq (ctrl);
 
-                       mutex_unlock(&ctrl->crit_sect);
+                       up(&ctrl->crit_sect);
                }
 
        }
@@ -1439,7 +1488,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
            __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
 
-       mutex_lock(&ctrl->crit_sect);
+       down(&ctrl->crit_sect);
 
        /* turn on board without attaching to the bus */
        enable_slot_power(ctrl, hp_slot);
@@ -1473,7 +1522,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        /* Wait for SOBS to be unset */
        wait_for_ctrl_irq(ctrl);
 
-       mutex_unlock(&ctrl->crit_sect);
+       up(&ctrl->crit_sect);
 
        if (rc)
                return rc;
@@ -1483,7 +1532,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        /* turn on board and blink green LED */
 
        dbg("%s: before down\n", __FUNCTION__);
-       mutex_lock(&ctrl->crit_sect);
+       down(&ctrl->crit_sect);
        dbg("%s: after down\n", __FUNCTION__);
 
        dbg("%s: before slot_enable\n", __FUNCTION__);
@@ -1504,7 +1553,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
 
        dbg("%s: before up\n", __FUNCTION__);
-       mutex_unlock(&ctrl->crit_sect);
+       up(&ctrl->crit_sect);
        dbg("%s: after up\n", __FUNCTION__);
 
        /* Wait for ~1 second because of hot plug spec */
@@ -1558,7 +1607,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
 
                if (rc) {
-                       mutex_lock(&ctrl->crit_sect);
+                       down(&ctrl->crit_sect);
 
                        amber_LED_on (ctrl, hp_slot);
                        green_LED_off (ctrl, hp_slot);
@@ -1569,7 +1618,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                        /* Wait for SOBS to be unset */
                        wait_for_ctrl_irq (ctrl);
 
-                       mutex_unlock(&ctrl->crit_sect);
+                       up(&ctrl->crit_sect);
                        return rc;
                } else {
                        cpqhp_save_slot_config(ctrl, func);
@@ -1591,7 +1640,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                        }
                } while (new_slot);
 
-               mutex_lock(&ctrl->crit_sect);
+               down(&ctrl->crit_sect);
 
                green_LED_on (ctrl, hp_slot);
 
@@ -1600,9 +1649,9 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               mutex_unlock(&ctrl->crit_sect);
+               up(&ctrl->crit_sect);
        } else {
-               mutex_lock(&ctrl->crit_sect);
+               down(&ctrl->crit_sect);
 
                amber_LED_on (ctrl, hp_slot);
                green_LED_off (ctrl, hp_slot);
@@ -1613,7 +1662,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               mutex_unlock(&ctrl->crit_sect);
+               up(&ctrl->crit_sect);
 
                return rc;
        }
@@ -1672,7 +1721,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
                func->status = 0x01;
        func->configured = 0;
 
-       mutex_lock(&ctrl->crit_sect);
+       down(&ctrl->crit_sect);
 
        green_LED_off (ctrl, hp_slot);
        slot_disable (ctrl, hp_slot);
@@ -1687,7 +1736,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
        /* Wait for SOBS to be unset */
        wait_for_ctrl_irq (ctrl);
 
-       mutex_unlock(&ctrl->crit_sect);
+       up(&ctrl->crit_sect);
 
        if (!replace_flag && ctrl->add_support) {
                while (func) {
@@ -1850,7 +1899,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        dbg("button cancel\n");
                                        del_timer(&p_slot->task_event);
 
-                                       mutex_lock(&ctrl->crit_sect);
+                                       down(&ctrl->crit_sect);
 
                                        if (p_slot->state == BLINKINGOFF_STATE) {
                                                /* slot is on */
@@ -1873,7 +1922,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        /* Wait for SOBS to be unset */
                                        wait_for_ctrl_irq (ctrl);
 
-                                       mutex_unlock(&ctrl->crit_sect);
+                                       up(&ctrl->crit_sect);
                                }
                                /*** button Released (No action on press...) */
                                else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
@@ -1888,7 +1937,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                p_slot->state = BLINKINGON_STATE;
                                                info(msg_button_on, p_slot->number);
                                        }
-                                       mutex_lock(&ctrl->crit_sect);
+                                       down(&ctrl->crit_sect);
                                        
                                        dbg("blink green LED and turn off amber\n");
                                        
@@ -1900,7 +1949,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        /* Wait for SOBS to be unset */
                                        wait_for_ctrl_irq (ctrl);
 
-                                       mutex_unlock(&ctrl->crit_sect);
+                                       up(&ctrl->crit_sect);
                                        init_timer(&p_slot->task_event);
                                        p_slot->hp_slot = hp_slot;
                                        p_slot->ctrl = ctrl;