Linux USB
 help / color / mirror / Atom feed
* [PATCH v4 2/2] usb: host: xhci-sideband: delegate offload_usage tracking to class drivers
From: Guan-Yu Lin @ 2026-04-01 12:32 UTC (permalink / raw)
  To: gregkh, mathias.nyman, perex, dominique.martinet, eadavis,
	hannelotta, tiwai, quic_wcheng, broonie, arnd, xiaopei01,
	wesley.cheng, sakari.ailus, stern, amardeep.rai, xu.yang_2,
	andriy.shevchenko, nkapron
  Cc: linux-usb, linux-kernel, linux-sound, Guan-Yu Lin, stable,
	Hailong Liu
In-Reply-To: <20260401123238.3790062-1-guanyulin@google.com>

Remove usb_offload_get() and usb_offload_put() from the xHCI sideband
interrupter creation and removal paths.

The responsibility of manipulating offload_usage now lies entirely with
the USB class drivers. They have the precise context of when an offload
data stream actually starts and stops, ensuring a much more accurate
representation of offload activity for power management.

Cc: stable@vger.kernel.org
Fixes: ef82a4803aab ("xhci: sideband: add api to trace sideband usage")
Signed-off-by: Guan-Yu Lin <guanyulin@google.com>
Tested-by: Hailong Liu <hailong.liu@oppo.com>
---
 drivers/usb/host/xhci-sideband.c  | 14 +-------------
 sound/usb/qcom/qc_audio_offload.c | 10 +++++++++-
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c
index 1ddb64b0a48e..651973606137 100644
--- a/drivers/usb/host/xhci-sideband.c
+++ b/drivers/usb/host/xhci-sideband.c
@@ -93,8 +93,6 @@ __xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *e
 static void
 __xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
 {
-	struct usb_device *udev;
-
 	lockdep_assert_held(&sb->mutex);
 
 	if (!sb->ir)
@@ -102,10 +100,6 @@ __xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
 
 	xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
 	sb->ir = NULL;
-	udev = sb->vdev->udev;
-
-	if (udev->state != USB_STATE_NOTATTACHED)
-		usb_offload_put(udev);
 }
 
 /* sideband api functions */
@@ -328,9 +322,6 @@ int
 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
 				 bool ip_autoclear, u32 imod_interval, int intr_num)
 {
-	int ret = 0;
-	struct usb_device *udev;
-
 	if (!sb || !sb->xhci)
 		return -ENODEV;
 
@@ -348,12 +339,9 @@ xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
 	if (!sb->ir)
 		return -ENOMEM;
 
-	udev = sb->vdev->udev;
-	ret = usb_offload_get(udev);
-
 	sb->ir->ip_autoclear = ip_autoclear;
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
 
diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_offload.c
index cfb30a195364..abafbc78dea9 100644
--- a/sound/usb/qcom/qc_audio_offload.c
+++ b/sound/usb/qcom/qc_audio_offload.c
@@ -699,6 +699,7 @@ static void uaudio_event_ring_cleanup_free(struct uaudio_dev *dev)
 		uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE,
 				   PAGE_SIZE);
 		xhci_sideband_remove_interrupter(uadev[dev->chip->card->number].sb);
+		usb_offload_put(dev->udev);
 	}
 }
 
@@ -1182,12 +1183,16 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
 	dma_coherent = dev_is_dma_coherent(subs->dev->bus->sysdev);
 	er_pa = 0;
 
+	ret = usb_offload_get(subs->dev);
+	if (ret < 0)
+		goto exit;
+
 	/* event ring */
 	ret = xhci_sideband_create_interrupter(uadev[card_num].sb, 1, false,
 					       0, uaudio_qdev->data->intr_num);
 	if (ret < 0) {
 		dev_err(&subs->dev->dev, "failed to fetch interrupter\n");
-		goto exit;
+		goto put_offload;
 	}
 
 	sgt = xhci_sideband_get_event_buffer(uadev[card_num].sb);
@@ -1219,6 +1224,8 @@ static int uaudio_event_ring_setup(struct snd_usb_substream *subs,
 	mem_info->dma = 0;
 remove_interrupter:
 	xhci_sideband_remove_interrupter(uadev[card_num].sb);
+put_offload:
+	usb_offload_put(subs->dev);
 exit:
 	return ret;
 }
@@ -1483,6 +1490,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
 	uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE, PAGE_SIZE);
 free_sec_ring:
 	xhci_sideband_remove_interrupter(uadev[card_num].sb);
+	usb_offload_put(subs->dev);
 drop_sync_ep:
 	if (subs->sync_endpoint) {
 		uaudio_iommu_unmap(MEM_XFER_RING,
-- 
2.53.0.1018.g2bb0e51243-goog


^ permalink raw reply related

* Re: [PATCH] usbip: vhci: validate ret_submit number_of_packets
From: Greg KH @ 2026-04-01 12:32 UTC (permalink / raw)
  To: hkbinbin; +Cc: valentina.manea.m, shuah, i, linux-usb, linux-kernel, stable
In-Reply-To: <20260401120857.1443552-1-hkbinbinbin@gmail.com>

On Wed, Apr 01, 2026 at 12:08:57PM +0000, hkbinbin wrote:
> vhci_recv_ret_submit() unpacks USBIP_RET_SUBMIT directly into the URB,
> including number_of_packets from the remote server. For isochronous
> URBs, iso_frame_desc[] was allocated using the original locally
> submitted number_of_packets.
> 
> If a malicious or buggy USB/IP server returns a larger
> number_of_packets, usbip_recv_iso() will iterate past the end of
> urb->iso_frame_desc[] and write attacker-controlled ISO descriptors out
> of bounds. Later completion paths may also walk past iso_frame_desc[]
> if the poisoned number_of_packets is left in the URB after rejecting
> the response.
> 
> Fix this by saving the original packet count before unpacking the PDU,
> rejecting larger values from the server, restoring the original count
> on error, and marking the connection as broken.
> 
> Fixes: 1325f85fa49f ("staging: usbip: bugfix add number of packets for isochronous frames")
> Cc: stable@vger.kernel.org
> Signed-off-by: hkbinbin <hkbinbinbin@gmail.com>

We need a "real name" here please.

Also, this really looks like the same patch sent here:
	https://lore.kernel.org/r/20260329125437.517980-2-sebasjosue84@gmail.com

Is everyone forgetting to disclose that they are using AI tools to
generate these things?

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH v2] dma-debug: suppress cacheline overlap warning when arch has no DMA alignment requirement
From: Andy Shevchenko @ 2026-04-01 13:25 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Marek Szyprowski, Mikhail Gavrilov, iommu, linux-kernel,
	linux-usb, linux-mm, harry, vbabka, akpm, stern, linux, hch,
	Jeff.kirsher, catalin.marinas
In-Reply-To: <c9ded35b-fc10-47d8-bfaa-cecb4fa91add@arm.com>

On Wed, Apr 1, 2026 at 3:11 PM Robin Murphy <robin.murphy@arm.com> wrote:
> On 2026-03-30 8:44 am, Marek Szyprowski wrote:
> > On 27.03.2026 13:41, Mikhail Gavrilov wrote:

...

> TBH I'd be inclined to have CONFIG_DMA_DEBUG raise ARCH_DMA_MINALIGN as
> appropriate such that genuine false-positives can't happen, rather than
> effectively defeat the whole check,

I dunno if you read v1 thread, where I proposed to unroll the check
and use pr_debug_once() for the cases which we expect not to panic,
but would be good to have a track of.


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH v4 0/2] usb: offload: Decouple interrupter lifecycle and refactor usage tracking
From: Greg KH @ 2026-04-01 13:38 UTC (permalink / raw)
  To: Guan-Yu Lin
  Cc: mathias.nyman, perex, dominique.martinet, eadavis, hannelotta,
	tiwai, quic_wcheng, broonie, arnd, xiaopei01, wesley.cheng,
	sakari.ailus, stern, amardeep.rai, xu.yang_2, andriy.shevchenko,
	nkapron, linux-usb, linux-kernel, linux-sound
In-Reply-To: <20260401123238.3790062-1-guanyulin@google.com>

On Wed, Apr 01, 2026 at 12:32:16PM +0000, Guan-Yu Lin wrote:
> The current USB offload implementation couples the allocation of xHCI
> sideband interrupters with the device's offload usage counter. This
> coupling is conceptually incorrect, as hardware resource availability
> and power management state serve distinct purposes.
> 
> Furthermore, the reliance on the coarse USB device lock for offload
> state updates has led to potential recursive locking issues,
> especially during device disconnect when the lock is already held
> by the USB core.
> 
> This series refactors the offload synchronization by introducing a
> dedicated spinlock for offload state, allowing for more granular
> concurrency control and avoiding deadlocks. It also optimizes power
> management by ensuring that offload state is only modified when the
> device is already active, avoiding unnecessary auto-resumes.
> 
> Patch 1 introduces the `offload_lock` spinlock and `offload_pm_locked`
> synchronization, replacing the coarse `udev->lock` and the legacy
> `offload_at_suspend` flag. It also updates `usb_offload_get/put` to use
> `pm_runtime_get_if_active()`.
> 
> Patch 2 removes the implicit usage tracking from the xHCI sideband layer
> and delegates the responsibility to class drivers, who have the
> correct context for managing offload data stream activity.

Ok, this looks much better, thanks for the revisions.

If the xhci maintainer acks these, I'll be glad to apply them to my
tree.

thanks,

greg k-h

^ permalink raw reply

* [PATCH] usb: dwc3: imx8mp: fix memory leak on probe failure path
From: Xiaolei Wang @ 2026-04-01 13:49 UTC (permalink / raw)
  To: Thinh.Nguyen, gregkh, Frank.Li, s.hauer, kernel, festevam,
	Xiaolei.Wang
  Cc: linux-usb, imx, linux-arm-kernel, linux-kernel

