How Data Is Transferred Between Linux USB Host and Device Using USB Endpoints

How Data Is Transferred Between Linux USB Host and Device Using USB Endpoints

Communication between a Linux USB host system and a USB device follows a highly structured model defined by the USB specification. At the center of this model are USB endpoints - logical channels on the device through which data flows. Understanding how Linux uses these endpoints helps developers design drivers, debug issues, and optimize overall system performance.


1. What Are USB Endpoints?

A USB endpoint is a unidirectional data communication channel present inside the USB device. Each endpoint:

  • Has a direction:
  • Has a type (control, bulk, interrupt, or isochronous)
  • Is identified by an endpoint number (0–15 per direction)
  • Is managed by a USB pipe on the host side

Endpoint 0 is always a control endpoint, mandatory for enumeration and standard commands.


2. Endpoint Types and Their Behavior

Article content

Linux controls these endpoints using URBs (USB Request Blocks) and the USB core driver.


3. USB Pipes: Host-Side View of Endpoints

Linux does not directly operate on endpoints — instead, it uses pipes, which are the host’s representation of device endpoints.

A USB pipe encapsulates:

  • Device address
  • Endpoint number
  • Direction
  • Transfer type
  • Maximum packet size

There are 4 pipe types: control, bulk, interrupt, isochronous, corresponding to endpoint types.

Article content


How Pipes Are Created

During enumeration, Linux reads the device’s descriptors. It parses:

  • Device Descriptor
  • Configuration Descriptor
  • Interface Descriptor
  • Endpoint Descriptors

For each endpoint, Linux sets up a corresponding pipe (e.g., usb_rcvbulkpipe(), usb_sndbulkpipe() APIs) that the driver uses.


4. How Data Flows from Linux USB Host to a Device

Article content

Step 1: Driver Identifies the Endpoint

The driver parses endpoint descriptors found in:

struct usb_endpoint_descriptor *ep = &interface->endpoint[i].desc;
        

It checks:

  • Endpoint address → direction
  • Endpoint attributes → type
  • Max packet size

Step 2: Driver Creates a Pipe

To send OUT data to the device’s bulk endpoint:

pipe = usb_sndbulkpipe(udev, ep->bEndpointAddress);
        

Step 3: Prepare an URB

URB is the data carrier between Host and USB Core.

struct urb *urb = usb_alloc_urb(0, GFP_KERNEL);
usb_fill_bulk_urb(urb, udev, pipe, buffer, length, callback, context);
        

Step 4: Submit URB

The host controller driver (EHCI/XHCI/OHCI/UHCI) handles the hardware transfer.

usb_submit_urb(urb, GFP_KERNEL);
        

Step 5: Device Receives Data via Endpoint Buffer

The USB device firmware reads the OUT endpoint FIFO or DMA buffer and processes the data.


5. How Data Flows from Device to Linux USB Host (IN Endpoint)

Article content

  1. Driver allocates an URB and targets the IN endpoint pipe:
  2. Submits URB to ask for device data:
  3. Host controller schedules IN transactions.
  4. Device places data into its IN endpoint buffer.
  5. Host retrieves data and notifies driver via callback.


6. Role of Host Controller Driver (HCD)

Linux USB Core hands URBs to an HCD:

  • XHCI for USB 3.x
  • EHCI for USB 2.0 high-speed
  • OHCI/UHCI for USB 1.1 full/low-speed

HCD is responsible for:

  • Scheduling transfers
  • Handling retries (except isochronous)
  • Managing bandwidth
  • Generating interrupts on completion

This ensures reliable, predictable data movement via endpoints.


7. Practical Example: USB to Serial Device

For a USB modem (CDC-ACM type):

  • Bulk OUT endpoint → Send AT commands
  • Bulk IN endpoint → Receive modem responses
  • Interrupt IN endpoint → Notifications (network status, call events)

Linux’s cdc_acm driver uses URBs to communicate through these endpoints.


8. Summary

USB endpoints are the fundamental channels controlling how data flows between a Linux USB host and a USB device. The host uses pipes, URBs, and USB Core APIs to interact with these endpoints. The type and configuration of each endpoint determine:

  • How data is transmitted
  • Priorities and timing
  • Reliability and ordering

Understanding endpoint-based data transfer is essential for developing USB device drivers, debugging communication problems, and designing robust USB-based systems.

Follow newsletter Linux Core Concepts : Core Interface System

#LinuxKernel #EmbeddedLinux #USBDrivers #NetworkDeviceDriver #Networking #AI #AIDataCenter #DeviceDrivers #Networking #IoT #LinuxNetworking #CProgramming #KernelDevelopment #EmbeddedSystems #URB #LinuxInternals #OpenSource

To view or add a comment, sign in

More articles by Pravin Jogdand

Others also viewed

Explore content categories