diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2010-06-10 02:37:15 -0400 |
---|---|---|
committer | Clemens Ladisch <clemens@ladisch.de> | 2010-06-10 02:37:15 -0400 |
commit | 7e0e314f198d5048b74c8f0ef9f4c1c02e5ecfc9 (patch) | |
tree | 513fcf8f87f6b24121d4e4eb07e1345e29d81db2 | |
parent | 4ffb7a6a066e4be4577976d1c08e237c7479770a (diff) |
firewire: core: add CSR abdicate support
Implement the abdicate bit, which is required for bus manager
capable nodes and tested by the Base 1394 Test Suite.
Finally, something to do at a command reset! :-)
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
-rw-r--r-- | drivers/firewire/core-card.c | 3 | ||||
-rw-r--r-- | drivers/firewire/core-topology.c | 2 | ||||
-rw-r--r-- | drivers/firewire/core-transaction.c | 13 | ||||
-rw-r--r-- | drivers/firewire/core.h | 1 | ||||
-rw-r--r-- | include/linux/firewire.h | 2 |
5 files changed, 18 insertions, 3 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index d0f15c2f1e1d..7c4cf6cfa746 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -260,7 +260,8 @@ static void fw_card_bm_work(struct work_struct *work) | |||
260 | 260 | ||
261 | grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); | 261 | grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); |
262 | 262 | ||
263 | if (is_next_generation(generation, card->bm_generation) || | 263 | if ((is_next_generation(generation, card->bm_generation) && |
264 | !card->bm_abdicate) || | ||
264 | (card->bm_generation != generation && grace)) { | 265 | (card->bm_generation != generation && grace)) { |
265 | /* | 266 | /* |
266 | * This first step is to figure out who is IRM and | 267 | * This first step is to figure out who is IRM and |
diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index 93ec64cdeef7..ca3c65318165 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c | |||
@@ -552,6 +552,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, | |||
552 | smp_wmb(); | 552 | smp_wmb(); |
553 | card->generation = generation; | 553 | card->generation = generation; |
554 | card->reset_jiffies = jiffies; | 554 | card->reset_jiffies = jiffies; |
555 | card->bm_abdicate = card->csr_abdicate; | ||
556 | card->csr_abdicate = false; | ||
555 | fw_schedule_bm_work(card, 0); | 557 | fw_schedule_bm_work(card, 0); |
556 | 558 | ||
557 | local_node = build_tree(card, self_ids, self_id_count); | 559 | local_node = build_tree(card, self_ids, self_id_count); |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index e0c6cce894cf..85a54da243e2 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -1008,6 +1008,10 @@ static u32 read_state_register(struct fw_card *card) | |||
1008 | /* Bit 8 (cmstr): */ | 1008 | /* Bit 8 (cmstr): */ |
1009 | value |= card->driver->read_csr_reg(card, CSR_STATE_CLEAR); | 1009 | value |= card->driver->read_csr_reg(card, CSR_STATE_CLEAR); |
1010 | 1010 | ||
1011 | /* Bit 10 (abdicate): */ | ||
1012 | if (card->csr_abdicate) | ||
1013 | value |= CSR_STATE_BIT_ABDICATE; | ||
1014 | |||
1011 | return value; | 1015 | return value; |
1012 | } | 1016 | } |
1013 | 1017 | ||
@@ -1041,6 +1045,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
1041 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { | 1045 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { |
1042 | card->driver->write_csr_reg(card, CSR_STATE_CLEAR, | 1046 | card->driver->write_csr_reg(card, CSR_STATE_CLEAR, |
1043 | be32_to_cpu(*data)); | 1047 | be32_to_cpu(*data)); |
1048 | if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) | ||
1049 | card->csr_abdicate = false; | ||
1044 | } else { | 1050 | } else { |
1045 | rcode = RCODE_TYPE_ERROR; | 1051 | rcode = RCODE_TYPE_ERROR; |
1046 | } | 1052 | } |
@@ -1052,7 +1058,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
1052 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { | 1058 | } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { |
1053 | card->driver->write_csr_reg(card, CSR_STATE_SET, | 1059 | card->driver->write_csr_reg(card, CSR_STATE_SET, |
1054 | be32_to_cpu(*data)); | 1060 | be32_to_cpu(*data)); |
1055 | /* FIXME: implement abdicate */ | 1061 | if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) |
1062 | card->csr_abdicate = true; | ||
1056 | } else { | 1063 | } else { |
1057 | rcode = RCODE_TYPE_ERROR; | 1064 | rcode = RCODE_TYPE_ERROR; |
1058 | } | 1065 | } |
@@ -1070,7 +1077,9 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
1070 | break; | 1077 | break; |
1071 | 1078 | ||
1072 | case CSR_RESET_START: | 1079 | case CSR_RESET_START: |
1073 | if (tcode != TCODE_WRITE_QUADLET_REQUEST) | 1080 | if (tcode == TCODE_WRITE_QUADLET_REQUEST) |
1081 | card->csr_abdicate = false; | ||
1082 | else | ||
1074 | rcode = RCODE_TYPE_ERROR; | 1083 | rcode = RCODE_TYPE_ERROR; |
1075 | break; | 1084 | break; |
1076 | 1085 | ||
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index aaecdd1c1767..a9ace1f8dc3f 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -41,6 +41,7 @@ struct fw_packet; | |||
41 | #define FEATURE_PRIORITY_BUDGET 0x01 | 41 | #define FEATURE_PRIORITY_BUDGET 0x01 |
42 | 42 | ||
43 | #define CSR_STATE_BIT_CMSTR (1 << 8) | 43 | #define CSR_STATE_BIT_CMSTR (1 << 8) |
44 | #define CSR_STATE_BIT_ABDICATE (1 << 10) | ||
44 | 45 | ||
45 | struct fw_card_driver { | 46 | struct fw_card_driver { |
46 | /* | 47 | /* |
diff --git a/include/linux/firewire.h b/include/linux/firewire.h index f1160e831dad..4d22643215ef 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h | |||
@@ -119,6 +119,8 @@ struct fw_card { | |||
119 | int bm_retries; | 119 | int bm_retries; |
120 | int bm_generation; | 120 | int bm_generation; |
121 | __be32 bm_transaction_data[2]; | 121 | __be32 bm_transaction_data[2]; |
122 | bool bm_abdicate; /* value of csr_abdicate before last bus reset */ | ||
123 | bool csr_abdicate; /* visible in CSR STATE_CLEAR/SET registers */ | ||
122 | 124 | ||
123 | bool broadcast_channel_allocated; | 125 | bool broadcast_channel_allocated; |
124 | u32 broadcast_channel; | 126 | u32 broadcast_channel; |