aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/fw-iso.c2
-rw-r--r--drivers/firewire/fw-ohci.c107
-rw-r--r--drivers/firewire/fw-transaction.h3
3 files changed, 95 insertions, 17 deletions
diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c
index 1605e1157237..736b1bf1513e 100644
--- a/drivers/firewire/fw-iso.c
+++ b/drivers/firewire/fw-iso.c
@@ -111,7 +111,7 @@ fw_iso_context_create(struct fw_card *card, int type, size_t header_size,
111{ 111{
112 struct fw_iso_context *ctx; 112 struct fw_iso_context *ctx;
113 113
114 ctx = card->driver->allocate_iso_context(card, type); 114 ctx = card->driver->allocate_iso_context(card, type, header_size);
115 if (IS_ERR(ctx)) 115 if (IS_ERR(ctx))
116 return ctx; 116 return ctx;
117 117
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 76ac70a38545..9b9ea0f3c416 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1267,16 +1267,34 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
1267 spin_unlock_irqrestore(&ohci->lock, flags); 1267 spin_unlock_irqrestore(&ohci->lock, flags);
1268 return retval; 1268 return retval;
1269} 1269}
1270
1271static int handle_ir_bufferfill_packet(struct context *context,
1272 struct descriptor *d,
1273 struct descriptor *last)
1274{
1275 struct iso_context *ctx =
1276 container_of(context, struct iso_context, context);
1270 1277
1271static int handle_ir_packet(struct context *context, 1278 if (d->res_count > 0)
1272 struct descriptor *d, 1279 return 0;
1273 struct descriptor *last) 1280
1281 if (le16_to_cpu(last->control) & descriptor_irq_always)
1282 ctx->base.callback(&ctx->base,
1283 le16_to_cpu(last->res_count),
1284 0, NULL, ctx->base.callback_data);
1285
1286 return 1;
1287}
1288
1289static int handle_ir_dualbuffer_packet(struct context *context,
1290 struct descriptor *d,
1291 struct descriptor *last)
1274{ 1292{
1275 struct iso_context *ctx = 1293 struct iso_context *ctx =
1276 container_of(context, struct iso_context, context); 1294 container_of(context, struct iso_context, context);
1277 struct db_descriptor *db = (struct db_descriptor *) d; 1295 struct db_descriptor *db = (struct db_descriptor *) d;
1278 size_t header_length; 1296 size_t header_length;
1279 1297
1280 if (db->first_res_count > 0 && db->second_res_count > 0) 1298 if (db->first_res_count > 0 && db->second_res_count > 0)
1281 /* This descriptor isn't done yet, stop iteration. */ 1299 /* This descriptor isn't done yet, stop iteration. */
1282 return 0; 1300 return 0;
@@ -1317,7 +1335,7 @@ static int handle_it_packet(struct context *context,
1317} 1335}
1318 1336
1319static struct fw_iso_context * 1337static struct fw_iso_context *
1320ohci_allocate_iso_context(struct fw_card *card, int type) 1338ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
1321{ 1339{
1322 struct fw_ohci *ohci = fw_ohci(card); 1340 struct fw_ohci *ohci = fw_ohci(card);
1323 struct iso_context *ctx, *list; 1341 struct iso_context *ctx, *list;
@@ -1333,7 +1351,10 @@ ohci_allocate_iso_context(struct fw_card *card, int type)
1333 } else { 1351 } else {
1334 mask = &ohci->ir_context_mask; 1352 mask = &ohci->ir_context_mask;
1335 list = ohci->ir_context_list; 1353 list = ohci->ir_context_list;
1336 callback = handle_ir_packet; 1354 if (header_size > 0)
1355 callback = handle_ir_dualbuffer_packet;
1356 else
1357 callback = handle_ir_bufferfill_packet;
1337 } 1358 }
1338 1359
1339 spin_lock_irqsave(&ohci->lock, flags); 1360 spin_lock_irqsave(&ohci->lock, flags);
@@ -1378,7 +1399,7 @@ static int ohci_start_iso(struct fw_iso_context *base, s32 cycle)
1378{ 1399{
1379 struct iso_context *ctx = container_of(base, struct iso_context, base); 1400 struct iso_context *ctx = container_of(base, struct iso_context, base);
1380 struct fw_ohci *ohci = ctx->context.ohci; 1401 struct fw_ohci *ohci = ctx->context.ohci;
1381 u32 cycle_match = 0; 1402 u32 cycle_match = 0, mode;
1382 int index; 1403 int index;
1383 1404
1384 if (ctx->base.type == FW_ISO_CONTEXT_TRANSMIT) { 1405 if (ctx->base.type == FW_ISO_CONTEXT_TRANSMIT) {
@@ -1393,11 +1414,15 @@ static int ohci_start_iso(struct fw_iso_context *base, s32 cycle)
1393 } else { 1414 } else {
1394 index = ctx - ohci->ir_context_list; 1415 index = ctx - ohci->ir_context_list;
1395 1416
1417 if (ctx->base.header_size > 0)
1418 mode = IR_CONTEXT_DUAL_BUFFER_MODE;
1419 else
1420 mode = IR_CONTEXT_BUFFER_FILL;
1396 reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 1 << index); 1421 reg_write(ohci, OHCI1394_IsoRecvIntEventClear, 1 << index);
1397 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); 1422 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index);
1398 reg_write(ohci, context_match(ctx->context.regs), 1423 reg_write(ohci, context_match(ctx->context.regs),
1399 0xf0000000 | ctx->base.channel); 1424 0xf0000000 | ctx->base.channel);
1400 context_run(&ctx->context, IR_CONTEXT_DUAL_BUFFER_MODE); 1425 context_run(&ctx->context, mode);
1401 } 1426 }
1402 1427
1403 return 0; 1428 return 0;
@@ -1544,10 +1569,10 @@ ohci_queue_iso_transmit(struct fw_iso_context *base,
1544} 1569}
1545 1570
1546static int 1571static int
1547ohci_queue_iso_receive(struct fw_iso_context *base, 1572ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
1548 struct fw_iso_packet *packet, 1573 struct fw_iso_packet *packet,
1549 struct fw_iso_buffer *buffer, 1574 struct fw_iso_buffer *buffer,
1550 unsigned long payload) 1575 unsigned long payload)
1551{ 1576{
1552 struct iso_context *ctx = container_of(base, struct iso_context, base); 1577 struct iso_context *ctx = container_of(base, struct iso_context, base);
1553 struct db_descriptor *db = NULL; 1578 struct db_descriptor *db = NULL;
@@ -1604,10 +1629,58 @@ ohci_queue_iso_receive(struct fw_iso_context *base,
1604 1629
1605 if (p->interrupt) 1630 if (p->interrupt)
1606 db->control |= cpu_to_le16(descriptor_irq_always); 1631 db->control |= cpu_to_le16(descriptor_irq_always);
1632
1633 return 0;
1634}
1607 1635
1608 return 0; 1636static int
1609 } 1637ohci_queue_iso_receive_bufferfill(struct fw_iso_context *base,
1638 struct fw_iso_packet *packet,
1639 struct fw_iso_buffer *buffer,
1640 unsigned long payload)
1641{
1642 struct iso_context *ctx = container_of(base, struct iso_context, base);
1643 struct descriptor *d = NULL;
1644 dma_addr_t d_bus, page_bus;
1645 u32 length, rest;
1646 int page, offset;
1610 1647
1648 page = payload >> PAGE_SHIFT;
1649 offset = payload & ~PAGE_MASK;
1650 rest = packet->payload_length;
1651
1652 while (rest > 0) {
1653 d = context_get_descriptors(&ctx->context, 1, &d_bus);
1654 if (d == NULL)
1655 return -ENOMEM;
1656
1657 d->control = cpu_to_le16(descriptor_input_more |
1658 descriptor_status |
1659 descriptor_branch_always);
1660
1661 if (offset + rest < PAGE_SIZE)
1662 length = rest;
1663 else
1664 length = PAGE_SIZE - offset;
1665
1666 page_bus = page_private(buffer->pages[page]);
1667 d->data_address = cpu_to_le32(page_bus + offset);
1668 d->req_count = cpu_to_le16(length);
1669 d->res_count = cpu_to_le16(length);
1670
1671 context_append(&ctx->context, d, 1, 0);
1672
1673 offset = (offset + length) & ~PAGE_MASK;
1674 rest -= length;
1675 page++;
1676 }
1677
1678 if (packet->interrupt)
1679 d->control |= cpu_to_le16(descriptor_irq_always);
1680
1681 return 0;
1682}
1683
1611static int 1684static int
1612ohci_queue_iso(struct fw_iso_context *base, 1685ohci_queue_iso(struct fw_iso_context *base,
1613 struct fw_iso_packet *packet, 1686 struct fw_iso_packet *packet,
@@ -1616,8 +1689,12 @@ ohci_queue_iso(struct fw_iso_context *base,
1616{ 1689{
1617 if (base->type == FW_ISO_CONTEXT_TRANSMIT) 1690 if (base->type == FW_ISO_CONTEXT_TRANSMIT)
1618 return ohci_queue_iso_transmit(base, packet, buffer, payload); 1691 return ohci_queue_iso_transmit(base, packet, buffer, payload);
1692 else if (base->header_size == 0)
1693 return ohci_queue_iso_receive_bufferfill(base, packet,
1694 buffer, payload);
1619 else 1695 else
1620 return ohci_queue_iso_receive(base, packet, buffer, payload); 1696 return ohci_queue_iso_receive_dualbuffer(base, packet,
1697 buffer, payload);
1621} 1698}
1622 1699
1623static const struct fw_card_driver ohci_driver = { 1700static const struct fw_card_driver ohci_driver = {
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 7942e914b8f1..1bbcbb341f2f 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -425,7 +425,8 @@ struct fw_card_driver {
425 int node_id, int generation); 425 int node_id, int generation);
426 426
427 struct fw_iso_context * 427 struct fw_iso_context *
428 (*allocate_iso_context)(struct fw_card *card, int type); 428 (*allocate_iso_context)(struct fw_card *card,
429 int type, size_t header_size);
429 void (*free_iso_context)(struct fw_iso_context *ctx); 430 void (*free_iso_context)(struct fw_iso_context *ctx);
430 431
431 int (*start_iso)(struct fw_iso_context *ctx, s32 cycle); 432 int (*start_iso)(struct fw_iso_context *ctx, s32 cycle);