drivers/usb/gadget/composite.c

Source file repositories/reference/linux-study-clean/drivers/usb/gadget/composite.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/gadget/composite.c
Extension
.c
Size
77315 bytes
Lines
2806
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct usb_os_string {
	__u8	bLength;
	__u8	bDescriptorType;
	__u8	qwSignature[OS_STRING_QW_SIGN_LEN];
	__u8	bMS_VendorCode;
	__u8	bPad;
} __packed;

/*
 * The code in this file is utility code, used to build a gadget driver
 * from one or more "function" drivers, one or more "configuration"
 * objects, and a "usb_composite_driver" by gluing them together along
 * with the relevant device-wide data.
 */

static struct usb_gadget_strings **get_containers_gs(
		struct usb_gadget_string_container *uc)
{
	return (struct usb_gadget_strings **)uc->stash;
}

/**
 * function_descriptors() - get function descriptors for speed
 * @f: the function
 * @speed: the speed
 *
 * Returns the descriptors or NULL if not set.
 */
static struct usb_descriptor_header **
function_descriptors(struct usb_function *f,
		     enum usb_device_speed speed)
{
	struct usb_descriptor_header **descriptors;

	/*
	 * NOTE: we try to help gadget drivers which might not be setting
	 * max_speed appropriately.
	 */

	switch (speed) {
	case USB_SPEED_SUPER_PLUS:
		descriptors = f->ssp_descriptors;
		if (descriptors)
			break;
		fallthrough;
	case USB_SPEED_SUPER:
		descriptors = f->ss_descriptors;
		if (descriptors)
			break;
		fallthrough;
	case USB_SPEED_HIGH:
		descriptors = f->hs_descriptors;
		if (descriptors)
			break;
		fallthrough;
	default:
		descriptors = f->fs_descriptors;
	}

	/*
	 * if we can't find any descriptors at all, then this gadget deserves to
	 * Oops with a NULL pointer dereference
	 */

	return descriptors;
}

/**
 * next_desc() - advance to the next desc_type descriptor
 * @t: currect pointer within descriptor array
 * @desc_type: descriptor type
 *
 * Return: next desc_type descriptor or NULL
 *
 * Iterate over @t until either desc_type descriptor found or
 * NULL (that indicates end of list) encountered
 */
static struct usb_descriptor_header**
next_desc(struct usb_descriptor_header **t, u8 desc_type)
{
	for (; *t; t++) {
		if ((*t)->bDescriptorType == desc_type)
			return t;
	}
	return NULL;
}

/*
 * for_each_desc() - iterate over desc_type descriptors in the
 * descriptors list

Annotation

Implementation Notes