Skip to content

Usb: phytium: update phytium usb controller driver support to 6.6.0.4 - #2221

Merged
opsiff merged 1 commit into
deepin-community:linux-6.6.yfrom
wangchenlu2236:usb-6.6.y
Oct 23, 2026
Merged

opsiff merged 1 commit into
deepin-community:linux-6.6.yfrom
wangchenlu2236:usb-6.6.y

Conversation

@wangchenlu2236

@wangchenlu2236 wangchenlu2236 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

This patches updates the support for phytium usb controller driver.
1.Revert "usb: xhci: Add a reset endpoint command to the specified PHYTIUM SOC"

Summary by Sourcery

Enhancements:

  • Update the Phytium USB controller support by removing the Phytium-specific endpoint reset handling from xHCI transfer completion processing.

@sourcery-ai

sourcery-ai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Updates Phytium USB support with a new USB TCM host/gadget data path, SoC-specific xHCI failure recovery and port-reset handling, DMA safety fixes, and revised USB v2 power-management and role/lifecycle behavior.

Sequence diagram for Phytium xHCI failure recovery

sequenceDiagram
    participant XHCI as Phytium xHCI
    participant Workqueue as xhci_wq
    participant Driver as xhci_generic_plat_probe

    XHCI->>XHCI: xhci_hc_died
    alt PE220X or PD2408 with XHCI_S1_SUSPEND_WAKEUP
        XHCI->>Workqueue: mod_delayed_work
        Workqueue->>XHCI: xhci_delay_work_func
        XHCI->>Driver: xhci_plat_remove
        Driver->>Driver: xhci_generic_plat_probe
    end
Loading

Flow diagram for Phytium USB port reset handling

flowchart TD
    Reset[HubPortReset] --> Force[Write FORCE_PORT_RESET to portctrl]
    Force --> Status[Set USB_PORT_STAT_RESET]
    Status --> Disable[Clear USB_PORT_STAT_ENABLE]
    Disable --> Done[Clear port_resetting]
Loading

File-Level Changes

Change Details Files
Adds a Phytium-specific USB TCM host driver and gadget function for bidirectional bulk/character-device communication.
  • Registers the new USB host driver for VID:PID 0x4875:0x0100.
  • Implements 512-byte URB-based host reads and writes with wait queues.
  • Adds a configurable USB gadget function with FS/HS/SS descriptors, endpoint request queues, polling, and a character device interface.
  • Adds Kconfig/Makefile integration and shared packet/function-instance definitions.
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/usb_tcm_phytium.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/function/Makefile
drivers/usb/gadget/function/f_usb_tcm.c
drivers/usb/gadget/function/u_usb_tcm.h
drivers/usb/gadget/function/usb_tcm_pk.h
Extends Phytium xHCI recovery for selected SoCs by re-probing the controller after a hardware failure.
  • Adds a dedicated workqueue and delayed recovery callback for PE220X/PD2408.
  • Re-maps controller registers using a Phytium-specific path and schedules recovery when the suspend/wakeup quirk is active.
  • Adds delayed-work state and workqueue accessors to xHCI structures.
  • Adds the Phytium port-reset register operation and guards DMA TRB-list handling against empty lists.
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.h
drivers/usb/phytium/host.c
drivers/usb/phytium/dma.c
Updates the Phytium USB v2 role, suspend/resume, gadget, and host lifecycle behavior.
  • Changes role recovery to query hardware only when no role switch is present and bumps the driver version.
  • Preserves gadget memory across suspend and simplifies resume/start paths.
  • Initializes the endpoint device pointer before dequeue validation and reorders host shutdown cleanup.
  • Updates Kconfig selections for the revised driver support.
drivers/usb/phytium_usb_v2/Kconfig
drivers/usb/phytium_usb_v2/core.c
drivers/usb/phytium_usb_v2/core.h
drivers/usb/phytium_usb_v2/gadget.c
drivers/usb/phytium_usb_v2/host.c
drivers/usb/phytium/Kconfig
drivers/usb/phytium_usb_v2/Kconfig

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

Hi @wangchenlu2236. Thanks for your PR.

I'm waiting for a deepin-community member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 15 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="drivers/char/usb_tcm_phytium.c" line_range="113" />
<code_context>
+
+	ptcm->read_condition = 0;
+
+	memcpy(buf, ptcm->read_data_buf, ptcm->read_urb->actual_length);
+
+	return ptcm->read_urb->actual_length;
</code_context>
<issue_to_address>
**Long reads corrupt the stack**

