From b77f95af463e6e3ebf6e75d689cab3913517bedf Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 10 Jun 2010 08:37:15 +0200 Subject: [PATCH] --- yaml --- r: 206815 b: refs/heads/master c: 7e0e314f198d5048b74c8f0ef9f4c1c02e5ecfc9 h: refs/heads/master i: 206813: 0a07eb4092f71160ba44a92543ac747277fa373c 206811: 0c50f91004d87d6d9cc1b0d0672b8c916ceaa295 206807: a64bbad21554a28ea750297da74c2a6755f0ced3 206799: ab6751debdd2c6a5b8981e9cc40b3e5f7223f959 206783: 0226ca6c52b398e4f35214112673e9866653429d v: v3 --- [refs] | 2 +- trunk/drivers/firewire/core-card.c | 3 ++- trunk/drivers/firewire/core-topology.c | 2 ++ trunk/drivers/firewire/core-transaction.c | 13 +++++++++++-- trunk/drivers/firewire/core.h | 1 + trunk/include/linux/firewire.h | 2 ++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index a284f54419d7..4b1e456b257f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4ffb7a6a066e4be4577976d1c08e237c7479770a +refs/heads/master: 7e0e314f198d5048b74c8f0ef9f4c1c02e5ecfc9 diff --git a/trunk/drivers/firewire/core-card.c b/trunk/drivers/firewire/core-card.c index d0f15c2f1e1d..7c4cf6cfa746 100644 --- a/trunk/drivers/firewire/core-card.c +++ b/trunk/drivers/firewire/core-card.c @@ -260,7 +260,8 @@ static void fw_card_bm_work(struct work_struct *work) grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); - if (is_next_generation(generation, card->bm_generation) || + if ((is_next_generation(generation, card->bm_generation) && + !card->bm_abdicate) || (card->bm_generation != generation && grace)) { /* * This first step is to figure out who is IRM and diff --git a/trunk/drivers/firewire/core-topology.c b/trunk/drivers/firewire/core-topology.c index 93ec64cdeef7..ca3c65318165 100644 --- a/trunk/drivers/firewire/core-topology.c +++ b/trunk/drivers/firewire/core-topology.c @@ -552,6 +552,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, smp_wmb(); card->generation = generation; card->reset_jiffies = jiffies; + card->bm_abdicate = card->csr_abdicate; + card->csr_abdicate = false; fw_schedule_bm_work(card, 0); local_node = build_tree(card, self_ids, self_id_count); diff --git a/trunk/drivers/firewire/core-transaction.c b/trunk/drivers/firewire/core-transaction.c index e0c6cce894cf..85a54da243e2 100644 --- a/trunk/drivers/firewire/core-transaction.c +++ b/trunk/drivers/firewire/core-transaction.c @@ -1008,6 +1008,10 @@ static u32 read_state_register(struct fw_card *card) /* Bit 8 (cmstr): */ value |= card->driver->read_csr_reg(card, CSR_STATE_CLEAR); + /* Bit 10 (abdicate): */ + if (card->csr_abdicate) + value |= CSR_STATE_BIT_ABDICATE; + return value; } @@ -1041,6 +1045,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { card->driver->write_csr_reg(card, CSR_STATE_CLEAR, be32_to_cpu(*data)); + if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) + card->csr_abdicate = false; } else { rcode = RCODE_TYPE_ERROR; } @@ -1052,7 +1058,8 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) { card->driver->write_csr_reg(card, CSR_STATE_SET, be32_to_cpu(*data)); - /* FIXME: implement abdicate */ + if (*data & cpu_to_be32(CSR_STATE_BIT_ABDICATE)) + card->csr_abdicate = true; } else { rcode = RCODE_TYPE_ERROR; } @@ -1070,7 +1077,9 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, break; case CSR_RESET_START: - if (tcode != TCODE_WRITE_QUADLET_REQUEST) + if (tcode == TCODE_WRITE_QUADLET_REQUEST) + card->csr_abdicate = false; + else rcode = RCODE_TYPE_ERROR; break; diff --git a/trunk/drivers/firewire/core.h b/trunk/drivers/firewire/core.h index aaecdd1c1767..a9ace1f8dc3f 100644 --- a/trunk/drivers/firewire/core.h +++ b/trunk/drivers/firewire/core.h @@ -41,6 +41,7 @@ struct fw_packet; #define FEATURE_PRIORITY_BUDGET 0x01 #define CSR_STATE_BIT_CMSTR (1 << 8) +#define CSR_STATE_BIT_ABDICATE (1 << 10) struct fw_card_driver { /* diff --git a/trunk/include/linux/firewire.h b/trunk/include/linux/firewire.h index f1160e831dad..4d22643215ef 100644 --- a/trunk/include/linux/firewire.h +++ b/trunk/include/linux/firewire.h @@ -119,6 +119,8 @@ struct fw_card { int bm_retries; int bm_generation; __be32 bm_transaction_data[2]; + bool bm_abdicate; /* value of csr_abdicate before last bus reset */ + bool csr_abdicate; /* visible in CSR STATE_CLEAR/SET registers */ bool broadcast_channel_allocated; u32 broadcast_channel;