From eff98deac839d21524c33fdbe4fa86fe1f48bdde Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 12 Apr 2008 22:31:25 +0200 Subject: [PATCH] --- yaml --- r: 89639 b: refs/heads/master c: d34316a4bdcd4fef050da584401c7f4ed22482f2 h: refs/heads/master i: 89637: 977a3b11a91b44848d87f1359fca2fec39a3396e 89635: e7658d57af54b47653083d242271435bdde1341d 89631: e5201c07cbb32e3a3d828c57cd1574486e0d6817 v: v3 --- [refs] | 2 +- trunk/drivers/firewire/fw-ohci.c | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 2c3f91ab9f03..e95942ba59ed 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 08ddb2f4c270b5dff063f7dbcd7e9248a52e7c65 +refs/heads/master: d34316a4bdcd4fef050da584401c7f4ed22482f2 diff --git a/trunk/drivers/firewire/fw-ohci.c b/trunk/drivers/firewire/fw-ohci.c index b98d81967f70..d5d8177da6d9 100644 --- a/trunk/drivers/firewire/fw-ohci.c +++ b/trunk/drivers/firewire/fw-ohci.c @@ -181,6 +181,7 @@ struct fw_ohci { int request_generation; u32 bus_seconds; bool old_uninorth; + bool bus_reset_packet_quirk; /* * 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) * generation. We only need this for requests; for responses * we use the unique tlabel for finding the matching * request. + * + * Alas some chips sometimes emit bus reset packets with a + * wrong generation. We set the correct generation for these + * at a slightly incorrect time (in bus_reset_tasklet). */ - - if (evt == OHCI1394_evt_bus_reset) - ohci->request_generation = (p.header[2] >> 16) & 0xff; - else if (ctx == &ohci->ar_request_ctx) + if (evt == OHCI1394_evt_bus_reset) { + if (!ohci->bus_reset_packet_quirk) + ohci->request_generation = (p.header[2] >> 16) & 0xff; + } else if (ctx == &ohci->ar_request_ctx) { fw_core_handle_request(&ohci->card, &p); - else + } else { fw_core_handle_response(&ohci->card, &p); + } return buffer + length + 1; } @@ -1285,6 +1291,9 @@ static void bus_reset_tasklet(unsigned long data) context_stop(&ohci->at_response_ctx); reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + if (ohci->bus_reset_packet_quirk) + ohci->request_generation = generation; + /* * This next bit is unrelated to the AT context stuff but we * 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) ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; #endif + ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; + spin_lock_init(&ohci->lock); tasklet_init(&ohci->bus_reset_tasklet,