1/*
2 * IEEE 1394 for Linux
3 *
4 * Transaction support.
5 *
6 * Copyright (C) 1999 Andreas E. Bombe
7 *
8 * This code is licensed under the GPL.  See the file COPYING in the root
9 * directory of the kernel sources for details.
10 */
11
12#include <linux/sched.h>
13#include <asm/errno.h>
14#include <asm/bitops.h>
15
16#include "ieee1394.h"
17#include "ieee1394_types.h"
18#include "hosts.h"
19#include "ieee1394_core.h"
20#include "highlevel.h"
21
22
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
29
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
36
37
38void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
39{
40        PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
41        packet->header_size = 12;
42        packet->data_size = 0;
43        packet->expect_response = 1;
44}
45
46void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
47                              quadlet_t data)
48{
49        PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
50        packet->header[3] = data;
51        packet->header_size = 16;
52        packet->data_size = 0;
53}
54
55void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length)
56{
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;
62}
63
64void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
65                               int length)
66{
67        if (rcode != RCODE_COMPLETE) {
68                length = 0;
69        }
70
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);
75}
76
77void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data)
78{
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;
84}
85
86void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length)
87{
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);
93}
94
95void fill_async_write_resp(struct hpsb_packet *packet, int rcode)
96{
97        PREP_ASYNC_HEAD_RCODE(TCODE_WRITE_RESPONSE);
98        packet->header[2] = 0;
99        packet->header_size = 12;
100        packet->data_size = 0;
101}
102
103void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
104                     int length)
105{
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;
111}
112
113void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
114                          int length)
115{
116        if (rcode != RCODE_COMPLETE) {
117                length = 0;
118        }
119
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;
124}
125
126void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
127                     int tag, int sync)
128{
129        packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
130                | (TCODE_ISO_DATA << 4) | sync;
131
132        packet->header_size = 4;
133        packet->data_size = length;
134        packet->type = hpsb_iso;
135        packet->tcode = TCODE_ISO_DATA;
136}
137
138void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
139{
140        packet->header[0] = data;
141        packet->header[1] = ~data;
142        packet->header_size = 8;
143        packet->data_size = 0;
144        packet->expect_response = 0;
145        packet->type = hpsb_raw;             /* No CRC added */
146        packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */
147}
148
149
150/**
151 * get_tlabel - allocate a transaction label
152 * @host: host to be used for transmission
153 * @nodeid: the node ID of the transmission target
154 * @wait: whether to sleep if no tlabel is available
155 *
156 * Every asynchronous transaction on the 1394 bus needs a transaction label to
157 * match the response to the request.  This label has to be different from any
158 * other transaction label in an outstanding request to the same node to make
159 * matching possible without ambiguity.
160 *
161 * There are 64 different tlabels, so an allocated tlabel has to be freed with
162 * free_tlabel() after the transaction is complete (unless it's reused again for
163 * the same target node).
164 *
165 * @wait must not be set to true if you are calling from interrupt context.
166 *
167 * Return value: The allocated transaction label or -1 if there was no free
168 * tlabel and @wait is false.
169 */
170int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
171{
172	int tlabel = 0;
173	unsigned long flags;
174	int found_tlabel = 0;
175
176	if (wait) {
177		down(&host->tlabel_count);
178	} else {
179		if (down_trylock(&host->tlabel_count)) return -1;
180	}
181
182	spin_lock_irqsave(&host->tlabel_lock, flags);
183
184	while (!found_tlabel) {
185		tlabel = host->tlabel_current;
186		if (tlabel < 32 && !(host->tlabel_pool[0] & 1 << tlabel)) {
187			host->tlabel_pool[0] |= 1 << tlabel;
188			found_tlabel = 1;
189		} else if (!(host->tlabel_pool[1] & 1 << (tlabel - 32))) {
190			host->tlabel_pool[1] |= 1 << (tlabel - 32);
191			found_tlabel = 1;
192		}
193		host->tlabel_current = (host->tlabel_current + 1) % 64;
194	}
195
196	spin_unlock_irqrestore(&host->tlabel_lock, flags);
197
198	return tlabel;
199}
200
201/**
202 * free_tlabel - free an allocated transaction label
203 * @host: host to be used for transmission
204 * @nodeid: the node ID of the transmission target
205 * @tlabel: the transaction label to free
206 *
207 * Frees the transaction label allocated with get_tlabel().  The tlabel has to
208 * be freed after the transaction is complete (i.e. response was received for a
209 * split transaction or packet was sent for a unified transaction).
210 *
211 * A tlabel must not be freed twice.
212 */
213void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel)
214{
215        unsigned long flags;
216
217        spin_lock_irqsave(&host->tlabel_lock, flags);
218
219        if (tlabel < 32) {
220                host->tlabel_pool[0] &= ~(1 << tlabel);
221        } else {
222                host->tlabel_pool[1] &= ~(1 << (tlabel-32));
223        }
224
225        spin_unlock_irqrestore(&host->tlabel_lock, flags);
226
227        up(&host->tlabel_count);
228}
229
230
231
232int hpsb_packet_success(struct hpsb_packet *packet)
233{
234        switch (packet->ack_code) {
235        case ACK_PENDING:
236                switch ((packet->header[1] >> 12) & 0xf) {
237                case RCODE_COMPLETE:
238                        return 0;
239                case RCODE_CONFLICT_ERROR:
240                        return -EAGAIN;
241                case RCODE_DATA_ERROR:
242                        return -EREMOTEIO;
243                case RCODE_TYPE_ERROR:
244                        return -EACCES;
245                case RCODE_ADDRESS_ERROR:
246                        return -EINVAL;
247                default:
248                        HPSB_ERR("received reserved rcode %d from node %d",
249                                 (packet->header[1] >> 12) & 0xf,
250                                 packet->node_id);
251                        return -EAGAIN;
252                }
253                HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
254
255        case ACK_BUSY_X:
256        case ACK_BUSY_A:
257        case ACK_BUSY_B:
258                return -EBUSY;
259
260        case ACK_TYPE_ERROR:
261                return -EACCES;
262
263        case ACK_COMPLETE:
264                if (packet->tcode == TCODE_WRITEQ
265                    || packet->tcode == TCODE_WRITEB) {
266                        return 0;
267                } else {
268                        HPSB_ERR("impossible ack_complete from node %d "
269                                 "(tcode %d)", packet->node_id, packet->tcode);
270                        return -EAGAIN;
271                }
272
273
274        case ACK_DATA_ERROR:
275                if (packet->tcode == TCODE_WRITEB
276                    || packet->tcode == TCODE_LOCK_REQUEST) {
277                        return -EAGAIN;
278                } else {
279                        HPSB_ERR("impossible ack_data_error from node %d "
280                                 "(tcode %d)", packet->node_id, packet->tcode);
281                        return -EAGAIN;
282                }
283
284        case ACKX_NONE:
285        case ACKX_SEND_ERROR:
286        case ACKX_ABORTED:
287        case ACKX_TIMEOUT:
288                /* error while sending */
289                return -EAGAIN;
290
291        default:
292                HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
293                         packet->ack_code, packet->node_id, packet->tcode);
294                return -EAGAIN;
295        }
296
297        HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
298}
299
300
301int hpsb_read_trylocal(struct hpsb_host *host, nodeid_t node, u64 addr,
302                       quadlet_t *buffer, size_t length)
303{
304        if (host->node_id != node) return -1;
305        return highlevel_read(host, node, buffer, addr, length);
306}
307
308struct hpsb_packet *hpsb_make_readqpacket(struct hpsb_host *host, nodeid_t node,
309                                          u64 addr)
310{
311        struct hpsb_packet *p;
312
313        p = alloc_hpsb_packet(0);
314        if (!p) return NULL;
315
316        p->host = host;
317        p->tlabel = get_tlabel(host, node, 1);
318        p->node_id = node;
319        fill_async_readquad(p, addr);
320
321        return p;
322}
323
324struct hpsb_packet *hpsb_make_readbpacket(struct hpsb_host *host, nodeid_t node,
325                                          u64 addr, size_t length)
326{
327        struct hpsb_packet *p;
328
329        p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
330        if (!p) return NULL;
331
332        p->host = host;
333        p->tlabel = get_tlabel(host, node, 1);
334        p->node_id = node;
335        fill_async_readblock(p, addr, length);
336
337        return p;
338}
339
340struct hpsb_packet *hpsb_make_writeqpacket(struct hpsb_host *host,
341                                           nodeid_t node, u64 addr,
342                                           quadlet_t data)
343{
344        struct hpsb_packet *p;
345
346        p = alloc_hpsb_packet(0);
347        if (!p) return NULL;
348
349        p->host = host;
350        p->tlabel = get_tlabel(host, node, 1);
351        p->node_id = node;
352        fill_async_writequad(p, addr, data);
353
354        return p;
355}
356
357struct hpsb_packet *hpsb_make_writebpacket(struct hpsb_host *host,
358                                           nodeid_t node, u64 addr,
359                                           size_t length)
360{
361        struct hpsb_packet *p;
362
363        p = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
364        if (!p) return NULL;
365
366        if (length % 4) {
367                p->data[length / 4] = 0;
368        }
369
370        p->host = host;
371        p->tlabel = get_tlabel(host, node, 1);
372        p->node_id = node;
373        fill_async_writeblock(p, addr, length);
374
375        return p;
376}
377
378struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
379                                         u64 addr, int extcode)
380{
381        struct hpsb_packet *p;
382
383        p = alloc_hpsb_packet(8);
384        if (!p) return NULL;
385
386        p->host = host;
387        p->tlabel = get_tlabel(host, node, 1);
388        p->node_id = node;
389
390        switch (extcode) {
391        case EXTCODE_FETCH_ADD:
392        case EXTCODE_LITTLE_ADD:
393                fill_async_lock(p, addr, extcode, 4);
394                break;
395        default:
396                fill_async_lock(p, addr, extcode, 8);
397                break;
398        }
399
400        return p;
401}
402
403struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
404                                        quadlet_t data)
405{
406        struct hpsb_packet *p;
407
408        p = alloc_hpsb_packet(0);
409        if (!p) return NULL;
410
411        p->host = host;
412        fill_phy_packet(p, data);
413
414        return p;
415}
416
417
418int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
419	      u64 addr, quadlet_t *buffer, size_t length)
420{
421        struct hpsb_packet *packet;
422        int retval = 0;
423
424        if (length == 0) {
425                return -EINVAL;
426        }
427
428        if (host->node_id == node) {
429                switch(highlevel_read(host, node, buffer, addr, length)) {
430                case RCODE_COMPLETE:
431                        return 0;
432                case RCODE_TYPE_ERROR:
433                        return -EACCES;
434                case RCODE_ADDRESS_ERROR:
435                default:
436                        return -EINVAL;
437                }
438        }
439
440        if (length == 4) {
441                packet = hpsb_make_readqpacket(host, node, addr);
442        } else {
443                packet = hpsb_make_readbpacket(host, node, addr, length);
444        }
445
446        if (!packet) {
447                return -ENOMEM;
448        }
449
450	packet->generation = generation;
451        if (!hpsb_send_packet(packet)) {
452		retval = -EINVAL;
453		goto hpsb_read_fail;
454	}
455
456        down(&packet->state_change);
457        down(&packet->state_change);
458        retval = hpsb_packet_success(packet);
459
460        if (retval == 0) {
461                if (length == 4) {
462                        *buffer = packet->header[3];
463                } else {
464                        memcpy(buffer, packet->data, length);
465                }
466        }
467
468hpsb_read_fail:
469        free_tlabel(host, node, packet->tlabel);
470        free_hpsb_packet(packet);
471
472        return retval;
473}
474
475struct hpsb_packet *hpsb_make_packet (struct hpsb_host *host, nodeid_t node,
476				      u64 addr, quadlet_t *buffer, size_t length)
477{
478        struct hpsb_packet *packet;
479
480        if (length == 0)
481                return NULL;
482
483        if (length == 4)
484                packet = hpsb_make_writeqpacket(host, node, addr, *buffer);
485        else
486                packet = hpsb_make_writebpacket(host, node, addr, length);
487
488        if (!packet)
489                return NULL;
490
491	/* Sometimes this may be called without data, just to allocate the
492	 * packet. */
493        if (length != 4 && buffer)
494                memcpy(packet->data, buffer, length);
495
496	return packet;
497}
498
499int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
500	       u64 addr, quadlet_t *buffer, size_t length)
501{
502	struct hpsb_packet *packet;
503	int retval;
504
505	if (length == 0)
506		return -EINVAL;
507
508	if (host->node_id == node) {
509		switch(highlevel_write(host, node, node, buffer, addr, length)) {
510		case RCODE_COMPLETE:
511			return 0;
512		case RCODE_TYPE_ERROR:
513			return -EACCES;
514		case RCODE_ADDRESS_ERROR:
515		default:
516			return -EINVAL;
517		}
518	}
519
520	packet = hpsb_make_packet (host, node, addr, buffer, length);
521
522	if (!packet)
523		return -ENOMEM;
524
525	packet->generation = generation;
526        if (!hpsb_send_packet(packet)) {
527		retval = -EINVAL;
528		goto hpsb_write_fail;
529	}
530
531        down(&packet->state_change);
532        down(&packet->state_change);
533        retval = hpsb_packet_success(packet);
534
535hpsb_write_fail:
536        free_tlabel(host, node, packet->tlabel);
537        free_hpsb_packet(packet);
538
539        return retval;
540}
541
542
543/* We need a hpsb_lock64 function for the 64 bit equivalent.  Probably. */
544int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
545	      u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
546{
547        struct hpsb_packet *packet;
548        int retval = 0, length;
549
550        if (host->node_id == node) {
551                switch(highlevel_lock(host, node, data, addr, *data, arg,
552                                      extcode)) {
553                case RCODE_COMPLETE:
554                        return 0;
555                case RCODE_TYPE_ERROR:
556                        return -EACCES;
557                case RCODE_ADDRESS_ERROR:
558                default:
559                        return -EINVAL;
560                }
561        }
562
563        packet = alloc_hpsb_packet(8);
564        if (!packet) {
565                return -ENOMEM;
566        }
567
568        packet->host = host;
569        packet->tlabel = get_tlabel(host, node, 1);
570        packet->node_id = node;
571
572        switch (extcode) {
573        case EXTCODE_MASK_SWAP:
574        case EXTCODE_COMPARE_SWAP:
575        case EXTCODE_BOUNDED_ADD:
576        case EXTCODE_WRAP_ADD:
577                length = 8;
578                packet->data[0] = arg;
579                packet->data[1] = *data;
580                break;
581        case EXTCODE_FETCH_ADD:
582        case EXTCODE_LITTLE_ADD:
583                length = 4;
584                packet->data[0] = *data;
585                break;
586        default:
587                return -EINVAL;
588        }
589        fill_async_lock(packet, addr, extcode, length);
590
591	packet->generation = generation;
592        if (!hpsb_send_packet(packet)) {
593		retval = -EINVAL;
594		goto hpsb_lock_fail;
595	}
596        down(&packet->state_change);
597        down(&packet->state_change);
598        retval = hpsb_packet_success(packet);
599
600        if (retval == 0) {
601                *data = packet->data[0];
602        }
603
604hpsb_lock_fail:
605        free_tlabel(host, node, packet->tlabel);
606        free_hpsb_packet(packet);
607
608        return retval;
609}
610