diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-09-06 12:50:29 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-09-12 08:48:40 -0400 |
commit | b171e204b32b69e241af994d6e9be559e33535c1 (patch) | |
tree | 0ba90b20dfed4e721a573e2dfe9e4584e8a80737 /drivers/firewire | |
parent | 18668ff9a3232d5f942a2f7abc1ad67d2760dcdf (diff) |
firewire: core: fix race with parallel PCI device probe
The config ROM buffer received from generate_config_rom is a globally
shared static buffer. Extend the card_mutex protection in fw_add_card
until after the config ROM was copied into the card driver's buffer.
Otherwise, parallelized card driver probes may end up with ROM contents
that were meant for a different card.
firewire-ohci's card->driver->enable hook is safe to be called within
the card_mutex. Furthermore, it is safe to reorder card_list update
versus card enable, which simplifies the code a little.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-card.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index f74edae5cb4c..e4864e894e4f 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -444,16 +444,13 @@ int fw_card_add(struct fw_card *card, | |||
444 | card->guid = guid; | 444 | card->guid = guid; |
445 | 445 | ||
446 | mutex_lock(&card_mutex); | 446 | mutex_lock(&card_mutex); |
447 | config_rom = generate_config_rom(card, &length); | ||
448 | list_add_tail(&card->link, &card_list); | ||
449 | mutex_unlock(&card_mutex); | ||
450 | 447 | ||
448 | config_rom = generate_config_rom(card, &length); | ||
451 | ret = card->driver->enable(card, config_rom, length); | 449 | ret = card->driver->enable(card, config_rom, length); |
452 | if (ret < 0) { | 450 | if (ret == 0) |
453 | mutex_lock(&card_mutex); | 451 | list_add_tail(&card->link, &card_list); |
454 | list_del(&card->link); | 452 | |
455 | mutex_unlock(&card_mutex); | 453 | mutex_unlock(&card_mutex); |
456 | } | ||
457 | 454 | ||
458 | return ret; | 455 | return ret; |
459 | } | 456 | } |