drivers/usb/core/generic.c
Source file repositories/reference/linux-study-clean/drivers/usb/core/generic.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/core/generic.c- Extension
.c- Size
- 9502 bytes
- Lines
- 337
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/usb.hlinux/usb/hcd.hlinux/string_choices.huapi/linux/usb/audio.husb.h
Detected Declarations
function is_rndisfunction is_activesyncfunction is_audiofunction is_uac3_configfunction usb_choose_configurationfunction __check_for_non_generic_matchfunction usb_generic_driver_matchfunction usb_generic_driver_probefunction usb_generic_driver_disconnectfunction usb_generic_driver_suspendfunction usb_generic_driver_resumeexport usb_choose_configuration
Annotated Snippet
static int __check_for_non_generic_match(struct device_driver *drv, void *data)
{
struct usb_device *udev = data;
struct usb_device_driver *udrv;
if (!is_usb_device_driver(drv))
return 0;
udrv = to_usb_device_driver(drv);
if (udrv == &usb_generic_driver)
return 0;
return usb_driver_applicable(udev, udrv);
}
static bool usb_generic_driver_match(struct usb_device *udev)
{
if (udev->use_generic_driver)
return true;
/*
* If any other driver wants the device, leave the device to this other
* driver.
*/
if (bus_for_each_drv(&usb_bus_type, NULL, udev, __check_for_non_generic_match))
return false;
return true;
}
int usb_generic_driver_probe(struct usb_device *udev)
{
int err, c;
/* Choose and set the configuration. This registers the interfaces
* with the driver core and lets interface drivers bind to them.
*/
if (udev->authorized == 0)
dev_info(&udev->dev, "Device is not authorized for usage\n");
else {
c = usb_choose_configuration(udev);
if (c >= 0) {
err = usb_set_configuration(udev, c);
if (err && err != -ENODEV) {
dev_err(&udev->dev, "can't set config #%d, error %d\n",
c, err);
/* This need not be fatal. The user can try to
* set other configurations. */
}
}
}
/* USB device state == configured ... usable */
usb_notify_add_device(udev);
return 0;
}
void usb_generic_driver_disconnect(struct usb_device *udev)
{
usb_notify_remove_device(udev);
/* if this is only an unbind, not a physical disconnect, then
* unconfigure the device */
if (udev->actconfig)
usb_set_configuration(udev, -1);
}
#ifdef CONFIG_PM
int usb_generic_driver_suspend(struct usb_device *udev, pm_message_t msg)
{
int rc;
/* Normal USB devices suspend through their upstream port.
* Root hubs don't have upstream ports to suspend,
* so we have to shut down their downstream HC-to-USB
* interfaces manually by doing a bus (or "global") suspend.
*/
if (!udev->parent)
rc = hcd_bus_suspend(udev, msg);
/*
* Non-root USB2 devices don't need to do anything for FREEZE
* or PRETHAW. USB3 devices don't support global suspend and
* needs to be selectively suspended.
*/
else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
&& (udev->speed < USB_SPEED_SUPER))
rc = 0;
else
rc = usb_port_suspend(udev, msg);
Annotation
- Immediate include surface: `linux/usb.h`, `linux/usb/hcd.h`, `linux/string_choices.h`, `uapi/linux/usb/audio.h`, `usb.h`.
- Detected declarations: `function is_rndis`, `function is_activesync`, `function is_audio`, `function is_uac3_config`, `function usb_choose_configuration`, `function __check_for_non_generic_match`, `function usb_generic_driver_match`, `function usb_generic_driver_probe`, `function usb_generic_driver_disconnect`, `function usb_generic_driver_suspend`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: pattern implementation candidate.
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.