diff options
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 80 |
1 files changed, 59 insertions, 21 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 5d524254499e..ae4556f0c0c1 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -205,7 +205,7 @@ struct fw_ohci { | |||
205 | dma_addr_t config_rom_bus; | 205 | dma_addr_t config_rom_bus; |
206 | __be32 *next_config_rom; | 206 | __be32 *next_config_rom; |
207 | dma_addr_t next_config_rom_bus; | 207 | dma_addr_t next_config_rom_bus; |
208 | u32 next_header; | 208 | __be32 next_header; |
209 | 209 | ||
210 | struct ar_context ar_request_ctx; | 210 | struct ar_context ar_request_ctx; |
211 | struct ar_context ar_response_ctx; | 211 | struct ar_context ar_response_ctx; |
@@ -275,7 +275,7 @@ static void log_irqs(u32 evt) | |||
275 | !(evt & OHCI1394_busReset)) | 275 | !(evt & OHCI1394_busReset)) |
276 | return; | 276 | return; |
277 | 277 | ||
278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, | 278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, |
279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", | 279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", |
280 | evt & OHCI1394_RQPkt ? " AR_req" : "", | 280 | evt & OHCI1394_RQPkt ? " AR_req" : "", |
281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", | 281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", |
@@ -286,6 +286,7 @@ static void log_irqs(u32 evt) | |||
286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", | 286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", |
287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", | 287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", |
288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", | 288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", |
289 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", | ||
289 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", | 290 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", |
290 | evt & OHCI1394_busReset ? " busReset" : "", | 291 | evt & OHCI1394_busReset ? " busReset" : "", |
291 | evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | | 292 | evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | |
@@ -293,6 +294,7 @@ static void log_irqs(u32 evt) | |||
293 | OHCI1394_respTxComplete | OHCI1394_isochRx | | 294 | OHCI1394_respTxComplete | OHCI1394_isochRx | |
294 | OHCI1394_isochTx | OHCI1394_postedWriteErr | | 295 | OHCI1394_isochTx | OHCI1394_postedWriteErr | |
295 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | | 296 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | |
297 | OHCI1394_cycleInconsistent | | ||
296 | OHCI1394_regAccessFail | OHCI1394_busReset) | 298 | OHCI1394_regAccessFail | OHCI1394_busReset) |
297 | ? " ?" : ""); | 299 | ? " ?" : ""); |
298 | } | 300 | } |
@@ -995,7 +997,8 @@ static int at_context_queue_packet(struct context *ctx, | |||
995 | packet->ack = RCODE_SEND_ERROR; | 997 | packet->ack = RCODE_SEND_ERROR; |
996 | return -1; | 998 | return -1; |
997 | } | 999 | } |
998 | packet->payload_bus = payload_bus; | 1000 | packet->payload_bus = payload_bus; |
1001 | packet->payload_mapped = true; | ||
999 | 1002 | ||
1000 | d[2].req_count = cpu_to_le16(packet->payload_length); | 1003 | d[2].req_count = cpu_to_le16(packet->payload_length); |
1001 | d[2].data_address = cpu_to_le32(payload_bus); | 1004 | d[2].data_address = cpu_to_le32(payload_bus); |
@@ -1023,7 +1026,7 @@ static int at_context_queue_packet(struct context *ctx, | |||
1023 | */ | 1026 | */ |
1024 | if (ohci->generation != packet->generation || | 1027 | if (ohci->generation != packet->generation || |
1025 | reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { | 1028 | reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) { |
1026 | if (packet->payload_length > 0) | 1029 | if (packet->payload_mapped) |
1027 | dma_unmap_single(ohci->card.device, payload_bus, | 1030 | dma_unmap_single(ohci->card.device, payload_bus, |
1028 | packet->payload_length, DMA_TO_DEVICE); | 1031 | packet->payload_length, DMA_TO_DEVICE); |
1029 | packet->ack = RCODE_GENERATION; | 1032 | packet->ack = RCODE_GENERATION; |
@@ -1059,7 +1062,7 @@ static int handle_at_packet(struct context *context, | |||
1059 | /* This packet was cancelled, just continue. */ | 1062 | /* This packet was cancelled, just continue. */ |
1060 | return 1; | 1063 | return 1; |
1061 | 1064 | ||
1062 | if (packet->payload_bus) | 1065 | if (packet->payload_mapped) |
1063 | dma_unmap_single(ohci->card.device, packet->payload_bus, | 1066 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1064 | packet->payload_length, DMA_TO_DEVICE); | 1067 | packet->payload_length, DMA_TO_DEVICE); |
1065 | 1068 | ||
@@ -1355,8 +1358,9 @@ static void bus_reset_tasklet(unsigned long data) | |||
1355 | */ | 1358 | */ |
1356 | reg_write(ohci, OHCI1394_BusOptions, | 1359 | reg_write(ohci, OHCI1394_BusOptions, |
1357 | be32_to_cpu(ohci->config_rom[2])); | 1360 | be32_to_cpu(ohci->config_rom[2])); |
1358 | ohci->config_rom[0] = cpu_to_be32(ohci->next_header); | 1361 | ohci->config_rom[0] = ohci->next_header; |
1359 | reg_write(ohci, OHCI1394_ConfigROMhdr, ohci->next_header); | 1362 | reg_write(ohci, OHCI1394_ConfigROMhdr, |
1363 | be32_to_cpu(ohci->next_header)); | ||
1360 | } | 1364 | } |
1361 | 1365 | ||
1362 | #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA | 1366 | #ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA |
@@ -1439,6 +1443,17 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1439 | OHCI1394_LinkControl_cycleMaster); | 1443 | OHCI1394_LinkControl_cycleMaster); |
1440 | } | 1444 | } |
1441 | 1445 | ||
1446 | if (unlikely(event & OHCI1394_cycleInconsistent)) { | ||
1447 | /* | ||
1448 | * We need to clear this event bit in order to make | ||
1449 | * cycleMatch isochronous I/O work. In theory we should | ||
1450 | * stop active cycleMatch iso contexts now and restart | ||
1451 | * them at least two cycles later. (FIXME?) | ||
1452 | */ | ||
1453 | if (printk_ratelimit()) | ||
1454 | fw_notify("isochronous cycle inconsistent\n"); | ||
1455 | } | ||
1456 | |||
1442 | if (event & OHCI1394_cycle64Seconds) { | 1457 | if (event & OHCI1394_cycle64Seconds) { |
1443 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1458 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1444 | if ((cycle_time & 0x80000000) == 0) | 1459 | if ((cycle_time & 0x80000000) == 0) |
@@ -1464,7 +1479,17 @@ static int software_reset(struct fw_ohci *ohci) | |||
1464 | return -EBUSY; | 1479 | return -EBUSY; |
1465 | } | 1480 | } |
1466 | 1481 | ||
1467 | static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | 1482 | static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) |
1483 | { | ||
1484 | size_t size = length * 4; | ||
1485 | |||
1486 | memcpy(dest, src, size); | ||
1487 | if (size < CONFIG_ROM_SIZE) | ||
1488 | memset(&dest[length], 0, CONFIG_ROM_SIZE - size); | ||
1489 | } | ||
1490 | |||
1491 | static int ohci_enable(struct fw_card *card, | ||
1492 | const __be32 *config_rom, size_t length) | ||
1468 | { | 1493 | { |
1469 | struct fw_ohci *ohci = fw_ohci(card); | 1494 | struct fw_ohci *ohci = fw_ohci(card); |
1470 | struct pci_dev *dev = to_pci_dev(card->device); | 1495 | struct pci_dev *dev = to_pci_dev(card->device); |
@@ -1528,6 +1553,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1528 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | 1553 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | |
1529 | OHCI1394_isochRx | OHCI1394_isochTx | | 1554 | OHCI1394_isochRx | OHCI1394_isochTx | |
1530 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | | 1555 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | |
1556 | OHCI1394_cycleInconsistent | | ||
1531 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | | 1557 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | |
1532 | OHCI1394_masterIntEnable); | 1558 | OHCI1394_masterIntEnable); |
1533 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1559 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
@@ -1565,8 +1591,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1565 | if (ohci->next_config_rom == NULL) | 1591 | if (ohci->next_config_rom == NULL) |
1566 | return -ENOMEM; | 1592 | return -ENOMEM; |
1567 | 1593 | ||
1568 | memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); | 1594 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
1569 | fw_memcpy_to_be32(ohci->next_config_rom, config_rom, length * 4); | ||
1570 | } else { | 1595 | } else { |
1571 | /* | 1596 | /* |
1572 | * In the suspend case, config_rom is NULL, which | 1597 | * In the suspend case, config_rom is NULL, which |
@@ -1576,7 +1601,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1576 | ohci->next_config_rom_bus = ohci->config_rom_bus; | 1601 | ohci->next_config_rom_bus = ohci->config_rom_bus; |
1577 | } | 1602 | } |
1578 | 1603 | ||
1579 | ohci->next_header = be32_to_cpu(ohci->next_config_rom[0]); | 1604 | ohci->next_header = ohci->next_config_rom[0]; |
1580 | ohci->next_config_rom[0] = 0; | 1605 | ohci->next_config_rom[0] = 0; |
1581 | reg_write(ohci, OHCI1394_ConfigROMhdr, 0); | 1606 | reg_write(ohci, OHCI1394_ConfigROMhdr, 0); |
1582 | reg_write(ohci, OHCI1394_BusOptions, | 1607 | reg_write(ohci, OHCI1394_BusOptions, |
@@ -1610,7 +1635,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1610 | } | 1635 | } |
1611 | 1636 | ||
1612 | static int ohci_set_config_rom(struct fw_card *card, | 1637 | static int ohci_set_config_rom(struct fw_card *card, |
1613 | u32 *config_rom, size_t length) | 1638 | const __be32 *config_rom, size_t length) |
1614 | { | 1639 | { |
1615 | struct fw_ohci *ohci; | 1640 | struct fw_ohci *ohci; |
1616 | unsigned long flags; | 1641 | unsigned long flags; |
@@ -1659,9 +1684,7 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
1659 | ohci->next_config_rom = next_config_rom; | 1684 | ohci->next_config_rom = next_config_rom; |
1660 | ohci->next_config_rom_bus = next_config_rom_bus; | 1685 | ohci->next_config_rom_bus = next_config_rom_bus; |
1661 | 1686 | ||
1662 | memset(ohci->next_config_rom, 0, CONFIG_ROM_SIZE); | 1687 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
1663 | fw_memcpy_to_be32(ohci->next_config_rom, config_rom, | ||
1664 | length * 4); | ||
1665 | 1688 | ||
1666 | ohci->next_header = config_rom[0]; | 1689 | ohci->next_header = config_rom[0]; |
1667 | ohci->next_config_rom[0] = 0; | 1690 | ohci->next_config_rom[0] = 0; |
@@ -1715,7 +1738,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) | |||
1715 | if (packet->ack != 0) | 1738 | if (packet->ack != 0) |
1716 | goto out; | 1739 | goto out; |
1717 | 1740 | ||
1718 | if (packet->payload_bus) | 1741 | if (packet->payload_mapped) |
1719 | dma_unmap_single(ohci->card.device, packet->payload_bus, | 1742 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1720 | packet->payload_length, DMA_TO_DEVICE); | 1743 | packet->payload_length, DMA_TO_DEVICE); |
1721 | 1744 | ||
@@ -1890,15 +1913,30 @@ static int handle_it_packet(struct context *context, | |||
1890 | { | 1913 | { |
1891 | struct iso_context *ctx = | 1914 | struct iso_context *ctx = |
1892 | container_of(context, struct iso_context, context); | 1915 | container_of(context, struct iso_context, context); |
1916 | int i; | ||
1917 | struct descriptor *pd; | ||
1893 | 1918 | ||
1894 | if (last->transfer_status == 0) | 1919 | for (pd = d; pd <= last; pd++) |
1895 | /* This descriptor isn't done yet, stop iteration. */ | 1920 | if (pd->transfer_status) |
1921 | break; | ||
1922 | if (pd > last) | ||
1923 | /* Descriptor(s) not done yet, stop iteration */ | ||
1896 | return 0; | 1924 | return 0; |
1897 | 1925 | ||
1898 | if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) | 1926 | i = ctx->header_length; |
1927 | if (i + 4 < PAGE_SIZE) { | ||
1928 | /* Present this value as big-endian to match the receive code */ | ||
1929 | *(__be32 *)(ctx->header + i) = cpu_to_be32( | ||
1930 | ((u32)le16_to_cpu(pd->transfer_status) << 16) | | ||
1931 | le16_to_cpu(pd->res_count)); | ||
1932 | ctx->header_length += 4; | ||
1933 | } | ||
1934 | if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) { | ||
1899 | ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count), | 1935 | ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count), |
1900 | 0, NULL, ctx->base.callback_data); | 1936 | ctx->header_length, ctx->header, |
1901 | 1937 | ctx->base.callback_data); | |
1938 | ctx->header_length = 0; | ||
1939 | } | ||
1902 | return 1; | 1940 | return 1; |
1903 | } | 1941 | } |
1904 | 1942 | ||