This is pre8 ...
[linux-2.6/linux-mips.git] / drivers / ieee1394 / ieee1394_transactions.c
blob179834ac726fcc476c96f589ef1ccd72a4c6c77f
1 /*
2 * IEEE 1394 for Linux
4 * Transaction support.
6 * Copyright (C) 1999 Andreas E. Bombe
8 * This code is licensed under the GPL. See the file COPYING in the root
9 * directory of the kernel sources for details.
12 #include <linux/sched.h>
13 #include <asm/errno.h>
14 #include <asm/bitops.h>
16 #include "ieee1394.h"
17 #include "ieee1394_types.h"
18 #include "hosts.h"
19 #include "ieee1394_core.h"
20 #include "highlevel.h"
23 #define PREP_ASYNC_HEAD_ADDRESS(tc) \
24 packet->tcode = tc; \
25 packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
26 | (1 << 8) | (tc << 4); \
27 packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
28 packet->header[2] = addr & 0xffffffff
30 #define PREP_ASYNC_HEAD_RCODE(tc) \
31 packet->tcode = tc; \
32 packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
33 | (1 << 8) | (tc << 4); \
34 packet->header[1] = (packet->host->node_id << 16) | (rcode << 12); \
35 packet->header[2] = 0
38 void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
40 PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
41 packet->header_size = 12;
42 packet->data_size = 0;
43 packet->expect_response = 1;
46 void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
47 quadlet_t data)
49 PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
50 packet->header[3] = data;
51 packet->header_size = 16;
52 packet->data_size = 0;
55 void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length)
57 PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
58 packet->header[3] = length << 16;
59 packet->header_size = 16;
60 packet->data_size = 0;
61 packet->expect_response = 1;
64 void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
65 int length)
67 if (rcode != RCODE_COMPLETE) {
68 length = 0;
71 PREP_ASYNC_HEAD_RCODE(TCODE_READB_RESPONSE);
72 packet->header[3] = length << 16;
73 packet->header_size = 16;
74 packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
77 void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data)
79 PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
80 packet->header[3] = data;
81 packet->header_size = 16;
82 packet->data_size = 0;
83 packet->expect_response = 1;
86 void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length)
88 PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
89 packet->header[3] = length << 16;
90 packet->header_size = 16;
91 packet->expect_response = 1;
92 packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
95 void fill_async_write_resp(struct hpsb_packet *packet, int rcode)
97 PREP_ASYNC_HEAD_RCODE(TCODE_WRITE_RESPONSE);
98 packet->header[2] = 0;
99 packet->header_size = 12;
100 packet->data_size = 0;
103 void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
104 int length)
106 PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
107 packet->header[3] = (length << 16) | extcode;
108 packet->header_size = 16;
109 packet->data_size = length;
110 packet->expect_response = 1;
113 void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
114 int length)
116 if (rcode != RCODE_COMPLETE) {
117 length = 0;
120 PREP_ASYNC_HEAD_RCODE(TCODE_LOCK_RESPONSE);
121 packet->header[3] = (length << 16) | extcode;
122 packet->header_size = 16;
123 packet->data_size = length;
126 void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
127 int tag, int sync)
129 packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
130 | (TCODE_ISO_DATA << 4) | sync;
132 packet->header_size = 4;
133 packet->data_size = length;
134 packet->tcode = TCODE_ISO_DATA;
139 * get_tlabel - allocate a transaction label
140 * @host: host to be used for transmission
141 * @nodeid: the node ID of the transmission target
142 * @wait: whether to sleep if no tlabel is available
144 * Every asynchronous transaction on the 1394 bus needs a transaction label to
145 * match the response to the request. This label has to be different from any
146 * other transaction label in an outstanding request to the same node to make
147 * matching possible without ambiguity.
149 * There are 64 different tlabels, so an allocated tlabel has to be freed with
150 * free_tlabel() after the transaction is complete (unless it's reused again for
151 * the same target node).
153 * @wait must not be set to true if you are calling from interrupt context.
155 * Return value: The allocated transaction label or -1 if there was no free
156 * tlabel and @wait is false.
158 static int __get_tlabel(struct hpsb_host *host, nodeid_t nodeid)
160 int tlabel;
162 if (host->tlabel_count) {
163 host->tlabel_count--;
165 if (host->tlabel_pool[0] != ~0) {
166 tlabel = ffz(host->tlabel_pool[0]);
167 host->tlabel_pool[0] |= 1 << tlabel;
168 } else {
169 tlabel = ffz(host->tlabel_pool[1]);
170 host->tlabel_pool[1] |= 1 << tlabel;
171 tlabel += 32;
173 return tlabel;
175 return -1;
178 int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
180 unsigned long flags;
181 int tlabel;
182 wait_queue_t wq;
184 spin_lock_irqsave(&host->tlabel_lock, flags);
186 tlabel = __get_tlabel(host, nodeid);
187 if (tlabel != -1 || !wait) {
188 spin_unlock_irqrestore(&host->tlabel_lock, flags);
189 return tlabel;
192 init_waitqueue_entry(&wq, current);
193 add_wait_queue(&host->tlabel_wait, &wq);
195 for (;;) {
196 set_current_state(TASK_UNINTERRUPTIBLE);
197 tlabel = __get_tlabel(host, nodeid);
198 if (tlabel != -1) break;
200 spin_unlock_irqrestore(&host->tlabel_lock, flags);
201 schedule();
202 spin_lock_irqsave(&host->tlabel_lock, flags);
205 spin_unlock_irqrestore(&host->tlabel_lock, flags);
206 set_current_state(TASK_RUNNING);
207 remove_wait_queue(&host->tlabel_wait, &wq);
209 return tlabel;
213 * free_tlabel - free an allocated transaction label
214 * @host: host to be used for transmission
215 * @nodeid: the node ID of the transmission target
216 * @tlabel: the transaction label to free
218 * Frees the transaction label allocated with get_tlabel(). The tlabel has to
219 * be freed after the transaction is complete (i.e. response was received for a
220 * split transaction or packet was sent for a unified transaction).
222 * A tlabel must not be freed twice.
224 void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel)
226 unsigned long flags;
228 spin_lock_irqsave(&host->tlabel_lock, flags);
230 if (tlabel < 32) {
231 host->tlabel_pool[0] &= ~(1 << tlabel);
232 } else {
233 host->tlabel_pool[1] &= ~(1 << (tlabel-32));
236 host->tlabel_count++;
238 spin_unlock_irqrestore(&host->tlabel_lock, flags);
240 wake_up(&host->tlabel_wait);
245 int hpsb_packet_success(struct hpsb_packet *packet)
247 switch (packet->ack_code) {
248 case ACK_PENDING:
249 switch ((packet->header[1] >> 12) & 0xf) {
250 case RCODE_COMPLETE:
251 return 0;
252 case RCODE_CONFLICT_ERROR:
253 return -EAGAIN;
254 case RCODE_DATA_ERROR:
255 return -EREMOTEIO;
256 case RCODE_TYPE_ERROR:
257 return -EACCES;
258 case RCODE_ADDRESS_ERROR:
259 return -EINVAL;
260 default:
261 HPSB_ERR("received reserved rcode %d from node %d",
262 (packet->header[1] >> 12) & 0xf,
263 packet->node_id);
264 return -EAGAIN;
266 HPSB_PANIC("reached unreachable code 1 in " __FUNCTION__);
268 case ACK_BUSY_X:
269 case ACK_BUSY_A:
270 case ACK_BUSY_B:
271 return -EBUSY;
273 case ACK_TYPE_ERROR:
274 return -EACCES;
276 case ACK_COMPLETE:
277 if (packet->tcode == TCODE_WRITEQ
278 || packet->tcode == TCODE_WRITEB) {
279 return 0;
280 } else {
281 HPSB_ERR("impossible ack_complete from node %d "
282 "(tcode %d)", packet->node_id, packet->tcode);
283 return -EAGAIN;
287 case ACK_DATA_ERROR:
288 if (packet->tcode == TCODE_WRITEB
289 || packet->tcode == TCODE_LOCK_REQUEST) {
290 return -EAGAIN;
291 } else {
292 HPSB_ERR("impossible ack_data_error from node %d "
293 "(tcode %d)", packet->node_id, packet->tcode);
294 return -EAGAIN;
297 case ACKX_NONE:
298 case ACKX_SEND_ERROR:
299 case ACKX_ABORTED:
300 case ACKX_TIMEOUT:
301 /* error while sending */
302 return -EAGAIN;
304 default:
305 HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
306 packet->ack_code, packet->node_id, packet->tcode);
307 return -EAGAIN;
310 HPSB_PANIC("reached unreachable code 2 in " __FUNCTION__);
314 int hpsb_read_trylocal(struct hpsb_host *host, nodeid_t node, u64 addr,
315 quadlet_t *buffer, size_t length)
317 if (host->node_id != node) return -1;
318 return highlevel_read(host, node, buffer, addr, length);
321 struct hpsb_packet *hpsb_make_readqpacket(struct hpsb_host *host, nodeid_t node,
322 u64 addr)
324 struct hpsb_packet *p;
326 p = alloc_hpsb_packet(0);
327 if (!p) return NULL;
329 p->host = host;
330 p->tlabel = get_tlabel(host, node, 1);
331 p->node_id = node;
332 fill_async_readquad(p, addr);
334 return p;
337 struct hpsb_packet *hpsb_make_readbpacket(struct hpsb_host *host, nodeid_t node,
338 u64 addr, size_t length)
340 struct hpsb_packet *p;
342 p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
343 if (!p) return NULL;
345 p->host = host;
346 p->tlabel = get_tlabel(host, node, 1);
347 p->node_id = node;
348 fill_async_readblock(p, addr, length);
350 return p;
353 struct hpsb_packet *hpsb_make_writeqpacket(struct hpsb_host *host,
354 nodeid_t node, u64 addr,
355 quadlet_t data)
357 struct hpsb_packet *p;
359 p = alloc_hpsb_packet(0);
360 if (!p) return NULL;
362 p->host = host;
363 p->tlabel = get_tlabel(host, node, 1);
364 p->node_id = node;
365 fill_async_writequad(p, addr, data);
367 return p;
370 struct hpsb_packet *hpsb_make_writebpacket(struct hpsb_host *host,
371 nodeid_t node, u64 addr,
372 size_t length)
374 struct hpsb_packet *p;
376 p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
377 if (!p) return NULL;
379 if (length % 4) {
380 p->data[length / 4] = 0;
383 p->host = host;
384 p->tlabel = get_tlabel(host, node, 1);
385 p->node_id = node;
386 fill_async_writeblock(p, addr, length);
388 return p;
391 struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
392 u64 addr, int extcode)
394 struct hpsb_packet *p;
396 p = alloc_hpsb_packet(8);
397 if (!p) return NULL;
399 p->host = host;
400 p->tlabel = get_tlabel(host, node, 1);
401 p->node_id = node;
403 switch (extcode) {
404 case EXTCODE_FETCH_ADD:
405 case EXTCODE_LITTLE_ADD:
406 fill_async_lock(p, addr, extcode, 4);
407 break;
408 default:
409 fill_async_lock(p, addr, extcode, 8);
410 break;
413 return p;
417 * FIXME - these functions should probably read from / write to user space to
418 * avoid in kernel buffers for user space callers
421 int hpsb_read(struct hpsb_host *host, nodeid_t node, u64 addr,
422 quadlet_t *buffer, size_t length)
424 struct hpsb_packet *packet;
425 int retval = 0;
427 if (length == 0) {
428 return -EINVAL;
431 if (host->node_id == node) {
432 switch(highlevel_read(host, node, buffer, addr, length)) {
433 case RCODE_COMPLETE:
434 return 0;
435 case RCODE_TYPE_ERROR:
436 return -EACCES;
437 case RCODE_ADDRESS_ERROR:
438 default:
439 return -EINVAL;
443 if (length == 4) {
444 packet = hpsb_make_readqpacket(host, node, addr);
445 } else {
446 packet = hpsb_make_readbpacket(host, node, addr, length);
449 if (!packet) {
450 return -ENOMEM;
453 hpsb_send_packet(packet);
454 down(&packet->state_change);
455 down(&packet->state_change);
456 retval = hpsb_packet_success(packet);
458 if (retval == 0) {
459 if (length == 4) {
460 *buffer = packet->header[3];
461 } else {
462 memcpy(buffer, packet->data, length);
466 free_tlabel(host, node, packet->tlabel);
467 free_hpsb_packet(packet);
469 return retval;
473 int hpsb_write(struct hpsb_host *host, nodeid_t node, u64 addr,
474 quadlet_t *buffer, size_t length)
476 struct hpsb_packet *packet;
477 int retval = 0;
479 if (length == 0) {
480 return -EINVAL;
483 if (host->node_id == node) {
484 switch(highlevel_write(host, node, buffer, addr, length)) {
485 case RCODE_COMPLETE:
486 return 0;
487 case RCODE_TYPE_ERROR:
488 return -EACCES;
489 case RCODE_ADDRESS_ERROR:
490 default:
491 return -EINVAL;
495 if (length == 4) {
496 packet = hpsb_make_writeqpacket(host, node, addr, *buffer);
497 } else {
498 packet = hpsb_make_writebpacket(host, node, addr, length);
501 if (!packet) {
502 return -ENOMEM;
505 if (length != 4) {
506 memcpy(packet->data, buffer, length);
509 hpsb_send_packet(packet);
510 down(&packet->state_change);
511 down(&packet->state_change);
512 retval = hpsb_packet_success(packet);
514 free_tlabel(host, node, packet->tlabel);
515 free_hpsb_packet(packet);
517 return retval;
521 /* We need a hpsb_lock64 function for the 64 bit equivalent. Probably. */
522 int hpsb_lock(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode,
523 quadlet_t *data, quadlet_t arg)
525 struct hpsb_packet *packet;
526 int retval = 0, length;
528 if (host->node_id == node) {
529 switch(highlevel_lock(host, node, data, addr, *data, arg,
530 extcode)) {
531 case RCODE_COMPLETE:
532 return 0;
533 case RCODE_TYPE_ERROR:
534 return -EACCES;
535 case RCODE_ADDRESS_ERROR:
536 default:
537 return -EINVAL;
541 packet = alloc_hpsb_packet(8);
542 if (!packet) {
543 return -ENOMEM;
546 packet->host = host;
547 packet->tlabel = get_tlabel(host, node, 1);
548 packet->node_id = node;
550 switch (extcode) {
551 case EXTCODE_MASK_SWAP:
552 case EXTCODE_COMPARE_SWAP:
553 case EXTCODE_BOUNDED_ADD:
554 case EXTCODE_WRAP_ADD:
555 length = 8;
556 packet->data[0] = arg;
557 packet->data[1] = *data;
558 break;
559 case EXTCODE_FETCH_ADD:
560 case EXTCODE_LITTLE_ADD:
561 length = 4;
562 packet->data[0] = *data;
563 break;
564 default:
565 return -EINVAL;
567 fill_async_lock(packet, addr, extcode, length);
569 hpsb_send_packet(packet);
570 down(&packet->state_change);
571 down(&packet->state_change);
572 retval = hpsb_packet_success(packet);
574 if (retval == 0) {
575 *data = packet->data[0];
578 free_tlabel(host, node, packet->tlabel);
579 free_hpsb_packet(packet);
581 return retval;