aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-07-12 08:50:06 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-07-14 07:06:04 -0400
commite9aeb46c93a8b1b703d00586c05d9a71aa7e0f0c (patch)
tree8e20402235bdcdf0e250e90ba02ac9f5eae2b87c
parent792a61021c6043f6c2b24b1cdd42be5753b3e54c (diff)
firewire: fully initialize fw_transaction before marking it pending
In theory, card->flush_timer could already access a transaction between fw_send_request()'s spin_unlock_irqrestore and the rest of what happens in fw_send_request(). This would happen if the process which sends the request is preempted and put to sleep right after spin_unlock_irqrestore for longer than 100ms. Therefore we fill in everything in struct fw_transaction at which the flush_timer might look at before we lift the lock. To do: Ensure that the timer does not pick up the transaction before the time of the AT request event plus split transaction timeout. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/fw-transaction.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 40db80752272..7addfb3b070b 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -279,11 +279,6 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
279 card->current_tlabel = (card->current_tlabel + 1) & 0x1f; 279 card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
280 card->tlabel_mask |= (1 << tlabel); 280 card->tlabel_mask |= (1 << tlabel);
281 281
282 list_add_tail(&t->link, &card->transaction_list);
283
284 spin_unlock_irqrestore(&card->lock, flags);
285
286 /* Initialize rest of transaction, fill out packet and send it. */
287 t->node_id = node_id; 282 t->node_id = node_id;
288 t->tlabel = tlabel; 283 t->tlabel = tlabel;
289 t->callback = callback; 284 t->callback = callback;
@@ -294,6 +289,10 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
294 speed, offset, payload, length); 289 speed, offset, payload, length);
295 t->packet.callback = transmit_complete_callback; 290 t->packet.callback = transmit_complete_callback;
296 291
292 list_add_tail(&t->link, &card->transaction_list);
293
294 spin_unlock_irqrestore(&card->lock, flags);
295
297 card->driver->send_request(card, &t->packet); 296 card->driver->send_request(card, &t->packet);
298} 297}
299EXPORT_SYMBOL(fw_send_request); 298EXPORT_SYMBOL(fw_send_request);