aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/tm6000
diff options
context:
space:
mode:
authorJulian Scheel <julian@jusst.de>2012-10-04 09:04:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-04 11:54:21 -0500
commit16427faf28674451a7a0485ab0a929402f355ffd (patch)
tree954b9a70cffce0a8120a298b8254ec8fc83947c2 /drivers/media/usb/tm6000
parent6823627b933decf5842fcfc37cc71c549f56c6a2 (diff)
[media] tm6000: Add parameter to keep urb bufs allocated
On systems where it cannot be assured that enough continous memory is available all the time it can be very useful to only allocate the memory once when it is needed the first time. Afterwards the initially allocated memory will be reused, so it is ensured that the memory will stay available until the driver is unloaded. [mchehab@redhat.com: Codingstyle fixups] Signed-off-by: Julian Scheel <julian@jusst.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/tm6000')
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c112
-rw-r--r--drivers/media/usb/tm6000/tm6000.h5
2 files changed, 98 insertions, 19 deletions
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index f656fd7a39a2..82968017a253 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -49,12 +49,15 @@
49#define TM6000_MIN_BUF 4 49#define TM6000_MIN_BUF 4
50#define TM6000_DEF_BUF 8 50#define TM6000_DEF_BUF 8
51 51
52#define TM6000_NUM_URB_BUF 8
53
52#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */ 54#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */
53 55
54/* Declare static vars that will be used as parameters */ 56/* Declare static vars that will be used as parameters */
55static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 57static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
56static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 58static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
57static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */ 59static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */
60static int keep_urb; /* keep urb buffers allocated */
58 61
59/* Debug level */ 62/* Debug level */
60int tm6000_debug; 63int tm6000_debug;
@@ -538,6 +541,71 @@ static void tm6000_irq_callback(struct urb *urb)
538} 541}
539 542
540/* 543/*
544 * Allocate URB buffers
545 */
546static int tm6000_alloc_urb_buffers(struct tm6000_core *dev)
547{
548 int num_bufs = TM6000_NUM_URB_BUF;
549 int i;
550
551 if (dev->urb_buffer != NULL)
552 return 0;
553
554 dev->urb_buffer = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
555 if (!dev->urb_buffer) {
556 tm6000_err("cannot allocate memory for urb buffers\n");
557 return -ENOMEM;
558 }
559
560 dev->urb_dma = kmalloc(sizeof(dma_addr_t *)*num_bufs, GFP_KERNEL);
561 if (!dev->urb_dma) {
562 tm6000_err("cannot allocate memory for urb dma pointers\n");
563 return -ENOMEM;
564 }
565
566 for (i = 0; i < num_bufs; i++) {
567 dev->urb_buffer[i] = usb_alloc_coherent(
568 dev->udev, dev->urb_size,
569 GFP_KERNEL, &dev->urb_dma[i]);
570 if (!dev->urb_buffer[i]) {
571 tm6000_err("unable to allocate %i bytes for transfer buffer %i\n",
572 dev->urb_size, i);
573 return -ENOMEM;
574 }
575 memset(dev->urb_buffer[i], 0, dev->urb_size);
576 }
577
578 return 0;
579}
580
581/*
582 * Free URB buffers
583 */
584static int tm6000_free_urb_buffers(struct tm6000_core *dev)
585{
586 int i;
587
588 if (dev->urb_buffer == NULL)
589 return 0;
590
591 for (i = 0; i < TM6000_NUM_URB_BUF; i++) {
592 if (dev->urb_buffer[i]) {
593 usb_free_coherent(dev->udev,
594 dev->urb_size,
595 dev->urb_buffer[i],
596 dev->urb_dma[i]);
597 dev->urb_buffer[i] = NULL;
598 }
599 }
600 kfree(dev->urb_buffer);
601 kfree(dev->urb_dma);
602 dev->urb_buffer = NULL;
603 dev->urb_dma = NULL;
604
605 return 0;
606}
607
608/*
541 * Stop and Deallocate URBs 609 * Stop and Deallocate URBs
542 */ 610 */
543static void tm6000_uninit_isoc(struct tm6000_core *dev) 611static void tm6000_uninit_isoc(struct tm6000_core *dev)
@@ -551,18 +619,15 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
551 if (urb) { 619 if (urb) {
552 usb_kill_urb(urb); 620 usb_kill_urb(urb);
553 usb_unlink_urb(urb); 621 usb_unlink_urb(urb);
554 if (dev->isoc_ctl.transfer_buffer[i]) {
555 usb_free_coherent(dev->udev,
556 urb->transfer_buffer_length,
557 dev->isoc_ctl.transfer_buffer[i],
558 urb->transfer_dma);
559 }
560 usb_free_urb(urb); 622 usb_free_urb(urb);
561 dev->isoc_ctl.urb[i] = NULL; 623 dev->isoc_ctl.urb[i] = NULL;
562 } 624 }
563 dev->isoc_ctl.transfer_buffer[i] = NULL; 625 dev->isoc_ctl.transfer_buffer[i] = NULL;
564 } 626 }
565 627
628 if (!keep_urb)
629 tm6000_free_urb_buffers(dev);
630
566 kfree(dev->isoc_ctl.urb); 631 kfree(dev->isoc_ctl.urb);
567 kfree(dev->isoc_ctl.transfer_buffer); 632 kfree(dev->isoc_ctl.transfer_buffer);
568 633
@@ -572,12 +637,13 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
572} 637}
573 638
574/* 639/*
575 * Allocate URBs and start IRQ 640 * Assign URBs and start IRQ
576 */ 641 */
577static int tm6000_prepare_isoc(struct tm6000_core *dev) 642static int tm6000_prepare_isoc(struct tm6000_core *dev)
578{ 643{
579 struct tm6000_dmaqueue *dma_q = &dev->vidq; 644 struct tm6000_dmaqueue *dma_q = &dev->vidq;
580 int i, j, sb_size, pipe, size, max_packets, num_bufs = 8; 645 int i, j, sb_size, pipe, size, max_packets;
646 int num_bufs = TM6000_NUM_URB_BUF;
581 struct urb *urb; 647 struct urb *urb;
582 648
583 /* De-allocates all pending stuff */ 649 /* De-allocates all pending stuff */
@@ -605,6 +671,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
605 671
606 max_packets = TM6000_MAX_ISO_PACKETS; 672 max_packets = TM6000_MAX_ISO_PACKETS;
607 sb_size = max_packets * size; 673 sb_size = max_packets * size;
674 dev->urb_size = sb_size;
608 675
609 dev->isoc_ctl.num_bufs = num_bufs; 676 dev->isoc_ctl.num_bufs = num_bufs;
610 677
@@ -627,6 +694,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
627 max_packets, num_bufs, sb_size, 694 max_packets, num_bufs, sb_size,
628 dev->isoc_in.maxsize, size); 695 dev->isoc_in.maxsize, size);
629 696
697
698 if (!dev->urb_buffer && tm6000_alloc_urb_buffers(dev) < 0) {
699 tm6000_err("cannot allocate memory for urb buffers\n");
700
701 /* call free, as some buffers might have been allocated */
702 tm6000_free_urb_buffers(dev);
703 kfree(dev->isoc_ctl.urb);
704 kfree(dev->isoc_ctl.transfer_buffer);
705 return -ENOMEM;
706 }
707
630 /* allocate urbs and transfer buffers */ 708 /* allocate urbs and transfer buffers */
631 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 709 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
632 urb = usb_alloc_urb(max_packets, GFP_KERNEL); 710 urb = usb_alloc_urb(max_packets, GFP_KERNEL);
@@ -638,17 +716,8 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev)
638 } 716 }
639 dev->isoc_ctl.urb[i] = urb; 717 dev->isoc_ctl.urb[i] = urb;
640 718
641 dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev, 719 urb->transfer_dma = dev->urb_dma[i];
642 sb_size, GFP_KERNEL, &urb->transfer_dma); 720 dev->isoc_ctl.transfer_buffer[i] = dev->urb_buffer[i];
643 if (!dev->isoc_ctl.transfer_buffer[i]) {
644 tm6000_err("unable to allocate %i bytes for transfer"
645 " buffer %i%s\n",
646 sb_size, i,
647 in_interrupt() ? " while in int" : "");
648 tm6000_uninit_isoc(dev);
649 return -ENOMEM;
650 }
651 memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
652 721
653 usb_fill_bulk_urb(urb, dev->udev, pipe, 722 usb_fill_bulk_urb(urb, dev->udev, pipe,
654 dev->isoc_ctl.transfer_buffer[i], sb_size, 723 dev->isoc_ctl.transfer_buffer[i], sb_size,
@@ -1826,6 +1895,9 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev)
1826{ 1895{
1827 video_unregister_device(dev->vfd); 1896 video_unregister_device(dev->vfd);
1828 1897
1898 /* if URB buffers are still allocated free them now */
1899 tm6000_free_urb_buffers(dev);
1900
1829 if (dev->radio_dev) { 1901 if (dev->radio_dev) {
1830 if (video_is_registered(dev->radio_dev)) 1902 if (video_is_registered(dev->radio_dev))
1831 video_unregister_device(dev->radio_dev); 1903 video_unregister_device(dev->radio_dev);
@@ -1851,3 +1923,5 @@ MODULE_PARM_DESC(debug, "activates debug info");
1851module_param(vid_limit, int, 0644); 1923module_param(vid_limit, int, 0644);
1852MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); 1924MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
1853 1925
1926module_param(keep_urb, bool, 0);
1927MODULE_PARM_DESC(keep_urb, "Keep urb buffers allocated even when the device is closed by the user");
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h
index 6df418658c9c..173dcd7a7284 100644
--- a/drivers/media/usb/tm6000/tm6000.h
+++ b/drivers/media/usb/tm6000/tm6000.h
@@ -264,6 +264,11 @@ struct tm6000_core {
264 264
265 spinlock_t slock; 265 spinlock_t slock;
266 266
267 /* urb dma buffers */
268 char **urb_buffer;
269 dma_addr_t *urb_dma;
270 unsigned int urb_size;
271
267 unsigned long quirks; 272 unsigned long quirks;
268}; 273};
269 274