When the device returns more than 30 bytes, `usb_tcm_read` copies `actual_length` bytes into its 30-byte local `buf`, so a longer response overwrites the kernel stack before the function returns.

Copy into a destination sized for the transfer, and reject or limit responses that exceed its capacity.
</issue_to_address>

### Comment 2
<location path="drivers/char/usb_tcm_phytium.c" line_range="59" />
<code_context>
+
+	len = count > DEFAULT_PK_SIZE ? DEFAULT_PK_SIZE : count;
+
+	memcpy(ptcm->write_data_buf, buffer, count);
+
+	pipe = usb_sndbulkpipe(ptcm->usbdev,
</code_context>
<issue_to_address>
**Large writes corrupt memory**

When a caller passes more than 512 bytes, `usb_tcm_write` copies `count` bytes into the 512-byte `write_data_buf` even though it caps the URB length, overwriting adjacent kernel memory.

Limit the copy length to the buffer capacity, and make the returned or submitted length consistent with that limit.
</issue_to_address>

### Comment 3
<location path="drivers/usb/gadget/function/f_usb_tcm.c" line_range="816" />
<code_context>
+	usb_tcm_g = func_to_usb_tcm_g(f);
+	opts = container_of(f->fi, struct f_usb_tcm_opts, func_inst);
+
+	kfree(usb_tcm_g);
+	mutex_lock(&opts->lock);
+	--opts->refcnt;
</code_context>
<issue_to_address>
**Open files access freed state**

When userspace keeps the character device open while the gadget function is unbound or removed, `usb_tcm_g_free` frees the function object retained in `file->private_data`; removing the cdev does not invalidate existing descriptors, so later file operations dereference freed memory.

Keep the function object alive until all open files have released it, or otherwise make their operations safe after unbind.

Also at `drivers/usb/gadget/function/f_usb_tcm.c:438-439`, `drivers/usb/gadget/function/f_usb_tcm.c:478-501`, `drivers/usb/gadget/function/f_usb_tcm.c:827-829`.
</issue_to_address>

### Comment 4
<location path="drivers/usb/host/xhci-plat.c" line_range="224" />
<code_context>
+#ifdef CONFIG_ARCH_PHYTIUM
+	if (is_pe220x() || is_pd2408()) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		hcd->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	} else {
+		hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
</code_context>
<issue_to_address>
**Failed mapping crashes probe**

When the Phytium register mapping fails or its memory resource is absent, `devm_ioremap` can return `NULL`, which the `IS_ERR` check does not catch; an absent resource can also leave `res` unset before it is dereferenced, so probe continues or fails with a kernel fault instead of a clean error.

Validate the resource before using it and treat a `NULL` mapping as a probe failure.

Also at `drivers/usb/host/xhci-plat.c:225-231`.
</issue_to_address>

### Comment 5
<location path="drivers/char/usb_tcm_phytium.c" line_range="113" />
<code_context>
+
+	ptcm->read_condition = 0;
+
+	memcpy(buf, ptcm->read_data_buf, ptcm->read_urb->actual_length);
+
+	return ptcm->read_urb->actual_length;
</code_context>
<issue_to_address>
**Successful reads return no data**

When a USB TCM read completes, `usb_tcm_read` copies received bytes into its local `buf` instead of the caller's `buffer`, then returns a positive length while the caller's destination remains unchanged.

Copy the received data into `buffer` before returning the byte count.
</issue_to_address>

### Comment 6
<location path="drivers/usb/gadget/function/f_usb_tcm.c" line_range="89" />
<code_context>
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+	.bEndpointAddress	= USB_DIR_IN,
+	.bmAttributes		= USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize	= cpu_to_le16(128),
+	.bInterval		= 4, /* FIXME: Add this field in the
</code_context>
<issue_to_address>
**Transfers fail at two speeds**

When the gadget and Phytium host communicate at Full-Speed or SuperSpeed, the gadget advertises interrupt endpoints at those speeds, but the host submits bulk URBs; the endpoint types do not match, so TCM transfers fail.

Advertise endpoint types that match the host's bulk URBs at every supported speed.

Also at `drivers/char/usb_tcm_phytium.c:61-66`, `drivers/char/usb_tcm_phytium.c:93-97`, `drivers/char/usb_tcm_phytium.c:139-140`, `drivers/usb/gadget/function/f_usb_tcm.c:90`, `drivers/usb/gadget/function/f_usb_tcm.c:111`, `drivers/usb/gadget/function/f_usb_tcm.c:168`, `drivers/usb/gadget/function/f_usb_tcm.c:175-189`.
</issue_to_address>

### Comment 7
<location path="drivers/usb/gadget/function/f_usb_tcm.c" line_range="567" />
<code_context>
+				req->context  = usb_tcm_g;
+				status = usb_ep_queue(usb_tcm_g->out_ep, req,
+								GFP_ATOMIC);
+				if (status) {
+					ERROR(cdev, "%s queue req --> %d\n",
+						usb_tcm_g->out_ep->name, status);
</code_context>
<issue_to_address>
**Failed queueing reports success**

When `usb_ep_queue` fails while setting up the OUT endpoint, `usb_tcm_g_set_alt` frees the failed request but continues setup and returns 0, reporting an active function with missing OUT receive requests; host data is then not serviced.

Stop setup and return the queueing error when an OUT request cannot be queued.

Also at `drivers/usb/gadget/function/f_usb_tcm.c:568-570`, `drivers/usb/gadget/function/f_usb_tcm.c:586`.
</issue_to_address>

### Comment 8
<location path="drivers/char/usb_tcm_phytium.c" line_range="74" />
<code_context>
+		return ret;
+	}
+
+	ret = wait_event_interruptible(ptcm->write_wq, ptcm->write_condition);
+	if (ret) {
+		pr_err("receive signal ....\n");
</code_context>
<issue_to_address>
**Later writes report early completion**

When a write follows a completed write, `usb_complete_out` leaves `write_condition` set, so the next `usb_tcm_write` wait returns immediately before its URB finishes; callers can reuse the shared URB or buffer while the transfer is active.

Reset the completion condition for each submission and synchronize access to the shared URB and buffer.

Also at `drivers/char/usb_tcm_phytium.c:49`.
</issue_to_address>

### Comment 9
<location path="drivers/char/usb_tcm_phytium.c" line_range="43" />
<code_context>
+
+void usb_complete_in(struct urb *urb)
+{
+	ptcm->read_condition = 1;
+	wake_up_interruptible(&ptcm->read_wq);
+}
</code_context>
<issue_to_address>
**Failed transfers report success**

When a submitted URB completes with an error status, the completion callbacks ignore `urb->status`, and `usb_tcm_write` returns the requested length after completion, so callers see failed USB transfers as successful.

Record and return the URB status so callers can distinguish transfer errors from success.

Also at `drivers/char/usb_tcm_phytium.c:47-51`.
</issue_to_address>

### Comment 10
<location path="drivers/usb/gadget/function/f_usb_tcm.c" line_range="486" />
<code_context>
+
+	usb_ep_disable(usb_tcm_g->in_ep);
+
+	usb_ep_disable(usb_tcm_g->out_ep);
+
+	spin_lock_irqsave(&usb_tcm_g->read_spinlock, flags);
</code_context>
<issue_to_address>
**Blocked reads never wake**

When a process is blocked in read while the gadget function is disabled or disconnected, `usb_tcm_g_disable` drains or disables the OUT endpoint without marking reads terminal or waking `read_queue`, so `f_usb_tcm_g_read` remains blocked after disconnect.

Set a shutdown condition and wake blocked readers when disabling the function.

Also at `drivers/usb/gadget/function/f_usb_tcm.c:248`, `drivers/usb/gadget/function/f_usb_tcm.c:471`, `drivers/usb/gadget/function/f_usb_tcm.c:501`, `drivers/usb/gadget/function/f_usb_tcm.c:583`.
</issue_to_address>

### Comment 11
<location path="drivers/usb/gadget/function/f_usb_tcm.c" line_range="373" />
<code_context>
+		 * TODO
+		 * Should we fail with error here?
+		 */
+		goto try_again;
+	}
+
</code_context>
<issue_to_address>
**Disabled writes wait forever**

