Skip to content

Conversation

@n-p-soft
Copy link
Contributor

@n-p-soft n-p-soft commented Nov 29, 2025

First, we try to better init MPU-401 chip so that it is put in UART mode using the recommended way: <wait_for_ack><enable_uart_mode>. This must be done before the interrupt handler is active, so that the ACK is the only data received between the two commands. Actually this setup may occur after interrupts are enabled for the card.

Second, there is a mechanism to periodically call the interrupt handler, probably to address very old or spurious cards. We remove this because all cards in the tree using MPU-401 (CSMedia chips, Crystal chips, and Soundblasters) have proper interrupt handling for MIDI events.

Rather old hardware is concerned; but PCI soundcards may work fine using a PCIe-to-PCI bridge, and some have pretty decent chipsets.

25/12/09: testing against some hardware

  • snd_emu10kx (Soundblaster): seems to work, other tests to come. PR to enable MIDI code.
  • snd_emu10k1 (previous Soundblaster driver): MIDI not working, probably due to a bad setup of the card. As emu10kx is working for (most of? all?) these cards, is it useful to keep this code ?
  • snd_cmi (C-Media): I only have a cheap Chinese board. MIDI-IN is working (hardware problem for MIDI-OUT on my board). Patch needed to enable MIDI code (few lines, PR to come).
  • snd_csa (Crystal): I'm trying to get a cheap card to test this driver. Patch probably needed.

n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Nov 29, 2025
NOTE: this depends on pull requests freebsd#1905 and freebsd#1892.

MIDI code in emu10kx driver was disabled due to possible locking problems
in MIDI core, which should have been corrected by freebsd#1905.

Here, we also fixed that the card interrupts were enabled too early and
disabled too late.

This was tested under FreeBSD 15.0 using a SoundBlaster Audigy
(chipset CA0100, I will also try one Audigy2).

Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Nov 29, 2025
NOTE: this depends on pull requests freebsd#1902 and freebsd#1905.

MIDI code in emu10kx driver was disabled due to possible locking problems
in MIDI core, which should have been corrected by freebsd#1902.

Here, we also fixed that the card interrupts were enabled too early and
disabled too late.

This was tested under FreeBSD 15.0 using a SoundBlaster Audigy
(chipset CA0100, I will also try one Audigy2).

Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
@christosmarg christosmarg self-requested a review December 2, 2025 10:16
Copy link
Contributor

@christosmarg christosmarg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly good, just some notes.

for (i = 0; i < MPU_TRYDATA; i++) {
if (TXRDY(m))
return (1);
else if (RXRDY(m))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned in the old PR, it'd be good to have a comment here explaining the reason for discarding input. It is not obvious to someone looking at this for the first time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rework all these comments soon.

return (0);
}

