drivers/usb/host/ehci-hub.c
Source file repositories/reference/linux-study-clean/drivers/usb/host/ehci-hub.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/host/ehci-hub.c- Extension
.c- Size
- 34021 bytes
- Lines
- 1223
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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
- No C-style include directives detected by the generator.
Detected Declarations
function persist_enabled_on_companionfunction ehci_handover_companion_portsfunction ehci_port_changefunction ehci_adjust_port_wakeup_flagsfunction ehci_bus_suspendfunction ehci_bus_resumefunction ehci_get_resuming_portsfunction set_ownerfunction check_reset_completefunction ehci_hub_status_datafunction ehci_hub_descriptorfunction ehci_hub_controlfunction valuesfunction resetfunction ehci_relinquish_portfunction ehci_port_handed_overfunction ehci_port_powerexport ehci_adjust_port_wakeup_flagsexport ehci_hub_control
Annotated Snippet
if (test_bit(port, &ehci->owned_ports)) {
reg = &ehci->regs->port_status[port];
status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
if (!(status & PORT_POWER))
ehci_port_power(ehci, port, true);
}
}
/* Give the connections some time to appear */
msleep(20);
spin_lock_irq(&ehci->lock);
port = HCS_N_PORTS(ehci->hcs_params);
while (port--) {
if (test_bit(port, &ehci->owned_ports)) {
reg = &ehci->regs->port_status[port];
status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
/* Port already owned by companion? */
if (status & PORT_OWNER)
clear_bit(port, &ehci->owned_ports);
else if (test_bit(port, &ehci->companion_ports))
ehci_writel(ehci, status & ~PORT_PE, reg);
else {
spin_unlock_irq(&ehci->lock);
ehci_hub_control(hcd, SetPortFeature,
USB_PORT_FEAT_RESET, port + 1,
NULL, 0);
spin_lock_irq(&ehci->lock);
}
}
}
spin_unlock_irq(&ehci->lock);
if (!ehci->owned_ports)
return;
msleep(90); /* Wait for resets to complete */
spin_lock_irq(&ehci->lock);
port = HCS_N_PORTS(ehci->hcs_params);
while (port--) {
if (test_bit(port, &ehci->owned_ports)) {
spin_unlock_irq(&ehci->lock);
ehci_hub_control(hcd, GetPortStatus,
0, port + 1,
(char *) &buf, sizeof(buf));
spin_lock_irq(&ehci->lock);
/* The companion should now own the port,
* but if something went wrong the port must not
* remain enabled.
*/
reg = &ehci->regs->port_status[port];
status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
if (status & PORT_OWNER)
ehci_writel(ehci, status | PORT_CSC, reg);
else {
ehci_dbg(ehci, "failed handover port %d: %x\n",
port + 1, status);
ehci_writel(ehci, status & ~PORT_PE, reg);
}
}
}
ehci->owned_ports = 0;
spin_unlock_irq(&ehci->lock);
}
static int ehci_port_change(struct ehci_hcd *ehci)
{
int i = HCS_N_PORTS(ehci->hcs_params);
/* First check if the controller indicates a change event */
if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)
return 1;
/*
* Not all controllers appear to update this while going from D3 to D0,
* so check the individual port status registers as well
*/
while (i--)
if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC)
return 1;
return 0;
}
void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
Annotation
- Detected declarations: `function persist_enabled_on_companion`, `function ehci_handover_companion_ports`, `function ehci_port_change`, `function ehci_adjust_port_wakeup_flags`, `function ehci_bus_suspend`, `function ehci_bus_resume`, `function ehci_get_resuming_ports`, `function set_owner`, `function check_reset_complete`, `function ehci_hub_status_data`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: integration 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.