Thursday, December 21, 2006

Functionality Summary

I'm using this post to keep a complete list of all the problems and solutions.

Sound
01/07/2007 - I get headphone sound if I mute the speakers. Go figure. I'm not saying it's fixed, but it's less broke.
12/21/2006 - Audio jacks are ignored. Back to work on this one.
12/18/2006 - Finally got some sound out of my speakers, but only with oss.


APIC
12/18/2006 - After more testing it became clear that while my solution works, it isn't optimal. The research continues.
12/17/2006 - I tried a bunch of stuff that didn't work, so I went ahead and modified the kernel source. It appeared to work.
12/02/2006 - I started doing research and found a patch for the 2.2 kernel to allow manual setting of interrupt types. I decided to keep doing research to see if there was a better way.
11/21/2006 - I originally switched APIC off so X would start.


USB
I originally listed USB as not working (it would crash and take the network subsystem with it), but all problems were created by my APIC problem.

Headphone jack doesn't work

My very first commenter, rreagan3, asked if I had done any testing of the headphone jack before I ran around screaming that it worked. I hadn't, so of course it doesn't work. Nothing happens when I plug headphones into any of the sound jacks. It goes on my TODO list.

Monday, December 18, 2006

Sound Off

Which is not what I want. I want it on. So here we go. Now that I've sort of got a handle on my APIC issue I thought I'd take a crack at getting sound working.

According to the Alsa Project the driver the NVidia MCP51 High Definition Audio Card is the intel8x0. As far as I can tell, this is a lie. I tried every way from sunday to get that driver to load. Nothing ever happened. I got fed up with it and tried shotgunning.

For those of you who don't build your own kernel (or haven't shotgunned before), it basically works like this. When you don't know what driver works, you compile them all in and see what happens. This works a remarkably high amount of the time for my network and sound card.

Not this time. The driver snd-hda-intel claimed the card, but /dev/dsp did not get made and mpg123 didn't work. Crud. I decided to try using the alsa-drivers package since it generally contains newer stuff than the kernel. I followed the Gentoo Alsa Guide and switched from kernel sound to user-space sound. I ignored the bit about setting a specific card and compiled them all in. Alsaconf found the card and installed the snd-hda-intel. So much for the website.

Of course, I still didn't have /dev/dsp but I did have some stuff in /dev/snd. Per suggestion from the Gentoo Alsa Guide I tried using aplay to play something (a random wave from /usr/share). It actually worked. I played a crappy wave in all it's 8-bit glory. Now I just had to figure out why nothing else would play.

I started poking around in /proc/asound to see if anything looked interesting and I noticed that I was missing the oss stuff. On a whim, I installed the ALSA-OSS compatibility layer and /dev/dsp appeared. On the up side, I now have sound. On the down side, it's obviously OSS. I'll fight the ALSA battle another day.

Expounding on the kludge

My kludge seems to be turning out reasonably well for me, so I thought I'd give a more thorough explanation of what I did. To recap, when ACPI is enabled, the kernel sets basically all the devices to be edge-triggered. This is bad.

I've researched an obscene number of possible solutions, but I'll discuss those later as some of them may still prove to be better solutions overall than my current one. On with the show.

The kernel determines what kind of trigger to set an IRQ to by calling MPBIOS_trigger in arch/$ARCH/kernel/io_apic.c. Basically, it takes an integer and runs through some cases and returns the trigger at the bottom. Reading through it, you'll quickly notice that one of the cases is labeled the "edge" case. In my case, I pretty much wanted everything on IRQ 11 to be level-triggered. If you just groaned aloud, you guessed it.

In the "edge" case, I slapped my if statment in the middle of things so it reads:

case 1: /* edge */
{
trigger = 0
if (idx == 11) {
trigger = 1;
}
break;
}

Sure enough, when the computer starts up everything that used to be on IRQ 9 and/or 11 now has it's own interrupt and they are all level triggered. I'll admit that I was a little weirded out to see my sound card on IRQ 20. I don't know what the implications are for that sort of thing but I'm sure I'll find out.

My testing so far has revealed only the problem I mentioned in the previous post: boot freezes about 2/3 of the time when trying to set the system clock from hardware. This is almost certainly related to my change, but it's an acceptable trade for now.

Sunday, December 17, 2006

an introductory kludge

First, I'd like to say that I hate blogger.com. They've lost my post 4 times now, so it's going to be real short.

I modified io_apic.c in the kernel sources so they returned level_triggered for anything that reported being on irq 11. That's not really a great idea, but the only effect I've noticed so far is that the computer hangs on boot about half the time. Once it's up, it seems to be fine.

Saturday, December 02, 2006

A possible irq override patch

A friend suggested that I see if there were any updates to my BIOS. I had checked before, but I thought I might get lucky. Lo and behold, a new BIOS (F.1A) had been posted in early November. Of course, the things it claimed to fix had nothing to do with my problems, but I figured I'd give it a shot anyway. No dice. It does exactly what it says it does. Those bastards.

Moving on to google, I found my first promising lead in a July 2000 post on kerneltraffic.org from a guy with the same problem (bios reporting incorrect interrupt types with a need to override). A few days later, he responded to his own post saying he had found a patch from July 1999 that allowed the override. The patch applied to the 2.2.10 kernel, but at least it was an idea.

Hoping that this feature had made its way permanently into the kernel, I added ioapic_level=10,11 to my kernel options and rebooted. Absolutely nothing changed. So much for luck. I'll stick this in my back pocket for now. I'd rather not write my own kernel patch if I can help it. But if it comes to that, I'll do it.