aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-01-26 02:10:19 -0500
committerTakashi Iwai <tiwai@suse.de>2009-01-26 11:05:10 -0500
commit160389c8d21c8139a93191c2e5ca2273f311ed4e (patch)
tree7be9b7c475d23343ec41b7ef0f2d97e7fffbc7b0
parent4d788e040b72d2a46ea3ba726b7fa0b65de06c88 (diff)
sound: usb-audio: make URB sizes more equal
Distribute the packets evenly among the URBs, instead of making all URBs except the last one to have the maximum size. This makes the timing of pointer updates more regular and removes some special cases from the code. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/usbaudio.c29
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)
1035static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes, 1035static 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 */