drivers/usb/host/ohci-dbg.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/host/ohci-dbg.c
Extension
.c
Size
19846 bytes
Lines
786
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_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 *ohci_debug_root;

struct debug_buffer {
	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
	struct ohci_hcd *ohci;
	struct mutex mutex;	/* protect filling of buffer */
	size_t count;		/* number of characters filled into buffer */
	char *page;
};

static ssize_t
show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
{
	unsigned		temp, size = count;

	if (!ed)
		return 0;

	/* print first --> last */
	while (ed->ed_prev)
		ed = ed->ed_prev;

	/* dump a snapshot of the bulk or control schedule */
	while (ed) {
		u32		info = hc32_to_cpu (ohci, ed->hwINFO);
		u32		headp = hc32_to_cpu (ohci, ed->hwHeadP);
		struct list_head *entry;
		struct td	*td;

		temp = scnprintf (buf, size,
			"ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
			ed,
			(info & ED_LOWSPEED) ? 'l' : 'f',
			info & 0x7f,
			(info >> 7) & 0xf,
			(info & ED_IN) ? "in" : "out",
			0x03ff & (info >> 16),
			info,
			(info & ED_SKIP) ? " s" : "",
			(headp & ED_H) ? " H" : "",
			(headp & ED_C) ? data1 : data0);
		size -= temp;
		buf += temp;

		list_for_each (entry, &ed->td_list) {
			u32		cbp, be;

			td = list_entry (entry, struct td, td_list);
			info = hc32_to_cpup (ohci, &td->hwINFO);
			cbp = hc32_to_cpup (ohci, &td->hwCBP);
			be = hc32_to_cpup (ohci, &td->hwBE);
			temp = scnprintf (buf, size,
					"\n\ttd %p %s %d cc=%x urb %p (%08x)",
					td,
					({ char *pid;
					switch (info & TD_DP) {
					case TD_DP_SETUP: pid = "setup"; break;
					case TD_DP_IN: pid = "in"; break;
					case TD_DP_OUT: pid = "out"; break;
					default: pid = "(?)"; break;
					 } pid;}),
					cbp ? (be + 1 - cbp) : 0,
					TD_CC_GET (info), td->urb, info);
			size -= temp;
			buf += temp;
		}

		temp = scnprintf (buf, size, "\n");

Annotation

Implementation Notes