/* Some cards only support UART mode but others will start in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should start on the next line. Same applies to other multi-line comments.

}

/* Some cards only support UART mode but others will start in
* "Intelligent" mode, so we must try to switch to UART mode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we say that "we must try to switch to UART mode" but I do not think it is entirely clear why we must do this. I'm not saying it's not correct to do this, but the comment should also explain the "why" in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, the intelligent mode may change on-the-fly the MIDI messages in some way, whereas in UART mode, the raw bytes are simply transmitted, then safely processed by userspace tools. When a card supports the intelligent mode, it is enabled by default.

i++;
/* DELAY(100); */
s = STATUS(m);
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} else {

Same below.

if ((m->flags & M_TXEN) && (m->si)) {
callout_reset(&m->timer, 1, mpu401_timeout, m);
/* Read and buffer all input bytes, then send data.
* Note that pending input may inhibits data sending.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inhibits -> inhibit

callout_reset(&m->timer, 1, mpu401_timeout, m);
/* Read and buffer all input bytes, then send data.
* Note that pending input may inhibits data sending.
* Spurious cards may also be sticky, so limit the count of tries
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should explain what "sticky" means. Also "number of tries", not "count of tries".

Copy link
Contributor Author

@n-p-soft n-p-soft Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this because there is no spurious (for example: bad interrupts) card in the FreeBSD tree, to my knowledge.

* (probably MPU cards have no more than 16 bytes as internal buffer).
*/
for (i = 0; RXRDY(m) && i < MPU_INTR_BUF; i++) {
/* XXX we should check midi_in has room in its buffer, else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this patch does not do what the comment here says?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the midi_in function (midi.c) should be modified to report when its buffer is full. Ideally we should ensure midi_in has room to store the byte before reading it from the MPU. MIDI commands are multi-byte (often 3 bytes) so each byte matters.

As I noticed you're working on midi.c, are you sure the data queues (midiq.h) are safe ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be more precise, to get the room available in the input queue, we need a lock on the midi device, which is taken in the function midi_in.
For example we could modify midi_in to return the number of bytes available in the input queue if it is passed a NULL buffer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE (25/12/10): there is a panic in midi_read/midi_write when opening in blocking mode, I think it is the msleep call.

@n-p-soft n-p-soft force-pushed the mpu-init branch 4 times, most recently from 3e283cd to 21b2ca2 Compare December 9, 2025 10:03
n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Dec 9, 2025
    NOTE: this depends on pull request freebsd#1905.

    MIDI code in cmi driver (C-Media sound cards) was disabled due to possible
    locking problems in MIDI core, which should have been corrected by freebsd#1902
    (or another pending PR).

    This was tested under FreeBSD 15.0 against a CM8738 generic card.

    Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Dec 9, 2025
    NOTE: this depends on pull requests freebsd#1902 (or similar pending PR) and freebsd#1905.

    MIDI code in emu10kx driver was disabled due to possible locking problems
    in MIDI core, which should have been corrected by freebsd#1902.

    Here, we also fixed that the card interrupts were enabled too early and
    disabled too late.

    This was tested under FreeBSD 15.0 using a SoundBlaster Audigy
    (chipset CA0100, I will also try one Audigy2).

    Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Dec 9, 2025
    NOTE: this depends on pull request freebsd#1905.

    MIDI code in cmi driver (C-Media sound cards) was disabled due to
    possible locking problems in MIDI core, which should have been
    corrected by freebsd#1902 (or another pending PR).

    This was tested under FreeBSD 15.0 against a CM8738 generic card.

    Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Dec 9, 2025
    NOTE: this depends on pull request freebsd#1905.

    MIDI code in cmi driver (C-Media sound cards) was disabled due to
    possible locking problems in MIDI core, which should have been
    corrected by freebsd#1902 (or another pending PR).

    This was tested under FreeBSD 15.0 against a CM8738 generic card.

    Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
First, we try to better init MPU-401 chip so that it is put in UART mode
using the recommended way: <reset><wait_for_ack><enable_uart_mode>. This
must be done before the interrupt handler is active, so that the ACK is
the only data received between the two commands. Actually this setup may
occur after interrupts are enabled for the card.

Second, there is a mechanism to periodically call the interrupt handler,
probably to address very old or spurious cards. We remove this because
all cards in the tree using MPU-401 (CSMedia chips, Crystal chips, and
Soundblasters) have proper interrupt handling for MIDI events.

Rather old hardware is concerned; but PCI soundcards may work fine using
a PCIe-to-PCI bridge, and some have pretty decent chipsets.

Signed-off-by: Nicolas Provost <dev@nicolas-provost.fr>
n-p-soft added a commit to n-p-soft/freebsd-src that referenced this pull request Dec 11, 2025
    Only midi.c and mpu401.c files are modified.

    - changes to MPU-401 published in freebsd#1905
    - remove MPU_CALLBACKP from the MPU interface (same as MPU_CALLBACK)
    - changes to midi.c published in freebsd#1902 (locks)
    = midi.c: fix a kernel panic when opening a MIDI device in blocking mode
    - midi.c: remove useless 'busy' field in MIDI device data
    - midi.c: silently ignore errors when closing device (ex: process crash)
    - midi.c: correct how to unload MIDI device when unloading a driver
    - midi.c: clarify when rchan/wchan are set to 1 or 0
@github-actions
Copy link

github-actions bot commented Dec 11, 2025

Thank you for taking the time to contribute to FreeBSD!
There is an issue that needs to be fixed:

  • Missing Signed-off-by lines (0f7ab48)

Please review CONTRIBUTING.md, then update and push your branch again.

@n-p-soft
Copy link
Contributor Author

n-p-soft commented Dec 11, 2025

Made a test using the following:

MIDI reads and writes are well processed, in blocking and non-blocking mode, using my Soundblaster Audigy2 (emu10kx).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants