2001-04-30 16:41:22

by Jeff Garzik

[permalink] [raw]
Subject: PATCH 2.4.4: Via audio fixes

Index: linux_2_4/drivers/sound/via82cxxx_audio.c
diff -u linux_2_4/drivers/sound/via82cxxx_audio.c:1.1.1.16 linux_2_4/drivers/sound/via82cxxx_audio.c:1.1.1.16.70.3
--- linux_2_4/drivers/sound/via82cxxx_audio.c:1.1.1.16 Sat Mar 3 18:12:35 2001
+++ linux_2_4/drivers/sound/via82cxxx_audio.c Mon Apr 30 09:35:21 2001
@@ -15,7 +15,7 @@
*/


-#define VIA_VERSION "1.1.14b"
+#define VIA_VERSION "1.1.15"


#include <linux/config.h>
@@ -92,6 +92,7 @@
#endif

/* 82C686 function 5 (audio codec) PCI configuration registers */
+#define VIA_ACLINK_STATUS 0x40
#define VIA_ACLINK_CTRL 0x41
#define VIA_FUNC_ENABLE 0x42
#define VIA_PNP_CONTROL 0x43
@@ -1405,20 +1406,41 @@
#endif

/*
- * reset AC97 controller: enable, disable, enable
- * pause after each command for good luck
+ * Reset AC97 controller: enable, disable, enable,
+ * pausing after each command for good luck. Only
+ * do this if the codec is not ready, because it causes
+ * loud pops and such due to such a hard codec reset.
*/
- pci_write_config_byte (pdev, VIA_ACLINK_CTRL, VIA_CR41_AC97_ENABLE |
- VIA_CR41_AC97_RESET | VIA_CR41_AC97_WAKEUP);
- udelay (100);
-
- pci_write_config_byte (pdev, VIA_ACLINK_CTRL, 0);
- udelay (100);
-
- pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
- VIA_CR41_AC97_ENABLE | VIA_CR41_PCM_ENABLE |
- VIA_CR41_VRA | VIA_CR41_AC97_RESET);
- udelay (100);
+ pci_read_config_byte (pdev, VIA_ACLINK_STATUS, &tmp8);
+ if ((tmp8 & VIA_CR40_AC97_READY) == 0) {
+ pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
+ VIA_CR41_AC97_ENABLE |
+ VIA_CR41_AC97_RESET |
+ VIA_CR41_AC97_WAKEUP);
+ udelay (100);
+
+ pci_write_config_byte (pdev, VIA_ACLINK_CTRL, 0);
+ udelay (100);
+
+ pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
+ VIA_CR41_AC97_ENABLE |
+ VIA_CR41_PCM_ENABLE |
+ VIA_CR41_VRA | VIA_CR41_AC97_RESET);
+ udelay (100);
+ }
+
+ /* Make sure VRA is enabled, in case we didn't do a
+ * complete codec reset, above
+ */
+ pci_read_config_byte (pdev, VIA_ACLINK_CTRL, &tmp8);
+ if (((tmp8 & VIA_CR41_VRA) == 0) ||
+ ((tmp8 & VIA_CR41_AC97_ENABLE) == 0) ||
+ ((tmp8 & VIA_CR41_PCM_ENABLE) == 0) ||
+ ((tmp8 & VIA_CR41_AC97_RESET) == 0))
+ pci_write_config_byte (pdev, VIA_ACLINK_CTRL,
+ VIA_CR41_AC97_ENABLE |
+ VIA_CR41_PCM_ENABLE |
+ VIA_CR41_VRA | VIA_CR41_AC97_RESET);

