-
Notifications
You must be signed in to change notification settings - Fork 3.1k
sound/mpu: clarify MPU-401 init #1888
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
Conversation
Signed-off-by: Nicolas Provost <[email protected]>
|
Thank you for taking the time to contribute to FreeBSD! Please review CONTRIBUTING.md, then update and push your branch again. |
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.
This is an initial review. Also note that I do not own a physical MIDI device (only USB ones), so I'm unable to test this.
I think it is necessary to update the commit message with an explanation of your approach and what these changes do, as they are not really obvious.
sys/dev/sound/midi/mpu401.c
Outdated
| static void mpu401_mcallback(struct snd_midi *, void *, int); | ||
| static void mpu401_mcallbackp(struct snd_midi *, void *, int); | ||
| static const char *mpu401_mdescr(struct snd_midi *, void *, int); | ||
| static const char *mpu401_mprovider(struct snd_midi *, void *); |
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.
Are these needed somewhere?
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.
Probably not, I started working on 13.5 source tree..
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.
I have made a few cleanups in the MIDI codebase, so I'd strongly advise you do your development on main (-CURRENT)
sys/dev/sound/midi/mpu401.c
Outdated
| } | ||
|
|
||
| #define MPU_TIMEOUT 50 | ||
| #define MPU_PAUSE pause_sbt("mpusetup", SBT_1MS, 0, 0) |
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.
I would suggest you define this as an inline function instead.
| } | ||
| printf("mpu401_minit failed active sensing\n"); | ||
| return 1; | ||
| return (0); |
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.
What is the rationale for merging parts of this with mpu401_setup()?
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.
This init is now run before the interrupt handler is active. The function returns 0 even on failure because we may have a card that is always in 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.
That should also definitely be documented, and also explain why this should run before the interrupt handler.
sys/dev/sound/midi/mpu401.c
Outdated
| static int | ||
| mpu401_intr(struct mpu401 *m) | ||
| { | ||
| MIDI_TYPE b; |
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.
Why this type? What does it expand to?
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.
This type was used in the file before (see midi.h) ! I agree it should be resolved to unsigned char.
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 said in a previous comment, please write the patches on top of main, not 13.5.
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.
Ah ok ! Was wondering is someone was interested by these changes, and the starting point for me was a project under 13.5.
sys/dev/sound/midi/mpu401.c
Outdated
| * Note that pending input may inhibits data sending. | ||
| * Spurious cards may also be sticky.. | ||
| */ | ||
| for (i = 0; RXRDY(m) && i < 512; i++) { |
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.
I suppose your comment about "pending input may inhibits data sending" is probably why you cap to 512 iterations, but why 512 iterations specifically? Same question applies to loop below.
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 you say, it is an upper bound. I've really not idea what to set here -512 is probably too much. I've no such sticky card but I read that this may happen (probably no more nowadays -ISA cards ?).
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.
That should be documented IMHO.
| if (midi_out(m->mid, &b, 1)) | ||
| WRITE(m, b); | ||
| else | ||
| break; |
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 current mpu401_intr() returns in this case, is there a reason we break here instead?
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 the callout_reset be called in this case ?
Also, we can avoid missing one byte in this code but this case is tied to midi_in/midi_out functions in midi.c.
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.
Not really sure about the callout to be honest.
sys/dev/sound/midi/mpu401.c
Outdated
| #define MPU_INPUTBUSY 0x80 | ||
| #define MPU_TRYDATA 50 | ||
| #define MPU_DELAY 2500 | ||
| #define MPU_INTR_BUF 64 |
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 current value is 16, why are you increasing it?
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.
This is related to the changes I'm currently working on in midi.c (functions midi_in and midi_out). I will probably publish changes for both midi.c and mpu401.c.
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.
If this is needed by a follow-up patch, then that change should be in that patch instead, but also documented.
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.
Ok, to explain my goals: I noticed the MIDI support in sound/pci/emu10kx.c is not enabled for unknown reasons. I've enabled it for my SoundBlaster Audigy 2 (two fixes in the code) but this brings me to review midi.c and mpu401.c. In midi.c, there may be locking issues due to the two mutexes (one is probably enough) and perhaps buffering problems. In mpu401.c, the init was not optimal. My Audigy's MIDI-IN port is now working but some work is to be done. Is there a PCI card with a really working MIDI port under FreeBSD ?
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.
There are locking issues indeed, and I'm pretty sure quite a few Lock Order Reversals. In fact, for months now my plan has been to scrap the whole current MIDI codebase and rewrite it cleanly. We could try to address some of the obvious issues temporarily at least, but do know that I will most likely rewrite this anyway. The current structure is rather obsolete and confusing, and does not work with USB MIDI.
If you do own physical MIDI devices, I would appreciate it a lot if we could do some testing together.
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 PCI card with a really working MIDI port under FreeBSD ?
Not really sure to be honest. Haven't checked.
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.
What I'm currently planning:
- mpu401.c: update changes to match branch 'main'.
- midi.c: remove one of the two mutexes to avoid possible inter-locks. I think only midi.c and mpu401.are directly concerned in the whole kernel.
- midi.c: rework midi_in and replace the current buffering queue with a simple buffer [currently testing]. Same thing for midi-out (is it currently working ?).
- midi.c: code cleaning
- pci/: enable MIDI for SoundBlaster Audigy 2 cards [currently testing]. Test other cards for MIDI support.
- take care of not breaking too much OSS !
PCI devices that are concerned are quite old, but work well using a PCIe-to-PCI bridge, and some have pretty decent hardware.
|
The new commits are confusing and quite hard to see what's going on. The second commit especially (35d1d1c) seems to be deleting what I already removed in e4b3198. The rest of the commits seem to be mixed up also. Could you please clean this up first? That is, combine everything into one commit, and make sure your branch is tracking the most recent main. First |
|
I'm sorry but I cancel this pull request (#1888): I'm now working on branch main and created a fresh one (#1892).
It seems that the callout_xxx stuff is using the giant lock which may be remove d in 15.0. So I also disabled it and I'm testing this.
N. Provost
Le 19 novembre 2025 13:49:16 GMT+01:00, Christos Margiolis ***@***.***> a écrit :
…christosmarg left a comment (freebsd/freebsd-src#1888)
The new commits are confusing and quite hard to see what's going on. The second commit especially (35d1d1c) seems to be deleting what I already removed in e4b3198. The rest of the commits seem to be mixed up also.
Could you please clean this up first? That is, combine everything into one commit, and make sure your branch is tracking the most recent main. First `git pull` on `main`, and then in your branch (assuming you don't work on `main` directly): `git rebase main`.
--
Reply to this email directly or view it on GitHub:
#1888 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
… 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 trigger the interrupt handler which is using the Giant lock, probably to address very old (ISA ?) or spurious cards. Giant lock being removed, we disable this when our new init succeeds. Rather old hardware is concerned; but a PCI soundcard may work fine using a PCIe-to-PCI bridge, and some cards have pretty decent chipsets. Signed-off-by: Nicolas Provost <[email protected]>
Signed-off-by: Nicolas Provost <[email protected]>
…ode 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 trigger the interrupt handler which is using the Giant lock, probably to address very old (ISA ?) or spurious cards. Giant lock being removed, we disable this when our new init succeeds. Rather old hardware is concerned; but a PCI soundcard may work fine using a PCIe-to-PCI bridge, and some cards have pretty decent chipsets. Signed-off-by: Nicolas Provost <[email protected]>
Signed-off-by: Nicolas Provost <[email protected]>
First, we try to better initialize the 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 trigger the interrupt handler which is using the Giant lock, probably to address very old (ISA ?) or spurious cards. Giant lock being removed, we disable this when our new init succeeds.
Rather old hardware is concerned; but a PCI soundcard may work fine using a PCIe-to-PCI bridge, and some cards have pretty decent chipsets.
Signed-off-by: Nicolas Provost [email protected]