diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-09-06 18:50:29 +0200 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-09-12 14:48:40 +0200 |
commit | b171e204b32b69e241af994d6e9be559e33535c1 (patch) | |
tree | 0ba90b20dfed4e721a573e2dfe9e4584e8a80737 /drivers/firewire | |
parent | 18668ff9a3232d5f942a2f7abc1ad67d2760dcdf (diff) | |
download | kernel_samsung_tuna-b171e204b32b69e241af994d6e9be559e33535c1.zip kernel_samsung_tuna-b171e204b32b69e241af994d6e9be559e33535c1.tar.gz kernel_samsung_tuna-b171e204b32b69e241af994d6e9be559e33535c1.tar.bz2 |
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 f74edae..e4864e8 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, card->guid = guid; mutex_lock(&card_mutex); - config_rom = generate_config_rom(card, &length); - list_add_tail(&card->link, &card_list); - mutex_unlock(&card_mutex); + config_rom = generate_config_rom(card, &length); ret = card->driver->enable(card, config_rom, length); - if (ret < 0) { - mutex_lock(&card_mutex); - list_del(&card->link); - mutex_unlock(&card_mutex); - } + if (ret == 0) + list_add_tail(&card->link, &card_list); + + mutex_unlock(&card_mutex); return ret; } |