drivers/usb/usbip/stub_tx.c
Source file repositories/reference/linux-study-clean/drivers/usb/usbip/stub_tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/usbip/stub_tx.c- Extension
.c- Size
- 11634 bytes
- Lines
- 451
- 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.
- 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/kthread.hlinux/minmax.hlinux/socket.hlinux/scatterlist.husbip_common.hstub.h
Detected Declarations
function Copyrightfunction stub_completefunction setup_base_pdufunction setup_ret_submit_pdufunction setup_ret_unlink_pdufunction list_for_each_entry_safefunction stub_send_ret_submitfunction usb_pipetypefunction for_each_sgfunction usb_pipetypefunction list_for_each_entry_safefunction stub_send_ret_unlinkfunction list_for_each_entry_safefunction stub_tx_loop
Annotated Snippet
if (!iov) {
usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC);
return -1;
}
iovnum = 0;
/* 1. setup usbip_header */
setup_ret_submit_pdu(&pdu_header, urb);
usbip_dbg_stub_tx("setup txdata seqnum: %u\n",
pdu_header.base.seqnum);
if (priv->sgl) {
for (i = 0; i < priv->num_urbs; i++)
actual_length += priv->urbs[i]->actual_length;
pdu_header.u.ret_submit.status = priv->urb_status;
pdu_header.u.ret_submit.actual_length = actual_length;
}
usbip_header_correct_endian(&pdu_header, 1);
iov[iovnum].iov_base = &pdu_header;
iov[iovnum].iov_len = sizeof(pdu_header);
iovnum++;
txsize += sizeof(pdu_header);
/* 2. setup transfer buffer */
if (usb_pipein(urb->pipe) && priv->sgl) {
/* If the server split a single SG request into several
* URBs because the server's HCD doesn't support SG,
* reassemble the split URB buffers into a single
* return command.
*/
for (i = 0; i < priv->num_urbs; i++) {
iov[iovnum].iov_base =
priv->urbs[i]->transfer_buffer;
iov[iovnum].iov_len =
priv->urbs[i]->actual_length;
iovnum++;
}
txsize += actual_length;
} else if (usb_pipein(urb->pipe) &&
usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS &&
urb->actual_length > 0) {
if (urb->num_sgs) {
unsigned int copy = urb->actual_length;
unsigned int size;
for_each_sg(urb->sg, sg, urb->num_sgs, i) {
if (copy == 0)
break;
size = min(copy, sg->length);
iov[iovnum].iov_base = sg_virt(sg);
iov[iovnum].iov_len = size;
iovnum++;
copy -= size;
}
} else {
iov[iovnum].iov_base = urb->transfer_buffer;
iov[iovnum].iov_len = urb->actual_length;
iovnum++;
}
txsize += urb->actual_length;
} else if (usb_pipein(urb->pipe) &&
usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
/*
* For isochronous packets: actual length is the sum of
* the actual length of the individual, packets, but as
* the packet offsets are not changed there will be
* padding between the packets. To optimally use the
* bandwidth the padding is not transmitted.
*/
int i;
for (i = 0; i < urb->number_of_packets; i++) {
iov[iovnum].iov_base = urb->transfer_buffer +
urb->iso_frame_desc[i].offset;
iov[iovnum].iov_len =
urb->iso_frame_desc[i].actual_length;
iovnum++;
txsize += urb->iso_frame_desc[i].actual_length;
}
if (txsize != sizeof(pdu_header) + urb->actual_length) {
dev_err(&sdev->udev->dev,
"actual length of urb %d does not match iso packet sizes %zu\n",
Annotation
- Immediate include surface: `linux/kthread.h`, `linux/minmax.h`, `linux/socket.h`, `linux/scatterlist.h`, `usbip_common.h`, `stub.h`.
- Detected declarations: `function Copyright`, `function stub_complete`, `function setup_base_pdu`, `function setup_ret_submit_pdu`, `function setup_ret_unlink_pdu`, `function list_for_each_entry_safe`, `function stub_send_ret_submit`, `function usb_pipetype`, `function for_each_sg`, `function usb_pipetype`.
- 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.