-
Notifications
You must be signed in to change notification settings - Fork 3.1k
sound/midi: Clarify MPU-401 init #1905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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]>
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
left a comment
There was a problem hiding this 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)) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
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.