drivers/usb/host/ohci-q.c
Source file repositories/reference/linux-study-clean/drivers/usb/host/ohci-q.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/host/ohci-q.c- Extension
.c- Size
- 34363 bytes
- Lines
- 1236
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/irq.hlinux/slab.h
Detected Declarations
function HCDfunction finish_urbfunction balancefunction periodic_linkfunction ed_schedulefunction linkedfunction periodic_unlinkfunction finish_unlinksfunction queuesfunction framefunction td_fillfunction td_submit_urbfunction td_donefunction ed_haltedfunction add_to_done_listfunction update_done_listfunction finish_unlinksfunction list_for_each_safefunction takeback_tdfunction completionsfunction ohci_work
Annotated Snippet
if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
if (quirk_amdiso(ohci))
usb_amd_quirk_pll_enable();
if (quirk_amdprefetch(ohci))
sb800_prefetch(dev, 0);
}
break;
case PIPE_INTERRUPT:
ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
break;
}
/* urb->complete() can reenter this HCD */
usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb);
spin_unlock (&ohci->lock);
usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status);
spin_lock (&ohci->lock);
/* stop periodic dma if it's not needed */
if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
&& ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0) {
ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE);
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
}
/*
* An isochronous URB that is sumitted too late won't have any TDs
* (marked by the fact that the td_cnt value is larger than the
* actual number of TDs). If the next URB on this endpoint is like
* that, give it back now.
*/
if (!list_empty(&ep->urb_list)) {
urb = list_first_entry(&ep->urb_list, struct urb, urb_list);
urb_priv = urb->hcpriv;
if (urb_priv->td_cnt > urb_priv->length) {
status = 0;
goto restart;
}
}
}
/*-------------------------------------------------------------------------*
* ED handling functions
*-------------------------------------------------------------------------*/
/* search for the right schedule branch to use for a periodic ed.
* does some load balancing; returns the branch, or negative errno.
*/
static int balance (struct ohci_hcd *ohci, int interval, int load)
{
int i, branch = -ENOSPC;
/* iso periods can be huge; iso tds specify frame numbers */
if (interval > NUM_INTS)
interval = NUM_INTS;
/* search for the least loaded schedule branch of that period
* that has enough bandwidth left unreserved.
*/
for (i = 0; i < interval ; i++) {
if (branch < 0 || ohci->load [branch] > ohci->load [i]) {
int j;
/* usb 1.1 says 90% of one frame */
for (j = i; j < NUM_INTS; j += interval) {
if ((ohci->load [j] + load) > 900)
break;
}
if (j < NUM_INTS)
continue;
branch = i;
}
}
return branch;
}
/*-------------------------------------------------------------------------*/
/* both iso and interrupt requests have periods; this routine puts them
* into the schedule tree in the apppropriate place. most iso devices use
* 1msec periods, but that's not required.
*/
static void periodic_link (struct ohci_hcd *ohci, struct ed *ed)
{
unsigned i;
ohci_dbg(ohci, "link %sed %p branch %d [%dus.], interval %d\n",
(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
ed, ed->branch, ed->load, ed->interval);
Annotation
- Immediate include surface: `linux/irq.h`, `linux/slab.h`.
- Detected declarations: `function HCD`, `function finish_urb`, `function balance`, `function periodic_link`, `function ed_schedule`, `function linked`, `function periodic_unlink`, `function finish_unlinks`, `function queues`, `function frame`.
- 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.
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.