aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-12-24 08:40:15 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2011-01-03 16:34:48 -0500
commit82b662dc41027527675740de15344d1b4e34958e (patch)
treee9e38e035e426c40b5f52f48da7928872fe61f5c /drivers/firewire
parentc16714704bb35165e5b85d927873dcc643772648 (diff)
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>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/ohci.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 5e5d5d3d43d1..3372cd187c25 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -125,6 +125,7 @@ struct context {
125 struct fw_ohci *ohci; 125 struct fw_ohci *ohci;
126 u32 regs; 126 u32 regs;
127 int total_allocation; 127 int total_allocation;
128 bool flushing;
128 129
129 /* 130 /*
130 * List of page-sized buffers for storing DMA descriptors. 131 * List of page-sized buffers for storing DMA descriptors.
@@ -1356,6 +1357,17 @@ static int at_context_queue_packet(struct context *ctx,
1356 return 0; 1357 return 0;
1357} 1358}
1358 1359
1360static 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
1359static int handle_at_packet(struct context *context, 1371static int handle_at_packet(struct context *context,
1360 struct descriptor *d, 1372 struct descriptor *d,
1361 struct descriptor *last) 1373 struct descriptor *last)
@@ -1365,7 +1377,7 @@ static int handle_at_packet(struct context *context,
1365 struct fw_ohci *ohci = context->ohci; 1377 struct fw_ohci *ohci = context->ohci;
1366 int evt; 1378 int evt;
1367 1379
1368 if (last->transfer_status == 0) 1380 if (last->transfer_status == 0 && !context->flushing)
1369 /* This descriptor isn't done yet, stop iteration. */ 1381 /* This descriptor isn't done yet, stop iteration. */
1370 return 0; 1382 return 0;
1371 1383
@@ -1399,11 +1411,15 @@ static int handle_at_packet(struct context *context,
1399 break; 1411 break;
1400 1412
1401 case OHCI1394_evt_missing_ack: 1413 case OHCI1394_evt_missing_ack:
1402 /* 1414 if (context->flushing)
1403 * Using a valid (current) generation count, but the 1415 packet->ack = RCODE_GENERATION;
1404 * node is not on the bus or not sending acks. 1416 else {
1405 */ 1417 /*
1406 packet->ack = RCODE_NO_ACK; 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 break; 1423 break;
1408 1424
1409 case ACK_COMPLETE + 0x10: 1425 case ACK_COMPLETE + 0x10:
@@ -1416,6 +1432,13 @@ static int handle_at_packet(struct context *context,
1416 packet->ack = evt - 0x10; 1432 packet->ack = evt - 0x10;
1417 break; 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 default: 1442 default:
1420 packet->ack = RCODE_SEND_ERROR; 1443 packet->ack = RCODE_SEND_ERROR;
1421 break; 1444 break;
@@ -1721,9 +1744,18 @@ static void bus_reset_tasklet(unsigned long data)
1721 /* FIXME: Document how the locking works. */ 1744 /* FIXME: Document how the locking works. */
1722 spin_lock_irqsave(&ohci->lock, flags); 1745 spin_lock_irqsave(&ohci->lock, flags);
1723 1746
1724 ohci->generation = generation; 1747 ohci->generation = -1; /* prevent AT packet queueing */
1725 context_stop(&ohci->at_request_ctx); 1748 context_stop(&ohci->at_request_ctx);
1726 context_stop(&ohci->at_response_ctx); 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 reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); 1759 reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
1728 1760
1729 if (ohci->quirks & QUIRK_RESET_PACKET) 1761 if (ohci->quirks & QUIRK_RESET_PACKET)