Date: Mon, 19 Sep 2011 00:17:37 +0200 From: Stefan Richter Subject: firewire: ohci: TSB41BA3D support tweaks Fix: phy_reg_mutex must be held over the write/read_phy_reg pair which gets PHY port status. Only print to the log when a TSB41BA3D was found. By far most TSB82AA2 cards have a TSB81BA3, and firewire-ohci can keep quiet about that. Shorten some strings and comments. Change some whitespace. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 74 ++++++++++++---------------------------- 1 file changed, 23 insertions(+), 51 deletions(-) Index: b/drivers/firewire/ohci.c =================================================================== --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -325,7 +325,7 @@ MODULE_PARM_DESC(quirks, "Chip quirks (d ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) ", disable MSI = " __stringify(QUIRK_NO_MSI) - ", workaround for TI SLLZ059 errata = " __stringify(QUIRK_TI_SLLZ059) + ", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059) ")"); #define OHCI_PARAM_DEBUG_AT_AR 1 @@ -1730,12 +1730,8 @@ static int get_status_for_port(struct fw mutex_lock(&ohci->phy_reg_mutex); reg = write_phy_reg(ohci, 7, port_index); - mutex_unlock(&ohci->phy_reg_mutex); - if (reg < 0) - return reg; - - mutex_lock(&ohci->phy_reg_mutex); - reg = read_phy_reg(ohci, 8); + if (reg >= 0) + reg = read_phy_reg(ohci, 8); mutex_unlock(&ohci->phy_reg_mutex); if (reg < 0) return reg; @@ -1754,6 +1750,7 @@ static int get_self_id_pos(struct fw_ohc { int i; u32 entry; + for (i = 0; i < self_id_count; i++) { entry = ohci->self_id_buffer[i]; if ((self_id & 0xff000000) == (entry & 0xff000000)) @@ -1765,33 +1762,16 @@ static int get_self_id_pos(struct fw_ohc } /* - * This function implements a work around for the Texas Instruments PHY - * TSB41BA3D. This phy has a bug at least in combination with the TI - * LLCs TSB82AA2B and TSB12LV26. The selfid coming from the locally - * connected phy is not propagated into the selfid buffer of the OHCI - * (see http://www.ti.com/litv/pdf/sllz059 for details). - * The main idea is to construct the selfid ourselves. + * TI TSB82AA2B and TSB12LV26 do not receive the selfID of a locally + * attached TSB41BA3D phy; see http://www.ti.com/litv/pdf/sllz059. + * Construct the selfID from phy register contents. + * FIXME: How to determine the selfID.i flag? */ - static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count) { - int reg; - int i; - int pos; - int status; - u32 self_id; - -/* - * preset bits in self_id - * - * link active: 0b1 - * speed: 0b11 - * bridge: 0b00 - * contender: 0b1 - * initiated reset: 0b0 - * more packets: 0b0 - */ - self_id = 0x8040C800; + int reg, i, pos, status; + /* link active 1, speed 3, bridge 0, contender 1, more packets 0 */ + u32 self_id = 0x8040c800; reg = reg_read(ohci, OHCI1394_NodeID); if (!(reg & OHCI1394_NodeID_idValid)) { @@ -1800,16 +1780,12 @@ static int find_and_insert_self_id(struc } self_id |= ((reg & 0x3f) << 24); /* phy ID */ - mutex_lock(&ohci->phy_reg_mutex); - reg = read_phy_reg(ohci, 4); - mutex_unlock(&ohci->phy_reg_mutex); + reg = ohci_read_phy_reg(&ohci->card, 4); if (reg < 0) return reg; self_id |= ((reg & 0x07) << 8); /* power class */ - mutex_lock(&ohci->phy_reg_mutex); - reg = read_phy_reg(ohci, 1); - mutex_unlock(&ohci->phy_reg_mutex); + reg = ohci_read_phy_reg(&ohci->card, 1); if (reg < 0) return reg; self_id |= ((reg & 0x3f) << 16); /* gap count */ @@ -1894,7 +1870,7 @@ static void bus_reset_work(struct work_s if (ohci->quirks & QUIRK_TI_SLLZ059) { self_id_count = find_and_insert_self_id(ohci, self_id_count); if (self_id_count < 0) { - fw_notify("could not construct local self IDs\n"); + fw_notify("could not construct local self ID\n"); return; } } @@ -2188,10 +2164,7 @@ static int configure_1394a_enhancements( static int probe_tsb41ba3d(struct fw_ohci *ohci) { - int reg; - int i; - int vendor_id; - int product_id; + int reg, i, vendor_id, product_id; reg = read_phy_reg(ohci, 2); if (reg < 0) @@ -2214,7 +2187,7 @@ static int probe_tsb41ba3d(struct fw_ohc } if ((vendor_id == TSB41BA3D_VID) && - (product_id == TSB41BA3D_PID)) + (product_id == TSB41BA3D_PID)) return 1; } return 0; @@ -2226,7 +2199,7 @@ static int ohci_enable(struct fw_card *c struct fw_ohci *ohci = fw_ohci(card); struct pci_dev *dev = to_pci_dev(card->device); u32 lps, seconds, version, irqs; - int i, ret, tsb41ba3d_found; + int i, ret; if (software_reset(ohci)) { fw_error("Failed to reset ohci card.\n"); @@ -2258,14 +2231,13 @@ static int ohci_enable(struct fw_card *c } if (ohci->quirks & QUIRK_TI_SLLZ059) { - tsb41ba3d_found = probe_tsb41ba3d(ohci); - if (tsb41ba3d_found < 0) - return tsb41ba3d_found; - if (!tsb41ba3d_found) { - fw_notify("No TSB41BA3D found, " - "resetting QUIRK_TI_SLLZ059\n"); + ret = probe_tsb41ba3d(ohci); + if (ret < 0) + return ret; + if (ret) + fw_notify("local TSB41BA3D phy\n"); + else ohci->quirks &= ~QUIRK_TI_SLLZ059; - } } reg_write(ohci, OHCI1394_HCControlClear,