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, |
