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 alighed 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 spin_lock_irq(&efw
->lock
);
126 t
= (struct snd_efw_transaction
*)data
;
127 length
= min_t(size_t, be32_to_cpu(t
->length
) * sizeof(u32
), length
);
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
;
159 wake_up(&efw
->hwdep_wait
);
161 *rcode
= RCODE_COMPLETE
;
163 spin_unlock_irq(&efw
->lock
);
167 handle_resp_for_user(struct fw_card
*card
, int generation
, int source
,
168 void *data
, size_t length
, int *rcode
)
170 struct fw_device
*device
;
174 spin_lock_irq(&instances_lock
);
176 for (i
= 0; i
< SNDRV_CARDS
; i
++) {
180 device
= fw_parent_device(efw
->unit
);
181 if ((device
->card
!= card
) ||
182 (device
->generation
!= generation
))
184 smp_rmb(); /* node id vs. generation */
185 if (device
->node_id
!= source
)
190 if (i
== SNDRV_CARDS
)
193 copy_resp_to_buf(efw
, data
, length
, rcode
);
195 spin_unlock_irq(&instances_lock
);
199 handle_resp_for_kernel(struct fw_card
*card
, int generation
, int source
,
200 void *data
, size_t length
, int *rcode
, u32 seqnum
)
202 struct fw_device
*device
;
203 struct transaction_queue
*t
;
206 spin_lock_irqsave(&transaction_queues_lock
, flags
);
207 list_for_each_entry(t
, &transaction_queues
, list
) {
208 device
= fw_parent_device(t
->unit
);
209 if ((device
->card
!= card
) ||
210 (device
->generation
!= generation
))
212 smp_rmb(); /* node_id vs. generation */
213 if (device
->node_id
!= source
)
216 if ((t
->state
== STATE_PENDING
) && (t
->seqnum
== seqnum
)) {
217 t
->state
= STATE_COMPLETE
;
218 t
->size
= min_t(unsigned int, length
, t
->size
);
219 memcpy(t
->buf
, data
, t
->size
);
221 *rcode
= RCODE_COMPLETE
;
224 spin_unlock_irqrestore(&transaction_queues_lock
, flags
);
228 efw_response(struct fw_card
*card
, struct fw_request
*request
,
229 int tcode
, int destination
, int source
,
230 int generation
, unsigned long long offset
,
231 void *data
, size_t length
, void *callback_data
)
236 rcode
= RCODE_TYPE_ERROR
;
237 if (length
< sizeof(struct snd_efw_transaction
)) {
238 rcode
= RCODE_DATA_ERROR
;
240 } else if (offset
!= MEMORY_SPACE_EFW_RESPONSE
) {
241 rcode
= RCODE_ADDRESS_ERROR
;
245 seqnum
= be32_to_cpu(((struct snd_efw_transaction
*)data
)->seqnum
);
246 if (seqnum
> SND_EFW_TRANSACTION_USER_SEQNUM_MAX
+ 1) {
247 handle_resp_for_kernel(card
, generation
, source
,
248 data
, length
, &rcode
, seqnum
);
249 if (snd_efw_resp_buf_debug
)
250 handle_resp_for_user(card
, generation
, source
,
251 data
, length
, &dummy
);
253 handle_resp_for_user(card
, generation
, source
,
254 data
, length
, &rcode
);
257 fw_send_response(card
, request
, rcode
);
260 void snd_efw_transaction_add_instance(struct snd_efw
*efw
)
264 spin_lock_irq(&instances_lock
);
266 for (i
= 0; i
< SNDRV_CARDS
; i
++) {
267 if (instances
[i
] != NULL
)
273 spin_unlock_irq(&instances_lock
);
276 void snd_efw_transaction_remove_instance(struct snd_efw
*efw
)
280 spin_lock_irq(&instances_lock
);
282 for (i
= 0; i
< SNDRV_CARDS
; i
++) {
283 if (instances
[i
] != efw
)
288 spin_unlock_irq(&instances_lock
);
291 void snd_efw_transaction_bus_reset(struct fw_unit
*unit
)
293 struct transaction_queue
*t
;
295 spin_lock_irq(&transaction_queues_lock
);
296 list_for_each_entry(t
, &transaction_queues
, list
) {
297 if ((t
->unit
== unit
) &&
298 (t
->state
== STATE_PENDING
)) {
299 t
->state
= STATE_BUS_RESET
;
303 spin_unlock_irq(&transaction_queues_lock
);
306 static struct fw_address_handler resp_register_handler
= {
307 .length
= SND_EFW_RESPONSE_MAXIMUM_BYTES
,
308 .address_callback
= efw_response
311 int snd_efw_transaction_register(void)
313 static const struct fw_address_region resp_register_region
= {
314 .start
= MEMORY_SPACE_EFW_RESPONSE
,
315 .end
= MEMORY_SPACE_EFW_RESPONSE
+
316 SND_EFW_RESPONSE_MAXIMUM_BYTES
318 return fw_core_add_address_handler(&resp_register_handler
,
319 &resp_register_region
);
322 void snd_efw_transaction_unregister(void)
324 WARN_ON(!list_empty(&transaction_queues
));
325 fw_core_remove_address_handler(&resp_register_handler
);