diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-07-29 12:19:22 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-07-29 17:09:18 -0400 |
commit | 872e330e38806d835bd6c311c93ab998e2fb9058 (patch) | |
tree | 92497ce79b1157761b1aebdb63b8d74f68d42c15 /include/linux/firewire-cdev.h | |
parent | ae2a97661482c1d0f1aa41b837da95054d0e9a1b (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-cdev.h')
-rw-r--r-- | include/linux/firewire-cdev.h | 281 |
1 files changed, 195 insertions, 86 deletions
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 14831119ff71..bc5c26fc1c64 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h | |||
@@ -25,17 +25,18 @@ | |||
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/firewire-constants.h> | 26 | #include <linux/firewire-constants.h> |
27 | 27 | ||
28 | #define FW_CDEV_EVENT_BUS_RESET 0x00 | 28 | #define FW_CDEV_EVENT_BUS_RESET 0x00 |
29 | #define FW_CDEV_EVENT_RESPONSE 0x01 | 29 | #define FW_CDEV_EVENT_RESPONSE 0x01 |
30 | #define FW_CDEV_EVENT_REQUEST 0x02 | 30 | #define FW_CDEV_EVENT_REQUEST 0x02 |
31 | #define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 | 31 | #define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 |
32 | #define FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED 0x04 | 32 | #define FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED 0x04 |
33 | #define FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED 0x05 | 33 | #define FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED 0x05 |
34 | 34 | ||
35 | /* available since kernel version 2.6.36 */ | 35 | /* available since kernel version 2.6.36 */ |
36 | #define FW_CDEV_EVENT_REQUEST2 0x06 | 36 | #define FW_CDEV_EVENT_REQUEST2 0x06 |
37 | #define FW_CDEV_EVENT_PHY_PACKET_SENT 0x07 | 37 | #define FW_CDEV_EVENT_PHY_PACKET_SENT 0x07 |
38 | #define FW_CDEV_EVENT_PHY_PACKET_RECEIVED 0x08 | 38 | #define FW_CDEV_EVENT_PHY_PACKET_RECEIVED 0x08 |
39 | #define FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL 0x09 | ||
39 | 40 | ||
40 | /** | 41 | /** |
41 | * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types | 42 | * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types |
@@ -218,35 +219,41 @@ struct fw_cdev_event_request2 { | |||
218 | * This event is sent when the controller has completed an &fw_cdev_iso_packet | 219 | * This event is sent when the controller has completed an &fw_cdev_iso_packet |
219 | * with the %FW_CDEV_ISO_INTERRUPT bit set. | 220 | * with the %FW_CDEV_ISO_INTERRUPT bit set. |
220 | * | 221 | * |
221 | * Isochronous transmit events: | 222 | * Isochronous transmit events (context type %FW_CDEV_ISO_CONTEXT_TRANSMIT): |
222 | * | 223 | * |
223 | * In version 1 of the ABI, &header_length is 0. In version 3 and some | 224 | * In version 3 and some implementations of version 2 of the ABI, &header_length |
224 | * implementations of version 2 of the ABI, &header_length is a multiple of 4 | 225 | * is a multiple of 4 and &header contains timestamps of all packets up until |
225 | * and &header contains timestamps of all packets up until the interrupt packet. | 226 | * the interrupt packet. The format of the timestamps is as described below for |
226 | * The format of the timestamps is as described below for isochronous reception. | 227 | * isochronous reception. In version 1 of the ABI, &header_length was 0. |
227 | * | 228 | * |
228 | * Isochronous receive events: | 229 | * Isochronous receive events (context type %FW_CDEV_ISO_CONTEXT_RECEIVE): |
229 | * | 230 | * |
230 | * The headers stripped of all packets up until and including the interrupt | 231 | * The headers stripped of all packets up until and including the interrupt |
231 | * packet are returned in the @header field. The amount of header data per | 232 | * packet are returned in the @header field. The amount of header data per |
232 | * packet is as specified at iso context creation by | 233 | * packet is as specified at iso context creation by |
233 | * &fw_cdev_create_iso_context.header_size. | 234 | * &fw_cdev_create_iso_context.header_size. |
234 | * | 235 | * |
235 | * In version 1 of this ABI, header data consisted of the 1394 isochronous | 236 | * Hence, _interrupt.header_length / _context.header_size is the number of |
236 | * packet header, followed by quadlets from the packet payload if | 237 | * packets received in this interrupt event. The client can now iterate |
237 | * &fw_cdev_create_iso_context.header_size > 4. | 238 | * through the mmap()'ed DMA buffer according to this number of packets and |
239 | * to the buffer sizes as the client specified in &fw_cdev_queue_iso. | ||
238 | * | 240 | * |
239 | * In version 2 of this ABI, header data consist of the 1394 isochronous | 241 | * Since version 2 of this ABI, the portion for each packet in _interrupt.header |
240 | * packet header, followed by a timestamp quadlet if | 242 | * consists of the 1394 isochronous packet header, followed by a timestamp |
241 | * &fw_cdev_create_iso_context.header_size > 4, followed by quadlets from the | 243 | * quadlet if &fw_cdev_create_iso_context.header_size > 4, followed by quadlets |
242 | * packet payload if &fw_cdev_create_iso_context.header_size > 8. | 244 | * from the packet payload if &fw_cdev_create_iso_context.header_size > 8. |
243 | * | 245 | * |
244 | * Behaviour of ver. 1 of this ABI is no longer available since ABI ver. 2. | 246 | * Format of 1394 iso packet header: 16 bits data_length, 2 bits tag, 6 bits |
247 | * channel, 4 bits tcode, 4 bits sy, in big endian byte order. | ||
248 | * data_length is the actual received size of the packet without the four | ||
249 | * 1394 iso packet header bytes. | ||
250 | * | ||
251 | * Format of timestamp: 16 bits invalid, 3 bits cycleSeconds, 13 bits | ||
252 | * cycleCount, in big endian byte order. | ||
245 | * | 253 | * |
246 | * Format of 1394 iso packet header: 16 bits len, 2 bits tag, 6 bits channel, | 254 | * In version 1 of the ABI, no timestamp quadlet was inserted; instead, payload |
247 | * 4 bits tcode, 4 bits sy, in big endian byte order. Format of timestamp: | 255 | * data followed directly after the 1394 is header if header_size > 4. |
248 | * 16 bits invalid, 3 bits cycleSeconds, 13 bits cycleCount, in big endian byte | 256 | * Behaviour of ver. 1 of this ABI is no longer available since ABI ver. 2. |
249 | * order. | ||
250 | */ | 257 | */ |
251 | struct fw_cdev_event_iso_interrupt { | 258 | struct fw_cdev_event_iso_interrupt { |
252 | __u64 closure; | 259 | __u64 closure; |
@@ -257,6 +264,43 @@ struct fw_cdev_event_iso_interrupt { | |||
257 | }; | 264 | }; |
258 | 265 | ||
259 | /** | 266 | /** |
267 | * struct fw_cdev_event_iso_interrupt_mc - An iso buffer chunk was completed | ||
268 | * @closure: See &fw_cdev_event_common; | ||
269 | * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl | ||
270 | * @type: %FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL | ||
271 | * @completed: Offset into the receive buffer; data before this offest is valid | ||
272 | * | ||
273 | * This event is sent in multichannel contexts (context type | ||
274 | * %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL) for &fw_cdev_iso_packet buffer | ||
275 | * chunks that have the %FW_CDEV_ISO_INTERRUPT bit set. Whether this happens | ||
276 | * when a packet is completed and/or when a buffer chunk is completed depends | ||
277 | * on the hardware implementation. | ||
278 | * | ||
279 | * The buffer is continuously filled with the following data, per packet: | ||
280 | * - the 1394 iso packet header as described at &fw_cdev_event_iso_interrupt, | ||
281 | * but in little endian byte order, | ||
282 | * - packet payload (as many bytes as specified in the data_length field of | ||
283 | * the 1394 iso packet header) in big endian byte order, | ||
284 | * - 0...3 padding bytes as needed to align the following trailer quadlet, | ||
285 | * - trailer quadlet, containing the reception timestamp as described at | ||
286 | * &fw_cdev_event_iso_interrupt, but in little endian byte order. | ||
287 | * | ||
288 | * Hence the per-packet size is data_length (rounded up to a multiple of 4) + 8. | ||
289 | * When processing the data, stop before a packet that would cross the | ||
290 | * @completed offset. | ||
291 | * | ||
292 | * A packet near the end of a buffer chunk will typically spill over into the | ||
293 | * next queued buffer chunk. It is the responsibility of the client to check | ||
294 | * for this condition, assemble a broken-up packet from its parts, and not to | ||
295 | * re-queue any buffer chunks in which as yet unread packet parts reside. | ||
296 | */ | ||
297 | struct fw_cdev_event_iso_interrupt_mc { | ||
298 | __u64 closure; | ||
299 | __u32 type; | ||
300 | __u32 completed; | ||
301 | }; | ||
302 | |||
303 | /** | ||
260 | * struct fw_cdev_event_iso_resource - Iso resources were allocated or freed | 304 | * struct fw_cdev_event_iso_resource - Iso resources were allocated or freed |
261 | * @closure: See &fw_cdev_event_common; | 305 | * @closure: See &fw_cdev_event_common; |
262 | * set by %FW_CDEV_IOC_(DE)ALLOCATE_ISO_RESOURCE(_ONCE) ioctl | 306 | * set by %FW_CDEV_IOC_(DE)ALLOCATE_ISO_RESOURCE(_ONCE) ioctl |
@@ -311,16 +355,18 @@ struct fw_cdev_event_phy_packet { | |||
311 | 355 | ||
312 | /** | 356 | /** |
313 | * union fw_cdev_event - Convenience union of fw_cdev_event_ types | 357 | * union fw_cdev_event - Convenience union of fw_cdev_event_ types |
314 | * @common: Valid for all types | 358 | * @common: Valid for all types |
315 | * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET | 359 | * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET |
316 | * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE | 360 | * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE |
317 | * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST | 361 | * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST |
318 | * @request2: Valid if @common.type == %FW_CDEV_EVENT_REQUEST2 | 362 | * @request2: Valid if @common.type == %FW_CDEV_EVENT_REQUEST2 |
319 | * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT | 363 | * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT |
320 | * @iso_resource: Valid if @common.type == | 364 | * @iso_interrupt_mc: Valid if @common.type == |
365 | * %FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL | ||
366 | * @iso_resource: Valid if @common.type == | ||
321 | * %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED or | 367 | * %FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED or |
322 | * %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED | 368 | * %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED |
323 | * @phy_packet: Valid if @common.type == | 369 | * @phy_packet: Valid if @common.type == |
324 | * %FW_CDEV_EVENT_PHY_PACKET_SENT or | 370 | * %FW_CDEV_EVENT_PHY_PACKET_SENT or |
325 | * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED | 371 | * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED |
326 | * | 372 | * |
@@ -337,10 +383,11 @@ union fw_cdev_event { | |||
337 | struct fw_cdev_event_bus_reset bus_reset; | 383 | struct fw_cdev_event_bus_reset bus_reset; |
338 | struct fw_cdev_event_response response; | 384 | struct fw_cdev_event_response response; |
339 | struct fw_cdev_event_request request; | 385 | struct fw_cdev_event_request request; |
340 | struct fw_cdev_event_request2 request2; /* added in 2.6.36 */ | 386 | struct fw_cdev_event_request2 request2; /* added in 2.6.36 */ |
341 | struct fw_cdev_event_iso_interrupt iso_interrupt; | 387 | struct fw_cdev_event_iso_interrupt iso_interrupt; |
342 | struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */ | 388 | struct fw_cdev_event_iso_interrupt_mc iso_interrupt_mc; /* added in 2.6.36 */ |
343 | struct fw_cdev_event_phy_packet phy_packet; /* added in 2.6.36 */ | 389 | struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */ |
390 | struct fw_cdev_event_phy_packet phy_packet; /* added in 2.6.36 */ | ||
344 | }; | 391 | }; |
345 | 392 | ||
346 | /* available since kernel version 2.6.22 */ | 393 | /* available since kernel version 2.6.22 */ |
@@ -375,6 +422,7 @@ union fw_cdev_event { | |||
375 | /* available since kernel version 2.6.36 */ | 422 | /* available since kernel version 2.6.36 */ |
376 | #define FW_CDEV_IOC_SEND_PHY_PACKET _IOWR('#', 0x15, struct fw_cdev_send_phy_packet) | 423 | #define FW_CDEV_IOC_SEND_PHY_PACKET _IOWR('#', 0x15, struct fw_cdev_send_phy_packet) |
377 | #define FW_CDEV_IOC_RECEIVE_PHY_PACKETS _IOW('#', 0x16, struct fw_cdev_receive_phy_packets) | 424 | #define FW_CDEV_IOC_RECEIVE_PHY_PACKETS _IOW('#', 0x16, struct fw_cdev_receive_phy_packets) |
425 | #define FW_CDEV_IOC_SET_ISO_CHANNELS _IOW('#', 0x17, struct fw_cdev_set_iso_channels) | ||
378 | 426 | ||
379 | /* | 427 | /* |
380 | * ABI version history | 428 | * ABI version history |
@@ -391,10 +439,13 @@ union fw_cdev_event { | |||
391 | * - shared use and auto-response for FCP registers | 439 | * - shared use and auto-response for FCP registers |
392 | * 3 (2.6.34) - made &fw_cdev_get_cycle_timer reliable | 440 | * 3 (2.6.34) - made &fw_cdev_get_cycle_timer reliable |
393 | * - added %FW_CDEV_IOC_GET_CYCLE_TIMER2 | 441 | * - added %FW_CDEV_IOC_GET_CYCLE_TIMER2 |
394 | * 4 (2.6.36) - added %FW_CDEV_EVENT_REQUEST2, %FW_CDEV_EVENT_PHY_PACKET_* | 442 | * 4 (2.6.36) - added %FW_CDEV_EVENT_REQUEST2, %FW_CDEV_EVENT_PHY_PACKET_*, |
443 | * and &fw_cdev_allocate.region_end | ||
395 | * - implemented &fw_cdev_event_bus_reset.bm_node_id | 444 | * - implemented &fw_cdev_event_bus_reset.bm_node_id |
396 | * - added %FW_CDEV_IOC_SEND_PHY_PACKET, _RECEIVE_PHY_PACKETS | 445 | * - added %FW_CDEV_IOC_SEND_PHY_PACKET, _RECEIVE_PHY_PACKETS |
397 | * - added &fw_cdev_allocate.region_end | 446 | * - added %FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL, |
447 | * %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL, and | ||
448 | * %FW_CDEV_IOC_SET_ISO_CHANNELS | ||
398 | */ | 449 | */ |
399 | #define FW_CDEV_VERSION 3 /* Meaningless; don't use this macro. */ | 450 | #define FW_CDEV_VERSION 3 /* Meaningless; don't use this macro. */ |
400 | 451 | ||
@@ -597,34 +648,43 @@ struct fw_cdev_remove_descriptor { | |||
597 | __u32 handle; | 648 | __u32 handle; |
598 | }; | 649 | }; |
599 | 650 | ||
600 | #define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 | 651 | #define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 |
601 | #define FW_CDEV_ISO_CONTEXT_RECEIVE 1 | 652 | #define FW_CDEV_ISO_CONTEXT_RECEIVE 1 |
653 | #define FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL 2 /* added in 2.6.36 */ | ||
602 | 654 | ||
603 | /** | 655 | /** |
604 | * struct fw_cdev_create_iso_context - Create a context for isochronous IO | 656 | * struct fw_cdev_create_iso_context - Create a context for isochronous I/O |
605 | * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE | 657 | * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE or |
606 | * @header_size: Header size to strip for receive contexts | 658 | * %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL |
607 | * @channel: Channel to bind to | 659 | * @header_size: Header size to strip in single-channel reception |
608 | * @speed: Speed for transmit contexts | 660 | * @channel: Channel to bind to in single-channel reception or transmission |
609 | * @closure: To be returned in &fw_cdev_event_iso_interrupt | 661 | * @speed: Transmission speed |
662 | * @closure: To be returned in &fw_cdev_event_iso_interrupt or | ||
663 | * &fw_cdev_event_iso_interrupt_multichannel | ||
610 | * @handle: Handle to context, written back by kernel | 664 | * @handle: Handle to context, written back by kernel |
611 | * | 665 | * |
612 | * Prior to sending or receiving isochronous I/O, a context must be created. | 666 | * Prior to sending or receiving isochronous I/O, a context must be created. |
613 | * The context records information about the transmit or receive configuration | 667 | * The context records information about the transmit or receive configuration |
614 | * and typically maps to an underlying hardware resource. A context is set up | 668 | * and typically maps to an underlying hardware resource. A context is set up |
615 | * for either sending or receiving. It is bound to a specific isochronous | 669 | * for either sending or receiving. It is bound to a specific isochronous |
616 | * channel. | 670 | * @channel. |
617 | * | 671 | * |
618 | * If a context was successfully created, the kernel writes back a handle to the | 672 | * In case of multichannel reception, @header_size and @channel are ignored |
619 | * context, which must be passed in for subsequent operations on that context. | 673 | * and the channels are selected by %FW_CDEV_IOC_SET_ISO_CHANNELS. |
674 | * | ||
675 | * For %FW_CDEV_ISO_CONTEXT_RECEIVE contexts, @header_size must be at least 4 | ||
676 | * and must be a multiple of 4. It is ignored in other context types. | ||
620 | * | 677 | * |
621 | * For receive contexts, @header_size must be at least 4 and must be a multiple | 678 | * @speed is ignored in receive context types. |
622 | * of 4. | ||
623 | * | 679 | * |
624 | * Note that the effect of a @header_size > 4 depends on | 680 | * If a context was successfully created, the kernel writes back a handle to the |
625 | * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt. | 681 | * context, which must be passed in for subsequent operations on that context. |
626 | * | 682 | * |
683 | * Limitations: | ||
627 | * No more than one iso context can be created per fd. | 684 | * No more than one iso context can be created per fd. |
685 | * The total number of contexts that all userspace and kernelspace drivers can | ||
686 | * create on a card at a time is a hardware limit, typically 4 or 8 contexts per | ||
687 | * direction, and of them at most one multichannel receive context. | ||
628 | */ | 688 | */ |
629 | struct fw_cdev_create_iso_context { | 689 | struct fw_cdev_create_iso_context { |
630 | __u32 type; | 690 | __u32 type; |
@@ -635,6 +695,22 @@ struct fw_cdev_create_iso_context { | |||
635 | __u32 handle; | 695 | __u32 handle; |
636 | }; | 696 | }; |
637 | 697 | ||
698 | /** | ||
699 | * struct fw_cdev_set_iso_channels - Select channels in multichannel reception | ||
700 | * @channels: Bitmask of channels to listen to | ||
701 | * @handle: Handle of the mutichannel receive context | ||
702 | * | ||
703 | * @channels is the bitwise or of 1ULL << n for each channel n to listen to. | ||
704 | * | ||
705 | * The ioctl fails with errno %EBUSY if there is already another receive context | ||
706 | * on a channel in @channels. In that case, the bitmask of all unoccupied | ||
707 | * channels is returned in @channels. | ||
708 | */ | ||
709 | struct fw_cdev_set_iso_channels { | ||
710 | __u64 channels; | ||
711 | __u32 handle; | ||
712 | }; | ||
713 | |||
638 | #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) | 714 | #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) |
639 | #define FW_CDEV_ISO_INTERRUPT (1 << 16) | 715 | #define FW_CDEV_ISO_INTERRUPT (1 << 16) |
640 | #define FW_CDEV_ISO_SKIP (1 << 17) | 716 | #define FW_CDEV_ISO_SKIP (1 << 17) |
@@ -645,42 +721,72 @@ struct fw_cdev_create_iso_context { | |||
645 | 721 | ||
646 | /** | 722 | /** |
647 | * struct fw_cdev_iso_packet - Isochronous packet | 723 | * struct fw_cdev_iso_packet - Isochronous packet |
648 | * @control: Contains the header length (8 uppermost bits), the sy field | 724 | * @control: Contains the header length (8 uppermost bits), |
649 | * (4 bits), the tag field (2 bits), a sync flag (1 bit), | 725 | * the sy field (4 bits), the tag field (2 bits), a sync flag |
650 | * a skip flag (1 bit), an interrupt flag (1 bit), and the | 726 | * or a skip flag (1 bit), an interrupt flag (1 bit), and the |
651 | * payload length (16 lowermost bits) | 727 | * payload length (16 lowermost bits) |
652 | * @header: Header and payload | 728 | * @header: Header and payload in case of a transmit context. |
653 | * | 729 | * |
654 | * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. | 730 | * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. |
655 | * | ||
656 | * Use the FW_CDEV_ISO_ macros to fill in @control. | 731 | * Use the FW_CDEV_ISO_ macros to fill in @control. |
732 | * The @header array is empty in case of receive contexts. | ||
733 | * | ||
734 | * Context type %FW_CDEV_ISO_CONTEXT_TRANSMIT: | ||
735 | * | ||
736 | * @control.HEADER_LENGTH must be a multiple of 4. It specifies the numbers of | ||
737 | * bytes in @header that will be prepended to the packet's payload. These bytes | ||
738 | * are copied into the kernel and will not be accessed after the ioctl has | ||
739 | * returned. | ||
740 | * | ||
741 | * The @control.SY and TAG fields are copied to the iso packet header. These | ||
742 | * fields are specified by IEEE 1394a and IEC 61883-1. | ||
743 | * | ||
744 | * The @control.SKIP flag specifies that no packet is to be sent in a frame. | ||
745 | * When using this, all other fields except @control.INTERRUPT must be zero. | ||
746 | * | ||
747 | * When a packet with the @control.INTERRUPT flag set has been completed, an | ||
748 | * &fw_cdev_event_iso_interrupt event will be sent. | ||
749 | * | ||
750 | * Context type %FW_CDEV_ISO_CONTEXT_RECEIVE: | ||
657 | * | 751 | * |
658 | * For transmit packets, the header length must be a multiple of 4 and specifies | 752 | * @control.HEADER_LENGTH must be a multiple of the context's header_size. |
659 | * the numbers of bytes in @header that will be prepended to the packet's | 753 | * If the HEADER_LENGTH is larger than the context's header_size, multiple |
660 | * payload; these bytes are copied into the kernel and will not be accessed | 754 | * packets are queued for this entry. |
661 | * after the ioctl has returned. The sy and tag fields are copied to the iso | 755 | * |
662 | * packet header (these fields are specified by IEEE 1394a and IEC 61883-1). | 756 | * The @control.SY and TAG fields are ignored. |
663 | * The skip flag specifies that no packet is to be sent in a frame; when using | 757 | * |
664 | * this, all other fields except the interrupt flag must be zero. | 758 | * If the @control.SYNC flag is set, the context drops all packets until a |
665 | * | 759 | * packet with a sy field is received which matches &fw_cdev_start_iso.sync. |
666 | * For receive packets, the header length must be a multiple of the context's | 760 | * |
667 | * header size; if the header length is larger than the context's header size, | 761 | * @control.PAYLOAD_LENGTH defines how many payload bytes can be received for |
668 | * multiple packets are queued for this entry. The sy and tag fields are | 762 | * one packet (in addition to payload quadlets that have been defined as headers |
669 | * ignored. If the sync flag is set, the context drops all packets until | 763 | * and are stripped and returned in the &fw_cdev_event_iso_interrupt structure). |
670 | * a packet with a matching sy field is received (the sync value to wait for is | 764 | * If more bytes are received, the additional bytes are dropped. If less bytes |
671 | * specified in the &fw_cdev_start_iso structure). The payload length defines | 765 | * are received, the remaining bytes in this part of the payload buffer will not |
672 | * how many payload bytes can be received for one packet (in addition to payload | 766 | * be written to, not even by the next packet. I.e., packets received in |
673 | * quadlets that have been defined as headers and are stripped and returned in | 767 | * consecutive frames will not necessarily be consecutive in memory. If an |
674 | * the &fw_cdev_event_iso_interrupt structure). If more bytes are received, the | 768 | * entry has queued multiple packets, the PAYLOAD_LENGTH is divided equally |
675 | * additional bytes are dropped. If less bytes are received, the remaining | 769 | * among them. |
676 | * bytes in this part of the payload buffer will not be written to, not even by | 770 | * |
677 | * the next packet, i.e., packets received in consecutive frames will not | 771 | * When a packet with the @control.INTERRUPT flag set has been completed, an |
678 | * necessarily be consecutive in memory. If an entry has queued multiple | ||
679 | * packets, the payload length is divided equally among them. | ||
680 | * | ||
681 | * When a packet with the interrupt flag set has been completed, the | ||
682 | * &fw_cdev_event_iso_interrupt event will be sent. An entry that has queued | 772 | * &fw_cdev_event_iso_interrupt event will be sent. An entry that has queued |
683 | * multiple receive packets is completed when its last packet is completed. | 773 | * multiple receive packets is completed when its last packet is completed. |
774 | * | ||
775 | * Context type %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL: | ||
776 | * | ||
777 | * Here, &fw_cdev_iso_packet would be more aptly named _iso_buffer_chunk since | ||
778 | * it specifies a chunk of the mmap()'ed buffer, while the number and alignment | ||
779 | * of packets to be placed into the buffer chunk is not known beforehand. | ||
780 | * | ||
781 | * @control.PAYLOAD_LENGTH is the size of the buffer chunk and specifies room | ||
782 | * for header, payload, padding, and trailer bytes of one or more packets. | ||
783 | * It must be a multiple of 4. | ||
784 | * | ||
785 | * @control.HEADER_LENGTH, TAG and SY are ignored. SYNC is treated as described | ||
786 | * for single-channel reception. | ||
787 | * | ||
788 | * When a buffer chunk with the @control.INTERRUPT flag set has been filled | ||
789 | * entirely, an &fw_cdev_event_iso_interrupt_mc event will be sent. | ||
684 | */ | 790 | */ |
685 | struct fw_cdev_iso_packet { | 791 | struct fw_cdev_iso_packet { |
686 | __u32 control; | 792 | __u32 control; |
@@ -689,9 +795,9 @@ struct fw_cdev_iso_packet { | |||
689 | 795 | ||
690 | /** | 796 | /** |
691 | * struct fw_cdev_queue_iso - Queue isochronous packets for I/O | 797 | * struct fw_cdev_queue_iso - Queue isochronous packets for I/O |
692 | * @packets: Userspace pointer to packet data | 798 | * @packets: Userspace pointer to an array of &fw_cdev_iso_packet |
693 | * @data: Pointer into mmap()'ed payload buffer | 799 | * @data: Pointer into mmap()'ed payload buffer |
694 | * @size: Size of packet data in bytes | 800 | * @size: Size of the @packets array, in bytes |
695 | * @handle: Isochronous context handle | 801 | * @handle: Isochronous context handle |
696 | * | 802 | * |
697 | * Queue a number of isochronous packets for reception or transmission. | 803 | * Queue a number of isochronous packets for reception or transmission. |
@@ -704,6 +810,9 @@ struct fw_cdev_iso_packet { | |||
704 | * The kernel may or may not queue all packets, but will write back updated | 810 | * The kernel may or may not queue all packets, but will write back updated |
705 | * values of the @packets, @data and @size fields, so the ioctl can be | 811 | * values of the @packets, @data and @size fields, so the ioctl can be |
706 | * resubmitted easily. | 812 | * resubmitted easily. |
813 | * | ||
814 | * In case of a multichannel receive context, @data must be quadlet-aligned | ||
815 | * relative to the buffer start. | ||
707 | */ | 816 | */ |
708 | struct fw_cdev_queue_iso { | 817 | struct fw_cdev_queue_iso { |
709 | __u64 packets; | 818 | __u64 packets; |