diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-08-23 09:27:25 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-23 12:58:07 -0400 |
commit | 70bdbd3d1ae9c4ca3e84a43df34262face26575d (patch) | |
tree | 667e5e1b54749f5dedfabb22f5d884429332a145 | |
parent | f065fabc864f4c98857bf67caa2365e9f8545751 (diff) |
ALSA: ali5451: fix timeout handling in snd_ali_{codecs,timer}_ready()
Modify loops in such way that the register value is checked also after
the timeout condition, just in case the heavy interrupt load etc. caused
the thread to sleep for the time period exceeding the timeout value.
While at it remove an extra ALI_STIMER read from snd_ali_stimer_ready().
Reported-by: Jack Byer <ojbyer@usa.net>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/ali5451/ali5451.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index c551006e2920..76d76c08339b 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -310,12 +310,16 @@ static int snd_ali_codec_ready(struct snd_ali *codec, | |||
310 | unsigned int res; | 310 | unsigned int res; |
311 | 311 | ||
312 | end_time = jiffies + msecs_to_jiffies(250); | 312 | end_time = jiffies + msecs_to_jiffies(250); |
313 | do { | 313 | |
314 | for (;;) { | ||
314 | res = snd_ali_5451_peek(codec,port); | 315 | res = snd_ali_5451_peek(codec,port); |
315 | if (!(res & 0x8000)) | 316 | if (!(res & 0x8000)) |
316 | return 0; | 317 | return 0; |
318 | if (!time_after_eq(end_time, jiffies)) | ||
319 | break; | ||
317 | schedule_timeout_uninterruptible(1); | 320 | schedule_timeout_uninterruptible(1); |
318 | } while (time_after_eq(end_time, jiffies)); | 321 | } |
322 | |||
319 | snd_ali_5451_poke(codec, port, res & ~0x8000); | 323 | snd_ali_5451_poke(codec, port, res & ~0x8000); |
320 | snd_printdd("ali_codec_ready: codec is not ready.\n "); | 324 | snd_printdd("ali_codec_ready: codec is not ready.\n "); |
321 | return -EIO; | 325 | return -EIO; |
@@ -327,15 +331,17 @@ static int snd_ali_stimer_ready(struct snd_ali *codec) | |||
327 | unsigned long dwChk1,dwChk2; | 331 | unsigned long dwChk1,dwChk2; |
328 | 332 | ||
329 | dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER); | 333 | dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER); |
330 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); | ||
331 | |||
332 | end_time = jiffies + msecs_to_jiffies(250); | 334 | end_time = jiffies + msecs_to_jiffies(250); |
333 | do { | 335 | |
336 | for (;;) { | ||
334 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); | 337 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); |
335 | if (dwChk2 != dwChk1) | 338 | if (dwChk2 != dwChk1) |
336 | return 0; | 339 | return 0; |
340 | if (!time_after_eq(end_time, jiffies)) | ||
341 | break; | ||
337 | schedule_timeout_uninterruptible(1); | 342 | schedule_timeout_uninterruptible(1); |
338 | } while (time_after_eq(end_time, jiffies)); | 343 | } |
344 | |||
339 | snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n"); | 345 | snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n"); |
340 | return -EIO; | 346 | return -EIO; |
341 | } | 347 | } |