aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-14 07:23:58 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-06-14 08:23:42 -0400
commit1e626fdcef61460dc75fe7377f38bb019722b848 (patch)
tree5ae5587507b07ff4832d1f3c53fe4dd01a8636d3
parent837ec787d85fda8d73193a399ebcea0288e4765b (diff)
firewire: core: use more outbound tlabels
Tlabel is a 6 bits wide datum. Wrap it after 63 rather than 31 for more safety against transaction label exhaustion and potential responders' transaction layer bugs. (As noted by Guus Sliepen, this change requires an expansion of tlabel_mask to 64 bits.) Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/core-transaction.c8
-rw-r--r--include/linux/firewire.h3
2 files changed, 6 insertions, 5 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 9a6ce9ab2a67..479b22f5a1eb 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -82,7 +82,7 @@ static int close_transaction(struct fw_transaction *transaction,
82 list_for_each_entry(t, &card->transaction_list, link) { 82 list_for_each_entry(t, &card->transaction_list, link) {
83 if (t == transaction) { 83 if (t == transaction) {
84 list_del(&t->link); 84 list_del(&t->link);
85 card->tlabel_mask &= ~(1 << t->tlabel); 85 card->tlabel_mask &= ~(1ULL << t->tlabel);
86 break; 86 break;
87 } 87 }
88 } 88 }
@@ -288,14 +288,14 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
288 spin_lock_irqsave(&card->lock, flags); 288 spin_lock_irqsave(&card->lock, flags);
289 289
290 tlabel = card->current_tlabel; 290 tlabel = card->current_tlabel;
291 if (card->tlabel_mask & (1 << tlabel)) { 291 if (card->tlabel_mask & (1ULL << tlabel)) {
292 spin_unlock_irqrestore(&card->lock, flags); 292 spin_unlock_irqrestore(&card->lock, flags);
293 callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); 293 callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data);
294 return; 294 return;
295 } 295 }
296 296
297 card->current_tlabel = (card->current_tlabel + 1) & 0x1f; 297 card->current_tlabel = (card->current_tlabel + 1) & 0x3f;
298 card->tlabel_mask |= (1 << tlabel); 298 card->tlabel_mask |= (1ULL << tlabel);
299 299
300 t->node_id = destination_id; 300 t->node_id = destination_id;
301 t->tlabel = tlabel; 301 t->tlabel = tlabel;
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 610eade8abb4..e584b7215e8b 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -98,7 +98,8 @@ struct fw_card {
98 98
99 int node_id; 99 int node_id;
100 int generation; 100 int generation;
101 int current_tlabel, tlabel_mask; 101 int current_tlabel;
102 u64 tlabel_mask;
102 struct list_head transaction_list; 103 struct list_head transaction_list;
103 struct timer_list flush_timer; 104 struct timer_list flush_timer;
104 unsigned long reset_jiffies; 105 unsigned long reset_jiffies;