drivers/usb/serial/quatech2.c
Source file repositories/reference/linux-study-clean/drivers/usb/serial/quatech2.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/serial/quatech2.c- Extension
.c- Size
- 24109 bytes
- Lines
- 958
- 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/unaligned.hlinux/errno.hlinux/slab.hlinux/tty.hlinux/tty_driver.hlinux/tty_flip.hlinux/module.hlinux/serial.hlinux/usb.hlinux/usb/serial.hlinux/serial_reg.hlinux/uaccess.h
Detected Declarations
struct qt2_device_detailstruct qt2_serial_privatestruct qt2_port_privatefunction qt2_releasefunction calc_baud_divisorfunction qt2_set_port_configfunction qt2_control_msgfunction qt2_getregisterfunction qt2_setregisterfunction update_mctrlfunction qt2_calc_num_portsfunction qt2_set_termiosfunction qt2_openfunction qt2_closefunction qt2_disconnectfunction qt2_process_statusfunction qt2_process_read_urbfunction qt2_write_bulk_callbackfunction qt2_read_bulk_callbackfunction qt2_setup_urbsfunction qt2_attachfunction qt2_port_probefunction qt2_port_removefunction qt2_tiocmgetfunction qt2_tiocmsetfunction qt2_break_ctlfunction qt2_dtr_rtsfunction qt2_update_msrfunction qt2_update_lsrfunction qt2_write_roomfunction qt2_write
Annotated Snippet
struct qt2_device_detail {
int product_id;
int num_ports;
};
#define QT_DETAILS(prod, ports) \
.product_id = (prod), \
.num_ports = (ports)
static const struct qt2_device_detail qt2_device_details[] = {
{QT_DETAILS(QUATECH_SSU2_100, 1)},
{QT_DETAILS(QUATECH_DSU2_400, 2)},
{QT_DETAILS(QUATECH_DSU2_100, 2)},
{QT_DETAILS(QUATECH_QSU2_400, 4)},
{QT_DETAILS(QUATECH_QSU2_100, 4)},
{QT_DETAILS(QUATECH_ESU2_400, 8)},
{QT_DETAILS(QUATECH_ESU2_100, 8)},
{QT_DETAILS(0, 0)} /* Terminating entry */
};
static const struct usb_device_id id_table[] = {
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_400)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_100)},
{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_400)},
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
struct qt2_serial_private {
unsigned char current_port; /* current port for incoming data */
struct urb *read_urb; /* shared among all ports */
char *read_buffer;
};
struct qt2_port_private {
u8 device_port;
spinlock_t urb_lock;
bool urb_in_use;
struct urb *write_urb;
char *write_buffer;
spinlock_t lock;
u8 shadowLSR;
u8 shadowMSR;
struct usb_serial_port *port;
};
static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch);
static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch);
static void qt2_write_bulk_callback(struct urb *urb);
static void qt2_read_bulk_callback(struct urb *urb);
static void qt2_release(struct usb_serial *serial)
{
struct qt2_serial_private *serial_priv;
serial_priv = usb_get_serial_data(serial);
usb_kill_urb(serial_priv->read_urb);
usb_free_urb(serial_priv->read_urb);
kfree(serial_priv->read_buffer);
kfree(serial_priv);
}
static inline int calc_baud_divisor(int baudrate)
{
int divisor, rem;
divisor = MAX_BAUD_RATE / baudrate;
rem = MAX_BAUD_RATE % baudrate;
/* Round to nearest divisor */
if (((rem * 2) >= baudrate) && (baudrate != 110))
divisor++;
return divisor;
}
static inline int qt2_set_port_config(struct usb_device *dev,
unsigned char port_number,
u16 baudrate, u16 lcr)
{
int divisor = calc_baud_divisor(baudrate);
u16 index = ((u16) (lcr << 8) | (u16) (port_number));
Annotation
- Immediate include surface: `linux/unaligned.h`, `linux/errno.h`, `linux/slab.h`, `linux/tty.h`, `linux/tty_driver.h`, `linux/tty_flip.h`, `linux/module.h`, `linux/serial.h`.
- Detected declarations: `struct qt2_device_detail`, `struct qt2_serial_private`, `struct qt2_port_private`, `function qt2_release`, `function calc_baud_divisor`, `function qt2_set_port_config`, `function qt2_control_msg`, `function qt2_getregister`, `function qt2_setregister`, `function update_mctrl`.
- 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.