示例#1
0
static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
		const struct dwc3_event_depevt *event)
{
	switch (event->status) {
	case DEPEVT_STATUS_CONTROL_SETUP:
		dev_vdbg(dwc->dev, "Control Setup\n");
		dwc3_ep0_do_control_setup(dwc, event);
		break;

	case DEPEVT_STATUS_CONTROL_DATA:
		dev_vdbg(dwc->dev, "Control Data\n");

		if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) {
			dev_vdbg(dwc->dev, "Expected %d got %d\n",
					dwc->ep0_next_event,
					DWC3_EP0_NRDY_DATA);

			dwc3_ep0_stall_and_restart(dwc);
			return;
		}

		/*
		 * One of the possible error cases is when Host _does_
		 * request for Data Phase, but it does so on the wrong
		 * direction.
		 *
		 * Here, we already know ep0_next_event is DATA (see above),
		 * so we only need to check for direction.
		 */
		if (dwc->ep0_expect_in != event->endpoint_number) {
			dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
			dwc3_ep0_stall_and_restart(dwc);
			return;
		}

		dwc3_ep0_do_control_data(dwc, event);
		break;

	case DEPEVT_STATUS_CONTROL_STATUS:
		dev_vdbg(dwc->dev, "Control Status\n");

		if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) {
			dev_vdbg(dwc->dev, "Expected %d got %d\n",
					dwc->ep0_next_event,
					DWC3_EP0_NRDY_STATUS);

			dwc3_ep0_stall_and_restart(dwc);
			return;
		}
		dwc3_ep0_do_control_status(dwc, event);
	}
}
示例#2
0
文件: ep0.c 项目: AllenWeb/linux
static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
		const struct dwc3_event_depevt *event)
{
	dwc->setup_packet_pending = true;

	/*
	 * This part is very tricky: If we has just handled
	 * XferNotReady(Setup) and we're now expecting a
	 * XferComplete but, instead, we receive another
	 * XferNotReady(Setup), we should STALL and restart
	 * the state machine.
	 *
	 * In all other cases, we just continue waiting
	 * for the XferComplete event.
	 *
	 * We are a little bit unsafe here because we're
	 * not trying to ensure that last event was, indeed,
	 * XferNotReady(Setup).
	 *
	 * Still, we don't expect any condition where that
	 * should happen and, even if it does, it would be
	 * another error condition.
	 */
	if (dwc->ep0_next_event == DWC3_EP0_COMPLETE) {
		switch (event->status) {
		case DEPEVT_STATUS_CONTROL_SETUP:
			dev_vdbg(dwc->dev, "Unexpected XferNotReady(Setup)\n");
			dwc3_ep0_stall_and_restart(dwc);
			break;
		case DEPEVT_STATUS_CONTROL_DATA:
			/* FALLTHROUGH */
		case DEPEVT_STATUS_CONTROL_STATUS:
			/* FALLTHROUGH */
		default:
			dev_vdbg(dwc->dev, "waiting for XferComplete\n");
		}

		return;
	}

	switch (event->status) {
	case DEPEVT_STATUS_CONTROL_SETUP:
		dev_vdbg(dwc->dev, "Control Setup\n");

		dwc->ep0state = EP0_SETUP_PHASE;

		dwc3_ep0_do_control_setup(dwc, event);
		break;

	case DEPEVT_STATUS_CONTROL_DATA:
		dev_vdbg(dwc->dev, "Control Data\n");

		dwc->ep0state = EP0_DATA_PHASE;

		if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) {
			dev_vdbg(dwc->dev, "Expected %d got %d\n",
					dwc->ep0_next_event,
					DWC3_EP0_NRDY_DATA);

			dwc3_ep0_stall_and_restart(dwc);
			return;
		}

		/*
		 * One of the possible error cases is when Host _does_
		 * request for Data Phase, but it does so on the wrong
		 * direction.
		 *
		 * Here, we already know ep0_next_event is DATA (see above),
		 * so we only need to check for direction.
		 */
		if (dwc->ep0_expect_in != event->endpoint_number) {
			dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
			dwc3_ep0_stall_and_restart(dwc);
			return;
		}

		dwc3_ep0_do_control_data(dwc, event);
		break;

	case DEPEVT_STATUS_CONTROL_STATUS:
		dev_vdbg(dwc->dev, "Control Status\n");

		dwc->ep0state = EP0_STATUS_PHASE;

		if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) {
			dev_vdbg(dwc->dev, "Expected %d got %d\n",
					dwc->ep0_next_event,
					DWC3_EP0_NRDY_STATUS);

			dwc3_ep0_stall_and_restart(dwc);
			return;
		}

		if (dwc->delayed_status) {
			WARN_ON_ONCE(event->endpoint_number != 1);
			dev_vdbg(dwc->dev, "Mass Storage delayed status\n");
			return;
		}

		dwc3_ep0_do_control_status(dwc, event->endpoint_number);
	}
}