* [PATCH] soundwire: qcom: Fix off-by-one error in port exhaustion check
@ 2026-10-12 10:17 Christopher Obbard
2026-10-19 8:10 ` Srinivas Kandagatla
0 siblings, 1 reply; 2+ messages in thread
From: Christopher Obbard @ 2026-10-12 10:17 UTC (permalink / raw)
To: Srinivas Kandagatla, Vinod Koul, Bard Liao, Pierre-Louis Bossart
Cc: Srinivas Kandagatla, linux-arm-msm, linux-sound, linux-kernel,
Christopher Obbard
Qualcomm SoundWire master ports are indexed from 1, with bit 0 of
port_mask reserved. Valid port numbers therefore range from 1 to
maxport.
Commit 6ccec91c3535 ("soundwire: qcom: Fix port exhaustion check in
stream_alloc_ports") changed the port exhaustion check from
pn > maxport to pn >= maxport which rejects the last valid port.
On RB3gen2 (QCS6490), two WSA883x speaker amplifiers are connected
to swr2, which has 8 ports. Each amplifier uses one port for playback
and another for voltage and current sensing. The right amplifier's
VISENSE port is mapped to master port 8, which is rejected by the new
check.
Since all ports in a SoundWire stream are allocated together during
hw_params, this causes the stream to fail with:
qcom-soundwire 3250000.soundwire: All ports busy
The codec DMA backend then returns -EBUSY, preventing speaker playback.
Disabling VISENSE works around the issue but also disables speaker
protection.
The original fix addressed an exhaustion check that could never
trigger because find_first_zero_bit() returns maxport when all
searched bits are set. Include the reserved bit 0 in the search so
exhaustion returns maxport + 1 and restore the pn > maxport check.
Fixes: 6ccec91c3535 ("soundwire: qcom: Fix port exhaustion check in stream_alloc_ports")
Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
---
drivers/soundwire/qcom.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index 6e0c5fb10efad..b4ce96792fa94 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -1348,9 +1348,9 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl,
if (m_port)
pn = m_port;
else
- pn = find_first_zero_bit(port_mask, maxport);
+ pn = find_first_zero_bit(port_mask, maxport + 1);
- if (pn >= maxport) {
+ if (pn > maxport) {
dev_err(ctrl->dev, "All ports busy\n");
return -EBUSY;
}
---
base-commit: 2e9eff8847a46530ab937696f340b9d5bea2e4ef
change-id: 20261012-wip-obbardc-soundwire-qcom-fix-port-off-by-one-47c0a8af1c5e
Best regards,
--
Christopher Obbard
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] soundwire: qcom: Fix off-by-one error in port exhaustion check
2026-10-12 10:17 [PATCH] soundwire: qcom: Fix off-by-one error in port exhaustion check Christopher Obbard
@ 2026-10-19 8:10 ` Srinivas Kandagatla
0 siblings, 0 replies; 2+ messages in thread
From: Srinivas Kandagatla @ 2026-10-19 8:10 UTC (permalink / raw)
To: Christopher Obbard, Srinivas Kandagatla, Vinod Koul, Bard Liao,
Pierre-Louis Bossart
Cc: Srinivas Kandagatla, linux-arm-msm, linux-sound, linux-kernel
On 10/12/26 11:17 AM, Christopher Obbard wrote:
> Qualcomm SoundWire master ports are indexed from 1, with bit 0 of
> port_mask reserved. Valid port numbers therefore range from 1 to
> maxport.
>
> Commit 6ccec91c3535 ("soundwire: qcom: Fix port exhaustion check in
> stream_alloc_ports") changed the port exhaustion check from
> pn > maxport to pn >= maxport which rejects the last valid port.
>
> On RB3gen2 (QCS6490), two WSA883x speaker amplifiers are connected
> to swr2, which has 8 ports. Each amplifier uses one port for playback
> and another for voltage and current sensing. The right amplifier's
> VISENSE port is mapped to master port 8, which is rejected by the new
> check.
>
> Since all ports in a SoundWire stream are allocated together during
> hw_params, this causes the stream to fail with:
>
> qcom-soundwire 3250000.soundwire: All ports busy
>
> The codec DMA backend then returns -EBUSY, preventing speaker playback.
> Disabling VISENSE works around the issue but also disables speaker
> protection.
This comment is incorrect, we do not have speaker protection enabled on
any of the devices.
>
> The original fix addressed an exhaustion check that could never
> trigger because find_first_zero_bit() returns maxport when all
> searched bits are set. Include the reserved bit 0 in the search so
> exhaustion returns maxport + 1 and restore the pn > maxport check.
>
> Fixes: 6ccec91c3535 ("soundwire: qcom: Fix port exhaustion check in stream_alloc_ports")
Cc Stable and Reported-by missing
> Signed-off-by: Christopher Obbard <chris.obbard@oss.qualcomm.com>
> ---
> drivers/soundwire/qcom.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
> index 6e0c5fb10efad..b4ce96792fa94 100644
> --- a/drivers/soundwire/qcom.c
> +++ b/drivers/soundwire/qcom.c
> @@ -1348,9 +1348,9 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl,
> if (m_port)
> pn = m_port;
> else
> - pn = find_first_zero_bit(port_mask, maxport);
> + pn = find_first_zero_bit(port_mask, maxport + 1);
thanks for adding this case, rb3gen2 should not hit this anyway.
>
> - if (pn >= maxport) {
> + if (pn > maxport) {
> dev_err(ctrl->dev, "All ports busy\n");
> return -EBUSY;
> }
>
Once those are fixed,
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
--srini
> ---
> base-commit: 2e9eff8847a46530ab937696f340b9d5bea2e4ef
> change-id: 20261012-wip-obbardc-soundwire-qcom-fix-port-off-by-one-47c0a8af1c5e
>
> Best regards,
> --
> Christopher Obbard
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-19 8:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12 10:17 [PATCH] soundwire: qcom: Fix off-by-one error in port exhaustion check Christopher Obbard
2026-10-19 8:10 ` Srinivas Kandagatla
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®