Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+29 −15
Original line number Original line Diff line number Diff line
@@ -3269,7 +3269,7 @@ 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;
@@ -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)
	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)
	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,7 +3524,7 @@ 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;
@@ -3525,13 +3532,18 @@ ali_setup_multi_channels(struct trident_card *card, int chan_nums)
	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,7 +4115,7 @@ 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)
	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)


	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)
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)
		}
		}
	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");