drivers/usb/fotg210/fotg210-hcd.c

Source file repositories/reference/linux-study-clean/drivers/usb/fotg210/fotg210-hcd.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/fotg210/fotg210-hcd.c
Extension
.c
Size
158609 bytes
Lines
5642
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 *fotg210_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 scratch)
{
	switch (scratch & (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 fotg210_hcd *fotg210, __hc32 token)
{
	__u32 v = hc32_to_cpu(fotg210, 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 fotg210_hcd *fotg210, struct fotg210_qh *qh,
		char **nextp, unsigned *sizep)
{
	u32 scratch;
	u32 hw_curr;
	struct fotg210_qtd *td;
	unsigned temp;
	unsigned size = *sizep;
	char *next = *nextp;
	char mark;
	__le32 list_end = FOTG210_LIST_END(fotg210);
	struct fotg210_qh_hw *hw = qh->hw;

	if (hw->hw_qtd_next == list_end) /* NEC does this */
		mark = '@';
	else
		mark = token_mark(fotg210, hw->hw_token);
	if (mark == '/') { /* qh_alt_next controls qh advance? */
		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
		    fotg210->async->hw->hw_alt_next)
			mark = '#'; /* blocked */
		else if (hw->hw_alt_next == list_end)
			mark = '.'; /* use hw_qtd_next */
		/* else alt_next points to some other qtd */
	}
	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);

Annotation

Implementation Notes