aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-08-12 09:19:39 -0400
committerJaroslav Kysela <perex@suse.cz>2005-08-30 02:45:16 -0400
commita93bf99077886d209f8e72bc134e1ceb36e76aa2 (patch)
treea26ba330656f9d0aa693dabea5c585e266a90555 /sound/usb
parent71d848ca00a16179b17e58e5f51c2d9a6c4f97a2 (diff)
[ALSA] usb-audio: schedule high speed URBs with 1 ms alignment
USB generic driver The EHCI driver doesn't interrupt more than once per millisecond, and organizes all iso transfers with frame-sized ITDs, so we can (try to) be more efficient by aligning all URBs on frame boundaries. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/usbaudio.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 49075f06f846..a62d1313da17 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -893,7 +893,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
893{ 893{
894 unsigned int maxsize, n, i; 894 unsigned int maxsize, n, i;
895 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; 895 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
896 unsigned int npacks[MAX_URBS], urb_packs, total_packs; 896 unsigned int npacks[MAX_URBS], urb_packs, total_packs, packs_per_ms;
897 897
898 /* calculate the frequency in 16.16 format */ 898 /* calculate the frequency in 16.16 format */
899 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) 899 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
@@ -920,14 +920,18 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
920 else 920 else
921 subs->curpacksize = maxsize; 921 subs->curpacksize = maxsize;
922 922
923 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
924 packs_per_ms = 8 >> subs->datainterval;
925 else
926 packs_per_ms = 1;
927
923 if (is_playback) { 928 if (is_playback) {
924 urb_packs = nrpacks; 929 urb_packs = nrpacks;
925 urb_packs = max(urb_packs, (unsigned int)MIN_PACKS_URB); 930 urb_packs = max(urb_packs, (unsigned int)MIN_PACKS_URB);
926 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS); 931 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
927 } else 932 } else
928 urb_packs = 1; 933 urb_packs = 1;
929 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) 934 urb_packs *= packs_per_ms;
930 urb_packs = (urb_packs * 8) >> subs->datainterval;
931 935
932 /* allocate a temporary buffer for playback */ 936 /* allocate a temporary buffer for playback */
933 if (is_playback) { 937 if (is_playback) {
@@ -949,8 +953,12 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
949 minsize -= minsize >> 2; 953 minsize -= minsize >> 2;
950 minsize = max(minsize, 1u); 954 minsize = max(minsize, 1u);
951 total_packs = (period_bytes + minsize - 1) / minsize; 955 total_packs = (period_bytes + minsize - 1) / minsize;
952 if (total_packs < 2 * MIN_PACKS_URB) 956 /* round up to multiple of packs_per_ms */
953 total_packs = 2 * MIN_PACKS_URB; 957 total_packs = (total_packs + packs_per_ms - 1)
958 & ~(packs_per_ms - 1);
959 /* we need at least two URBs for queueing */
960 if (total_packs < 2 * MIN_PACKS_URB * packs_per_ms)
961 total_packs = 2 * MIN_PACKS_URB * packs_per_ms;
954 } else { 962 } else {
955 total_packs = MAX_URBS * urb_packs; 963 total_packs = MAX_URBS * urb_packs;
956 } 964 }
@@ -972,7 +980,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
972 subs->nurbs = 2; 980 subs->nurbs = 2;
973 npacks[0] = (total_packs + 1) / 2; 981 npacks[0] = (total_packs + 1) / 2;
974 npacks[1] = total_packs - npacks[0]; 982 npacks[1] = total_packs - npacks[0];
975 } else if (npacks[subs->nurbs-1] < MIN_PACKS_URB) { 983 } else if (npacks[subs->nurbs-1] < MIN_PACKS_URB * packs_per_ms) {
976 /* the last packet is too small.. */ 984 /* the last packet is too small.. */
977 if (subs->nurbs > 2) { 985 if (subs->nurbs > 2) {
978 /* merge to the first one */ 986 /* merge to the first one */