Re: IDE DVD and CD drive seem to not work with Linux desktop3.3.0-030300-generic

From: Matthew Garrett
Date: Fri Mar 23 2012 - 13:20:52 EST


Ok, this is very odd - ASPM is disabled in both cases. The only thing I
can think of here is that the hardware dislikes us writing to the
registers? Can you test this patch on top of the broken kernel?

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 24f049e..04eb680 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -185,6 +185,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
int ppos, cpos, same_clock = 1;
u16 reg16, parent_reg, child_reg[8];
unsigned long start_jiffies;
+ bool retrain = false;
struct pci_dev *child, *parent = link->pdev;
struct pci_bus *linkbus = parent->subordinate;
/*
@@ -215,7 +216,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
- pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
+ if (reg16 != child_reg[PCI_FUNC(child->devfn)]) {
+ retrain = true;
+ pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
+ }
}

/* Configure upstream component */
@@ -225,9 +229,15 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
- pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
+ if (reg16 != parent_reg) {
+ retrain = true;
+ pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
+ }

/* Retrain link */
+ if (!retrain)
+ return;
+
reg16 |= PCI_EXP_LNKCTL_RL;
pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);

@@ -436,13 +446,16 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)

static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
{
- u16 reg16;
+ u16 reg16, orig_reg16;
int pos = pci_pcie_cap(pdev);

pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+ orig_reg16 = reg16;
reg16 &= ~0x3;
reg16 |= val;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+
+ if (reg16 != orig_reg16)
+ pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
}

static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)

--
Matthew Garrett | mjg59@xxxxxxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/