16870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher/* usb-urb.c is part of the DVB USB library. 26870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * 36870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) 46870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * see dvb-usb-init.c for copyright information. 56870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * 66870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * This file keeps functions for initializing and handling the 76870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * BULK and ISOC USB data transfers in a generic way. 86870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * Can be used for DVB-only and also, that's the plan, for 96870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher * Hybrid USB devices (analog and DVB). 106870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher */ 116870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher#include "dvb-usb-common.h" 126870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 136870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher/* URB stuff for streaming */ 147d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic void usb_urb_complete(struct urb *urb) 156870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 166870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher struct usb_data_stream *stream = urb->context; 176870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int ptype = usb_pipetype(urb->pipe); 186870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int i; 196870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher u8 *b; 206870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 216870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n", 226870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", 236870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->status,urb->actual_length,urb->transfer_buffer_length, 246870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->number_of_packets,urb->error_count); 256870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 266870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher switch (urb->status) { 276870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case 0: /* success */ 286870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case -ETIMEDOUT: /* NAK */ 296870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher break; 306870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case -ECONNRESET: /* kill */ 316870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case -ENOENT: 326870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case -ESHUTDOWN: 336870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return; 346870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher default: /* error */ 356870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_ts("urb completition error %d.\n", urb->status); 366870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher break; 376870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 386870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 396870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher b = (u8 *) urb->transfer_buffer; 406870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher switch (ptype) { 416870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case PIPE_ISOCHRONOUS: 426870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (i = 0; i < urb->number_of_packets; i++) { 436870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 446870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (urb->iso_frame_desc[i].status != 0) 456870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status); 466870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher else if (urb->iso_frame_desc[i].actual_length > 0) 476870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); 486870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 496870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->iso_frame_desc[i].status = 0; 506870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->iso_frame_desc[i].actual_length = 0; 516870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 526870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher debug_dump(b,20,deb_uxfer); 536870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher break; 546870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case PIPE_BULK: 556870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (urb->actual_length > 0) 566870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->complete(stream, b, urb->actual_length); 576870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher break; 586870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher default: 59af901ca181d92aac3a7dc265144a9081a86d8f39André Goddard Rosa err("unknown endpoint type in completition handler."); 606870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return; 616870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 626870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_submit_urb(urb,GFP_ATOMIC); 636870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 646870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 656870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherint usb_urb_kill(struct usb_data_stream *stream) 666870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 676870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int i; 686870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (i = 0; i < stream->urbs_submitted; i++) { 696870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_ts("killing URB no. %d.\n",i); 706870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 716870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher /* stop the URB */ 726870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_kill_urb(stream->urb_list[i]); 736870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 746870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->urbs_submitted = 0; 756870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 766870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 776870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 786870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherint usb_urb_submit(struct usb_data_stream *stream) 796870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 806870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int i,ret; 816870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (i = 0; i < stream->urbs_initialized; i++) { 826870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_ts("submitting URB no. %d\n",i); 836870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) { 846870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher err("could not submit URB no. %d - get them all back",i); 856870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_urb_kill(stream); 866870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return ret; 876870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 886870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->urbs_submitted++; 896870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 906870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 916870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 926870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 936870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherstatic int usb_free_stream_buffers(struct usb_data_stream *stream) 946870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 956870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (stream->state & USB_STATE_URB_BUF) { 966870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher while (stream->buf_num) { 976870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->buf_num--; 986870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_mem("freeing buffer %d\n",stream->buf_num); 99997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_free_coherent(stream->udev, stream->buf_size, 100997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack stream->buf_list[stream->buf_num], 101997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack stream->dma_addr[stream->buf_num]); 1026870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 1036870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 1046870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1056870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->state &= ~USB_STATE_URB_BUF; 1066870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1076870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 1086870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 1096870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1106870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherstatic int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) 1116870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 1126870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->buf_num = 0; 1136870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->buf_size = size; 1146870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1156870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_mem("all in all I will use %lu bytes for streaming\n",num*size); 1166870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1176870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { 1186870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_mem("allocating buffer %d\n",stream->buf_num); 1196870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (( stream->buf_list[stream->buf_num] = 120997ea58eb92f9970b8af7aae48800d0ef43b9423Daniel Mack usb_alloc_coherent(stream->udev, size, GFP_ATOMIC, 1216870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher &stream->dma_addr[stream->buf_num]) ) == NULL) { 1226870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_mem("not enough memory for urb-buffer allocation.\n"); 1236870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_free_stream_buffers(stream); 1246870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return -ENOMEM; 1256870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 126e1634208b77872ac0884da6d92f0d46f9a61eaa7Mauro Carvalho Chehab deb_mem("buffer %d: %p (dma: %Lu)\n", 127e1634208b77872ac0884da6d92f0d46f9a61eaa7Mauro Carvalho Chehab stream->buf_num, 128e1634208b77872ac0884da6d92f0d46f9a61eaa7Mauro Carvalho Chehabstream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); 1296870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher memset(stream->buf_list[stream->buf_num],0,size); 1306870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->state |= USB_STATE_URB_BUF; 1316870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 1326870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_mem("allocation successful\n"); 1336870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1346870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 1356870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 1366870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1376870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherstatic int usb_bulk_urb_init(struct usb_data_stream *stream) 1386870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 1394faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf int i, j; 1406870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1416870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if ((i = usb_allocate_stream_buffers(stream,stream->props.count, 1426870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->props.u.bulk.buffersize)) < 0) 1436870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return i; 1446870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1456870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher /* allocate the URBs */ 1466870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (i = 0; i < stream->props.count; i++) { 1474faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); 1484faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf if (!stream->urb_list[i]) { 1494faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf deb_mem("not enough memory for urb_alloc_urb!.\n"); 1504faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf for (j = 0; j < i; j++) 151eb28dc39d3e82674584cc768b9757d1cae222a52Julia Lawall usb_free_urb(stream->urb_list[j]); 1526870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return -ENOMEM; 1534faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf } 1546870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_fill_bulk_urb( stream->urb_list[i], stream->udev, 1556870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_rcvbulkpipe(stream->udev,stream->props.endpoint), 1566870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->buf_list[i], 1576870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->props.u.bulk.buffersize, 1586870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_urb_complete, stream); 1596870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 160d29ca09d50309bb7df5d57aec88efdcd09a56f9fThomas Reitmayr stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 161d29ca09d50309bb7df5d57aec88efdcd09a56f9fThomas Reitmayr stream->urb_list[i]->transfer_dma = stream->dma_addr[i]; 1626870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->urbs_initialized++; 1636870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 1646870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 1656870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 1666870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1676870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherstatic int usb_isoc_urb_init(struct usb_data_stream *stream) 1686870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 1696870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int i,j; 1706870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1716870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if ((i = usb_allocate_stream_buffers(stream,stream->props.count, 1726870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0) 1736870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return i; 1746870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1756870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher /* allocate the URBs */ 1766870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (i = 0; i < stream->props.count; i++) { 1776870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher struct urb *urb; 1786870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int frame_offset = 0; 1794faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf 1804faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC); 1814faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf if (!stream->urb_list[i]) { 1824faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf deb_mem("not enough memory for urb_alloc_urb!\n"); 1834faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf for (j = 0; j < i; j++) 184eb28dc39d3e82674584cc768b9757d1cae222a52Julia Lawall usb_free_urb(stream->urb_list[j]); 1856870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return -ENOMEM; 1864faf1004c32819035c5325879a466f27e189feb5Douglas Schilling Landgraf } 1876870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1886870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb = stream->urb_list[i]; 1896870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 1906870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->dev = stream->udev; 1916870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->context = stream; 1926870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->complete = usb_urb_complete; 1936870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint); 1946870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 1956870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->interval = stream->props.u.isoc.interval; 1966870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->number_of_packets = stream->props.u.isoc.framesperurb; 1976870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->transfer_buffer_length = stream->buf_size; 1986870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->transfer_buffer = stream->buf_list[i]; 1996870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->transfer_dma = stream->dma_addr[i]; 2006870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2016870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (j = 0; j < stream->props.u.isoc.framesperurb; j++) { 2026870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->iso_frame_desc[j].offset = frame_offset; 2036870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize; 2046870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher frame_offset += stream->props.u.isoc.framesize; 2056870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 2066870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2076870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->urbs_initialized++; 2086870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 2096870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 2106870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 2116870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2126870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherint usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props) 2136870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 2146870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (stream == NULL || props == NULL) 2156870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return -EINVAL; 2166870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2176870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher memcpy(&stream->props, props, sizeof(*props)); 2186870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2196870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint)); 2206870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2216870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (stream->complete == NULL) { 2226870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher err("there is no data callback - this doesn't make sense."); 2236870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return -EINVAL; 2246870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 2256870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2266870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher switch (stream->props.type) { 2276870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case USB_BULK: 2286870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return usb_bulk_urb_init(stream); 2296870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher case USB_ISOC: 2306870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return usb_isoc_urb_init(stream); 2316870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher default: 232af901ca181d92aac3a7dc265144a9081a86d8f39André Goddard Rosa err("unknown URB-type for data transfer."); 2336870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return -EINVAL; 2346870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 2356870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 2366870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2376870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcherint usb_urb_exit(struct usb_data_stream *stream) 2386870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher{ 2396870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher int i; 2406870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2416870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_urb_kill(stream); 2426870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2436870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher for (i = 0; i < stream->urbs_initialized; i++) { 2446870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher if (stream->urb_list[i] != NULL) { 2456870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher deb_mem("freeing URB no. %d.\n",i); 2466870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher /* free the URBs */ 2476870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_free_urb(stream->urb_list[i]); 2486870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 2496870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher } 2506870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher stream->urbs_initialized = 0; 2516870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher 2526870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher usb_free_stream_buffers(stream); 2536870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher return 0; 2546870ab576c86a496869fbd5bb339da7e442ee7f5Patrick Boettcher} 255