Commit dc4ff5bf authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] add locking to global list in ymfpci.c

This driver has a global list of devices which has no locking.
parent 0f9f751c
...@@ -99,6 +99,7 @@ static void ymfpci_disable_dsp(ymfpci_t *unit); ...@@ -99,6 +99,7 @@ static void ymfpci_disable_dsp(ymfpci_t *unit);
static void ymfpci_download_image(ymfpci_t *codec); static void ymfpci_download_image(ymfpci_t *codec);
static void ymf_memload(ymfpci_t *unit); static void ymf_memload(ymfpci_t *unit);
static spinlock_t ymf_devs_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(ymf_devs); static LIST_HEAD(ymf_devs);
/* /*
...@@ -1912,12 +1913,14 @@ static int ymf_open(struct inode *inode, struct file *file) ...@@ -1912,12 +1913,14 @@ static int ymf_open(struct inode *inode, struct file *file)
} }
unit = NULL; /* gcc warns */ unit = NULL; /* gcc warns */
spin_lock(&ymf_devs_lock);
list_for_each(list, &ymf_devs) { list_for_each(list, &ymf_devs) {
unit = list_entry(list, ymfpci_t, ymf_devs); unit = list_entry(list, ymfpci_t, ymf_devs);
if (((unit->dev_audio ^ minor) & ~0x0F) == 0) if (((unit->dev_audio ^ minor) & ~0x0F) == 0)
break; break;
} }
if (list == &ymf_devs) spin_unlock(&ymf_devs_lock);
if (unit == NULL)
return -ENODEV; return -ENODEV;
down(&unit->open_sem); down(&unit->open_sem);
...@@ -2021,15 +2024,18 @@ static int ymf_open_mixdev(struct inode *inode, struct file *file) ...@@ -2021,15 +2024,18 @@ static int ymf_open_mixdev(struct inode *inode, struct file *file)
ymfpci_t *unit; ymfpci_t *unit;
int i; int i;
spin_lock(&ymf_devs_lock);
list_for_each(list, &ymf_devs) { list_for_each(list, &ymf_devs) {
unit = list_entry(list, ymfpci_t, ymf_devs); unit = list_entry(list, ymfpci_t, ymf_devs);
for (i = 0; i < NR_AC97; i++) { for (i = 0; i < NR_AC97; i++) {
if (unit->ac97_codec[i] != NULL && if (unit->ac97_codec[i] != NULL &&
unit->ac97_codec[i]->dev_mixer == minor) { unit->ac97_codec[i]->dev_mixer == minor) {
spin_unlock(&ymf_devs_lock);
goto match; goto match;
} }
} }
} }
spin_unlock(&ymf_devs_lock);
return -ENODEV; return -ENODEV;
match: match:
...@@ -2607,7 +2613,9 @@ static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_devi ...@@ -2607,7 +2613,9 @@ static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_devi
#endif /* CONFIG_SOUND_YMFPCI_LEGACY */ #endif /* CONFIG_SOUND_YMFPCI_LEGACY */
/* put it into driver list */ /* put it into driver list */
spin_lock(&ymf_devs_lock);
list_add_tail(&codec->ymf_devs, &ymf_devs); list_add_tail(&codec->ymf_devs, &ymf_devs);
spin_unlock(&ymf_devs_lock);
pci_set_drvdata(pcidev, codec); pci_set_drvdata(pcidev, codec);
return 0; return 0;
...@@ -2639,7 +2647,9 @@ static void __devexit ymf_remove_one(struct pci_dev *pcidev) ...@@ -2639,7 +2647,9 @@ static void __devexit ymf_remove_one(struct pci_dev *pcidev)
ymfpci_t *codec = pci_get_drvdata(pcidev); ymfpci_t *codec = pci_get_drvdata(pcidev);
/* remove from list of devices */ /* remove from list of devices */
spin_lock(&ymf_devs_lock);
list_del(&codec->ymf_devs); list_del(&codec->ymf_devs);
spin_unlock(&ymf_devs_lock);
unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer); unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer);
ac97_release_codec(codec->ac97_codec[0]); ac97_release_codec(codec->ac97_codec[0]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment