drivers/usb/class/usbtmc.c
Source file repositories/reference/linux-study-clean/drivers/usb/class/usbtmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/class/usbtmc.c- Extension
.c- Size
- 63199 bytes
- Lines
- 2626
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/module.hlinux/kernel.hlinux/fs.hlinux/uaccess.hlinux/kref.hlinux/slab.hlinux/poll.hlinux/mutex.hlinux/usb.hlinux/compat.hlinux/usb/tmc.h
Detected Declarations
struct usbtmc_dev_capabilitiesstruct usbtmc_device_datastruct usbtmc_file_datafunction usbtmc_deletefunction usbtmc_openfunction usbtmc_flushfunction usbtmc_releasefunction usbtmc_ioctl_abort_bulk_in_tagfunction usbtmc_ioctl_abort_bulk_infunction usbtmc_ioctl_abort_bulk_out_tagfunction usbtmc_ioctl_abort_bulk_outfunction usbtmc_get_stbfunction usbtmc488_ioctl_read_stbfunction usbtmc_ioctl_get_srq_stbfunction usbtmc488_ioctl_wait_srqfunction usbtmc488_ioctl_simplefunction usbtmc488_ioctl_triggerfunction usbtmc_read_bulk_cbfunction usbtmc_do_transferfunction usbtmc_generic_readfunction usbtmc_ioctl_generic_readfunction usbtmc_write_bulk_cbfunction usbtmc_generic_writefunction usbtmc_ioctl_generic_writefunction usbtmc_ioctl_write_resultfunction send_request_dev_dep_msg_infunction usbtmc_readfunction usbtmc_writefunction usbtmc_ioctl_clearfunction usbtmc_ioctl_clear_out_haltfunction usbtmc_ioctl_clear_in_haltfunction usbtmc_ioctl_cancel_iofunction usbtmc_ioctl_cleanup_iofunction get_capabilitiesfunction usbtmc_ioctl_indicator_pulsefunction usbtmc_ioctl_requestfunction usbtmc_ioctl_get_timeoutfunction usbtmc_ioctl_set_timeoutfunction usbtmc_ioctl_eom_enablefunction readfunction usbtmc_ioctlfunction usbtmc_fasyncfunction usbtmc_pollfunction usbtmc_interruptfunction list_for_eachfunction usbtmc_free_intfunction usbtmc_probefunction usbtmc_disconnect
Annotated Snippet
static const struct file_operations fops = {
.owner = THIS_MODULE,
.read = usbtmc_read,
.write = usbtmc_write,
.open = usbtmc_open,
.release = usbtmc_release,
.flush = usbtmc_flush,
.unlocked_ioctl = usbtmc_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.fasync = usbtmc_fasync,
.poll = usbtmc_poll,
.llseek = default_llseek,
};
static struct usb_class_driver usbtmc_class = {
.name = "usbtmc%d",
.fops = &fops,
.minor_base = USBTMC_MINOR_BASE,
};
static void usbtmc_interrupt(struct urb *urb)
{
struct usbtmc_device_data *data = urb->context;
struct device *dev = &data->intf->dev;
int status = urb->status;
int rv;
dev_dbg(&data->intf->dev, "int status: %d len %d\n",
status, urb->actual_length);
switch (status) {
case 0: /* SUCCESS */
/* ensure at least two bytes of headers were transferred */
if (urb->actual_length < 2) {
dev_warn(dev,
"actual length %d not sufficient for interrupt headers\n",
urb->actual_length);
goto exit;
}
/* check for valid STB notification */
if (data->iin_buffer[0] > 0x81) {
data->bNotify1 = data->iin_buffer[0];
data->bNotify2 = data->iin_buffer[1];
atomic_set(&data->iin_data_valid, 1);
wake_up_interruptible(&data->waitq);
goto exit;
}
/* check for SRQ notification */
if (data->iin_buffer[0] == 0x81) {
unsigned long flags;
struct list_head *elem;
if (data->fasync)
kill_fasync(&data->fasync,
SIGIO, POLL_PRI);
spin_lock_irqsave(&data->dev_lock, flags);
list_for_each(elem, &data->file_list) {
struct usbtmc_file_data *file_data;
file_data = list_entry(elem,
struct usbtmc_file_data,
file_elem);
file_data->srq_byte = data->iin_buffer[1];
atomic_set(&file_data->srq_asserted, 1);
}
spin_unlock_irqrestore(&data->dev_lock, flags);
dev_dbg(dev, "srq received bTag %x stb %x\n",
(unsigned int)data->iin_buffer[0],
(unsigned int)data->iin_buffer[1]);
wake_up_interruptible_all(&data->waitq);
goto exit;
}
dev_warn(dev, "invalid notification: %x\n",
data->iin_buffer[0]);
break;
case -EOVERFLOW:
dev_err(dev, "overflow with length %d, actual length is %d\n",
data->iin_wMaxPacketSize, urb->actual_length);
fallthrough;
default:
/* urb terminated, clean up */
dev_dbg(dev, "urb terminated, status: %d\n", status);
return;
}
exit:
rv = usb_submit_urb(urb, GFP_ATOMIC);
if (rv)
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/fs.h`, `linux/uaccess.h`, `linux/kref.h`, `linux/slab.h`, `linux/poll.h`, `linux/mutex.h`.
- Detected declarations: `struct usbtmc_dev_capabilities`, `struct usbtmc_device_data`, `struct usbtmc_file_data`, `function usbtmc_delete`, `function usbtmc_open`, `function usbtmc_flush`, `function usbtmc_release`, `function usbtmc_ioctl_abort_bulk_in_tag`, `function usbtmc_ioctl_abort_bulk_in`, `function usbtmc_ioctl_abort_bulk_out_tag`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.