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>
17 #include "ieee1394_types.h"
19 #include "ieee1394_core.h"
20 #include "highlevel.h"
23 #define PREP_ASYNC_HEAD_ADDRESS(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) \
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); \
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
,
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
,
67 if (rcode
!= RCODE_COMPLETE
) {
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
,
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
,
116 if (rcode
!= RCODE_COMPLETE
) {
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
,
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
)
164 down(&host
->tlabel_count
);
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
;
175 tlabel
= ffz(host
->tlabel_pool
[1]);
176 host
->tlabel_pool
[1] |= 1 << tlabel
;
180 spin_unlock_irqrestore(&host
->tlabel_lock
, flags
);
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
)
201 spin_lock_irqsave(&host
->tlabel_lock
, flags
);
204 host
->tlabel_pool
[0] &= ~(1 << tlabel
);
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
) {
220 switch ((packet
->header
[1] >> 12) & 0xf) {
223 case RCODE_CONFLICT_ERROR
:
225 case RCODE_DATA_ERROR
:
227 case RCODE_TYPE_ERROR
:
229 case RCODE_ADDRESS_ERROR
:
232 HPSB_ERR("received reserved rcode %d from node %d",
233 (packet
->header
[1] >> 12) & 0xf,
237 HPSB_PANIC("reached unreachable code 1 in " __FUNCTION__
);
248 if (packet
->tcode
== TCODE_WRITEQ
249 || packet
->tcode
== TCODE_WRITEB
) {
252 HPSB_ERR("impossible ack_complete from node %d "
253 "(tcode %d)", packet
->node_id
, packet
->tcode
);
259 if (packet
->tcode
== TCODE_WRITEB
260 || packet
->tcode
== TCODE_LOCK_REQUEST
) {
263 HPSB_ERR("impossible ack_data_error from node %d "
264 "(tcode %d)", packet
->node_id
, packet
->tcode
);
269 case ACKX_SEND_ERROR
:
272 /* error while sending */
276 HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
277 packet
->ack_code
, packet
->node_id
, packet
->tcode
);
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
,
295 struct hpsb_packet
*p
;
297 p
= alloc_hpsb_packet(0);
301 p
->tlabel
= get_tlabel(host
, node
, 1);
303 fill_async_readquad(p
, addr
);
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));
317 p
->tlabel
= get_tlabel(host
, node
, 1);
319 fill_async_readblock(p
, addr
, length
);
324 struct hpsb_packet
*hpsb_make_writeqpacket(struct hpsb_host
*host
,
325 nodeid_t node
, u64 addr
,
328 struct hpsb_packet
*p
;
330 p
= alloc_hpsb_packet(0);
334 p
->tlabel
= get_tlabel(host
, node
, 1);
336 fill_async_writequad(p
, addr
, data
);
341 struct hpsb_packet
*hpsb_make_writebpacket(struct hpsb_host
*host
,
342 nodeid_t node
, u64 addr
,
345 struct hpsb_packet
*p
;
347 p
= alloc_hpsb_packet(length
+ (length
% 4 ? 4 - (length
% 4) : 0));
351 p
->data
[length
/ 4] = 0;
355 p
->tlabel
= get_tlabel(host
, node
, 1);
357 fill_async_writeblock(p
, addr
, length
);
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);
371 p
->tlabel
= get_tlabel(host
, node
, 1);
375 case EXTCODE_FETCH_ADD
:
376 case EXTCODE_LITTLE_ADD
:
377 fill_async_lock(p
, addr
, extcode
, 4);
380 fill_async_lock(p
, addr
, extcode
, 8);
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
;
402 if (host
->node_id
== node
) {
403 switch(highlevel_read(host
, node
, buffer
, addr
, length
)) {
406 case RCODE_TYPE_ERROR
:
408 case RCODE_ADDRESS_ERROR
:
415 packet
= hpsb_make_readqpacket(host
, node
, addr
);
417 packet
= hpsb_make_readbpacket(host
, node
, addr
, length
);
424 hpsb_send_packet(packet
);
425 down(&packet
->state_change
);
426 down(&packet
->state_change
);
427 retval
= hpsb_packet_success(packet
);
431 *buffer
= packet
->header
[3];
433 memcpy(buffer
, packet
->data
, length
);
437 free_tlabel(host
, node
, packet
->tlabel
);
438 free_hpsb_packet(packet
);
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
;
454 if (host
->node_id
== node
) {
455 switch(highlevel_write(host
, node
, buffer
, addr
, length
)) {
458 case RCODE_TYPE_ERROR
:
460 case RCODE_ADDRESS_ERROR
:
467 packet
= hpsb_make_writeqpacket(host
, node
, addr
, *buffer
);
469 packet
= hpsb_make_writebpacket(host
, node
, addr
, length
);
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
);
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
,
504 case RCODE_TYPE_ERROR
:
506 case RCODE_ADDRESS_ERROR
:
512 packet
= alloc_hpsb_packet(8);
518 packet
->tlabel
= get_tlabel(host
, node
, 1);
519 packet
->node_id
= node
;
522 case EXTCODE_MASK_SWAP
:
523 case EXTCODE_COMPARE_SWAP
:
524 case EXTCODE_BOUNDED_ADD
:
525 case EXTCODE_WRAP_ADD
:
527 packet
->data
[0] = arg
;
528 packet
->data
[1] = *data
;
530 case EXTCODE_FETCH_ADD
:
531 case EXTCODE_LITTLE_ADD
:
533 packet
->data
[0] = *data
;
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
);
546 *data
= packet
->data
[0];
549 free_tlabel(host
, node
, packet
->tlabel
);
550 free_hpsb_packet(packet
);