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 static int __get_tlabel(struct hpsb_host
*host
, nodeid_t nodeid
)
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
;
169 tlabel
= ffz(host
->tlabel_pool
[1]);
170 host
->tlabel_pool
[1] |= 1 << tlabel
;
178 int get_tlabel(struct hpsb_host
*host
, nodeid_t nodeid
, int wait
)
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
);
192 init_waitqueue_entry(&wq
, current
);
193 add_wait_queue(&host
->tlabel_wait
, &wq
);
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
);
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
);
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
)
228 spin_lock_irqsave(&host
->tlabel_lock
, flags
);
231 host
->tlabel_pool
[0] &= ~(1 << tlabel
);
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
) {
249 switch ((packet
->header
[1] >> 12) & 0xf) {
252 case RCODE_CONFLICT_ERROR
:
254 case RCODE_DATA_ERROR
:
256 case RCODE_TYPE_ERROR
:
258 case RCODE_ADDRESS_ERROR
:
261 HPSB_ERR("received reserved rcode %d from node %d",
262 (packet
->header
[1] >> 12) & 0xf,
266 HPSB_PANIC("reached unreachable code 1 in " __FUNCTION__
);
277 if (packet
->tcode
== TCODE_WRITEQ
278 || packet
->tcode
== TCODE_WRITEB
) {
281 HPSB_ERR("impossible ack_complete from node %d "
282 "(tcode %d)", packet
->node_id
, packet
->tcode
);
288 if (packet
->tcode
== TCODE_WRITEB
289 || packet
->tcode
== TCODE_LOCK_REQUEST
) {
292 HPSB_ERR("impossible ack_data_error from node %d "
293 "(tcode %d)", packet
->node_id
, packet
->tcode
);
298 case ACKX_SEND_ERROR
:
301 /* error while sending */
305 HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
306 packet
->ack_code
, packet
->node_id
, packet
->tcode
);
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
,
324 struct hpsb_packet
*p
;
326 p
= alloc_hpsb_packet(0);
330 p
->tlabel
= get_tlabel(host
, node
, 1);
332 fill_async_readquad(p
, addr
);
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));
346 p
->tlabel
= get_tlabel(host
, node
, 1);
348 fill_async_readblock(p
, addr
, length
);
353 struct hpsb_packet
*hpsb_make_writeqpacket(struct hpsb_host
*host
,
354 nodeid_t node
, u64 addr
,
357 struct hpsb_packet
*p
;
359 p
= alloc_hpsb_packet(0);
363 p
->tlabel
= get_tlabel(host
, node
, 1);
365 fill_async_writequad(p
, addr
, data
);
370 struct hpsb_packet
*hpsb_make_writebpacket(struct hpsb_host
*host
,
371 nodeid_t node
, u64 addr
,
374 struct hpsb_packet
*p
;
376 p
= alloc_hpsb_packet(length
+ (length
% 4 ? 4 - (length
% 4) : 0));
380 p
->data
[length
/ 4] = 0;
384 p
->tlabel
= get_tlabel(host
, node
, 1);
386 fill_async_writeblock(p
, addr
, length
);
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);
400 p
->tlabel
= get_tlabel(host
, node
, 1);
404 case EXTCODE_FETCH_ADD
:
405 case EXTCODE_LITTLE_ADD
:
406 fill_async_lock(p
, addr
, extcode
, 4);
409 fill_async_lock(p
, addr
, extcode
, 8);
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
;
431 if (host
->node_id
== node
) {
432 switch(highlevel_read(host
, node
, buffer
, addr
, length
)) {
435 case RCODE_TYPE_ERROR
:
437 case RCODE_ADDRESS_ERROR
:
444 packet
= hpsb_make_readqpacket(host
, node
, addr
);
446 packet
= hpsb_make_readbpacket(host
, node
, addr
, length
);
453 hpsb_send_packet(packet
);
454 down(&packet
->state_change
);
455 down(&packet
->state_change
);
456 retval
= hpsb_packet_success(packet
);
460 *buffer
= packet
->header
[3];
462 memcpy(buffer
, packet
->data
, length
);
466 free_tlabel(host
, node
, packet
->tlabel
);
467 free_hpsb_packet(packet
);
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
;
483 if (host
->node_id
== node
) {
484 switch(highlevel_write(host
, node
, buffer
, addr
, length
)) {
487 case RCODE_TYPE_ERROR
:
489 case RCODE_ADDRESS_ERROR
:
496 packet
= hpsb_make_writeqpacket(host
, node
, addr
, *buffer
);
498 packet
= hpsb_make_writebpacket(host
, node
, addr
, length
);
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
);
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
,
533 case RCODE_TYPE_ERROR
:
535 case RCODE_ADDRESS_ERROR
:
541 packet
= alloc_hpsb_packet(8);
547 packet
->tlabel
= get_tlabel(host
, node
, 1);
548 packet
->node_id
= node
;
551 case EXTCODE_MASK_SWAP
:
552 case EXTCODE_COMPARE_SWAP
:
553 case EXTCODE_BOUNDED_ADD
:
554 case EXTCODE_WRAP_ADD
:
556 packet
->data
[0] = arg
;
557 packet
->data
[1] = *data
;
559 case EXTCODE_FETCH_ADD
:
560 case EXTCODE_LITTLE_ADD
:
562 packet
->data
[0] = *data
;
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
);
575 *data
= packet
->data
[0];
578 free_tlabel(host
, node
, packet
->tlabel
);
579 free_hpsb_packet(packet
);