static int __xudc_ep0_queue(struct xusb_ep *ep0, struct xusb_req *req)
{
	struct xusb_udc *udc = ep0->udc;
	u32 length;
	u8 *corebuf;

	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
		dev_dbg(udc->dev, "%s, bogus device state\n", __func__);
		return -EINVAL;
	}
	if (!list_empty(&ep0->queue)) {
		dev_dbg(udc->dev, "%s:ep0 busy\n", __func__);
		return -EBUSY;
	}

	req->usb_req.status = -EINPROGRESS;
	req->usb_req.actual = 0;

	list_add_tail(&req->queue, &ep0->queue);

	if (udc->setup.bRequestType & USB_DIR_IN) {
		prefetch(req->usb_req.buf);
		length = req->usb_req.length;
		corebuf = (void __force *) ((ep0->rambase << 2) +
			   udc->addr);
		length = req->usb_req.actual = min_t(u32, length,
						     EP0_MAX_PACKET);
		memcpy(corebuf, req->usb_req.buf, length);
		udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, length);
		udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
	} else {
		if (udc->setup.wLength) {
			/* Enable EP0 buffer to receive data */
			udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, 0);
			udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
		} else {
			xudc_wrstatus(udc);
		}
	}

	return 0;
}
static int __xudc_ep0_queue(struct xusb_ep *ep0, struct xusb_req *req)
{
	struct xusb_udc *udc = ep0->udc;
	u32 length;
	u8 *corebuf;

	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
		dev_dbg(udc->dev, "%s, bogus device state\n", __func__);
		return -EINVAL;
	}
	if (!list_empty(&ep0->queue)) {
		dev_dbg(udc->dev, "%s:ep0 busy\n", __func__);
		return -EBUSY;
	}

	req->usb_req.status = -EINPROGRESS;
	req->usb_req.actual = 0;

	list_add_tail(&req->queue, &ep0->queue);

	if (udc->setup.bRequestType & USB_DIR_IN) {
		prefetch(req->usb_req.buf);
		length = req->usb_req.length;
		corebuf = (void __force *) ((ep0->rambase << 2) +
			   udc->addr);
		length = req->usb_req.actual = min_t(u32, length,
						     EP0_MAX_PACKET);
		memcpy(corebuf, req->usb_req.buf, length);
		udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, length);
		udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
	} else {
		if (udc->setup.wLength) {
			 
			udc->write_fn(udc->addr, XUSB_EP_BUF0COUNT_OFFSET, 0);
			udc->write_fn(udc->addr, XUSB_BUFFREADY_OFFSET, 1);
		} else {
			xudc_wrstatus(udc);
		}
	}

	return 0;
}