Commit ee8a0bf5 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Felipe Balbi

usb: gadget: renesas_usbhs: cleanup complicated ureq alloc/free

DCP data/status stage needs ureq to usbhs_pkt_push(),
but sometimes, there is no data stage.
In that case, allocated ureq was not freed,
Current ureq alloc/free pair were difficult to understand.
This patch removed unnecessary/un-understandable ureq alloc
from usbhsh_urb_enqueue(), and create simpler alloc/free pair.
Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 1ab6f257
...@@ -503,11 +503,12 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) ...@@ -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, static int usbhsh_queue_push(struct usb_hcd *hcd,
struct usbhs_pipe *pipe, struct usbhs_pipe *pipe,
struct urb *urb) struct urb *urb,
gfp_t mem_flags)
{ {
struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd);
struct usbhs_pkt *pkt = &ureq->pkt;
struct device *dev = usbhsh_hcd_to_dev(hcd); struct device *dev = usbhsh_hcd_to_dev(hcd);
struct usbhsh_request *ureq;
void *buf; void *buf;
int len; int len;
...@@ -516,6 +517,14 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, ...@@ -516,6 +517,14 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
return -EIO; 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)) if (usb_pipein(urb->pipe))
pipe->handler = &usbhs_fifo_pio_pop_handler; pipe->handler = &usbhs_fifo_pio_pop_handler;
else else
...@@ -525,7 +534,7 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, ...@@ -525,7 +534,7 @@ static int usbhsh_queue_push(struct usb_hcd *hcd,
len = urb->transfer_buffer_length - urb->actual_length; len = urb->transfer_buffer_length - urb->actual_length;
dev_dbg(dev, "%s\n", __func__); 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)); buf, len, (urb->transfer_flags & URB_ZERO_PACKET));
usbhs_pkt_start(pipe); usbhs_pkt_start(pipe);
...@@ -605,72 +614,72 @@ static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, ...@@ -605,72 +614,72 @@ static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv,
usbhsh_urb_to_ureq(urb) = NULL; usbhsh_urb_to_ureq(urb) = NULL;
} }
static void usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv,
struct urb *urb, struct urb *urb,
struct usbhs_pipe *pipe) struct usbhs_pipe *pipe,
gfp_t mem_flags)
{ {
struct usbhsh_request *ureq; struct usbhsh_request *ureq;
struct usbhs_pkt *pkt;
/* /* this ureq will be freed on usbhsh_data_stage_packet_done() */
* FIXME ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
* if (unlikely(!ureq))
* data stage uses ureq which is connected to urb return -ENOMEM;
* see usbhsh_urb_enqueue() :: alloc new request. usbhsh_urb_to_ureq(urb) = ureq;
* it will be freed in usbhsh_data_stage_packet_done()
*/
ureq = usbhsh_urb_to_ureq(urb);
pkt = &ureq->pkt;
if (usb_pipein(urb->pipe)) if (usb_pipein(urb->pipe))
pipe->handler = &usbhs_dcp_data_stage_in_handler; pipe->handler = &usbhs_dcp_data_stage_in_handler;
else else
pipe->handler = &usbhs_dcp_data_stage_out_handler; pipe->handler = &usbhs_dcp_data_stage_out_handler;
usbhs_pkt_push(pipe, pkt, usbhs_pkt_push(pipe, &ureq->pkt,
usbhsh_data_stage_packet_done, usbhsh_data_stage_packet_done,
urb->transfer_buffer, urb->transfer_buffer,
urb->transfer_buffer_length, urb->transfer_buffer_length,
(urb->transfer_flags & URB_ZERO_PACKET)); (urb->transfer_flags & URB_ZERO_PACKET));
return 0;
} }
/* /*
* DCP status stage * 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 urb *urb,
struct usbhs_pipe *pipe) struct usbhs_pipe *pipe,
gfp_t mem_flags)
{ {
struct usbhsh_request *ureq; struct usbhsh_request *ureq;
struct usbhs_pkt *pkt;
/* /* This ureq will be freed on usbhsh_queue_done() */
* FIXME ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags);
* if (unlikely(!ureq))
* status stage uses allocated ureq. return -ENOMEM;
* it will be freed on usbhsh_queue_done() usbhsh_urb_to_ureq(urb) = ureq;
*/
ureq = usbhsh_ureq_alloc(hpriv, urb, GFP_KERNEL);
pkt = &ureq->pkt;
if (usb_pipein(urb->pipe)) if (usb_pipein(urb->pipe))
pipe->handler = &usbhs_dcp_status_stage_in_handler; pipe->handler = &usbhs_dcp_status_stage_in_handler;
else else
pipe->handler = &usbhs_dcp_status_stage_out_handler; pipe->handler = &usbhs_dcp_status_stage_out_handler;
usbhs_pkt_push(pipe, pkt, usbhs_pkt_push(pipe, &ureq->pkt,
usbhsh_queue_done, usbhsh_queue_done,
NULL, NULL,
urb->transfer_buffer_length, urb->transfer_buffer_length,
0); 0);
return 0;
} }
static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
struct usbhsh_hpriv *hpriv,
struct usbhs_pipe *pipe, 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); struct device *dev = usbhsh_hcd_to_dev(hcd);
int ret;
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
...@@ -686,13 +695,22 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, ...@@ -686,13 +695,22 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
* *
* It is pushed only when urb has buffer. * It is pushed only when urb has buffer.
*/ */
if (urb->transfer_buffer_length) if (urb->transfer_buffer_length) {
usbhsh_data_stage_packet_push(hpriv, urb, pipe); ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags);
if (ret < 0) {
dev_err(dev, "data stage failed\n");
return ret;
}
}
/* /*
* status stage * 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 * start pushed packets
...@@ -731,7 +749,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, ...@@ -731,7 +749,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
struct device *dev = usbhs_priv_to_dev(priv); struct device *dev = usbhs_priv_to_dev(priv);
struct usb_device *usbv = usbhsh_urb_to_usbv(urb); struct usb_device *usbv = usbhsh_urb_to_usbv(urb);
struct usb_host_endpoint *ep = urb->ep; struct usb_host_endpoint *ep = urb->ep;
struct usbhsh_request *ureq;
struct usbhsh_device *udev, *new_udev = NULL; struct usbhsh_device *udev, *new_udev = NULL;
struct usbhs_pipe *pipe; struct usbhs_pipe *pipe;
struct usbhsh_ep *uep; struct usbhsh_ep *uep;
...@@ -769,28 +786,16 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, ...@@ -769,28 +786,16 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
} }
pipe = usbhsh_uep_to_pipe(uep); 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 * push packet
*/ */
if (usb_pipecontrol(urb->pipe)) if (usb_pipecontrol(urb->pipe))
usbhsh_dcp_queue_push(hcd, hpriv, pipe, urb); ret = usbhsh_dcp_queue_push(hcd, pipe, urb, mem_flags);
else 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: usbhsh_urb_enqueue_error_free_device:
if (new_udev) if (new_udev)
usbhsh_device_free(hpriv, new_udev); usbhsh_device_free(hpriv, new_udev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment