It is possible to judge whether renesas_usbhs driver is running, by checking attch irq mask. This patch adds usbhsh_is_running() to check it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx> --- drivers/usb/renesas_usbhs/mod_host.c | 38 +++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index a970653..85db7b0 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -191,6 +191,21 @@ static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, } /* + * status + */ +static int usbhsh_is_running(struct usbhsh_hpriv *hpriv) +{ + /* + * we can decide some device is attached or not + * by checking mod.irq_attch + * see + * usbhsh_irq_attch() + * usbhsh_irq_dtch() + */ + return (hpriv->mod.irq_attch == NULL); +} + +/* * pipe control */ static void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv, @@ -620,6 +635,7 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) struct urb *urb = ureq->urb; struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); struct device *dev = usbhs_priv_to_dev(priv); + int status = 0; dev_dbg(dev, "%s\n", __func__); @@ -628,6 +644,9 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) return; } + if (!usbhsh_is_running(hpriv)) + status = -ESHUTDOWN; + urb->actual_length = pkt->actual; usbhsh_ureq_free(hpriv, ureq); @@ -635,7 +654,7 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) usbhsh_pipe_detach(hpriv, uep); usb_hcd_unlink_urb_from_ep(hcd, urb); - usb_hcd_giveback_urb(hcd, urb, 0); + usb_hcd_giveback_urb(hcd, urb, status); } static int usbhsh_queue_push(struct usb_hcd *hcd, @@ -900,6 +919,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); + if (!usbhsh_is_running(hpriv)) { + ret = -EIO; + goto usbhsh_urb_enqueue_error_not_linked; + } + ret = usb_hcd_link_urb_to_ep(hcd, urb); if (ret) goto usbhsh_urb_enqueue_error_not_linked; @@ -1252,6 +1276,12 @@ static int usbhsh_irq_attch(struct usbhs_priv *priv, * attch interrupt might happen infinitely on some device * (on self power USB hub ?) * disable it here. + * + * usbhsh_is_running() becomes effective + * according to this process. + * see + * usbhsh_is_running() + * usbhsh_urb_enqueue() */ hpriv->mod.irq_attch = NULL; usbhs_irq_callback_update(priv, &hpriv->mod); @@ -1272,6 +1302,12 @@ static int usbhsh_irq_dtch(struct usbhs_priv *priv, /* * enable attch interrupt again + * + * usbhsh_is_running() becomes invalid + * according to this process. + * see + * usbhsh_is_running() + * usbhsh_urb_enqueue() */ hpriv->mod.irq_attch = usbhsh_irq_attch; usbhs_irq_callback_update(priv, &hpriv->mod); -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html