drivers/usb/class/usblp.c
Source file repositories/reference/linux-study-clean/drivers/usb/class/usblp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/class/usblp.c- Extension
.c- Size
- 40503 bytes
- Lines
- 1489
- 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/minmax.hlinux/sched/signal.hlinux/signal.hlinux/poll.hlinux/slab.hlinux/lp.hlinux/mutex.hlinux/usb.hlinux/usb/ch9.hlinux/ratelimit.h
Detected Declarations
struct usblpstruct quirk_printer_structfunction usblp_dumpfunction usblp_ctrl_msgfunction usblp_hp_channel_change_requestfunction usblp_bulk_readfunction usblp_bulk_writefunction usblp_check_statusfunction handle_bidirfunction usblp_openfunction usblp_cleanupfunction usblp_unlink_urbsfunction usblp_releasefunction usblp_pollfunction usblp_ioctlfunction usblp_writefunction usblp_readfunction copy_to_userfunction selectfunction usblp_wtestfunction usblp_r_lock_and_waitfunction usblp_rtestfunction usblp_submit_readfunction flawfunction ieee1284_id_showfunction usblp_probefunction printersfunction usblp_set_protocolfunction usblp_cache_device_id_stringfunction usblp_disconnectfunction usblp_suspendfunction usblp_resume
Annotated Snippet
static const struct file_operations usblp_fops = {
.owner = THIS_MODULE,
.read = usblp_read,
.write = usblp_write,
.poll = usblp_poll,
.unlocked_ioctl = usblp_ioctl,
.compat_ioctl = usblp_ioctl,
.open = usblp_open,
.release = usblp_release,
.llseek = noop_llseek,
};
static char *usblp_devnode(const struct device *dev, umode_t *mode)
{
return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
}
static struct usb_class_driver usblp_class = {
.name = "lp%d",
.devnode = usblp_devnode,
.fops = &usblp_fops,
.minor_base = USBLP_MINOR_BASE,
};
static ssize_t ieee1284_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf = to_usb_interface(dev);
struct usblp *usblp = usb_get_intfdata(intf);
if (usblp->device_id_string[0] == 0 &&
usblp->device_id_string[1] == 0)
return 0;
return sprintf(buf, "%s", usblp->device_id_string+2);
}
static DEVICE_ATTR_RO(ieee1284_id);
static struct attribute *usblp_attrs[] = {
&dev_attr_ieee1284_id.attr,
NULL,
};
ATTRIBUTE_GROUPS(usblp);
static int usblp_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev(intf);
struct usblp *usblp;
int protocol;
int retval;
/* Malloc and start initializing usblp structure so we can use it
* directly. */
usblp = kzalloc_obj(struct usblp);
if (!usblp) {
retval = -ENOMEM;
goto abort_ret;
}
usblp->dev = dev;
mutex_init(&usblp->wmut);
mutex_init(&usblp->mut);
spin_lock_init(&usblp->lock);
init_waitqueue_head(&usblp->rwait);
init_waitqueue_head(&usblp->wwait);
init_usb_anchor(&usblp->urbs);
usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
usblp->intf = usb_get_intf(intf);
/* Malloc device ID string buffer to the largest expected length,
* since we can re-query it on an ioctl and a dynamic string
* could change in length. */
usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL);
if (!usblp->device_id_string) {
retval = -ENOMEM;
goto abort;
}
/*
* Allocate read buffer. We somewhat wastefully
* malloc both regardless of bidirectionality, because the
* alternate setting can be changed later via an ioctl.
*/
usblp->readbuf = kmalloc(USBLP_BUF_SIZE_IN, GFP_KERNEL);
if (!usblp->readbuf) {
retval = -ENOMEM;
goto abort;
}
/* Allocate buffer for printer status */
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/minmax.h`, `linux/sched/signal.h`, `linux/signal.h`, `linux/poll.h`, `linux/slab.h`, `linux/lp.h`.
- Detected declarations: `struct usblp`, `struct quirk_printer_struct`, `function usblp_dump`, `function usblp_ctrl_msg`, `function usblp_hp_channel_change_request`, `function usblp_bulk_read`, `function usblp_bulk_write`, `function usblp_check_status`, `function handle_bidir`, `function usblp_open`.
- 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.