When platform_get_drvdata() returns NULL and probe defers, the error
path jumps to the 'depopulate' label, skipping put_device() for the
reference acquired by of_find_device_by_node(). This extra reference
prevents the child platform device from being freed when
of_platform_depopulate() is called, resulting in memory leaks reported
by kmemleak:

  unreferenced object 0xffff0000c92c1480 (size 64):
    comm "kworker/u16:2", pid 50, jiffies 4294895789
    backtrace (crc 49d507d0):
      kmemleak_alloc+0x34/0x40
      __kmalloc_noprof+0x430/0x670
      of_device_alloc+0xec/0x26c
      of_platform_device_create_pdata+0x60/0x1f0
      of_platform_bus_create+0x290/0x610
      of_platform_populate+0x74/0x118
      dwc3_imx8mp_probe+0x228/0x734

Fixes: 86767625f525 ("usb: dwc3: imx8mp: disable auto suspend for host role")
Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
---
 drivers/usb/dwc3/dwc3-imx8mp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index b3d7252bd910..1cf96540b66e 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -263,7 +263,7 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	dwc3 = platform_get_drvdata(dwc3_imx->dwc3_pdev);
 	if (!dwc3) {
 		err = dev_err_probe(dev, -EPROBE_DEFER, "failed to get dwc3 platform data\n");
-		goto depopulate;
+		goto put_dwc3;
 	}
 
 	dwc3->glue_ops = &dwc3_imx_glue_ops;
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] usb: chipidea: udc: reject non-control requests while controller is suspended
From: Alan Stern @ 2026-04-01 14:15 UTC (permalink / raw)
  To: Andreea.Popescu@aumovio.com
  Cc: Peter Chen, Greg Kroah-Hartman, linux-usb@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <FRYP281MB2618D382481440BFDFAEB2FCEA50A@FRYP281MB2618.DEUP281.PROD.OUTLOOK.COM>

On Wed, Apr 01, 2026 at 06:45:24AM +0000, Andreea.Popescu@aumovio.com wrote:
> On Tue, Mar 31, 2026 at 12:21:45PM +0000, Andreea.Popescu@aumovio.com wrote:
> >> When Linux runtime PM autosuspends a ChipIdea UDC that is still
> >> enumerated by the host, the driver gates the PHY clocks and marks
> >> the controller as suspended (ci->in_lpm = 1) but deliberately leaves
> >> gadget.speed unchanged so upper-layer gadget drivers do not see a
> >> spurious disconnect.
> >>
> >> The problem is that those same drivers may continue to call
> >> usb_ep_queue() during the autosuspend window.  _hardware_enqueue()
> >> silently adds the request to the endpoint queue and returns 0, but
> >> hw_ep_prime() cannot succeed with gated clocks, so the completion
> >> interrupt never fires.  The request — and its backing buffer — is
> >> permanently lost.  The caller sees a successful return and never
> >> frees the buffer.
> >Won't the request complete normally after the gadget is resumed, or
> >abnormally after a reset, disconnect, or shutdown?  Either way, it
> >wouldn't be lost permanently.
> >
> >Alan Stern
> Thank you very much for the review!
> On "complete normally after resume":
> This would be true only if the runtime-resume path reprimed the pending endpoints. It does not. ci_controller_resume() clears PORTSC_PHCD and ci->in_lpm, restoring the PHY, but it performs no endpoint repriming. The TD that was enqueued during the suspended window has its DMA node linked in hwep->qh.queue and the QH's td.next is written, but the OP_ENDPTPRIME write inside hw_ep_prime() was a no-op against gated clocks. After resume the controller has no knowledge of that TD — the ENDPTPRIME/ENDPTSTAT bits are clean — so it never processes it. The request is not picked up automatically.
> A subsequent request on the same endpoint would be appended to the existing TD chain via the "non-empty queue" branch of _hardware_enqueue(), which does not issue a fresh prime either; it relies on the hardware already being active on that endpoint. Since the first prime was lost, that chain never becomes active.

Okay.  Then surely the appropriate way to fix the problem is to change 
the runtime-resume path so that it _does_ reprime the pending endpoints.

Alan Stern

^ permalink raw reply

* Re: [PATCH] usbip: vhci: validate ret_submit number_of_packets
From: hkbinbin @ 2026-04-01 14:26 UTC (permalink / raw)
  To: gregkh
  Cc: hkbinbinbin, i, linux-kernel, linux-usb, shuah, stable,
	valentina.manea.m
In-Reply-To: <2026040100-brewing-ethics-990c@gregkh>

Thank you for your time and for pointing these out. 
I sincerely apologize for the oversight.

I cloned the repository a few days ago and discovered the bugs, 
but I must admit that I used AI tools to figure out how to patch, 
and generate the patch and description. 

I was not aware of the earlier submission
https://lore.kernel.org/r/20260329125437.517980-2-sebasjosue84@gmail.com.
Since this issue has been correctly fixed by the other author,
please ignore my submission.
I have realized my mistake, and i will correct it.
I sincerely apologize again. Really sorry for the trouble.

thanks,

ZhiTao Ou

^ permalink raw reply

* Re: [PATCH] usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable()
From: Mathias Nyman @ 2026-04-01 14:34 UTC (permalink / raw)
  To: Michal Pecio, Mathias Nyman, Greg Kroah-Hartman
  Cc: Alan Stern, linux-usb, linux-kernel
In-Reply-To: <20260331010654.269ac270.michal.pecio@gmail.com>

On 3/31/26 02:06, Michal Pecio wrote:
> xHCI hardware maintains its endpoint state between add_endpoint()
> and drop_endpoint() calls followed by successful check_bandwidth().
> So does the driver.
> 
> Core may call endpoint_disable() during xHCI endpoint life, so don't
> clear host_ep->hcpriv then, because this breaks endpoint_reset().
> 
> If a driver calls usb_set_interface(), submits URBs which make host
> sequence state non-zero and calls usb_clear_halt(), the device clears
> its sequence state but xhci_endpoint_reset() bails out. The next URB
> malfunctions: USB2 loses one packet, USB3 gets Transaction Error or
> may not complete at all on some (buggy?) HCs from ASMedia and AMD.
> This is triggered by uvcvideo on bulk video devices.

Were you able to trigger a usb_clear_halt() called with ep->hcpriv == NULL,
causing a toggle/seq mismatch?

The ep->hcpriv should be set back correctly in usb_set_interface():

usb_set_interface()
   usb_hcd_alloc_bandwidth()
     hcd->driver->add_endpoint()
       xhci_add_endpoint()
         ep->hcpriv = udev;

I'm not against this patch, but would like to understand how we end here

Thanks
Mathias


^ permalink raw reply

* Re: [PATCH v4 0/2] usb: offload: Decouple interrupter lifecycle and refactor usage tracking
From: Mathias Nyman @ 2026-04-01 14:47 UTC (permalink / raw)
  To: Greg KH, Guan-Yu Lin
  Cc: mathias.nyman, perex, dominique.martinet, eadavis, hannelotta,
	tiwai, quic_wcheng, broonie, arnd, xiaopei01, wesley.cheng,
	sakari.ailus, stern, amardeep.rai, xu.yang_2, andriy.shevchenko,
	nkapron, linux-usb, linux-kernel, linux-sound
In-Reply-To: <2026040148-cucumber-automatic-9a6b@gregkh>

On 4/1/26 16:38, Greg KH wrote:
> On Wed, Apr 01, 2026 at 12:32:16PM +0000, Guan-Yu Lin wrote:
>> The current USB offload implementation couples the allocation of xHCI
>> sideband interrupters with the device's offload usage counter. This
>> coupling is conceptually incorrect, as hardware resource availability
>> and power management state serve distinct purposes.
>>
>> Furthermore, the reliance on the coarse USB device lock for offload
>> state updates has led to potential recursive locking issues,
>> especially during device disconnect when the lock is already held
>> by the USB core.
>>
>> This series refactors the offload synchronization by introducing a
>> dedicated spinlock for offload state, allowing for more granular
>> concurrency control and avoiding deadlocks. It also optimizes power
>> management by ensuring that offload state is only modified when the
>> device is already active, avoiding unnecessary auto-resumes.
>>
>> Patch 1 introduces the `offload_lock` spinlock and `offload_pm_locked`
>> synchronization, replacing the coarse `udev->lock` and the legacy
>> `offload_at_suspend` flag. It also updates `usb_offload_get/put` to use
>> `pm_runtime_get_if_active()`.
>>
>> Patch 2 removes the implicit usage tracking from the xHCI sideband layer
>> and delegates the responsibility to class drivers, who have the
>> correct context for managing offload data stream activity.
> 
> Ok, this looks much better, thanks for the revisions.
> 
> If the xhci maintainer acks these, I'll be glad to apply them to my
> tree.

For both patches:

Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>


^ permalink raw reply

* Re: [PATCH] usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable()
From: Michal Pecio @ 2026-04-01 14:52 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: Mathias Nyman, Greg Kroah-Hartman, Alan Stern, linux-usb,
	linux-kernel
In-Reply-To: <e14fb308-a003-4a76-b908-106b5271eccc@linux.intel.com>

On Wed, 1 Apr 2026 17:34:37 +0300, Mathias Nyman wrote:
> On 3/31/26 02:06, Michal Pecio wrote:
> > xHCI hardware maintains its endpoint state between add_endpoint()
> > and drop_endpoint() calls followed by successful check_bandwidth().
> > So does the driver.
> > 
> > Core may call endpoint_disable() during xHCI endpoint life, so don't
> > clear host_ep->hcpriv then, because this breaks endpoint_reset().
> > 
> > If a driver calls usb_set_interface(), submits URBs which make host
> > sequence state non-zero and calls usb_clear_halt(), the device clears
> > its sequence state but xhci_endpoint_reset() bails out. The next URB
> > malfunctions: USB2 loses one packet, USB3 gets Transaction Error or
> > may not complete at all on some (buggy?) HCs from ASMedia and AMD.
> > This is triggered by uvcvideo on bulk video devices.  
> 
> Were you able to trigger a usb_clear_halt() called with ep->hcpriv == NULL,
> causing a toggle/seq mismatch?
> 
> The ep->hcpriv should be set back correctly in usb_set_interface():
> 
> usb_set_interface()
>    usb_hcd_alloc_bandwidth()
>      hcd->driver->add_endpoint()
>        xhci_add_endpoint()
>          ep->hcpriv = udev;

