mirror of https://gitee.com/openkylin/linux.git
usb: gadget: renesas_usbhs: bugfix: care pipe direction
renesas_usbhs is caring pipe type and its direction. but current usbhs_endpoint_alloc() didn't check direction. this patch modify it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
4703d2e9d0
commit
73ef635a07
|
@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv,
|
||||||
struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
||||||
struct usbhsh_device *udev,
|
struct usbhsh_device *udev,
|
||||||
struct usb_host_endpoint *ep,
|
struct usb_host_endpoint *ep,
|
||||||
|
int dir_in_req,
|
||||||
gfp_t mem_flags)
|
gfp_t mem_flags)
|
||||||
{
|
{
|
||||||
struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
|
struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
|
||||||
|
@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
||||||
struct usbhs_pipe *pipe, *best_pipe;
|
struct usbhs_pipe *pipe, *best_pipe;
|
||||||
struct device *dev = usbhsh_hcd_to_dev(hcd);
|
struct device *dev = usbhsh_hcd_to_dev(hcd);
|
||||||
struct usb_endpoint_descriptor *desc = &ep->desc;
|
struct usb_endpoint_descriptor *desc = &ep->desc;
|
||||||
int type, i;
|
int type, i, dir_in;
|
||||||
unsigned int min_usr;
|
unsigned int min_usr;
|
||||||
|
|
||||||
|
dir_in_req = !!dir_in_req;
|
||||||
|
|
||||||
uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
|
uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
|
||||||
if (!uep) {
|
if (!uep) {
|
||||||
dev_err(dev, "usbhsh_ep alloc fail\n");
|
dev_err(dev, "usbhsh_ep alloc fail\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
type = usb_endpoint_type(desc);
|
|
||||||
|
if (usb_endpoint_xfer_control(desc)) {
|
||||||
|
best_pipe = usbhsh_hpriv_to_dcp(hpriv);
|
||||||
|
goto usbhsh_endpoint_alloc_find_pipe;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find best pipe for endpoint
|
* find best pipe for endpoint
|
||||||
* see
|
* see
|
||||||
* HARDWARE LIMITATION
|
* HARDWARE LIMITATION
|
||||||
*/
|
*/
|
||||||
|
type = usb_endpoint_type(desc);
|
||||||
min_usr = ~0;
|
min_usr = ~0;
|
||||||
best_pipe = NULL;
|
best_pipe = NULL;
|
||||||
usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
|
usbhs_for_each_pipe(pipe, priv, i) {
|
||||||
if (!usbhs_pipe_type_is(pipe, type))
|
if (!usbhs_pipe_type_is(pipe, type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
dir_in = !!usbhs_pipe_is_dir_in(pipe);
|
||||||
|
if (0 != (dir_in - dir_in_req))
|
||||||
|
continue;
|
||||||
|
|
||||||
info = usbhsh_pipe_info(pipe);
|
info = usbhsh_pipe_info(pipe);
|
||||||
|
|
||||||
if (min_usr > info->usr_cnt) {
|
if (min_usr > info->usr_cnt) {
|
||||||
|
@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
||||||
kfree(uep);
|
kfree(uep);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
usbhsh_endpoint_alloc_find_pipe:
|
||||||
/*
|
/*
|
||||||
* init uep
|
* init uep
|
||||||
*/
|
*/
|
||||||
|
@ -430,7 +442,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
||||||
|
|
||||||
dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
|
dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
|
||||||
usbhsh_device_number(hpriv, udev),
|
usbhsh_device_number(hpriv, udev),
|
||||||
usbhs_pipe_name(pipe), uep);
|
usbhs_pipe_name(uep->pipe), uep);
|
||||||
|
|
||||||
return uep;
|
return uep;
|
||||||
}
|
}
|
||||||
|
@ -722,11 +734,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
|
||||||
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;
|
||||||
|
int is_dir_in = usb_pipein(urb->pipe);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dev_dbg(dev, "%s (%s)\n",
|
dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
|
||||||
__func__, usb_pipein(urb->pipe) ? "in" : "out");
|
|
||||||
|
|
||||||
ret = usb_hcd_link_urb_to_ep(hcd, urb);
|
ret = usb_hcd_link_urb_to_ep(hcd, urb);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -749,7 +761,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
|
||||||
*/
|
*/
|
||||||
uep = usbhsh_ep_to_uep(ep);
|
uep = usbhsh_ep_to_uep(ep);
|
||||||
if (!uep) {
|
if (!uep) {
|
||||||
uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags);
|
uep = usbhsh_endpoint_alloc(hpriv, udev, ep,
|
||||||
|
is_dir_in, mem_flags);
|
||||||
if (!uep)
|
if (!uep)
|
||||||
goto usbhsh_urb_enqueue_error_free_device;
|
goto usbhsh_urb_enqueue_error_free_device;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue