Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280864
b: refs/heads/master
c: ee8a0bf
h: refs/heads/master
v: v3
  • Loading branch information
Kuninori Morimoto authored and Felipe Balbi committed Dec 12, 2011
1 parent 5bc9854 commit ae95278
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1ab6f257e12a89f62f58fcef9f7b85badce412bc
refs/heads/master: ee8a0bf5a775098b1140195b6bfacb4813166e5f
107 changes: 56 additions & 51 deletions trunk/drivers/usb/renesas_usbhs/mod_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,12 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)

static int usbhsh_queue_push(struct usb_hcd *hcd,
struct usbhs_pipe *pipe,
struct urb *urb)
struct urb *urb,
gfp_t mem_flags)
{
struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb);
struct usbhs_pkt *pkt = &ureq->pkt;
struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
struct device *dev = usbhsh_hcd_to_dev(hcd);
struct usbhsh_request *ureq;
void *buf;
int len;

Expand All @@ -516,6 +517,14 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
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;
}
usbhsh_urb_to_ureq(urb) = ureq;

if (usb_pipein(urb->pipe))
pipe->handler = &usbhs_fifo_pio_pop_handler;
else
Expand All @@ -525,7 +534,7 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
len = urb->transfer_buffer_length - urb->actual_length;

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

Expand Down Expand Up @@ -605,72 +614,72 @@ static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv,
usbhsh_urb_to_ureq(urb) = NULL;
}

static void usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv,
struct urb *urb,
struct usbhs_pipe *pipe)
static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv,
struct urb *urb,
struct usbhs_pipe *pipe,
gfp_t mem_flags)

{
struct usbhsh_request *ureq;
struct usbhs_pkt *pkt;

/*
* FIXME
*
* data stage uses ureq which is connected to urb
* see usbhsh_urb_enqueue() :: alloc new request.
* it will be freed in usbhsh_data_stage_packet_done()
*/
ureq = usbhsh_urb_to_ureq(urb);
pkt = &ureq->pkt;
/* this ureq will be freed on usbhsh_data_stage_packet_done() */
ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
if (unlikely(!ureq))
return -ENOMEM;
usbhsh_urb_to_ureq(urb) = ureq;

if (usb_pipein(urb->pipe))
pipe->handler = &usbhs_dcp_data_stage_in_handler;
else
pipe->handler = &usbhs_dcp_data_stage_out_handler;

usbhs_pkt_push(pipe, pkt,
usbhs_pkt_push(pipe, &ureq->pkt,
usbhsh_data_stage_packet_done,
urb->transfer_buffer,
urb->transfer_buffer_length,
(urb->transfer_flags & URB_ZERO_PACKET));

return 0;
}

/*
* DCP status stage
*/
static void usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv,
static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv,
struct urb *urb,
struct usbhs_pipe *pipe)
struct usbhs_pipe *pipe,
gfp_t mem_flags)
{
struct usbhsh_request *ureq;
struct usbhs_pkt *pkt;

/*
* FIXME
*
* status stage uses allocated ureq.
* it will be freed on usbhsh_queue_done()
*/
ureq = usbhsh_ureq_alloc(hpriv, urb, GFP_KERNEL);
pkt = &ureq->pkt;
/* This ureq will be freed on usbhsh_queue_done() */
ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
if (unlikely(!ureq))
return -ENOMEM;
usbhsh_urb_to_ureq(urb) = ureq;

if (usb_pipein(urb->pipe))
pipe->handler = &usbhs_dcp_status_stage_in_handler;
else
pipe->handler = &usbhs_dcp_status_stage_out_handler;

usbhs_pkt_push(pipe, pkt,
usbhs_pkt_push(pipe, &ureq->pkt,
usbhsh_queue_done,
NULL,
urb->transfer_buffer_length,
0);

return 0;
}

static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
struct usbhsh_hpriv *hpriv,
struct usbhs_pipe *pipe,
struct urb *urb)
struct urb *urb,
gfp_t mflags)
{
struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
struct device *dev = usbhsh_hcd_to_dev(hcd);
int ret;

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

Expand All @@ -686,13 +695,22 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
*
* It is pushed only when urb has buffer.
*/
if (urb->transfer_buffer_length)
usbhsh_data_stage_packet_push(hpriv, urb, pipe);
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
*/
usbhsh_status_stage_packet_push(hpriv, urb, pipe);
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
Expand Down Expand Up @@ -731,7 +749,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
struct device *dev = usbhs_priv_to_dev(priv);
struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
struct usb_host_endpoint *ep = urb->ep;
struct usbhsh_request *ureq;
struct usbhsh_device *udev, *new_udev = NULL;
struct usbhs_pipe *pipe;
struct usbhsh_ep *uep;
Expand Down Expand Up @@ -769,28 +786,16 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
}
pipe = usbhsh_uep_to_pipe(uep);

/*
* alloc new request
*/
ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
if (unlikely(!ureq)) {
ret = -ENOMEM;
goto usbhsh_urb_enqueue_error_free_endpoint;
}
usbhsh_urb_to_ureq(urb) = ureq;

/*
* push packet
*/
if (usb_pipecontrol(urb->pipe))
usbhsh_dcp_queue_push(hcd, hpriv, pipe, urb);
ret = usbhsh_dcp_queue_push(hcd, pipe, urb, mem_flags);
else
usbhsh_queue_push(hcd, pipe, urb);
ret = usbhsh_queue_push(hcd, pipe, urb, mem_flags);

return 0;
return ret;

usbhsh_urb_enqueue_error_free_endpoint:
usbhsh_endpoint_free(hpriv, ep);
usbhsh_urb_enqueue_error_free_device:
if (new_udev)
usbhsh_device_free(hpriv, new_udev);
Expand Down

0 comments on commit ae95278

Please sign in to comment.