right, and later:

     usb_disable_interface(dev, iface, true)
       usb_disable_endpoint(dev, ..., true)
         usb_hcd_disable_endpoint(dev, ep)
           hcd->driver->endpoint_disable(hcd, ep)
     usb_enable_interface(dev, iface, true)
       usb_enable_endpoint(dev, ..., true)
         usb_hcd_reset_endpoint(dev, ep)
           hcd->driver->endpoint_reset(hcd, ep)

So it seems set_interface() is broken and doesn't actually reset host
sequence state (while the device is supposed to reset its own).

This alone is rarely a problem because the endpoint is usually "fresh".

But uvcvideo calls usb_clear_halt() *after* stopping a bulk stream,
because that's what Windows does. Then sequence state is random and
gets cleared only on the device, because hcpriv is still NULL.

The next URB gets Transaction Error, the host endpoint is reset and
another URB succeeds (because we restart the endpoint unconditionally).

Regards,
Michal

^ permalink raw reply

* [PATCH v2] usb: gadget: f_uac1_legacy: validate control request size
From: Taegu Ha @ 2026-04-01 15:15 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Taegu Ha
In-Reply-To: <2026040124-unheated-opponent-3c56@gregkh>

f_audio_complete() copies req->length bytes into a 4-byte stack
variable:

  u32 data = 0;
  memcpy(&data, req->buf, req->length);

req->length is derived from the host-controlled USB request path,
which can lead to a stack out-of-bounds write.

Validate req->actual against the expected payload size for the
supported control selectors and decode only the expected amount
of data.

This avoids copying a host-influenced length into a fixed-size
stack object.

Signed-off-by: Taegu Ha <hataegu0826@gmail.com>

Changes in v2:
- rewrite the validation logic into a switch on control type
- use constant-size memcpy() for fixed-size payloads
- convert the volume payload with le16_to_cpu()

Build-tested: not tested, build environment not prepared

---
 drivers/usb/gadget/function/f_uac1_legacy.c | 47 ++++++++++++++++-----
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c
index a0c953a99727..00cc7161db66 100644
--- a/drivers/usb/gadget/function/f_uac1_legacy.c
+++ b/drivers/usb/gadget/function/f_uac1_legacy.c
@@ -360,19 +360,46 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req)
 static void f_audio_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_audio *audio = req->context;
-	int status = req->status;
-	u32 data = 0;
 	struct usb_ep *out_ep = audio->out_ep;
 
-	switch (status) {
-
-	case 0:				/* normal completion? */
-		if (ep == out_ep)
+	switch (req->status) {
+	case 0:
+		if (ep == out_ep) {
 			f_audio_out_ep_complete(ep, req);
-		else if (audio->set_con) {
-			memcpy(&data, req->buf, req->length);
-			audio->set_con->set(audio->set_con, audio->set_cmd,
-					le16_to_cpu(data));
+		} else if (audio->set_con) {
+			struct usb_audio_control *con = audio->set_con;
+			u8 type = con->type;
+			u32 data = 0;
+			bool valid_request = false;
+
+			switch (type) {
+			case UAC_FU_MUTE: {
+				u8 value;
+
+				if (req->actual == sizeof(value)) {
+					memcpy(&value, req->buf, sizeof(value));
+					data = value;
+					valid_request = true;
+				}
+				break;
+			}
+			case UAC_FU_VOLUME: {
+				__le16 value;
+
+				if (req->actual == sizeof(value)) {
+					memcpy(&value, req->buf, sizeof(value));
+					data = le16_to_cpu(value);
+					valid_request = true;
+				}
+				break;
+			}
+			}
+
+			if (valid_request)
+				con->set(con, audio->set_cmd, data);
+			else
+				usb_ep_set_halt(ep);
+
 			audio->set_con = NULL;
 		}
 		break;
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v2] dma-debug: suppress cacheline overlap warning when arch has no DMA alignment requirement
From: Robin Murphy @ 2026-04-01 15:26 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Marek Szyprowski, Mikhail Gavrilov, iommu, linux-kernel,
	linux-usb, linux-mm, harry, vbabka, akpm, stern, linux, hch,
	Jeff.kirsher, catalin.marinas
In-Reply-To: <CAHp75VdrGk=foAzQBJNRNDZ1yfFY8p-tC_ApM8_gN4EehpmN_Q@mail.gmail.com>

On 2026-04-01 2:25 pm, Andy Shevchenko wrote:
> On Wed, Apr 1, 2026 at 3:11 PM Robin Murphy <robin.murphy@arm.com> wrote:
>> On 2026-03-30 8:44 am, Marek Szyprowski wrote:
>>> On 27.03.2026 13:41, Mikhail Gavrilov wrote:
> 
> ...
> 
>> TBH I'd be inclined to have CONFIG_DMA_DEBUG raise ARCH_DMA_MINALIGN as
>> appropriate such that genuine false-positives can't happen, rather than
>> effectively defeat the whole check,
> 
> I dunno if you read v1 thread, where I proposed to unroll the check
> and use pr_debug_once() for the cases which we expect not to panic,
> but would be good to have a track of.

I had not seen v1, as I took the last 3 days off and hadn't got that far 
up my inbox yet - I guess it's at least reassuring to have reached 
similar conclusions independently :)

The fundamental issue here is that dma-debug doesn't realistically have 
a way to know whether the thing being mapped is intentionally a whole 
dedicated kmalloc allocation - where we can trust SLUB (and 
DMA_BOUNCE_UNALIGNED_KMALLOC if appropriate) to do the right thing 
across different systems - or just something which might happen to line 
up by coincidence on someone's development machine, but for portability 
they definitely do still need to take explicit care about (e.g. struct 
devres::data).

Certainly some milder and/or opt-in reporting of 
potential-false-positive overlaps wouldn't be a terrible idea, if 
someone wants to have a crack at it.

Thanks,
Robin.

^ permalink raw reply

* Re: Fwd: USB DBC hang during earlyprintk initialization
From: Milan Oravec @ 2026-04-01 15:58 UTC (permalink / raw)
  To: Mathias Nyman; +Cc: Greg KH, linux-usb
In-Reply-To: <CAAcb1K-Ksf7zDb1gT5TEa8Wk5aKUehiiYOOEa5YSZDiW+aA0=w@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 9236 bytes --]