#if 0 /* this breaks on K7M */
/* disable legacy stuff */
@@ -1983,17 +2005,16 @@
tmp = atomic_read (&chan->n_frags);
assert (tmp >= 0);
assert (tmp <= chan->frag_number);
- while (tmp == 0) {
+ if (tmp == 0) {
+ int ret;
if (nonblock || !chan->is_active)
return -EAGAIN;

DPRINTK ("Sleeping on block %d\n", n);
- interruptible_sleep_on (&chan->wait);
-
- if (signal_pending (current))
- return -ERESTARTSYS;
-
- tmp = atomic_read (&chan->n_frags);
+ ret = wait_event_interruptible(chan->wait,
+ (tmp = atomic_read(&chan->n_frags)));
+ if (ret < 0)
+ return ret;
}

/* Now that we have a buffer we can read from, send
@@ -2130,17 +2151,16 @@
tmp = atomic_read (&chan->n_frags);
assert (tmp >= 0);
assert (tmp <= chan->frag_number);
- while (tmp == 0) {
+ if (tmp == 0) {
+ int ret;
if (nonblock || !chan->is_enabled)
return -EAGAIN;

DPRINTK ("Sleeping on page %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record);
- interruptible_sleep_on (&chan->wait);
-
- if (signal_pending (current))
- return -ERESTARTSYS;
-
- tmp = atomic_read (&chan->n_frags);
+ ret = wait_event_interruptible(chan->wait,
+ (tmp = atomic_read(&chan->n_frags)));
+ if (ret < 0)
+ return ret;
}

/* Now that we have at least one fragment we can write to, fill the buffer
@@ -2324,7 +2344,8 @@

via_chan_maybe_start (chan);

- while (atomic_read (&chan->n_frags) < chan->frag_number) {
+ if (atomic_read (&chan->n_frags) < chan->frag_number) {
+ int ret;
if (nonblock) {
DPRINTK ("EXIT, returning -EAGAIN\n");
return -EAGAIN;
@@ -2357,11 +2378,11 @@
#endif

DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_frags));
- interruptible_sleep_on (&chan->wait);
-
- if (signal_pending (current)) {
+ ret = wait_event_interruptible(chan->wait,
+ (atomic_read (&chan->n_frags) >= chan->frag_number));
+ if (ret < 0) {
DPRINTK ("EXIT, returning -ERESTARTSYS\n");
- return -ERESTARTSYS;
+ return ret;
}
}

@@ -3012,7 +3033,6 @@
{
int rc;
struct via_info *card;
- u8 tmp;
static int printed_version = 0;

DPRINTK ("ENTER\n");
@@ -3020,24 +3040,19 @@
if (printed_version++ == 0)
printk (KERN_INFO "Via 686a audio driver " VIA_VERSION "\n");

- if (!request_region (pci_resource_start (pdev, 0),
- pci_resource_len (pdev, 0),
- VIA_MODULE_NAME)) {
- printk (KERN_ERR PFX "unable to obtain I/O resources, aborting\n");
- rc = -EBUSY;
+ rc = pci_enable_device (pdev);
+ if (rc)
goto err_out;
- }

- if (pci_enable_device (pdev)) {
- rc = -EIO;
- goto err_out_none;
- }
+ rc = pci_request_regions (pdev, "via82cxxx_audio");
+ if (rc)
+ goto err_out;

card = kmalloc (sizeof (*card), GFP_KERNEL);
if (!card) {
printk (KERN_ERR PFX "out of memory, aborting\n");
rc = -ENOMEM;
- goto err_out_none;
+ goto err_out_res;
}

pci_set_drvdata (pdev, card);
@@ -3108,19 +3123,6 @@
goto err_out_have_proc;
}

- pci_read_config_byte (pdev, 0x3C, &tmp);
- if ((tmp & 0x0F) != pdev->irq) {
- printk (KERN_WARNING PFX "IRQ fixup, 0x3C==0x%02X\n", tmp);
- udelay (15);
- tmp &= 0xF0;
- tmp |= pdev->irq;
- pci_write_config_byte (pdev, 0x3C, tmp);
- DPRINTK ("new 0x3c==0x%02x\n", tmp);
- } else {
- DPRINTK ("IRQ reg 0x3c==0x%02x, irq==%d\n",
- tmp, tmp & 0x0F);
- }
-
printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n",
card->card_num + 1, card->baseaddr, pdev->irq);

@@ -3142,8 +3144,8 @@
#endif
kfree (card);

-err_out_none:
- release_region (pci_resource_start (pdev, 0), pci_resource_len (pdev, 0));
+err_out_res:
+ pci_release_regions (pdev);
err_out:
pci_set_drvdata (pdev, NULL);
DPRINTK ("EXIT - returning %d\n", rc);
@@ -3166,7 +3168,7 @@
via_dsp_cleanup (card);
via_ac97_cleanup (card);

- release_region (pci_resource_start (pdev, 0), pci_resource_len (pdev, 0));
+ pci_release_regions (pdev);

#ifndef VIA_NDEBUG
memset (card, 0xAB, sizeof (*card)); /* poison memory */


Attachments:
via.patch (6.44 kB)

2001-04-30 20:32:04

by Greg Hosler

[permalink] [raw]
Subject: RE: PATCH 2.4.4: Via audio fixes


On 30-Apr-01 Jeff Garzik wrote:
> The attached patch includes fixes to the Via audio driver for which I'm
> interested finding testers. Testing and a private "it works" (hopefully
>:)) or "it doesn't work, <here> is what breaks for me" would be
> appreciated.
> --
> Jeff Garzik | Game called on account of naked chick
> Building 1024 |
> MandrakeSoft |

it doesn't work.

configuration: SMP, ac'97, IRQ gets assigned to 18.

problem: interrupts appear to not be firing. Neither PRINTK() in
via_intr_channel() or via_interrupt() ever get called (suggesting that
the interrupt is either not firing, or not connected to the service routine).

I've enabled debug, and have more information in the logs, but the short answer
is "the interrupts aren't firing".

in single processor more, no problem. (but that was always the case).

-Greg

+---------------------------------------------------------------------+
"DOS Computers manufactured by companies such as IBM, Compaq, Tandy, and
millions of others are by far the most popular, with about 70 million
machines in use wordwide. Macintosh fans, on the other hand, may note that
cockroaches are far more numerous than humans, and that numbers alone do
not denote a higher life form." (New York Times, November 26, 1991)
| Greg Hosler i-net: [email protected] |
+---------------------------------------------------------------------+

2001-04-30 20:42:14

by Jeff Garzik

[permalink] [raw]
Subject: Re: PATCH 2.4.4: Via audio fixes

Would it be possible for you to make a code change and send me the dmesg
output?

Update linux/arch/i386/kernel/pci-i386.h and change
-#undef DEBUG
+#define DEBUG 1

Recompile, and privately e-mail me "dmesg -s 16384" output...

--
Jeff Garzik | Game called on account of naked chick
Building 1024 |
MandrakeSoft |