Example #1
0
static void mxc_udc_recv_setup(void)
{
	setup_packet *s = &ep0_urb->device_request;

	mxc_udc_read_setup_pkt(s);
	if (s->wLength)	{
		mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ?
					USB_DIR_OUT : USB_DIR_IN;
		mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
	}
	if (ep0_recv_setup(ep0_urb)) {
		mxc_ep0_stall();
		return;
	}
	switch (s->bRequest) {
	case USB_REQ_GET_STATUS:
		if ((s->bmRequestType & (USB_DIR_IN | USB_TYPE_MASK)) !=
					 (USB_DIR_IN | USB_TYPE_STANDARD))
			break;
		ch9getstatus(s->bmRequestType, s->wValue,
				s->wIndex, s->wLength);
		return;
	case USB_REQ_SET_ADDRESS:
		if (s->bmRequestType != (USB_DIR_OUT |
			    USB_TYPE_STANDARD | USB_RECIP_DEVICE))
			break;
		mxc_udc.setaddr = 1;
		mxc_udc.ep0_dir = USB_DIR_IN;
		mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
		usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0);
		return;
	case USB_REQ_SET_CONFIGURATION:
		usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
	case USB_REQ_CLEAR_FEATURE:
	case USB_REQ_SET_FEATURE:
	{
		int rc = -1;
		if ((s->bmRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) ==
				 (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD))
			rc = 0;
		else if ((s->bmRequestType &
			    (USB_RECIP_MASK | USB_TYPE_MASK)) ==
			     (USB_RECIP_DEVICE | USB_TYPE_STANDARD))
			rc = 0;
		else
			break;
		if (rc == 0) {
			mxc_udc.ep0_dir = USB_DIR_IN;
			mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
		}
		return;
	}
	default:
		break;
	}
	if (s->wLength) {
		mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ?
					USB_DIR_IN : USB_DIR_OUT;
		mxc_udc_queue_update(0, ep0_urb->buffer,
				ep0_urb->actual_length, 0xffffffff);
		ep0_urb->actual_length = 0;
	} else {
		mxc_udc.ep0_dir = USB_DIR_IN;
		mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
	}
}
Example #2
0
static void mxc_udc_recv_setup(void)
{
	struct usb_device_request *s = &ep0_urb->device_request;

	mxc_udc_read_setup_pkt(s);
	if (s->wLength)	{
		/* If has a data phase,
		  * then prime a dtd for status stage which has zero length DATA0.
		  * The direction of status stage should oppsite to direction of data phase.
		  */
		mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ?
					USB_DIR_OUT : USB_DIR_IN;
		mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
	}
	if (ep0_recv_setup(ep0_urb)) {
		mxc_ep0_stall();
		return;
	}
	switch (s->bRequest) {
	case USB_REQ_GET_STATUS:
		if ((s->bmRequestType & (USB_DIR_IN | USB_TYPE_MASK)) !=
					 (USB_DIR_IN | USB_TYPE_STANDARD))
			break;
		ch9getstatus(s->bmRequestType, s->wValue,
				s->wIndex, s->wLength);

		DBG("[SETUP] REQ_GET_STATUS\n");
		return;
	case USB_REQ_SET_ADDRESS:
		if (s->bmRequestType != (USB_DIR_OUT |
			    USB_TYPE_STANDARD | USB_RECIP_DEVICE))
			break;
		mxc_udc.setaddr = 1;
		mxc_udc.ep0_dir = USB_DIR_IN;
		mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
		usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0);
		DBG("[SETUP] REQ_SET_ADDRESS\n");
		return;
	case USB_REQ_SET_CONFIGURATION:
		usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
		DBG("[SETUP] REQ_SET_CONFIGURATION\n");
	case USB_REQ_CLEAR_FEATURE:
	case USB_REQ_SET_FEATURE:
	{
		int rc = -1;
		if ((s->bmRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) ==
				 (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD))
			rc = 0;
		else if ((s->bmRequestType &
			    (USB_RECIP_MASK | USB_TYPE_MASK)) ==
			     (USB_RECIP_DEVICE | USB_TYPE_STANDARD))
			rc = 0;
		else
			break;
		if (rc == 0) {
			mxc_udc.ep0_dir = USB_DIR_IN;
			mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
		}
		return;
	}
	default:
		break;
	}
	if (s->wLength) {
		mxc_udc.ep0_dir = (s->bmRequestType & USB_DIR_IN) ?
					USB_DIR_IN : USB_DIR_OUT;
		mxc_udc_queue_update(0, ep0_urb->buffer,
				ep0_urb->actual_length, 0xffffffff);
		ep0_urb->actual_length = 0;
	} else {
		mxc_udc.ep0_dir = USB_DIR_IN;
		mxc_udc_queue_update(0, NULL, 0, 0xffffffff);
	}
}