Hello to all, I've here another laptop with hibernation problems, this
time it is HP OmniBook X (OmniBook X Flip Laptop 16-ar0xxx/8DA8, BIOS
F.11 11/03/2025), unfortunately DbC does not work here too :( Without
your experimental patches:

mar 31 21:19:13 migo-HP kernel: xhci_dbc:early_xdbc_parse_parameter: dbgp_num: 1
mar 31 21:19:13 migo-HP kernel: ------------[ cut here ]------------
mar 31 21:19:13 migo-HP kernel: nrpages > NR_FIX_BTMAPS
mar 31 21:19:13 migo-HP kernel: WARNING: mm/early_ioremap.c:139 at
__early_ioremap+0xac/0x190, CPU#0: swapper/0
mar 31 21:19:13 migo-HP kernel: Modules linked in:
mar 31 21:19:13 migo-HP kernel: CPU: 0 UID: 0 PID: 0 Comm: swapper Not
tainted 6.19.10-arch1-1 #1 PREEMPT(undef)
63ba695b544fca873a9b42d2eb96b2b409fa31b5
mar 31 21:19:13 migo-HP kernel: RIP: 0010:__early_ioremap+0xac/0x190
mar 31 21:19:13 migo-HP kernel: Code: 60 3d a9 90 4c 89 ca 48 81 e3 00
f0 ff ff 48 81 e2 00 f0 ff ff 48 29 d3 48 89 14 24 48 89 da 48 c1 ea
0c 89 d5 83 fa >
mar 31 21:19:13 migo-HP kernel: RSP: 0000:ffffffff90003cb8 EFLAGS:
00010006 ORIG_RAX: 0000000000000000
mar 31 21:19:13 migo-HP kernel: RAX: 0000000000000000 RBX:
0000000000100000 RCX: 0000000000100000
mar 31 21:19:13 migo-HP kernel: RDX: 0000000000000100 RSI:
0000000000100000 RDI: 0000000098900000
mar 31 21:19:13 migo-HP kernel: RBP: 0000000000000100 R08:
0000000000000000 R09: 0000000098900000
mar 31 21:19:13 migo-HP kernel: R10: 0000000000000004 R11:
ffffffff90003ad0 R12: 8000000000000163
mar 31 21:19:13 migo-HP kernel: R13: 0000000000000000 R14:
0000000098900000 R15: 0000000000000000
mar 31 21:19:13 migo-HP kernel: FS:  0000000000000000(0000)
GS:0000000000000000(0000) knlGS:0000000000000000
mar 31 21:19:13 migo-HP kernel: CS:  0010 DS: 0000 ES: 0000 CR0:
0000000080050033
mar 31 21:19:13 migo-HP kernel: CR2: ffff888000000413 CR3:
000000018f19a000 CR4: 00000000000000f0
mar 31 21:19:13 migo-HP kernel: Call Trace:
mar 31 21:19:13 migo-HP kernel:  <TASK>
mar 31 21:19:13 migo-HP kernel:  ? early_xdbc_parse_parameter+0x32c/0x360
mar 31 21:19:13 migo-HP kernel:  ? setup_early_printk+0x51b/0x540
mar 31 21:19:13 migo-HP kernel:  ? do_early_param+0x44/0x70
mar 31 21:19:13 migo-HP kernel:  ? parse_args+0x1e0/0x410
mar 31 21:19:13 migo-HP kernel:  ? __pfx_do_early_param+0x10/0x10
mar 31 21:19:13 migo-HP kernel:  ? parse_early_options+0x29/0x30
mar 31 21:19:13 migo-HP kernel:  ? __pfx_do_early_param+0x10/0x10
mar 31 21:19:13 migo-HP kernel:  ? parse_early_param+0x64/0xc0
mar 31 21:19:13 migo-HP kernel:  ? setup_arch+0x542/0xbe0
mar 31 21:19:13 migo-HP kernel:  ? _printk+0x6b/0x90
mar 31 21:19:13 migo-HP kernel:  ? start_kernel+0x6b/0xa60
mar 31 21:19:13 migo-HP kernel:  ? x86_64_start_reservations+0x24/0x30
mar 31 21:19:13 migo-HP kernel:  ? x86_64_start_kernel+0xd1/0xe0
mar 31 21:19:13 migo-HP kernel:  ? common_startup_64+0x13e/0x141
mar 31 21:19:13 migo-HP kernel:  </TASK>
mar 31 21:19:13 migo-HP kernel: ---[ end trace 0000000000000000 ]---

It is somehow better with your experimental patches applied:

mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup: DCE
successfully cleared
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup:
Successfully got xdbc table_dma page
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup:
Successfully got xdbc out_dma page
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup:
Successfully allocated event ring
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup:
Successfully allocated in ring
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup:
Successfully allocated out ring
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_start: waiting for
connection timed out
mar 31 21:16:09 migo-HP kernel: xhci_dbc:xdbc_early_setup: Failed to
start xdbc ret: -110
mar 31 21:16:09 migo-HP kernel: xhci_dbc:early_xdbc_setup_hardware:
failed to setup the connection to host

I was able to read the first line of the log on the debug host with
cat /dev/ttyUSB0 but that was all, boot hangs and no other messages
were displayed on the debug host. But the strange thing is that
minicom -D /dev/ttyUSB0 failed to establish connection with: Failed to
set baud rate error. I'm attaching a screenshot from the debugging
host.

If i need to report this and follow up in another thread please excuse
me and let me know, I'll do.
I'll add more technical info upon request off course.

Is there somebody that can help me with this?

Thank you very much, best regards
Milan


On Mon, Jan 19, 2026 at 12:01 PM Milan Oravec <migo.oravec@gmail.com> wrote:
>
> Hello, I've moved a bit further. I connected the usb debugging cable 3
> seconds after the boot started (like normal), but not connected the
> minicom at that time but waited for another 10-15 seconds and then ran
> the minicom. I still need to hold the enter key to keep displaying
> messages in minicom but this later connection prevented that boot hang
> that I had before. Boot continues on the minicom console to one point
> (displaying: Poking KASLR using RDRAND RDTSC...)  and then returns to
> the laptop screen and the system successfully boots. There are some
> errors in dmesg and the Logitech USB mouse is not working.
>
> I've attached the output from the Minicom as minicom.txt and the dmesg
> -T output from the laptop itself as dmesg.txt. I hope this can help
> with this problem.
>
> Thank you,
> Milan
>
> On Mon, Jan 19, 2026 at 9:18 AM Milan Oravec <migo.oravec@gmail.com> wrote:
> >
> > Hello, I've tried the 6.19.0-rc6 kernel with experimental patches
> > applied, but no changes unfortunately, the system freezes at the same
> > log output line as before. :( DbC log attached. Any ideas?
> >
> > Thank you,
> > Milan
> >
> > On Thu, Dec 18, 2025 at 9:03 PM Milan Oravec <migo.oravec@gmail.com> wrote:
> > >
> > > Hello Mathias, thank you very much.
> > >
> > > I've tried without the keep flag, and setting timeout to 100ms instead
> > > of 2 seconds. I need to hold the enter button on the debug host to see
> > > messages from the debug target. But without a keep flag system doesn't
> > > hang during boot but DbC is disconnected instead and console messages
> > > return to the display of the debug target, please see attached log
> > > from debug host.
> > >
> > > It seems the computer hangs with the keep flag at the same moment that
> > > console messages are returned to the laptop screen without the keep
> > > flag applied.
> > >
> > > Do you have any other ideas to try?
> > >
> > > Thank you,
> > > Milan
> > >
> > > On Wed, Dec 17, 2025 at 10:20 AM Mathias Nyman
> > > <mathias.nyman@linux.intel.com> wrote:
> > > >
> > > > Hi
> > > >
> > > > On 12/5/25 20:49, Milan Oravec wrote:
> > > > > Hello Mathias, I've replaced cat with minicom in the script above and
> > > > > let minicom capture the file. First minicom displayed no messages,
> > > > > then I realised I need to press and hold enter to be able see messages
> > > > > sent from debug target.
> > > >
> > > > You shouldn't need to do that, something is set up oddly.
> > > >
> > > > >
> > > > > Computer hangs and needs a long press of the power button to recover.
> > > > > Boot cmd used:
> > > > > linux /vmlinuz root=UUID=584262b6-b020-4e4f-95a3-1db754e28b6c
> > > > > earlyprintk=keep,xdbc2 debug ignore_loglevel sysrq_always_enabled
> > > > > force_early_printk sched_verbose usbcore.autosuspend=-1
> > > > > no_console_suspend resume=UUID=54ed98b5-56c0-4ab9-95ea-da1a9322ce49
> > > > >
> > > > > I've attached a captured log from deminicom.
> > > > >
> > > > > What should I try next?
> > > >
> > > > early_xdbc_write() is called every time a new entry is written to console.
> > > > It only uses one transfer buffer, (one TRB).
> > > > early_xdbc_write() will block for up to 2 seconds in a udelay loop waiting
> > > > for the previous transfer to complete.
> > > >
> > > > blocking for 2 seconds on every console message doesn't sound reasonable.
> > > > Maybe for the first message to make sure other side is set up and reading the data.
> > > >
> > > > I'm also not sure the "keep" flag works.
> > > > Once the actual xhci driver binds to the device it will reset the controller , losing
> > > > DBC capability and console.
> > > >
> > > > You could try without the keep flag, and setting timeout to 100ms instead of 2 seconds
> > > >
> > > > diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c
> > > > index 41118bba9197..515a172ba25b 100644
> > > > --- a/drivers/usb/early/xhci-dbc.c
> > > > +++ b/drivers/usb/early/xhci-dbc.c
> > > > @@ -855,7 +855,7 @@ static int xdbc_bulk_write(const char *bytes, int size)
> > > >         xdbc_handle_events();
> > > >
> > > >         /* Check completion of the previous request: */
> > > > -       if ((xdbc.flags & XDBC_FLAGS_OUT_PROCESS) && (timeout < 2000000)) {
> > > > +       if ((xdbc.flags & XDBC_FLAGS_OUT_PROCESS) && (timeout < 100000)) {
> > > >                 raw_spin_unlock_irqrestore(&xdbc.lock, flags);
> > > >                 udelay(100);
> > > >                 timeout += 100;
> > > >
> > > > Thanks
> > > > Mathias
> > > >

[-- Attachment #2: signal-2026-03-31-212543_002.png --]
[-- Type: image/png, Size: 109973 bytes --]

^ permalink raw reply

* Re: [PATCH v3] usbip: tools: add hint when no exported devices are found
From: Shuah Khan @ 2026-04-01 16:06 UTC (permalink / raw)
  To: Zongmin Zhou
  Cc: gregkh, i, linux-kernel, linux-usb, valentina.manea.m,
	Zongmin Zhou, Shuah Khan
In-Reply-To: <6ed1738b-9d15-4311-a0f5-9b1a7db69f8c@163.com>

On 3/31/26 20:47, Zongmin Zhou wrote:
> 
> On 2026/4/1 08:27, Shuah Khan wrote:
>> On 3/31/26 03:58, Zongmin Zhou wrote:
>>> From: Zongmin Zhou <zhouzongmin@kylinos.cn>
>>>
>>> When refresh_exported_devices() finds no devices, it's helpful to
>>> inform users about potential causes. This could be due to:
>>>
>>> 1. The usbip driver module is not loaded.
>>> 2. No devices have been exported yet.
>>>
>>> Add an informational message to guide users when ndevs == 0.
>>>
>>> Message visibility by scenario:
>>> - usbipd (console mode): Show on console/serial, this allows instant
>>>    visibility for debugging.
>>> - usbipd -D (daemon mode): Message logged to syslog, can keep logs for
>>>    later traceability in production. Also can use "journalctl -f" to
>>>    trace on console.
>>>
>>> Suggested-by: Shuah Khan <skhan@linuxfoundation.org>
>>> Signed-off-by: Zongmin Zhou <zhouzongmin@kylinos.cn>
>>> ---
>>> Changes in v3:
>>> - Just add an informational message when no devices are found.
>>> Changes in v2:
>>> - Use system calls directly instead of checking sysfs dir.
>>>
>>>   tools/usb/usbip/libsrc/usbip_host_common.c | 7 +++++++
>>>   1 file changed, 7 insertions(+)
>>>
>>> diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c
>>> index ca78aa368476..cd92baee310c 100644
>>> --- a/tools/usb/usbip/libsrc/usbip_host_common.c
>>> +++ b/tools/usb/usbip/libsrc/usbip_host_common.c
>>> @@ -149,6 +149,13 @@ static int refresh_exported_devices(struct usbip_host_driver *hdriver)
>>>           }
>>>       }
>>>   +    if (hdriver->ndevs == 0) {
>>> +        if (!strcmp(hdriver->udev_subsystem, "usb"))
>>> +            info("Please check if %s driver is loaded or export devices.",USBIP_HOST_DRV_NAME);
>>
>> Check coding guidelines and match the new code to the existing. Need a space between
>> the string and the next argument.
>>
>>
>>> +        else
>>> +            info("Please check if %s driver is loaded or export devices.",USBIP_DEVICE_DRV_NAME);
>>
>> When will this be true? Isn't refresh_exported_devices() called from
>>
>> Thinking about this more, since you have to differentiate between
>> host and device, it makes sense to make this change to
>>
>> usbip_device_driver_open() and usbip_host_driver_open()
>> There is an err() message already in both of these routines.
>> that prints the right information.
>>
> Shuah,
> 
> Regarding your comment about the existing err() message in these routines:
> 
> The existing err("please load *.ko") message only triggers when usbip_generic_driver_open()
> returns a non-zero value. Since refresh_exported_devices() always returns 0
> (even when ndevs == 0 and no devices are found), usbip_generic_driver_open()
> only returns non-zero when udev_new() fails.
> 
> Therefore, when ndevs == 0, the existing err() message is never printed,
> so it doesn't actually help users diagnose the "no devices found or driver not load" situation.

Correct. There is no need to remove this. What I am suggesting is these
messages from usbip_device_driver_open() and usbip_host_driver_open()

What I am suggesting changing usbip_device_driver_open() and
usbip_host_driver_open() like this:

if (ret || hdriver->ndevs == 0)
                 info("please load " USBIP_CORE_MOD_NAME ".ko and "
                     USBIP_DEVICE_DRV_NAME ".ko!");


This should solve the problem for you ...

I don't like the idea of adding string compares to refresh_exported_devices()

if (!strcmp(hdriver->udev_subsystem, "usb"))

to differentiate when you can simply leverage the existing code by adding
one more conditional and changing the err() to info()

thanks,
-- Shuah

^ permalink raw reply

* Re: [PATCH net-next 3/3] net: usb: smsc95xx: suspend PHY during USB suspend
From: Oliver Neukum @ 2026-04-01 17:24 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: netdev, linux-usb, piergiorgio.beruto, andrew, hkallweit1, linux,
	davem, edumazet, kuba, pabeni, steve.glendinning, UNGLinuxDriver
In-Reply-To: <2e9bc390-c870-46a3-b673-c7cdb5187cc3@microchip.com>

Hi,

On 01.04.26 05:18, Parthiban.Veerasooran@microchip.com wrote:

> Thank you for pointing it out. I agree with you. I didn’t note it
> earlier since the issue did not occur during my testing. I will move the
> phy_suspend() to the appropriate place.

Thank you.

>> And, as a question of principle: Why do you suspend the phy
>> in suspend(), but take no action in resume()?
> 
> In resume(), I did not call phy_resume() because the resume path already
> invokes phy_init_hw(), which internally calls
> phydev->drv->config_init(). This reinitializes and reconfigures the PHY.

Thank you for the explanation. May I suggest that you add a comment
to that effect to the driver with your patch? This needs to be pointed
out. Your code as such is fine. It just needs a comment.

	Regards
		Oliver



^ permalink raw reply

* Re: [PATCH v2] usb: gadget: f_uac1_legacy: validate control request size
From: Greg KH @ 2026-04-01 18:28 UTC (permalink / raw)
  To: Taegu Ha; +Cc: linux-usb
In-Reply-To: <20260401151539.3441000-1-hataegu0826@gmail.com>

On Thu, Apr 02, 2026 at 12:15:39AM +0900, Taegu Ha wrote:
> f_audio_complete() copies req->length bytes into a 4-byte stack
> variable:
> 
>   u32 data = 0;
>   memcpy(&data, req->buf, req->length);
> 
> req->length is derived from the host-controlled USB request path,
> which can lead to a stack out-of-bounds write.
> 
> Validate req->actual against the expected payload size for the
> supported control selectors and decode only the expected amount
> of data.
> 
> This avoids copying a host-influenced length into a fixed-size
> stack object.
> 
> Signed-off-by: Taegu Ha <hataegu0826@gmail.com>
> 
> Changes in v2:
> - rewrite the validation logic into a switch on control type
> - use constant-size memcpy() for fixed-size payloads
> - convert the volume payload with le16_to_cpu()
> 
> Build-tested: not tested, build environment not prepared

As you found and tested your previous change, can you please test this
one to verify it solves the issue?



> 
> ---
>  drivers/usb/gadget/function/f_uac1_legacy.c | 47 ++++++++++++++++-----
>  1 file changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c
> index a0c953a99727..00cc7161db66 100644
> --- a/drivers/usb/gadget/function/f_uac1_legacy.c
> +++ b/drivers/usb/gadget/function/f_uac1_legacy.c
> @@ -360,19 +360,46 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req)
>  static void f_audio_complete(struct usb_ep *ep, struct usb_request *req)
>  {
>  	struct f_audio *audio = req->context;
> -	int status = req->status;
> -	u32 data = 0;
>  	struct usb_ep *out_ep = audio->out_ep;
>  
> -	switch (status) {
> -
> -	case 0:				/* normal completion? */
> -		if (ep == out_ep)
> +	switch (req->status) {
> +	case 0:
> +		if (ep == out_ep) {
>  			f_audio_out_ep_complete(ep, req);
> -		else if (audio->set_con) {
> -			memcpy(&data, req->buf, req->length);
> -			audio->set_con->set(audio->set_con, audio->set_cmd,
> -					le16_to_cpu(data));
> +		} else if (audio->set_con) {
> +			struct usb_audio_control *con = audio->set_con;
> +			u8 type = con->type;
> +			u32 data = 0;

No need to set this to 0 ahead of time, right?

thanks,

greg k-h

^ permalink raw reply

* [PATCH v7 0/3] usb: typec: ucsi: Add support for SET_PDOS command
From: Pooja Katiyar @ 2026-04-01 19:00 UTC (permalink / raw)
  To: linux-usb
  Cc: gregkh, heikki.krogerus, dmitry.baryshkov, johan, asutosh.pathak,
	pooja.katiyar

[Resending with linux-usb@vger.kernel.org added, previous send
 missed LKML]

This series implements support for UCSI SET PDOS command. It provides
interface to send message out data and update source or sink
capabilities PDOs on a connector over debugfs interface.

Pooja Katiyar (3):
  usb: typec: ucsi: Add support for message_out data structure
  usb: typec: ucsi: Enable debugfs for message_out data structure
  usb: typec: ucsi: Add support for SET_PDOS command

 drivers/usb/typec/ucsi/cros_ec_ucsi.c   |  6 ++-
 drivers/usb/typec/ucsi/debugfs.c        | 31 +++++++++++++++
 drivers/usb/typec/ucsi/ucsi.c           | 52 ++++++++++++++++++++-----
 drivers/usb/typec/ucsi/ucsi.h           | 20 +++++++++-
 drivers/usb/typec/ucsi/ucsi_acpi.c      | 22 ++++++++++-
 drivers/usb/typec/ucsi/ucsi_ccg.c       |  6 ++-
 drivers/usb/typec/ucsi/ucsi_yoga_c630.c |  6 ++-
 7 files changed, 123 insertions(+), 20 deletions(-)

-- 
2.43.0


^ permalink raw reply

* [PATCH v7 1/3] usb: typec: ucsi: Add support for message_out data structure
From: Pooja Katiyar @ 2026-04-01 19:00 UTC (permalink / raw)
  To: linux-usb
  Cc: gregkh, heikki.krogerus, dmitry.baryshkov, johan, asutosh.pathak,
	pooja.katiyar
In-Reply-To: <cover.1774994425.git.pooja.katiyar@intel.com>

Add support for UCSI message_out data structure. The UCSI
interface defines separate message_in and message_out data
structure for bidirectional communication, where commands
like Set PDOs and LPM Firmware Update require writing data
to message_out before command execution.

Add write_message_out operation to ucsi_operations structure
to allow platform drivers to implement message_out data writing
capability.

Update ucsi_sync_control_common to accept message_out parameters
and call write_message_out followed by command execution to
maintain proper sequencing as per the UCSI specification.

Introduce ucsi_write_message_out_command for commands that need
to send message_out data, while maintaining ucsi_send_command
for commands that only require message_in response data.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Pooja Katiyar <pooja.katiyar@intel.com>
---
Changelog v7:
- Added changelogs.

Changelog v6:
- Removed message_in and message_out related fields from global ucsi data
  structure and replaced with function parameter approach.
- Added message_out parameters to existing function parameters, keeping the
  flow similar to message_in data handling.
- Modified ucsi_sync_control_common() signature to accept msg_out and
  msg_out_size.
- Added write_message_out() to ucsi_operations struct.
- Added ucsi_write_message_out_command() function to handle commands
  which need to send message_out data to PPM.
- Updated platform interfaces and other function callers with new function
  signatures.

Changelog v5:
- Rebased patches to v6.18-rc3.

Changelog v4:
- Fixed build errors reported by kernel test robot.
- Added changelogs.

Changelog v3:
- Added message fields to UCSI structure and updated
  sync_control handling.

Changelog v2:
- Moved write_message_out operation to .sync_control.
- Updated ucsi_send_command to accept message_out data.

 drivers/usb/typec/ucsi/cros_ec_ucsi.c   |  6 ++-
 drivers/usb/typec/ucsi/ucsi.c           | 52 ++++++++++++++++++++-----
 drivers/usb/typec/ucsi/ucsi.h           | 13 ++++++-
 drivers/usb/typec/ucsi/ucsi_acpi.c      | 22 ++++++++++-
 drivers/usb/typec/ucsi/ucsi_ccg.c       |  6 ++-
 drivers/usb/typec/ucsi/ucsi_yoga_c630.c |  6 ++-
 6 files changed, 85 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c
index 6bca2dce211c..d0d25ab707b4 100644
--- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c
+++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c
@@ -112,12 +112,14 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd)
 }
 
 static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci,
-				  void *data, size_t size)
+				  void *data, size_t size, void *msg_out,
+				  size_t msg_out_size)
 {
 	struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi);
 	int ret;
 
-	ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size);
+	ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size, msg_out,
+				       msg_out_size);
 	switch (ret) {
 	case -EBUSY:
 		/* EC may return -EBUSY if CCI.busy is set.
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index f38a4d7ebc42..153a59248a61 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -57,7 +57,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
 EXPORT_SYMBOL_GPL(ucsi_notify_common);
 
 int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
-			     void *data, size_t size)
+			     void *data, size_t size, void *msg_out,
+			     size_t msg_out_size)
 {
 	bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
 	int ret;
@@ -69,6 +70,17 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
 
 	reinit_completion(&ucsi->complete);
 
+	if (msg_out && msg_out_size) {
+		if (!ucsi->ops->write_message_out) {
+			ret = -EOPNOTSUPP;
+			goto out_clear_bit;
+		}
+
+		ret = ucsi->ops->write_message_out(ucsi, msg_out, msg_out_size);
+		if (ret)
+			goto out_clear_bit;
+	}
+
 	ret = ucsi->ops->async_control(ucsi, command);
 	if (ret)
 		goto out_clear_bit;
@@ -104,11 +116,12 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
 		ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
 	}
 
-	return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0);
+	return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0, NULL, 0);
 }
 
 static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
-			    void *data, size_t size, bool conn_ack)
+			    void *data, size_t size, void *msg_out,
+			    size_t msg_out_size, bool conn_ack)
 {
 	int ret, err;
 
@@ -117,10 +130,12 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
 	if (size > UCSI_MAX_DATA_LENGTH(ucsi))
 		return -EINVAL;
 
-	ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);
+	ret = ucsi->ops->sync_control(ucsi, command, cci, data, size,
+				      msg_out, msg_out_size);
 
 	if (*cci & UCSI_CCI_BUSY)
-		return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY;
+		return ucsi_run_command(ucsi, UCSI_CANCEL, cci,
+					NULL, 0, NULL, 0, false) ?: -EBUSY;
 	if (ret)
 		return ret;
 
@@ -152,7 +167,8 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
 	int ret;
 
 	command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num);
-	ret = ucsi_run_command(ucsi, command, &cci, &error, sizeof(error), false);
+	ret = ucsi_run_command(ucsi, command, &cci, &error,
+			       sizeof(error), NULL, 0, false);
 	if (ret < 0)
 		return ret;
 
@@ -202,7 +218,8 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
 }
 
 static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,
-				    void *data, size_t size, bool conn_ack)
+				    void *data, size_t size, void *msg_out,
+				    size_t msg_out_size, bool conn_ack)
 {
 	u8 connector_num;
 	u32 cci;
@@ -230,7 +247,8 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,
 
 	mutex_lock(&ucsi->ppm_lock);
 
-	ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack);
+	ret = ucsi_run_command(ucsi, cmd, &cci, data, size,
+			       msg_out, msg_out_size, conn_ack);
 
 	if (cci & UCSI_CCI_ERROR)
 		ret = ucsi_read_error(ucsi, connector_num);
@@ -242,10 +260,23 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,
 int ucsi_send_command(struct ucsi *ucsi, u64 command,
 		      void *data, size_t size)
 {
-	return ucsi_send_command_common(ucsi, command, data, size, false);
+	return ucsi_send_command_common(ucsi, command, data,
+					size, NULL, 0, false);
 }
 EXPORT_SYMBOL_GPL(ucsi_send_command);
 
+int ucsi_write_message_out_command(struct ucsi *ucsi, u64 command,
+				   void *data, size_t size, void *msg_out,
+				   size_t msg_out_size)
+{
+	if (msg_out_size > UCSI_MAX_MSG_OUT_DATA_LEN(ucsi))
+		return -EINVAL;
+
+	return ucsi_send_command_common(ucsi, command, data,
+					size, msg_out, msg_out_size, false);
+}
+EXPORT_SYMBOL_GPL(ucsi_write_message_out_command);
+
 /* -------------------------------------------------------------------------- */
 
 struct ucsi_work {
@@ -673,7 +704,8 @@ static int ucsi_get_connector_status(struct ucsi_connector *con, bool conn_ack)
 			  UCSI_MAX_DATA_LENGTH(con->ucsi));
 	int ret;
 
-	ret = ucsi_send_command_common(con->ucsi, command, &con->status, size, conn_ack);
+	ret = ucsi_send_command_common(con->ucsi, command, &con->status, size,
+				       NULL, 0, conn_ack);
 
 	return ret < 0 ? ret : 0;
 }
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 43a0d01ade8f..82565f502bdf 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -65,6 +65,7 @@ struct dentry;
  * @read_cci: Read CCI register
  * @poll_cci: Read CCI register while polling with notifications disabled
  * @read_message_in: Read message data from UCSI
+ * @write_message_out: Write message data to UCSI
  * @sync_control: Blocking control operation
  * @async_control: Non-blocking control operation
  * @update_altmodes: Squashes duplicate DP altmodes
@@ -82,8 +83,9 @@ struct ucsi_operations {
 	int (*read_cci)(struct ucsi *ucsi, u32 *cci);
 	int (*poll_cci)(struct ucsi *ucsi, u32 *cci);
 	int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len);
+	int (*write_message_out)(struct ucsi *ucsi, void *data, size_t data_len);
 	int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci,
-			    void *data, size_t size);
+			    void *data, size_t size, void *msg_out, size_t msg_out_size);
 	int (*async_control)(struct ucsi *ucsi, u64 command);
 	bool (*update_altmodes)(struct ucsi *ucsi, u8 recipient,
 				struct ucsi_altmode *orig,
@@ -500,6 +502,9 @@ struct ucsi {
 };
 
 #define UCSI_MAX_DATA_LENGTH(u) (((u)->version < UCSI_VERSION_2_0) ? 0x10 : 0xff)
+#define UCSI_MAX_MSG_OUT_DATA_LEN(u) \
+	(((u)->version >= UCSI_VERSION_3_0) ? 255 : \
+	 (((u)->version >= UCSI_VERSION_2_0) ? 256 : 16))
 
 #define UCSI_MAX_SVID		5
 #define UCSI_MAX_ALTMODES	(UCSI_MAX_SVID * 6)
@@ -561,13 +566,17 @@ struct ucsi_connector {
 
 int ucsi_send_command(struct ucsi *ucsi, u64 command,
 		      void *retval, size_t size);
+int ucsi_write_message_out_command(struct ucsi *ucsi, u64 command,
+				   void *retval, size_t size,
+				   void *msg_out, size_t msg_out_size);
 
 void ucsi_altmode_update_active(struct ucsi_connector *con);
 int ucsi_resume(struct ucsi *ucsi);
 
 void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
 int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
-			     void *data, size_t size);
+			     void *data, size_t size, void *msg_out,
+			     size_t msg_out_size);
 
 #if IS_ENABLED(CONFIG_POWER_SUPPLY)
 int ucsi_register_port_psy(struct ucsi_connector *con);
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index 6b92f296e985..60b12961e1a4 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -86,6 +86,21 @@ static int ucsi_acpi_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
 	return 0;
 }
 
