aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-transaction.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-10 16:02:21 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-24 15:56:50 -0400
commit18e9b10fcdc090d3a38606958167d5923c7099b7 (patch)
treefd83055d908e8786afc9b3fbc791b57b2ba10c33 /drivers/firewire/fw-transaction.c
parent664d8010b170ae8b3ce9268b4f4da934d27b0491 (diff)
firewire: cdev: add closure to async stream ioctl
This changes the as yet unreleased FW_CDEV_IOC_SEND_STREAM_PACKET ioctl to generate an fw_cdev_event_response event just like the other two ioctls for asynchronous request transmission do. This way, clients get feedback on successful or unsuccessful transmission. This also adds input validation for length, tag, channel, sy, speed. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-transaction.c')
-rw-r--r--drivers/firewire/fw-transaction.c42
1 files changed, 16 insertions, 26 deletions
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index e3da58991960..4a9b37461c26 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -37,10 +37,6 @@
37#include "fw-topology.h" 37#include "fw-topology.h"
38#include "fw-device.h" 38#include "fw-device.h"
39 39
40#define HEADER_TAG(tag) ((tag) << 14)
41#define HEADER_CHANNEL(ch) ((ch) << 8)
42#define HEADER_SY(sy) ((sy) << 0)
43
44#define HEADER_PRI(pri) ((pri) << 0) 40#define HEADER_PRI(pri) ((pri) << 0)
45#define HEADER_TCODE(tcode) ((tcode) << 4) 41#define HEADER_TCODE(tcode) ((tcode) << 4)
46#define HEADER_RETRY(retry) ((retry) << 8) 42#define HEADER_RETRY(retry) ((retry) << 8)
@@ -158,6 +154,18 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
158{ 154{
159 int ext_tcode; 155 int ext_tcode;
160 156
157 if (tcode == TCODE_STREAM_DATA) {
158 packet->header[0] =
159 HEADER_DATA_LENGTH(length) |
160 destination_id |
161 HEADER_TCODE(TCODE_STREAM_DATA);
162 packet->header_length = 4;
163 packet->payload = payload;
164 packet->payload_length = length;
165
166 goto common;
167 }
168
161 if (tcode > 0x10) { 169 if (tcode > 0x10) {
162 ext_tcode = tcode & ~0x10; 170 ext_tcode = tcode & ~0x10;
163 tcode = TCODE_LOCK_REQUEST; 171 tcode = TCODE_LOCK_REQUEST;
@@ -204,7 +212,7 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
204 packet->payload_length = 0; 212 packet->payload_length = 0;
205 break; 213 break;
206 } 214 }
207 215 common:
208 packet->speed = speed; 216 packet->speed = speed;
209 packet->generation = generation; 217 packet->generation = generation;
210 packet->ack = 0; 218 packet->ack = 0;
@@ -246,6 +254,9 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
246 * @param callback function to be called when the transaction is completed 254 * @param callback function to be called when the transaction is completed
247 * @param callback_data pointer to arbitrary data, which will be 255 * @param callback_data pointer to arbitrary data, which will be
248 * passed to the callback 256 * passed to the callback
257 *
258 * In case of asynchronous stream packets i.e. TCODE_STREAM_DATA, the caller
259 * needs to synthesize @destination_id with fw_stream_packet_destination_id().
249 */ 260 */
250void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, 261void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
251 int destination_id, int generation, int speed, 262 int destination_id, int generation, int speed,
@@ -297,27 +308,6 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
297} 308}
298EXPORT_SYMBOL(fw_send_request); 309EXPORT_SYMBOL(fw_send_request);
299 310
300void fw_send_stream_packet(struct fw_card *card, struct fw_packet *p,
301 int generation, int speed, int channel, int sy, int tag,
302 void *payload, size_t length, fw_packet_callback_t callback)
303{
304 p->callback = callback;
305 p->header[0] =
306 HEADER_DATA_LENGTH(length)
307 | HEADER_TAG(tag)
308 | HEADER_CHANNEL(channel)
309 | HEADER_TCODE(TCODE_STREAM_DATA)
310 | HEADER_SY(sy);
311 p->header_length = 4;
312 p->payload = payload;
313 p->payload_length = length;
314 p->speed = speed;
315 p->generation = generation;
316 p->ack = 0;
317
318 card->driver->send_request(card, p);
319}
320
321struct transaction_callback_data { 311struct transaction_callback_data {
322 struct completion done; 312 struct completion done;
323 void *payload; 313 void *payload;