drivers/usb/serial/generic.c
Source file repositories/reference/linux-study-clean/drivers/usb/serial/generic.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/serial/generic.c- Extension
.c- Size
- 16696 bytes
- Lines
- 658
- 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
linux/kernel.hlinux/sched/signal.hlinux/errno.hlinux/slab.hlinux/sysrq.hlinux/tty.hlinux/tty_flip.hlinux/module.hlinux/moduleparam.hlinux/usb.hlinux/usb/serial.hlinux/uaccess.hlinux/kfifo.hlinux/serial.h
Detected Declarations
function usb_serial_generic_probefunction usb_serial_generic_calc_num_portsfunction usb_serial_generic_registerfunction usb_serial_generic_deregisterfunction usb_serial_generic_openfunction usb_serial_generic_closefunction usb_serial_generic_prepare_write_bufferfunction usb_serial_generic_write_startfunction usb_serial_generic_writefunction usb_serial_generic_write_roomfunction usb_serial_generic_chars_in_bufferfunction usb_serial_generic_wait_until_sentfunction usb_serial_generic_submit_read_urbfunction usb_serial_generic_submit_read_urbsfunction usb_serial_generic_process_read_urbfunction usb_serial_generic_read_bulk_callbackfunction usb_serial_generic_write_bulk_callbackfunction usb_serial_generic_throttlefunction usb_serial_generic_unthrottlefunction usb_serial_generic_msr_changedfunction usb_serial_generic_tiocmiwaitfunction usb_serial_generic_get_icountfunction usb_serial_handle_sysrq_charfunction usb_serial_handle_breakfunction usb_serial_handle_dcd_changefunction usb_serial_generic_resumeexport usb_serial_generic_openexport usb_serial_generic_closeexport usb_serial_generic_write_startexport usb_serial_generic_writeexport usb_serial_generic_chars_in_bufferexport usb_serial_generic_wait_until_sentexport usb_serial_generic_submit_read_urbsexport usb_serial_generic_process_read_urbexport usb_serial_generic_read_bulk_callbackexport usb_serial_generic_write_bulk_callbackexport usb_serial_generic_throttleexport usb_serial_generic_unthrottleexport usb_serial_generic_tiocmiwaitexport usb_serial_generic_get_icountexport usb_serial_handle_sysrq_charexport usb_serial_handle_breakexport usb_serial_handle_dcd_changeexport usb_serial_generic_resume
Annotated Snippet
if (res != -EPERM && res != -ENODEV) {
dev_err(&port->dev,
"%s - usb_submit_urb failed: %d\n",
__func__, res);
}
set_bit(index, &port->read_urbs_free);
return res;
}
return 0;
}
int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port,
gfp_t mem_flags)
{
int res;
int i;
for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
res = usb_serial_generic_submit_read_urb(port, i, mem_flags);
if (res)
goto err;
}
return 0;
err:
for (; i >= 0; --i)
usb_kill_urb(port->read_urbs[i]);
return res;
}
EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs);
void usb_serial_generic_process_read_urb(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
char *ch = urb->transfer_buffer;
int i;
if (!urb->actual_length)
return;
/*
* The per character mucking around with sysrq path it too slow for
* stuff like 3G modems, so shortcircuit it in the 99.9999999% of
* cases where the USB serial is not a console anyway.
*/
if (port->sysrq) {
for (i = 0; i < urb->actual_length; i++, ch++) {
if (!usb_serial_handle_sysrq_char(port, *ch))
tty_insert_flip_char(&port->port, *ch, TTY_NORMAL);
}
} else {
tty_insert_flip_string(&port->port, ch, urb->actual_length);
}
tty_flip_buffer_push(&port->port);
}
EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb);
void usb_serial_generic_read_bulk_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
bool stopped = false;
int status = urb->status;
int i;
for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
if (urb == port->read_urbs[i])
break;
}
dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
urb->actual_length);
switch (status) {
case 0:
usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
data);
port->serial->type->process_read_urb(urb);
break;
case -ENOENT:
case -ECONNRESET:
case -ESHUTDOWN:
dev_dbg(&port->dev, "%s - urb stopped: %d\n",
__func__, status);
stopped = true;
break;
case -EPIPE:
dev_err(&port->dev, "%s - urb stopped: %d\n",
__func__, status);
stopped = true;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/sched/signal.h`, `linux/errno.h`, `linux/slab.h`, `linux/sysrq.h`, `linux/tty.h`, `linux/tty_flip.h`, `linux/module.h`.
- Detected declarations: `function usb_serial_generic_probe`, `function usb_serial_generic_calc_num_ports`, `function usb_serial_generic_register`, `function usb_serial_generic_deregister`, `function usb_serial_generic_open`, `function usb_serial_generic_close`, `function usb_serial_generic_prepare_write_buffer`, `function usb_serial_generic_write_start`, `function usb_serial_generic_write`, `function usb_serial_generic_write_room`.
- 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.