+static int ucsi_acpi_write_message_out(struct ucsi *ucsi, void *data, size_t data_len)
+{
+	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
+
+	if (!data || !data_len)
+		return -EINVAL;
+
+	if (ucsi->version <= UCSI_VERSION_1_2)
+		memcpy(ua->base + UCSI_MESSAGE_OUT, data, data_len);
+	else
+		memcpy(ua->base + UCSIv2_MESSAGE_OUT, data, data_len);
+
+	return 0;
+}
+
 static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command)
 {
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
@@ -101,19 +116,22 @@ static const struct ucsi_operations ucsi_acpi_ops = {
 	.read_cci = ucsi_acpi_read_cci,
 	.poll_cci = ucsi_acpi_poll_cci,
 	.read_message_in = ucsi_acpi_read_message_in,
+	.write_message_out = ucsi_acpi_write_message_out,
 	.sync_control = ucsi_sync_control_common,
 	.async_control = ucsi_acpi_async_control
 };
 
 static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
-				  void *val, size_t len)
+				  void *val, size_t len, void *msg_out,
+				  size_t msg_out_size)
 {
 	u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE |
 			   UCSI_CONSTAT_PDOS_CHANGE;
 	struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
 	int ret;
 
-	ret = ucsi_sync_control_common(ucsi, command, cci, val, len);
+	ret = ucsi_sync_control_common(ucsi, command, cci, val, len,
+				       msg_out, msg_out_size);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 199799b319c2..0592938078a9 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -608,7 +608,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command)
 }
 
 static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
