[PATCH TRIDENT] fix pci_dev reference counting and buglet

From: Muli Ben-Yehuda
Date: Tue Sep 26 2006 - 18:01:57 EST


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: Alan Cox <alan@xxxxxxxxxx>
Signed-off-by: Muli Ben-Yehuda <muli@xxxxxxxxxx>

diff -r 7e955ce92497 sound/oss/trident.c
--- a/sound/oss/trident.c Wed Sep 27 01:49:46 2006 +0700
+++ b/sound/oss/trident.c Wed Sep 27 00:58:36 2006 +0300
@@ -3280,8 +3280,8 @@ ali_setup_spdif_out(struct trident_card
char temp;
struct pci_dev *pci_dev = NULL;

- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return;
pci_read_config_byte(pci_dev, 0x61, &temp);
@@ -3294,6 +3294,8 @@ ali_setup_spdif_out(struct trident_card
temp &= (~0x20);
temp |= 0x10;
pci_write_config_byte(pci_dev, 0x7e, temp);
+
+ pci_dev_put(pci_dev);

ch = inb(TRID_REG(card, ALI_SCTRL));
outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL));
@@ -3501,16 +3503,19 @@ ali_close_multi_channels(void)
char temp = 0;
struct pci_dev *pci_dev = NULL;

- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return -1;
+
pci_read_config_byte(pci_dev, 0x59, &temp);
temp &= ~0x80;
pci_write_config_byte(pci_dev, 0x59, temp);

- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
- pci_dev);
+ pci_dev_put(pci_dev);
+
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+ NULL);
if (pci_dev == NULL)
return -1;

@@ -3518,6 +3523,8 @@ ali_close_multi_channels(void)
temp &= ~0x20;
pci_write_config_byte(pci_dev, 0xB8, temp);

+ pci_dev_put(pci_dev);
+
return 0;
}

@@ -3528,21 +3535,26 @@ ali_setup_multi_channels(struct trident_
char temp = 0;
struct pci_dev *pci_dev = NULL;

- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return -1;
pci_read_config_byte(pci_dev, 0x59, &temp);
temp |= 0x80;
pci_write_config_byte(pci_dev, 0x59, temp);

- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
- pci_dev);
+ pci_dev_put(pci_dev);
+
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+ NULL);
if (pci_dev == NULL)
return -1;
pci_read_config_byte(pci_dev, (int) 0xB8, &temp);
temp |= 0x20;
pci_write_config_byte(pci_dev, (int) 0xB8, (u8) temp);
+
+ pci_dev_put(pci_dev);
+
if (chan_nums == 6) {
dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000;
outl(dwValue, TRID_REG(card, ALI_SCTRL));
@@ -4105,8 +4117,8 @@ ali_reset_5451(struct trident_card *card
unsigned int dwVal;
unsigned short wCount, wReg;

- pci_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- pci_dev);
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+ pci_dev);
if (pci_dev == NULL)
return -1;

@@ -4116,6 +4128,7 @@ ali_reset_5451(struct trident_card *card
pci_read_config_dword(pci_dev, 0x7c, &dwVal);
pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
udelay(5000);
+ pci_dev_put(pci_dev);

pci_dev = card->pci_dev;
if (pci_dev == NULL)
@@ -4395,7 +4408,7 @@ trident_probe(struct pci_dev *pci_dev, c

init_timer(&card->timer);
card->iobase = iobase;
- card->pci_dev = pci_dev;
+ card->pci_dev = pci_dev_get(pci_dev);
card->pci_id = pci_id->device;
card->revision = revision;
card->irq = pci_dev->irq;
@@ -4549,6 +4562,7 @@ out_free_irq:
out_free_irq:
free_irq(card->irq, card);
out_proc_fs:
+ pci_dev_put(card->pci_dev);
if (res) {
remove_proc_entry("ALi5451", NULL);
res = NULL;
@@ -4599,9 +4613,9 @@ trident_remove(struct pci_dev *pci_dev)
}
unregister_sound_dsp(card->dev_audio);

+ pci_set_drvdata(pci_dev, NULL);
+ pci_dev_put(card->pci_dev);
kfree(card);
-
- pci_set_drvdata(pci_dev, NULL);
}

MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee, Muli Ben-Yehuda");
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/