1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/completion.h>
22#include <linux/kernel.h>
23#include <linux/kref.h>
24#include <linux/module.h>
25#include <linux/mutex.h>
26#include <linux/init.h>
27#include <linux/interrupt.h>
28#include <linux/pci.h>
29#include <linux/delay.h>
30#include <linux/poll.h>
31#include <linux/list.h>
32#include <linux/kthread.h>
33#include <asm/uaccess.h>
34
35#include "fw-transaction.h"
36#include "fw-topology.h"
37#include "fw-device.h"
38
39#define HEADER_PRI(pri) ((pri) << 0)
40#define HEADER_TCODE(tcode) ((tcode) << 4)
41#define HEADER_RETRY(retry) ((retry) << 8)
42#define HEADER_TLABEL(tlabel) ((tlabel) << 10)
43#define HEADER_DESTINATION(destination) ((destination) << 16)
44#define HEADER_SOURCE(source) ((source) << 16)
45#define HEADER_RCODE(rcode) ((rcode) << 12)
46#define HEADER_OFFSET_HIGH(offset_high) ((offset_high) << 0)
47#define HEADER_DATA_LENGTH(length) ((length) << 16)
48#define HEADER_EXTENDED_TCODE(tcode) ((tcode) << 0)
49
50#define HEADER_GET_TCODE(q) (((q) >> 4) & 0x0f)
51#define HEADER_GET_TLABEL(q) (((q) >> 10) & 0x3f)
52#define HEADER_GET_RCODE(q) (((q) >> 12) & 0x0f)
53#define HEADER_GET_DESTINATION(q) (((q) >> 16) & 0xffff)
54#define HEADER_GET_SOURCE(q) (((q) >> 16) & 0xffff)
55#define HEADER_GET_OFFSET_HIGH(q) (((q) >> 0) & 0xffff)
56#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
57#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)
58
59#define HEADER_DESTINATION_IS_BROADCAST(q) \
60 (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f))
61
62#define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22))
63#define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23))
64#define PHY_IDENTIFIER(id) ((id) << 30)
65
66static int
67close_transaction(struct fw_transaction *transaction,
68 struct fw_card *card, int rcode,
69 u32 *payload, size_t length)
70{
71 struct fw_transaction *t;
72 unsigned long flags;
73
74 spin_lock_irqsave(&card->lock, flags);
75 list_for_each_entry(t, &card->transaction_list, link) {
76 if (t == transaction) {
77 list_del(&t->link);
78 card->tlabel_mask &= ~(1 << t->tlabel);
79 break;
80 }
81 }
82 spin_unlock_irqrestore(&card->lock, flags);
83
84 if (&t->link != &card->transaction_list) {
85 t->callback(card, rcode, payload, length, t->callback_data);
86 return 0;
87 }
88
89 return -ENOENT;
90}
91
92
93
94
95
96int
97fw_cancel_transaction(struct fw_card *card,
98 struct fw_transaction *transaction)
99{
100
101
102
103
104
105
106 if (card->driver->cancel_packet(card, &transaction->packet) == 0)
107 return 0;
108
109
110
111
112
113
114 return close_transaction(transaction, card, RCODE_CANCELLED, NULL, 0);
115}
116EXPORT_SYMBOL(fw_cancel_transaction);
117
118static void
119transmit_complete_callback(struct fw_packet *packet,
120 struct fw_card *card, int status)
121{
122 struct fw_transaction *t =
123 container_of(packet, struct fw_transaction, packet);
124
125 switch (status) {
126 case ACK_COMPLETE:
127 close_transaction(t, card, RCODE_COMPLETE, NULL, 0);
128 break;
129 case ACK_PENDING:
130 t->timestamp = packet->timestamp;
131 break;
132 case ACK_BUSY_X:
133 case ACK_BUSY_A:
134 case ACK_BUSY_B:
135 close_transaction(t, card, RCODE_BUSY, NULL, 0);
136 break;
137 case ACK_DATA_ERROR:
138 close_transaction(t, card, RCODE_DATA_ERROR, NULL, 0);
139 break;
140 case ACK_TYPE_ERROR:
141 close_transaction(t, card, RCODE_TYPE_ERROR, NULL, 0);
142 break;
143 default:
144
145
146
147
148 close_transaction(t, card, status, NULL, 0);
149 break;
150 }
151}
152
153static void
154fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
155 int destination_id, int source_id, int generation, int speed,
156 unsigned long long offset, void *payload, size_t length)
157{
158 int ext_tcode;
159
160 if (tcode > 0x10) {
161 ext_tcode = tcode & ~0x10;
162 tcode = TCODE_LOCK_REQUEST;
163 } else
164 ext_tcode = 0;
165
166 packet->header[0] =
167 HEADER_RETRY(RETRY_X) |
168 HEADER_TLABEL(tlabel) |
169 HEADER_TCODE(tcode) |
170 HEADER_DESTINATION(destination_id);
171 packet->header[1] =
172 HEADER_OFFSET_HIGH(offset >> 32) | HEADER_SOURCE(source_id);
173 packet->header[2] =
174 offset;
175
176 switch (tcode) {
177 case TCODE_WRITE_QUADLET_REQUEST:
178 packet->header[3] = *(u32 *)payload;
179 packet->header_length = 16;
180 packet->payload_length = 0;
181 break;
182
183 case TCODE_LOCK_REQUEST:
184 case TCODE_WRITE_BLOCK_REQUEST:
185 packet->header[3] =
186 HEADER_DATA_LENGTH(length) |
187 HEADER_EXTENDED_TCODE(ext_tcode);
188 packet->header_length = 16;
189 packet->payload = payload;
190 packet->payload_length = length;
191 break;
192
193 case TCODE_READ_QUADLET_REQUEST:
194 packet->header_length = 12;
195 packet->payload_length = 0;
196 break;
197
198 case TCODE_READ_BLOCK_REQUEST:
199 packet->header[3] =
200 HEADER_DATA_LENGTH(length) |
201 HEADER_EXTENDED_TCODE(ext_tcode);
202 packet->header_length = 16;
203 packet->payload_length = 0;
204 break;
205 }
206
207 packet->speed = speed;
208 packet->generation = generation;
209 packet->ack = 0;
210 packet->payload_bus = 0;
211}
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249void
250fw_send_request(struct fw_card *card, struct fw_transaction *t,
251 int tcode, int destination_id, int generation, int speed,
252 unsigned long long offset,
253 void *payload, size_t length,
254 fw_transaction_callback_t callback, void *callback_data)
255{
256 unsigned long flags;
257 int tlabel;
258
259
260
261
262
263
264 mod_timer(&card->flush_timer, jiffies + DIV_ROUND_UP(HZ, 10));
265
266
267
268
269
270
271 spin_lock_irqsave(&card->lock, flags);
272
273 tlabel = card->current_tlabel;
274 if (card->tlabel_mask & (1 << tlabel)) {
275 spin_unlock_irqrestore(&card->lock, flags);
276 callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
277 return;
278 }
279
280 card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
281 card->tlabel_mask |= (1 << tlabel);
282
283 t->node_id = destination_id;
284 t->tlabel = tlabel;
285 t->callback = callback;
286 t->callback_data = callback_data;
287
288 fw_fill_request(&t->packet, tcode, t->tlabel,
289 destination_id, card->node_id, generation,
290 speed, offset, payload, length);
291 t->packet.callback = transmit_complete_callback;
292
293 list_add_tail(&t->link, &card->transaction_list);
294
295 spin_unlock_irqrestore(&card->lock, flags);
296
297 card->driver->send_request(card, &t->packet);
298}
299EXPORT_SYMBOL(fw_send_request);
300
301struct transaction_callback_data {
302 struct completion done;
303 void *payload;
304 int rcode;
305};
306
307static void transaction_callback(struct fw_card *card, int rcode,
308 void *payload, size_t length, void *data)
309{
310 struct transaction_callback_data *d = data;
311
312 if (rcode == RCODE_COMPLETE)
313 memcpy(d->payload, payload, length);
314 d->rcode = rcode;
315 complete(&d->done);
316}
317
318
319
320
321
322
323int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
324 int generation, int speed, unsigned long long offset,
325 void *data, size_t length)
326{
327 struct transaction_callback_data d;
328 struct fw_transaction t;
329
330 init_completion(&d.done);
331 d.payload = data;
332 fw_send_request(card, &t, tcode, destination_id, generation, speed,
333 offset, data, length, transaction_callback, &d);
334 wait_for_completion(&d.done);
335
336 return d.rcode;
337}
338EXPORT_SYMBOL(fw_run_transaction);
339
340static DEFINE_MUTEX(phy_config_mutex);
341static DECLARE_COMPLETION(phy_config_done);
342
343static void transmit_phy_packet_callback(struct fw_packet *packet,
344 struct fw_card *card, int status)
345{
346 complete(&phy_config_done);
347}
348
349static struct fw_packet phy_config_packet = {
350 .header_length = 8,
351 .payload_length = 0,
352 .speed = SCODE_100,
353 .callback = transmit_phy_packet_callback,
354};
355
356void fw_send_phy_config(struct fw_card *card,
357 int node_id, int generation, int gap_count)
358{
359 long timeout = DIV_ROUND_UP(HZ, 10);
360 u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) |
361 PHY_CONFIG_ROOT_ID(node_id) |
362 PHY_CONFIG_GAP_COUNT(gap_count);
363
364 mutex_lock(&phy_config_mutex);
365
366 phy_config_packet.header[0] = data;
367 phy_config_packet.header[1] = ~data;
368 phy_config_packet.generation = generation;
369 INIT_COMPLETION(phy_config_done);
370
371 card->driver->send_request(card, &phy_config_packet);
372 wait_for_completion_timeout(&phy_config_done, timeout);
373
374 mutex_unlock(&phy_config_mutex);
375}
376
377void fw_flush_transactions(struct fw_card *card)
378{
379 struct fw_transaction *t, *next;
380 struct list_head list;
381 unsigned long flags;
382
383 INIT_LIST_HEAD(&list);
384 spin_lock_irqsave(&card->lock, flags);
385 list_splice_init(&card->transaction_list, &list);
386 card->tlabel_mask = 0;
387 spin_unlock_irqrestore(&card->lock, flags);
388
389 list_for_each_entry_safe(t, next, &list, link) {
390 card->driver->cancel_packet(card, &t->packet);
391
392
393
394
395
396
397 t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data);
398 }
399}
400
401static struct fw_address_handler *
402lookup_overlapping_address_handler(struct list_head *list,
403 unsigned long long offset, size_t length)
404{
405 struct fw_address_handler *handler;
406
407 list_for_each_entry(handler, list, link) {
408 if (handler->offset < offset + length &&
409 offset < handler->offset + handler->length)
410 return handler;
411 }
412
413 return NULL;
414}
415
416static struct fw_address_handler *
417lookup_enclosing_address_handler(struct list_head *list,
418 unsigned long long offset, size_t length)
419{
420 struct fw_address_handler *handler;
421
422 list_for_each_entry(handler, list, link) {
423 if (handler->offset <= offset &&
424 offset + length <= handler->offset + handler->length)
425 return handler;
426 }
427
428 return NULL;
429}
430
431static DEFINE_SPINLOCK(address_handler_lock);
432static LIST_HEAD(address_handler_list);
433
434const struct fw_address_region fw_high_memory_region =
435 { .start = 0x000100000000ULL, .end = 0xffffe0000000ULL, };
436EXPORT_SYMBOL(fw_high_memory_region);
437
438#if 0
439const struct fw_address_region fw_low_memory_region =
440 { .start = 0x000000000000ULL, .end = 0x000100000000ULL, };
441const struct fw_address_region fw_private_region =
442 { .start = 0xffffe0000000ULL, .end = 0xfffff0000000ULL, };
443const struct fw_address_region fw_csr_region =
444 { .start = CSR_REGISTER_BASE,
445 .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM_END, };
446const struct fw_address_region fw_unit_space_region =
447 { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
448#endif
449
450
451
452
453
454
455
456
457
458
459
460
461
462int
463fw_core_add_address_handler(struct fw_address_handler *handler,
464 const struct fw_address_region *region)
465{
466 struct fw_address_handler *other;
467 unsigned long flags;
468 int ret = -EBUSY;
469
470 spin_lock_irqsave(&address_handler_lock, flags);
471
472 handler->offset = roundup(region->start, 4);
473 while (handler->offset + handler->length <= region->end) {
474 other =
475 lookup_overlapping_address_handler(&address_handler_list,
476 handler->offset,
477 handler->length);
478 if (other != NULL) {
479 handler->offset =
480 roundup(other->offset + other->length, 4);
481 } else {
482 list_add_tail(&handler->link, &address_handler_list);
483 ret = 0;
484 break;
485 }
486 }
487
488 spin_unlock_irqrestore(&address_handler_lock, flags);
489
490 return ret;
491}
492EXPORT_SYMBOL(fw_core_add_address_handler);
493
494
495
496
497
498
499
500
501
502void fw_core_remove_address_handler(struct fw_address_handler *handler)
503{
504 unsigned long flags;
505
506 spin_lock_irqsave(&address_handler_lock, flags);
507 list_del(&handler->link);
508 spin_unlock_irqrestore(&address_handler_lock, flags);
509}
510EXPORT_SYMBOL(fw_core_remove_address_handler);
511
512struct fw_request {
513 struct fw_packet response;
514 u32 request_header[4];
515 int ack;
516 u32 length;
517 u32 data[0];
518};
519
520static void
521free_response_callback(struct fw_packet *packet,
522 struct fw_card *card, int status)
523{
524 struct fw_request *request;
525
526 request = container_of(packet, struct fw_request, response);
527 kfree(request);
528}
529
530void
531fw_fill_response(struct fw_packet *response, u32 *request_header,
532 int rcode, void *payload, size_t length)
533{
534 int tcode, tlabel, extended_tcode, source, destination;
535
536 tcode = HEADER_GET_TCODE(request_header[0]);
537 tlabel = HEADER_GET_TLABEL(request_header[0]);
538 source = HEADER_GET_DESTINATION(request_header[0]);
539 destination = HEADER_GET_SOURCE(request_header[1]);
540 extended_tcode = HEADER_GET_EXTENDED_TCODE(request_header[3]);
541
542 response->header[0] =
543 HEADER_RETRY(RETRY_1) |
544 HEADER_TLABEL(tlabel) |
545 HEADER_DESTINATION(destination);
546 response->header[1] =
547 HEADER_SOURCE(source) |
548 HEADER_RCODE(rcode);
549 response->header[2] = 0;
550
551 switch (tcode) {
552 case TCODE_WRITE_QUADLET_REQUEST:
553 case TCODE_WRITE_BLOCK_REQUEST:
554 response->header[0] |= HEADER_TCODE(TCODE_WRITE_RESPONSE);
555 response->header_length = 12;
556 response->payload_length = 0;
557 break;
558
559 case TCODE_READ_QUADLET_REQUEST:
560 response->header[0] |=
561 HEADER_TCODE(TCODE_READ_QUADLET_RESPONSE);
562 if (payload != NULL)
563 response->header[3] = *(u32 *)payload;
564 else
565 response->header[3] = 0;
566 response->header_length = 16;
567 response->payload_length = 0;
568 break;
569
570 case TCODE_READ_BLOCK_REQUEST:
571 case TCODE_LOCK_REQUEST:
572 response->header[0] |= HEADER_TCODE(tcode + 2);
573 response->header[3] =
574 HEADER_DATA_LENGTH(length) |
575 HEADER_EXTENDED_TCODE(extended_tcode);
576 response->header_length = 16;
577 response->payload = payload;
578 response->payload_length = length;
579 break;
580
581 default:
582 BUG();
583 return;
584 }
585
586 response->payload_bus = 0;
587}
588EXPORT_SYMBOL(fw_fill_response);
589
590static struct fw_request *
591allocate_request(struct fw_packet *p)
592{
593 struct fw_request *request;
594 u32 *data, length;
595 int request_tcode, t;
596
597 request_tcode = HEADER_GET_TCODE(p->header[0]);
598 switch (request_tcode) {
599 case TCODE_WRITE_QUADLET_REQUEST:
600 data = &p->header[3];
601 length = 4;
602 break;
603
604 case TCODE_WRITE_BLOCK_REQUEST:
605 case TCODE_LOCK_REQUEST:
606 data = p->payload;
607 length = HEADER_GET_DATA_LENGTH(p->header[3]);
608 break;
609
610 case TCODE_READ_QUADLET_REQUEST:
611 data = NULL;
612 length = 4;
613 break;
614
615 case TCODE_READ_BLOCK_REQUEST:
616 data = NULL;
617 length = HEADER_GET_DATA_LENGTH(p->header[3]);
618 break;
619
620 default:
621 fw_error("ERROR - corrupt request received - %08x %08x %08x\n",
622 p->header[0], p->header[1], p->header[2]);
623 return NULL;
624 }
625
626 request = kmalloc(sizeof(*request) + length, GFP_ATOMIC);
627 if (request == NULL)
628 return NULL;
629
630 t = (p->timestamp & 0x1fff) + 4000;
631 if (t >= 8000)
632 t = (p->timestamp & ~0x1fff) + 0x2000 + t - 8000;
633 else
634 t = (p->timestamp & ~0x1fff) + t;
635
636 request->response.speed = p->speed;
637 request->response.timestamp = t;
638 request->response.generation = p->generation;
639 request->response.ack = 0;
640 request->response.callback = free_response_callback;
641 request->ack = p->ack;
642 request->length = length;
643 if (data)
644 memcpy(request->data, data, length);
645
646 memcpy(request->request_header, p->header, sizeof(p->header));
647
648 return request;
649}
650
651void
652fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
653{
654
655 if (request->ack != ACK_PENDING ||
656 HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
657 kfree(request);
658 return;
659 }
660
661 if (rcode == RCODE_COMPLETE)
662 fw_fill_response(&request->response, request->request_header,
663 rcode, request->data, request->length);
664 else
665 fw_fill_response(&request->response, request->request_header,
666 rcode, NULL, 0);
667
668 card->driver->send_response(card, &request->response);
669}
670EXPORT_SYMBOL(fw_send_response);
671
672void
673fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
674{
675 struct fw_address_handler *handler;
676 struct fw_request *request;
677 unsigned long long offset;
678 unsigned long flags;
679 int tcode, destination, source;
680
681 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
682 return;
683
684 request = allocate_request(p);
685 if (request == NULL) {
686
687 return;
688 }
689
690 offset =
691 ((unsigned long long)
692 HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | p->header[2];
693 tcode = HEADER_GET_TCODE(p->header[0]);
694 destination = HEADER_GET_DESTINATION(p->header[0]);
695 source = HEADER_GET_SOURCE(p->header[1]);
696
697 spin_lock_irqsave(&address_handler_lock, flags);
698 handler = lookup_enclosing_address_handler(&address_handler_list,
699 offset, request->length);
700 spin_unlock_irqrestore(&address_handler_lock, flags);
701
702
703
704
705
706
707
708
709
710 if (handler == NULL)
711 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
712 else
713 handler->address_callback(card, request,
714 tcode, destination, source,
715 p->generation, p->speed, offset,
716 request->data, request->length,
717 handler->callback_data);
718}
719EXPORT_SYMBOL(fw_core_handle_request);
720
721void
722fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
723{
724 struct fw_transaction *t;
725 unsigned long flags;
726 u32 *data;
727 size_t data_length;
728 int tcode, tlabel, destination, source, rcode;
729
730 tcode = HEADER_GET_TCODE(p->header[0]);
731 tlabel = HEADER_GET_TLABEL(p->header[0]);
732 destination = HEADER_GET_DESTINATION(p->header[0]);
733 source = HEADER_GET_SOURCE(p->header[1]);
734 rcode = HEADER_GET_RCODE(p->header[1]);
735
736 spin_lock_irqsave(&card->lock, flags);
737 list_for_each_entry(t, &card->transaction_list, link) {
738 if (t->node_id == source && t->tlabel == tlabel) {
739 list_del(&t->link);
740 card->tlabel_mask &= ~(1 << t->tlabel);
741 break;
742 }
743 }
744 spin_unlock_irqrestore(&card->lock, flags);
745
746 if (&t->link == &card->transaction_list) {
747 fw_notify("Unsolicited response (source %x, tlabel %x)\n",
748 source, tlabel);
749 return;
750 }
751
752
753
754
755
756
757 switch (tcode) {
758 case TCODE_READ_QUADLET_RESPONSE:
759 data = (u32 *) &p->header[3];
760 data_length = 4;
761 break;
762
763 case TCODE_WRITE_RESPONSE:
764 data = NULL;
765 data_length = 0;
766 break;
767
768 case TCODE_READ_BLOCK_RESPONSE:
769 case TCODE_LOCK_RESPONSE:
770 data = p->payload;
771 data_length = HEADER_GET_DATA_LENGTH(p->header[3]);
772 break;
773
774 default:
775
776 data = NULL;
777 data_length = 0;
778 break;
779 }
780
781
782
783
784
785 card->driver->cancel_packet(card, &t->packet);
786
787 t->callback(card, rcode, data, data_length, t->callback_data);
788}
789EXPORT_SYMBOL(fw_core_handle_response);
790
791static const struct fw_address_region topology_map_region =
792 { .start = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP,
793 .end = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP_END, };
794
795static void
796handle_topology_map(struct fw_card *card, struct fw_request *request,
797 int tcode, int destination, int source,
798 int generation, int speed,
799 unsigned long long offset,
800 void *payload, size_t length, void *callback_data)
801{
802 int i, start, end;
803 __be32 *map;
804
805 if (!TCODE_IS_READ_REQUEST(tcode)) {
806 fw_send_response(card, request, RCODE_TYPE_ERROR);
807 return;
808 }
809
810 if ((offset & 3) > 0 || (length & 3) > 0) {
811 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
812 return;
813 }
814
815 start = (offset - topology_map_region.start) / 4;
816 end = start + length / 4;
817 map = payload;
818
819 for (i = 0; i < length / 4; i++)
820 map[i] = cpu_to_be32(card->topology_map[start + i]);
821
822 fw_send_response(card, request, RCODE_COMPLETE);
823}
824
825static struct fw_address_handler topology_map = {
826 .length = 0x200,
827 .address_callback = handle_topology_map,
828};
829
830static const struct fw_address_region registers_region =
831 { .start = CSR_REGISTER_BASE,
832 .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, };
833
834static void
835handle_registers(struct fw_card *card, struct fw_request *request,
836 int tcode, int destination, int source,
837 int generation, int speed,
838 unsigned long long offset,
839 void *payload, size_t length, void *callback_data)
840{
841 int reg = offset & ~CSR_REGISTER_BASE;
842 unsigned long long bus_time;
843 __be32 *data = payload;
844 int rcode = RCODE_COMPLETE;
845
846 switch (reg) {
847 case CSR_CYCLE_TIME:
848 case CSR_BUS_TIME:
849 if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
850 rcode = RCODE_TYPE_ERROR;
851 break;
852 }
853
854 bus_time = card->driver->get_bus_time(card);
855 if (reg == CSR_CYCLE_TIME)
856 *data = cpu_to_be32(bus_time);
857 else
858 *data = cpu_to_be32(bus_time >> 25);
859 break;
860
861 case CSR_BROADCAST_CHANNEL:
862 if (tcode == TCODE_READ_QUADLET_REQUEST)
863 *data = cpu_to_be32(card->broadcast_channel);
864 else if (tcode == TCODE_WRITE_QUADLET_REQUEST)
865 card->broadcast_channel =
866 (be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) |
867 BROADCAST_CHANNEL_INITIAL;
868 else
869 rcode = RCODE_TYPE_ERROR;
870 break;
871
872 case CSR_BUS_MANAGER_ID:
873 case CSR_BANDWIDTH_AVAILABLE:
874 case CSR_CHANNELS_AVAILABLE_HI:
875 case CSR_CHANNELS_AVAILABLE_LO:
876
877
878
879
880
881
882
883 BUG();
884 break;
885
886 case CSR_BUSY_TIMEOUT:
887
888
889 default:
890 rcode = RCODE_ADDRESS_ERROR;
891 break;
892 }
893
894 fw_send_response(card, request, rcode);
895}
896
897static struct fw_address_handler registers = {
898 .length = 0x400,
899 .address_callback = handle_registers,
900};
901
902MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
903MODULE_DESCRIPTION("Core IEEE1394 transaction logic");
904MODULE_LICENSE("GPL");
905
906static const u32 vendor_textual_descriptor[] = {
907
908 0x00060000,
909 0x00000000,
910 0x00000000,
911 0x4c696e75,
912 0x78204669,
913 0x72657769,
914 0x72650000,
915};
916
917static const u32 model_textual_descriptor[] = {
918
919 0x00030000,
920 0x00000000,
921 0x00000000,
922 0x4a756a75,
923};
924
925static struct fw_descriptor vendor_id_descriptor = {
926 .length = ARRAY_SIZE(vendor_textual_descriptor),
927 .immediate = 0x03d00d1e,
928 .key = 0x81000000,
929 .data = vendor_textual_descriptor,
930};
931
932static struct fw_descriptor model_id_descriptor = {
933 .length = ARRAY_SIZE(model_textual_descriptor),
934 .immediate = 0x17000001,
935 .key = 0x81000000,
936 .data = model_textual_descriptor,
937};
938
939static int __init fw_core_init(void)
940{
941 int retval;
942
943 retval = bus_register(&fw_bus_type);
944 if (retval < 0)
945 return retval;
946
947 fw_cdev_major = register_chrdev(0, "firewire", &fw_device_ops);
948 if (fw_cdev_major < 0) {
949 bus_unregister(&fw_bus_type);
950 return fw_cdev_major;
951 }
952
953 retval = fw_core_add_address_handler(&topology_map,
954 &topology_map_region);
955 BUG_ON(retval < 0);
956
957 retval = fw_core_add_address_handler(®isters,
958 ®isters_region);
959 BUG_ON(retval < 0);
960
961
962 retval = fw_core_add_descriptor(&vendor_id_descriptor);
963 BUG_ON(retval < 0);
964 retval = fw_core_add_descriptor(&model_id_descriptor);
965 BUG_ON(retval < 0);
966
967 return 0;
968}
969
970static void __exit fw_core_cleanup(void)
971{
972 unregister_chrdev(fw_cdev_major, "firewire");
973 bus_unregister(&fw_bus_type);
974}
975
976module_init(fw_core_init);
977module_exit(fw_core_cleanup);
978