-				 void *data, size_t size)
+				 void *data, size_t size, void *msg_out,
+				 size_t msg_out_size)
 {
 	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
 	struct ucsi_connector *con;
@@ -630,7 +631,8 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
 		ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
 	}
 
-	ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
+	ret = ucsi_sync_control_common(ucsi, command, cci, data, size,
+				       msg_out, msg_out_size);
 
 	switch (UCSI_COMMAND(command)) {
 	case UCSI_GET_CURRENT_CAM:
diff --git a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c
index 0187c1c4b21a..1be18d101842 100644
--- a/drivers/usb/typec/ucsi/ucsi_yoga_c630.c
+++ b/drivers/usb/typec/ucsi/ucsi_yoga_c630.c
@@ -89,7 +89,8 @@ static int yoga_c630_ucsi_async_control(struct ucsi *ucsi, u64 command)
 static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
 				       u64 command,
 				       u32 *cci,
-				       void *data, size_t size)
+				       void *data, size_t size,
+				       void *msg_out, size_t msg_out_size)
 {
 	int ret;
 
@@ -126,7 +127,8 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
 		return 0;
 	}
 
-	ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
+	ret = ucsi_sync_control_common(ucsi, command, cci,
+				       data, size, msg_out, msg_out_size);
 	if (ret < 0)
 		return ret;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v7 2/3] usb: typec: ucsi: Enable debugfs for message_out data structure
From: Pooja Katiyar @ 2026-04-01 19:00 UTC (permalink / raw)
  To: linux-usb
  Cc: gregkh, heikki.krogerus, dmitry.baryshkov, johan, asutosh.pathak,
	pooja.katiyar
In-Reply-To: <cover.1774994425.git.pooja.katiyar@intel.com>

Add debugfs entry for writing message_out data structure to handle
UCSI 2.1 and 3.0 commands through debugfs interface.

Users writing to the message_out debugfs file should ensure the input
data adheres to the following format:
1. Input must be a non-empty valid hexadecimal string.
2. Input length of hexadecimal string must not exceed 256 bytes of
   length to be in alignment with the message out data structure size
   as per the UCSI specification v2.1.
3. If the input string length is odd, then user needs to prepend a
   '0' to the first character for proper hex conversion.

Below are examples of valid hex strings. Note that these values are
just examples. The exact values depend on specific command use case.

        #echo 1A2B3C4D > message_out
        #echo 01234567 > message_out

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Pooja Katiyar <pooja.katiyar@intel.com>
---
Changelog v7:
- Added changelog.

