drivers/usb/host/fhci-tds.c

Source file repositories/reference/linux-study-clean/drivers/usb/host/fhci-tds.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/host/fhci-tds.c
Extension
.c
Size
16569 bytes
Lines
620
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source 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_td {
	__be16 status;
	__be16 length;
	__be32 buf_ptr;
	__be16 extra;
	__be16 reserved;
};

static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
				      struct usb_td __iomem *td,
				      u16 status)
{
	if (status & TD_W)
		return base;
	else
		return ++td;
}

void fhci_push_dummy_bd(struct endpoint *ep)
{
	if (!ep->already_pushed_dummy_bd) {
		u16 td_status = in_be16(&ep->empty_td->status);

		out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
		/* get the next TD in the ring */
		ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
		ep->already_pushed_dummy_bd = true;
	}
}

/* destroy an USB endpoint */
void fhci_ep0_free(struct fhci_usb *usb)
{
	struct endpoint *ep;
	int size;

	ep = usb->ep0;
	if (ep) {
		if (ep->td_base)
			cpm_muram_free(cpm_muram_offset(ep->td_base));

		if (kfifo_initialized(&ep->conf_frame_Q)) {
			size = cq_howmany(&ep->conf_frame_Q);
			for (; size; size--) {
				struct packet *pkt = cq_get(&ep->conf_frame_Q);

				kfree(pkt);
			}
			cq_delete(&ep->conf_frame_Q);
		}

		if (kfifo_initialized(&ep->empty_frame_Q)) {
			size = cq_howmany(&ep->empty_frame_Q);
			for (; size; size--) {
				struct packet *pkt = cq_get(&ep->empty_frame_Q);

				kfree(pkt);
			}
			cq_delete(&ep->empty_frame_Q);
		}

		if (kfifo_initialized(&ep->dummy_packets_Q)) {
			size = cq_howmany(&ep->dummy_packets_Q);
			for (; size; size--) {
				u8 *buff = cq_get(&ep->dummy_packets_Q);

				kfree(buff);
			}
			cq_delete(&ep->dummy_packets_Q);
		}

		kfree(ep);
		usb->ep0 = NULL;
	}
}

/*
 * create the endpoint structure
 *
 * arguments:
 * usb		A pointer to the data structure of the USB
 * data_mem	The data memory partition(BUS)
 * ring_len	TD ring length
 */
u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
			   u32 ring_len)
{
	struct endpoint *ep;
	struct usb_td __iomem *td;
	unsigned long ep_offset;

Annotation

Implementation Notes