NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/50278: umidi(4) loses first incoming message after second open



>Number:         50278
>Category:       kern
>Synopsis:       umidi(4) loses first incoming message after second open
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Sep 26 20:15:00 +0000 2015
>Originator:     Andreas Gustafsson
>Release:        NetBSD-current as of today; also NetBSD 6.1.5
>Organization:

>Environment:
System: NetBSD guiro.gson.org
Architecture: i386
Machine: i386
>Description:

I'm trying to use an external MIDI device via an Edirol UM-1SX USB
MIDI interface and the umidi(4) driver.  I'm using the "raw" device,
/dev/rmidi1.

The transmit side seems to work, but I'm having a strange problem with
the receive side.  The first time I run my program after booting the
machine or plugging in the USB cable, it works fine.  But when I run
the program for a second time, or in other words, after /dev/rmidi1 is
closed and re-opened, the program fails to receive the first MIDI
message transmitted by the external device after the device has been
opened.  The second and subsequent messages are received; only the
first message that arrives after the device has been reopened is lost.

>How-To-Repeat:

Connect a USB MIDI interface to a NetBSD machine, and set up a
loopback by connecting a MIDI cable from its output back to its input.

Compile the following test program, which attempts to send a single
MIDI message to itself through the loopback cable and verify that it
is arrives unchanged:

#include <err.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

unsigned char data[3] = { 0x90, 0x40, 0x7F };
unsigned char rbuf[3];

int main(int argc, char **argv) {
    if (argc < 2)
        errx(1, "missing argument");
    alarm(5);
    int fd = open(argv[1], O_RDWR);
    if (fd < 0)
        err(1, "open");
    ssize_t r = write(fd, data, sizeof data);
    if (r < 0)
        err(1, "write");
    if (r != sizeof data)
        errx(1, "short write");
    unsigned char *p = rbuf;
    unsigned char *end = rbuf + sizeof rbuf;
    while (p < end) {
        r = read(fd, p, end - p);
        printf("read %d bytes\n", (int) r);
        if (r < 0)
            err(1, "read");
        p += r;
    }
    if (memcmp(data, rbuf, sizeof data) != 0)
        errx(1, "mismatch");
    printf("pass\n");
    return 0;
}

Run the program twice, giving the name of the raw MIDI interface as a
command line argument each time.  You will see something like this:

  $ ./a.out /dev/rmidi1
  read 3 bytes
  pass
  $ ./a.out /dev/rmidi1
  Alarm clock

where the "Alarm clock" indicates that the program timed out trying
to read the looped-back data.

>Fix:

Don't know.  In case it helps, here is the dmesg output from
running the above test on a kernel with "options AUDIO_DEBUG"
and mididebug=9:

umidi0 at uhub0 port 2 configuration 1 interface 0
umidi0: EDIROL UM-1, rev 1.10/2.00, addr 2
umidi0: (genuine USB-MIDI)
umidi0: out=1, in=1
midiprobe: type=1 sa=0xdd60ccc4 hw=0xc0d47c60
midi1 at umidi0MIDI attach
: <0 >0 on umidi0
midiopen 0xc5886008
midiwrite: 0xc5886008, unit=1, count=3
midi_fst: s=0xc5886984 data=0x90 state=0
midi_fst: s=0xc5886984 data=0x40 state=12
midi_fst: s=0xc5886984 data=0x7f state=16
midiwrite: uio_resid now 0, props=3
midi_out: 0xc5886008
midiread: 0xc5886008, count=3
midi_fst: s=0xc5886924 data=0x90 state=0
midi_fst: s=0xc5886924 data=0x40 state=12
midi_fst: s=0xc5886924 data=0x7f state=16
midiread: uiomove cc=3
midiclose 0xc5886008
midiopen 0xc5886008
midiwrite: 0xc5886008, unit=1, count=3
midi_fst: s=0xc5886984 data=0x90 state=0
midi_fst: s=0xc5886984 data=0x40 state=12
midi_fst: s=0xc5886984 data=0x7f state=16
midiwrite: uio_resid now 0, props=3
midi_out: 0xc5886008
midiread: 0xc5886008, count=3
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midi_out: 0xc5886008
midiclose 0xc5886008



Home | Main Index | Thread Index | Old Index