aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-10 16:09:28 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-24 15:56:52 -0400
commit7889b60ee71eafaf50699a154a2455424bb92daa (patch)
treed5bb3a4d274bf186e32605284a34a36398475818 /drivers/firewire/fw-device.c
parentcbae787c0f288c3ad385ad4165ae30b5500a1f23 (diff)
firewire: core: optimize propagation of BROADCAST_CHANNEL
Cache the test result of whether a device implements BROADCAST_CHANNEL. This minimizes traffic on the bus after each bus reset. A majority of devices does not implement BROADCAST_CHANNEL. Remove busy retries; just rely on the hardware to retry requests to busy responders. Remove unnecessary log messages. Rename the flag is_irm to broadcast_channel_allocated to better reflect its meaning. Reset the flag earlier in fw_core_handle_bus_reset. Pass the generation down as a call parameter; that way generation can't be newer than card->broadcast_channel_allocated and device->node_id. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r--drivers/firewire/fw-device.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index a40444e8eb20..a47e2129d83d 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -518,7 +518,7 @@ static int read_bus_info_block(struct fw_device *device, int generation)
518 518
519 kfree(old_rom); 519 kfree(old_rom);
520 ret = 0; 520 ret = 0;
521 device->cmc = rom[2] & 1 << 30; 521 device->cmc = rom[2] >> 30 & 1;
522 out: 522 out:
523 kfree(rom); 523 kfree(rom);
524 524
@@ -756,6 +756,44 @@ static int lookup_existing_device(struct device *dev, void *data)
756 return match; 756 return match;
757} 757}
758 758
759enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
760
761void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
762{
763 struct fw_card *card = device->card;
764 __be32 data;
765 int rcode;
766
767 if (!card->broadcast_channel_allocated)
768 return;
769
770 if (device->bc_implemented == BC_UNKNOWN) {
771 rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
772 device->node_id, generation, device->max_speed,
773 CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
774 &data, 4);
775 switch (rcode) {
776 case RCODE_COMPLETE:
777 if (data & cpu_to_be32(1 << 31)) {
778 device->bc_implemented = BC_IMPLEMENTED;
779 break;
780 }
781 /* else fall through to case address error */
782 case RCODE_ADDRESS_ERROR:
783 device->bc_implemented = BC_UNIMPLEMENTED;
784 }
785 }
786
787 if (device->bc_implemented == BC_IMPLEMENTED) {
788 data = cpu_to_be32(BROADCAST_CHANNEL_INITIAL |
789 BROADCAST_CHANNEL_VALID);
790 fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
791 device->node_id, generation, device->max_speed,
792 CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
793 &data, 4);
794 }
795}
796
759static void fw_device_init(struct work_struct *work) 797static void fw_device_init(struct work_struct *work)
760{ 798{
761 struct fw_device *device = 799 struct fw_device *device =
@@ -849,9 +887,8 @@ static void fw_device_init(struct work_struct *work)
849 device->config_rom[3], device->config_rom[4], 887 device->config_rom[3], device->config_rom[4],
850 1 << device->max_speed); 888 1 << device->max_speed);
851 device->config_rom_retries = 0; 889 device->config_rom_retries = 0;
852 if (device->card->is_irm) 890
853 fw_irm_set_broadcast_channel_register(&device->device, 891 fw_device_set_broadcast_channel(device, device->generation);
854 NULL);
855 } 892 }
856 893
857 /* 894 /*