diff options
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r-- | drivers/firewire/fw-device.c | 45 |
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 | ||
759 | enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, }; | ||
760 | |||
761 | void 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 | |||
759 | static void fw_device_init(struct work_struct *work) | 797 | static 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 | /* |