56fc827a5dda2b55b2bc52e83387f75360bf8e2f
[openpandora.oe.git] / recipes / linux / omap3-pandora-kernel-wifi / musb-dma-iso-in.eml
1 Fixes blurred capture images in dma mode. Isochronous error field in
2 urb and source data buffer pointer were not updated properly in dma
3 mode.
4
5 Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
6 ---
7 diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
8 index 08e421f..a481d54 100644
9 --- a/drivers/usb/musb/musb_host.c
10 +++ b/drivers/usb/musb/musb_host.c
11 @@ -1505,10 +1505,29 @@ void musb_host_rx(struct musb *musb, u8 epnum)
12                 musb_writew(hw_ep->regs, MUSB_RXCSR, val);
13  
14  #ifdef CONFIG_USB_INVENTRA_DMA
15 +               if (usb_pipeisoc(pipe)) {
16 +                       struct usb_iso_packet_descriptor *d;
17 +
18 +                       d = urb->iso_frame_desc + qh->iso_idx;
19 +                       d->actual_length = xfer_len;
20 +
21 +                       /* even if there was an error, we did the dma
22 +                        * for iso_frame_desc->length
23 +                        */
24 +                       if (d->status != EILSEQ && d->status != -EOVERFLOW)
25 +                               d->status = 0;
26 +
27 +                       if (++qh->iso_idx >= urb->number_of_packets)
28 +                               done = true;
29 +                       else
30 +                               done = false;
31 +
32 +               } else  {
33                 /* done if urb buffer is full or short packet is recd */
34                 done = (urb->actual_length + xfer_len >=
35                                 urb->transfer_buffer_length
36                         || dma->actual_len < qh->maxpacket);
37 +               }
38  
39                 /* send IN token for next packet, without AUTOREQ */
40                 if (!done) {
41 @@ -1545,7 +1564,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
42                 if (dma) {
43                         struct dma_controller   *c;
44                         u16                     rx_count;
45 -                       int                     ret;
46 +                       int                     ret, length;
47 +                       dma_addr_t              buf;
48  
49                         rx_count = musb_readw(epio, MUSB_RXCOUNT);
50  
51 @@ -1558,6 +1578,35 @@ void musb_host_rx(struct musb *musb, u8 epnum)
52  
53                         c = musb->dma_controller;
54  
55 +                       if (usb_pipeisoc(pipe)) {
56 +                               int status = 0;
57 +                               struct usb_iso_packet_descriptor *d;
58 +
59 +                               d = urb->iso_frame_desc + qh->iso_idx;
60 +
61 +                               if (iso_err) {
62 +                                       status = -EILSEQ;
63 +                                       urb->error_count++;
64 +                               }
65 +                               if (rx_count > d->length) {
66 +                                       if (status == 0) {
67 +                                               status = -EOVERFLOW;
68 +                                               urb->error_count++;
69 +                                       }
70 +                                       DBG(2, "** OVERFLOW %d into %d\n",\
71 +                                           rx_count, d->length);
72 +
73 +                                       length = d->length;
74 +                               } else
75 +                                       length = rx_count;
76 +                               d->status = status;
77 +                               buf = urb->transfer_dma + d->offset;
78 +                       } else {
79 +                               length = rx_count;
80 +                               buf = urb->transfer_dma +
81 +                                               urb->actual_length;
82 +                       }
83 +
84                         dma->desired_mode = 0;
85  #ifdef USE_MODE1
86                         /* because of the issue below, mode 1 will
87 @@ -1569,6 +1618,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
88                                                 urb->actual_length)
89                                         > qh->maxpacket)
90                                 dma->desired_mode = 1;
91 +                       if (rx_count < hw_ep->max_packet_sz_rx) {
92 +                               length = rx_count;
93 +                               dma->bDesiredMode = 0;
94 +                       } else {
95 +                               length = urb->transfer_buffer_length;
96 +                       }
97  #endif
98  
99  /* Disadvantage of using mode 1:
100 @@ -1606,12 +1661,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
101                          */
102                         ret = c->channel_program(
103                                 dma, qh->maxpacket,
104 -                               dma->desired_mode,
105 -                               urb->transfer_dma
106 -                                       + urb->actual_length,
107 -                               (dma->desired_mode == 0)
108 -                                       ? rx_count
109 -                                       : urb->transfer_buffer_length);
110 +                               dma->desired_mode, buf, length);
111  
112                         if (!ret) {
113                                 c->channel_release(dma);
114 @@ -1628,19 +1678,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
115                 }
116         }
117  
118 -       if (dma && usb_pipeisoc(pipe)) {
119 -               struct usb_iso_packet_descriptor        *d;
120 -               int                                     iso_stat = status;
121 -
122 -               d = urb->iso_frame_desc + qh->iso_idx;
123 -               d->actual_length += xfer_len;
124 -               if (iso_err) {
125 -                       iso_stat = -EILSEQ;
126 -                       urb->error_count++;
127 -               }
128 -               d->status = iso_stat;
129 -       }
130 -
131  finish:
132         urb->actual_length += xfer_len;
133         qh->offset += xfer_len;
134 --
135 To unsubscribe from this list: send the line "unsubscribe linux-omap" in
136 the body of a message to majordomo@vger.kernel.org
137 More majordomo info at  http://vger.kernel.org/majordomo-info.html
138