diff options
Diffstat (limited to 'sound/usb')
-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 */ |