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, "%s: %s urb completed " \ 26 "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, "%s: iso frame " \ 53 "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, "%s: unknown endpoint type in " \ 71 "completition handler\n", KBUILD_MODNAME); 72 return; 73 } 74 usb_submit_urb(urb, GFP_ATOMIC); 75 } 76 77 int usb_urb_killv2(struct usb_data_stream *stream) 78 { 79 int i; 80 for (i = 0; i < stream->urbs_submitted; i++) { 81 dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i); 82 /* stop the URB */ 83 usb_kill_urb(stream->urb_list[i]); 84 } 85 stream->urbs_submitted = 0; 86 return 0; 87 } 88 89 int usb_urb_submitv2(struct usb_data_stream *stream, 90 struct usb_data_stream_properties *props) 91 { 92 int i, ret; 93 94 if (props) { 95 ret = usb_urb_reconfig(stream, props); 96 if (ret < 0) 97 return ret; 98 } 99 100 for (i = 0; i < stream->urbs_initialized; i++) { 101 dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i); 102 ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC); 103 if (ret) { 104 dev_err(&stream->udev->dev, "%s: could not submit " \ 105 "urb no. %d - get them all back\n", 106 KBUILD_MODNAME, i); 107 usb_urb_killv2(stream); 108 return ret; 109 } 110 stream->urbs_submitted++; 111 } 112 return 0; 113 } 114 115 static int usb_urb_free_urbs(struct usb_data_stream *stream) 116 { 117 int i; 118 119 usb_urb_killv2(stream); 120 121 for (i = stream->urbs_initialized - 1; i >= 0; i--) { 122 if (stream->urb_list[i]) { 123 dev_dbg(&stream->udev->dev, "%s: free urb=%d\n", 124 __func__, i); 125 /* free the URBs */ 126 usb_free_urb(stream->urb_list[i]); 127 } 128 } 129 stream->urbs_initialized = 0; 130 131 return 0; 132 } 133 134 static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream) 135 { 136 int i, j; 137 138 /* allocate the URBs */ 139 for (i = 0; i < stream->props.count; i++) { 140 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i); 141 stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); 142 if (!stream->urb_list[i]) { 143 dev_dbg(&stream->udev->dev, "%s: failed\n", __func__); 144 for (j = 0; j < i; j++) 145 usb_free_urb(stream->urb_list[j]); 146 return -ENOMEM; 147 } 148 usb_fill_bulk_urb(stream->urb_list[i], 149 stream->udev, 150 usb_rcvbulkpipe(stream->udev, 151 stream->props.endpoint), 152 stream->buf_list[i], 153 stream->props.u.bulk.buffersize, 154 usb_urb_complete, stream); 155 156 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 157 stream->urb_list[i]->transfer_dma = stream->dma_addr[i]; 158 stream->urbs_initialized++; 159 } 160 return 0; 161 } 162 163 static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream) 164 { 165 int i, j; 166 167 /* allocate the URBs */ 168 for (i = 0; i < stream->props.count; i++) { 169 struct urb *urb; 170 int frame_offset = 0; 171 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i); 172 stream->urb_list[i] = usb_alloc_urb( 173 stream->props.u.isoc.framesperurb, GFP_ATOMIC); 174 if (!stream->urb_list[i]) { 175 dev_dbg(&stream->udev->dev, "%s: failed\n", __func__); 176 for (j = 0; j < i; j++) 177 usb_free_urb(stream->urb_list[j]); 178 return -ENOMEM; 179 } 180 181 urb = stream->urb_list[i]; 182 183 urb->dev = stream->udev; 184 urb->context = stream; 185 urb->complete = usb_urb_complete; 186 urb->pipe = usb_rcvisocpipe(stream->udev, 187 stream->props.endpoint); 188 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 189 urb->interval = stream->props.u.isoc.interval; 190 urb->number_of_packets = stream->props.u.isoc.framesperurb; 191 urb->transfer_buffer_length = stream->props.u.isoc.framesize * 192 stream->props.u.isoc.framesperurb; 193 urb->transfer_buffer = stream->buf_list[i]; 194 urb->transfer_dma = stream->dma_addr[i]; 195 196 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) { 197 urb->iso_frame_desc[j].offset = frame_offset; 198 urb->iso_frame_desc[j].length = 199 stream->props.u.isoc.framesize; 200 frame_offset += stream->props.u.isoc.framesize; 201 } 202 203 stream->urbs_initialized++; 204 } 205 return 0; 206 } 207 208 static int usb_free_stream_buffers(struct usb_data_stream *stream) 209 { 210 if (stream->state & USB_STATE_URB_BUF) { 211 while (stream->buf_num) { 212 stream->buf_num--; 213 dev_dbg(&stream->udev->dev, "%s: free buf=%d\n", 214 __func__, stream->buf_num); 215 usb_free_coherent(stream->udev, stream->buf_size, 216 stream->buf_list[stream->buf_num], 217 stream->dma_addr[stream->buf_num]); 218 } 219 } 220 221 stream->state &= ~USB_STATE_URB_BUF; 222 223 return 0; 224 } 225 226 static int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num, 227 unsigned long size) 228 { 229 stream->buf_num = 0; 230 stream->buf_size = size; 231 232 dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \ 233 "streaming\n", __func__, num * size); 234 235 for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { 236 stream->buf_list[stream->buf_num] = usb_alloc_coherent( 237 stream->udev, size, GFP_ATOMIC, 238 &stream->dma_addr[stream->buf_num]); 239 if (!stream->buf_list[stream->buf_num]) { 240 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n", 241 __func__, stream->buf_num); 242 usb_free_stream_buffers(stream); 243 return -ENOMEM; 244 } 245 246 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n", 247 __func__, stream->buf_num, 248 stream->buf_list[stream->buf_num], 249 (long long)stream->dma_addr[stream->buf_num]); 250 memset(stream->buf_list[stream->buf_num], 0, size); 251 stream->state |= USB_STATE_URB_BUF; 252 } 253 254 return 0; 255 } 256 257 int usb_urb_reconfig(struct usb_data_stream *stream, 258 struct usb_data_stream_properties *props) 259 { 260 int buf_size; 261 262 if (!props) 263 return 0; 264 265 /* check allocated buffers are large enough for the request */ 266 if (props->type == USB_BULK) { 267 buf_size = stream->props.u.bulk.buffersize; 268 } else if (props->type == USB_ISOC) { 269 buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb; 270 } else { 271 dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n", 272 KBUILD_MODNAME, props->type); 273 return -EINVAL; 274 } 275 276 if (stream->buf_num < props->count || stream->buf_size < buf_size) { 277 dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \ 278 "allocated buffers are too small\n", 279 KBUILD_MODNAME); 280 return -EINVAL; 281 } 282 283 /* check if all fields are same */ 284 if (stream->props.type == props->type && 285 stream->props.count == props->count && 286 stream->props.endpoint == props->endpoint) { 287 if (props->type == USB_BULK && 288 props->u.bulk.buffersize == 289 stream->props.u.bulk.buffersize) 290 return 0; 291 else if (props->type == USB_ISOC && 292 props->u.isoc.framesperurb == 293 stream->props.u.isoc.framesperurb && 294 props->u.isoc.framesize == 295 stream->props.u.isoc.framesize && 296 props->u.isoc.interval == 297 stream->props.u.isoc.interval) 298 return 0; 299 } 300 301 dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__); 302 303 usb_urb_free_urbs(stream); 304 memcpy(&stream->props, props, sizeof(*props)); 305 if (props->type == USB_BULK) 306 return usb_urb_alloc_bulk_urbs(stream); 307 else if (props->type == USB_ISOC) 308 return usb_urb_alloc_isoc_urbs(stream); 309 310 return 0; 311 } 312 313 int usb_urb_initv2(struct usb_data_stream *stream, 314 const struct usb_data_stream_properties *props) 315 { 316 int ret; 317 318 if (!stream || !props) 319 return -EINVAL; 320 321 memcpy(&stream->props, props, sizeof(*props)); 322 323 if (!stream->complete) { 324 dev_err(&stream->udev->dev, "%s: there is no data callback - " \ 325 "this doesn't make sense\n", KBUILD_MODNAME); 326 return -EINVAL; 327 } 328 329 switch (stream->props.type) { 330 case USB_BULK: 331 ret = usb_alloc_stream_buffers(stream, stream->props.count, 332 stream->props.u.bulk.buffersize); 333 if (ret < 0) 334 return ret; 335 336 return usb_urb_alloc_bulk_urbs(stream); 337 case USB_ISOC: 338 ret = usb_alloc_stream_buffers(stream, stream->props.count, 339 stream->props.u.isoc.framesize * 340 stream->props.u.isoc.framesperurb); 341 if (ret < 0) 342 return ret; 343 344 return usb_urb_alloc_isoc_urbs(stream); 345 default: 346 dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \ 347 "transfer\n", KBUILD_MODNAME); 348 return -EINVAL; 349 } 350 } 351 352 int usb_urb_exitv2(struct usb_data_stream *stream) 353 { 354 usb_urb_free_urbs(stream); 355 usb_free_stream_buffers(stream); 356 357 return 0; 358 } 359