Commit e5b90898 authored by Aaro Koskinen's avatar Aaro Koskinen Committed by Greg Kroah-Hartman

staging: octeon-usb: use usb_hcd_link_urb_to_ep()

The driver did not use link_urb_to_ep() / unlink_urb_from_ep(). This
caused odd behaviour in some error recovery situations, all requests
would start to fail after the first failure.
Signed-off-by: default avatarAaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cdd15d89
...@@ -2230,6 +2230,7 @@ static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb, ...@@ -2230,6 +2230,7 @@ static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
urb->status = -EPROTO; urb->status = -EPROTO;
break; break;
} }
usb_hcd_unlink_urb_from_ep(octeon_to_hcd(priv), urb);
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status); usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
spin_lock(&priv->lock); spin_lock(&priv->lock);
...@@ -3291,10 +3292,17 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd, ...@@ -3291,10 +3292,17 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
unsigned long flags; unsigned long flags;
struct cvmx_usb_iso_packet *iso_packet; struct cvmx_usb_iso_packet *iso_packet;
struct usb_host_endpoint *ep = urb->ep; struct usb_host_endpoint *ep = urb->ep;
int rc;
urb->status = 0; urb->status = 0;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
rc = usb_hcd_link_urb_to_ep(hcd, urb);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
if (!ep->hcpriv) { if (!ep->hcpriv) {
enum cvmx_usb_transfer transfer_type; enum cvmx_usb_transfer transfer_type;
enum cvmx_usb_speed speed; enum cvmx_usb_speed speed;
...@@ -3370,6 +3378,7 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd, ...@@ -3370,6 +3378,7 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
>> 11) & 0x3, >> 11) & 0x3,
split_device, split_port); split_device, split_port);
if (!pipe) { if (!pipe) {
usb_hcd_unlink_urb_from_ep(hcd, urb);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(dev, "Failed to create pipe\n"); dev_dbg(dev, "Failed to create pipe\n");
return -ENOMEM; return -ENOMEM;
...@@ -3440,6 +3449,7 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd, ...@@ -3440,6 +3449,7 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
break; break;
} }
if (!transaction) { if (!transaction) {
usb_hcd_unlink_urb_from_ep(hcd, urb);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(dev, "Failed to submit\n"); dev_dbg(dev, "Failed to submit\n");
return -ENOMEM; return -ENOMEM;
...@@ -3455,18 +3465,24 @@ static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, ...@@ -3455,18 +3465,24 @@ static int octeon_usb_urb_dequeue(struct usb_hcd *hcd,
{ {
struct octeon_hcd *priv = hcd_to_octeon(hcd); struct octeon_hcd *priv = hcd_to_octeon(hcd);
unsigned long flags; unsigned long flags;
int rc;
if (!urb->dev) if (!urb->dev)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
rc = usb_hcd_check_unlink_urb(hcd, urb, status);
if (rc)
goto out;
urb->status = status; urb->status = status;
cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv); cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
out:
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
return 0; return rc;
} }
static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, static void octeon_usb_endpoint_disable(struct usb_hcd *hcd,
......
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