Loading drivers/media/dvb/dvb-usb/dvb_usb_common.h +2 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,8 @@ extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff); extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props); extern int usb_urb_exit(struct usb_data_stream *stream); extern int usb_urb_submit(struct usb_data_stream *stream); extern int usb_urb_submit(struct usb_data_stream *stream, struct usb_data_stream_properties *props); extern int usb_urb_kill(struct usb_data_stream *stream); extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap); Loading drivers/media/dvb/dvb-usb/dvb_usb_dvb.c +1 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) */ if (adap->feedcount == onoff && adap->feedcount > 0) { deb_ts("submitting all URBs\n"); usb_urb_submit(&adap->fe_adap[adap->active_fe].stream); usb_urb_submit(&adap->fe_adap[adap->active_fe].stream, NULL); deb_ts("controlling pid parser\n"); if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER && Loading drivers/media/dvb/dvb-usb/usb_urb.c +148 −72 Original line number Diff line number Diff line Loading @@ -11,6 +11,10 @@ #include "dvb_usb_common.h" /* URB stuff for streaming */ int usb_urb_reconfig(struct usb_data_stream *stream, struct usb_data_stream_properties *props); static void usb_urb_complete(struct urb *urb) { struct usb_data_stream *stream = urb->context; Loading Loading @@ -79,9 +83,17 @@ int usb_urb_kill(struct usb_data_stream *stream) return 0; } int usb_urb_submit(struct usb_data_stream *stream) int usb_urb_submit(struct usb_data_stream *stream, struct usb_data_stream_properties *props) { int i, ret; if (props) { ret = usb_urb_reconfig(stream, props); if (ret < 0) return ret; } for (i = 0; i < stream->urbs_initialized; i++) { deb_ts("submitting URB no. %d\n", i); ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC); Loading @@ -96,65 +108,32 @@ int usb_urb_submit(struct usb_data_stream *stream) return 0; } static int usb_free_stream_buffers(struct usb_data_stream *stream) int usb_urb_free_urbs(struct usb_data_stream *stream) { if (stream->state & USB_STATE_URB_BUF) { while (stream->buf_num) { stream->buf_num--; deb_mem("freeing buffer %d\n", stream->buf_num); usb_free_coherent(stream->udev, stream->buf_size, stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]); } } stream->state &= ~USB_STATE_URB_BUF; return 0; } static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) { stream->buf_num = 0; stream->buf_size = size; int i; deb_mem("all in all I will use %lu bytes for streaming\n", num * size); usb_urb_kill(stream); for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { deb_mem("allocating buffer %d\n", stream->buf_num); stream->buf_list[stream->buf_num] = usb_alloc_coherent( stream->udev, size, GFP_ATOMIC, &stream->dma_addr[stream->buf_num]); if (stream->buf_list[stream->buf_num] == NULL) { deb_mem("not enough memory for urb-buffer" \ " allocation.\n"); usb_free_stream_buffers(stream); return -ENOMEM; for (i = 0; i < stream->urbs_initialized; i++) { if (stream->urb_list[i] != NULL) { deb_mem("freeing URB no. %d.\n", i); pr_debug("%s: free URB=%d\n", __func__, i); /* free the URBs */ usb_free_urb(stream->urb_list[i]); } deb_mem("buffer %d: %p (dma: %llu)\n", stream->buf_num, stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); memset(stream->buf_list[stream->buf_num], 0, size); stream->state |= USB_STATE_URB_BUF; } deb_mem("allocation successful\n"); stream->urbs_initialized = 0; return 0; } static int usb_bulk_urb_init(struct usb_data_stream *stream) static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream) { int i, j; i = usb_allocate_stream_buffers(stream, stream->props.count, stream->props.u.bulk.buffersize); if (i < 0) return i; /* allocate the URBs */ for (i = 0; i < stream->props.count; i++) { pr_debug("%s: alloc URB=%d\n", __func__, i); stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); if (!stream->urb_list[i]) { deb_mem("not enough memory for urb_alloc_urb!.\n"); Loading @@ -162,7 +141,8 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) usb_free_urb(stream->urb_list[j]); return -ENOMEM; } usb_fill_bulk_urb(stream->urb_list[i], stream->udev, usb_fill_bulk_urb(stream->urb_list[i], stream->udev, usb_rcvbulkpipe(stream->udev, stream->props.endpoint), stream->buf_list[i], Loading @@ -176,21 +156,15 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) return 0; } static int usb_isoc_urb_init(struct usb_data_stream *stream) static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream) { int i, j; i = usb_allocate_stream_buffers(stream, stream->props.count, stream->props.u.isoc.framesize * stream->props.u.isoc.framesperurb); if (i < 0) return i; /* allocate the URBs */ for (i = 0; i < stream->props.count; i++) { struct urb *urb; int frame_offset = 0; pr_debug("%s: alloc URB=%d\n", __func__, i); stream->urb_list[i] = usb_alloc_urb( stream->props.u.isoc.framesperurb, GFP_ATOMIC); if (!stream->urb_list[i]) { Loading @@ -210,7 +184,8 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = stream->props.u.isoc.interval; urb->number_of_packets = stream->props.u.isoc.framesperurb; urb->transfer_buffer_length = stream->buf_size; urb->transfer_buffer_length = stream->props.u.isoc.framesize * stream->props.u.isoc.framesperurb; urb->transfer_buffer = stream->buf_list[i]; urb->transfer_dma = stream->dma_addr[i]; Loading @@ -226,9 +201,110 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) return 0; } int usb_free_stream_buffers(struct usb_data_stream *stream) { if (stream->state & USB_STATE_URB_BUF) { while (stream->buf_num) { stream->buf_num--; deb_mem("freeing buffer %d\n", stream->buf_num); usb_free_coherent(stream->udev, stream->buf_size, stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]); } } stream->state &= ~USB_STATE_URB_BUF; return 0; } int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) { stream->buf_num = 0; stream->buf_size = size; deb_mem("all in all I will use %lu bytes for streaming\n", num * size); for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { deb_mem("allocating buffer %d\n", stream->buf_num); stream->buf_list[stream->buf_num] = usb_alloc_coherent( stream->udev, size, GFP_ATOMIC, &stream->dma_addr[stream->buf_num]); if (stream->buf_list[stream->buf_num] == NULL) { deb_mem("not enough memory for urb-buffer" \ " allocation.\n"); usb_free_stream_buffers(stream); return -ENOMEM; } deb_mem("buffer %d: %p (dma: %llu)\n", stream->buf_num, stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); memset(stream->buf_list[stream->buf_num], 0, size); stream->state |= USB_STATE_URB_BUF; } deb_mem("allocation successful\n"); return 0; } int usb_urb_reconfig(struct usb_data_stream *stream, struct usb_data_stream_properties *props) { int buf_size; if (props == NULL) return 0; /* check allocated buffers are large enough for the request */ if (props->type == USB_BULK) buf_size = stream->props.u.bulk.buffersize; else if (props->type == USB_ISOC) buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb; else return -EINVAL; if (stream->buf_num < props->count || stream->buf_size < buf_size) { err("cannot reconfigure as allocated buffers are too small"); return -EINVAL; } /* check if all fields are same */ if (stream->props.type == props->type && stream->props.count == props->count && stream->props.endpoint == props->endpoint) { if (props->type == USB_BULK && props->u.bulk.buffersize == stream->props.u.bulk.buffersize) return 0; else if (props->type == USB_ISOC && props->u.isoc.framesperurb == stream->props.u.isoc.framesperurb && props->u.isoc.framesize == stream->props.u.isoc.framesize && props->u.isoc.interval == stream->props.u.isoc.interval) return 0; } pr_debug("%s: re-alloc URBs\n", __func__); usb_urb_free_urbs(stream); memcpy(&stream->props, props, sizeof(*props)); if (props->type == USB_BULK) return usb_urb_alloc_bulk_urbs(stream); else if (props->type == USB_ISOC) return usb_urb_alloc_isoc_urbs(stream); return 0; } int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props) { int ret; if (stream == NULL || props == NULL) return -EINVAL; Loading @@ -244,9 +320,20 @@ int usb_urb_init(struct usb_data_stream *stream, switch (stream->props.type) { case USB_BULK: return usb_bulk_urb_init(stream); ret = usb_alloc_stream_buffers(stream, stream->props.count, stream->props.u.bulk.buffersize); if (ret < 0) return ret; return usb_urb_alloc_bulk_urbs(stream); case USB_ISOC: return usb_isoc_urb_init(stream); ret = usb_alloc_stream_buffers(stream, stream->props.count, stream->props.u.isoc.framesize * stream->props.u.isoc.framesperurb); if (ret < 0) return ret; return usb_urb_alloc_isoc_urbs(stream); default: err("unknown URB-type for data transfer."); return -EINVAL; Loading @@ -255,19 +342,8 @@ int usb_urb_init(struct usb_data_stream *stream, int usb_urb_exit(struct usb_data_stream *stream) { int i; usb_urb_kill(stream); for (i = 0; i < stream->urbs_initialized; i++) { if (stream->urb_list[i] != NULL) { deb_mem("freeing URB no. %d.\n", i); /* free the URBs */ usb_free_urb(stream->urb_list[i]); } } stream->urbs_initialized = 0; usb_urb_free_urbs(stream); usb_free_stream_buffers(stream); return 0; } Loading
drivers/media/dvb/dvb-usb/dvb_usb_common.h +2 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,8 @@ extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff); extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props); extern int usb_urb_exit(struct usb_data_stream *stream); extern int usb_urb_submit(struct usb_data_stream *stream); extern int usb_urb_submit(struct usb_data_stream *stream, struct usb_data_stream_properties *props); extern int usb_urb_kill(struct usb_data_stream *stream); extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap); Loading
drivers/media/dvb/dvb-usb/dvb_usb_dvb.c +1 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) */ if (adap->feedcount == onoff && adap->feedcount > 0) { deb_ts("submitting all URBs\n"); usb_urb_submit(&adap->fe_adap[adap->active_fe].stream); usb_urb_submit(&adap->fe_adap[adap->active_fe].stream, NULL); deb_ts("controlling pid parser\n"); if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER && Loading
drivers/media/dvb/dvb-usb/usb_urb.c +148 −72 Original line number Diff line number Diff line Loading @@ -11,6 +11,10 @@ #include "dvb_usb_common.h" /* URB stuff for streaming */ int usb_urb_reconfig(struct usb_data_stream *stream, struct usb_data_stream_properties *props); static void usb_urb_complete(struct urb *urb) { struct usb_data_stream *stream = urb->context; Loading Loading @@ -79,9 +83,17 @@ int usb_urb_kill(struct usb_data_stream *stream) return 0; } int usb_urb_submit(struct usb_data_stream *stream) int usb_urb_submit(struct usb_data_stream *stream, struct usb_data_stream_properties *props) { int i, ret; if (props) { ret = usb_urb_reconfig(stream, props); if (ret < 0) return ret; } for (i = 0; i < stream->urbs_initialized; i++) { deb_ts("submitting URB no. %d\n", i); ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC); Loading @@ -96,65 +108,32 @@ int usb_urb_submit(struct usb_data_stream *stream) return 0; } static int usb_free_stream_buffers(struct usb_data_stream *stream) int usb_urb_free_urbs(struct usb_data_stream *stream) { if (stream->state & USB_STATE_URB_BUF) { while (stream->buf_num) { stream->buf_num--; deb_mem("freeing buffer %d\n", stream->buf_num); usb_free_coherent(stream->udev, stream->buf_size, stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]); } } stream->state &= ~USB_STATE_URB_BUF; return 0; } static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) { stream->buf_num = 0; stream->buf_size = size; int i; deb_mem("all in all I will use %lu bytes for streaming\n", num * size); usb_urb_kill(stream); for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { deb_mem("allocating buffer %d\n", stream->buf_num); stream->buf_list[stream->buf_num] = usb_alloc_coherent( stream->udev, size, GFP_ATOMIC, &stream->dma_addr[stream->buf_num]); if (stream->buf_list[stream->buf_num] == NULL) { deb_mem("not enough memory for urb-buffer" \ " allocation.\n"); usb_free_stream_buffers(stream); return -ENOMEM; for (i = 0; i < stream->urbs_initialized; i++) { if (stream->urb_list[i] != NULL) { deb_mem("freeing URB no. %d.\n", i); pr_debug("%s: free URB=%d\n", __func__, i); /* free the URBs */ usb_free_urb(stream->urb_list[i]); } deb_mem("buffer %d: %p (dma: %llu)\n", stream->buf_num, stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); memset(stream->buf_list[stream->buf_num], 0, size); stream->state |= USB_STATE_URB_BUF; } deb_mem("allocation successful\n"); stream->urbs_initialized = 0; return 0; } static int usb_bulk_urb_init(struct usb_data_stream *stream) static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream) { int i, j; i = usb_allocate_stream_buffers(stream, stream->props.count, stream->props.u.bulk.buffersize); if (i < 0) return i; /* allocate the URBs */ for (i = 0; i < stream->props.count; i++) { pr_debug("%s: alloc URB=%d\n", __func__, i); stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); if (!stream->urb_list[i]) { deb_mem("not enough memory for urb_alloc_urb!.\n"); Loading @@ -162,7 +141,8 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) usb_free_urb(stream->urb_list[j]); return -ENOMEM; } usb_fill_bulk_urb(stream->urb_list[i], stream->udev, usb_fill_bulk_urb(stream->urb_list[i], stream->udev, usb_rcvbulkpipe(stream->udev, stream->props.endpoint), stream->buf_list[i], Loading @@ -176,21 +156,15 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) return 0; } static int usb_isoc_urb_init(struct usb_data_stream *stream) static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream) { int i, j; i = usb_allocate_stream_buffers(stream, stream->props.count, stream->props.u.isoc.framesize * stream->props.u.isoc.framesperurb); if (i < 0) return i; /* allocate the URBs */ for (i = 0; i < stream->props.count; i++) { struct urb *urb; int frame_offset = 0; pr_debug("%s: alloc URB=%d\n", __func__, i); stream->urb_list[i] = usb_alloc_urb( stream->props.u.isoc.framesperurb, GFP_ATOMIC); if (!stream->urb_list[i]) { Loading @@ -210,7 +184,8 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = stream->props.u.isoc.interval; urb->number_of_packets = stream->props.u.isoc.framesperurb; urb->transfer_buffer_length = stream->buf_size; urb->transfer_buffer_length = stream->props.u.isoc.framesize * stream->props.u.isoc.framesperurb; urb->transfer_buffer = stream->buf_list[i]; urb->transfer_dma = stream->dma_addr[i]; Loading @@ -226,9 +201,110 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) return 0; } int usb_free_stream_buffers(struct usb_data_stream *stream) { if (stream->state & USB_STATE_URB_BUF) { while (stream->buf_num) { stream->buf_num--; deb_mem("freeing buffer %d\n", stream->buf_num); usb_free_coherent(stream->udev, stream->buf_size, stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]); } } stream->state &= ~USB_STATE_URB_BUF; return 0; } int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) { stream->buf_num = 0; stream->buf_size = size; deb_mem("all in all I will use %lu bytes for streaming\n", num * size); for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { deb_mem("allocating buffer %d\n", stream->buf_num); stream->buf_list[stream->buf_num] = usb_alloc_coherent( stream->udev, size, GFP_ATOMIC, &stream->dma_addr[stream->buf_num]); if (stream->buf_list[stream->buf_num] == NULL) { deb_mem("not enough memory for urb-buffer" \ " allocation.\n"); usb_free_stream_buffers(stream); return -ENOMEM; } deb_mem("buffer %d: %p (dma: %llu)\n", stream->buf_num, stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); memset(stream->buf_list[stream->buf_num], 0, size); stream->state |= USB_STATE_URB_BUF; } deb_mem("allocation successful\n"); return 0; } int usb_urb_reconfig(struct usb_data_stream *stream, struct usb_data_stream_properties *props) { int buf_size; if (props == NULL) return 0; /* check allocated buffers are large enough for the request */ if (props->type == USB_BULK) buf_size = stream->props.u.bulk.buffersize; else if (props->type == USB_ISOC) buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb; else return -EINVAL; if (stream->buf_num < props->count || stream->buf_size < buf_size) { err("cannot reconfigure as allocated buffers are too small"); return -EINVAL; } /* check if all fields are same */ if (stream->props.type == props->type && stream->props.count == props->count && stream->props.endpoint == props->endpoint) { if (props->type == USB_BULK && props->u.bulk.buffersize == stream->props.u.bulk.buffersize) return 0; else if (props->type == USB_ISOC && props->u.isoc.framesperurb == stream->props.u.isoc.framesperurb && props->u.isoc.framesize == stream->props.u.isoc.framesize && props->u.isoc.interval == stream->props.u.isoc.interval) return 0; } pr_debug("%s: re-alloc URBs\n", __func__); usb_urb_free_urbs(stream); memcpy(&stream->props, props, sizeof(*props)); if (props->type == USB_BULK) return usb_urb_alloc_bulk_urbs(stream); else if (props->type == USB_ISOC) return usb_urb_alloc_isoc_urbs(stream); return 0; } int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props) { int ret; if (stream == NULL || props == NULL) return -EINVAL; Loading @@ -244,9 +320,20 @@ int usb_urb_init(struct usb_data_stream *stream, switch (stream->props.type) { case USB_BULK: return usb_bulk_urb_init(stream); ret = usb_alloc_stream_buffers(stream, stream->props.count, stream->props.u.bulk.buffersize); if (ret < 0) return ret; return usb_urb_alloc_bulk_urbs(stream); case USB_ISOC: return usb_isoc_urb_init(stream); ret = usb_alloc_stream_buffers(stream, stream->props.count, stream->props.u.isoc.framesize * stream->props.u.isoc.framesperurb); if (ret < 0) return ret; return usb_urb_alloc_isoc_urbs(stream); default: err("unknown URB-type for data transfer."); return -EINVAL; Loading @@ -255,19 +342,8 @@ int usb_urb_init(struct usb_data_stream *stream, int usb_urb_exit(struct usb_data_stream *stream) { int i; usb_urb_kill(stream); for (i = 0; i < stream->urbs_initialized; i++) { if (stream->urb_list[i] != NULL) { deb_mem("freeing URB no. %d.\n", i); /* free the URBs */ usb_free_urb(stream->urb_list[i]); } } stream->urbs_initialized = 0; usb_urb_free_urbs(stream); usb_free_stream_buffers(stream); return 0; }