drivers/usb/cdns3/cdnsp-gadget.c

Source file repositories/reference/linux-study-clean/drivers/usb/cdns3/cdnsp-gadget.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/cdns3/cdnsp-gadget.c
Extension
.c
Size
52758 bytes
Lines
2078
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

TRB_TO_EP_ID(data) == (pep->idx + 1)) {
			data |= TRB_EVENT_INVALIDATE;
			event->trans_event.flags = cpu_to_le32(data);
		}

		if (cdnsp_last_trb_on_seg(segment, event)) {
			cycle_state ^= 1;
			segment = pdev->event_ring->deq_seg->next;
			event = segment->trbs;
		} else {
			event++;
		}
	}
}

int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)
{
	struct cdnsp_segment *event_deq_seg;
	union cdnsp_trb *cmd_trb;
	dma_addr_t cmd_deq_dma;
	union cdnsp_trb *event;
	u32 cycle_state;
	u32 retry = 10;
	int ret, val;
	u64 cmd_dma;
	u32  flags;

	cmd_trb = pdev->cmd.command_trb;
	pdev->cmd.status = 0;

	trace_cdnsp_cmd_wait_for_compl(pdev->cmd_ring, &cmd_trb->generic);

	ret = readl_poll_timeout_atomic(&pdev->op_regs->cmd_ring, val,
					!CMD_RING_BUSY(val), 1,
					CDNSP_CMD_TIMEOUT);
	if (ret) {
		dev_err(pdev->dev, "ERR: Timeout while waiting for command\n");
		trace_cdnsp_cmd_timeout(pdev->cmd_ring, &cmd_trb->generic);
		pdev->cdnsp_state = CDNSP_STATE_DYING;
		return -ETIMEDOUT;
	}

	event = pdev->event_ring->dequeue;
	event_deq_seg = pdev->event_ring->deq_seg;
	cycle_state = pdev->event_ring->cycle_state;

	cmd_deq_dma = cdnsp_trb_virt_to_dma(pdev->cmd_ring->deq_seg, cmd_trb);
	if (!cmd_deq_dma)
		return -EINVAL;

	while (1) {
		flags = le32_to_cpu(event->event_cmd.flags);

		/* Check the owner of the TRB. */
		if ((flags & TRB_CYCLE) != cycle_state) {
			/*
			 * Give some extra time to get chance controller
			 * to finish command before returning error code.
			 * Checking CMD_RING_BUSY is not sufficient because
			 * this bit is cleared to '0' when the Command
			 * Descriptor has been executed by controller
			 * and not when command completion event has
			 * be added to event ring.
			 */
			if (retry--) {
				udelay(20);
				continue;
			}

			return -EINVAL;
		}

		cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb);

		/*
		 * Check whether the completion event is for last queued
		 * command.
		 */
		if (TRB_FIELD_TO_TYPE(flags) != TRB_COMPLETION ||
		    cmd_dma != (u64)cmd_deq_dma) {
			if (!cdnsp_last_trb_on_seg(event_deq_seg, event)) {
				event++;
				continue;
			}

			if (cdnsp_last_trb_on_ring(pdev->event_ring,
						   event_deq_seg, event))
				cycle_state ^= 1;

			event_deq_seg = event_deq_seg->next;

Annotation

Implementation Notes