Changelog v6:
- Removed message_out field from UCSI structure and added it back
  to ucsi_debugfs_entry structure. 

Changelog v3:
- Updated debugfs message_out write handler to use message_out fields
  in UCSI structure.

 drivers/usb/typec/ucsi/debugfs.c | 26 ++++++++++++++++++++++++++
 drivers/usb/typec/ucsi/ucsi.h    |  3 +++
 2 files changed, 29 insertions(+)

diff --git a/drivers/usb/typec/ucsi/debugfs.c b/drivers/usb/typec/ucsi/debugfs.c
index a4b9a6b51649..be987e53a8bd 100644
--- a/drivers/usb/typec/ucsi/debugfs.c
+++ b/drivers/usb/typec/ucsi/debugfs.c
@@ -110,6 +110,30 @@ static int ucsi_vbus_volt_show(struct seq_file *m, void *v)
 }
 DEFINE_SHOW_ATTRIBUTE(ucsi_vbus_volt);
 
+static ssize_t ucsi_message_out_write(struct file *file,
+				      const char __user *data, size_t count, loff_t *ppos)
+{
+	struct ucsi *ucsi = file->private_data;
+	int ret;
+
+	char *buf __free(kfree) = memdup_user_nul(data, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	ret = hex2bin(ucsi->debugfs->message_out, buf,
+		      min(count / 2, sizeof(ucsi->debugfs->message_out)));
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations ucsi_message_out_fops = {
+	.open = simple_open,
+	.write = ucsi_message_out_write,
+	.llseek = generic_file_llseek,
+};
+
 void ucsi_debugfs_register(struct ucsi *ucsi)
 {
 	ucsi->debugfs = kzalloc_obj(*ucsi->debugfs);
@@ -122,6 +146,8 @@ void ucsi_debugfs_register(struct ucsi *ucsi)
 	debugfs_create_file("peak_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_peak_curr_fops);
 	debugfs_create_file("avg_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_avg_curr_fops);
 	debugfs_create_file("vbus_voltage", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_vbus_volt_fops);
+	debugfs_create_file("message_out", 0200, ucsi->debugfs->dentry, ucsi,
+			    &ucsi_message_out_fops);
 }
 
 void ucsi_debugfs_unregister(struct ucsi *ucsi)
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 82565f502bdf..e51a8472fc27 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -455,6 +455,8 @@ struct ucsi_bitfield {
 
 /* -------------------------------------------------------------------------- */
 
+#define MESSAGE_OUT_MAX_LEN 256
+
 struct ucsi_debugfs_entry {
 	u64 command;
 	struct ucsi_data {
@@ -462,6 +464,7 @@ struct ucsi_debugfs_entry {
 		u64 high;
 	} response;
 	int status;
+	u8 message_out[MESSAGE_OUT_MAX_LEN];
 	struct dentry *dentry;
 };
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v7 3/3] usb: typec: ucsi: Add support for SET_PDOS command
From: Pooja Katiyar @ 2026-04-01 19:00 UTC (permalink / raw)
  To: linux-usb
  Cc: gregkh, heikki.krogerus, dmitry.baryshkov, johan, asutosh.pathak,
	pooja.katiyar
In-Reply-To: <cover.1774994425.git.pooja.katiyar@intel.com>

Add support for UCSI SET_PDOS command as per UCSI specification v2.1 and
above to debugfs.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Pooja Katiyar <pooja.katiyar@intel.com>
---
Changelog v7:
- Added changelogs.

Changelog v6:
- Removed message_out field from UCSI structure and added it back
  to ucsi_debugfs_entry structure. 

Changelog v2:
- Send message_out data as part of ucsi_send_command.

 drivers/usb/typec/ucsi/debugfs.c | 5 +++++
 drivers/usb/typec/ucsi/ucsi.h    | 4 ++++
 2 files changed, 9 insertions(+)

diff --git a/drivers/usb/typec/ucsi/debugfs.c b/drivers/usb/typec/ucsi/debugfs.c
index be987e53a8bd..ff33a5e7c6b0 100644
--- a/drivers/usb/typec/ucsi/debugfs.c
+++ b/drivers/usb/typec/ucsi/debugfs.c
@@ -40,6 +40,11 @@ static int ucsi_cmd(void *data, u64 val)
 	case UCSI_READ_POWER_LEVEL:
 		ret = ucsi_send_command(ucsi, val, NULL, 0);
 		break;
+	case UCSI_SET_PDOS:
+		ret = ucsi_write_message_out_command(ucsi, val, NULL, 0,
+						     ucsi->debugfs->message_out,
+						     UCSI_COMMAND_DATA_LEN(val));
+		break;
 	case UCSI_GET_CAPABILITY:
 	case UCSI_GET_CONNECTOR_CAPABILITY:
 	case UCSI_GET_ALTERNATE_MODES:
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index e51a8472fc27..e1a14f043abf 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -138,6 +138,7 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
 #define UCSI_GET_PD_MESSAGE			0x15
 #define UCSI_GET_CAM_CS			0x18
 #define UCSI_SET_SINK_PATH			0x1c
+#define UCSI_SET_PDOS				0x1d
 #define UCSI_READ_POWER_LEVEL			0x1e
 #define UCSI_SET_USB				0x21
 #define UCSI_GET_LPM_PPM_INFO			0x22
@@ -215,6 +216,9 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
 #define   UCSI_GET_PD_MESSAGE_TYPE_IDENTITY	4
 #define   UCSI_GET_PD_MESSAGE_TYPE_REVISION	5
 
+/* Data length bits */
+#define UCSI_COMMAND_DATA_LEN(_cmd_)           (((_cmd_) >> 8) & GENMASK(7, 0))
+
 /* -------------------------------------------------------------------------- */
 
 /* Error information returned by PPM in response to GET_ERROR_STATUS command. */
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net-next v4 1/2] r8152: Add support for 5Gbit Link Speeds and EEE
From: Andrew Lunn @ 2026-04-01 19:00 UTC (permalink / raw)
  To: Birger Koblitz
  Cc: Jakub Kicinski, andrew+netdev, davem, edumazet, pabeni, linux-usb,
	netdev, linux-kernel
In-Reply-To: <59b4be26-1fee-40f1-b9ff-45881cddc7df@birger-koblitz.de>

>  One thing I
> noticed in particular is that the AI does not seem to take into account
> that the code actually works: suspecting broken SRAM-access or wrong
> descriptor-size settings would break the driver at such a fundamental level,
> it would not be able to work at all.

The flip side to this is that we get a lot of patches which are
compile tested only. So assuming the patch has run on real hardware is
a poor assumption to make.

We humans however do have a feeling about who is submitting the
patches and how likely they have run it on hardware. So we know to
look for fundamental problems or not.

	Andrew

^ permalink raw reply

* [PATCH v3] usb: gadget: f_uac1_legacy: validate control request size
From: Taegu Ha @ 2026-04-01 19:13 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Taegu Ha
In-Reply-To: <2026040144-gratitude-haven-f28a@gregkh>

f_audio_complete() copies req->length bytes into a 4-byte stack
variable:

  u32 data = 0;
  memcpy(&data, req->buf, req->length);

req->length is derived from the host-controlled USB request path,
which can lead to a stack out-of-bounds write.

Validate req->actual against the expected payload size for the
supported control selectors and decode only the expected amount
of data.

This avoids copying a host-influenced length into a fixed-size
stack object.

Signed-off-by: Taegu Ha <hataegu0826@gmail.com>

Changes in v3:
- drop the unnecessary zero-initialization of data
- build-test the updated change
- add KUnit coverage for valid and malformed mute/volume payload sizes

Build-tested: make drivers/usb/gadget/function/f_uac1_legacy.o
Runtime-tested: KUnit on x86_64 with KASAN
- malformed mute/volume payload sizes are rejected
- valid 1-byte mute and 2-byte volume payloads still reach the setter

---
 drivers/usb/gadget/function/f_uac1_legacy.c | 47 ++++++++++++++++-----
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c
index a0c953a99727..5d201a2e30e7 100644
--- a/drivers/usb/gadget/function/f_uac1_legacy.c
+++ b/drivers/usb/gadget/function/f_uac1_legacy.c
@@ -360,19 +360,46 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req)
 static void f_audio_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_audio *audio = req->context;
-	int status = req->status;
-	u32 data = 0;
 	struct usb_ep *out_ep = audio->out_ep;
 
-	switch (status) {
-
-	case 0:				/* normal completion? */
-		if (ep == out_ep)
+	switch (req->status) {
+	case 0:
+		if (ep == out_ep) {
 			f_audio_out_ep_complete(ep, req);
-		else if (audio->set_con) {
-			memcpy(&data, req->buf, req->length);
-			audio->set_con->set(audio->set_con, audio->set_cmd,
-					le16_to_cpu(data));
+		} else if (audio->set_con) {
+			struct usb_audio_control *con = audio->set_con;
+			u8 type = con->type;
+			u32 data;
+			bool valid_request = false;
+
+			switch (type) {
+			case UAC_FU_MUTE: {
+				u8 value;
+
+				if (req->actual == sizeof(value)) {
+					memcpy(&value, req->buf, sizeof(value));
+					data = value;
+					valid_request = true;
+				}
+				break;
+			}
+			case UAC_FU_VOLUME: {
+				__le16 value;
+
+				if (req->actual == sizeof(value)) {
+					memcpy(&value, req->buf, sizeof(value));
+					data = le16_to_cpu(value);
+					valid_request = true;
+				}
+				break;
+			}
+			}
+
+			if (valid_request)
+				con->set(con, audio->set_cmd, data);
+			else
+				usb_ep_set_halt(ep);
+
 			audio->set_con = NULL;
 		}
 		break;
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable()
From: Mathias Nyman @ 2026-04-01 19:27 UTC (permalink / raw)
  To: Michal Pecio
  Cc: Mathias Nyman, Greg Kroah-Hartman, Alan Stern, linux-usb,
	linux-kernel
In-Reply-To: <20260401165205.56dcfcda.michal.pecio@gmail.com>

On 4/1/26 17:52, Michal Pecio wrote:
> On Wed, 1 Apr 2026 17:34:37 +0300, Mathias Nyman wrote:
>> On 3/31/26 02:06, Michal Pecio wrote:
>>> xHCI hardware maintains its endpoint state between add_endpoint()
>>> and drop_endpoint() calls followed by successful check_bandwidth().
>>> So does the driver.
>>>
>>> Core may call endpoint_disable() during xHCI endpoint life, so don't
>>> clear host_ep->hcpriv then, because this breaks endpoint_reset().
>>>
>>> If a driver calls usb_set_interface(), submits URBs which make host
>>> sequence state non-zero and calls usb_clear_halt(), the device clears
>>> its sequence state but xhci_endpoint_reset() bails out. The next URB
>>> malfunctions: USB2 loses one packet, USB3 gets Transaction Error or
>>> may not complete at all on some (buggy?) HCs from ASMedia and AMD.
>>> This is triggered by uvcvideo on bulk video devices.
>>
>> Were you able to trigger a usb_clear_halt() called with ep->hcpriv == NULL,
>> causing a toggle/seq mismatch?
>>
>> The ep->hcpriv should be set back correctly in usb_set_interface():
>>
>> usb_set_interface()
>>     usb_hcd_alloc_bandwidth()
>>       hcd->driver->add_endpoint()
>>         xhci_add_endpoint()
>>           ep->hcpriv = udev;
> 
> right, and later:
> 
>       usb_disable_interface(dev, iface, true)
>         usb_disable_endpoint(dev, ..., true)
>           usb_hcd_disable_endpoint(dev, ep)
>             hcd->driver->endpoint_disable(hcd, ep)
>       usb_enable_interface(dev, iface, true)
>         usb_enable_endpoint(dev, ..., true)
>           usb_hcd_reset_endpoint(dev, ep)
>             hcd->driver->endpoint_reset(hcd, ep)
> 

True, thanks, usb_set_interface() calls usb_disable_interface() twice.
First time just to flush pending URBs, second time with reset_hardware
flag set.

Adding patch to queue

-Mathias


^ permalink raw reply

* [PATCH] mfd: max77759: fix comment style for enums
From: Amit Sunil Dhamne via B4 Relay @ 2026-04-01 21:02 UTC (permalink / raw)
  To: André Draszik, Lee Jones, Greg Kroah-Hartman
  Cc: linux-kernel, linux-usb, Badhri Jagan Sridharan,
	Amit Sunil Dhamne

From: Amit Sunil Dhamne <amitsd@google.com>

Fix comment style for enums so they're kernel-doc compliant.

Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
---
This patch is a follow-up to the series [1]. [1] has been accepted in
the USB subsystem tree (usb-next). However, since Lee has additional
feedback [2], I am sending this patch to fix it. Please note that this
patch is based out of usb-next branch on usb tree. This patch should be
applied on top of b422f7c072ac ("mfd: max77759: add register bitmasks
and modify irq configs for charger").

[1] https://lore.kernel.org/all/20260325-max77759-charger-v9-0-4486dd297adc@google.com/
[2] https://lore.kernel.org/all/20260331123138.GE3795166@google.com/
---
Output of kernel-doc script (none format)
$ scripts/kernel-doc -v -none -Wall include/linux/mfd/max77759.h
Info: include/linux/mfd/max77759.h:134 Scanning doc for enum max77759_chgr_chgin_dtls_status
Info: include/linux/mfd/max77759.h:152 Scanning doc for enum max77759_chgr_bat_dtls_states
Info: include/linux/mfd/max77759.h:174 Scanning doc for enum max77759_chgr_chg_dtls_states
Info: include/linux/mfd/max77759.h:212 Scanning doc for struct max77759
Info: include/linux/mfd/max77759.h:235 Scanning doc for struct max77759_maxq_command
Info: include/linux/mfd/max77759.h:247 Scanning doc for struct max77759_maxq_response
Info: include/linux/mfd/max77759.h:258 Scanning doc for function max77759_maxq_command
---
 include/linux/mfd/max77759.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/mfd/max77759.h b/include/linux/mfd/max77759.h
index ad1aa4c2b779..ec19be952877 100644
--- a/include/linux/mfd/max77759.h
+++ b/include/linux/mfd/max77759.h
@@ -131,12 +131,12 @@
 #define MAX77759_MAXQ_OPCODE_USER_SPACE_READ     0x81
 #define MAX77759_MAXQ_OPCODE_USER_SPACE_WRITE    0x82
 
-/*
+/**
  * enum max77759_chgr_chgin_dtls_status - Charger Input Status
  * @MAX77759_CHGR_CHGIN_DTLS_VBUS_UNDERVOLTAGE:
  *     Charger input voltage (Vchgin) < Under Voltage Threshold (Vuvlo)
- * @MAX77759_CHGR_CHGIN_DTLS_VBUS_MARGINAL_VOLTAGE: Vchgin > Vuvlo and
- *     Vchgin < (Battery Voltage (Vbatt) + system voltage (Vsys))
+ * @MAX77759_CHGR_CHGIN_DTLS_VBUS_MARGINAL_VOLTAGE:
+ *     Vchgin > Vuvlo and Vchgin < (Battery Voltage (Vbatt) + system voltage (Vsys))
  * @MAX77759_CHGR_CHGIN_DTLS_VBUS_OVERVOLTAGE:
  *     Vchgin > Over Voltage threshold (Vovlo)
  * @MAX77759_CHGR_CHGIN_DTLS_VBUS_VALID:
@@ -149,7 +149,7 @@ enum max77759_chgr_chgin_dtls_status {
 	MAX77759_CHGR_CHGIN_DTLS_VBUS_VALID,
 };
 
-/*
+/**
  * enum max77759_chgr_bat_dtls_states - Battery Details
  * @MAX77759_CHGR_BAT_DTLS_NO_BATT_CHG_SUSP:	No battery and the charger suspended
  * @MAX77759_CHGR_BAT_DTLS_DEAD_BATTERY:	Vbatt < Vtrickle
@@ -171,7 +171,7 @@ enum max77759_chgr_bat_dtls_states {
 	MAX77759_CHGR_BAT_DTLS_BAT_ONLY_MODE,
 };
 
-/*
+/**
  * enum max77759_chgr_chg_dtls_states - Charger Details
  * @MAX77759_CHGR_CHG_DTLS_PREQUAL:		Charger in prequalification mode
  * @MAX77759_CHGR_CHG_DTLS_CC:			Charger in fast charge const curr mode

---
base-commit: 81ebd43cc0d6d106ce7b6ccbf7b5e40ca7f5503d
change-id: 20260401-fix-mfd-max77759-usb-next-e687dd13c08a

Best regards,
-- 
Amit Sunil Dhamne <amitsd@google.com>



^ permalink raw reply related

* [PATCHv2] thunderbolt: tunnel: simplify allocation
From: Rosen Penev @ 2026-04-01 21:47 UTC (permalink / raw)
  To: linux-usb
  Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, Kees Cook,
	Gustavo A. R. Silva, open list,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b

Use a flexible array member and kzalloc_flex to combine allocations.

Add __counted_by for extra runtime analysis. Move counting variable
assignment after allocation. kzalloc_flex with GCC >= 15 does this
automatically.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 v2: move kernel-doc and reword slightly.
 drivers/thunderbolt/tunnel.c | 10 ++--------
 drivers/thunderbolt/tunnel.h |  5 +++--
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index 89676acf1290..f38f7753b6e4 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -180,19 +180,14 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths,
 {
 	struct tb_tunnel *tunnel;

-	tunnel = kzalloc_obj(*tunnel);
+	tunnel = kzalloc_flex(*tunnel, paths, npaths);
 	if (!tunnel)
 		return NULL;

-	tunnel->paths = kzalloc_objs(tunnel->paths[0], npaths);
-	if (!tunnel->paths) {
-		kfree(tunnel);
-		return NULL;
-	}
+	tunnel->npaths = npaths;

 	INIT_LIST_HEAD(&tunnel->list);
 	tunnel->tb = tb;
-	tunnel->npaths = npaths;
 	tunnel->type = type;
 	kref_init(&tunnel->kref);

@@ -219,7 +214,6 @@ static void tb_tunnel_destroy(struct kref *kref)
 			tb_path_free(tunnel->paths[i]);
 	}

-	kfree(tunnel->paths);
 	kfree(tunnel);
 }

diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h
index 2c44fc8a10bc..4878763a82b3 100644
--- a/drivers/thunderbolt/tunnel.h
+++ b/drivers/thunderbolt/tunnel.h
@@ -37,7 +37,6 @@ enum tb_tunnel_state {
  * @src_port: Source port of the tunnel
  * @dst_port: Destination port of the tunnel. For discovered incomplete
  *	      tunnels may be %NULL or null adapter port instead.
- * @paths: All paths required by the tunnel
  * @npaths: Number of paths in @paths
  * @pre_activate: Optional tunnel specific initialization called before
  *		  activation. Can touch hardware.
@@ -69,13 +68,13 @@ enum tb_tunnel_state {
  * @dprx_work: Worker that is scheduled to poll completion of DPRX capabilities read
  * @callback: Optional callback called when DP tunnel is fully activated
  * @callback_data: Optional data for @callback
+ * @paths: All paths required by the tunnel
  */
 struct tb_tunnel {
 	struct kref kref;
 	struct tb *tb;
 	struct tb_port *src_port;
 	struct tb_port *dst_port;
-	struct tb_path **paths;
 	size_t npaths;
 	int (*pre_activate)(struct tb_tunnel *tunnel);
 	int (*activate)(struct tb_tunnel *tunnel, bool activate);
@@ -107,6 +106,8 @@ struct tb_tunnel {
 	struct delayed_work dprx_work;
 	void (*callback)(struct tb_tunnel *tunnel, void *data);
 	void *callback_data;
+
+	struct tb_path *paths[] __counted_by(npaths);
 };

 struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down,
--
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox