2 * fireworks_transaction.c - a part of driver for Fireworks based devices
4 * Copyright (c) 2013-2014 Takashi Sakamoto
6 * Licensed under the terms of the GNU General Public License, version 2.
10 * Fireworks have its own transaction. The transaction can be delivered by AV/C
11 * Vendor Specific command frame or usual asynchronous transaction. At least,
12 * Windows driver and firmware version 5.5 or later don't use AV/C command.
14 * Transaction substance:
15 * At first, 6 data exist. Following to the data, parameters for each command
16 * exist. All of the parameters are 32 bit aligned to big endian.
17 * data[0]: Length of transaction substance
18 * data[1]: Transaction version
19 * data[2]: Sequence number. This is incremented by the device
20 * data[3]: Transaction category
21 * data[4]: Transaction command
22 * data[5]: Return value in response.
23 * data[6-]: Parameters
25 * Transaction address:
26 * command: 0xecc000000000
27 * response: 0xecc080000000 (default)
29 * I note that the address for response can be changed by command. But this
30 * module uses the default address.
32 #include "./fireworks.h"
34 #define MEMORY_SPACE_EFW_COMMAND 0xecc000000000ULL
35 #define MEMORY_SPACE_EFW_RESPONSE 0xecc080000000ULL
37 #define ERROR_RETRIES 3
38 #define ERROR_DELAY_MS 5
39 #define EFC_TIMEOUT_MS 125
41 static DEFINE_SPINLOCK(instances_lock
);
42 static struct snd_efw
*instances
[SNDRV_CARDS
] = SNDRV_DEFAULT_PTR
;
44 static DEFINE_SPINLOCK(transaction_queues_lock
);
45 static LIST_HEAD(transaction_queues
);
47 enum transaction_queue_state
{
53 struct transaction_queue
{
54 struct list_head list
;
59 enum transaction_queue_state state
;
60 wait_queue_head_t wait
;
63 int snd_efw_transaction_cmd(struct fw_unit
*unit
,
64 const void *cmd
, unsigned int size
)
66 return snd_fw_transaction(unit
, TCODE_WRITE_BLOCK_REQUEST
,
67 MEMORY_SPACE_EFW_COMMAND
,
68 (void *)cmd
, size
, 0);
71 int snd_efw_transaction_run(struct fw_unit
*unit
,
72 const void *cmd
, unsigned int cmd_size
,
73 void *resp
, unsigned int resp_size
)
75 struct transaction_queue t
;
82 t
.seqnum
= be32_to_cpu(((struct snd_efw_transaction
*)cmd
)->seqnum
) + 1;
83 t
.state
= STATE_PENDING
;
84 init_waitqueue_head(&t
.wait
);
86 spin_lock_irq(&transaction_queues_lock
);
87 list_add_tail(&t
.list
, &transaction_queues
);
88 spin_unlock_irq(&transaction_queues_lock
);
92 ret
= snd_efw_transaction_cmd(t
.unit
, (void *)cmd
, cmd_size
);
96 wait_event_timeout(t
.wait
, t
.state
!= STATE_PENDING
,
97 msecs_to_jiffies(EFC_TIMEOUT_MS
));
99 if (t
.state
== STATE_COMPLETE
) {
102 } else if (t
.state
== STATE_BUS_RESET
) {
103 msleep(ERROR_DELAY_MS
);
104 } else if (++tries
>= ERROR_RETRIES
) {
105 dev_err(&t
.unit
->device
, "EFW transaction timed out\n");
111 spin_lock_irq(&transaction_queues_lock
);
113 spin_unlock_irq(&transaction_queues_lock
);
119 copy_resp_to_buf(struct snd_efw
*efw
, void *data
, size_t length
, int *rcode
)
121 size_t capacity
, till_end
;
122 struct snd_efw_transaction
*t
;
124 t
= (struct snd_efw_transaction
*)data
;
125 length
= min_t(size_t, be32_to_cpu(t
->length
) * sizeof(u32
), length
);
127 spin_lock_irq(&efw
->lock
);
129 if (efw
->push_ptr
< efw
->pull_ptr
)
130 capacity
= (unsigned int)(efw
->pull_ptr
- efw
->push_ptr
);
132 capacity
= snd_efw_resp_buf_size
-
133 (unsigned int)(efw
->push_ptr
- efw
->pull_ptr
);
135 /* confirm enough space for this response */
136 if (capacity
< length
) {
137 *rcode
= RCODE_CONFLICT_ERROR
;
141 /* copy to ring buffer */
143 till_end
= snd_efw_resp_buf_size
-
144 (unsigned int)(efw
->push_ptr
- efw
->resp_buf
);
145 till_end
= min_t(unsigned int, length
, till_end
);
147 memcpy(efw
->push_ptr
, data
, till_end
);
149 efw
->push_ptr
+= till_end
;
150 if (efw
->push_ptr
>= efw
->resp_buf
+ snd_efw_resp_buf_size
)
151 efw
->push_ptr
-= snd_efw_resp_buf_size
;
158 wake_up(&efw
->hwdep_wait
);
160 *rcode
= RCODE_COMPLETE
;
162 spin_unlock_irq(&efw
->lock
);
166 handle_resp_for_user(struct fw_card
*card
, int generation
, int source
,
167 void *data
, size_t length
, int *rcode
)
169 struct fw_device
*device
;
173 spin_lock_irq(&instances_lock
);
175 for (i
= 0; i
< SNDRV_CARDS
; i
++) {
179 device
= fw_parent_device(efw
->unit
);
180 if ((device
->card
!= card
) ||
181 (device
->generation
!= generation
))
183 smp_rmb(); /* node id vs. generation */
184 if (device
->node_id
!= source
)
189 if (i
== SNDRV_CARDS
)
192 copy_resp_to_buf(efw
, data
, length
, rcode
);
194 spin_unlock_irq(&instances_lock
);
198 handle_resp_for_kernel(struct fw_card
*card
, int generation
, int source
,
199 void *data
, size_t length
, int *rcode
, u32 seqnum
)
201 struct fw_device
*device
;
202 struct transaction_queue
*t
;
205 spin_lock_irqsave(&transaction_queues_lock
, flags
);
206 list_for_each_entry(t
, &transaction_queues
, list
) {
207 device
= fw_parent_device(t
->unit
);
208 if ((device
->card
!= card
) ||
209 (device
->generation
!= generation
))
211 smp_rmb(); /* node_id vs. generation */
212 if (device
->node_id
!= source
)
215 if ((t
->state
== STATE_PENDING
) && (t
->seqnum
== seqnum
)) {
216 t
->state
= STATE_COMPLETE
;
217 t
->size
= min_t(unsigned int, length
, t
->size
);
218 memcpy(t
->buf
, data
, t
->size
);
220 *rcode
= RCODE_COMPLETE
;
223 spin_unlock_irqrestore(&transaction_queues_lock
, flags
);
227 efw_response(struct fw_card
*card
, struct fw_request
*request
,
228 int tcode
, int destination
, int source
,
229 int generation
, unsigned long long offset
,
230 void *data
, size_t length
, void *callback_data
)
235 rcode
= RCODE_TYPE_ERROR
;
236 if (length
< sizeof(struct snd_efw_transaction
)) {
237 rcode
= RCODE_DATA_ERROR
;
239 } else if (offset
!= MEMORY_SPACE_EFW_RESPONSE
) {
240 rcode
= RCODE_ADDRESS_ERROR
;
244 seqnum
= be32_to_cpu(((struct snd_efw_transaction
*)data
)->seqnum
);
245 if (seqnum
> SND_EFW_TRANSACTION_USER_SEQNUM_MAX
+ 1) {
246 handle_resp_for_kernel(card
, generation
, source
,
247 data
, length
, &rcode
, seqnum
);
248 if (snd_efw_resp_buf_debug
)
249 handle_resp_for_user(card
, generation
, source
,
250 data
, length
, &dummy
);
252 handle_resp_for_user(card
, generation
, source
,
253 data
, length
, &rcode
);
256 fw_send_response(card
, request
, rcode
);
259 void snd_efw_transaction_add_instance(struct snd_efw
*efw
)
263 spin_lock_irq(&instances_lock
);
265 for (i
= 0; i
< SNDRV_CARDS
; i
++) {
266 if (instances
[i
] != NULL
)
272 spin_unlock_irq(&instances_lock
);
275 void snd_efw_transaction_remove_instance(struct snd_efw
*efw
)
279 spin_lock_irq(&instances_lock
);
281 for (i
= 0; i
< SNDRV_CARDS
; i
++) {
282 if (instances
[i
] != efw
)
287 spin_unlock_irq(&instances_lock
);
290 void snd_efw_transaction_bus_reset(struct fw_unit
*unit
)
292 struct transaction_queue
*t
;
294 spin_lock_irq(&transaction_queues_lock
);
295 list_for_each_entry(t
, &transaction_queues
, list
) {
296 if ((t
->unit
== unit
) &&
297 (t
->state
== STATE_PENDING
)) {
298 t
->state
= STATE_BUS_RESET
;
302 spin_unlock_irq(&transaction_queues_lock
);
305 static struct fw_address_handler resp_register_handler
= {
306 .length
= SND_EFW_RESPONSE_MAXIMUM_BYTES
,
307 .address_callback
= efw_response
310 int snd_efw_transaction_register(void)
312 static const struct fw_address_region resp_register_region
= {
313 .start
= MEMORY_SPACE_EFW_RESPONSE
,
314 .end
= MEMORY_SPACE_EFW_RESPONSE
+
315 SND_EFW_RESPONSE_MAXIMUM_BYTES
317 return fw_core_add_address_handler(&resp_register_handler
,
318 &resp_register_region
);
321 void snd_efw_transaction_unregister(void)
323 WARN_ON(!list_empty(&transaction_queues
));
324 fw_core_remove_address_handler(&resp_register_handler
);