diff options
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-transaction.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index f33a629c8379..6971400b6354 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -969,6 +969,30 @@ static const struct fw_address_region registers_region = | |||
969 | { .start = CSR_REGISTER_BASE, | 969 | { .start = CSR_REGISTER_BASE, |
970 | .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; | 970 | .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; |
971 | 971 | ||
972 | static u32 read_state_register(struct fw_card *card) | ||
973 | { | ||
974 | /* | ||
975 | * Fixed bits (IEEE 1394-2008 8.3.2.2.1): | ||
976 | * Bits 0-1 (state) always read 00=running. | ||
977 | * Bits 2,3 (off, atn) are not implemented as per the spec. | ||
978 | * Bit 4 (elog) is not implemented because there is no error log. | ||
979 | * Bit 6 (dreq) cannot be set. It is intended to "disable requests | ||
980 | * from unreliable nodes"; however, IEEE 1212 states that devices | ||
981 | * may "clear their own dreq bit when it has been improperly set". | ||
982 | * Our implementation might be seen as an improperly extensive | ||
983 | * interpretation of "improperly", but the 1212-2001 revision | ||
984 | * dropped this bit altogether, so we're in the clear. :o) | ||
985 | * Bit 7 (lost) always reads 0 because a power reset has never occurred | ||
986 | * during normal operation. | ||
987 | * Bit 9 (linkoff) is not implemented because the PC is not powered | ||
988 | * from the FireWire cable. | ||
989 | * Bit 15 (gone) always reads 0. It must be set at a power/command/bus | ||
990 | * reset, but then cleared when the units are ready again, which | ||
991 | * happens immediately for us. | ||
992 | */ | ||
993 | return 0; | ||
994 | } | ||
995 | |||
972 | static void handle_registers(struct fw_card *card, struct fw_request *request, | 996 | static void handle_registers(struct fw_card *card, struct fw_request *request, |
973 | int tcode, int destination, int source, int generation, | 997 | int tcode, int destination, int source, int generation, |
974 | int speed, unsigned long long offset, | 998 | int speed, unsigned long long offset, |
@@ -979,6 +1003,26 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
979 | int rcode = RCODE_COMPLETE; | 1003 | int rcode = RCODE_COMPLETE; |
980 | 1004 | ||
981 | switch (reg) { | 1005 | switch (reg) { |
1006 | case CSR_STATE_CLEAR: | ||
1007 | if (tcode == TCODE_READ_QUADLET_REQUEST) { | ||
1008 | *data = cpu_to_be32(read_state_register(card)); | ||
1009 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { | ||
1010 | } else { | ||
1011 | rcode = RCODE_TYPE_ERROR; | ||
1012 | } | ||
1013 | break; | ||
1014 | |||
1015 | case CSR_STATE_SET: | ||
1016 | if (tcode == TCODE_READ_QUADLET_REQUEST) { | ||
1017 | *data = cpu_to_be32(read_state_register(card)); | ||
1018 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { | ||
1019 | /* FIXME: implement cmstr */ | ||
1020 | /* FIXME: implement abdicate */ | ||
1021 | } else { | ||
1022 | rcode = RCODE_TYPE_ERROR; | ||
1023 | } | ||
1024 | break; | ||
1025 | |||
982 | case CSR_CYCLE_TIME: | 1026 | case CSR_CYCLE_TIME: |
983 | if (TCODE_IS_READ_REQUEST(tcode) && length == 4) | 1027 | if (TCODE_IS_READ_REQUEST(tcode) && length == 4) |
984 | *data = cpu_to_be32(card->driver->get_cycle_time(card)); | 1028 | *data = cpu_to_be32(card->driver->get_cycle_time(card)); |