[S390] dasd: correct offline processing
[safe/jmp/linux-2.6] / drivers / pci / hotplug / pciehp_hpc.c
index 7f35aff..40b48f5 100644 (file)
@@ -45,25 +45,25 @@ static atomic_t pciehp_num_controllers = ATOMIC_INIT(0);
 static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
 {
        struct pci_dev *dev = ctrl->pcie->port;
-       return pci_read_config_word(dev, ctrl->cap_base + reg, value);
+       return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
 {
        struct pci_dev *dev = ctrl->pcie->port;
-       return pci_read_config_dword(dev, ctrl->cap_base + reg, value);
+       return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
 {
        struct pci_dev *dev = ctrl->pcie->port;
-       return pci_write_config_word(dev, ctrl->cap_base + reg, value);
+       return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
 {
        struct pci_dev *dev = ctrl->pcie->port;
-       return pci_write_config_dword(dev, ctrl->cap_base + reg, value);
+       return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value);
 }
 
 /* Power Control Command */
@@ -318,8 +318,8 @@ int pciehp_get_attention_status(struct slot *slot, u8 *status)
                return retval;
        }
 
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
 
        atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6;
 
@@ -356,8 +356,8 @@ int pciehp_get_power_status(struct slot *slot, u8 *status)
                ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
                return retval;
        }
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
 
        pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10;
 
@@ -442,8 +442,8 @@ int pciehp_set_attention_status(struct slot *slot, u8 value)
        default:
                return -EINVAL;
        }
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
        return pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
 }
 
@@ -456,8 +456,8 @@ void pciehp_green_led_on(struct slot *slot)
        slot_cmd = 0x0100;
        cmd_mask = PCI_EXP_SLTCTL_PIC;
        pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 void pciehp_green_led_off(struct slot *slot)
@@ -469,8 +469,8 @@ void pciehp_green_led_off(struct slot *slot)
        slot_cmd = 0x0300;
        cmd_mask = PCI_EXP_SLTCTL_PIC;
        pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 void pciehp_green_led_blink(struct slot *slot)
@@ -482,8 +482,8 @@ void pciehp_green_led_blink(struct slot *slot)
        slot_cmd = 0x0200;
        cmd_mask = PCI_EXP_SLTCTL_PIC;
        pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
 int pciehp_power_on_slot(struct slot * slot)
@@ -492,6 +492,7 @@ int pciehp_power_on_slot(struct slot * slot)
        u16 slot_cmd;
        u16 cmd_mask;
        u16 slot_status;
+       u16 lnk_status;
        int retval = 0;
 
        /* Clear sticky power-fault bit from previous power failures */
@@ -511,24 +512,26 @@ int pciehp_power_on_slot(struct slot * slot)
                        return retval;
                }
        }
+       ctrl->power_fault_detected = 0;
 
        slot_cmd = POWER_ON;
        cmd_mask = PCI_EXP_SLTCTL_PCC;
-       if (!pciehp_poll_mode) {
-               /* Enable power fault detection turned off at power off time */
-               slot_cmd |= PCI_EXP_SLTCTL_PFDE;
-               cmd_mask |= PCI_EXP_SLTCTL_PFDE;
-       }
-
        retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
        if (retval) {
                ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
                return retval;
        }
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
+
+       retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
+       if (retval) {
+               ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n",
+                               __func__);
+               return retval;
+       }
+       pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
 
-       ctrl->power_fault_detected = 0;
        return retval;
 }
 
@@ -541,19 +544,13 @@ int pciehp_power_off_slot(struct slot * slot)
 
        slot_cmd = POWER_OFF;
        cmd_mask = PCI_EXP_SLTCTL_PCC;
-       if (!pciehp_poll_mode) {
-               /* Disable power fault detection */
-               slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
-               cmd_mask |= PCI_EXP_SLTCTL_PFDE;
-       }
-
        retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
        if (retval) {
                ctrl_err(ctrl, "Write command failed!\n");
                return retval;
        }
-       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
-                __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+       ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
        return 0;
 }
 
@@ -622,37 +619,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value)
-{
-       struct controller *ctrl = slot->ctrl;
-       enum pcie_link_speed lnk_speed;
-       u32     lnk_cap;
-       int retval = 0;
-
-       retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap);
-       if (retval) {
-               ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
-               return retval;
-       }
-
-       switch (lnk_cap & 0x000F) {
-       case 1:
-               lnk_speed = PCIE_2_5GB;
-               break;
-       case 2:
-               lnk_speed = PCIE_5_0GB;
-               break;
-       default:
-               lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
-               break;
-       }
-
-       *value = lnk_speed;
-       ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed);
-
-       return retval;
-}
-
 int pciehp_get_max_lnk_width(struct slot *slot,
                                 enum pcie_link_width *value)
 {
@@ -703,38 +669,6 @@ int pciehp_get_max_lnk_width(struct slot *slot,
        return retval;
 }
 
-int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value)
-{
-       struct controller *ctrl = slot->ctrl;
-       enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
-       int retval = 0;
-       u16 lnk_status;
-
-       retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
-       if (retval) {
-               ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
-                        __func__);
-               return retval;
-       }
-
-       switch (lnk_status & PCI_EXP_LNKSTA_CLS) {
-       case 1:
-               lnk_speed = PCIE_2_5GB;
-               break;
-       case 2:
-               lnk_speed = PCIE_5_0GB;
-               break;
-       default:
-               lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
-               break;
-       }
-
-       *value = lnk_speed;
-       ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed);
-
-       return retval;
-}
-
 int pciehp_get_cur_lnk_width(struct slot *slot,
                                 enum pcie_link_width *value)
 {
@@ -790,11 +724,19 @@ int pcie_enable_notification(struct controller *ctrl)
 {
        u16 cmd, mask;
 
+       /*
+        * TBD: Power fault detected software notification support.
+        *
+        * Power fault detected software notification is not enabled
+        * now, because it caused power fault detected interrupt storm
+        * on some machines. On those machines, power fault detected
+        * bit in the slot status register was set again immediately
+        * when it is cleared in the interrupt service routine, and
+        * next power fault detected interrupt was notified again.
+        */
        cmd = PCI_EXP_SLTCTL_PDCE;
        if (ATTN_BUTTN(ctrl))
                cmd |= PCI_EXP_SLTCTL_ABPE;
-       if (POWER_CTRL(ctrl))
-               cmd |= PCI_EXP_SLTCTL_PFDE;
        if (MRL_SENS(ctrl))
                cmd |= PCI_EXP_SLTCTL_MRLSCE;
        if (!pciehp_poll_mode)
@@ -885,7 +827,8 @@ static inline void dbg_ctrl(struct controller *ctrl)
                  pdev->subsystem_device);
        ctrl_info(ctrl, "  Subsystem Vendor ID  : 0x%04x\n",
                  pdev->subsystem_vendor);
-       ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n", ctrl->cap_base);
+       ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n",
+                 pci_pcie_cap(pdev));
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                if (!pci_resource_len(pdev, i))
                        continue;
@@ -929,8 +872,7 @@ struct controller *pcie_init(struct pcie_device *dev)
                goto abort;
        }
        ctrl->pcie = dev;
-       ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-       if (!ctrl->cap_base) {
+       if (!pci_pcie_cap(pdev)) {
                ctrl_err(ctrl, "Cannot find PCI Express capability\n");
                goto abort_ctrl;
        }