All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] hw/usb: Add ASPEED USB Device Controller (UDC)
@ 2026-09-02  2:15 Jamin Lin
  2026-09-02  2:15 ` [PATCH v5 1/4] hw/usb/aspeed-udc: Add ASPEED UDC device controller Jamin Lin
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Jamin Lin @ 2026-09-02  2:15 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Maydell, Cédric Le Goater, Steven Lee,
	Troy Lee, Kane Chen, Andrew Jeffery, Joel Stanley,
	open list:ARM TCG CPUs, open list:All patches CC here
  Cc: Jamin Lin, Troy Lee

This series adds a QEMU model for the ASPEED USB Device Controller (UDC),
driven by the Linux "aspeed_udc" gadget driver.

It is the first step of a larger plan to model USB device-side support on
ASPEED BMC/BIC SoCs, which has three goals:

1. Model the ASPEED UDC (AST2600 / AST1030). The AST2600 also has USB host
   (EHCI) controllers, so this series targets the AST2600 UDC: its gadget can
   be attached to the SoC's own EHCI bus, letting the guest enumerate its own
   gadget and exercise the UDC end-to-end.  [this series]

2. AST1030 UDC. The AST1030 has no USB host controller, so testing its UDC
   needs a second QEMU instance. The plan is to redirect the UDC gadget out
   of the guest using libusbredir and attach it to another QEMU that runs a
   USB host (a VMM, or an AST2600 / AST2700 guest).  [on-going]
   
3. ASPEED vHub, as a longer-term goal towards BMC KVM / Virtual Media support
   in QEMU.  [future]

This series implements goal 1 only.

Design
------
The UDC is modelled as two QOM objects, because a single object cannot be
both a SysBusDevice and a USBDevice:

  - "aspeed.udc": the sysbus device (MMIO register map, IRQ and DMA engine)
    that the guest gadget driver programs.

  - "aspeed.udc-gadget": a user-creatable USB device presented on a USB host
    controller's bus. It links back to its controller through the "udc"
    property.

The SoC creates the controller; the gadget is added on the command line, e.g.

  -device aspeed.udc-gadget,udc=/machine/soc/udc
     
Test result:
-----------
The default ASPEED SDK prebuilt image does not enable the UDC driver, so
build a kernel with CONFIG_USB_ASPEED_UDC=y first.

Start QEMU with the gadget attached to the on-SoC EHCI:

  qemu-system-arm -machine ast2600-evb -drive file=<image>,if=mtd,format=raw \
      -device aspeed.udc-gadget,udc=/machine/soc/udc -nographic

In the guest, bring up a mass-storage gadget and verify enumeration and I/O:

1. Before: only the host controllers are present
root@ast2600-default:~# lsusb
unable to initialize usb specBus 001 Device 001: ID 1d6b:0002 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty ehci_hcd EHCI Host Controller
Bus 002 Device 001: ID 1d6b:0001 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty uhci_hcd Generic UHCI Host Controller

2. Enable the gadget
root@ast2600-default:~# ./usb-storage.sh
Using UDC: 1e6a2000.usb
[  598.582205] Mass Storage Function, version: 2009/09/11
[  598.582635] LUN: removable file: (no medium)
USB Mass Storage gadget is enabled.
Backing file: /home/root/jamin
root@ast2600-default:~# [  598.876395] usb 1-1: new high-speed USB device number 2 using ehci-platform
[  599.070035] usb 1-1: New USB device found, idVendor=1d6b, idProduct=0104, bcdDevice= 1.00
[  599.070821] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  599.071448] usb 1-1: Product: ASPEED USB Storage
[  599.072687] usb 1-1: Manufacturer: ASPEED
[  599.073384] usb 1-1: SerialNumber: 1234567890
[  599.103625] usb-storage 1-1:1.0: USB Mass Storage device detected
[  599.136326] scsi host0: usb-storage 1-1:1.0
[  600.230921] scsi 0:0:0:0: Direct-Access     Linux    File-Stor Gadget 0618 PQ: 0 ANSI: 2
[  600.243758] sd 0:0:0:0: Attached scsi generic sg0 type 0
[  600.263452] sd 0:0:0:0: Power-on or device reset occurred
[  600.289381] sd 0:0:0:0: [sda] 2048 512-byte logical blocks: (1.05 MB/1.00 MiB)
[  600.297896] sd 0:0:0:0: [sda] Write Protect is off
[  600.306379] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  600.424608]  sda:
[  600.425526] sd 0:0:0:0: [sda] Attached SCSI removable disk

3. After: the gadget enumerates on the EHCI bus
root@ast2600-default:~# lsusb
unable to initialize usb specBus 001 Device 001: ID 1d6b:0002 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty ehci_hcd EHCI Host Controller
Bus 001 Device 002: ID 1d6b:0104 ASPEED ASPEED USB Storage
Bus 002 Device 001: ID 1d6b:0001 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty uhci_hcd Generic UHCI Host Controller

4. Mount and verify data
root@ast2600-default:~# mount /dev/sda /mnt/
root@ast2600-default:~# sha256sum /mnt/testfile
3308890a1289f6a327c014537523e8ebd0833301af3d25a7c5893dc7050d2c70  /mnt/testfile
root@ast2600-default:~# umount /mnt

5. Stop the gadget -> clean disconnect
root@ast2600-default:~# ./usb-storage.sh stop
Stopping USB gadget...
[  669.866439] usb 1-1: USB disconnect, device number 2
Stopped.
root@ast2600-default:~# [  669.968156] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[  669.969307] sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=0x01 driverbyte=DRIVER_OK

root@ast2600-default:~# lsusb
unable to initialize usb specBus 001 Device 001: ID 1d6b:0002 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty ehci_hcd EHCI Host Controller
Bus 002 Device 001: ID 1d6b:0001 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty uhci_hcd Generic UHCI Host Controller


The contents of this scripts
---------------------------
root@ast2600-default:~# cat  usb-storage.sh
#!/bin/sh
set -e

G=/sys/kernel/config/usb_gadget/g1
IMG=/home/root/jamin
SIZE_MB=64

mount_configfs()
{
    mountpoint -q /sys/kernel/config || mount -t configfs none /sys/kernel/config
}

get_udc()
{
    ls /sys/class/udc | head -n 1
}

stop_gadget()
{
    if [ ! -d "$G" ]; then
        return
    fi

    echo "Stopping USB gadget..."

    # Unbind UDC first
    if [ -f "$G/UDC" ]; then
        echo "" > "$G/UDC" 2>/dev/null || true
    fi

    # Clear backing file to release image
    if [ -f "$G/functions/mass_storage.0/lun.0/file" ]; then
        echo "" > "$G/functions/mass_storage.0/lun.0/file" 2>/dev/null || true
    fi

    # Remove function link from config
    rm -f "$G/configs/c.1/mass_storage.0" 2>/dev/null || true

    echo "Stopped."
}

start_gadget()
{
    mount_configfs

    UDC="$(get_udc)"
    if [ -z "$UDC" ]; then
        echo "ERROR: No UDC found in /sys/class/udc"
        exit 1
    fi

    stop_gadget

    echo "Using UDC: $UDC"

    modprobe libcomposite 2>/dev/null || true

    mkdir -p "$G"
    cd "$G"

    echo 0x1d6b > idVendor
    echo 0x0104 > idProduct
    echo 0x0200 > bcdUSB
    echo 0x0100 > bcdDevice

    mkdir -p strings/0x409
    echo "1234567890" > strings/0x409/serialnumber
    echo "ASPEED" > strings/0x409/manufacturer
    echo "ASPEED USB Storage" > strings/0x409/product

    mkdir -p configs/c.1/strings/0x409
    echo "Mass Storage" > configs/c.1/strings/0x409/configuration
    echo 120 > configs/c.1/MaxPower

    if [ ! -f "$IMG" ]; then
        echo "Creating backing image: $IMG"
        dd if=/dev/zero of="$IMG" bs=1M count="$SIZE_MB"
        mkfs.vfat "$IMG"
    fi

    mkdir -p functions/mass_storage.0

    # Make sure old LUN is detached before changing attributes
    echo "" > functions/mass_storage.0/lun.0/file 2>/dev/null || true

    echo 0 > functions/mass_storage.0/stall
    echo 0 > functions/mass_storage.0/lun.0/cdrom
    echo 0 > functions/mass_storage.0/lun.0/ro
    echo 1 > functions/mass_storage.0/lun.0/removable
    echo "$IMG" > functions/mass_storage.0/lun.0/file

    ln -sf functions/mass_storage.0 configs/c.1/mass_storage.0

    echo "$UDC" > UDC

    echo "USB Mass Storage gadget is enabled."
    echo "Backing file: $IMG"
}

case "$1" in
    start|"")
        start_gadget
        ;;
    stop)
        stop_gadget
        ;;
    restart)
        stop_gadget
        sleep 1
        start_gadget
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac


v1:
  1. Add ASPEED UDC device controller
  2. Add ASPEED UDC gadget USB device

v2:
  1. Replace dynamic memory allocation with fixed-size arrays.
  2. Use an OR gate to route the interrupt signals from the UDC and EHCI2.
  3. Split the "Add ASPEED UDC gadget USB device" patch into two patches:
    a. Add ASPEED UDC gadget USB device
      Implement EP0 control transfers.
    b. Add programmable endpoint DMA transfers
      Implement DMA transfers for programmable endpoints.
  4. Remove unused macros.
  
v3:
  1. Remove unused macros.
  2. Bind the gadget to the controller via a QOM link property
   ("usbgadget", weak) instead of writing the back-pointer directly

v4:
  1. Move the "select USB" dependency to the appropriate patch.

v5:
  1. Dynamically allocate the buffer in aspeed_udc_ep_xfer_out() to reduce stack usage.

Jamin Lin (4):
  hw/usb/aspeed-udc: Add ASPEED UDC device controller
  hw/usb/aspeed-udc: Add ASPEED UDC gadget USB device
  hw/usb/aspeed-udc: Add programmable endpoint DMA transfers
  hw/arm/aspeed_ast2600: Wire up the UDC

 include/hw/arm/aspeed_soc.h |    4 +
 include/hw/usb/aspeed-udc.h |   85 +++
 hw/arm/aspeed_ast2600.c     |   37 +-
 hw/usb/aspeed-udc.c         | 1058 +++++++++++++++++++++++++++++++++++
 hw/arm/Kconfig              |    1 +
 hw/usb/Kconfig              |    4 +
 hw/usb/meson.build          |    1 +
 hw/usb/trace-events         |   16 +
 8 files changed, 1203 insertions(+), 3 deletions(-)
 create mode 100644 include/hw/usb/aspeed-udc.h
 create mode 100644 hw/usb/aspeed-udc.c

-- 
2.53.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-09-02  6:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02  2:15 [PATCH v5 0/4] hw/usb: Add ASPEED USB Device Controller (UDC) Jamin Lin
2026-09-02  2:15 ` [PATCH v5 1/4] hw/usb/aspeed-udc: Add ASPEED UDC device controller Jamin Lin
2026-09-02  2:15 ` [PATCH v5 2/4] hw/usb/aspeed-udc: Add ASPEED UDC gadget USB device Jamin Lin
2026-09-02  2:15 ` [PATCH v5 3/4] hw/usb/aspeed-udc: Add programmable endpoint DMA transfers Jamin Lin
2026-09-02  5:45   ` Cédric Le Goater
2026-09-02  2:15 ` [PATCH v5 4/4] hw/arm/aspeed_ast2600: Wire up the UDC Jamin Lin
2026-09-02  6:10 ` [PATCH v5 0/4] hw/usb: Add ASPEED USB Device Controller (UDC) Cédric Le Goater

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.