Skip to content

Commit

Permalink
firewire: ohci: fix probe failure with Agere/LSI controllers
Browse files Browse the repository at this point in the history
Since commit bd97268
"firewire: ohci: Fix 'failed to read phy reg' on FW643 rev8",
there is a high chance that firewire-ohci fails to initialize LSI née
Agere controllers.
https://bugzilla.kernel.org/show_bug.cgi?id=65151

Peter Hurley points out the reason:  IEEE 1394a:2000 clause 5A.1 (or
IEEE 1394:2008 clause 17.2.1) say:  "The PHY shall insure that no more
than 10 ms elapse from the reassertion of LPS until the interface is
reset.  The link shall not assert LReq until the reset is complete."
In other words, the link needs to give the PHY at least 10 ms to get
the interface operational.

With just the msleep(1) in bd97268, the first read_phy_reg()
during ohci_enable() may happen before the phy-link interface reset was
finished, and fail.  Due to the high variability of msleep(n) with small
n, this failure was not fully reproducible, and not apparent at all with
low CONFIG_HZ setting.

On the other hand, Peter can no longer reproduce the issue with FW643
rev8.  The read phy reg failures that happened back then may have had an
unrelated cause.  So, just revert bd97268, except for the valid
comment on TSB82AA2 cards.

Reported-by: Mikhail Gavrilov
Reported-by: Jay Fenlason <[email protected]>
Reported-by: Clemens Ladisch <[email protected]>
Reported-by: Peter Hurley <[email protected]>
Cc: [email protected] # v3.10+
Signed-off-by: Stefan Richter <[email protected]>
  • Loading branch information
Stefan Richter committed Mar 6, 2014
1 parent 8987583 commit 0ca4934
Showing 1 changed file with 2 additions and 13 deletions.
15 changes: 2 additions & 13 deletions drivers/firewire/ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define QUIRK_NO_MSI 0x10
#define QUIRK_TI_SLLZ059 0x20
#define QUIRK_IR_WAKE 0x40
#define QUIRK_PHY_LCTRL_TIMEOUT 0x80

/* In case of multiple matches in ohci_quirks[], only the first one is used. */
static const struct {
Expand All @@ -303,10 +302,7 @@ static const struct {
QUIRK_BE_HEADERS},

{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
QUIRK_PHY_LCTRL_TIMEOUT | QUIRK_NO_MSI},

{PCI_VENDOR_ID_ATT, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_PHY_LCTRL_TIMEOUT},
QUIRK_NO_MSI},

{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
QUIRK_RESET_PACKET},
Expand Down Expand Up @@ -353,7 +349,6 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
", disable MSI = " __stringify(QUIRK_NO_MSI)
", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059)
", IR wake unreliable = " __stringify(QUIRK_IR_WAKE)
", phy LCtrl timeout = " __stringify(QUIRK_PHY_LCTRL_TIMEOUT)
")");

#define OHCI_PARAM_DEBUG_AT_AR 1
Expand Down Expand Up @@ -2299,21 +2294,15 @@ static int ohci_enable(struct fw_card *card,
* TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but
* cannot actually use the phy at that time. These need tens of
* millisecods pause between LPS write and first phy access too.
*
* But do not wait for 50msec on Agere/LSI cards. Their phy
* arbitration state machine may time out during such a long wait.
*/

reg_write(ohci, OHCI1394_HCControlSet,
OHCI1394_HCControl_LPS |
OHCI1394_HCControl_postedWriteEnable);
flush_writes(ohci);

if (!(ohci->quirks & QUIRK_PHY_LCTRL_TIMEOUT))
for (lps = 0, i = 0; !lps && i < 3; i++) {
msleep(50);

for (lps = 0, i = 0; !lps && i < 150; i++) {
msleep(1);
lps = reg_read(ohci, OHCI1394_HCControlSet) &
OHCI1394_HCControl_LPS;
}
Expand Down

0 comments on commit 0ca4934

Please sign in to comment.