Date: 2012-05-27 16:51:30 From: Stefan Richter Subject: firewire: ohci: skip regAccessFail checks on Agere and VIA controllers The datasheets of - Agere FW323 rev 5 - VIA VT6306, VT6307, VT6308, VT6315, VT6320, VT6325, VT6330 specify that intEvent.bit18 (regAccessFail according to OHCI 1.1) is always 0. I do not have datasheets of the other Agere 1394 link layer controllers but the product briefs of FW322, FW323, FW643, and FW643E state that they can be configured via PCI bus commands or EEPROM to operate in either OHCI 1.0 or OHCI 1.1 mode. This implies that their PHY and their PHY--link interface cannot exhibit the kind of unreliability which brought the regAccessFail misfeature into OHCI 1.1. So we can skip the regAccessFail test on these chips. Now my test_cycle_time tool gets from 19 million samples per minute to 36 million samples per minute with FW643E on an Unibrain "Fireboard800-e Pro Dual" card. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -266,6 +266,7 @@ static inline struct fw_ohci *fw_ohci(st static char ohci_driver_name[] = KBUILD_MODNAME; +#define PCI_DEVICE_ID_AGERE_FW323 0x5811 #define PCI_DEVICE_ID_AGERE_FW643 0x5901 #define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 @@ -282,6 +283,9 @@ static char ohci_driver_name[] = KBUILD_ #define QUIRK_TI_SLLZ059 0x20 #define QUIRK_REG_ACCESS_FAIL 0x40 +/* OHCI 1.1 and 1.0 compatible link without intEvent.regAccessFail bit */ +#define NO_REG_ACCESS_FAIL (1 << 15) + /* In case of multiple matches in ohci_quirks[], only the first one is used. */ static const struct { unsigned short vendor, device, revision, flags; @@ -292,8 +296,14 @@ static const struct { {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID, QUIRK_BE_HEADERS}, + {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW323, PCI_ANY_ID, + NO_REG_ACCESS_FAIL}, + {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, - QUIRK_NO_MSI}, + QUIRK_NO_MSI | NO_REG_ACCESS_FAIL}, + + {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, PCI_ANY_ID, + NO_REG_ACCESS_FAIL}, {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID, QUIRK_RESET_PACKET}, @@ -323,7 +333,7 @@ static const struct { QUIRK_RESET_PACKET}, {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID, - QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, + QUIRK_CYCLE_TIMER | QUIRK_NO_MSI | NO_REG_ACCESS_FAIL}, }; /* This overrides anything that was found in ohci_quirks[]. */ @@ -2386,7 +2396,8 @@ static int ohci_enable(struct fw_card *c } version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; - if (version >= OHCI_VERSION_1_1) { + if (version >= OHCI_VERSION_1_1 && + !(ohci->quirks & NO_REG_ACCESS_FAIL)) { reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_regAccessFail); ohci->quirks |= QUIRK_REG_ACCESS_FAIL; } @@ -3838,7 +3849,7 @@ static int __devinit pci_probe(struct pc "added OHCI v%x.%x device as card %d, " "%d IR + %d IT contexts, quirks 0x%x\n", version >> 16, version & 0xff, ohci->card.index, - ohci->n_ir, ohci->n_it, ohci->quirks); + ohci->n_ir, ohci->n_it, ohci->quirks & ~NO_REG_ACCESS_FAIL); return 0;