Commit 1cfee2b3 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] trident: fix pci_dev reference counting and buglet

Switch trident to use pci_get/put_dev properly.  Also fix a bug where the
driver erroneously passed pdev not NULL to a second search.  This happened
to always work except with pci=reverse because of chip ordering.
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarMuli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b2e9c7d0
...@@ -3269,8 +3269,8 @@ ali_setup_spdif_out(struct trident_card *card, int flag) ...@@ -3269,8 +3269,8 @@ ali_setup_spdif_out(struct trident_card *card, int flag)
char temp; char temp;
struct pci_dev *pci_dev = NULL; struct pci_dev *pci_dev = NULL;
pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
pci_dev); pci_dev);
if (pci_dev == NULL) if (pci_dev == NULL)
return; return;
pci_read_config_byte(pci_dev, 0x61, &temp); pci_read_config_byte(pci_dev, 0x61, &temp);
...@@ -3284,6 +3284,8 @@ ali_setup_spdif_out(struct trident_card *card, int flag) ...@@ -3284,6 +3284,8 @@ ali_setup_spdif_out(struct trident_card *card, int flag)
temp |= 0x10; temp |= 0x10;
pci_write_config_byte(pci_dev, 0x7e, temp); pci_write_config_byte(pci_dev, 0x7e, temp);
pci_dev_put(pci_dev);
ch = inb(TRID_REG(card, ALI_SCTRL)); ch = inb(TRID_REG(card, ALI_SCTRL));
outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL)); outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL));
ch = inb(TRID_REG(card, ALI_SPDIF_CTRL)); ch = inb(TRID_REG(card, ALI_SPDIF_CTRL));
...@@ -3490,16 +3492,19 @@ ali_close_multi_channels(void) ...@@ -3490,16 +3492,19 @@ ali_close_multi_channels(void)
char temp = 0; char temp = 0;
struct pci_dev *pci_dev = NULL; struct pci_dev *pci_dev = NULL;
pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
pci_dev); pci_dev);
if (pci_dev == NULL) if (pci_dev == NULL)
return -1; return -1;
pci_read_config_byte(pci_dev, 0x59, &temp); pci_read_config_byte(pci_dev, 0x59, &temp);
temp &= ~0x80; temp &= ~0x80;
pci_write_config_byte(pci_dev, 0x59, temp); pci_write_config_byte(pci_dev, 0x59, temp);
pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, pci_dev_put(pci_dev);
pci_dev);
pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
NULL);
if (pci_dev == NULL) if (pci_dev == NULL)
return -1; return -1;
...@@ -3507,6 +3512,8 @@ ali_close_multi_channels(void) ...@@ -3507,6 +3512,8 @@ ali_close_multi_channels(void)
temp &= ~0x20; temp &= ~0x20;
pci_write_config_byte(pci_dev, 0xB8, temp); pci_write_config_byte(pci_dev, 0xB8, temp);
pci_dev_put(pci_dev);
return 0; return 0;
} }
...@@ -3517,21 +3524,26 @@ ali_setup_multi_channels(struct trident_card *card, int chan_nums) ...@@ -3517,21 +3524,26 @@ ali_setup_multi_channels(struct trident_card *card, int chan_nums)
char temp = 0; char temp = 0;
struct pci_dev *pci_dev = NULL; struct pci_dev *pci_dev = NULL;
pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
pci_dev); pci_dev);
if (pci_dev == NULL) if (pci_dev == NULL)
return -1; return -1;
pci_read_config_byte(pci_dev, 0x59, &temp); pci_read_config_byte(pci_dev, 0x59, &temp);
temp |= 0x80; temp |= 0x80;
pci_write_config_byte(pci_dev, 0x59, temp); pci_write_config_byte(pci_dev, 0x59, temp);
pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, pci_dev_put(pci_dev);
pci_dev);
pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
NULL);
if (pci_dev == NULL) if (pci_dev == NULL)
return -1; return -1;
pci_read_config_byte(pci_dev, (int) 0xB8, &temp); pci_read_config_byte(pci_dev, (int) 0xB8, &temp);
temp |= 0x20; temp |= 0x20;
pci_write_config_byte(pci_dev, (int) 0xB8, (u8) temp); pci_write_config_byte(pci_dev, (int) 0xB8, (u8) temp);
pci_dev_put(pci_dev);
if (chan_nums == 6) { if (chan_nums == 6) {
dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000; dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000;
outl(dwValue, TRID_REG(card, ALI_SCTRL)); outl(dwValue, TRID_REG(card, ALI_SCTRL));
...@@ -4103,8 +4115,8 @@ ali_reset_5451(struct trident_card *card) ...@@ -4103,8 +4115,8 @@ ali_reset_5451(struct trident_card *card)
unsigned int dwVal; unsigned int dwVal;
unsigned short wCount, wReg; unsigned short wCount, wReg;
pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
pci_dev); pci_dev);
if (pci_dev == NULL) if (pci_dev == NULL)
return -1; return -1;
...@@ -4114,6 +4126,7 @@ ali_reset_5451(struct trident_card *card) ...@@ -4114,6 +4126,7 @@ ali_reset_5451(struct trident_card *card)
pci_read_config_dword(pci_dev, 0x7c, &dwVal); pci_read_config_dword(pci_dev, 0x7c, &dwVal);
pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff); pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
udelay(5000); udelay(5000);
pci_dev_put(pci_dev);
pci_dev = card->pci_dev; pci_dev = card->pci_dev;
if (pci_dev == NULL) if (pci_dev == NULL)
...@@ -4393,7 +4406,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) ...@@ -4393,7 +4406,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
init_timer(&card->timer); init_timer(&card->timer);
card->iobase = iobase; card->iobase = iobase;
card->pci_dev = pci_dev; card->pci_dev = pci_dev_get(pci_dev);
card->pci_id = pci_id->device; card->pci_id = pci_id->device;
card->revision = revision; card->revision = revision;
card->irq = pci_dev->irq; card->irq = pci_dev->irq;
...@@ -4547,6 +4560,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) ...@@ -4547,6 +4560,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
out_free_irq: out_free_irq:
free_irq(card->irq, card); free_irq(card->irq, card);
out_proc_fs: out_proc_fs:
pci_dev_put(card->pci_dev);
if (res) { if (res) {
remove_proc_entry("ALi5451", NULL); remove_proc_entry("ALi5451", NULL);
res = NULL; res = NULL;
...@@ -4597,9 +4611,9 @@ trident_remove(struct pci_dev *pci_dev) ...@@ -4597,9 +4611,9 @@ trident_remove(struct pci_dev *pci_dev)
} }
unregister_sound_dsp(card->dev_audio); unregister_sound_dsp(card->dev_audio);
kfree(card);
pci_set_drvdata(pci_dev, NULL); pci_set_drvdata(pci_dev, NULL);
pci_dev_put(card->pci_dev);
kfree(card);
} }
MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee, Muli Ben-Yehuda"); MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee, Muli Ben-Yehuda");
......
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