drivers/usb/host/sl811-hcd.c
Source file repositories/reference/linux-study-clean/drivers/usb/host/sl811-hcd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/host/sl811-hcd.c- Extension
.c- Size
- 46569 bytes
- Lines
- 1800
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/moduleparam.hlinux/kernel.hlinux/delay.hlinux/ioport.hlinux/sched.hlinux/slab.hlinux/errno.hlinux/timer.hlinux/list.hlinux/interrupt.hlinux/usb.hlinux/usb/sl811.hlinux/usb/hcd.hlinux/platform_device.hlinux/prefetch.hlinux/string_choices.hlinux/debugfs.hlinux/seq_file.hasm/io.hasm/irq.hasm/byteorder.hlinux/unaligned.hsl811.h
Detected Declarations
function port_powerfunction setup_packetfunction status_packetfunction in_packetfunction out_packetfunction sofirq_onfunction sofirq_offfunction transfersfunction start_transferfunction finish_requestfunction donefunction checkdonefunction sl811h_irqfunction balancefunction sl811h_urb_enqueuefunction sl811h_urb_dequeuefunction sl811h_endpoint_disablefunction sl811h_get_framefunction sl811h_hub_status_datafunction sl811h_hub_descriptorfunction sl811h_timerfunction sl811h_hub_controlfunction sl811h_bus_suspendfunction sl811h_bus_resumefunction dump_irqfunction sl811h_debug_showfunction list_for_each_entryfunction create_debug_filefunction remove_debug_filefunction sl811h_stopfunction sl811h_startfunction sl811h_removefunction sl811h_probefunction sl811h_suspendfunction sl811h_resumeexport sl811h_driver
Annotated Snippet
if (control & SL11H_HCTLMASK_PREAMBLE) {
/* also note erratum 1: some hubs won't work */
fclock -= 800;
}
fclock -= ep->maxpacket << 8;
/* erratum 2: AFTERSOF only works for fullspeed */
if (fclock < 0) {
if (ep->period)
sl811->stat_overrun++;
sofirq_on(sl811);
return NULL;
}
} else {
fclock -= 12000 / 19; /* 19 64byte packets/msec */
if (fclock < 0) {
if (ep->period)
sl811->stat_overrun++;
control |= SL11H_HCTLMASK_AFTERSOF;
/* throttle bulk/control irq noise */
} else if (ep->nak_count)
control |= SL11H_HCTLMASK_AFTERSOF;
}
switch (ep->nextpid) {
case USB_PID_IN:
in_packet(sl811, ep, urb, bank, control);
break;
case USB_PID_OUT:
out_packet(sl811, ep, urb, bank, control);
break;
case USB_PID_SETUP:
setup_packet(sl811, ep, urb, bank, control);
break;
case USB_PID_ACK: /* for control status */
status_packet(sl811, ep, urb, bank, control);
break;
default:
dev_dbg(sl811_to_hcd(sl811)->self.controller,
"bad ep%p pid %02x\n", ep, ep->nextpid);
ep = NULL;
}
return ep;
}
#define MIN_JIFFIES ((msecs_to_jiffies(2) > 1) ? msecs_to_jiffies(2) : 2)
static inline void start_transfer(struct sl811 *sl811)
{
if (sl811->port1 & USB_PORT_STAT_SUSPEND)
return;
if (sl811->active_a == NULL) {
sl811->active_a = start(sl811, SL811_EP_A(SL811_HOST_BUF));
if (sl811->active_a != NULL)
sl811->jiffies_a = jiffies + MIN_JIFFIES;
}
#ifdef USE_B
if (sl811->active_b == NULL) {
sl811->active_b = start(sl811, SL811_EP_B(SL811_HOST_BUF));
if (sl811->active_b != NULL)
sl811->jiffies_b = jiffies + MIN_JIFFIES;
}
#endif
}
static void finish_request(
struct sl811 *sl811,
struct sl811h_ep *ep,
struct urb *urb,
int status
) __releases(sl811->lock) __acquires(sl811->lock)
{
unsigned i;
if (usb_pipecontrol(urb->pipe))
ep->nextpid = USB_PID_SETUP;
usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb);
spin_unlock(&sl811->lock);
usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, status);
spin_lock(&sl811->lock);
/* leave active endpoints in the schedule */
if (!list_empty(&ep->hep->urb_list))
return;
/* async deschedule? */
if (!list_empty(&ep->schedule)) {
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/kernel.h`, `linux/delay.h`, `linux/ioport.h`, `linux/sched.h`, `linux/slab.h`, `linux/errno.h`.
- Detected declarations: `function port_power`, `function setup_packet`, `function status_packet`, `function in_packet`, `function out_packet`, `function sofirq_on`, `function sofirq_off`, `function transfers`, `function start_transfer`, `function finish_request`.
- 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.
- 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.