diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-07-12 08:50:06 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-07-14 07:06:04 -0400 |
commit | e9aeb46c93a8b1b703d00586c05d9a71aa7e0f0c (patch) | |
tree | 8e20402235bdcdf0e250e90ba02ac9f5eae2b87c /drivers/firewire/fw-transaction.c | |
parent | 792a61021c6043f6c2b24b1cdd42be5753b3e54c (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>
Diffstat (limited to 'drivers/firewire/fw-transaction.c')
-rw-r--r-- | drivers/firewire/fw-transaction.c | 9 |
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 | } |
299 | EXPORT_SYMBOL(fw_send_request); | 298 | EXPORT_SYMBOL(fw_send_request); |