drivers/usb/renesas_usbhs/fifo.c

Source file repositories/reference/linux-study-clean/drivers/usb/renesas_usbhs/fifo.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/renesas_usbhs/fifo.c
Extension
.c
Size
35285 bytes
Lines
1487
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

if (chan) {
			dmaengine_terminate_sync(chan);
			usbhsf_dma_unmap(pkt);
		} else {
			if (usbhs_pipe_is_dir_in(pipe))
				usbhsf_rx_irq_ctrl(pipe, 0);
			else
				usbhsf_tx_irq_ctrl(pipe, 0);
		}

		usbhs_pipe_clear_without_sequence(pipe, 0, 0);
		usbhs_pipe_running(pipe, 0);

		__usbhsf_pkt_del(pkt);
	}

	if (fifo)
		usbhsf_fifo_unselect(pipe, fifo);

	usbhs_unlock(priv, flags);
	/********************  spin unlock ******************/

	return pkt;
}

enum {
	USBHSF_PKT_PREPARE,
	USBHSF_PKT_TRY_RUN,
	USBHSF_PKT_DMA_DONE,
};

static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type)
{
	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
	struct usbhs_pkt *pkt;
	struct device *dev = usbhs_priv_to_dev(priv);
	int (*func)(struct usbhs_pkt *pkt, int *is_done);
	unsigned long flags;
	int ret = 0;
	int is_done = 0;

	/********************  spin lock ********************/
	usbhs_lock(priv, flags);

	pkt = __usbhsf_pkt_get(pipe);
	if (!pkt) {
		ret = -EINVAL;
		goto __usbhs_pkt_handler_end;
	}

	switch (type) {
	case USBHSF_PKT_PREPARE:
		func = pkt->handler->prepare;
		break;
	case USBHSF_PKT_TRY_RUN:
		func = pkt->handler->try_run;
		break;
	case USBHSF_PKT_DMA_DONE:
		func = pkt->handler->dma_done;
		break;
	default:
		dev_err(dev, "unknown pkt handler\n");
		goto __usbhs_pkt_handler_end;
	}

	if (likely(func))
		ret = func(pkt, &is_done);

	if (is_done)
		__usbhsf_pkt_del(pkt);

__usbhs_pkt_handler_end:
	usbhs_unlock(priv, flags);
	/********************  spin unlock ******************/

	if (is_done) {
		pkt->done(priv, pkt);
		usbhs_pkt_start(pipe);
	}

	return ret;
}

void usbhs_pkt_start(struct usbhs_pipe *pipe)
{
	usbhsf_pkt_handler(pipe, USBHSF_PKT_PREPARE);
}

/*
 *		irq enable/disable function

Annotation

Implementation Notes