1 // SPDX-License-Identifier: GPL-2.0 2 /* usb-urb.c is part of the DVB USB library. 3 * 4 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de) 5 * see dvb-usb-init.c for copyright information. 6 * 7 * This file keeps functions for initializing and handling the 8 * BULK and ISOC USB data transfers in a generic way. 9 * Can be used for DVB-only and also, that's the plan, for 10 * Hybrid USB devices (analog and DVB). 11 */ 12 #include "dvb-usb-common.h" 13 14 /* URB stuff for streaming */ 15 static void usb_urb_complete(struct urb *urb) 16 { 17 struct usb_data_stream *stream = urb->context; 18 int ptype = usb_pipetype(urb->pipe); 19 int i; 20 u8 *b; 21 22 deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n", 23 ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", 24 urb->status,urb->actual_length,urb->transfer_buffer_length, 25 urb->number_of_packets,urb->error_count); 26 27 switch (urb->status) { 28 case 0: /* success */ 29 case -ETIMEDOUT: /* NAK */ 30 break; 31 case -ECONNRESET: /* kill */ 32 case -ENOENT: 33 case -ESHUTDOWN: 34 return; 35 default: /* error */ 36 deb_ts("urb completion error %d.\n", urb->status); 37 break; 38 } 39 40 b = (u8 *) urb->transfer_buffer; 41 switch (ptype) { 42 case PIPE_ISOCHRONOUS: 43 for (i = 0; i < urb->number_of_packets; i++) { 44 45 if (urb->iso_frame_desc[i].status != 0) 46 deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status); 47 else if (urb->iso_frame_desc[i].actual_length > 0) 48 stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); 49 50 urb->iso_frame_desc[i].status = 0; 51 urb->iso_frame_desc[i].actual_length = 0; 52 } 53 debug_dump(b,20,deb_uxfer); 54 break; 55 case PIPE_BULK: 56 if (urb->actual_length > 0) 57 stream->complete(stream, b, urb->actual_length); 58 break; 59 default: 60 err("unknown endpoint type in completion handler."); 61 return; 62 } 63 usb_submit_urb(urb,GFP_ATOMIC); 64 } 65 66 int usb_urb_kill(struct usb_data_stream *stream) 67 { 68 int i; 69 for (i = 0; i < stream->urbs_submitted; i++) { 70 deb_ts("killing URB no. %d.\n",i); 71 72 /* stop the URB */ 73 usb_kill_urb(stream->urb_list[i]); 74 } 75 stream->urbs_submitted = 0; 76 return 0; 77 } 78 79 int usb_urb_submit(struct usb_data_stream *stream) 80 { 81 int i,ret; 82 for (i = 0; i < stream->urbs_initialized; i++) { 83 deb_ts("submitting URB no. %d\n",i); 84 if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) { 85 err("could not submit URB no. %d - get them all back",i); 86 usb_urb_kill(stream); 87 return ret; 88 } 89 stream->urbs_submitted++; 90 } 91 return 0; 92 } 93 94 static int usb_free_stream_buffers(struct usb_data_stream *stream) 95 { 96 if (stream->state & USB_STATE_URB_BUF) { 97 while (stream->buf_num) { 98 stream->buf_num--; 99 deb_mem("freeing buffer %d\n",stream->buf_num); 100 usb_free_coherent(stream->udev, stream->buf_size, 101 stream->buf_list[stream->buf_num], 102 stream->dma_addr[stream->buf_num]); 103 } 104 } 105 106 stream->state &= ~USB_STATE_URB_BUF; 107 108 return 0; 109 } 110 111 static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) 112 { 113 stream->buf_num = 0; 114 stream->buf_size = size; 115 116 deb_mem("all in all I will use %lu bytes for streaming\n",num*size); 117 118 for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { 119 deb_mem("allocating buffer %d\n",stream->buf_num); 120 if (( stream->buf_list[stream->buf_num] = 121 usb_alloc_coherent(stream->udev, size, GFP_KERNEL, 122 &stream->dma_addr[stream->buf_num]) ) == NULL) { 123 deb_mem("not enough memory for urb-buffer allocation.\n"); 124 usb_free_stream_buffers(stream); 125 return -ENOMEM; 126 } 127 deb_mem("buffer %d: %p (dma: %Lu)\n", 128 stream->buf_num, 129 stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); 130 memset(stream->buf_list[stream->buf_num],0,size); 131 stream->state |= USB_STATE_URB_BUF; 132 } 133 deb_mem("allocation successful\n"); 134 135 return 0; 136 } 137 138 static int usb_bulk_urb_init(struct usb_data_stream *stream) 139 { 140 int i, j; 141 142 if ((i = usb_allocate_stream_buffers(stream,stream->props.count, 143 stream->props.u.bulk.buffersize)) < 0) 144 return i; 145 146 /* allocate the URBs */ 147 for (i = 0; i < stream->props.count; i++) { 148 stream->urb_list[i] = usb_alloc_urb(0, GFP_KERNEL); 149 if (!stream->urb_list[i]) { 150 deb_mem("not enough memory for urb_alloc_urb!.\n"); 151 for (j = 0; j < i; j++) 152 usb_free_urb(stream->urb_list[j]); 153 return -ENOMEM; 154 } 155 usb_fill_bulk_urb( stream->urb_list[i], stream->udev, 156 usb_rcvbulkpipe(stream->udev,stream->props.endpoint), 157 stream->buf_list[i], 158 stream->props.u.bulk.buffersize, 159 usb_urb_complete, stream); 160 161 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 162 stream->urb_list[i]->transfer_dma = stream->dma_addr[i]; 163 stream->urbs_initialized++; 164 } 165 return 0; 166 } 167 168 static int usb_isoc_urb_init(struct usb_data_stream *stream) 169 { 170 int i,j; 171 172 if ((i = usb_allocate_stream_buffers(stream,stream->props.count, 173 stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0) 174 return i; 175 176 /* allocate the URBs */ 177 for (i = 0; i < stream->props.count; i++) { 178 struct urb *urb; 179 int frame_offset = 0; 180 181 stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_KERNEL); 182 if (!stream->urb_list[i]) { 183 deb_mem("not enough memory for urb_alloc_urb!\n"); 184 for (j = 0; j < i; j++) 185 usb_free_urb(stream->urb_list[j]); 186 return -ENOMEM; 187 } 188 189 urb = stream->urb_list[i]; 190 191 urb->dev = stream->udev; 192 urb->context = stream; 193 urb->complete = usb_urb_complete; 194 urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint); 195 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 196 urb->interval = stream->props.u.isoc.interval; 197 urb->number_of_packets = stream->props.u.isoc.framesperurb; 198 urb->transfer_buffer_length = stream->buf_size; 199 urb->transfer_buffer = stream->buf_list[i]; 200 urb->transfer_dma = stream->dma_addr[i]; 201 202 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) { 203 urb->iso_frame_desc[j].offset = frame_offset; 204 urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize; 205 frame_offset += stream->props.u.isoc.framesize; 206 } 207 208 stream->urbs_initialized++; 209 } 210 return 0; 211 } 212 213 int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props) 214 { 215 if (stream == NULL || props == NULL) 216 return -EINVAL; 217 218 memcpy(&stream->props, props, sizeof(*props)); 219 220 usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint)); 221 222 if (stream->complete == NULL) { 223 err("there is no data callback - this doesn't make sense."); 224 return -EINVAL; 225 } 226 227 switch (stream->props.type) { 228 case USB_BULK: 229 return usb_bulk_urb_init(stream); 230 case USB_ISOC: 231 return usb_isoc_urb_init(stream); 232 default: 233 err("unknown URB-type for data transfer."); 234 return -EINVAL; 235 } 236 } 237 238 int usb_urb_exit(struct usb_data_stream *stream) 239 { 240 int i; 241 242 usb_urb_kill(stream); 243 244 for (i = 0; i < stream->urbs_initialized; i++) { 245 if (stream->urb_list[i] != NULL) { 246 deb_mem("freeing URB no. %d.\n",i); 247 /* free the URBs */ 248 usb_free_urb(stream->urb_list[i]); 249 } 250 } 251 stream->urbs_initialized = 0; 252 253 usb_free_stream_buffers(stream); 254 return 0; 255 } 256