[alsa-devel] MTP-AV Bugs

Holger Dehnhardt dehnhardt at ahdehnhardt.de
Tue Feb 10 21:54:32 CET 2009

Hi everybody,

I recently started again to use my older music equipment and try to get it 
work under Linux.

One of these things is an Motu Midi Express XT (8 Port Midi Interface at 
parallel port), which is listed as supported along with the Motu MidiTimePiece 

After upgrading to a recent Kernel, sending Midi from an Sequencer Programm to 
the Interface was working, but connecting an input port resulted in an 
immediate kernel freeze.

After trying some different parallel port settings and some other things, I 
upgraded to the latest alsa release (alsa-driver-1.0.19) and after the problem 
remains, started debugging the driver. (Because I never did any driver 
programming I only used print statements and returns to locate the point of 
failure..., if anyone of you has a good tutorial about debugging kernel 
modules - please sent a private Mail...)

After some time I found the following bug:

static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
        if (inbyte >= 0xf8) {
                /* real-time midi code */
-->                snd_mtpav_inmidi_process(mcrd, inbyte);
	//here the inmidiport is not translated to the prtnumber, so 
	// snd_mtpav_inmidi_process the port with an index of some 80000 
	// in the ports array of the mtpav struct was called

        if (mcrd->inmidistate == 0) {   // awaiting command
                if (inbyte == 0xf5)     // MTP port #
                        mcrd->inmidistate = 1;
                        snd_mtpav_inmidi_process(mcrd, inbyte);
        } else if (mcrd->inmidistate) {
                mcrd->inmidiport = 
			translate_hwport_to_subdevice(mcrd, inbyte);
                mcrd->inmidistate = 0;

The following change made the driver work:
static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
        if (inbyte >= 0xf8) {
                /* real-time midi code */
		mcrd->inmidiport = translate_hwport_to_subdevice(mcrd, inbyte);
                snd_mtpav_inmidi_process(mcrd, inbyte);

After that I realised, that with the recent driver - even without my change - 
playing midi files din not work anymore.
Only the first midi event was sent to the interface, everything else was 
dropped somewhere.

So a diff between the last workin version and the recent version showed only 
one change:
<       card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card));
<       if (! card)
<               return -ENOMEM;
>       err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), 
>       if (err < 0)
>               return err;

which seems due to an api change. After rolling that back to the old 
(deprecated) way of creating the sound card, everything works fine.

Could someone with a little bit more experience in driver programming please 
look into the first change.

For the second change I would be happy about every tip why the old way works 
and the new way not. I'm willing to correct this as well.

Thank you for listening!


More information about the Alsa-devel mailing list