When the function is disabled while a write is copying data, `f_usb_tcm_g_write` reaches `try_again` with `write_pending` still set and no request queued to clear it, so the blocking writer never returns.

Clear or terminate the pending write and wake the writer when disable interrupts the copy.

Also at `drivers/usb/gadget/function/f_usb_tcm.c:497-501`.
</issue_to_address>

### Comment 12
<location path="drivers/char/usb_tcm_phytium.c" line_range="64-68" />
<code_context>
+	pipe = usb_sndbulkpipe(ptcm->usbdev,
+			ptcm->bulk_out_ep->desc.bEndpointAddress);
+
+	usb_fill_bulk_urb(ptcm->write_urb, ptcm->usbdev, pipe,
+			ptcm->write_data_buf, len, usb_complete_out,
+			(void *)ptcm);
+
+	ret = usb_submit_urb(ptcm->write_urb, GFP_ATOMIC);
+	if (ret) {
+		pr_err("%s error:%d\n", __func__, ret);
</code_context>
<issue_to_address>
**Concurrent calls corrupt active transfers**

When multiple callers invoke the same transfer function concurrently, concurrent calls reuse the same URB and transfer buffer without serialization. A second call can overwrite URB fields or shared data while the first transfer is active, causing a failed submission or sending/receiving the wrong data.

Serialize submissions and buffer access, or allocate independent URBs and buffers for concurrent operations.

Also at `drivers/char/usb_tcm_phytium.c:95-97`.
</issue_to_address>

### Comment 13
<location path="drivers/usb/phytium_usb_v2/gadget.c" line_range="1500" />
<code_context>
 	int ret = 0;

 	if (phytium_usb_otg_power_is_lost((void *)phytium_usb)) {
</code_context>
<issue_to_address>
**Failed gadget start reports success**

When the `setup_buf` allocation fails during gadget start, `gadget_start()` returns 0 when allocating `setup_buf` fails, even though it frees `pdev` and leaves `phytium_usb->gadget_dev` pointing at that freed object. The role manager treats the start as successful, and later suspend or stop paths use the stale pointer.

Return `-ENOMEM` on this failure path and clear `gadget_dev` before freeing `pdev`.
</issue_to_address>

### Comment 14
<location path="drivers/usb/gadget/function/f_usb_tcm.c" line_range="730" />
<code_context>
+
+static ssize_t f_usb_tcm_opts_dev_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%d:%s\n", __LINE__, __func__);
+}
+
</code_context>
<issue_to_address>
**Configfs reports an unusable device value**

When userspace reads the function's `dev` configfs attribute, `f_usb_tcm_opts_dev_show` prints the source line and function name instead of the character device's major and minor, so userspace cannot identify the device node.

Return the character device's major and minor numbers from the attribute.
</issue_to_address>

### Comment 15
<location path="drivers/char/usb_tcm_phytium.c" line_range="53" />
<code_context>
+	wake_up_interruptible(&ptcm->write_wq);
+}
+
+int usb_tcm_write(const char *buffer, int count)
+{
+	int ret, len, pipe;
</code_context>
<issue_to_address>
**Host communication API is inaccessible**

The host driver provides no character-device or other userspace interface, and its communication functions are not exported for other modules to call. As a result, the driver can bind to the device but callers cannot use it to send or receive TCM data through an available interface.

Provide a usable interface for the host driver, such as a character device or exported API with declarations and in-tree callers.

Also at `drivers/char/usb_tcm_phytium.c:84`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨


ptcm->read_condition = 0;

memcpy(buf, ptcm->read_data_buf, ptcm->read_urb->actual_length);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Critical · Long reads corrupt the stack

When the device returns more than 30 bytes, usb_tcm_read copies actual_length bytes into its 30-byte local buf, so a longer response overwrites the kernel stack before the function returns.

Copy into a destination sized for the transfer, and reject or limit responses that exceed its capacity.

Prompt for AI agents
In `drivers/char/usb_tcm_phytium.c` at line 113:

**Long reads corrupt the stack**

When the device returns more than 30 bytes, `usb_tcm_read` copies `actual_length` bytes into its 30-byte local `buf`, so a longer response overwrites the kernel stack before the function returns.

Copy into a destination sized for the transfer, and reject or limit responses that exceed its capacity.


len = count > DEFAULT_PK_SIZE ? DEFAULT_PK_SIZE : count;

memcpy(ptcm->write_data_buf, buffer, count);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Critical · Large writes corrupt memory

When a caller passes more than 512 bytes, usb_tcm_write copies count bytes into the 512-byte write_data_buf even though it caps the URB length, overwriting adjacent kernel memory.

Limit the copy length to the buffer capacity, and make the returned or submitted length consistent with that limit.

Prompt for AI agents
In `drivers/char/usb_tcm_phytium.c` at line 59:

**Large writes corrupt memory**

When a caller passes more than 512 bytes, `usb_tcm_write` copies `count` bytes into the 512-byte `write_data_buf` even though it caps the URB length, overwriting adjacent kernel memory.

Limit the copy length to the buffer capacity, and make the returned or submitted length consistent with that limit.

usb_tcm_g = func_to_usb_tcm_g(f);
opts = container_of(f->fi, struct f_usb_tcm_opts, func_inst);

kfree(usb_tcm_g);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Open files access freed state

When userspace keeps the character device open while the gadget function is unbound or removed, usb_tcm_g_free frees the function object retained in file->private_data; removing the cdev does not invalidate existing descriptors, so later file operations dereference freed memory.

Keep the function object alive until all open files have released it, or otherwise make their operations safe after unbind.

Also at drivers/usb/gadget/function/f_usb_tcm.c:438-439, drivers/usb/gadget/function/f_usb_tcm.c:478-501, drivers/usb/gadget/function/f_usb_tcm.c:827-829.

Prompt for AI agents
In `drivers/usb/gadget/function/f_usb_tcm.c` at line 816:

**Open files access freed state**

When userspace keeps the character device open while the gadget function is unbound or removed, `usb_tcm_g_free` frees the function object retained in `file->private_data`; removing the cdev does not invalidate existing descriptors, so later file operations dereference freed memory.

Keep the function object alive until all open files have released it, or otherwise make their operations safe after unbind.

Also at `drivers/usb/gadget/function/f_usb_tcm.c:438-439`, `drivers/usb/gadget/function/f_usb_tcm.c:478-501`, `drivers/usb/gadget/function/f_usb_tcm.c:827-829`.

#ifdef CONFIG_ARCH_PHYTIUM
if (is_pe220x() || is_pd2408()) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Failed mapping crashes probe

When the Phytium register mapping fails or its memory resource is absent, devm_ioremap can return NULL, which the IS_ERR check does not catch; an absent resource can also leave res unset before it is dereferenced, so probe continues or fails with a kernel fault instead of a clean error.

Validate the resource before using it and treat a NULL mapping as a probe failure.

Also at drivers/usb/host/xhci-plat.c:225-231.

Prompt for AI agents
In `drivers/usb/host/xhci-plat.c` at line 224:

**Failed mapping crashes probe**

When the Phytium register mapping fails or its memory resource is absent, `devm_ioremap` can return `NULL`, which the `IS_ERR` check does not catch; an absent resource can also leave `res` unset before it is dereferenced, so probe continues or fails with a kernel fault instead of a clean error.

Validate the resource before using it and treat a `NULL` mapping as a probe failure.

Also at `drivers/usb/host/xhci-plat.c:225-231`.


ptcm->read_condition = 0;

memcpy(buf, ptcm->read_data_buf, ptcm->read_urb->actual_length);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Successful reads return no data

When a USB TCM read completes, usb_tcm_read copies received bytes into its local buf instead of the caller's buffer, then returns a positive length while the caller's destination remains unchanged.

Copy the received data into buffer before returning the byte count.

Prompt for AI agents
In `drivers/char/usb_tcm_phytium.c` at line 113:

**Successful reads return no data**

When a USB TCM read completes, `usb_tcm_read` copies received bytes into its local `buf` instead of the caller's `buffer`, then returns a positive length while the caller's destination remains unchanged.

Copy the received data into `buffer` before returning the byte count.

* TODO
* Should we fail with error here?
*/
goto try_again;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Disabled writes wait forever

When the function is disabled while a write is copying data, f_usb_tcm_g_write reaches try_again with write_pending still set and no request queued to clear it, so the blocking writer never returns.

Clear or terminate the pending write and wake the writer when disable interrupts the copy.

Also at drivers/usb/gadget/function/f_usb_tcm.c:497-501.

Prompt for AI agents
In `drivers/usb/gadget/function/f_usb_tcm.c` at line 373:

**Disabled writes wait forever**

When the function is disabled while a write is copying data, `f_usb_tcm_g_write` reaches `try_again` with `write_pending` still set and no request queued to clear it, so the blocking writer never returns.

Clear or terminate the pending write and wake the writer when disable interrupts the copy.

Also at `drivers/usb/gadget/function/f_usb_tcm.c:497-501`.

Comment on lines +64 to +68
usb_fill_bulk_urb(ptcm->write_urb, ptcm->usbdev, pipe,
ptcm->write_data_buf, len, usb_complete_out,
(void *)ptcm);

ret = usb_submit_urb(ptcm->write_urb, GFP_ATOMIC);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Concurrent calls corrupt active transfers

When multiple callers invoke the same transfer function concurrently, concurrent calls reuse the same URB and transfer buffer without serialization. A second call can overwrite URB fields or shared data while the first transfer is active, causing a failed submission or sending/receiving the wrong data.

Serialize submissions and buffer access, or allocate independent URBs and buffers for concurrent operations.

Also at drivers/char/usb_tcm_phytium.c:95-97.

Prompt for AI agents
In `drivers/char/usb_tcm_phytium.c` at lines 64-68:

**Concurrent calls corrupt active transfers**

When multiple callers invoke the same transfer function concurrently, concurrent calls reuse the same URB and transfer buffer without serialization. A second call can overwrite URB fields or shared data while the first transfer is active, causing a failed submission or sending/receiving the wrong data.

Serialize submissions and buffer access, or allocate independent URBs and buffers for concurrent operations.

Also at `drivers/char/usb_tcm_phytium.c:95-97`.

struct phytium_usb *phytium_usb = (struct phytium_usb *)data;
u32 max_speed;
int ret = -ENOMEM;
int ret = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Failed gadget start reports success

When the setup_buf allocation fails during gadget start, gadget_start() returns 0 when allocating setup_buf fails, even though it frees pdev and leaves phytium_usb->gadget_dev pointing at that freed object. The role manager treats the start as successful, and later suspend or stop paths use the stale pointer.

Return -ENOMEM on this failure path and clear gadget_dev before freeing pdev.

Prompt for AI agents
In `drivers/usb/phytium_usb_v2/gadget.c` at line 1500:

**Failed gadget start reports success**

When the `setup_buf` allocation fails during gadget start, `gadget_start()` returns 0 when allocating `setup_buf` fails, even though it frees `pdev` and leaves `phytium_usb->gadget_dev` pointing at that freed object. The role manager treats the start as successful, and later suspend or stop paths use the stale pointer.

Return `-ENOMEM` on this failure path and clear `gadget_dev` before freeing `pdev`.


static ssize_t f_usb_tcm_opts_dev_show(struct config_item *item, char *page)
{
return sprintf(page, "%d:%s\n", __LINE__, __func__);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium · Configfs reports an unusable device value

When userspace reads the function's dev configfs attribute, f_usb_tcm_opts_dev_show prints the source line and function name instead of the character device's major and minor, so userspace cannot identify the device node.

Return the character device's major and minor numbers from the attribute.

Prompt for AI agents
In `drivers/usb/gadget/function/f_usb_tcm.c` at line 730:

**Configfs reports an unusable device value**

When userspace reads the function's `dev` configfs attribute, `f_usb_tcm_opts_dev_show` prints the source line and function name instead of the character device's major and minor, so userspace cannot identify the device node.

Return the character device's major and minor numbers from the attribute.

wake_up_interruptible(&ptcm->write_wq);
}

int usb_tcm_write(const char *buffer, int count)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High · Host communication API is inaccessible

The host driver provides no character-device or other userspace interface, and its communication functions are not exported for other modules to call. As a result, the driver can bind to the device but callers cannot use it to send or receive TCM data through an available interface.

Provide a usable interface for the host driver, such as a character device or exported API with declarations and in-tree callers.

Also at drivers/char/usb_tcm_phytium.c:84.

Prompt for AI agents
In `drivers/char/usb_tcm_phytium.c` at line 53:

**Host communication API is inaccessible**

The host driver provides no character-device or other userspace interface, and its communication functions are not exported for other modules to call. As a result, the driver can bind to the device but callers cannot use it to send or receive TCM data through an available interface.

Provide a usable interface for the host driver, such as a character device or exported API with declarations and in-tree callers.

Also at `drivers/char/usb_tcm_phytium.c:84`.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved memory-safety, device-lifetime, transfer-handling, and controller-recovery defects block approval.

26 open issues

And 6 more that still need to be addressed.

What changed in this PR

Updates Phytium USB controller support for the 6.6.0.4 release, adding TCM communication drivers and platform-specific recovery alongside existing controller fixes.

Changes:

  • Add USB TCM host support and a configurable gadget function with character-device access.
  • Introduce delayed xHCI recovery for affected Phytium platforms.
  • Adjust DMA initialization, port reset, gadget power management, shutdown ordering, and platform dependencies.
File Description
drivers/​usb/​phytium/​Kconfig Restrict controller options to Phytium platforms.
drivers/​usb/​phytium/​host.c Force the hardware port-reset operation.
drivers/​usb/​phytium/​dma.c Initialize channel lists earlier and guard empty queues.
drivers/​usb/​phytium_usb_v2/​Kconfig Add Phytium architecture dependencies.
drivers/​usb/​phytium_usb_v2/​host.c Unregister the host before powering it off.
drivers/​usb/​phytium_usb_v2/​gadget.c Adjust dequeue handling, initialization, and suspend/resume.
drivers/​usb/​phytium_usb_v2/​core.h Increment the internal driver version.
drivers/​usb/​phytium_usb_v2/​core.c Adjust role handling during power-loss recovery.
drivers/​usb/​host/​xhci.h Add Phytium recovery-work state.
drivers/​usb/​host/​xhci-ring.c Schedule recovery after controller failure.
drivers/​usb/​host/​xhci-plat.c Implement recovery callbacks, workqueue management, and mapping changes.
drivers/​usb/​gadget/​Kconfig Add TCM gadget configuration options.
drivers/​usb/​gadget/​function/​usb_tcm_pk.h Define TCM packet commands and layout.
drivers/​usb/​gadget/​function/​u_usb_tcm.h Define gadget-instance options and setup interfaces.
drivers/​usb/​gadget/​function/​Makefile Build the TCM gadget function.
drivers/​usb/​gadget/​function/​f_usb_tcm.c Implement gadget descriptors, transfers, and character-device operations.
drivers/​char/​usb_tcm_phytium.c Add the TCM host USB driver and transfer helpers.
drivers/​char/​Makefile Build the TCM host driver.
drivers/​char/​Kconfig Expose the TCM host-driver option.

Review effort: Balanced

Comment thread drivers/char/Kconfig

config PHYTIUM_USB_TCM
tristate "Phytium usb tcm"
depends on ARCH_PHYTIUM
Comment on lines +18 to +19
struct urb *read_urb;
struct urb *write_urb;
Comment on lines +57 to +59
len = count > DEFAULT_PK_SIZE ? DEFAULT_PK_SIZE : count;

memcpy(ptcm->write_data_buf, buffer, count);

ptcm->read_condition = 0;

memcpy(buf, ptcm->read_data_buf, ptcm->read_urb->actual_length);
init_waitqueue_head(&tcm->write_wq);

usb_set_intfdata(intf, tcm);
ptcm = tcm;
ret = wait_event_interruptible(ptcm->read_wq, ptcm->read_condition);
if (ret) {
pr_err("%s receive signal ....\n", __func__);
return ret;
return ret;
}

ptcm->read_condition = 0;
if (!tcm->write_urb)
goto fail4;

tcm->usbdev = dev;
Comment on lines +650 to +651
usb_tcm_g_ss_in_ep_desc.bEndpointAddress = usb_tcm_g_fs_in_ep_desc.bEndpointAddress;
usb_tcm_g_ss_out_ep_desc.bEndpointAddress = usb_tcm_g_fs_out_ep_desc.bEndpointAddress;
Comment on lines +640 to 648
#ifdef CONFIG_ARCH_PHYTIUM
if (is_pe220x() || is_pd2408()) {
xhci_wq = create_workqueue("xhci_wq");
if (!xhci_wq)
return -ENOMEM;
}
#endif
xhci_init_driver(&xhci_plat_hc_driver, &xhci_plat_overrides);
return platform_driver_register(&usb_generic_xhci_driver);
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign dongert for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

…IUM SOC"

This reverts commit 005e11a63e3773754f61eb76e5a588172edb1da4.

Reason for revert: <isoc trb error, don't use retry send trb>

Signed-off-by: Peng Yao <pengyao2712@phytium.com.cn>
Signed-off-by: Wang Yinfeng <wangyinfeng@phytium.com.cn>
Signed-off-by: Wang Chenlu <wangchenlu2236@phytium.com.cn>
@opsiff
opsiff merged commit b54d8ac into deepin-community:linux-6.6.y Oct 23, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants