Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / usb / dvb-usb-v2 / usb_urb.c
1 /* usb-urb.c is part of the DVB USB library.
2  *
3  * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4  * see dvb-usb-init.c for copyright information.
5  *
6  * This file keeps functions for initializing and handling the
7  * BULK and ISOC USB data transfers in a generic way.
8  * Can be used for DVB-only and also, that's the plan, for
9  * Hybrid USB devices (analog and DVB).
10  */
11 #include "dvb_usb_common.h"
12
13 /* URB stuff for streaming */
14
15 int usb_urb_reconfig(struct usb_data_stream *stream,
16                 struct usb_data_stream_properties *props);
17
18 static void usb_urb_complete(struct urb *urb)
19 {
20         struct usb_data_stream *stream = urb->context;
21         int ptype = usb_pipetype(urb->pipe);
22         int i;
23         u8 *b;
24
25         dev_dbg_ratelimited(&stream->udev->dev,
26                         "%s: %s urb completed status=%d length=%d/%d pack_num=%d errors=%d\n",
27                         __func__, ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
28                         urb->status, urb->actual_length,
29                         urb->transfer_buffer_length,
30                         urb->number_of_packets, urb->error_count);
31
32         switch (urb->status) {
33         case 0:         /* success */
34         case -ETIMEDOUT:    /* NAK */
35                 break;
36         case -ECONNRESET:   /* kill */
37         case -ENOENT:
38         case -ESHUTDOWN:
39                 return;
40         default:        /* error */
41                 dev_dbg_ratelimited(&stream->udev->dev,
42                                 "%s: urb completition failed=%d\n",
43                                 __func__, urb->status);
44                 break;
45         }
46
47         b = (u8 *) urb->transfer_buffer;
48         switch (ptype) {
49         case PIPE_ISOCHRONOUS:
50                 for (i = 0; i < urb->number_of_packets; i++) {
51                         if (urb->iso_frame_desc[i].status != 0)
52                                 dev_dbg(&stream->udev->dev,
53                                                 "%s: iso frame descriptor has an error=%d\n",
54                                                 __func__,
55                                                 urb->iso_frame_desc[i].status);
56                         else if (urb->iso_frame_desc[i].actual_length > 0)
57                                 stream->complete(stream,
58                                         b + urb->iso_frame_desc[i].offset,
59                                         urb->iso_frame_desc[i].actual_length);
60
61                         urb->iso_frame_desc[i].status = 0;
62                         urb->iso_frame_desc[i].actual_length = 0;
63                 }
64                 break;
65         case PIPE_BULK:
66                 if (urb->actual_length > 0)
67                         stream->complete(stream, b, urb->actual_length);
68                 break;
69         default:
70                 dev_err(&stream->udev->dev,
71                                 "%s: unknown endpoint type in completition handler\n",
72                                 KBUILD_MODNAME);
73                 return;
74         }
75         usb_submit_urb(urb, GFP_ATOMIC);
76 }
77
78 int usb_urb_killv2(struct usb_data_stream *stream)
79 {
80         int i;
81         for (i = 0; i < stream->urbs_submitted; i++) {
82                 dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
83                 /* stop the URB */
84                 usb_kill_urb(stream->urb_list[i]);
85         }
86         stream->urbs_submitted = 0;
87         return 0;
88 }
89
90 int usb_urb_submitv2(struct usb_data_stream *stream,
91                 struct usb_data_stream_properties *props)
92 {
93         int i, ret;
94
95         if (props) {
96                 ret = usb_urb_reconfig(stream, props);
97                 if (ret < 0)
98                         return ret;
99         }
100
101         for (i = 0; i < stream->urbs_initialized; i++) {
102                 dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
103                 ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
104                 if (ret) {
105                         dev_err(&stream->udev->dev,
106                                         "%s: could not submit urb no. %d - get them all back\n",
107                                         KBUILD_MODNAME, i);
108                         usb_urb_killv2(stream);
109                         return ret;
110                 }
111                 stream->urbs_submitted++;
112         }
113         return 0;
114 }
115
116 static int usb_urb_free_urbs(struct usb_data_stream *stream)
117 {
118         int i;
119
120         usb_urb_killv2(stream);
121
122         for (i = stream->urbs_initialized - 1; i >= 0; i--) {
123                 if (stream->urb_list[i]) {
124                         dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
125                                         __func__, i);
126                         /* free the URBs */
127                         usb_free_urb(stream->urb_list[i]);
128                 }
129         }
130         stream->urbs_initialized = 0;
131
132         return 0;
133 }
134
135 static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
136 {
137         int i, j;
138
139         /* allocate the URBs */
140         for (i = 0; i < stream->props.count; i++) {
141                 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
142                 stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
143                 if (!stream->urb_list[i]) {
144                         dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
145                         for (j = 0; j < i; j++)
146                                 usb_free_urb(stream->urb_list[j]);
147                         return -ENOMEM;
148                 }
149                 usb_fill_bulk_urb(stream->urb_list[i],
150                                 stream->udev,
151                                 usb_rcvbulkpipe(stream->udev,
152                                                 stream->props.endpoint),
153                                 stream->buf_list[i],
154                                 stream->props.u.bulk.buffersize,
155                                 usb_urb_complete, stream);
156
157                 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
158                 stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
159                 stream->urbs_initialized++;
160         }
161         return 0;
162 }
163
164 static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
165 {
166         int i, j;
167
168         /* allocate the URBs */
169         for (i = 0; i < stream->props.count; i++) {
170                 struct urb *urb;
171                 int frame_offset = 0;
172                 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
173                 stream->urb_list[i] = usb_alloc_urb(
174                                 stream->props.u.isoc.framesperurb, GFP_ATOMIC);
175                 if (!stream->urb_list[i]) {
176                         dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
177                         for (j = 0; j < i; j++)
178                                 usb_free_urb(stream->urb_list[j]);
179                         return -ENOMEM;
180                 }
181
182                 urb = stream->urb_list[i];
183
184                 urb->dev = stream->udev;
185                 urb->context = stream;
186                 urb->complete = usb_urb_complete;
187                 urb->pipe = usb_rcvisocpipe(stream->udev,
188                                 stream->props.endpoint);
189                 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
190                 urb->interval = stream->props.u.isoc.interval;
191                 urb->number_of_packets = stream->props.u.isoc.framesperurb;
192                 urb->transfer_buffer_length = stream->props.u.isoc.framesize *
193                                 stream->props.u.isoc.framesperurb;
194                 urb->transfer_buffer = stream->buf_list[i];
195                 urb->transfer_dma = stream->dma_addr[i];
196
197                 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
198                         urb->iso_frame_desc[j].offset = frame_offset;
199                         urb->iso_frame_desc[j].length =
200                                         stream->props.u.isoc.framesize;
201                         frame_offset += stream->props.u.isoc.framesize;
202                 }
203
204                 stream->urbs_initialized++;
205         }
206         return 0;
207 }
208
209 static int usb_free_stream_buffers(struct usb_data_stream *stream)
210 {
211         if (stream->state & USB_STATE_URB_BUF) {
212                 while (stream->buf_num) {
213                         stream->buf_num--;
214                         dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
215                                 __func__, stream->buf_num);
216                         usb_free_coherent(stream->udev, stream->buf_size,
217                                           stream->buf_list[stream->buf_num],
218                                           stream->dma_addr[stream->buf_num]);
219                 }
220         }
221
222         stream->state &= ~USB_STATE_URB_BUF;
223
224         return 0;
225 }
226
227 static int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
228                                     unsigned long size)
229 {
230         stream->buf_num = 0;
231         stream->buf_size = size;
232
233         dev_dbg(&stream->udev->dev,
234                         "%s: all in all I will use %lu bytes for streaming\n",
235                         __func__,  num * size);
236
237         for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
238                 stream->buf_list[stream->buf_num] = usb_alloc_coherent(
239                                 stream->udev, size, GFP_ATOMIC,
240                                 &stream->dma_addr[stream->buf_num]);
241                 if (!stream->buf_list[stream->buf_num]) {
242                         dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
243                                         __func__, stream->buf_num);
244                         usb_free_stream_buffers(stream);
245                         return -ENOMEM;
246                 }
247
248                 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
249                                 __func__, stream->buf_num,
250                                 stream->buf_list[stream->buf_num],
251                                 (long long)stream->dma_addr[stream->buf_num]);
252                 memset(stream->buf_list[stream->buf_num], 0, size);
253                 stream->state |= USB_STATE_URB_BUF;
254         }
255
256         return 0;
257 }
258
259 int usb_urb_reconfig(struct usb_data_stream *stream,
260                 struct usb_data_stream_properties *props)
261 {
262         int buf_size;
263
264         if (!props)
265                 return 0;
266
267         /* check allocated buffers are large enough for the request */
268         if (props->type == USB_BULK) {
269                 buf_size = stream->props.u.bulk.buffersize;
270         } else if (props->type == USB_ISOC) {
271                 buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
272         } else {
273                 dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
274                                 KBUILD_MODNAME, props->type);
275                 return -EINVAL;
276         }
277
278         if (stream->buf_num < props->count || stream->buf_size < buf_size) {
279                 dev_err(&stream->udev->dev,
280                                 "%s: cannot reconfigure as allocated buffers are too small\n",
281                                 KBUILD_MODNAME);
282                 return -EINVAL;
283         }
284
285         /* check if all fields are same */
286         if (stream->props.type == props->type &&
287                         stream->props.count == props->count &&
288                         stream->props.endpoint == props->endpoint) {
289                 if (props->type == USB_BULK &&
290                                 props->u.bulk.buffersize ==
291                                 stream->props.u.bulk.buffersize)
292                         return 0;
293                 else if (props->type == USB_ISOC &&
294                                 props->u.isoc.framesperurb ==
295                                 stream->props.u.isoc.framesperurb &&
296                                 props->u.isoc.framesize ==
297                                 stream->props.u.isoc.framesize &&
298                                 props->u.isoc.interval ==
299                                 stream->props.u.isoc.interval)
300                         return 0;
301         }
302
303         dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
304
305         usb_urb_free_urbs(stream);
306         memcpy(&stream->props, props, sizeof(*props));
307         if (props->type == USB_BULK)
308                 return usb_urb_alloc_bulk_urbs(stream);
309         else if (props->type == USB_ISOC)
310                 return usb_urb_alloc_isoc_urbs(stream);
311
312         return 0;
313 }
314
315 int usb_urb_initv2(struct usb_data_stream *stream,
316                 const struct usb_data_stream_properties *props)
317 {
318         int ret;
319
320         if (!stream || !props)
321                 return -EINVAL;
322
323         memcpy(&stream->props, props, sizeof(*props));
324
325         if (!stream->complete) {
326                 dev_err(&stream->udev->dev,
327                                 "%s: there is no data callback - this doesn't make sense\n",
328                                 KBUILD_MODNAME);
329                 return -EINVAL;
330         }
331
332         switch (stream->props.type) {
333         case USB_BULK:
334                 ret = usb_alloc_stream_buffers(stream, stream->props.count,
335                                 stream->props.u.bulk.buffersize);
336                 if (ret < 0)
337                         return ret;
338
339                 return usb_urb_alloc_bulk_urbs(stream);
340         case USB_ISOC:
341                 ret = usb_alloc_stream_buffers(stream, stream->props.count,
342                                 stream->props.u.isoc.framesize *
343                                 stream->props.u.isoc.framesperurb);
344                 if (ret < 0)
345                         return ret;
346
347                 return usb_urb_alloc_isoc_urbs(stream);
348         default:
349                 dev_err(&stream->udev->dev,
350                                 "%s: unknown urb-type for data transfer\n",
351                                 KBUILD_MODNAME);
352                 return -EINVAL;
353         }
354 }
355
356 int usb_urb_exitv2(struct usb_data_stream *stream)
357 {
358         usb_urb_free_urbs(stream);
359         usb_free_stream_buffers(stream);
360
361         return 0;
362 }