diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2011-09-18 18:17:37 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2011-10-09 11:00:17 -0400 |
commit | 28897fb73c848eb441e54e859d0b64ad6b44d2e6 (patch) | |
tree | 7bcd80bc463f4d3e6a11c2c2bcf4c8ef069b2142 /drivers/firewire/ohci.c | |
parent | 25935ebebd861182ac58ecea67718bb6a617c7cb (diff) |
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 <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 74 |
1 files changed, 23 insertions, 51 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index b983581cfe35..862fdf3400cf 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -325,7 +325,7 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" | |||
325 | ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) | 325 | ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) |
326 | ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) | 326 | ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) |
327 | ", disable MSI = " __stringify(QUIRK_NO_MSI) | 327 | ", disable MSI = " __stringify(QUIRK_NO_MSI) |
328 | ", workaround for TI SLLZ059 errata = " __stringify(QUIRK_TI_SLLZ059) | 328 | ", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059) |
329 | ")"); | 329 | ")"); |
330 | 330 | ||
331 | #define OHCI_PARAM_DEBUG_AT_AR 1 | 331 | #define OHCI_PARAM_DEBUG_AT_AR 1 |
@@ -1730,12 +1730,8 @@ static int get_status_for_port(struct fw_ohci *ohci, int port_index) | |||
1730 | 1730 | ||
1731 | mutex_lock(&ohci->phy_reg_mutex); | 1731 | mutex_lock(&ohci->phy_reg_mutex); |
1732 | reg = write_phy_reg(ohci, 7, port_index); | 1732 | reg = write_phy_reg(ohci, 7, port_index); |
1733 | mutex_unlock(&ohci->phy_reg_mutex); | 1733 | if (reg >= 0) |
1734 | if (reg < 0) | 1734 | reg = read_phy_reg(ohci, 8); |
1735 | return reg; | ||
1736 | |||
1737 | mutex_lock(&ohci->phy_reg_mutex); | ||
1738 | reg = read_phy_reg(ohci, 8); | ||
1739 | mutex_unlock(&ohci->phy_reg_mutex); | 1735 | mutex_unlock(&ohci->phy_reg_mutex); |
1740 | if (reg < 0) | 1736 | if (reg < 0) |
1741 | return reg; | 1737 | return reg; |
@@ -1754,6 +1750,7 @@ static int get_self_id_pos(struct fw_ohci *ohci, u32 self_id, | |||
1754 | { | 1750 | { |
1755 | int i; | 1751 | int i; |
1756 | u32 entry; | 1752 | u32 entry; |
1753 | |||
1757 | for (i = 0; i < self_id_count; i++) { | 1754 | for (i = 0; i < self_id_count; i++) { |
1758 | entry = ohci->self_id_buffer[i]; | 1755 | entry = ohci->self_id_buffer[i]; |
1759 | if ((self_id & 0xff000000) == (entry & 0xff000000)) | 1756 | if ((self_id & 0xff000000) == (entry & 0xff000000)) |
@@ -1765,33 +1762,16 @@ static int get_self_id_pos(struct fw_ohci *ohci, u32 self_id, | |||
1765 | } | 1762 | } |
1766 | 1763 | ||
1767 | /* | 1764 | /* |
1768 | * This function implements a work around for the Texas Instruments PHY | 1765 | * TI TSB82AA2B and TSB12LV26 do not receive the selfID of a locally |
1769 | * TSB41BA3D. This phy has a bug at least in combination with the TI | 1766 | * attached TSB41BA3D phy; see http://www.ti.com/litv/pdf/sllz059. |
1770 | * LLCs TSB82AA2B and TSB12LV26. The selfid coming from the locally | 1767 | * Construct the selfID from phy register contents. |
1771 | * connected phy is not propagated into the selfid buffer of the OHCI | 1768 | * FIXME: How to determine the selfID.i flag? |
1772 | * (see http://www.ti.com/litv/pdf/sllz059 for details). | ||
1773 | * The main idea is to construct the selfid ourselves. | ||
1774 | */ | 1769 | */ |
1775 | |||
1776 | static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count) | 1770 | static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count) |
1777 | { | 1771 | { |
1778 | int reg; | 1772 | int reg, i, pos, status; |
1779 | int i; | 1773 | /* link active 1, speed 3, bridge 0, contender 1, more packets 0 */ |
1780 | int pos; | 1774 | u32 self_id = 0x8040c800; |
1781 | int status; | ||
1782 | u32 self_id; | ||
1783 | |||
1784 | /* | ||
1785 | * preset bits in self_id | ||
1786 | * | ||
1787 | * link active: 0b1 | ||
1788 | * speed: 0b11 | ||
1789 | * bridge: 0b00 | ||
1790 | * contender: 0b1 | ||
1791 | * initiated reset: 0b0 | ||
1792 | * more packets: 0b0 | ||
1793 | */ | ||
1794 | self_id = 0x8040C800; | ||
1795 | 1775 | ||
1796 | reg = reg_read(ohci, OHCI1394_NodeID); | 1776 | reg = reg_read(ohci, OHCI1394_NodeID); |
1797 | if (!(reg & OHCI1394_NodeID_idValid)) { | 1777 | if (!(reg & OHCI1394_NodeID_idValid)) { |
@@ -1800,16 +1780,12 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count) | |||
1800 | } | 1780 | } |
1801 | self_id |= ((reg & 0x3f) << 24); /* phy ID */ | 1781 | self_id |= ((reg & 0x3f) << 24); /* phy ID */ |
1802 | 1782 | ||
1803 | mutex_lock(&ohci->phy_reg_mutex); | 1783 | reg = ohci_read_phy_reg(&ohci->card, 4); |
1804 | reg = read_phy_reg(ohci, 4); | ||
1805 | mutex_unlock(&ohci->phy_reg_mutex); | ||
1806 | if (reg < 0) | 1784 | if (reg < 0) |
1807 | return reg; | 1785 | return reg; |
1808 | self_id |= ((reg & 0x07) << 8); /* power class */ | 1786 | self_id |= ((reg & 0x07) << 8); /* power class */ |
1809 | 1787 | ||
1810 | mutex_lock(&ohci->phy_reg_mutex); | 1788 | reg = ohci_read_phy_reg(&ohci->card, 1); |
1811 | reg = read_phy_reg(ohci, 1); | ||
1812 | mutex_unlock(&ohci->phy_reg_mutex); | ||
1813 | if (reg < 0) | 1789 | if (reg < 0) |
1814 | return reg; | 1790 | return reg; |
1815 | self_id |= ((reg & 0x3f) << 16); /* gap count */ | 1791 | self_id |= ((reg & 0x3f) << 16); /* gap count */ |
@@ -1894,7 +1870,7 @@ static void bus_reset_work(struct work_struct *work) | |||
1894 | if (ohci->quirks & QUIRK_TI_SLLZ059) { | 1870 | if (ohci->quirks & QUIRK_TI_SLLZ059) { |
1895 | self_id_count = find_and_insert_self_id(ohci, self_id_count); | 1871 | self_id_count = find_and_insert_self_id(ohci, self_id_count); |
1896 | if (self_id_count < 0) { | 1872 | if (self_id_count < 0) { |
1897 | fw_notify("could not construct local self IDs\n"); | 1873 | fw_notify("could not construct local self ID\n"); |
1898 | return; | 1874 | return; |
1899 | } | 1875 | } |
1900 | } | 1876 | } |
@@ -2188,10 +2164,7 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci) | |||
2188 | 2164 | ||
2189 | static int probe_tsb41ba3d(struct fw_ohci *ohci) | 2165 | static int probe_tsb41ba3d(struct fw_ohci *ohci) |
2190 | { | 2166 | { |
2191 | int reg; | 2167 | int reg, i, vendor_id, product_id; |
2192 | int i; | ||
2193 | int vendor_id; | ||
2194 | int product_id; | ||
2195 | 2168 | ||
2196 | reg = read_phy_reg(ohci, 2); | 2169 | reg = read_phy_reg(ohci, 2); |
2197 | if (reg < 0) | 2170 | if (reg < 0) |
@@ -2214,7 +2187,7 @@ static int probe_tsb41ba3d(struct fw_ohci *ohci) | |||
2214 | } | 2187 | } |
2215 | 2188 | ||
2216 | if ((vendor_id == TSB41BA3D_VID) && | 2189 | if ((vendor_id == TSB41BA3D_VID) && |
2217 | (product_id == TSB41BA3D_PID)) | 2190 | (product_id == TSB41BA3D_PID)) |
2218 | return 1; | 2191 | return 1; |
2219 | } | 2192 | } |
2220 | return 0; | 2193 | return 0; |
@@ -2226,7 +2199,7 @@ static int ohci_enable(struct fw_card *card, | |||
2226 | struct fw_ohci *ohci = fw_ohci(card); | 2199 | struct fw_ohci *ohci = fw_ohci(card); |
2227 | struct pci_dev *dev = to_pci_dev(card->device); | 2200 | struct pci_dev *dev = to_pci_dev(card->device); |
2228 | u32 lps, seconds, version, irqs; | 2201 | u32 lps, seconds, version, irqs; |
2229 | int i, ret, tsb41ba3d_found; | 2202 | int i, ret; |
2230 | 2203 | ||
2231 | if (software_reset(ohci)) { | 2204 | if (software_reset(ohci)) { |
2232 | fw_error("Failed to reset ohci card.\n"); | 2205 | fw_error("Failed to reset ohci card.\n"); |
@@ -2258,14 +2231,13 @@ static int ohci_enable(struct fw_card *card, | |||
2258 | } | 2231 | } |
2259 | 2232 | ||
2260 | if (ohci->quirks & QUIRK_TI_SLLZ059) { | 2233 | if (ohci->quirks & QUIRK_TI_SLLZ059) { |
2261 | tsb41ba3d_found = probe_tsb41ba3d(ohci); | 2234 | ret = probe_tsb41ba3d(ohci); |
2262 | if (tsb41ba3d_found < 0) | 2235 | if (ret < 0) |
2263 | return tsb41ba3d_found; | 2236 | return ret; |
2264 | if (!tsb41ba3d_found) { | 2237 | if (ret) |
2265 | fw_notify("No TSB41BA3D found, " | 2238 | fw_notify("local TSB41BA3D phy\n"); |
2266 | "resetting QUIRK_TI_SLLZ059\n"); | 2239 | else |
2267 | ohci->quirks &= ~QUIRK_TI_SLLZ059; | 2240 | ohci->quirks &= ~QUIRK_TI_SLLZ059; |
2268 | } | ||
2269 | } | 2241 | } |
2270 | 2242 | ||
2271 | reg_write(ohci, OHCI1394_HCControlClear, | 2243 | reg_write(ohci, OHCI1394_HCControlClear, |