STRUCT DWC2_HSOTG(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

🌸 NAME 🌸

struct dwc2_hsotg β€” bestie, this is the struct. It holds the state of the driver, including the non-periodic and periodic schedules. It's from the Kernel API Manual, section 9 (yes, struct dwc2_hsotg(9), that's the whole vibe) πŸ’…


✨ SYNOPSIS ✨

Ok so picture this: one giant struct, and it's giving main character energy. Here's the whole thing, copy-pasted exactly, no cap:

struct dwc2_hsotg {
    struct device *dev;
    void __iomem *regs;
    struct dwc2_hw_params hw_params;
    struct dwc2_core_params params;
    enum usb_otg_state op_state;
    enum usb_dr_mode dr_mode;
    struct usb_role_switch *role_sw;
    enum usb_dr_mode role_sw_default_mode;
    unsigned int hcd_enabled:1;
    unsigned int gadget_enabled:1;
    unsigned int ll_hw_enabled:1;
    unsigned int hibernated:1;
    unsigned int in_ppd:1;
    bool bus_suspended;
    unsigned int reset_phy_on_wake:1;
    unsigned int need_phy_for_wake:1;
    unsigned int phy_off_for_suspend:1;
    u16 frame_number;
    struct phy *phy;
    struct usb_phy *uphy;
    struct dwc2_hsotg_plat *plat;
    struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES];
    struct regulator *vbus_supply;
    struct regulator *usb33d;
    spinlock_t lock;
    void *priv;
    int irq;
    struct clk *clk;
    struct clk *utmi_clk;
    struct reset_control *reset;
    struct reset_control *reset_ecc;
    unsigned int queuing_high_bandwidth:1;
    unsigned int srp_success:1;
    struct workqueue_struct *wq_otg;
    struct work_struct wf_otg;
    struct timer_list wkp_timer;
    enum dwc2_lx_state lx_state;
    struct dwc2_gregs_backup gr_backup;
    struct dwc2_dregs_backup dr_backup;
    struct dwc2_hregs_backup hr_backup;
    struct dentry *debug_root;
    struct debugfs_regset32 *regset;
    bool needs_byte_swap;
  #define DWC2_CORE_REV_4_30a     0x4f54430a;
  #define DWC2_CORE_REV_2_71a     0x4f54271a;
  #define DWC2_CORE_REV_2_72a     0x4f54272a;
  #define DWC2_CORE_REV_2_80a     0x4f54280a;
  #define DWC2_CORE_REV_2_90a     0x4f54290a;
  #define DWC2_CORE_REV_2_91a     0x4f54291a;
  #define DWC2_CORE_REV_2_92a     0x4f54292a;
  #define DWC2_CORE_REV_2_94a     0x4f54294a;
  #define DWC2_CORE_REV_3_00a     0x4f54300a;
  #define DWC2_CORE_REV_3_10a     0x4f54310a;
  #define DWC2_CORE_REV_4_00a     0x4f54400a;
  #define DWC2_CORE_REV_4_20a     0x4f54420a;
  #define DWC2_CORE_REV_5_00a     0x4f54500a;
  #define DWC2_FS_IOT_REV_1_00a   0x5531100a;
  #define DWC2_HS_IOT_REV_1_00a   0x5532100a;
  #define DWC2_HS_IOT_REV_5_00a   0x5532500a;
  #define DWC2_CORE_REV_MASK      0x0000ffff;
  #define DWC2_OTG_ID             0x4f540000;
  #define DWC2_FS_IOT_ID          0x55310000;
  #define DWC2_HS_IOT_ID          0x55320000;
  #define DWC2_RESTORE_DCTL BIT(0);
  #define DWC2_RESTORE_DCFG BIT(1);
  #if IS_ENABLED(CONFIG_USB_DWC2_HOST) ||
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE);
  union dwc2_hcd_internal_flags {
    u32 d32;
    struct {
      unsigned port_connect_status_change:1;
      unsigned port_connect_status:1;
      unsigned port_reset_change:1;
      unsigned port_enable_change:1;
      unsigned port_suspend_change:1;
      unsigned port_over_current_change:1;
      unsigned port_l1_change:1;
      unsigned reserved:25;
    } b;
  } flags;
  struct list_head non_periodic_sched_inactive;
  struct list_head non_periodic_sched_waiting;
  struct list_head non_periodic_sched_active;
  struct list_head *non_periodic_qh_ptr;
  struct list_head periodic_sched_inactive;
  struct list_head periodic_sched_ready;
  struct list_head periodic_sched_assigned;
  struct list_head periodic_sched_queued;
  struct list_head split_order;
  u16 periodic_usecs;
  unsigned long hs_periodic_bitmap[BITS_TO_LONGS(
DWC2_HS_SCHEDULE_US)];
  u16 periodic_qh_count;
  bool new_connection;
  u16 last_frame_num;
  #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS;
  #define FRAME_NUM_ARRAY_SIZE 1000;
  u16 *frame_num_array;
  u16 *last_frame_num_array;
  int frame_num_idx;
  int dumped_frame_num_array;
  #endif;
  struct list_head free_hc_list;
  int periodic_channels;
  int non_periodic_channels;
  int available_host_channels;
  struct dwc2_host_chan *hc_ptr_array[MAX_EPS_CHANNELS];
  u8 *status_buf;
  dma_addr_t status_buf_dma;
  #define DWC2_HCD_STATUS_BUF_SIZE 64;
  struct delayed_work start_work;
  struct delayed_work reset_work;
  struct work_struct phy_reset_work;
  u8 otg_port;
  u32 *frame_list;
  dma_addr_t frame_list_dma;
  u32 frame_list_sz;
  struct kmem_cache *desc_gen_cache;
  struct kmem_cache *desc_hsisoc_cache;
  struct kmem_cache *unaligned_cache;
  #define DWC2_KMEM_UNALIGNED_BUF_SIZE 1024;
  #endif ;
  #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) ||
IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE);
  struct usb_gadget_driver *driver;
  int fifo_mem;
  unsigned int dedicated_fifos:1;
  unsigned char num_of_eps;
  u32 fifo_map;
  struct usb_request *ep0_reply;
  struct usb_request *ctrl_req;
  void *ep0_buff;
  void *ctrl_buff;
  enum dwc2_ep0_state ep0_state;
  unsigned delayed_status : 1;
  u8 test_mode;
  dma_addr_t setup_desc_dma[2];
  struct dwc2_dma_desc *setup_desc[2];
  dma_addr_t ctrl_in_desc_dma;
  struct dwc2_dma_desc *ctrl_in_desc;
  dma_addr_t ctrl_out_desc_dma;
  struct dwc2_dma_desc *ctrl_out_desc;
  struct usb_gadget gadget;
  unsigned int enabled:1;
  unsigned int connected:1;
  unsigned int remote_wakeup_allowed:1;
  struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
  struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
  #endif ;
};

πŸŽ€ MEMBERS πŸŽ€

Ok now the part where we meet everyone individually, like a little cast of characters 🫢

  • dev β€” The struct device pointer. The whole device situation.
  • regs β€” Pointer to controller regs. Where the registers live.
  • hw_params β€” Parameters that were autodetected from the hardware registers β€” the hardware basically introduced itself ✨
  • params β€” Parameters that define how the core should be configured.
  • op_state β€” The operational State. During transitions (a_host=>a_peripheral and b_device=>b_host) this may not match the core, but it allows the software to determine transitions. It's giving "trust me, I know where we're going" energy.
  • dr_mode β€” Requested mode of operation, one of following:
    • USB_DR_MODE_PERIPHERAL
    • USB_DR_MODE_HOST
    • USB_DR_MODE_OTG
  • role_sw β€” usb_role_switch handle.
  • role_sw_default_mode β€” default operation mode of controller while usb role is USB_ROLE_NONE.
  • hcd_enabled β€” Host mode sub-driver initialization indicator.
  • gadget_enabled β€” Peripheral mode sub-driver initialization indicator.
  • ll_hw_enabled β€” Status of low-level hardware resources.
  • hibernated β€” True if core is hibernated 😴
  • in_ppd β€” True if core is partial power down mode.
  • bus_suspended β€” True if bus is suspended.
  • reset_phy_on_wake β€” Quirk saying that we should assert PHY reset on a remote wakeup.
  • need_phy_for_wake β€” Quirk saying that we should keep the PHY on at suspend if we need USB to wake us up.
  • phy_off_for_suspend β€” Status of whether we turned the PHY off at suspend.
  • frame_number β€” Frame number read from the core. For both device and host modes. The value ranges are from 0 to HFNUM_MAX_FRNUM.
  • phy β€” The otg phy transceiver structure for phy control.
  • uphy β€” The otg phy transceiver structure for old USB phy control.
  • plat β€” The platform specific configuration data. This can be removed once all SoCs support usb transceiver.
  • supplies β€” Definition of USB power supplies.
  • vbus_supply β€” Regulator supplying vbus.
  • usb33d β€” Optional 3.3v regulator used on some stm32 devices to supply ID and VBUS detection hardware.
  • lock β€” Spinlock that protects all the driver data structures. Do not mess with it, fr fr πŸ”’
  • priv β€” Stores a pointer to the struct usb_hcd.
  • irq β€” Interrupt request line number.
  • clk β€” Pointer to otg clock.
  • utmi_clk β€” Pointer to utmi_clk clock.
  • reset β€” Pointer to dwc2 reset controller.
  • reset_ecc β€” Pointer to dwc2 optional reset controller in Stratix10.
  • queuing_high_bandwidth β€” True if multiple packets of a high-bandwidth transfer are in process of being queued.
  • srp_success β€” Stores status of SRP request in the case of a FS PHY with an I2C interface.
  • wq_otg β€” Workqueue object used for handling of some interrupts.
  • wf_otg β€” Work object for handling Connector ID Status Change interrupt.
  • wkp_timer β€” Timer object for handling Wakeup Detected interrupt.
  • lx_state β€” Lx state of connected device.
  • gr_backup β€” Backup of global registers during suspend.
  • dr_backup β€” Backup of device registers during suspend.
  • hr_backup β€” Backup of host registers during suspend.
  • debug_root β€” Root directrory for debugfs.
  • regset β€” A pointer to a struct debugfs_regset32, which contains a pointer to an array of register definitions, the array size and the base address where the register bank is to be found.
  • needs_byte_swap β€” Specifies whether the opposite endianness.
  • flags β€” Flags for handling root port state changes.
  • flags.d32 β€” Contain all root port flags.
  • flags.b β€” Separate root port flags from each other.
  • flags.b.port_connect_status_change β€” True if root port connect status changed.
  • flags.b.port_connect_status β€” True if device connected to root port.
  • flags.b.port_reset_change β€” True if root port reset status changed.
  • flags.b.port_enable_change β€” True if root port enable status changed.
  • flags.b.port_suspend_change β€” True if root port suspend status changed.
  • flags.b.port_over_current_change β€” True if root port over current state changed.
  • flags.b.port_l1_change β€” True if root port l1 status changed.
  • flags.b.reserved β€” Reserved bits of root port register.
  • non_periodic_sched_inactive β€” Inactive QHs in the non-periodic schedule. Transfers associated with these QHs are not currently assigned to a host channel.
  • non_periodic_sched_waiting β€” Waiting QHs in the non-periodic schedule. Transfers associated with these QHs are not currently assigned to a host channel.
  • non_periodic_sched_active β€” Active QHs in the non-periodic schedule. Transfers associated with these QHs are currently assigned to a host channel.
  • non_periodic_qh_ptr β€” pointer to the next QH to process in the active non-periodic schedule. your little bookmark in the non-periodic queue πŸŽ€
  • periodic_sched_inactive β€” the inactive QHs in the periodic schedule, aka a list of QHs for periodic transfers that are not scheduled for the next frame. every QH in this list has an interval counter that decides when it needs to get scheduled for execution. and yeah, this whole scheduling mechanism only allows a simple calculation for the periodic bandwidth used (i.e. you must assume that all periodic transfers may need to execute in the same frame). but like β€” it greatly simplifies scheduling and should be sufficient for the vast majority of OTG hosts, which only need to connect to a small number of peripherals at one time. items move from this list to periodic_sched_ready when the QH interval counter is 0 at SOF. πŸ’«
  • periodic_sched_ready β€” list of periodic QHs that are ready for execution in the next frame but haven't been assigned to host channels yet. items move from this list to periodic_sched_assigned as host channels become available during the current frame. they're literally just waiting for their turn 🫢
  • periodic_sched_assigned β€” list of periodic QHs to be executed in the next frame that are assigned to host channels. items move from this list to periodic_sched_queued as the transactions for the QH get queued to the DWC_otg controller. glow-up complete ✨
  • periodic_sched_queued β€” list of periodic QHs that have been queued for execution. items move from this list to either periodic_sched_inactive or periodic_sched_ready when the channel associated with the transfer is released. if the interval for the QH is 1, the item moves to periodic_sched_ready because it must be rescheduled for the next frame. otherwise, the item moves to periodic_sched_inactive. no cap, those are the only two destinations πŸ’…
  • split_order β€” list keeping track of channels doing splits, in order.
  • periodic_usecs β€” total bandwidth claimed so far for periodic transfers. this value is in microseconds per (micro)frame. the assumption here is that all periodic transfers may occur in the same (micro)frame. πŸ”₯
  • hs_periodic_bitmap β€” bitmap used by the microframe scheduler any time the host is in high speed mode; low speed schedules are stored elsewhere since we need one per TT.
  • periodic_qh_count β€” count of periodic QHs, if using several eps. used for SOF enable/disable.
  • new_connection β€” used in host mode. True if there are new connected device. new friend detected πŸ¦‹
  • last_frame_num β€” number of last frame. range from 0 to 32768.
  • frame_num_array β€” used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is defined, for missed SOFs tracking. array holds that frame numbers, which not equal to last_frame_num +1. (yes i'm quoting it exactly, bestie, the grammar is not the vibe but the facts are sacred πŸŽ€)
  • last_frame_num_array β€” used only if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is defined, for missed SOFs tracking. if current_frame_number != last_frame_num+1 then last_frame_num added to this array.
  • frame_num_idx β€” actual size of frame_num_array and last_frame_num_array.
  • dumped_frame_num_array β€” 1 β€” if missed SOFs frame numbers dumbed; 0 β€” if missed SOFs frame numbers not dumbed. 😭 (their spelling, not mine, i love them for it)
  • free_hc_list β€” free host channels in the controller. this is a list of struct dwc2_host_chan items.
  • periodic_channels β€” number of host channels assigned to periodic transfers. currently assuming that there is a dedicated host channel for each periodic transaction and at least one host channel is available for non-periodic transactions.
  • non_periodic_channels β€” number of host channels assigned to non-periodic transfers.
  • available_host_channels β€” number of host channels available for the microframe scheduler to use.
  • hc_ptr_array β€” array of pointers to the host channel descriptors. lets you access a host channel descriptor given the host channel number. this is useful in interrupt handlers. genuinely iconic for that πŸ™ˆ
  • status_buf β€” buffer used for data received during the status phase of a control transfer.
  • status_buf_dma β€” DMA address for status_buf.
  • start_work β€” delayed work for handling host A-cable connection.
  • reset_work β€” delayed work for handling a port reset.
  • phy_reset_work β€” work structure for doing a PHY reset.
  • otg_port β€” OTG port number.
  • frame_list β€” frame list.
  • frame_list_dma β€” frame list DMA address.
  • frame_list_sz β€” frame list size.
  • desc_gen_cache β€” kmem cache for generic descriptors.
  • desc_hsisoc_cache β€” kmem cache for hs isochronous descriptors.
  • unaligned_cache β€” kmem cache for DMA mode to handle non-aligned buf.
  • driver β€” USB gadget driver.
  • fifo_mem β€” total internal RAM for FIFOs (bytes).
  • dedicated_fifos β€” set if the hardware has dedicated IN-EP fifos.
  • num_of_eps β€” number of available EPs (excluding EP0).
  • fifo_map β€” each bit intend for concrete fifo. if that bit is set, then that fifo is used.
  • ep0_reply β€” request used for ep0 reply.
  • ctrl_req β€” request for EP0 control packets.
  • ep0_buff β€” buffer for EP0 reply data, if needed.
  • ctrl_buff β€” buffer for EP0 control requests.
  • ep0_state β€” EP0 control transfers state.
  • delayed_status β€” true when gadget driver asks for delayed status.
  • test_mode β€” USB test mode requested by the host.
  • setup_desc_dma β€” EP0 setup stage desc chain DMA address.
  • setup_desc β€” EP0 setup stage desc chain pointer.
  • ctrl_in_desc_dma β€” EP0 IN data phase desc chain DMA address.
  • ctrl_in_desc β€” EP0 IN data phase desc chain pointer.
  • ctrl_out_desc_dma β€” EP0 OUT data phase desc chain DMA address.
  • ctrl_out_desc β€” EP0 OUT data phase desc chain pointer.
  • gadget β€” represents a usb gadget device.
  • enabled β€” indicates the enabling state of controller.
  • connected β€” used in slave mode. True if device connected with host.
  • remote_wakeup_allowed β€” True if device is allowed to wake-up host by remote-wakeup signalling.
  • eps_in β€” the IN endpoints being supplied to the gadget framework.
  • eps_out β€” the OUT endpoints being supplied to the gadget framework.

🌈 DESCRIPTION 🌈

okay so the page literally buckets everything into three groups, and here they are, word for word, no extra lore added by me:

  • these are common for both host and peripheral modes:
  • these are for host mode:
  • these are for peripheral mode:

and that's genuinely all it says β€” the buckets are empty in this listing, so don't come for me, i'm just the messenger πŸ’œ


πŸ¦‹ SEE ALSO πŸ¦‹

kernel file ./drivers/usb/dwc2/core.h

  • struct dwc2_hsotg_ep(9)
  • struct dwc2_hsotg_req(9)
  • struct dwc2_core_params(9)
  • struct dwc2_hw_params(9)
  • struct dwc2_gregs_backup(9)
  • struct dwc2_dregs_backup(9)
  • struct dwc2_hregs_backup(9)

go read them, they're all in the same friend group fr fr ✨


🌸 and that's a wrap on struct dwc2_hsotg(9)! this cutie lives in ./drivers/usb/dwc2, dated October 2026 β€” main character energy from the future, we love to see it. mwah, go touch some USB πŸ’…πŸŽ€

πŸ“¦ where this page comes from