aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJarod Wilson <jwilson@redhat.com>2008-04-07 16:32:33 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-04-18 11:55:35 -0400
commit76f73ca1b291a8d014ff0d2d802c817404dd9887 (patch)
treeffd21353249da5febbe5518d9f8eed6b886b5dbf /drivers
parent75f7832e3b032c6e4a83c14b58341abd9f2d81ef (diff)
firewire: fw-ohci: don't append to AT context when it's not active
I finally tracked down the issues with this JMicron PCI-e card in my possession to a failure to comply with section 7.2.3.2 of the OHCI 1.1 specification (thanks to Kristian for the pointer to illustrate that it is indeed a flaw in this card, not the driver). The controller should simply flush the packets we've appended to its AT queue if a bus reset occurs before they've been transmitted and we'll try again, but something goes wrong and the controller winds up hung. However, we can avoid the problem by simply checking if the IntEvent.busReset register had been set before we try appending to the AT context. When busReset is set, the AT context is completely halted until busReset is cleared, so there's no point in appending AT packets until the register is cleared. So at_context_queue_packet() now checks for busReset being set, and bails with an RCODE_GENERATION packet ack, which results in us trying to append the packet again after recognizing the fact there has been a bus reset, and clearing busReset. Signed-off-by: Jarod Wilson <jwilson@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/fw-ohci.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index ce18bab3f9d5..4789300b8241 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -950,8 +950,19 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
950 DESCRIPTOR_IRQ_ALWAYS | 950 DESCRIPTOR_IRQ_ALWAYS |
951 DESCRIPTOR_BRANCH_ALWAYS); 951 DESCRIPTOR_BRANCH_ALWAYS);
952 952
953 /* FIXME: Document how the locking works. */ 953 /*
954 if (ohci->generation != packet->generation) { 954 * If the controller and packet generations don't match, we need to
955 * bail out and try again. If IntEvent.busReset is set, the AT context
956 * is halted, so appending to the context and trying to run it is
957 * futile. Most controllers do the right thing and just flush the AT
958 * queue (per section 7.2.3.2 of the OHCI 1.1 specification), but
959 * some controllers (like a JMicron JMB381 PCI-e) misbehave and wind
960 * up stalling out. So we just bail out in software and try again
961 * later, and everyone is happy.
962 * FIXME: Document how the locking works.
963 */
964 if (ohci->generation != packet->generation ||
965 reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
955 if (packet->payload_length > 0) 966 if (packet->payload_length > 0)
956 dma_unmap_single(ohci->card.device, payload_bus, 967 dma_unmap_single(ohci->card.device, payload_bus,
957 packet->payload_length, DMA_TO_DEVICE); 968 packet->payload_length, DMA_TO_DEVICE);