diff options
| author | Clemens Ladisch <clemens@ladisch.de> | 2005-08-12 09:19:39 -0400 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2005-08-30 02:45:16 -0400 |
| commit | a93bf99077886d209f8e72bc134e1ceb36e76aa2 (patch) | |
| tree | a26ba330656f9d0aa693dabea5c585e266a90555 | |
| parent | 71d848ca00a16179b17e58e5f51c2d9a6c4f97a2 (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>
| -rw-r--r-- | sound/usb/usbaudio.c | 20 |
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 */ |
