aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 03:31:06 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 03:31:06 -0500
commit51c24aaacaea90c8e87f1dec75a2ac7622b593f8 (patch)
tree9f54936c87764bef75e97395cb56b7d1e0df24c6 /drivers/firewire
parent4276e47e2d1c85a2477caf0d22b91c4f2377fba8 (diff)
parent6be325719b3e54624397e413efd4b33a997e55a3 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/Kconfig44
-rw-r--r--drivers/firewire/core-cdev.c27
-rw-r--r--drivers/firewire/core-transaction.c118
-rw-r--r--drivers/firewire/ohci.c4
4 files changed, 129 insertions, 64 deletions
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 13efcd362072..a9371b36a9b9 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -1,5 +1,10 @@
1menu "IEEE 1394 (FireWire) support"
2 depends on PCI || BROKEN
3 # firewire-core does not depend on PCI but is
4 # not useful without PCI controller driver
5
1comment "You can enable one or both FireWire driver stacks." 6comment "You can enable one or both FireWire driver stacks."
2comment "See the help texts for more information." 7comment "The newer stack is recommended."
3 8
4config FIREWIRE 9config FIREWIRE
5 tristate "FireWire driver stack" 10 tristate "FireWire driver stack"
@@ -15,16 +20,6 @@ config FIREWIRE
15 To compile this driver as a module, say M here: the module will be 20 To compile this driver as a module, say M here: the module will be
16 called firewire-core. 21 called firewire-core.
17 22
18 This module functionally replaces ieee1394, raw1394, and video1394.
19 To access it from application programs, you generally need at least
20 libraw1394 v2. IIDC/DCAM applications need libdc1394 v2.
21 No libraries are required to access storage devices through the
22 firewire-sbp2 driver.
23
24 NOTE:
25 FireWire audio devices currently require the old drivers (ieee1394,
26 ohci1394, raw1394).
27
28config FIREWIRE_OHCI 23config FIREWIRE_OHCI
29 tristate "OHCI-1394 controllers" 24 tristate "OHCI-1394 controllers"
30 depends on PCI && FIREWIRE 25 depends on PCI && FIREWIRE
@@ -34,22 +29,7 @@ config FIREWIRE_OHCI
34 is the only chipset in use, so say Y here. 29 is the only chipset in use, so say Y here.
35 30
36 To compile this driver as a module, say M here: The module will be 31 To compile this driver as a module, say M here: The module will be
37 called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 32 called firewire-ohci.
38 stack.
39
40 NOTE:
41 If you want to install firewire-ohci and ohci1394 together, you
42 should configure them only as modules and blacklist the driver(s)
43 which you don't want to have auto-loaded. Add either
44
45 blacklist firewire-ohci
46 or
47 blacklist ohci1394
48 blacklist video1394
49 blacklist dv1394
50
51 to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
52 depending on your distribution.
53 33
54config FIREWIRE_OHCI_DEBUG 34config FIREWIRE_OHCI_DEBUG
55 bool 35 bool
@@ -66,8 +46,7 @@ config FIREWIRE_SBP2
66 like scanners. 46 like scanners.
67 47
68 To compile this driver as a module, say M here: The module will be 48 To compile this driver as a module, say M here: The module will be
69 called firewire-sbp2. It replaces sbp2 of the classic IEEE 1394 49 called firewire-sbp2.
70 stack.
71 50
72 You should also enable support for disks, CD-ROMs, etc. in the SCSI 51 You should also enable support for disks, CD-ROMs, etc. in the SCSI
73 configuration section. 52 configuration section.
@@ -83,5 +62,8 @@ config FIREWIRE_NET
83 NOTE, this driver is not stable yet! 62 NOTE, this driver is not stable yet!
84 63
85 To compile this driver as a module, say M here: The module will be 64 To compile this driver as a module, say M here: The module will be
86 called firewire-net. It replaces eth1394 of the classic IEEE 1394 65 called firewire-net.
87 stack. 66
67source "drivers/ieee1394/Kconfig"
68
69endmenu
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 231e6ee5ba43..e6d63849e78e 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -601,8 +601,9 @@ static void release_request(struct client *client,
601 struct inbound_transaction_resource *r = container_of(resource, 601 struct inbound_transaction_resource *r = container_of(resource,
602 struct inbound_transaction_resource, resource); 602 struct inbound_transaction_resource, resource);
603 603
604 fw_send_response(client->device->card, r->request, 604 if (r->request)
605 RCODE_CONFLICT_ERROR); 605 fw_send_response(client->device->card, r->request,
606 RCODE_CONFLICT_ERROR);
606 kfree(r); 607 kfree(r);
607} 608}
608 609
@@ -645,7 +646,8 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
645 failed: 646 failed:
646 kfree(r); 647 kfree(r);
647 kfree(e); 648 kfree(e);
648 fw_send_response(card, request, RCODE_CONFLICT_ERROR); 649 if (request)
650 fw_send_response(card, request, RCODE_CONFLICT_ERROR);
649} 651}
650 652
651static void release_address_handler(struct client *client, 653static void release_address_handler(struct client *client,
@@ -715,15 +717,18 @@ static int ioctl_send_response(struct client *client, void *buffer)
715 717
716 r = container_of(resource, struct inbound_transaction_resource, 718 r = container_of(resource, struct inbound_transaction_resource,
717 resource); 719 resource);
718 if (request->length < r->length) 720 if (r->request) {
719 r->length = request->length; 721 if (request->length < r->length)
720 722 r->length = request->length;
721 if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { 723 if (copy_from_user(r->data, u64_to_uptr(request->data),
722 ret = -EFAULT; 724 r->length)) {
723 goto out; 725 ret = -EFAULT;
726 kfree(r->request);
727 goto out;
728 }
729 fw_send_response(client->device->card, r->request,
730 request->rcode);
724 } 731 }
725
726 fw_send_response(client->device->card, r->request, request->rcode);
727 out: 732 out:
728 kfree(r); 733 kfree(r);
729 734
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 842739df23e2..495849eb13cc 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -432,14 +432,20 @@ static struct fw_address_handler *lookup_overlapping_address_handler(
432 return NULL; 432 return NULL;
433} 433}
434 434
435static bool is_enclosing_handler(struct fw_address_handler *handler,
436 unsigned long long offset, size_t length)
437{
438 return handler->offset <= offset &&
439 offset + length <= handler->offset + handler->length;
440}
441
435static struct fw_address_handler *lookup_enclosing_address_handler( 442static struct fw_address_handler *lookup_enclosing_address_handler(
436 struct list_head *list, unsigned long long offset, size_t length) 443 struct list_head *list, unsigned long long offset, size_t length)
437{ 444{
438 struct fw_address_handler *handler; 445 struct fw_address_handler *handler;
439 446
440 list_for_each_entry(handler, list, link) { 447 list_for_each_entry(handler, list, link) {
441 if (handler->offset <= offset && 448 if (is_enclosing_handler(handler, offset, length))
442 offset + length <= handler->offset + handler->length)
443 return handler; 449 return handler;
444 } 450 }
445 451
@@ -465,6 +471,12 @@ const struct fw_address_region fw_unit_space_region =
465 { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, }; 471 { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, };
466#endif /* 0 */ 472#endif /* 0 */
467 473
474static bool is_in_fcp_region(u64 offset, size_t length)
475{
476 return offset >= (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
477 offset + length <= (CSR_REGISTER_BASE | CSR_FCP_END);
478}
479
468/** 480/**
469 * fw_core_add_address_handler - register for incoming requests 481 * fw_core_add_address_handler - register for incoming requests
470 * @handler: callback 482 * @handler: callback
@@ -477,8 +489,11 @@ const struct fw_address_region fw_unit_space_region =
477 * give the details of the particular request. 489 * give the details of the particular request.
478 * 490 *
479 * Return value: 0 on success, non-zero otherwise. 491 * Return value: 0 on success, non-zero otherwise.
492 *
480 * The start offset of the handler's address region is determined by 493 * The start offset of the handler's address region is determined by
481 * fw_core_add_address_handler() and is returned in handler->offset. 494 * fw_core_add_address_handler() and is returned in handler->offset.
495 *
496 * Address allocations are exclusive, except for the FCP registers.
482 */ 497 */
483int fw_core_add_address_handler(struct fw_address_handler *handler, 498int fw_core_add_address_handler(struct fw_address_handler *handler,
484 const struct fw_address_region *region) 499 const struct fw_address_region *region)
@@ -498,10 +513,12 @@ int fw_core_add_address_handler(struct fw_address_handler *handler,
498 513
499 handler->offset = region->start; 514 handler->offset = region->start;
500 while (handler->offset + handler->length <= region->end) { 515 while (handler->offset + handler->length <= region->end) {
501 other = 516 if (is_in_fcp_region(handler->offset, handler->length))
502 lookup_overlapping_address_handler(&address_handler_list, 517 other = NULL;
503 handler->offset, 518 else
504 handler->length); 519 other = lookup_overlapping_address_handler
520 (&address_handler_list,
521 handler->offset, handler->length);
505 if (other != NULL) { 522 if (other != NULL) {
506 handler->offset += other->length; 523 handler->offset += other->length;
507 } else { 524 } else {
@@ -668,6 +685,9 @@ static struct fw_request *allocate_request(struct fw_packet *p)
668void fw_send_response(struct fw_card *card, 685void fw_send_response(struct fw_card *card,
669 struct fw_request *request, int rcode) 686 struct fw_request *request, int rcode)
670{ 687{
688 if (WARN_ONCE(!request, "invalid for FCP address handlers"))
689 return;
690
671 /* unified transaction or broadcast transaction: don't respond */ 691 /* unified transaction or broadcast transaction: don't respond */
672 if (request->ack != ACK_PENDING || 692 if (request->ack != ACK_PENDING ||
673 HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) { 693 HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
@@ -686,26 +706,15 @@ void fw_send_response(struct fw_card *card,
686} 706}
687EXPORT_SYMBOL(fw_send_response); 707EXPORT_SYMBOL(fw_send_response);
688 708
689void fw_core_handle_request(struct fw_card *card, struct fw_packet *p) 709static void handle_exclusive_region_request(struct fw_card *card,
710 struct fw_packet *p,
711 struct fw_request *request,
712 unsigned long long offset)
690{ 713{
691 struct fw_address_handler *handler; 714 struct fw_address_handler *handler;
692 struct fw_request *request;
693 unsigned long long offset;
694 unsigned long flags; 715 unsigned long flags;
695 int tcode, destination, source; 716 int tcode, destination, source;
696 717
697 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
698 return;
699
700 request = allocate_request(p);
701 if (request == NULL) {
702 /* FIXME: send statically allocated busy packet. */
703 return;
704 }
705
706 offset =
707 ((unsigned long long)
708 HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) | p->header[2];
709 tcode = HEADER_GET_TCODE(p->header[0]); 718 tcode = HEADER_GET_TCODE(p->header[0]);
710 destination = HEADER_GET_DESTINATION(p->header[0]); 719 destination = HEADER_GET_DESTINATION(p->header[0]);
711 source = HEADER_GET_SOURCE(p->header[1]); 720 source = HEADER_GET_SOURCE(p->header[1]);
@@ -732,6 +741,73 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
732 request->data, request->length, 741 request->data, request->length,
733 handler->callback_data); 742 handler->callback_data);
734} 743}
744
745static void handle_fcp_region_request(struct fw_card *card,
746 struct fw_packet *p,
747 struct fw_request *request,
748 unsigned long long offset)
749{
750 struct fw_address_handler *handler;
751 unsigned long flags;
752 int tcode, destination, source;
753
754 if ((offset != (CSR_REGISTER_BASE | CSR_FCP_COMMAND) &&
755 offset != (CSR_REGISTER_BASE | CSR_FCP_RESPONSE)) ||
756 request->length > 0x200) {
757 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
758
759 return;
760 }
761
762 tcode = HEADER_GET_TCODE(p->header[0]);
763 destination = HEADER_GET_DESTINATION(p->header[0]);
764 source = HEADER_GET_SOURCE(p->header[1]);
765
766 if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
767 tcode != TCODE_WRITE_BLOCK_REQUEST) {
768 fw_send_response(card, request, RCODE_TYPE_ERROR);
769
770 return;
771 }
772
773 spin_lock_irqsave(&address_handler_lock, flags);
774 list_for_each_entry(handler, &address_handler_list, link) {
775 if (is_enclosing_handler(handler, offset, request->length))
776 handler->address_callback(card, NULL, tcode,
777 destination, source,
778 p->generation, p->speed,
779 offset, request->data,
780 request->length,
781 handler->callback_data);
782 }
783 spin_unlock_irqrestore(&address_handler_lock, flags);
784
785 fw_send_response(card, request, RCODE_COMPLETE);
786}
787
788void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
789{
790 struct fw_request *request;
791 unsigned long long offset;
792
793 if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE)
794 return;
795
796 request = allocate_request(p);
797 if (request == NULL) {
798 /* FIXME: send statically allocated busy packet. */
799 return;
800 }
801
802 offset = ((u64)HEADER_GET_OFFSET_HIGH(p->header[1]) << 32) |
803 p->header[2];
804
805 if (!is_in_fcp_region(offset, request->length))
806 handle_exclusive_region_request(card, p, request, offset);
807 else
808 handle_fcp_region_request(card, p, request, offset);
809
810}
735EXPORT_SYMBOL(fw_core_handle_request); 811EXPORT_SYMBOL(fw_core_handle_request);
736 812
737void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) 813void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 96768e160866..a61571c63c59 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2226,7 +2226,6 @@ static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
2226 if (rest == 0) 2226 if (rest == 0)
2227 return -EINVAL; 2227 return -EINVAL;
2228 2228
2229 /* FIXME: make packet-per-buffer/dual-buffer a context option */
2230 while (rest > 0) { 2229 while (rest > 0) {
2231 d = context_get_descriptors(&ctx->context, 2230 d = context_get_descriptors(&ctx->context,
2232 z + header_z, &d_bus); 2231 z + header_z, &d_bus);
@@ -2470,7 +2469,10 @@ static int __devinit pci_probe(struct pci_dev *dev,
2470 } 2469 }
2471 2470
2472 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; 2471 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
2472#if 0
2473 /* FIXME: make it a context option or remove dual-buffer mode */
2473 ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; 2474 ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
2475#endif
2474 2476
2475 /* dual-buffer mode is broken if more than one IR context is active */ 2477 /* dual-buffer mode is broken if more than one IR context is active */
2476 if (dev->vendor == PCI_VENDOR_ID_AGERE && 2478 if (dev->vendor == PCI_VENDOR_ID_AGERE &&