drivers/usb/mtu3/mtu3_gadget_ep0.c

Source file repositories/reference/linux-study-clean/drivers/usb/mtu3/mtu3_gadget_ep0.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/mtu3/mtu3_gadget_ep0.c
Extension
.c
Size
21628 bytes
Lines
917
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 (mtu->g.speed >= USB_SPEED_SUPER) {
			result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED;
			result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED;
		}

		dev_dbg(mtu->dev, "%s result=%x, U1=%x, U2=%x\n", __func__,
			result[0], mtu->u1_enable, mtu->u2_enable);

		break;
	case USB_RECIP_INTERFACE:
		/* status of function remote wakeup, forward request */
		handled = 0;
		break;
	case USB_RECIP_ENDPOINT:
		epnum = (u8) le16_to_cpu(setup->wIndex);
		is_in = epnum & USB_DIR_IN;
		epnum &= USB_ENDPOINT_NUMBER_MASK;

		if (epnum >= mtu->num_eps) {
			handled = -EINVAL;
			break;
		}
		if (!epnum)
			break;

		mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
		if (!mep->desc) {
			handled = -EINVAL;
			break;
		}
		if (mep->flags & MTU3_EP_STALL)
			result[0] |= 1 << USB_ENDPOINT_HALT;

		break;
	default:
		/* class, vendor, etc ... delegate */
		handled = 0;
		break;
	}

	if (handled > 0) {
		int ret;

		/* prepare a data stage for GET_STATUS */
		dev_dbg(mtu->dev, "get_status=%x\n", *(u16 *)result);
		memcpy(mtu->setup_buf, result, sizeof(result));
		mtu->ep0_req.mep = mtu->ep0;
		mtu->ep0_req.request.length = 2;
		mtu->ep0_req.request.buf = &mtu->setup_buf;
		mtu->ep0_req.request.complete = ep0_dummy_complete;
		ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
		if (ret < 0)
			handled = ret;
	}
	return handled;
}

static int handle_test_mode(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
{
	void __iomem *mbase = mtu->mac_base;
	int handled = 1;
	u32 value;

	switch (le16_to_cpu(setup->wIndex) >> 8) {
	case USB_TEST_J:
		dev_dbg(mtu->dev, "USB_TEST_J\n");
		mtu->test_mode_nr = TEST_J_MODE;
		break;
	case USB_TEST_K:
		dev_dbg(mtu->dev, "USB_TEST_K\n");
		mtu->test_mode_nr = TEST_K_MODE;
		break;
	case USB_TEST_SE0_NAK:
		dev_dbg(mtu->dev, "USB_TEST_SE0_NAK\n");
		mtu->test_mode_nr = TEST_SE0_NAK_MODE;
		break;
	case USB_TEST_PACKET:
		dev_dbg(mtu->dev, "USB_TEST_PACKET\n");
		mtu->test_mode_nr = TEST_PACKET_MODE;
		break;
	default:
		handled = -EINVAL;
		goto out;
	}

	mtu->test_mode = true;

	/* no TX completion interrupt, and need restart platform after test */
	if (mtu->test_mode_nr == TEST_PACKET_MODE)
		ep0_load_test_packet(mtu);

Annotation

Implementation Notes