Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 <linux/bitops.h>
 14 #include <linux/smp_lock.h>
 15 #include <linux/interrupt.h>
 16 
 17 #include <asm/errno.h>
 18 
 19 #include "ieee1394.h"
 20 #include "ieee1394_types.h"
 21 #include "hosts.h"
 22 #include "ieee1394_core.h"
 23 #include "highlevel.h"
 24 #include "nodemgr.h"
 25 
 26 
 27 #define PREP_ASYNC_HEAD_ADDRESS(tc) \
 28         packet->tcode = tc; \
 29         packet->header[0] = (packet->node_id << 16) | (packet->tlabel << 10) \
 30                 | (1 << 8) | (tc << 4); \
 31         packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
 32         packet->header[2] = addr & 0xffffffff
 33 
 34 
 35 static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
 36 {
 37         PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
 38         packet->header_size = 12;
 39         packet->data_size = 0;
 40         packet->expect_response = 1;
 41 }
 42 
 43 static void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length)
 44 {
 45         PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
 46         packet->header[3] = length << 16;
 47         packet->header_size = 16;
 48         packet->data_size = 0;
 49         packet->expect_response = 1;
 50 }
 51 
 52 static void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data)
 53 {
 54         PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
 55         packet->header[3] = data;
 56         packet->header_size = 16;
 57         packet->data_size = 0;
 58         packet->expect_response = 1;
 59 }
 60 
 61 static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length)
 62 {
 63         PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
 64         packet->header[3] = length << 16;
 65         packet->header_size = 16;
 66         packet->expect_response = 1;
 67         packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
 68 }
 69 
 70 static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
 71                      int length)
 72 {
 73         PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
 74         packet->header[3] = (length << 16) | extcode;
 75         packet->header_size = 16;
 76         packet->data_size = length;
 77         packet->expect_response = 1;
 78 }
 79 
 80 static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
 81                      int tag, int sync)
 82 {
 83         packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
 84                 | (TCODE_ISO_DATA << 4) | sync;
 85 
 86         packet->header_size = 4;
 87         packet->data_size = length;
 88         packet->type = hpsb_iso;
 89         packet->tcode = TCODE_ISO_DATA;
 90 }
 91 
 92 static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
 93 {
 94         packet->header[0] = data;
 95         packet->header[1] = ~data;
 96         packet->header_size = 8;
 97         packet->data_size = 0;
 98         packet->expect_response = 0;
 99         packet->type = hpsb_raw;             /* No CRC added */
100         packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */
101 }
102 
103 static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
104                                      int channel, int tag, int sync)
105 {
106         packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
107                           | (TCODE_STREAM_DATA << 4) | sync;
108 
109         packet->header_size = 4;
110         packet->data_size = length;
111         packet->type = hpsb_async;
112         packet->tcode = TCODE_ISO_DATA;
113 }
114 
115 /**
116  * hpsb_get_tlabel - allocate a transaction label
117  * @packet: the packet who's tlabel/tpool we set
118  *
119  * Every asynchronous transaction on the 1394 bus needs a transaction
120  * label to match the response to the request.  This label has to be
121  * different from any other transaction label in an outstanding request to
122  * the same node to make matching possible without ambiguity.
123  *
124  * There are 64 different tlabels, so an allocated tlabel has to be freed
125  * with hpsb_free_tlabel() after the transaction is complete (unless it's
126  * reused again for the same target node).
127  *
128  * Return value: Zero on success, otherwise non-zero. A non-zero return
129  * generally means there are no available tlabels. If this is called out
130  * of interrupt or atomic context, then it will sleep until can return a
131  * tlabel.
132  */
133 int hpsb_get_tlabel(struct hpsb_packet *packet)
134 {
135         unsigned long flags;
136         struct hpsb_tlabel_pool *tp;
137 
138         tp = &packet->host->tpool[packet->node_id & NODE_MASK];
139 
140         if (irqs_disabled() || in_atomic()) {
141                 if (down_trylock(&tp->count))
142                         return 1;
143         } else {
144                 down(&tp->count);
145         }
146 
147         spin_lock_irqsave(&tp->lock, flags);
148 
149         packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
150         if (packet->tlabel > 63)
151                 packet->tlabel = find_first_zero_bit(tp->pool, 64);
152         tp->next = (packet->tlabel + 1) % 64;
153         /* Should _never_ happen */
154         BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
155         tp->allocations++;
156         spin_unlock_irqrestore(&tp->lock, flags);
157 
158         return 0;
159 }
160 
161 /**
162  * hpsb_free_tlabel - free an allocated transaction label
163  * @packet: packet whos tlabel/tpool needs to be cleared
164  *
165  * Frees the transaction label allocated with hpsb_get_tlabel().  The
166  * tlabel has to be freed after the transaction is complete (i.e. response
167  * was received for a split transaction or packet was sent for a unified
168  * transaction).
169  *
170  * A tlabel must not be freed twice.
171  */
172 void hpsb_free_tlabel(struct hpsb_packet *packet)
173 {
174         unsigned long flags;
175         struct hpsb_tlabel_pool *tp;
176 
177         tp = &packet->host->tpool[packet->node_id & NODE_MASK];
178 
179         BUG_ON(packet->tlabel > 63 || packet->tlabel < 0);
180 
181         spin_lock_irqsave(&tp->lock, flags);
182         BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
183         spin_unlock_irqrestore(&tp->lock, flags);
184 
185         up(&tp->count);
186 }
187 
188 
189 
190 int hpsb_packet_success(struct hpsb_packet *packet)
191 {
192         switch (packet->ack_code) {
193         case ACK_PENDING:
194                 switch ((packet->header[1] >> 12) & 0xf) {
195                 case RCODE_COMPLETE:
196                         return 0;
197                 case RCODE_CONFLICT_ERROR:
198                         return -EAGAIN;
199                 case RCODE_DATA_ERROR:
200                         return -EREMOTEIO;
201                 case RCODE_TYPE_ERROR:
202                         return -EACCES;
203                 case RCODE_ADDRESS_ERROR:
204                         return -EINVAL;
205                 default:
206                         HPSB_ERR("received reserved rcode %d from node %d",
207                                  (packet->header[1] >> 12) & 0xf,
208                                  packet->node_id);
209                         return -EAGAIN;
210                 }
211                 HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
212 
213         case ACK_BUSY_X:
214         case ACK_BUSY_A:
215         case ACK_BUSY_B:
216                 return -EBUSY;
217 
218         case ACK_TYPE_ERROR:
219                 return -EACCES;
220 
221         case ACK_COMPLETE:
222                 if (packet->tcode == TCODE_WRITEQ
223                     || packet->tcode == TCODE_WRITEB) {
224                         return 0;
225                 } else {
226                         HPSB_ERR("impossible ack_complete from node %d "
227                                  "(tcode %d)", packet->node_id, packet->tcode);
228                         return -EAGAIN;
229                 }
230 
231 
232         case ACK_DATA_ERROR:
233                 if (packet->tcode == TCODE_WRITEB
234                     || packet->tcode == TCODE_LOCK_REQUEST) {
235                         return -EAGAIN;
236                 } else {
237                         HPSB_ERR("impossible ack_data_error from node %d "
238                                  "(tcode %d)", packet->node_id, packet->tcode);
239                         return -EAGAIN;
240                 }
241 
242         case ACK_ADDRESS_ERROR:
243                 return -EINVAL;
244 
245         case ACK_TARDY:
246         case ACK_CONFLICT_ERROR:
247         case ACKX_NONE:
248         case ACKX_SEND_ERROR:
249         case ACKX_ABORTED:
250         case ACKX_TIMEOUT:
251                 /* error while sending */
252                 return -EAGAIN;
253 
254         default:
255                 HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
256                          packet->ack_code, packet->node_id, packet->tcode);
257                 return -EAGAIN;
258         }
259 
260         HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
261 }
262 
263 struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
264                                          u64 addr, size_t length)
265 {
266         struct hpsb_packet *packet;
267 
268         if (length == 0)
269                 return NULL;
270 
271         packet = hpsb_alloc_packet(length);
272         if (!packet)
273                 return NULL;
274 
275         packet->host = host;
276         packet->node_id = node;
277 
278         if (hpsb_get_tlabel(packet)) {
279                 hpsb_free_packet(packet);
280                 return NULL;
281         }
282 
283         if (length == 4)
284                 fill_async_readquad(packet, addr);
285         else
286                 fill_async_readblock(packet, addr, length);
287 
288         return packet;
289 }
290 
291 struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node,
292                                            u64 addr, quadlet_t *buffer, size_t length)
293 {
294         struct hpsb_packet *packet;
295 
296         if (length == 0)
297                 return NULL;
298 
299         packet = hpsb_alloc_packet(length);
300         if (!packet)
301                 return NULL;
302 
303         if (length % 4) { /* zero padding bytes */
304                 packet->data[length >> 2] = 0;
305         }
306         packet->host = host;
307         packet->node_id = node;
308 
309         if (hpsb_get_tlabel(packet)) {
310                 hpsb_free_packet(packet);
311                 return NULL;
312         }
313 
314         if (length == 4) {
315                 fill_async_writequad(packet, addr, buffer ? *buffer : 0);
316         } else {
317                 fill_async_writeblock(packet, addr, length);
318                 if (buffer)
319                         memcpy(packet->data, buffer, length);
320         }
321 
322         return packet;
323 }
324 
325 struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length,
326                                            int channel, int tag, int sync)
327 {
328         struct hpsb_packet *packet;
329 
330         if (length == 0)
331                 return NULL;
332 
333         packet = hpsb_alloc_packet(length);
334         if (!packet)
335                 return NULL;
336 
337         if (length % 4) { /* zero padding bytes */
338                 packet->data[length >> 2] = 0;
339         }
340         packet->host = host;
341 
342         if (hpsb_get_tlabel(packet)) {
343                 hpsb_free_packet(packet);
344                 return NULL;
345         }
346 
347         fill_async_stream_packet(packet, length, channel, tag, sync);
348         if (buffer)
349                 memcpy(packet->data, buffer, length);
350 
351         return packet;
352 }
353 
354 struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
355                                          u64 addr, int extcode, quadlet_t *data,
356                                          quadlet_t arg)
357 {
358         struct hpsb_packet *p;
359         u32 length;
360 
361         p = hpsb_alloc_packet(8);
362         if (!p) return NULL;
363 
364         p->host = host;
365         p->node_id = node;
366         if (hpsb_get_tlabel(p)) {
367                 hpsb_free_packet(p);
368                 return NULL;
369         }
370 
371         switch (extcode) {
372         case EXTCODE_FETCH_ADD:
373         case EXTCODE_LITTLE_ADD:
374                 length = 4;
375                 if (data)
376                         p->data[0] = *data;
377                 break;
378         default:
379                 length = 8;
380                 if (data) {
381                         p->data[0] = arg;
382                         p->data[1] = *data;
383                 }
384                 break;
385         }
386         fill_async_lock(p, addr, extcode, length);
387 
388         return p;
389 }
390 
391 struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
392                                            u64 addr, int extcode, octlet_t *data,
393                                            octlet_t arg)
394 {
395         struct hpsb_packet *p;
396         u32 length;
397 
398         p = hpsb_alloc_packet(16);
399         if (!p) return NULL;
400 
401         p->host = host;
402         p->node_id = node;
403         if (hpsb_get_tlabel(p)) {
404                 hpsb_free_packet(p);
405                 return NULL;
406         }
407 
408         switch (extcode) {
409         case EXTCODE_FETCH_ADD:
410         case EXTCODE_LITTLE_ADD:
411                 length = 8;
412                 if (data) {
413                         p->data[0] = *data >> 32;
414                         p->data[1] = *data & 0xffffffff;
415                 }
416                 break;
417         default:
418                 length = 16;
419                 if (data) {
420                         p->data[0] = arg >> 32;
421                         p->data[1] = arg & 0xffffffff;
422                         p->data[2] = *data >> 32;
423                         p->data[3] = *data & 0xffffffff;
424                 }
425                 break;
426         }
427         fill_async_lock(p, addr, extcode, length);
428 
429         return p;
430 }
431 
432 struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
433                                         quadlet_t data)
434 {
435         struct hpsb_packet *p;
436 
437         p = hpsb_alloc_packet(0);
438         if (!p) return NULL;
439 
440         p->host = host;
441         fill_phy_packet(p, data);
442 
443         return p;
444 }
445 
446 struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
447                                         int length, int channel,
448                                         int tag, int sync)
449 {
450         struct hpsb_packet *p;
451 
452         p = hpsb_alloc_packet(length);
453         if (!p) return NULL;
454 
455         p->host = host;
456         fill_iso_packet(p, length, channel, tag, sync);
457 
458         p->generation = get_hpsb_generation(host);
459 
460         return p;
461 }
462 
463 /*
464  * FIXME - these functions should probably read from / write to user space to
465  * avoid in kernel buffers for user space callers
466  */
467 
468 int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
469               u64 addr, quadlet_t *buffer, size_t length)
470 {
471         struct hpsb_packet *packet;
472         int retval = 0;
473 
474         if (length == 0)
475                 return -EINVAL;
476 
477         BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
478 
479         packet = hpsb_make_readpacket(host, node, addr, length);
480 
481         if (!packet) {
482                 return -ENOMEM;
483         }
484 
485         packet->generation = generation;
486         retval = hpsb_send_packet_and_wait(packet);
487         if (retval < 0)
488                 goto hpsb_read_fail;
489 
490         retval = hpsb_packet_success(packet);
491 
492         if (retval == 0) {
493                 if (length == 4) {
494                         *buffer = packet->header[3];
495                 } else {
496                         memcpy(buffer, packet->data, length);
497                 }
498         }
499 
500 hpsb_read_fail:
501         hpsb_free_tlabel(packet);
502         hpsb_free_packet(packet);
503 
504         return retval;
505 }
506 
507 
508 int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
509                u64 addr, quadlet_t *buffer, size_t length)
510 {
511         struct hpsb_packet *packet;
512         int retval;
513 
514         if (length == 0)
515                 return -EINVAL;
516 
517         BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
518 
519         packet = hpsb_make_writepacket (host, node, addr, buffer, length);
520 
521         if (!packet)
522                 return -ENOMEM;
523 
524         packet->generation = generation;
525         retval = hpsb_send_packet_and_wait(packet);
526         if (retval < 0)
527                 goto hpsb_write_fail;
528 
529         retval = hpsb_packet_success(packet);
530 
531 hpsb_write_fail:
532         hpsb_free_tlabel(packet);
533         hpsb_free_packet(packet);
534 
535         return retval;
536 }
537 
538 
539 int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
540               u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
541 {
542         struct hpsb_packet *packet;
543         int retval = 0;
544 
545         BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
546 
547         packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
548         if (!packet)
549                 return -ENOMEM;
550 
551         packet->generation = generation;
552         retval = hpsb_send_packet_and_wait(packet);
553         if (retval < 0)
554                 goto hpsb_lock_fail;
555 
556         retval = hpsb_packet_success(packet);
557 
558         if (retval == 0) {
559                 *data = packet->data[0];
560         }
561 
562 hpsb_lock_fail:
563         hpsb_free_tlabel(packet);
564         hpsb_free_packet(packet);
565 
566         return retval;
567 }
568 
569 int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation,
570                 u64 addr, int extcode, octlet_t *data, octlet_t arg)
571 {
572         struct hpsb_packet *packet;
573         int retval = 0;
574 
575         BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
576 
577         packet = hpsb_make_lock64packet(host, node, addr, extcode, data, arg);
578         if (!packet)
579                 return -ENOMEM;
580 
581         packet->generation = generation;
582         retval = hpsb_send_packet_and_wait(packet);
583         if (retval < 0)
584                 goto hpsb_lock64_fail;
585 
586         retval = hpsb_packet_success(packet);
587 
588         if (retval == 0)
589                 *data = (u64)packet->data[1] << 32 | packet->data[0];
590 
591 hpsb_lock64_fail:
592         hpsb_free_tlabel(packet);
593         hpsb_free_packet(packet);
594 
595         return retval;
596 }
597 
598 int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
599                    quadlet_t *buffer, size_t length, u32 specifier_id,
600                    unsigned int version)
601 {
602         struct hpsb_packet *packet;
603         int retval = 0;
604         u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8;
605         u8 specifier_id_lo = specifier_id & 0xff;
606 
607         HPSB_VERBOSE("Send GASP: channel = %d, length = %Zd", channel, length);
608 
609         length += 8;
610 
611         packet = hpsb_make_streampacket(host, NULL, length, channel, 3, 0);
612         if (!packet)
613                 return -ENOMEM;
614 
615         packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi);
616         packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
617 
618         memcpy(&(packet->data[2]), buffer, length - 8);
619 
620         packet->generation = generation;
621 
622         packet->no_waiter = 1;
623 
624         retval = hpsb_send_packet(packet);
625         if (retval < 0)
626                 hpsb_free_packet(packet);
627 
628         return retval;
629 }
630 
  This page was automatically generated by the LXR engine.