aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-10 03:53:24 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-12 08:56:59 -0500
commit1b3fd2d342667005855deae74200195695433259 (patch)
treeab2d9a85e517e552ae309942cc462e07fbf33e67 /drivers/media
parent439c491c4c3e1d4f2be0a17d5789e0a19d85622c (diff)
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number of packets per URB and the maximum URB size. This is not a good idea, as it: - wastes more bandwidth than necessary, by using a very large number of packets; - those constants are bound to an specific scenario, with a bandwidth of 48 kHz; - don't take the maximum endpoint size into account; - with urb->interval = 1 on xHCI, those constraints cause a "funny" setup: URBs with 64 packets inside, with only 24 bytes total. E. g. a complete waste of space. Change the code to do dynamic URB audio calculus and allocation. For now, use the same constraints as used before this patch, to avoid regressions. A good scenario (tested) seems to use those defines, instead: #define EM28XX_MAX_AUDIO_BUFS 8 #define EM28XX_MIN_AUDIO_PACKETS 2 But let's not do such change here, letting the optimization to happen on latter patches, after more tests. Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c141
-rw-r--r--drivers/media/usb/em28xx/em28xx.h8
2 files changed, 111 insertions, 38 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 4ee3488960e1..6c7d34600294 100644
--- a/drivers/media/usb/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -50,6 +50,8 @@ static int debug;
50module_param(debug, int, 0644); 50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "activates debug info"); 51MODULE_PARM_DESC(debug, "activates debug info");
52 52
53#define EM28XX_MAX_AUDIO_BUFS 5
54#define EM28XX_MIN_AUDIO_PACKETS 64
53#define dprintk(fmt, arg...) do { \ 55#define dprintk(fmt, arg...) do { \
54 if (debug) \ 56 if (debug) \
55 printk(KERN_INFO "em28xx-audio %s: " fmt, \ 57 printk(KERN_INFO "em28xx-audio %s: " fmt, \
@@ -63,7 +65,7 @@ static int em28xx_deinit_isoc_audio(struct em28xx *dev)
63 int i; 65 int i;
64 66
65 dprintk("Stopping isoc\n"); 67 dprintk("Stopping isoc\n");
66 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 68 for (i = 0; i < dev->adev.num_urb; i++) {
67 struct urb *urb = dev->adev.urb[i]; 69 struct urb *urb = dev->adev.urb[i];
68 70
69 if (!irqs_disabled()) 71 if (!irqs_disabled())
@@ -168,7 +170,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
168 dprintk("Starting isoc transfers\n"); 170 dprintk("Starting isoc transfers\n");
169 171
170 /* Start streaming */ 172 /* Start streaming */
171 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 173 for (i = 0; i < dev->adev.num_urb; i++) {
172 memset(dev->adev.transfer_buffer[i], 0x80, 174 memset(dev->adev.transfer_buffer[i], 0x80,
173 dev->adev.urb[i]->transfer_buffer_length); 175 dev->adev.urb[i]->transfer_buffer_length);
174 176
@@ -598,21 +600,35 @@ static void em28xx_audio_free_urb(struct em28xx *dev)
598{ 600{
599 int i; 601 int i;
600 602
601 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 603 for (i = 0; i < dev->adev.num_urb; i++) {
602 struct urb *urb = dev->adev.urb[i]; 604 struct urb *urb = dev->adev.urb[i];
603 605
604 if (!dev->adev.urb[i]) 606 if (!urb)
605 continue; 607 continue;
606 608
607 usb_free_coherent(dev->udev, 609 if (dev->adev.transfer_buffer[i])
608 urb->transfer_buffer_length, 610 usb_free_coherent(dev->udev,
609 dev->adev.transfer_buffer[i], 611 urb->transfer_buffer_length,
610 urb->transfer_dma); 612 dev->adev.transfer_buffer[i],
613 urb->transfer_dma);
611 614
612 usb_free_urb(urb); 615 usb_free_urb(urb);
613 dev->adev.urb[i] = NULL;
614 dev->adev.transfer_buffer[i] = NULL;
615 } 616 }
617 kfree(dev->adev.urb);
618 kfree(dev->adev.transfer_buffer);
619 dev->adev.num_urb = 0;
620}
621
622/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
623static int em28xx_audio_ep_packet_size(struct usb_device *udev,
624 struct usb_endpoint_descriptor *e)
625{
626 int size = le16_to_cpu(e->wMaxPacketSize);
627
628 if (udev->speed == USB_SPEED_HIGH)
629 return (size & 0x7ff) * (1 + (((size) >> 11) & 0x03));
630
631 return size & 0x7ff;
616} 632}
617 633
618static int em28xx_audio_init(struct em28xx *dev) 634static int em28xx_audio_init(struct em28xx *dev)
@@ -623,9 +639,8 @@ static int em28xx_audio_init(struct em28xx *dev)
623 struct usb_interface *intf; 639 struct usb_interface *intf;
624 struct usb_endpoint_descriptor *e, *ep = NULL; 640 struct usb_endpoint_descriptor *e, *ep = NULL;
625 static int devnr; 641 static int devnr;
626 int err, i; 642 int err, i, ep_size, interval, num_urb, npackets;
627 const int sb_size = EM28XX_NUM_AUDIO_PACKETS * 643 int urb_size, bytes_per_transfer;
628 EM28XX_AUDIO_MAX_PACKET_SIZE;
629 u8 alt; 644 u8 alt;
630 645
631 if (!dev->has_alsa_audio || dev->audio_ifnum < 0) { 646 if (!dev->has_alsa_audio || dev->audio_ifnum < 0) {
@@ -648,6 +663,9 @@ static int em28xx_audio_init(struct em28xx *dev)
648 return err; 663 return err;
649 664
650 spin_lock_init(&adev->slock); 665 spin_lock_init(&adev->slock);
666 adev->sndcard = card;
667 adev->udev = dev->udev;
668
651 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); 669 err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
652 if (err < 0) { 670 if (err < 0) {
653 snd_card_free(card); 671 snd_card_free(card);
@@ -712,25 +730,92 @@ static int em28xx_audio_init(struct em28xx *dev)
712 return -ENODEV; 730 return -ENODEV;
713 } 731 }
714 732
715 /* Alloc URB and transfer buffers */ 733 ep_size = em28xx_audio_ep_packet_size(dev->udev, ep);
716 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 734 interval = 1 << (ep->bInterval - 1);
735
736 em28xx_info("Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n",
737 EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed),
738 dev->audio_ifnum, alt,
739 interval,
740 ep_size);
741
742 /* Calculate the number and size of URBs to better fit the audio samples */
743
744 /*
745 * Estimate the number of bytes per DMA transfer.
746 *
747 * This is given by the bit rate (for now, only 48000 Hz) multiplied
748 * by 2 channels and 2 bytes/sample divided by the number of microframe
749 * intervals and by the microframe rate (125 us)
750 */
751 bytes_per_transfer = DIV_ROUND_UP(48000 * 2 * 2, 125 * interval);
752
753 /*
754 * Estimate the number of transfer URBs. Don't let it go past the
755 * maximum number of URBs that is known to be supported by the device.
756 */
757 num_urb = DIV_ROUND_UP(bytes_per_transfer, ep_size);
758 if (num_urb > EM28XX_MAX_AUDIO_BUFS)
759 num_urb = EM28XX_MAX_AUDIO_BUFS;
760
761 /*
762 * Now that we know the number of bytes per transfer and the number of
763 * URBs, estimate the typical size of an URB, in order to adjust the
764 * minimal number of packets.
765 */
766 urb_size = bytes_per_transfer / num_urb;
767
768 /*
769 * Now, calculate the amount of audio packets to be filled on each
770 * URB. In order to preserve the old behaviour, use a minimal
771 * threshold for this value.
772 */
773 npackets = EM28XX_MIN_AUDIO_PACKETS;
774 if (urb_size > ep_size * npackets)
775 npackets = DIV_ROUND_UP(urb_size, ep_size);
776
777 em28xx_info("Number of URBs: %d, with %d packets and %d size",
778 num_urb, npackets, urb_size);
779
780 /* Allocate space to store the number of URBs to be used */
781
782 dev->adev.transfer_buffer = kcalloc(num_urb,
783 sizeof(*dev->adev.transfer_buffer),
784 GFP_ATOMIC);
785 if (!dev->adev.transfer_buffer) {
786 snd_card_free(card);
787 return -ENOMEM;
788 }
789
790 dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC);
791 if (!dev->adev.urb) {
792 snd_card_free(card);
793 kfree(dev->adev.transfer_buffer);
794 return -ENOMEM;
795 }
796
797 /* Alloc memory for each URB and for each transfer buffer */
798 dev->adev.num_urb = num_urb;
799 for (i = 0; i < num_urb; i++) {
717 struct urb *urb; 800 struct urb *urb;
718 int j, k; 801 int j, k;
719 void *buf; 802 void *buf;
720 803
721 urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); 804 urb = usb_alloc_urb(npackets, GFP_ATOMIC);
722 if (!urb) { 805 if (!urb) {
723 em28xx_errdev("usb_alloc_urb failed!\n"); 806 em28xx_errdev("usb_alloc_urb failed!\n");
724 em28xx_audio_free_urb(dev); 807 em28xx_audio_free_urb(dev);
808 snd_card_free(card);
725 return -ENOMEM; 809 return -ENOMEM;
726 } 810 }
727 dev->adev.urb[i] = urb; 811 dev->adev.urb[i] = urb;
728 812
729 buf = usb_alloc_coherent(dev->udev, sb_size, GFP_ATOMIC, 813 buf = usb_alloc_coherent(dev->udev, npackets * ep_size, GFP_ATOMIC,
730 &urb->transfer_dma); 814 &urb->transfer_dma);
731 if (!buf) { 815 if (!buf) {
732 em28xx_errdev("usb_alloc_coherent failed!\n"); 816 em28xx_errdev("usb_alloc_coherent failed!\n");
733 em28xx_audio_free_urb(dev); 817 em28xx_audio_free_urb(dev);
818 snd_card_free(card);
734 return -ENOMEM; 819 return -ENOMEM;
735 } 820 }
736 dev->adev.transfer_buffer[i] = buf; 821 dev->adev.transfer_buffer[i] = buf;
@@ -739,23 +824,15 @@ static int em28xx_audio_init(struct em28xx *dev)
739 urb->context = dev; 824 urb->context = dev;
740 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO); 825 urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO);
741 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 826 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
742 urb->transfer_buffer = dev->adev.transfer_buffer[i]; 827 urb->transfer_buffer = buf;
743 urb->interval = 1 << (ep->bInterval - 1); 828 urb->interval = interval;
744 urb->complete = em28xx_audio_isocirq; 829 urb->complete = em28xx_audio_isocirq;
745 urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; 830 urb->number_of_packets = npackets;
746 urb->transfer_buffer_length = sb_size; 831 urb->transfer_buffer_length = ep_size * npackets;
747
748 if (!i)
749 dprintk("Will use ep 0x%02x on intf %d alt %d interval = %d (rcv isoc pipe: 0x%08x)\n",
750 EM28XX_EP_AUDIO, dev->audio_ifnum, alt,
751 urb->interval,
752 urb->pipe);
753 832
754 for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS; 833 for (j = k = 0; j < npackets; j++, k += ep_size) {
755 j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
756 urb->iso_frame_desc[j].offset = k; 834 urb->iso_frame_desc[j].offset = k;
757 urb->iso_frame_desc[j].length = 835 urb->iso_frame_desc[j].length = ep_size;
758 EM28XX_AUDIO_MAX_PACKET_SIZE;
759 } 836 }
760 } 837 }
761 838
@@ -765,8 +842,6 @@ static int em28xx_audio_init(struct em28xx *dev)
765 snd_card_free(card); 842 snd_card_free(card);
766 return err; 843 return err;
767 } 844 }
768 adev->sndcard = card;
769 adev->udev = dev->udev;
770 845
771 em28xx_info("Audio extension successfully initialized\n"); 846 em28xx_info("Audio extension successfully initialized\n");
772 return 0; 847 return 0;
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index efdf38642768..e76f993e3195 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -481,9 +481,6 @@ struct em28xx_eeprom {
481 u8 string_idx_table; 481 u8 string_idx_table;
482}; 482};
483 483
484#define EM28XX_AUDIO_BUFS 5
485#define EM28XX_NUM_AUDIO_PACKETS 64
486#define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */
487#define EM28XX_CAPTURE_STREAM_EN 1 484#define EM28XX_CAPTURE_STREAM_EN 1
488 485
489/* em28xx extensions */ 486/* em28xx extensions */
@@ -498,8 +495,9 @@ struct em28xx_eeprom {
498 495
499struct em28xx_audio { 496struct em28xx_audio {
500 char name[50]; 497 char name[50];
501 char *transfer_buffer[EM28XX_AUDIO_BUFS]; 498 unsigned num_urb;
502 struct urb *urb[EM28XX_AUDIO_BUFS]; 499 char **transfer_buffer;
500 struct urb **urb;
503 struct usb_device *udev; 501 struct usb_device *udev;
504 unsigned int capture_transfer_done; 502 unsigned int capture_transfer_done;
505 struct snd_pcm_substream *capture_pcm_substream; 503 struct snd_pcm_substream *capture_pcm_substream;