aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/firewire.h
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-07-29 12:19:22 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-07-29 17:09:18 -0400
commit872e330e38806d835bd6c311c93ab998e2fb9058 (patch)
tree92497ce79b1157761b1aebdb63b8d74f68d42c15 /include/linux/firewire.h
parentae2a97661482c1d0f1aa41b837da95054d0e9a1b (diff)
firewire: add isochronous multichannel reception
This adds the DMA context programming and userspace ABI for multichannel reception, i.e. for listening on multiple channel numbers by means of a single DMA context. The use case is reception of more streams than there are IR DMA units offered by the link layer. This is already implemented by the older ohci1394 + ieee1394 + raw1394 stack. And as discussed recently on linux1394-devel, this feature is occasionally used in practice. The big drawbacks of this mode are that buffer layout and interrupt generation necessarily differ from single-channel reception: Headers and trailers are not stripped from packets, packets are not aligned with buffer chunks, interrupts are per buffer chunk, not per packet. These drawbacks also cause a rather hefty code footprint to support this rarely used OHCI-1394 feature. (367 lines added, among them 94 lines of added userspace ABI documentation.) This implementation enforces that a multichannel reception context may only listen to channels to which no single-channel context on the same link layer is presently listening to. OHCI-1394 would allow to overlay single-channel contexts by the multi-channel context, but this would be a departure from the present first-come-first-served policy of IR context creation. The implementation is heavily based on an earlier one by Jay Fenlason. Thanks Jay. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'include/linux/firewire.h')
-rw-r--r--include/linux/firewire.h29
1 files changed, 19 insertions, 10 deletions
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index d974aa4a24c9..1cd637ef62d2 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -372,17 +372,19 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc);
372 * scatter-gather streaming (e.g. assembling video frame automatically). 372 * scatter-gather streaming (e.g. assembling video frame automatically).
373 */ 373 */
374struct fw_iso_packet { 374struct fw_iso_packet {
375 u16 payload_length; /* Length of indirect payload. */ 375 u16 payload_length; /* Length of indirect payload */
376 u32 interrupt:1; /* Generate interrupt on this packet */ 376 u32 interrupt:1; /* Generate interrupt on this packet */
377 u32 skip:1; /* Set to not send packet at all. */ 377 u32 skip:1; /* tx: Set to not send packet at all */
378 u32 tag:2; 378 /* rx: Sync bit, wait for matching sy */
379 u32 sy:4; 379 u32 tag:2; /* tx: Tag in packet header */
380 u32 header_length:8; /* Length of immediate header. */ 380 u32 sy:4; /* tx: Sy in packet header */
381 u32 header[0]; 381 u32 header_length:8; /* Length of immediate header */
382 u32 header[0]; /* tx: Top of 1394 isoch. data_block */
382}; 383};
383 384
384#define FW_ISO_CONTEXT_TRANSMIT 0 385#define FW_ISO_CONTEXT_TRANSMIT 0
385#define FW_ISO_CONTEXT_RECEIVE 1 386#define FW_ISO_CONTEXT_RECEIVE 1
387#define FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL 2
386 388
387#define FW_ISO_CONTEXT_MATCH_TAG0 1 389#define FW_ISO_CONTEXT_MATCH_TAG0 1
388#define FW_ISO_CONTEXT_MATCH_TAG1 2 390#define FW_ISO_CONTEXT_MATCH_TAG1 2
@@ -406,24 +408,31 @@ struct fw_iso_buffer {
406int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, 408int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
407 int page_count, enum dma_data_direction direction); 409 int page_count, enum dma_data_direction direction);
408void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card); 410void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
411size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed);
409 412
410struct fw_iso_context; 413struct fw_iso_context;
411typedef void (*fw_iso_callback_t)(struct fw_iso_context *context, 414typedef void (*fw_iso_callback_t)(struct fw_iso_context *context,
412 u32 cycle, size_t header_length, 415 u32 cycle, size_t header_length,
413 void *header, void *data); 416 void *header, void *data);
417typedef void (*fw_iso_mc_callback_t)(struct fw_iso_context *context,
418 dma_addr_t completed, void *data);
414struct fw_iso_context { 419struct fw_iso_context {
415 struct fw_card *card; 420 struct fw_card *card;
416 int type; 421 int type;
417 int channel; 422 int channel;
418 int speed; 423 int speed;
419 size_t header_size; 424 size_t header_size;
420 fw_iso_callback_t callback; 425 union {
426 fw_iso_callback_t sc;
427 fw_iso_mc_callback_t mc;
428 } callback;
421 void *callback_data; 429 void *callback_data;
422}; 430};
423 431
424struct fw_iso_context *fw_iso_context_create(struct fw_card *card, 432struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
425 int type, int channel, int speed, size_t header_size, 433 int type, int channel, int speed, size_t header_size,
426 fw_iso_callback_t callback, void *callback_data); 434 fw_iso_callback_t callback, void *callback_data);
435int fw_iso_context_set_channels(struct fw_iso_context *ctx, u64 *channels);
427int fw_iso_context_queue(struct fw_iso_context *ctx, 436int fw_iso_context_queue(struct fw_iso_context *ctx,
428 struct fw_iso_packet *packet, 437 struct fw_iso_packet *packet,
429 struct fw_iso_buffer *buffer, 438 struct fw_iso_buffer *buffer,