Skip to content

Conversation

@n-p-soft
Copy link
Contributor

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.

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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
@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.

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.

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".

* (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?

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