示例#1
0
/*
 *		USB_TYPE handler
 */
static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
				   struct usbhsg_recip_handle *handler,
				   struct usb_ctrlrequest *ctrl)
{
	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
	struct device *dev = usbhsg_gpriv_to_dev(gpriv);
	struct usbhsg_uep *uep;
	struct usbhs_pipe *pipe;
	int recip = ctrl->bRequestType & USB_RECIP_MASK;
	int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;
	int ret;
	int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep,
		    struct usb_ctrlrequest *ctrl);
	char *msg;

	uep = usbhsg_gpriv_to_nth_uep(gpriv, nth);
	pipe = usbhsg_uep_to_pipe(uep);
	if (!pipe) {
		dev_err(dev, "wrong recip request\n");
		ret = -EINVAL;
		goto usbhsg_recip_run_handle_end;
	}

	switch (recip) {
	case USB_RECIP_DEVICE:
		msg	= "DEVICE";
		func	= handler->device;
		break;
	case USB_RECIP_INTERFACE:
		msg	= "INTERFACE";
		func	= handler->interface;
		break;
	case USB_RECIP_ENDPOINT:
		msg	= "ENDPOINT";
		func	= handler->endpoint;
		break;
	default:
		dev_warn(dev, "unsupported RECIP(%d)\n", recip);
		func = NULL;
		ret = -EINVAL;
	}

	if (func) {
		unsigned long flags;

		dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg);

		/********************  spin lock ********************/
		usbhs_lock(priv, flags);
		ret = func(priv, uep, ctrl);
		usbhs_unlock(priv, flags);
		/********************  spin unlock ******************/
	}

usbhsg_recip_run_handle_end:
	usbhs_pkt_start(pipe);

	return ret;
}
示例#2
0
static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type)
{
	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
	struct usbhs_pkt *pkt;
	struct device *dev = usbhs_priv_to_dev(priv);
	int (*func)(struct usbhs_pkt *pkt, int *is_done);
	unsigned long flags;
	int ret = 0;
	int is_done = 0;

	/********************  spin lock ********************/
	usbhs_lock(priv, flags);

	pkt = __usbhsf_pkt_get(pipe);
	if (!pkt)
		goto __usbhs_pkt_handler_end;

	switch (type) {
	case USBHSF_PKT_PREPARE:
		func = pkt->handler->prepare;
		break;
	case USBHSF_PKT_TRY_RUN:
		func = pkt->handler->try_run;
		break;
	case USBHSF_PKT_DMA_DONE:
		func = pkt->handler->dma_done;
		break;
	default:
		dev_err(dev, "unknown pkt hander\n");
		goto __usbhs_pkt_handler_end;
	}

	ret = func(pkt, &is_done);

	if (is_done)
		__usbhsf_pkt_del(pkt);

__usbhs_pkt_handler_end:
	usbhs_unlock(priv, flags);
	/********************  spin unlock ******************/

	if (is_done) {
		pkt->done(priv, pkt);
		usbhs_pkt_start(pipe);
	}

	return ret;
}
示例#3
0
static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
				 struct urb *urb,
				 gfp_t mflags)
{
	struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
	struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep);
	struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep);
	struct device *dev = usbhsh_hcd_to_dev(hcd);
	int ret;

	dev_dbg(dev, "%s\n", __func__);

	/*
	 * setup stage
	 *
	 * usbhsh_send_setup_stage_packet() wait SACK/SIGN
	 */
	usbhsh_setup_stage_packet_push(hpriv, urb, pipe);

	/*
	 * data stage
	 *
	 * It is pushed only when urb has buffer.
	 */
	if (urb->transfer_buffer_length) {
		ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags);
		if (ret < 0) {
			dev_err(dev, "data stage failed\n");
			return ret;
		}
	}

	/*
	 * status stage
	 */
	ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags);
	if (ret < 0) {
		dev_err(dev, "status stage failed\n");
		return ret;
	}

	/*
	 * start pushed packets
	 */
	usbhs_pkt_start(pipe);

	return 0;
}
示例#4
0
static int usbhsh_queue_push(struct usb_hcd *hcd,
			     struct urb *urb,
			     gfp_t mem_flags)
{
	struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
	struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep);
	struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep);
	struct device *dev = usbhsh_hcd_to_dev(hcd);
	struct usbhsh_request *ureq;
	void *buf;
	int len, sequence;

	if (usb_pipeisoc(urb->pipe)) {
		dev_err(dev, "pipe iso is not supported now\n");
		return -EIO;
	}

	/* this ureq will be freed on usbhsh_queue_done() */
	ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
	if (unlikely(!ureq)) {
		dev_err(dev, "ureq alloc fail\n");
		return -ENOMEM;
	}

	if (usb_pipein(urb->pipe))
		pipe->handler = &usbhs_fifo_dma_pop_handler;
	else
		pipe->handler = &usbhs_fifo_dma_push_handler;

	buf = (void *)(urb->transfer_buffer + urb->actual_length);
	len = urb->transfer_buffer_length - urb->actual_length;

	sequence = usb_gettoggle(urb->dev,
				 usb_pipeendpoint(urb->pipe),
				 usb_pipeout(urb->pipe));

	dev_dbg(dev, "%s\n", __func__);
	usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done,
		       buf, len, (urb->transfer_flags & URB_ZERO_PACKET),
		       sequence);

	usbhs_pkt_start(pipe);

	return 0;
}
示例#5
0
文件: mod_gadget.c 项目: Abioy/kasan
static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv,
						   struct usbhsg_uep *uep,
						   struct usb_ctrlrequest *ctrl)
{
	struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
	struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);

	if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) {
		usbhs_pipe_disable(pipe);
		usbhs_pipe_sequence_data0(pipe);
		usbhs_pipe_enable(pipe);
	}

	usbhsg_recip_handler_std_control_done(priv, uep, ctrl);

	usbhs_pkt_start(pipe);

	return 0;
}
示例#6
0
文件: mod_gadget.c 项目: Abioy/kasan
static void usbhsg_queue_push(struct usbhsg_uep *uep,
			      struct usbhsg_request *ureq)
{
	struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
	struct device *dev = usbhsg_gpriv_to_dev(gpriv);
	struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
	struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
	struct usb_request *req = &ureq->req;

	req->actual = 0;
	req->status = -EINPROGRESS;
	usbhs_pkt_push(pipe, pkt, usbhsg_queue_done,
		       req->buf, req->length, req->zero, -1);
	usbhs_pkt_start(pipe);

	dev_dbg(dev, "pipe %d : queue push (%d)\n",
		usbhs_pipe_number(pipe),
		req->length);
}