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