aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/fw-ohci.c99
1 files changed, 49 insertions, 50 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index a44d16d0c505..a9f2d07e7c65 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1461,24 +1461,24 @@ static int handle_ir_packet_per_buffer(struct context *context,
1461{ 1461{
1462 struct iso_context *ctx = 1462 struct iso_context *ctx =
1463 container_of(context, struct iso_context, context); 1463 container_of(context, struct iso_context, context);
1464 struct descriptor *pd = d + 1; 1464 struct descriptor *pd;
1465 __le32 *ir_header; 1465 __le32 *ir_header;
1466 size_t header_length; 1466 void *p;
1467 void *p, *end; 1467 int i;
1468 int i, z;
1469 1468
1470 if (pd->res_count == pd->req_count) 1469 for (pd = d; pd <= last; pd++) {
1470 if (pd->transfer_status)
1471 break;
1472 }
1473 if (pd > last)
1471 /* Descriptor(s) not done yet, stop iteration */ 1474 /* Descriptor(s) not done yet, stop iteration */
1472 return 0; 1475 return 0;
1473 1476
1474 header_length = le16_to_cpu(d->req_count);
1475
1476 i = ctx->header_length; 1477 i = ctx->header_length;
1477 z = le32_to_cpu(pd->branch_address) & 0xf; 1478 p = last + 1;
1478 p = d + z;
1479 end = p + header_length;
1480 1479
1481 while (p < end && i + ctx->base.header_size <= PAGE_SIZE) { 1480 if (ctx->base.header_size > 0 &&
1481 i + ctx->base.header_size <= PAGE_SIZE) {
1482 /* 1482 /*
1483 * The iso header is byteswapped to little endian by 1483 * The iso header is byteswapped to little endian by
1484 * the controller, but the remaining header quadlets 1484 * the controller, but the remaining header quadlets
@@ -1487,14 +1487,11 @@ static int handle_ir_packet_per_buffer(struct context *context,
1487 */ 1487 */
1488 *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4)); 1488 *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
1489 memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4); 1489 memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
1490 i += ctx->base.header_size; 1490 ctx->header_length += ctx->base.header_size;
1491 p += ctx->base.header_size + 4;
1492 } 1491 }
1493 1492
1494 ctx->header_length = i; 1493 if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
1495 1494 ir_header = (__le32 *) p;
1496 if (le16_to_cpu(pd->control) & DESCRIPTOR_IRQ_ALWAYS) {
1497 ir_header = (__le32 *) (d + z);
1498 ctx->base.callback(&ctx->base, 1495 ctx->base.callback(&ctx->base,
1499 le32_to_cpu(ir_header[0]) & 0xffff, 1496 le32_to_cpu(ir_header[0]) & 0xffff,
1500 ctx->header_length, ctx->header, 1497 ctx->header_length, ctx->header,
@@ -1502,7 +1499,6 @@ static int handle_ir_packet_per_buffer(struct context *context,
1502 ctx->header_length = 0; 1499 ctx->header_length = 0;
1503 } 1500 }
1504 1501
1505
1506 return 1; 1502 return 1;
1507} 1503}
1508 1504
@@ -1853,67 +1849,70 @@ ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
1853{ 1849{
1854 struct iso_context *ctx = container_of(base, struct iso_context, base); 1850 struct iso_context *ctx = container_of(base, struct iso_context, base);
1855 struct descriptor *d = NULL, *pd = NULL; 1851 struct descriptor *d = NULL, *pd = NULL;
1856 struct fw_iso_packet *p; 1852 struct fw_iso_packet *p = packet;
1857 dma_addr_t d_bus, page_bus; 1853 dma_addr_t d_bus, page_bus;
1858 u32 z, header_z, rest; 1854 u32 z, header_z, rest;
1859 int i, page, offset, packet_count, header_size; 1855 int i, j, length;
1860 1856 int page, offset, packet_count, header_size, payload_per_buffer;
1861 if (packet->skip) {
1862 d = context_get_descriptors(&ctx->context, 1, &d_bus);
1863 if (d == NULL)
1864 return -ENOMEM;
1865
1866 d->control = cpu_to_le16(DESCRIPTOR_STATUS |
1867 DESCRIPTOR_INPUT_LAST |
1868 DESCRIPTOR_BRANCH_ALWAYS |
1869 DESCRIPTOR_WAIT);
1870 context_append(&ctx->context, d, 1, 0);
1871 }
1872
1873 /* one descriptor for header, one for payload */
1874 /* FIXME: handle cases where we need multiple desc. for payload */
1875 z = 2;
1876 p = packet;
1877 1857
1878 /* 1858 /*
1879 * The OHCI controller puts the status word in the 1859 * The OHCI controller puts the status word in the
1880 * buffer too, so we need 4 extra bytes per packet. 1860 * buffer too, so we need 4 extra bytes per packet.
1881 */ 1861 */
1882 packet_count = p->header_length / ctx->base.header_size; 1862 packet_count = p->header_length / ctx->base.header_size;
1883 header_size = packet_count * (ctx->base.header_size + 4); 1863 header_size = ctx->base.header_size + 4;
1884 1864
1885 /* Get header size in number of descriptors. */ 1865 /* Get header size in number of descriptors. */
1886 header_z = DIV_ROUND_UP(header_size, sizeof(*d)); 1866 header_z = DIV_ROUND_UP(header_size, sizeof(*d));
1887 page = payload >> PAGE_SHIFT; 1867 page = payload >> PAGE_SHIFT;
1888 offset = payload & ~PAGE_MASK; 1868 offset = payload & ~PAGE_MASK;
1889 rest = p->payload_length; 1869 payload_per_buffer = p->payload_length / packet_count;
1890 1870
1891 for (i = 0; i < packet_count; i++) { 1871 for (i = 0; i < packet_count; i++) {
1892 /* d points to the header descriptor */ 1872 /* d points to the header descriptor */
1873 z = DIV_ROUND_UP(payload_per_buffer + offset, PAGE_SIZE) + 1;
1893 d = context_get_descriptors(&ctx->context, 1874 d = context_get_descriptors(&ctx->context,
1894 z + header_z, &d_bus); 1875 z + header_z, &d_bus);
1895 if (d == NULL) 1876 if (d == NULL)
1896 return -ENOMEM; 1877 return -ENOMEM;
1897 1878
1898 d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE); 1879 d->control = cpu_to_le16(DESCRIPTOR_STATUS |
1880 DESCRIPTOR_INPUT_MORE);
1881 if (p->skip && i == 0)
1882 d->control |= cpu_to_le16(DESCRIPTOR_WAIT);
1899 d->req_count = cpu_to_le16(header_size); 1883 d->req_count = cpu_to_le16(header_size);
1900 d->res_count = d->req_count; 1884 d->res_count = d->req_count;
1885 d->transfer_status = 0;
1901 d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d))); 1886 d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d)));
1902 1887
1903 /* pd points to the payload descriptor */ 1888 rest = payload_per_buffer;
1904 pd = d + 1; 1889 for (j = 1; j < z; j++) {
1890 pd = d + j;
1891 pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
1892 DESCRIPTOR_INPUT_MORE);
1893
1894 if (offset + rest < PAGE_SIZE)
1895 length = rest;
1896 else
1897 length = PAGE_SIZE - offset;
1898 pd->req_count = cpu_to_le16(length);
1899 pd->res_count = pd->req_count;
1900 pd->transfer_status = 0;
1901
1902 page_bus = page_private(buffer->pages[page]);
1903 pd->data_address = cpu_to_le32(page_bus + offset);
1904
1905 offset = (offset + length) & ~PAGE_MASK;
1906 rest -= length;
1907 if (offset == 0)
1908 page++;
1909 }
1905 pd->control = cpu_to_le16(DESCRIPTOR_STATUS | 1910 pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
1906 DESCRIPTOR_INPUT_LAST | 1911 DESCRIPTOR_INPUT_LAST |
1907 DESCRIPTOR_BRANCH_ALWAYS); 1912 DESCRIPTOR_BRANCH_ALWAYS);
1908 if (p->interrupt) 1913 if (p->interrupt && i == packet_count - 1)
1909 pd->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS); 1914 pd->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS);
1910 1915
1911 pd->req_count = cpu_to_le16(rest);
1912 pd->res_count = pd->req_count;
1913
1914 page_bus = page_private(buffer->pages[page]);
1915 pd->data_address = cpu_to_le32(page_bus + offset);
1916
1917 context_append(&ctx->context, d, z, header_z); 1916 context_append(&ctx->context, d, z, header_z);
1918 } 1917 }
1919 1918