Commit 7ada60e367640fa8a4a349d9b105f235f346238b
Committed by
Stefan Richter
1 parent
5cd54c94b0
Exists in
master
and in
7 other branches
firewire: Document userspace ioctl interface.
The isochronous packet format is still not documented, but this is a good first step. Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (format, wording)
Showing 1 changed file with 264 additions and 33 deletions Side-by-side Diff
include/linux/firewire-cdev.h
... | ... | @@ -30,16 +30,38 @@ |
30 | 30 | #define FW_CDEV_EVENT_REQUEST 0x02 |
31 | 31 | #define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 |
32 | 32 | |
33 | -/* The 'closure' fields are for user space to use. Data passed in the | |
34 | - * 'closure' field for a request will be returned in the corresponding | |
35 | - * event. It's a 64-bit type so that it's a fixed size type big | |
36 | - * enough to hold a pointer on all platforms. */ | |
37 | - | |
33 | +/** | |
34 | + * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types | |
35 | + * @closure: For arbitrary use by userspace | |
36 | + * @type: Discriminates the fw_cdev_event_ types | |
37 | + * | |
38 | + * This struct may be used to access generic members of all fw_cdev_event_ | |
39 | + * types regardless of the specific type. | |
40 | + * | |
41 | + * Data passed in the @closure field for a request will be returned in the | |
42 | + * corresponding event. It is big enough to hold a pointer on all platforms. | |
43 | + * The ioctl used to set @closure depends on the @type of event. | |
44 | + */ | |
38 | 45 | struct fw_cdev_event_common { |
39 | 46 | __u64 closure; |
40 | 47 | __u32 type; |
41 | 48 | }; |
42 | 49 | |
50 | +/** | |
51 | + * struct fw_cdev_event_bus_reset - Sent when a bus reset occurred | |
52 | + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_GET_INFO ioctl | |
53 | + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_BUS_RESET | |
54 | + * @node_id: New node ID of this node | |
55 | + * @local_node_id: Node ID of the local node, i.e. of the controller | |
56 | + * @bm_node_id: Node ID of the bus manager | |
57 | + * @irm_node_id: Node ID of the iso resource manager | |
58 | + * @root_node_id: Node ID of the root node | |
59 | + * @generation: New bus generation | |
60 | + * | |
61 | + * This event is sent when the bus the device belongs to goes through a bus | |
62 | + * reset. It provides information about the new bus configuration, such as | |
63 | + * new node ID for this device, new root ID, and others. | |
64 | + */ | |
43 | 65 | struct fw_cdev_event_bus_reset { |
44 | 66 | __u64 closure; |
45 | 67 | __u32 type; |
... | ... | @@ -51,6 +73,20 @@ |
51 | 73 | __u32 generation; |
52 | 74 | }; |
53 | 75 | |
76 | +/** | |
77 | + * struct fw_cdev_event_response - Sent when a response packet was received | |
78 | + * @closure: See &fw_cdev_event_common; | |
79 | + * set by %FW_CDEV_IOC_SEND_REQUEST ioctl | |
80 | + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE | |
81 | + * @rcode: Response code returned by the remote node | |
82 | + * @length: Data length, i.e. the response's payload size in bytes | |
83 | + * @data: Payload data, if any | |
84 | + * | |
85 | + * This event is sent when the stack receives a response to an outgoing request | |
86 | + * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses | |
87 | + * carrying data (read and lock responses) follows immediately and can be | |
88 | + * accessed through the @data field. | |
89 | + */ | |
54 | 90 | struct fw_cdev_event_response { |
55 | 91 | __u64 closure; |
56 | 92 | __u32 type; |
... | ... | @@ -59,6 +95,25 @@ |
59 | 95 | __u32 data[0]; |
60 | 96 | }; |
61 | 97 | |
98 | +/** | |
99 | + * struct fw_cdev_event_request - Sent on incoming request to an address region | |
100 | + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl | |
101 | + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST | |
102 | + * @tcode: Transaction code of the incoming request | |
103 | + * @offset: The offset into the 48-bit per-node address space | |
104 | + * @handle: Reference to the kernel-side pending request | |
105 | + * @length: Data length, i.e. the request's payload size in bytes | |
106 | + * @data: Incoming data, if any | |
107 | + * | |
108 | + * This event is sent when the stack receives an incoming request to an address | |
109 | + * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is | |
110 | + * guaranteed to be completely contained in the specified region. Userspace is | |
111 | + * responsible for sending the response by %FW_CDEV_IOC_SEND_RESPONSE ioctl, | |
112 | + * using the same @handle. | |
113 | + * | |
114 | + * The payload data for requests carrying data (write and lock requests) | |
115 | + * follows immediately and can be accessed through the @data field. | |
116 | + */ | |
62 | 117 | struct fw_cdev_event_request { |
63 | 118 | __u64 closure; |
64 | 119 | __u32 type; |
65 | 120 | |
66 | 121 | |
... | ... | @@ -69,14 +124,39 @@ |
69 | 124 | __u32 data[0]; |
70 | 125 | }; |
71 | 126 | |
127 | +/** | |
128 | + * struct fw_cdev_event_iso_interrupt - Sent when an iso packet was completed | |
129 | + * @closure: See &fw_cdev_event_common; | |
130 | + * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl | |
131 | + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_ISO_INTERRUPT | |
132 | + * @cycle: Cycle counter of the interrupt packet | |
133 | + * @header_length: Total length of following headers, in bytes | |
134 | + * @header: Stripped headers, if any | |
135 | + * | |
136 | + * This event is sent when the controller has completed an &fw_cdev_iso_packet | |
137 | + * with the %FW_CDEV_ISO_INTERRUPT bit set. In the receive case, the headers | |
138 | + * stripped of all packets up until and including the interrupt packet are | |
139 | + * returned in the @header field. | |
140 | + */ | |
72 | 141 | struct fw_cdev_event_iso_interrupt { |
73 | 142 | __u64 closure; |
74 | 143 | __u32 type; |
75 | 144 | __u32 cycle; |
76 | - __u32 header_length; /* Length in bytes of following headers. */ | |
145 | + __u32 header_length; | |
77 | 146 | __u32 header[0]; |
78 | 147 | }; |
79 | 148 | |
149 | +/** | |
150 | + * union fw_cdev_event - Convenience union of fw_cdev_event_ types | |
151 | + * @common: Valid for all types | |
152 | + * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET | |
153 | + * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE | |
154 | + * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST | |
155 | + * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT | |
156 | + * | |
157 | + * Convenience union for userspace use. Events could be read(2) into a char | |
158 | + * buffer and then cast to this union for further processing. | |
159 | + */ | |
80 | 160 | union fw_cdev_event { |
81 | 161 | struct fw_cdev_event_common common; |
82 | 162 | struct fw_cdev_event_bus_reset bus_reset; |
83 | 163 | |
84 | 164 | |
85 | 165 | |
86 | 166 | |
87 | 167 | |
... | ... | @@ -105,35 +185,47 @@ |
105 | 185 | */ |
106 | 186 | #define FW_CDEV_VERSION 1 |
107 | 187 | |
188 | +/** | |
189 | + * struct fw_cdev_get_info - General purpose information ioctl | |
190 | + * @version: The version field is just a running serial number. | |
191 | + * We never break backwards compatibility, but may add more | |
192 | + * structs and ioctls in later revisions. | |
193 | + * @rom_length: If @rom is non-zero, at most rom_length bytes of configuration | |
194 | + * ROM will be copied into that user space address. In either | |
195 | + * case, @rom_length is updated with the actual length of the | |
196 | + * configuration ROM. | |
197 | + * @rom: If non-zero, address of a buffer to be filled by a copy of the | |
198 | + * local node's configuration ROM | |
199 | + * @bus_reset: If non-zero, address of a buffer to be filled by a | |
200 | + * &struct fw_cdev_event_bus_reset with the current state | |
201 | + * of the bus. This does not cause a bus reset to happen. | |
202 | + * @bus_reset_closure: Value of &closure in this and subsequent bus reset events | |
203 | + * @card: The index of the card this device belongs to | |
204 | + */ | |
108 | 205 | struct fw_cdev_get_info { |
109 | - /* The version field is just a running serial number. We | |
110 | - * never break backwards compatibility. Userspace passes in | |
111 | - * the version it expects and the kernel passes back the | |
112 | - * highest version it can provide. Even if the structs in | |
113 | - * this interface are extended in a later version, the kernel | |
114 | - * will not copy back more data than what was present in the | |
115 | - * interface version userspace expects. */ | |
116 | 206 | __u32 version; |
117 | - | |
118 | - /* If non-zero, at most rom_length bytes of config rom will be | |
119 | - * copied into that user space address. In either case, | |
120 | - * rom_length is updated with the actual length of the config | |
121 | - * rom. */ | |
122 | 207 | __u32 rom_length; |
123 | 208 | __u64 rom; |
124 | - | |
125 | - /* If non-zero, a fw_cdev_event_bus_reset struct will be | |
126 | - * copied here with the current state of the bus. This does | |
127 | - * not cause a bus reset to happen. The value of closure in | |
128 | - * this and sub-sequent bus reset events is set to | |
129 | - * bus_reset_closure. */ | |
130 | 209 | __u64 bus_reset; |
131 | 210 | __u64 bus_reset_closure; |
132 | - | |
133 | - /* The index of the card this devices belongs to. */ | |
134 | 211 | __u32 card; |
135 | 212 | }; |
136 | 213 | |
214 | +/** | |
215 | + * struct fw_cdev_send_request - Send an asynchronous request packet | |
216 | + * @tcode: Transaction code of the request | |
217 | + * @length: Length of outgoing payload, in bytes | |
218 | + * @offset: 48-bit offset at destination node | |
219 | + * @closure: Passed back to userspace in the response event | |
220 | + * @data: Userspace pointer to payload | |
221 | + * @generation: The bus generation where packet is valid | |
222 | + * | |
223 | + * Send a request to the device. This ioctl implements all outgoing requests. | |
224 | + * Both quadlet and block request specify the payload as a pointer to the data | |
225 | + * in the @data field. Once the transaction completes, the kernel writes an | |
226 | + * &fw_cdev_event_request event back. The @closure field is passed back to | |
227 | + * user space in the response event. | |
228 | + */ | |
137 | 229 | struct fw_cdev_send_request { |
138 | 230 | __u32 tcode; |
139 | 231 | __u32 length; |
... | ... | @@ -143,6 +235,19 @@ |
143 | 235 | __u32 generation; |
144 | 236 | }; |
145 | 237 | |
238 | +/** | |
239 | + * struct fw_cdev_send_response - Send an asynchronous response packet | |
240 | + * @rcode: Response code as determined by the userspace handler | |
241 | + * @length: Length of outgoing payload, in bytes | |
242 | + * @data: Userspace pointer to payload | |
243 | + * @handle: The handle from the &fw_cdev_event_request | |
244 | + * | |
245 | + * Send a response to an incoming request. By setting up an address range using | |
246 | + * the %FW_CDEV_IOC_ALLOCATE ioctl, userspace can listen for incoming requests. An | |
247 | + * incoming request will generate an %FW_CDEV_EVENT_REQUEST, and userspace must | |
248 | + * send a reply using this ioctl. The event has a handle to the kernel-side | |
249 | + * pending transaction, which should be used with this ioctl. | |
250 | + */ | |
146 | 251 | struct fw_cdev_send_response { |
147 | 252 | __u32 rcode; |
148 | 253 | __u32 length; |
... | ... | @@ -150,6 +255,21 @@ |
150 | 255 | __u32 handle; |
151 | 256 | }; |
152 | 257 | |
258 | +/** | |
259 | + * struct fw_cdev_allocate - Allocate a CSR address range | |
260 | + * @offset: Start offset of the address range | |
261 | + * @closure: To be passed back to userspace in request events | |
262 | + * @length: Length of the address range, in bytes | |
263 | + * @handle: Handle to the allocation, written by the kernel | |
264 | + * | |
265 | + * Allocate an address range in the 48-bit address space on the local node | |
266 | + * (the controller). This allows userspace to listen for requests with an | |
267 | + * offset within that address range. When the kernel receives a request | |
268 | + * within the range, an &fw_cdev_event_request event will be written back. | |
269 | + * The @closure field is passed back to userspace in the response event. | |
270 | + * The @handle field is an out parameter, returning a handle to the allocated | |
271 | + * range to be used for later deallocation of the range. | |
272 | + */ | |
153 | 273 | struct fw_cdev_allocate { |
154 | 274 | __u64 offset; |
155 | 275 | __u64 closure; |
... | ... | @@ -157,6 +277,11 @@ |
157 | 277 | __u32 handle; |
158 | 278 | }; |
159 | 279 | |
280 | +/** | |
281 | + * struct fw_cdev_deallocate - Free an address range allocation | |
282 | + * @handle: Handle to the address range, as returned by the kernel when the | |
283 | + * range was allocated | |
284 | + */ | |
160 | 285 | struct fw_cdev_deallocate { |
161 | 286 | __u32 handle; |
162 | 287 | }; |
163 | 288 | |
164 | 289 | |
... | ... | @@ -164,10 +289,41 @@ |
164 | 289 | #define FW_CDEV_LONG_RESET 0 |
165 | 290 | #define FW_CDEV_SHORT_RESET 1 |
166 | 291 | |
292 | +/** | |
293 | + * struct fw_cdev_initiate_bus_reset - Initiate a bus reset | |
294 | + * @type: %FW_CDEV_SHORT_RESET or %FW_CDEV_LONG_RESET | |
295 | + * | |
296 | + * Initiate a bus reset for the bus this device is on. The bus reset can be | |
297 | + * either the original (long) bus reset or the arbitrated (short) bus reset | |
298 | + * introduced in 1394a-2000. | |
299 | + */ | |
167 | 300 | struct fw_cdev_initiate_bus_reset { |
168 | - __u32 type; | |
301 | + __u32 type; /* FW_CDEV_SHORT_RESET or FW_CDEV_LONG_RESET */ | |
169 | 302 | }; |
170 | 303 | |
304 | +/** | |
305 | + * struct fw_cdev_add_descriptor - Add contents to the local node's config ROM | |
306 | + * @immediate: If non-zero, immediate key to insert before pointer | |
307 | + * @key: Upper 8 bits of root directory pointer | |
308 | + * @data: Userspace pointer to contents of descriptor block | |
309 | + * @length: Length of descriptor block data, in bytes | |
310 | + * @handle: Handle to the descriptor, written by the kernel | |
311 | + * | |
312 | + * Add a descriptor block and optionally a preceding immediate key to the local | |
313 | + * node's configuration ROM. | |
314 | + * | |
315 | + * The @key field specifies the upper 8 bits of the descriptor root directory | |
316 | + * pointer and the @data and @length fields specify the contents. The @key | |
317 | + * should be of the form 0xXX000000. The offset part of the root directory entry | |
318 | + * will be filled in by the kernel. | |
319 | + * | |
320 | + * If not 0, the @immediate field specifies an immediate key which will be | |
321 | + * inserted before the root directory pointer. | |
322 | + * | |
323 | + * If successful, the kernel adds the descriptor and writes back a handle to the | |
324 | + * kernel-side object to be used for later removal of the descriptor block and | |
325 | + * immediate key. | |
326 | + */ | |
171 | 327 | struct fw_cdev_add_descriptor { |
172 | 328 | __u32 immediate; |
173 | 329 | __u32 key; |
... | ... | @@ -176,6 +332,14 @@ |
176 | 332 | __u32 handle; |
177 | 333 | }; |
178 | 334 | |
335 | +/** | |
336 | + * struct fw_cdev_remove_descriptor - Remove contents from the configuration ROM | |
337 | + * @handle: Handle to the descriptor, as returned by the kernel when the | |
338 | + * descriptor was added | |
339 | + * | |
340 | + * Remove a descriptor block and accompanying immediate key from the local | |
341 | + * node's configuration ROM. | |
342 | + */ | |
179 | 343 | struct fw_cdev_remove_descriptor { |
180 | 344 | __u32 handle; |
181 | 345 | }; |
... | ... | @@ -183,12 +347,24 @@ |
183 | 347 | #define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 |
184 | 348 | #define FW_CDEV_ISO_CONTEXT_RECEIVE 1 |
185 | 349 | |
186 | -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 | |
187 | -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 | |
188 | -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 | |
189 | -#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 | |
190 | -#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 | |
191 | - | |
350 | +/** | |
351 | + * struct fw_cdev_create_iso_context - Create a context for isochronous IO | |
352 | + * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE | |
353 | + * @header_size: Header size to strip for receive contexts | |
354 | + * @channel: Channel to bind to | |
355 | + * @speed: Speed to transmit at | |
356 | + * @closure: To be returned in &fw_cdev_event_iso_interrupt | |
357 | + * @handle: Handle to context, written back by kernel | |
358 | + * | |
359 | + * Prior to sending or receiving isochronous I/O, a context must be created. | |
360 | + * The context records information about the transmit or receive configuration | |
361 | + * and typically maps to an underlying hardware resource. A context is set up | |
362 | + * for either sending or receiving. It is bound to a specific isochronous | |
363 | + * channel. | |
364 | + * | |
365 | + * If a context was successfully created, the kernel writes back a handle to the | |
366 | + * context, which must be passed in for subsequent operations on that context. | |
367 | + */ | |
192 | 368 | struct fw_cdev_create_iso_context { |
193 | 369 | __u32 type; |
194 | 370 | __u32 header_size; |
195 | 371 | |
196 | 372 | |
... | ... | @@ -201,15 +377,49 @@ |
201 | 377 | #define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) |
202 | 378 | #define FW_CDEV_ISO_INTERRUPT (1 << 16) |
203 | 379 | #define FW_CDEV_ISO_SKIP (1 << 17) |
380 | +#define FW_CDEV_ISO_SYNC (1 << 17) | |
204 | 381 | #define FW_CDEV_ISO_TAG(v) ((v) << 18) |
205 | 382 | #define FW_CDEV_ISO_SY(v) ((v) << 20) |
206 | 383 | #define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) |
207 | 384 | |
385 | +/** | |
386 | + * struct fw_cdev_iso_packet - Isochronous packet | |
387 | + * @control: Contains the header length (8 uppermost bits), the sy field | |
388 | + * (4 bits), the tag field (2 bits), a sync flag (1 bit), | |
389 | + * a skip flag (1 bit), an interrupt flag (1 bit), and the | |
390 | + * payload length (16 lowermost bits) | |
391 | + * @header: Header and payload | |
392 | + * | |
393 | + * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. | |
394 | + * | |
395 | + * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are | |
396 | + * specified by IEEE 1394a and IEC 61883. | |
397 | + * | |
398 | + * FIXME - finish this documentation | |
399 | + */ | |
208 | 400 | struct fw_cdev_iso_packet { |
209 | 401 | __u32 control; |
210 | 402 | __u32 header[0]; |
211 | 403 | }; |
212 | 404 | |
405 | +/** | |
406 | + * struct fw_cdev_queue_iso - Queue isochronous packets for I/O | |
407 | + * @packets: Userspace pointer to packet data | |
408 | + * @data: Pointer into mmap()'ed payload buffer | |
409 | + * @size: Size of packet data in bytes | |
410 | + * @handle: Isochronous context handle | |
411 | + * | |
412 | + * Queue a number of isochronous packets for reception or transmission. | |
413 | + * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs, | |
414 | + * which describe how to transmit from or receive into a contiguous region | |
415 | + * of a mmap()'ed payload buffer. As part of the packet descriptors, | |
416 | + * a series of headers can be supplied, which will be prepended to the | |
417 | + * payload during DMA. | |
418 | + * | |
419 | + * The kernel may or may not queue all packets, but will write back updated | |
420 | + * values of the @packets, @data and @size fields, so the ioctl can be | |
421 | + * resubmitted easily. | |
422 | + */ | |
213 | 423 | struct fw_cdev_queue_iso { |
214 | 424 | __u64 packets; |
215 | 425 | __u64 data; |
... | ... | @@ -217,6 +427,23 @@ |
217 | 427 | __u32 handle; |
218 | 428 | }; |
219 | 429 | |
430 | +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 | |
431 | +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 | |
432 | +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 | |
433 | +#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 | |
434 | +#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 | |
435 | + | |
436 | +/** | |
437 | + * struct fw_cdev_start_iso - Start an isochronous transmission or reception | |
438 | + * @cycle: Cycle in which to start I/O. If @cycle is greater than or | |
439 | + * equal to 0, the I/O will start on that cycle. | |
440 | + * @sync: Determines the value to wait for for receive packets that have | |
441 | + * the %FW_CDEV_ISO_SYNC bit set | |
442 | + * @tags: Tag filter bit mask. Only valid for isochronous reception. | |
443 | + * Determines the tag values for which packets will be accepted. | |
444 | + * Use FW_CDEV_ISO_CONTEXT_MATCH_ macros to set @tags. | |
445 | + * @handle: Isochronous context handle within which to transmit or receive | |
446 | + */ | |
220 | 447 | struct fw_cdev_start_iso { |
221 | 448 | __s32 cycle; |
222 | 449 | __u32 sync; |
... | ... | @@ -224,6 +451,10 @@ |
224 | 451 | __u32 handle; |
225 | 452 | }; |
226 | 453 | |
454 | +/** | |
455 | + * struct fw_cdev_stop_iso - Stop an isochronous transmission or reception | |
456 | + * @handle: Handle of isochronous context to stop | |
457 | + */ | |
227 | 458 | struct fw_cdev_stop_iso { |
228 | 459 | __u32 handle; |
229 | 460 | }; |