1 /* usb-urb.c is part of the DVB USB library.
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
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).
11 #include "dvb_usb_common.h"
13 /* URB stuff for streaming */
15 int usb_urb_reconfig(struct usb_data_stream
*stream
,
16 struct usb_data_stream_properties
*props
);
18 static void usb_urb_complete(struct urb
*urb
)
20 struct usb_data_stream
*stream
= urb
->context
;
21 int ptype
= usb_pipetype(urb
->pipe
);
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
);
32 switch (urb
->status
) {
34 case -ETIMEDOUT
: /* NAK */
36 case -ECONNRESET
: /* kill */
41 dev_dbg_ratelimited(&stream
->udev
->dev
,
42 "%s: urb completition failed=%d\n",
43 __func__
, urb
->status
);
47 b
= (u8
*) urb
->transfer_buffer
;
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",
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
);
61 urb
->iso_frame_desc
[i
].status
= 0;
62 urb
->iso_frame_desc
[i
].actual_length
= 0;
66 if (urb
->actual_length
> 0)
67 stream
->complete(stream
, b
, urb
->actual_length
);
70 dev_err(&stream
->udev
->dev
,
71 "%s: unknown endpoint type in completition handler\n",
75 usb_submit_urb(urb
, GFP_ATOMIC
);
78 int usb_urb_killv2(struct usb_data_stream
*stream
)
81 for (i
= 0; i
< stream
->urbs_submitted
; i
++) {
82 dev_dbg(&stream
->udev
->dev
, "%s: kill urb=%d\n", __func__
, i
);
84 usb_kill_urb(stream
->urb_list
[i
]);
86 stream
->urbs_submitted
= 0;
90 int usb_urb_submitv2(struct usb_data_stream
*stream
,
91 struct usb_data_stream_properties
*props
)
96 ret
= usb_urb_reconfig(stream
, props
);
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
);
105 dev_err(&stream
->udev
->dev
,
106 "%s: could not submit urb no. %d - get them all back\n",
108 usb_urb_killv2(stream
);
111 stream
->urbs_submitted
++;
116 static int usb_urb_free_urbs(struct usb_data_stream
*stream
)
120 usb_urb_killv2(stream
);
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",
127 usb_free_urb(stream
->urb_list
[i
]);
130 stream
->urbs_initialized
= 0;
135 static int usb_urb_alloc_bulk_urbs(struct usb_data_stream
*stream
)
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
]);
149 usb_fill_bulk_urb(stream
->urb_list
[i
],
151 usb_rcvbulkpipe(stream
->udev
,
152 stream
->props
.endpoint
),
154 stream
->props
.u
.bulk
.buffersize
,
155 usb_urb_complete
, stream
);
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
++;
164 static int usb_urb_alloc_isoc_urbs(struct usb_data_stream
*stream
)
168 /* allocate the URBs */
169 for (i
= 0; i
< stream
->props
.count
; i
++) {
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
]);
182 urb
= stream
->urb_list
[i
];
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
];
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
;
204 stream
->urbs_initialized
++;
209 static int usb_free_stream_buffers(struct usb_data_stream
*stream
)
211 if (stream
->state
& USB_STATE_URB_BUF
) {
212 while (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
]);
222 stream
->state
&= ~USB_STATE_URB_BUF
;
227 static int usb_alloc_stream_buffers(struct usb_data_stream
*stream
, int num
,
231 stream
->buf_size
= size
;
233 dev_dbg(&stream
->udev
->dev
,
234 "%s: all in all I will use %lu bytes for streaming\n",
235 __func__
, num
* size
);
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
);
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
;
259 int usb_urb_reconfig(struct usb_data_stream
*stream
,
260 struct usb_data_stream_properties
*props
)
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
;
273 dev_err(&stream
->udev
->dev
, "%s: invalid endpoint type=%d\n",
274 KBUILD_MODNAME
, props
->type
);
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",
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
)
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
)
303 dev_dbg(&stream
->udev
->dev
, "%s: re-alloc urbs\n", __func__
);
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
);
315 int usb_urb_initv2(struct usb_data_stream
*stream
,
316 const struct usb_data_stream_properties
*props
)
320 if (!stream
|| !props
)
323 memcpy(&stream
->props
, props
, sizeof(*props
));
325 if (!stream
->complete
) {
326 dev_err(&stream
->udev
->dev
,
327 "%s: there is no data callback - this doesn't make sense\n",
332 switch (stream
->props
.type
) {
334 ret
= usb_alloc_stream_buffers(stream
, stream
->props
.count
,
335 stream
->props
.u
.bulk
.buffersize
);
339 return usb_urb_alloc_bulk_urbs(stream
);
341 ret
= usb_alloc_stream_buffers(stream
, stream
->props
.count
,
342 stream
->props
.u
.isoc
.framesize
*
343 stream
->props
.u
.isoc
.framesperurb
);
347 return usb_urb_alloc_isoc_urbs(stream
);
349 dev_err(&stream
->udev
->dev
,
350 "%s: unknown urb-type for data transfer\n",
356 int usb_urb_exitv2(struct usb_data_stream
*stream
)
358 usb_urb_free_urbs(stream
);
359 usb_free_stream_buffers(stream
);