Previous Entry Add to Memories Share Next Entry
xiphmont

Linux eMagic driver update

Every now and then I'm reminded I'm not the last emi2|6 or 6|2m user left in the world-- apparently Debian just recently made some of the changes that broke the eMagic drivers on other distros years ago and I've been getting mail about it again.

Background: The eMagic emi2|6 and 6|2m firmware loaders shipped with the Linux kernel have been broken for many years. Different distros have had them on life support with an inconsistent array of minor patches, but they've got a couple problems across the lot: races in the loader, an incorrect memory target, deadlocking all of USB with synchronous firmware requests in probe(), and the fact that the bitstream.fw file being shipped for the 6|2m is the wrong file. Apparently, someone accidentally substituted the 2|6 version of the file in a code cleanup years ago, and so even if you get the 6|2m loader to work, it crashes the device because it uploads the wrong thing.

Oh, and Linux is apparently shipping a buggy, early version of the firmware without 96kHz support. Even if you don't care about 96kHz for audio production, and you probably shouldn't, the extra frequency range makes these guys a lot more useful as software oscilloscopes.

I've maintained a working version of the driver with updated firmware for the past several years, but getting it into the official kernel always stalled on 'wait, do you have permission from eMagic to use this firmware?' Unfortunately a) Apple bought eMagic and discontinued all their hardware products more than a decade ago, b) to my knowledge, no one ever had explicit permission to use the firmware currently being shipped either. I have no real interest in having a battle over firmware licensing, so my fixes continue to be my own. If Apple turns out to care, I'll pull them down, but I doubt that will happen. I don't think Apple remembers this device even exists. Seriously, they're Bondi Blue. That's soooo late-90's.

Anyway, here's my latest, updated, out-of-kernel firmware loader with the last firmware release form eMagic. It works properly on 2.6.x and 3.x.x kernels for both the emi2|6 and emi6|2m. It replaces the old firmware and two kernel modules with new firmware and a single unified firmware loader module name emi.ko. All new! Such shiny. Wow.

