mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
usb: ohci: Do not resubmit and leak urbs for interrupt packets
The u-boot usb code uses polling for all endpoints, including interrupt endpoints, so urbs should never be automatically resubmitted. This also fixes a leak of the urb, as submit_int_msg() did not check if an already re-submitted urb exists before creating a new one. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
e253637be7
commit
47976d2c16
1 changed files with 2 additions and 39 deletions
|
@ -587,40 +587,6 @@ int sohci_submit_job(ohci_t *ohci, ohci_dev_t *ohci_dev, urb_priv_t *urb,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)
|
|
||||||
{
|
|
||||||
struct ohci_regs *regs = hc->regs;
|
|
||||||
|
|
||||||
switch (usb_pipetype(urb->pipe)) {
|
|
||||||
case PIPE_INTERRUPT:
|
|
||||||
/* implicitly requeued */
|
|
||||||
if (urb->dev->irq_handle &&
|
|
||||||
(urb->dev->irq_act_len = urb->actual_length)) {
|
|
||||||
ohci_writel(OHCI_INTR_WDH, ®s->intrenable);
|
|
||||||
ohci_readl(®s->intrenable); /* PCI posting flush */
|
|
||||||
urb->dev->irq_handle(urb->dev);
|
|
||||||
ohci_writel(OHCI_INTR_WDH, ®s->intrdisable);
|
|
||||||
ohci_readl(®s->intrdisable); /* PCI posting flush */
|
|
||||||
}
|
|
||||||
urb->actual_length = 0;
|
|
||||||
td_submit_job( hc,
|
|
||||||
urb->dev,
|
|
||||||
urb->pipe,
|
|
||||||
urb->transfer_buffer,
|
|
||||||
urb->transfer_buffer_length,
|
|
||||||
NULL,
|
|
||||||
urb,
|
|
||||||
urb->interval);
|
|
||||||
break;
|
|
||||||
case PIPE_CONTROL:
|
|
||||||
case PIPE_BULK:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -1153,7 +1119,7 @@ static td_t *dl_reverse_done_list(ohci_t *ohci)
|
||||||
static void finish_urb(ohci_t *ohci, urb_priv_t *urb, int status)
|
static void finish_urb(ohci_t *ohci, urb_priv_t *urb, int status)
|
||||||
{
|
{
|
||||||
if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL))
|
if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL))
|
||||||
urb->finished = sohci_return_job(ohci, urb);
|
urb->finished = 1;
|
||||||
else
|
else
|
||||||
dbg("finish_urb: strange.., ED state %x, \n", status);
|
dbg("finish_urb: strange.., ED state %x, \n", status);
|
||||||
}
|
}
|
||||||
|
@ -1593,9 +1559,6 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,
|
||||||
#else
|
#else
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* free TDs in urb_priv */
|
|
||||||
if (!usb_pipeint(pipe))
|
|
||||||
urb_free_priv(urb);
|
urb_free_priv(urb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue