drivers/usb/host/ehci-dbg.c

Source file repositories/reference/linux-study-clean/drivers/usb/host/ehci-dbg.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/host/ehci-dbg.c
Extension
.c
Size
28250 bytes
Lines
1082
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations debug_async_fops = {
	.owner		= THIS_MODULE,
	.open		= debug_async_open,
	.read		= debug_output,
	.release	= debug_close,
	.llseek		= default_llseek,
};

static const struct file_operations debug_bandwidth_fops = {
	.owner		= THIS_MODULE,
	.open		= debug_bandwidth_open,
	.read		= debug_output,
	.release	= debug_close,
	.llseek		= default_llseek,
};

static const struct file_operations debug_periodic_fops = {
	.owner		= THIS_MODULE,
	.open		= debug_periodic_open,
	.read		= debug_output,
	.release	= debug_close,
	.llseek		= default_llseek,
};

static const struct file_operations debug_registers_fops = {
	.owner		= THIS_MODULE,
	.open		= debug_registers_open,
	.read		= debug_output,
	.release	= debug_close,
	.llseek		= default_llseek,
};

static struct dentry *ehci_debug_root;

struct debug_buffer {
	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
	struct usb_bus *bus;
	struct mutex mutex;	/* protect filling of buffer */
	size_t count;		/* number of characters filled into buffer */
	char *output_buf;
	size_t alloc_size;
};

static inline char speed_char(u32 info1)
{
	switch (info1 & (3 << 12)) {
	case QH_FULL_SPEED:
		return 'f';
	case QH_LOW_SPEED:
		return 'l';
	case QH_HIGH_SPEED:
		return 'h';
	default:
		return '?';
	}
}

static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
{
	__u32 v = hc32_to_cpu(ehci, token);

	if (v & QTD_STS_ACTIVE)
		return '*';
	if (v & QTD_STS_HALT)
		return '-';
	if (!IS_SHORT_READ(v))
		return ' ';
	/* tries to advance through hw_alt_next */
	return '/';
}

static void qh_lines(struct ehci_hcd *ehci, struct ehci_qh *qh,
		char **nextp, unsigned *sizep)
{
	u32			scratch;
	u32			hw_curr;
	struct list_head	*entry;
	struct ehci_qtd		*td;
	unsigned		temp;
	unsigned		size = *sizep;
	char			*next = *nextp;
	char			mark;
	__le32			list_end = EHCI_LIST_END(ehci);
	struct ehci_qh_hw	*hw = qh->hw;

	if (hw->hw_qtd_next == list_end)	/* NEC does this */
		mark = '@';
	else
		mark = token_mark(ehci, hw->hw_token);
	if (mark == '/') {	/* qh_alt_next controls qh advance? */

Annotation

Implementation Notes