drivers/usb/host/isp116x-hcd.c
Source file repositories/reference/linux-study-clean/drivers/usb/host/isp116x-hcd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/host/isp116x-hcd.c- Extension
.c- Size
- 44022 bytes
- Lines
- 1696
- 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.
- 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/delay.hlinux/debugfs.hlinux/seq_file.hlinux/errno.hlinux/list.hlinux/slab.hlinux/usb.hlinux/usb/isp116x.hlinux/usb/hcd.hlinux/platform_device.hasm/io.hasm/irq.hasm/byteorder.hisp116x.h
Detected Declarations
function write_ptddata_to_fifofunction read_ptddata_from_fifofunction pack_fifofunction unpack_fifofunction preproc_atl_queuefunction finish_requestfunction postproc_atl_queuefunction start_atl_transfersfunction finish_atl_transfersfunction isp116x_irqfunction balancefunction isp116x_urb_enqueuefunction isp116x_urb_dequeuefunction isp116x_endpoint_disablefunction isp116x_get_framefunction isp116x_hub_status_datafunction isp116x_hub_descriptorfunction root_port_resetfunction isp116x_hub_controlfunction dump_irqfunction dump_intfunction isp116x_debug_showfunction create_debug_filefunction remove_debug_filefunction create_debug_filefunction isp116x_resetfunction isp116x_stopfunction isp116x_startfunction isp116x_bus_suspendfunction isp116x_bus_resumefunction isp116x_removefunction isp116x_probefunction isp116x_suspendfunction isp116x_resume
Annotated Snippet
if (ep->active || (isp116x->atl_last_dir != PTD_DIR_IN)) {
write_ptddata_to_fifo(isp116x, ep->data, ep->length);
buflen -= ALIGN(ep->length, 4);
}
}
BUG_ON(buflen);
}
/*
Read the processed ptd's and data from fifo ram back to
URBs' buffers. Fifo must be full and done
*/
static void unpack_fifo(struct isp116x *isp116x)
{
struct isp116x_ep *ep;
struct ptd *ptd;
int buflen = isp116x->atl_last_dir == PTD_DIR_IN
? isp116x->atl_buflen : isp116x->atl_bufshrt;
isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
isp116x_write_addr(isp116x, HCATLPORT);
for (ep = isp116x->atl_active; ep; ep = ep->active) {
ptd = &ep->ptd;
ptd->count = isp116x_read_data16(isp116x);
ptd->mps = isp116x_read_data16(isp116x);
ptd->len = isp116x_read_data16(isp116x);
ptd->faddr = isp116x_read_data16(isp116x);
buflen -= sizeof(struct ptd);
/* Skip reading data for last Setup or Out PTD */
if (ep->active || (isp116x->atl_last_dir == PTD_DIR_IN)) {
read_ptddata_from_fifo(isp116x, ep->data, ep->length);
buflen -= ALIGN(ep->length, 4);
}
dump_ptd(ptd);
dump_ptd_in_data(ptd, ep->data);
}
BUG_ON(buflen);
}
/*---------------------------------------------------------------*/
/*
Set up PTD's.
*/
static void preproc_atl_queue(struct isp116x *isp116x)
{
struct isp116x_ep *ep;
struct urb *urb;
struct ptd *ptd;
u16 len;
for (ep = isp116x->atl_active; ep; ep = ep->active) {
u16 toggle = 0, dir = PTD_DIR_SETUP;
BUG_ON(list_empty(&ep->hep->urb_list));
urb = container_of(ep->hep->urb_list.next,
struct urb, urb_list);
ptd = &ep->ptd;
len = ep->length;
ep->data = (unsigned char *)urb->transfer_buffer
+ urb->actual_length;
switch (ep->nextpid) {
case USB_PID_IN:
toggle = usb_gettoggle(urb->dev, ep->epnum, 0);
dir = PTD_DIR_IN;
break;
case USB_PID_OUT:
toggle = usb_gettoggle(urb->dev, ep->epnum, 1);
dir = PTD_DIR_OUT;
break;
case USB_PID_SETUP:
len = sizeof(struct usb_ctrlrequest);
ep->data = urb->setup_packet;
break;
case USB_PID_ACK:
toggle = 1;
len = 0;
dir = (urb->transfer_buffer_length
&& usb_pipein(urb->pipe))
? PTD_DIR_OUT : PTD_DIR_IN;
break;
default:
ERR("%s %d: ep->nextpid %d\n", __func__, __LINE__,
ep->nextpid);
BUG();
}
ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle);
Annotation
- Immediate include surface: `linux/module.h`, `linux/delay.h`, `linux/debugfs.h`, `linux/seq_file.h`, `linux/errno.h`, `linux/list.h`, `linux/slab.h`, `linux/usb.h`.
- Detected declarations: `function write_ptddata_to_fifo`, `function read_ptddata_from_fifo`, `function pack_fifo`, `function unpack_fifo`, `function preproc_atl_queue`, `function finish_request`, `function postproc_atl_queue`, `function start_atl_transfers`, `function finish_atl_transfers`, `function isp116x_irq`.
- 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.