Open rohoog opened 2 years ago
@P33M any workarounds for this?
Unfortunately not. Bandwidth calculations for split transactions (full-speed / low-speed) on the Pi 4 are delegated to the VL805 firmware, and we've already got a version that claims to support the maximum possible.
High-speed DACs are not subject to this limitation.
One thing to try would be to see if the DAC is exposing a HID endpoint for button presses (volume / play / pause) and to unbind the HID driver if so - see https://forums.raspberrypi.com/viewtopic.php?t=85852
Yes there are HID buttons too. How would the HID buttons have such an impact on the available bandwidth? The SA9023 is USB2.0 full-speed compliant (not high-speed) according to the datasheet. 96KHz sample rate (the maximum of the chip) x 24 bit x 2 channels = a little over 4.6Mbit/s worst-case. USB2 full-speed 12 Mbit/s should be plenty enough. Is there some bandwidth calculation mistake somewhere in the infrastucture?
I tried unbinding the HID (and tree /sys/bus/usb/drivers/usbhid/
indeed shows unbinding was done), but it doesn't make the ENOSPC error go away.
What is "the maximum possible" for full speed USB-2 on RPI-4? Is it really less than 4 Mbit/s? How are these calculations done? Does it only take the 'worst case' (96K x 24bit x 2 channels) as the value for 'altsetting 2' independently of the actually chosen samplerate? Would this not be a restriction on RPI-3 or below? Would it be a workaround to connect the DAC to a USB-3 hub connected to a USB-3 port?
The available bandwidth should be at least 1012 periodic bytes per frame total, and I would expect altsetting 2 to be no more than 576 bytes per frame, so the error is unusual if there are no other periodic endpoints active.
Please post a full sudo lsusb -v
with everything connected to your Pi 4 when the error occurs, and the output of sudo rpi-eeprom-update
.
Nothing else connected, see the requested attached. rpi-eeprom-update.txt lsusb-v.txt
@P33M , could you get any hint from the requested outputs as of why the bandwidth is deemed insufficlent?
All of the S24_3LE sample rates are assigned to bAlternateSetting = 2, so this explains why you get bandwidth errors for every choice. This is overkill as it causes an over-reservation of bandwidth when it doesn't need it.
Are you sure that the OUT endpoints are not in use at the same time? What's the output of cat /proc/asound/card1/stream0
(card number may change depending on whether you have onboard audio enabled).
Shouldn't altsettings be mutually exclusive? There is indeed another endpoint for 'raw' output (no volume control), intended for non-PCM data over SPDIF (AAC, Dolby-Digitall, etc.). But I don't use it. Also there is only one output, so it can never be used concurrently.
ronald@raspberrypi:~$ cat /proc/asound/card1/stream0
Breeze audio SA9023 USB Audio at usb-0000:01:00.0-1.3, full speed : USB Audio
Playback:
Status: Stop
Interface 3
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 0x03 (3 OUT) (ADAPTIVE)
Rates: 96000, 88200, 48000, 44100, 32000
Bits: 16
Channel map: FL FR
Interface 3
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 0x03 (3 OUT) (ADAPTIVE)
Rates: 96000, 88200, 48000, 44100, 32000
Bits: 24
Channel map: FL FR
Capture:
Status: Stop
Interface 2
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 0x82 (2 IN) (ADAPTIVE)
Rates: 96000, 88200, 48000, 44100, 32000
Bits: 16
Channel map: FL FR
Interface 2
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 0x82 (2 IN) (ADAPTIVE)
Rates: 96000, 88200, 48000, 44100, 32000
Bits: 24
Channel map: FL FR
ronald@raspberrypi:~$ cat /proc/asound/card1/stream1
Breeze audio SA9023 USB Audio at usb-0000:01:00.0-1.3, full speed : USB Audio #1
Playback:
Status: Stop
Interface 3
Altset 3
Format: S16_LE
Channels: 2
Endpoint: 0x03 (3 OUT) (ADAPTIVE)
Rates: 48000, 44100
Bits: 0
Channel map: FL FR
It is unclear to me how this 'frame size' relates to the bandwidth allocation. There should be 12 Mbit/s for USB2 full speed. There is surely some overhead for packetizing etc. the bigger the frame the less the overhead, right? There is only one twisted pair D+/D- that needs to be shared for both directions (half duplex) and there needs to be enough 'spacing' to allow for the maximum USB cable length (propagation delay) when swtiching directions. What should be the formula for bandwidth allocation? Anyway it should be the same for RPi and laptop, right? Is there some extra constraint for RPi USB that's not there for your typical Intel USB chipset?
Is there some extra constraint for RPi USB that's not there for your typical Intel USB chipset?
Yes, as I said in my first response. The limitation is not in respect of the full-speed bus segment but for all full-speed periodic split transactions allocated in the single high-speed bus segment.
Full-speed USB uses 1ms timeslices to denote when periodic transfers should start - these are frames. Packets cannot span frames, and there is a maximum of 80% of the frame time available for allocation to periodic transfers. The maximum length of a periodic packet on a full-speed bus segment is 1023 bytes.
Even if the actual packet size on the bus is smaller than the maximal packet size specified in the endpoint's alternate setting, a reservation is done based on the maximal packet size.
1 ms of 12MBaud = 12Kbit = 1.5KByte. 80% of that aligns quite nicely with your 1023 bytes. The max packet size of SA9023 is 400 bytes according to the lsusb. This means that both a RX and a TX packet will fit in the 1ms frame: the sound can play full duplex (record+play). 400 byte each 1ms is 400 kbyte per second, which is sufficient for 66.666 stereo 3 byte samples per second. So this is sufficient for the 32k, 44.1k, and 48k samperates in S24_3 mode, but not for the 88.2k and 96k samplerates. In S16 mode, the 400 bytes every 1ms is sufficient for 100.000 stereo 2 byte samples per second. So that is sufficient for all the supported sample rates.
Do I interpret your statements correctly above?
The 1 ms 'frame rate' is apparently not a limitation on intel usb chipset. I guess it can have a higher frame rate to convey the required 576 kbyte per second. How come the RPi has this 1ms limitation? Apparently, the bandwidth allocation is based on the worst-case highest supported sample rate and therefore it is rejected. Would there be a way to 'tell' the bandwidth allocation that I don't want to use the highest 2 sample rates or maybe the bandwidth calculation is based on the actual selected samplerate instead of the worst-case 96k? Or alsa reduces the available samplerates to the ones that fit the bandwidth instead of 'all or nothing'?
The bandwidth calculation is handled by the VL805 firmware. Can you point me to the source file that does the handing-off?
The bandwidth calculation is handled by the VL805 firmware. Can you point me to the source file that does the handing-off?
xhci_configure_endpoint() in drivers/usb/host/xhci.c submits a TRB to the command ring which updates the controller's set of active endpoints. Encoded in this is the maxpacket size for the endpoint.
There are two alternate settings for the USB audio playback (and record) interface - one has a maxpacket size of 400, the other 600. The DAC shouldn't derive its expected bit depth from the alternate setting, an explicit control message should configure it - so it is theoretically possible to force usage of bAlternateSetting=1 for S24_3LE data. To override the parsing of descriptors (and substitute alternate ones) a snd_usb_audio quirk exists for this purpose - QUIRK_AUDIO_FIXED_ENDPOINT.
Or force 16-bit formats for this device through an .asoundrc config.
Right, I missed the maxpacketsize 600 under the altsetting 2. Now I'm confused again. The packetsize 600 every 1ms is indeed sufficient for all sample rates supported. However 2x 600 bytes doesn't fit in the 1023 maximum per frame, so it won't do duplex on 24 bit resolution. Also I don't need it, I'm only interested in the SPDIF 24 bit PCM output at the moment, I only use the OUT endpoint. So why does the RPi decide there isn't enough bandwidth? Isn't the altsetting 2 and therefore the 600 byte max packet size automatically selected when S24_3LE sample format is selected? Do I need this QUIRK to get this expected behavior?
Obviously, I'm interested in getting the 24 bit resolution working...
Describe the bug
I have a SA9023 based USB sound card, which should support 16 bit and packed 24 bit samples. On my x86_64 laptop, using the same kernel version (5.15) and driver, this indeed works, but with raspberry pi kernel on the pi-4 (64 bit), I always get ENOSPC errno when configuring that sample format (for instance using
speaker-test -F S24_3LE
).Browsing the snd-usb-audio sources, this means "not enough bandwidth". However, using 16 bit samples and 96KHz sample rate (which should require more bandwidth than 24 bit samples at 48KHz) works just fine. Even using 32 KHz with S24_3 results in ENOSPC.
This is a usb-2 card, so using the USB3 connector doesn't make any difference, as expected.
Steps to reproduce the behaviour
(using SA9023-based USB sound card)
speaker-test -D hw:CARD=Audio,DEV=0 -c 2 -F S16 -r 96000
on rpi-4 (kernel 5.15.50-v8+ aarch64) works.speaker-test -D hw:CARD=Audio,DEV=0 -c 2 -F S24_3LE
on rpi-4 -> "Setting of hwparams failed: No space left on device" (ENOSPC)On x86_64 laptop (kernel 5.15, x86_64), both commands work fine.
Device (s)
Raspberry Pi 4 Mod. B
System
cat /etc/rpi-issue
Raspberry Pi reference 2020-08-20 Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, 7252c154838ec5b4576f29c996ac8fe3750cae12, stage2
sudo vcgencmd versionJun 15 2022 20:01:08 Copyright (c) 2012 Broadcom version ede5f7d365ef42ebbd4aa144ee5b51ea75604c82 (clean) (release) (start)
uname -aLinux raspberrypi 5.15.50-v8+ #1568 SMP PREEMPT Mon Jun 27 19:22:41 BST 2022 aarch64 GNU/Linux
Logs
(usb2 socket) [ 409.208704] usb 1-1.4: Not enough bandwidth for new device state. [ 409.208750] usb 1-1.4: Not enough bandwidth for altsetting 2 [ 409.208766] usb 1-1.4: 3:2: usb_set_interface failed (-28)
(usb3 socket) [ 3577.291126] usb 1-1.2: Not enough bandwidth for new device state. [ 3577.291167] usb 1-1.2: Not enough bandwidth for altsetting 2 [ 3577.291184] usb 1-1.2: 3:2: usb_set_interface failed (-28)
Additional context
No response