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 AV.
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 return; }
if (mcrd->inmidistate == 0) { // awaiting command if (inbyte == 0xf5) // MTP port # mcrd->inmidistate = 1; else 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); return; } ....
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: 699,701c703,705 < 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),
&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!
Holger