0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "dvb_usb_common.h"
0013
0014
0015
0016 int usb_urb_reconfig(struct usb_data_stream *stream,
0017 struct usb_data_stream_properties *props);
0018
0019 static void usb_urb_complete(struct urb *urb)
0020 {
0021 struct usb_data_stream *stream = urb->context;
0022 int ptype = usb_pipetype(urb->pipe);
0023 int i;
0024 u8 *b;
0025
0026 dev_dbg_ratelimited(&stream->udev->dev,
0027 "%s: %s urb completed status=%d length=%d/%d pack_num=%d errors=%d\n",
0028 __func__, ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
0029 urb->status, urb->actual_length,
0030 urb->transfer_buffer_length,
0031 urb->number_of_packets, urb->error_count);
0032
0033 switch (urb->status) {
0034 case 0:
0035 case -ETIMEDOUT:
0036 break;
0037 case -ECONNRESET:
0038 case -ENOENT:
0039 case -ESHUTDOWN:
0040 return;
0041 default:
0042 dev_dbg_ratelimited(&stream->udev->dev,
0043 "%s: urb completion failed=%d\n",
0044 __func__, urb->status);
0045 break;
0046 }
0047
0048 b = (u8 *) urb->transfer_buffer;
0049 switch (ptype) {
0050 case PIPE_ISOCHRONOUS:
0051 for (i = 0; i < urb->number_of_packets; i++) {
0052 if (urb->iso_frame_desc[i].status != 0)
0053 dev_dbg(&stream->udev->dev,
0054 "%s: iso frame descriptor has an error=%d\n",
0055 __func__,
0056 urb->iso_frame_desc[i].status);
0057 else if (urb->iso_frame_desc[i].actual_length > 0)
0058 stream->complete(stream,
0059 b + urb->iso_frame_desc[i].offset,
0060 urb->iso_frame_desc[i].actual_length);
0061
0062 urb->iso_frame_desc[i].status = 0;
0063 urb->iso_frame_desc[i].actual_length = 0;
0064 }
0065 break;
0066 case PIPE_BULK:
0067 if (urb->actual_length > 0)
0068 stream->complete(stream, b, urb->actual_length);
0069 break;
0070 default:
0071 dev_err(&stream->udev->dev,
0072 "%s: unknown endpoint type in completion handler\n",
0073 KBUILD_MODNAME);
0074 return;
0075 }
0076 usb_submit_urb(urb, GFP_ATOMIC);
0077 }
0078
0079 int usb_urb_killv2(struct usb_data_stream *stream)
0080 {
0081 int i;
0082 for (i = 0; i < stream->urbs_submitted; i++) {
0083 dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
0084
0085 usb_kill_urb(stream->urb_list[i]);
0086 }
0087 stream->urbs_submitted = 0;
0088 return 0;
0089 }
0090
0091 int usb_urb_submitv2(struct usb_data_stream *stream,
0092 struct usb_data_stream_properties *props)
0093 {
0094 int i, ret;
0095
0096 if (props) {
0097 ret = usb_urb_reconfig(stream, props);
0098 if (ret < 0)
0099 return ret;
0100 }
0101
0102 for (i = 0; i < stream->urbs_initialized; i++) {
0103 dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
0104 ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
0105 if (ret) {
0106 dev_err(&stream->udev->dev,
0107 "%s: could not submit urb no. %d - get them all back\n",
0108 KBUILD_MODNAME, i);
0109 usb_urb_killv2(stream);
0110 return ret;
0111 }
0112 stream->urbs_submitted++;
0113 }
0114 return 0;
0115 }
0116
0117 static int usb_urb_free_urbs(struct usb_data_stream *stream)
0118 {
0119 int i;
0120
0121 usb_urb_killv2(stream);
0122
0123 for (i = stream->urbs_initialized - 1; i >= 0; i--) {
0124 if (stream->urb_list[i]) {
0125 dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
0126 __func__, i);
0127
0128 usb_free_urb(stream->urb_list[i]);
0129 }
0130 }
0131 stream->urbs_initialized = 0;
0132
0133 return 0;
0134 }
0135
0136 static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
0137 {
0138 int i, j;
0139
0140
0141 for (i = 0; i < stream->props.count; i++) {
0142 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
0143 stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
0144 if (!stream->urb_list[i]) {
0145 dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
0146 for (j = 0; j < i; j++)
0147 usb_free_urb(stream->urb_list[j]);
0148 return -ENOMEM;
0149 }
0150 usb_fill_bulk_urb(stream->urb_list[i],
0151 stream->udev,
0152 usb_rcvbulkpipe(stream->udev,
0153 stream->props.endpoint),
0154 stream->buf_list[i],
0155 stream->props.u.bulk.buffersize,
0156 usb_urb_complete, stream);
0157
0158 stream->urbs_initialized++;
0159 }
0160 return 0;
0161 }
0162
0163 static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
0164 {
0165 int i, j;
0166
0167
0168 for (i = 0; i < stream->props.count; i++) {
0169 struct urb *urb;
0170 int frame_offset = 0;
0171 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
0172 stream->urb_list[i] = usb_alloc_urb(
0173 stream->props.u.isoc.framesperurb, GFP_ATOMIC);
0174 if (!stream->urb_list[i]) {
0175 dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
0176 for (j = 0; j < i; j++)
0177 usb_free_urb(stream->urb_list[j]);
0178 return -ENOMEM;
0179 }
0180
0181 urb = stream->urb_list[i];
0182
0183 urb->dev = stream->udev;
0184 urb->context = stream;
0185 urb->complete = usb_urb_complete;
0186 urb->pipe = usb_rcvisocpipe(stream->udev,
0187 stream->props.endpoint);
0188 urb->transfer_flags = URB_ISO_ASAP;
0189 urb->interval = stream->props.u.isoc.interval;
0190 urb->number_of_packets = stream->props.u.isoc.framesperurb;
0191 urb->transfer_buffer_length = stream->props.u.isoc.framesize *
0192 stream->props.u.isoc.framesperurb;
0193 urb->transfer_buffer = stream->buf_list[i];
0194
0195 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
0196 urb->iso_frame_desc[j].offset = frame_offset;
0197 urb->iso_frame_desc[j].length =
0198 stream->props.u.isoc.framesize;
0199 frame_offset += stream->props.u.isoc.framesize;
0200 }
0201
0202 stream->urbs_initialized++;
0203 }
0204 return 0;
0205 }
0206
0207 static int usb_free_stream_buffers(struct usb_data_stream *stream)
0208 {
0209 if (stream->state & USB_STATE_URB_BUF) {
0210 while (stream->buf_num) {
0211 stream->buf_num--;
0212 kfree(stream->buf_list[stream->buf_num]);
0213 }
0214 }
0215
0216 stream->state &= ~USB_STATE_URB_BUF;
0217
0218 return 0;
0219 }
0220
0221 static int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
0222 unsigned long size)
0223 {
0224 stream->buf_num = 0;
0225 stream->buf_size = size;
0226
0227 dev_dbg(&stream->udev->dev,
0228 "%s: all in all I will use %lu bytes for streaming\n",
0229 __func__, num * size);
0230
0231 for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
0232 stream->buf_list[stream->buf_num] = kzalloc(size, GFP_ATOMIC);
0233 if (!stream->buf_list[stream->buf_num]) {
0234 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
0235 __func__, stream->buf_num);
0236 usb_free_stream_buffers(stream);
0237 return -ENOMEM;
0238 }
0239
0240 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
0241 __func__, stream->buf_num,
0242 stream->buf_list[stream->buf_num],
0243 (long long)stream->dma_addr[stream->buf_num]);
0244 stream->state |= USB_STATE_URB_BUF;
0245 }
0246
0247 return 0;
0248 }
0249
0250 int usb_urb_reconfig(struct usb_data_stream *stream,
0251 struct usb_data_stream_properties *props)
0252 {
0253 int buf_size;
0254
0255 if (!props)
0256 return 0;
0257
0258
0259 if (props->type == USB_BULK) {
0260 buf_size = stream->props.u.bulk.buffersize;
0261 } else if (props->type == USB_ISOC) {
0262 buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
0263 } else {
0264 dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
0265 KBUILD_MODNAME, props->type);
0266 return -EINVAL;
0267 }
0268
0269 if (stream->buf_num < props->count || stream->buf_size < buf_size) {
0270 dev_err(&stream->udev->dev,
0271 "%s: cannot reconfigure as allocated buffers are too small\n",
0272 KBUILD_MODNAME);
0273 return -EINVAL;
0274 }
0275
0276
0277 if (stream->props.type == props->type &&
0278 stream->props.count == props->count &&
0279 stream->props.endpoint == props->endpoint) {
0280 if (props->type == USB_BULK &&
0281 props->u.bulk.buffersize ==
0282 stream->props.u.bulk.buffersize)
0283 return 0;
0284 else if (props->type == USB_ISOC &&
0285 props->u.isoc.framesperurb ==
0286 stream->props.u.isoc.framesperurb &&
0287 props->u.isoc.framesize ==
0288 stream->props.u.isoc.framesize &&
0289 props->u.isoc.interval ==
0290 stream->props.u.isoc.interval)
0291 return 0;
0292 }
0293
0294 dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
0295
0296 usb_urb_free_urbs(stream);
0297 memcpy(&stream->props, props, sizeof(*props));
0298 if (props->type == USB_BULK)
0299 return usb_urb_alloc_bulk_urbs(stream);
0300 else if (props->type == USB_ISOC)
0301 return usb_urb_alloc_isoc_urbs(stream);
0302
0303 return 0;
0304 }
0305
0306 int usb_urb_initv2(struct usb_data_stream *stream,
0307 const struct usb_data_stream_properties *props)
0308 {
0309 int ret;
0310
0311 if (!stream || !props)
0312 return -EINVAL;
0313
0314 memcpy(&stream->props, props, sizeof(*props));
0315
0316 if (!stream->complete) {
0317 dev_err(&stream->udev->dev,
0318 "%s: there is no data callback - this doesn't make sense\n",
0319 KBUILD_MODNAME);
0320 return -EINVAL;
0321 }
0322
0323 switch (stream->props.type) {
0324 case USB_BULK:
0325 ret = usb_alloc_stream_buffers(stream, stream->props.count,
0326 stream->props.u.bulk.buffersize);
0327 if (ret < 0)
0328 return ret;
0329
0330 return usb_urb_alloc_bulk_urbs(stream);
0331 case USB_ISOC:
0332 ret = usb_alloc_stream_buffers(stream, stream->props.count,
0333 stream->props.u.isoc.framesize *
0334 stream->props.u.isoc.framesperurb);
0335 if (ret < 0)
0336 return ret;
0337
0338 return usb_urb_alloc_isoc_urbs(stream);
0339 default:
0340 dev_err(&stream->udev->dev,
0341 "%s: unknown urb-type for data transfer\n",
0342 KBUILD_MODNAME);
0343 return -EINVAL;
0344 }
0345 }
0346
0347 int usb_urb_exitv2(struct usb_data_stream *stream)
0348 {
0349 usb_urb_free_urbs(stream);
0350 usb_free_stream_buffers(stream);
0351
0352 return 0;
0353 }