linux-ti33x-psp 3.2: backport PM and USB fixes from PSP
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / psp / 0014-usb-musb-host-fix-for-urb-error-handling.patch
1 From 984969ee49797eadbfd4ca72f1d55c6ac52b4db6 Mon Sep 17 00:00:00 2001
2 From: Ajay Kumar Gupta <ajay.gupta@ti.com>
3 Date: Thu, 24 May 2012 15:56:37 +0530
4 Subject: [PATCH 14/18] usb: musb: host: fix for urb error handling
6 Fixes below two issues related urb error handling
8 1) Handling incomplete transfer when short packet not expected
10 2) Do not start next urb when current urb has failed, this is
11    because stack will unlink/dequeue remaining urbs. Programming
12    the next urb will endup in urb completion because of expected
13    error (cause of current urb failure) interrupts and interfere
14    with urb dequeue initiated by stack and cause a crash.
16 Signed-off-by: Ravi B <ravibabu@ti.com>
17 Signed-off-by: Visuvanadan Pasupathy <vichu@ti.com>
18 ---
19  drivers/usb/musb/musb_host.c |   24 +++++++++++++++++++++---
20  1 files changed, 21 insertions(+), 3 deletions(-)
22 diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
23 index 8981586..13520ee 100644
24 --- a/drivers/usb/musb/musb_host.c
25 +++ b/drivers/usb/musb/musb_host.c
26 @@ -481,7 +481,14 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
27                 }
28         }
29  
30 -       if (qh != NULL && qh->is_ready) {
31 +       /* we should not start next urb when current urb
32 +        * has failed, this is because stack will unlink/dequeue
33 +        * remaining urbs. Programming the next urb will endup in
34 +        * urb completion because of expected error (cause of current
35 +        * urb failure) interrupts and interfere with urb dequeue
36 +        * initiated by stack and cause a crash.
37 +        */
38 +       if (status == 0 && qh != NULL && qh->is_ready) {
39                 dev_dbg(musb->controller, "... next ep%d %cX urb %p\n",
40                     hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh));
41                 musb_start_urb(musb, is_in, qh);
42 @@ -1891,8 +1898,19 @@ finish:
43         urb->actual_length += xfer_len;
44         qh->offset += xfer_len;
45         if (done) {
46 -               if (urb->status == -EINPROGRESS)
47 -                       urb->status = status;
48 +               if (urb->status == -EINPROGRESS) {
49 +                       /* If short packet is not expected any transfer length
50 +                        * less than actual length is an error, hence
51 +                        * set urb status to -EREMOTEIO
52 +                        */
53 +                       if ((urb->status == -EINPROGRESS)
54 +                               && (urb->transfer_flags & URB_SHORT_NOT_OK)
55 +                               && (urb->actual_length
56 +                                       < urb->transfer_buffer_length))
57 +                               urb->status = -EREMOTEIO;
58 +                       else
59 +                               urb->status = status;
60 +               }
61                 musb_advance_schedule(musb, urb, hw_ep, USB_DIR_IN);
62         }
63  }
64 -- 
65 1.7.7.6