Reanimating a Zombie: CAPI4Linux

Tuesday, 19 January 2010 08:46 Jan

CAPI4Linux Rescue

For more than 5 years I'm running my home gateway with an ancient FRITZ!Card DSL v2.0. That's a dual channel adapter acting both as an ISDN interface as well as an ADSL modem. It supports up to 6 MBit/s downstream. No longer amazingly fast but still sufficient here. The nice thing about it is that it's only a single PCI card in my gateway box, no external device with additional powering required. But while the hardware is fine, its software sucked from the very first day.

The DSLv2 is pasive card. Wide parts of its lower ISDN and DSL stack run on the host. Only the signal processing is executed on a DSP, basically the heart of this PCI adapter. So the vendor, AVM, kept a lot of its core know-how on the host PC, specifically in the driver binary. Well, you may already guess what this means for Linux: a huge binary blob and a smaller "license adapter" form a proprietary device driver called fcdsl2 - the nightmare of every Linux user and developer.

Yet this nightmare worked more or less reliable for me over the last years. A few hacks were required to get it working with recent kernels and a few more hacks to fix the most annoying bugs. As the locking scheme of this thing always looked suspicious and many people already added various bits to improve it, I cowardly ran my box in CONFIG_PREEMPT_NONE mode. All was fine as long as the DSL connection was up and running.

Unfortunately, DSL links get lost once in a while, cut at least once per day by my provider. pppd was not always able to recover from this. Sometimes a full reload of the driver was required, triggered by a watchdog script. And of those reloads, some ended up in an unresponsive gateway, usually a crashed one. That happened once per month down to once per week - probably depending on the weather or my current bad aura level. Mostly too infrequent to start acting, but still too frequent to ignore it.

So, after another crash cut my home link over Christmas, I finally started looking into this mess. The original plan was to review and fix the fcdsl2, which would likely mean rewriting some parts of it - that was clear. But if I had known in advance how much was broken, well, I don't think I would have started this hack. Not only the driver required a complete locking rework, also the Linux CAPI stack that connects pppd and ISDN tools with the fcdsl2 was part of the problem.

OK, the CAPI stacks has its roots in an AVM driver that was written in the past millennium. That were the days when SMP and kernel preemption were far away from from being common. Some attempts were made to evolve the code towards a proper locking scheme, but the efforts widely stalled many years ago (see history before 2.6.12 and mostly drive-by changes for at least 6 years). So the stack was now in a zombie state: fairly broken inside, not much in use anymore (you can buy ready-to-use DSL+phone routers today), but not yet obsolete as at least a few CAPI-speaking adapters are still around (e.g. Gigaset equipment).

So I started digging my way through the CAPI code:

 Documentation/devices.txt      |    7 +-
drivers/isdn/capi/Kconfig | 3 +-
drivers/isdn/capi/capi.c | 937 ++++++++++++++++++----------------------
drivers/isdn/capi/capidrv.c | 48 +--
drivers/isdn/capi/capifs.c | 126 +++---
drivers/isdn/capi/capifs.h | 21 +-
drivers/isdn/capi/kcapi.c | 797 ++++++++++++++++++----------------
drivers/isdn/capi/kcapi.h | 12 +-
drivers/isdn/capi/kcapi_proc.c | 41 +-
include/linux/isdn/capilli.h | 2 +-
include/linux/kernelcapi.h | 17 +-
11 files changed, 1005 insertions(+), 1006 deletions(-)

The results are 31 kernel patches, mostly touching the user space interface (capi.c), the driver layer (kcapi.c), and the special CAPI filesystem (capifs.c). I did not look very long into capidrv.c, the adapter to the legacy ISDN stack of Linux. That adapter is broken like the rest was. But I'm afraid I would have to continue with digging into the almost obsolete ISDN code, and that is huge. Instead, I decided to replace the last local user of that part, isdnlog from the isdn4k-utils, with a CAPI version, but work on that hasn't started yet.

The series is currently parked in my git tree, waiting for submission after some final stress tests. That should be completed in a few days. Stay tuned for more news from the CAPI front. Next time I will report about my endeavor fixing the FRITZ!Card DSL v2.0 driver itself.

Last Updated on Tuesday, 19 January 2010 09:00