diff options
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 29 |
1 files changed, 5 insertions, 24 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index f3d4de23fedf..44485b29f675 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -1035,9 +1035,9 @@ static void release_substream_urbs(struct snd_usb_substream *subs, int force) | |||
1035 | static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes, | 1035 | static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes, |
1036 | unsigned int rate, unsigned int frame_bits) | 1036 | unsigned int rate, unsigned int frame_bits) |
1037 | { | 1037 | { |
1038 | unsigned int maxsize, n, i; | 1038 | unsigned int maxsize, i; |
1039 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; | 1039 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; |
1040 | unsigned int npacks[MAX_URBS], urb_packs, total_packs, packs_per_ms; | 1040 | unsigned int urb_packs, total_packs, packs_per_ms; |
1041 | 1041 | ||
1042 | /* calculate the frequency in 16.16 format */ | 1042 | /* calculate the frequency in 16.16 format */ |
1043 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | 1043 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
@@ -1109,31 +1109,11 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1109 | /* too much... */ | 1109 | /* too much... */ |
1110 | subs->nurbs = MAX_URBS; | 1110 | subs->nurbs = MAX_URBS; |
1111 | total_packs = MAX_URBS * urb_packs; | 1111 | total_packs = MAX_URBS * urb_packs; |
1112 | } | 1112 | } else if (subs->nurbs < 2) { |
1113 | n = total_packs; | ||
1114 | for (i = 0; i < subs->nurbs; i++) { | ||
1115 | npacks[i] = n > urb_packs ? urb_packs : n; | ||
1116 | n -= urb_packs; | ||
1117 | } | ||
1118 | if (subs->nurbs <= 1) { | ||
1119 | /* too little - we need at least two packets | 1113 | /* too little - we need at least two packets |
1120 | * to ensure contiguous playback/capture | 1114 | * to ensure contiguous playback/capture |
1121 | */ | 1115 | */ |
1122 | subs->nurbs = 2; | 1116 | subs->nurbs = 2; |
1123 | npacks[0] = (total_packs + 1) / 2; | ||
1124 | npacks[1] = total_packs - npacks[0]; | ||
1125 | } else if (npacks[subs->nurbs-1] < MIN_PACKS_URB * packs_per_ms) { | ||
1126 | /* the last packet is too small.. */ | ||
1127 | if (subs->nurbs > 2) { | ||
1128 | /* merge to the first one */ | ||
1129 | npacks[0] += npacks[subs->nurbs - 1]; | ||
1130 | subs->nurbs--; | ||
1131 | } else { | ||
1132 | /* divide to two */ | ||
1133 | subs->nurbs = 2; | ||
1134 | npacks[0] = (total_packs + 1) / 2; | ||
1135 | npacks[1] = total_packs - npacks[0]; | ||
1136 | } | ||
1137 | } | 1117 | } |
1138 | 1118 | ||
1139 | /* allocate and initialize data urbs */ | 1119 | /* allocate and initialize data urbs */ |
@@ -1141,7 +1121,8 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri | |||
1141 | struct snd_urb_ctx *u = &subs->dataurb[i]; | 1121 | struct snd_urb_ctx *u = &subs->dataurb[i]; |
1142 | u->index = i; | 1122 | u->index = i; |
1143 | u->subs = subs; | 1123 | u->subs = subs; |
1144 | u->packets = npacks[i]; | 1124 | u->packets = (i + 1) * total_packs / subs->nurbs |
1125 | - i * total_packs / subs->nurbs; | ||
1145 | u->buffer_size = maxsize * u->packets; | 1126 | u->buffer_size = maxsize * u->packets; |
1146 | if (subs->fmt_type == USB_FORMAT_TYPE_II) | 1127 | if (subs->fmt_type == USB_FORMAT_TYPE_II) |
1147 | u->packets++; /* for transfer delimiter */ | 1128 | u->packets++; /* for transfer delimiter */ |