- Kai Germaschewski: ymfpci cleanups and resource leak fixes
[davej-history.git] / drivers / ieee1394 / ieee1394_transactions.c
bloba87058b61fbdbd3d5f605f7cfd53b01dc0c2b584
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 int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
160 int tlabel;
161 unsigned long flags;
163 if (wait) {
164 down(&host->tlabel_count);
165 } else {
166 if (down_trylock(&host->tlabel_count)) return -1;
169 spin_lock_irqsave(&host->tlabel_lock, flags);
171 if (host->tlabel_pool[0] != ~0) {
172 tlabel = ffz(host->tlabel_pool[0]);
173 host->tlabel_pool[0] |= 1 << tlabel;
174 } else {
175 tlabel = ffz(host->tlabel_pool[1]);
176 host->tlabel_pool[1] |= 1 << tlabel;
177 tlabel += 32;
180 spin_unlock_irqrestore(&host->tlabel_lock, flags);
182 return tlabel;
186 * free_tlabel - free an allocated transaction label
187 * @host: host to be used for transmission
188 * @nodeid: the node ID of the transmission target
189 * @tlabel: the transaction label to free
191 * Frees the transaction label allocated with get_tlabel(). The tlabel has to
192 * be freed after the transaction is complete (i.e. response was received for a
193 * split transaction or packet was sent for a unified transaction).
195 * A tlabel must not be freed twice.
197 void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel)
199 unsigned long flags;
201 spin_lock_irqsave(&host->tlabel_lock, flags);
203 if (tlabel < 32) {
204 host->tlabel_pool[0] &= ~(1 << tlabel);
205 } else {
206 host->tlabel_pool[1] &= ~(1 << (tlabel-32));
209 spin_unlock_irqrestore(&host->tlabel_lock, flags);
211 up(&host->tlabel_count);
216 int hpsb_packet_success(struct hpsb_packet *packet)
218 switch (packet->ack_code) {
219 case ACK_PENDING:
220 switch ((packet->header[1] >> 12) & 0xf) {
221 case RCODE_COMPLETE:
222 return 0;
223 case RCODE_CONFLICT_ERROR:
224 return -EAGAIN;
225 case RCODE_DATA_ERROR:
226 return -EREMOTEIO;
227 case RCODE_TYPE_ERROR:
228 return -EACCES;
229 case RCODE_ADDRESS_ERROR:
230 return -EINVAL;
231 default:
232 HPSB_ERR("received reserved rcode %d from node %d",
233 (packet->header[1] >> 12) & 0xf,
234 packet->node_id);
235 return -EAGAIN;
237 HPSB_PANIC("reached unreachable code 1 in " __FUNCTION__);
239 case ACK_BUSY_X:
240 case ACK_BUSY_A:
241 case ACK_BUSY_B:
242 return -EBUSY;
244 case ACK_TYPE_ERROR:
245 return -EACCES;
247 case ACK_COMPLETE:
248 if (packet->tcode == TCODE_WRITEQ
249 || packet->tcode == TCODE_WRITEB) {
250 return 0;
251 } else {
252 HPSB_ERR("impossible ack_complete from node %d "
253 "(tcode %d)", packet->node_id, packet->tcode);
254 return -EAGAIN;
258 case ACK_DATA_ERROR:
259 if (packet->tcode == TCODE_WRITEB
260 || packet->tcode == TCODE_LOCK_REQUEST) {
261 return -EAGAIN;
262 } else {
263 HPSB_ERR("impossible ack_data_error from node %d "
264 "(tcode %d)", packet->node_id, packet->tcode);
265 return -EAGAIN;
268 case ACKX_NONE:
269 case ACKX_SEND_ERROR:
270 case ACKX_ABORTED:
271 case ACKX_TIMEOUT:
272 /* error while sending */
273 return -EAGAIN;
275 default:
276 HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
277 packet->ack_code, packet->node_id, packet->tcode);
278 return -EAGAIN;
281 HPSB_PANIC("reached unreachable code 2 in " __FUNCTION__);
285 int hpsb_read_trylocal(struct hpsb_host *host, nodeid_t node, u64 addr,
286 quadlet_t *buffer, size_t length)
288 if (host->node_id != node) return -1;
289 return highlevel_read(host, node, buffer, addr, length);
292 struct hpsb_packet *hpsb_make_readqpacket(struct hpsb_host *host, nodeid_t node,
293 u64 addr)
295 struct hpsb_packet *p;
297 p = alloc_hpsb_packet(0);
298 if (!p) return NULL;
300 p->host = host;
301 p->tlabel = get_tlabel(host, node, 1);
302 p->node_id = node;
303 fill_async_readquad(p, addr);
305 return p;
308 struct hpsb_packet *hpsb_make_readbpacket(struct hpsb_host *host, nodeid_t node,
309 u64 addr, size_t length)
311 struct hpsb_packet *p;
313 p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
314 if (!p) return NULL;
316 p->host = host;
317 p->tlabel = get_tlabel(host, node, 1);
318 p->node_id = node;
319 fill_async_readblock(p, addr, length);
321 return p;
324 struct hpsb_packet *hpsb_make_writeqpacket(struct hpsb_host *host,
325 nodeid_t node, u64 addr,
326 quadlet_t data)
328 struct hpsb_packet *p;
330 p = alloc_hpsb_packet(0);
331 if (!p) return NULL;
333 p->host = host;
334 p->tlabel = get_tlabel(host, node, 1);
335 p->node_id = node;
336 fill_async_writequad(p, addr, data);
338 return p;
341 struct hpsb_packet *hpsb_make_writebpacket(struct hpsb_host *host,
342 nodeid_t node, u64 addr,
343 size_t length)
345 struct hpsb_packet *p;
347 p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
348 if (!p) return NULL;
350 if (length % 4) {
351 p->data[length / 4] = 0;
354 p->host = host;
355 p->tlabel = get_tlabel(host, node, 1);
356 p->node_id = node;
357 fill_async_writeblock(p, addr, length);
359 return p;
362 struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
363 u64 addr, int extcode)
365 struct hpsb_packet *p;
367 p = alloc_hpsb_packet(8);
368 if (!p) return NULL;
370 p->host = host;
371 p->tlabel = get_tlabel(host, node, 1);
372 p->node_id = node;
374 switch (extcode) {
375 case EXTCODE_FETCH_ADD:
376 case EXTCODE_LITTLE_ADD:
377 fill_async_lock(p, addr, extcode, 4);
378 break;
379 default:
380 fill_async_lock(p, addr, extcode, 8);
381 break;
384 return p;
388 * FIXME - these functions should probably read from / write to user space to
389 * avoid in kernel buffers for user space callers
392 int hpsb_read(struct hpsb_host *host, nodeid_t node, u64 addr,
393 quadlet_t *buffer, size_t length)
395 struct hpsb_packet *packet;
396 int retval = 0;
398 if (length == 0) {
399 return -EINVAL;
402 if (host->node_id == node) {
403 switch(highlevel_read(host, node, buffer, addr, length)) {
404 case RCODE_COMPLETE:
405 return 0;
406 case RCODE_TYPE_ERROR:
407 return -EACCES;
408 case RCODE_ADDRESS_ERROR:
409 default:
410 return -EINVAL;
414 if (length == 4) {
415 packet = hpsb_make_readqpacket(host, node, addr);
416 } else {
417 packet = hpsb_make_readbpacket(host, node, addr, length);
420 if (!packet) {
421 return -ENOMEM;
424 hpsb_send_packet(packet);
425 down(&packet->state_change);
426 down(&packet->state_change);
427 retval = hpsb_packet_success(packet);
429 if (retval == 0) {
430 if (length == 4) {
431 *buffer = packet->header[3];
432 } else {
433 memcpy(buffer, packet->data, length);
437 free_tlabel(host, node, packet->tlabel);
438 free_hpsb_packet(packet);
440 return retval;
444 int hpsb_write(struct hpsb_host *host, nodeid_t node, u64 addr,
445 quadlet_t *buffer, size_t length)
447 struct hpsb_packet *packet;
448 int retval = 0;
450 if (length == 0) {
451 return -EINVAL;
454 if (host->node_id == node) {
455 switch(highlevel_write(host, node, buffer, addr, length)) {
456 case RCODE_COMPLETE:
457 return 0;
458 case RCODE_TYPE_ERROR:
459 return -EACCES;
460 case RCODE_ADDRESS_ERROR:
461 default:
462 return -EINVAL;
466 if (length == 4) {
467 packet = hpsb_make_writeqpacket(host, node, addr, *buffer);
468 } else {
469 packet = hpsb_make_writebpacket(host, node, addr, length);
472 if (!packet) {
473 return -ENOMEM;
476 if (length != 4) {
477 memcpy(packet->data, buffer, length);
480 hpsb_send_packet(packet);
481 down(&packet->state_change);
482 down(&packet->state_change);
483 retval = hpsb_packet_success(packet);
485 free_tlabel(host, node, packet->tlabel);
486 free_hpsb_packet(packet);
488 return retval;
492 /* We need a hpsb_lock64 function for the 64 bit equivalent. Probably. */
493 int hpsb_lock(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode,
494 quadlet_t *data, quadlet_t arg)
496 struct hpsb_packet *packet;
497 int retval = 0, length;
499 if (host->node_id == node) {
500 switch(highlevel_lock(host, node, data, addr, *data, arg,
501 extcode)) {
502 case RCODE_COMPLETE:
503 return 0;
504 case RCODE_TYPE_ERROR:
505 return -EACCES;
506 case RCODE_ADDRESS_ERROR:
507 default:
508 return -EINVAL;
512 packet = alloc_hpsb_packet(8);
513 if (!packet) {
514 return -ENOMEM;
517 packet->host = host;
518 packet->tlabel = get_tlabel(host, node, 1);
519 packet->node_id = node;
521 switch (extcode) {
522 case EXTCODE_MASK_SWAP:
523 case EXTCODE_COMPARE_SWAP:
524 case EXTCODE_BOUNDED_ADD:
525 case EXTCODE_WRAP_ADD:
526 length = 8;
527 packet->data[0] = arg;
528 packet->data[1] = *data;
529 break;
530 case EXTCODE_FETCH_ADD:
531 case EXTCODE_LITTLE_ADD:
532 length = 4;
533 packet->data[0] = *data;
534 break;
535 default:
536 return -EINVAL;
538 fill_async_lock(packet, addr, extcode, length);
540 hpsb_send_packet(packet);
541 down(&packet->state_change);
542 down(&packet->state_change);
543 retval = hpsb_packet_success(packet);
545 if (retval == 0) {
546 *data = packet->data[0];
549 free_tlabel(host, node, packet->tlabel);
550 free_hpsb_packet(packet);
552 return retval;