Commit 82b662dc41027527675740de15344d1b4e34958e
Committed by
Stefan Richter
1 parent
c16714704b
Exists in
master
and in
4 other branches
firewire: ohci: flush AT contexts after bus reset for OHCI 1.2
The OHCI 1.2 (draft) specification, clause 7.2.3.3, allows and recommends that, after a bus reset, the controller does not flush all the packets in the AT queues. Therefore, the driver has to do this itself. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Showing 1 changed file with 39 additions and 7 deletions Side-by-side Diff
drivers/firewire/ohci.c
... | ... | @@ -125,6 +125,7 @@ |
125 | 125 | struct fw_ohci *ohci; |
126 | 126 | u32 regs; |
127 | 127 | int total_allocation; |
128 | + bool flushing; | |
128 | 129 | |
129 | 130 | /* |
130 | 131 | * List of page-sized buffers for storing DMA descriptors. |
... | ... | @@ -1356,6 +1357,17 @@ |
1356 | 1357 | return 0; |
1357 | 1358 | } |
1358 | 1359 | |
1360 | +static void at_context_flush(struct context *ctx) | |
1361 | +{ | |
1362 | + tasklet_disable(&ctx->tasklet); | |
1363 | + | |
1364 | + ctx->flushing = true; | |
1365 | + context_tasklet((unsigned long)ctx); | |
1366 | + ctx->flushing = false; | |
1367 | + | |
1368 | + tasklet_enable(&ctx->tasklet); | |
1369 | +} | |
1370 | + | |
1359 | 1371 | static int handle_at_packet(struct context *context, |
1360 | 1372 | struct descriptor *d, |
1361 | 1373 | struct descriptor *last) |
... | ... | @@ -1365,7 +1377,7 @@ |
1365 | 1377 | struct fw_ohci *ohci = context->ohci; |
1366 | 1378 | int evt; |
1367 | 1379 | |
1368 | - if (last->transfer_status == 0) | |
1380 | + if (last->transfer_status == 0 && !context->flushing) | |
1369 | 1381 | /* This descriptor isn't done yet, stop iteration. */ |
1370 | 1382 | return 0; |
1371 | 1383 | |
... | ... | @@ -1399,11 +1411,15 @@ |
1399 | 1411 | break; |
1400 | 1412 | |
1401 | 1413 | case OHCI1394_evt_missing_ack: |
1402 | - /* | |
1403 | - * Using a valid (current) generation count, but the | |
1404 | - * node is not on the bus or not sending acks. | |
1405 | - */ | |
1406 | - packet->ack = RCODE_NO_ACK; | |
1414 | + if (context->flushing) | |
1415 | + packet->ack = RCODE_GENERATION; | |
1416 | + else { | |
1417 | + /* | |
1418 | + * Using a valid (current) generation count, but the | |
1419 | + * node is not on the bus or not sending acks. | |
1420 | + */ | |
1421 | + packet->ack = RCODE_NO_ACK; | |
1422 | + } | |
1407 | 1423 | break; |
1408 | 1424 | |
1409 | 1425 | case ACK_COMPLETE + 0x10: |
... | ... | @@ -1416,6 +1432,13 @@ |
1416 | 1432 | packet->ack = evt - 0x10; |
1417 | 1433 | break; |
1418 | 1434 | |
1435 | + case OHCI1394_evt_no_status: | |
1436 | + if (context->flushing) { | |
1437 | + packet->ack = RCODE_GENERATION; | |
1438 | + break; | |
1439 | + } | |
1440 | + /* fall through */ | |
1441 | + | |
1419 | 1442 | default: |
1420 | 1443 | packet->ack = RCODE_SEND_ERROR; |
1421 | 1444 | break; |
1422 | 1445 | |
... | ... | @@ -1721,9 +1744,18 @@ |
1721 | 1744 | /* FIXME: Document how the locking works. */ |
1722 | 1745 | spin_lock_irqsave(&ohci->lock, flags); |
1723 | 1746 | |
1724 | - ohci->generation = generation; | |
1747 | + ohci->generation = -1; /* prevent AT packet queueing */ | |
1725 | 1748 | context_stop(&ohci->at_request_ctx); |
1726 | 1749 | context_stop(&ohci->at_response_ctx); |
1750 | + | |
1751 | + spin_unlock_irqrestore(&ohci->lock, flags); | |
1752 | + | |
1753 | + at_context_flush(&ohci->at_request_ctx); | |
1754 | + at_context_flush(&ohci->at_response_ctx); | |
1755 | + | |
1756 | + spin_lock_irqsave(&ohci->lock, flags); | |
1757 | + | |
1758 | + ohci->generation = generation; | |
1727 | 1759 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); |
1728 | 1760 | |
1729 | 1761 | if (ohci->quirks & QUIRK_RESET_PACKET) |