If you have kernel module build dependencies installed, it should be as easy as untarring as root, make, and make install. I also included a 'make remove-old' target to clean out the old driver and avoid any conflicts. It just removes the old modules and firmware files; obviously that might make a packaging system a little pissy (and you'd probably have to re-run it on each kernel update).

tl;dr, get the driver here: http://people.xiph.org/~xiphmont/emagic/

Tags: , , ,

I dream of a world where instead of these broken drivers we would have just dummies that would spit out "Hello! This is just a dummy because we couldn't get Apple to sign a permission. Get the driver at http://people.xiph.org/~xiphmont/emagic/ and nag Apple about it." after modprobe.

How did we break this?

womble2

2013-12-11 03:59 am (UTC)

Every now and then I'm reminded I'm not the last emi2|6 or 6|2m user left in the world-- apparently Debian just recently made some of the changes that broke the eMagic drivers on other distros years ago and I've been getting mail about it again.

We're not patching the driver and it doesn't appear to have changed in any significant way upstream since 2.6.33 (where there was a single bug fix, backported to 2.6.32.y). So if it's regressed since Debian 6.0 'squeeze' this is probably due to changes in the USB stack.

Background: The eMagic emi2|6 and 6|2m firmware loaders shipped with the Linux kernel have been broken for many years. Different distros have had them on life support with an inconsistent array of minor patches, but they've got a couple problems across the lot: races in the loader, an incorrect memory target, deadlocking all of USB with synchronous firmware requests in probe(),

There was a regression in udev last year that would cause drivers that do this to hang for something like 30 seconds. I'm not sure whether that's what you're referring to. It has been fixed in udev (and worked around in the kernel).

and the fact that the bitstream.fw file being shipped for the 6|2m is the wrong file. Apparently, someone accidentally substituted the 2|6 version of the file in a code cleanup years ago, and so even if you get the 6|2m loader to work, it crashes the device because it uploads the wrong thing.

The conversions to use external firmware evidently weren't tested but there were subsequent fixes labelled as having been tested. But you're quite right, emi26/bitstream.fw and emi62/bitstream.fw are identical! I'll see if I can fix this.


Re: How did we break this?

womble2

2013-12-11 04:01 am (UTC)

There was a regression in udev last year that would cause drivers that do this to hang for something like 30 seconds. I'm not sure whether that's what you're referring to. It has been fixed in udev (and worked around in the kernel).

Never mind, I can see this was a different bug you fixed way back in 2006.


Re: How did we break this?

xiphmont

2013-12-11 04:14 am (UTC)

> We're not patching the driver and it doesn't appear to have changed in any significant way upstream since 2.6.33

The loaders were always a bit dodgy as the 'proper' way to do firmware requests shifted over the course of 2.6. The incorrect firmware file for the 6|2m showed up in 2.6.27. Then some other cleanup broke both loaders hard, and plugging in an eMagic box would actually panic the kernel.

Anyway, a few bugs in the loaders [like the panic] got fixed piecemeal at the end of 2.6 without ever actually getting reliably working loaders. Some patches made it, some just evaporated, I got frustrated with submitting patches, and so I just rewrote the whole thing and kept it out of tree. All I cared about was keeping my boxes running.

>There was a regression in udev last year that would cause drivers that do this to hang for something like 30 seconds.

If it's what I expect, this wasn't strictly udev's fault, and systemd still does the same thing, repeatedly triggering 30s of USB hang before giving up.

The simple fact is that drivers should not [now] be making synchronous firmware requests in probe(). Whatever changes got made to udev to mitigate the problem, systemd still triggers the deadlocks that are technically the old loaders' faults.

Note that the default firmware [in addition to shipping the completely wrong bitstream.fw file for the 6|2m] is also buggy-- 6|2m recording, which is sort of the whole point of the device, does not work properly in this early version. Every time you start recording, you have to toggle the switches on the front of the unit before the ADC will actually start running from the correct input source. And the 96kHz support is completely missing. The newer firmware fixes both.


Edited at 2013-12-11 04:25 am (UTC)

Re: How did we break this?

womble2

2013-12-11 05:24 am (UTC)

The incorrect firmware file for the 6|2m showed up in 2.6.27.

I've confirmed that your emi62_bitstream.fw is identical to what used to be in the driver, so this should get fixed shortly.

The simple fact is that drivers should not [now] be making synchronous firmware requests in probe().

This is what Kay Sievers said, but it is a rule he invented to make his life easier.

Whatever changes got made to udev to mitigate the problem, systemd still triggers the deadlocks that are technically the old loaders' faults.

Well, the udev and systemd projects were merged and I think the relevant code is now in libudev which is loaded by one or the other daemon. The kernel will now try to load firmware files directly before sending a uevent, but if a file isn't installed it can still hit this bug.

Note that the default firmware [in addition to shipping the completely wrong bitstream.fw file for the 6|2m] is also buggy-- 6|2m recording, which is sort of the whole point of the device, does not work properly in this early version. Every time you start recording, you have to toggle the switches on the front of the unit before the ADC will actually start running from the correct input source. And the 96kHz support is completely missing. The newer firmware fixes both.

Unfortunately I don't think I can do anything about this due to the unclear licence status.


Re: How did we break this?

womble2

2013-12-15 05:30 am (UTC)

It has been fixed in udev (and worked around in the kernel).

Actually, firmware loading has been removed from udev. So it's fixed in some sense...


> This is what Kay Sievers said, but it is a rule he invented to make his life easier.

Heh. I thought something along the same lines at first, and then decided this was the correct rule whatever the actual motivations behind it. probe() blocks all of USB, and so heavyweight calls should not be happening synchronously in probe(). My only lasting objection is that the [currently] 'correct' way to do the firmware load got changed after everyone wrote to the old system. "How to make sure all legacy drivers break on a regular basis, chapter N", not that I honestly think anyone did that on purpose.

> Well, the udev and systemd projects were merged and I think the relevant code is now in libudev
> which is loaded by one or the other daemon. The kernel will now try to load firmware files directly
> before sending a uevent, but if a file isn't installed it can still hit this bug.

That seems like a good thing irregardless everything else. I'm not sure what sent several Debian users my way in fact-- all they said was 'I upgraded my kernel and everything stopped working, help!' so I gave them my new driver and that made them happy.

> Unfortunately I don't think I can do anything about this due to the unclear licence status.

Right, that's where the patch process keeps stalling. OTOH, there was no permission to use the previous firmware either as far as anyone can find. I've decided to assume the risk and potential moral turpitude as an individual because the alternatives are stupid.

Edited at 2013-12-11 05:37 am (UTC)

You are viewing xiphmont