diff options
-rw-r--r-- | drivers/firewire/fw-ohci.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index b98d81967f70..d5d8177da6d9 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -181,6 +181,7 @@ struct fw_ohci { | |||
181 | int request_generation; | 181 | int request_generation; |
182 | u32 bus_seconds; | 182 | u32 bus_seconds; |
183 | bool old_uninorth; | 183 | bool old_uninorth; |
184 | bool bus_reset_packet_quirk; | ||
184 | 185 | ||
185 | /* | 186 | /* |
186 | * Spinlock for accessing fw_ohci data. Never call out of | 187 | * Spinlock for accessing fw_ohci data. Never call out of |
@@ -571,14 +572,19 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
571 | * generation. We only need this for requests; for responses | 572 | * generation. We only need this for requests; for responses |
572 | * we use the unique tlabel for finding the matching | 573 | * we use the unique tlabel for finding the matching |
573 | * request. | 574 | * request. |
575 | * | ||
576 | * Alas some chips sometimes emit bus reset packets with a | ||
577 | * wrong generation. We set the correct generation for these | ||
578 | * at a slightly incorrect time (in bus_reset_tasklet). | ||
574 | */ | 579 | */ |
575 | 580 | if (evt == OHCI1394_evt_bus_reset) { | |
576 | if (evt == OHCI1394_evt_bus_reset) | 581 | if (!ohci->bus_reset_packet_quirk) |
577 | ohci->request_generation = (p.header[2] >> 16) & 0xff; | 582 | ohci->request_generation = (p.header[2] >> 16) & 0xff; |
578 | else if (ctx == &ohci->ar_request_ctx) | 583 | } else if (ctx == &ohci->ar_request_ctx) { |
579 | fw_core_handle_request(&ohci->card, &p); | 584 | fw_core_handle_request(&ohci->card, &p); |
580 | else | 585 | } else { |
581 | fw_core_handle_response(&ohci->card, &p); | 586 | fw_core_handle_response(&ohci->card, &p); |
587 | } | ||
582 | 588 | ||
583 | return buffer + length + 1; | 589 | return buffer + length + 1; |
584 | } | 590 | } |
@@ -1285,6 +1291,9 @@ static void bus_reset_tasklet(unsigned long data) | |||
1285 | context_stop(&ohci->at_response_ctx); | 1291 | context_stop(&ohci->at_response_ctx); |
1286 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); | 1292 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); |
1287 | 1293 | ||
1294 | if (ohci->bus_reset_packet_quirk) | ||
1295 | ohci->request_generation = generation; | ||
1296 | |||
1288 | /* | 1297 | /* |
1289 | * This next bit is unrelated to the AT context stuff but we | 1298 | * This next bit is unrelated to the AT context stuff but we |
1290 | * have to do it under the spinlock also. If a new config rom | 1299 | * have to do it under the spinlock also. If a new config rom |
@@ -2360,6 +2369,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2360 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | 2369 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && |
2361 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | 2370 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; |
2362 | #endif | 2371 | #endif |
2372 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2373 | |||
2363 | spin_lock_init(&ohci->lock); | 2374 | spin_lock_init(&ohci->lock); |
2364 | 2375 | ||
2365 | tasklet_init(&ohci->bus_reset_tasklet, | 2376 | tasklet_init(&ohci->bus_reset_tasklet, |