drivers/usb/dwc2/hcd_intr.c
Source file repositories/reference/linux-study-clean/drivers/usb/dwc2/hcd_intr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/dwc2/hcd_intr.c- Extension
.c- Size
- 66996 bytes
- Lines
- 2267
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/spinlock.hlinux/interrupt.hlinux/dma-mapping.hlinux/io.hlinux/slab.hlinux/usb.hlinux/usb/hcd.hlinux/usb/ch11.hcore.hhcd.h
Detected Declarations
function Copyrightfunction dwc2_hc_handle_tt_clearfunction nextfunction dwc2_rx_fifo_level_intrfunction dwc2_np_tx_fifo_empty_intrfunction dwc2_perio_tx_fifo_empty_intrfunction dwc2_hprt0_enablefunction dwc2_port_intrfunction dwc2_get_actual_xfer_lengthfunction dwc2_update_urb_statefunction dwc2_hcd_save_data_togglefunction dwc2_update_isoc_urb_statefunction dwc2_deactivate_qhfunction dwc2_release_channelfunction dwc2_halt_channelfunction dwc2_complete_non_periodic_xferfunction dwc2_complete_periodic_xferfunction dwc2_xfercomp_isoc_split_infunction dwc2_hc_xfercomp_intrfunction dwc2_hc_stall_intrfunction dwc2_update_urb_state_abnfunction dwc2_hc_nak_intrfunction interruptfunction dwc2_hc_ack_intrfunction dwc2_hc_nyet_intrfunction dwc2_hc_babble_intrfunction dwc2_hc_ahberr_intrfunction dwc2_hc_xacterr_intrfunction dwc2_hc_frmovrun_intrfunction dwc2_hc_datatglerr_intrfunction dwc2_halt_status_okfunction dwc2_hc_chhltd_intr_dmafunction dwc2_hc_chhltd_intrfunction listfunction dwc2_hc_n_intrfunction dwc2_hcd_endpoint_disablefunction dwc2_hc_intrfunction dwc2_handle_hcd_intr
Annotated Snippet
if (expected != curr_frame_number) {
hsotg->frame_num_array[hsotg->frame_num_idx] =
curr_frame_number;
hsotg->last_frame_num_array[hsotg->frame_num_idx] =
hsotg->last_frame_num;
hsotg->frame_num_idx++;
}
} else if (!hsotg->dumped_frame_num_array) {
int i;
dev_info(hsotg->dev, "Frame Last Frame\n");
dev_info(hsotg->dev, "----- ----------\n");
for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
dev_info(hsotg->dev, "0x%04x 0x%04x\n",
hsotg->frame_num_array[i],
hsotg->last_frame_num_array[i]);
}
hsotg->dumped_frame_num_array = 1;
}
#endif
hsotg->last_frame_num = curr_frame_number;
}
static void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg,
struct dwc2_host_chan *chan,
struct dwc2_qtd *qtd)
{
struct usb_device *root_hub = dwc2_hsotg_to_hcd(hsotg)->self.root_hub;
struct urb *usb_urb;
if (!chan->qh)
return;
if (chan->qh->dev_speed == USB_SPEED_HIGH)
return;
if (!qtd->urb)
return;
usb_urb = qtd->urb->priv;
if (!usb_urb || !usb_urb->dev || !usb_urb->dev->tt)
return;
/*
* The root hub doesn't really have a TT, but Linux thinks it
* does because how could you have a "high speed hub" that
* directly talks directly to low speed devices without a TT?
* It's all lies. Lies, I tell you.
*/
if (usb_urb->dev->tt->hub == root_hub)
return;
if (qtd->urb->status != -EPIPE && qtd->urb->status != -EREMOTEIO) {
chan->qh->tt_buffer_dirty = 1;
if (usb_hub_clear_tt_buffer(usb_urb))
/* Clear failed; let's hope things work anyway */
chan->qh->tt_buffer_dirty = 0;
}
}
/*
* Handles the start-of-frame interrupt in host mode. Non-periodic
* transactions may be queued to the DWC_otg controller for the current
* (micro)frame. Periodic transactions may be queued to the controller
* for the next (micro)frame.
*/
static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
{
struct list_head *qh_entry;
struct dwc2_qh *qh;
enum dwc2_transaction_type tr_type;
/* Clear interrupt */
dwc2_writel(hsotg, GINTSTS_SOF, GINTSTS);
#ifdef DEBUG_SOF
dev_vdbg(hsotg->dev, "--Start of Frame Interrupt--\n");
#endif
hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg);
dwc2_track_missed_sofs(hsotg);
/* Determine whether any periodic QHs should be executed */
qh_entry = hsotg->periodic_sched_inactive.next;
while (qh_entry != &hsotg->periodic_sched_inactive) {
qh = list_entry(qh_entry, struct dwc2_qh, qh_list_entry);
qh_entry = qh_entry->next;
if (dwc2_frame_num_le(qh->next_active_frame,
hsotg->frame_number)) {
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/spinlock.h`, `linux/interrupt.h`, `linux/dma-mapping.h`, `linux/io.h`, `linux/slab.h`, `linux/usb.h`.
- Detected declarations: `function Copyright`, `function dwc2_hc_handle_tt_clear`, `function next`, `function dwc2_rx_fifo_level_intr`, `function dwc2_np_tx_fifo_empty_intr`, `function dwc2_perio_tx_fifo_empty_intr`, `function dwc2_hprt0_enable`, `function dwc2_port_intr`, `function dwc2_get_actual_xfer_length`, `function dwc2_update_urb_state`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.