aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2005-07-07 20:58:28 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-07 21:24:02 -0400
commit25de192660627e1e8dc8ee6a120ff8b54d108593 (patch)
tree45e15b799e09f6b5fe478082303a8c276529edc1
parente161f817bebecc1c1cc461dc83cce2eafbed9ee9 (diff)
[PATCH] dvb: ttpci: fix timeout handling to be save with PREEMPT
Timeout handling fixed, especially for preemtible kernels and/or high system load. Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Johannes Stezenbach <js@linuxtv.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/media/common/saa7146_core.c11
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c72
2 files changed, 56 insertions, 27 deletions
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 77ff22911566..cd5828b5e9e3 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -62,13 +62,15 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
62int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop) 62int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
63{ 63{
64 unsigned long start; 64 unsigned long start;
65 int err;
65 66
66 /* wait for registers to be programmed */ 67 /* wait for registers to be programmed */
67 start = jiffies; 68 start = jiffies;
68 while (1) { 69 while (1) {
69 if (saa7146_read(dev, MC2) & 2) 70 err = time_after(jiffies, start + HZ/20);
70 break; 71 if (saa7146_read(dev, MC2) & 2)
71 if (time_after(jiffies, start + HZ/20)) { 72 break;
73 if (err) {
72 DEB_S(("timed out while waiting for registers getting programmed\n")); 74 DEB_S(("timed out while waiting for registers getting programmed\n"));
73 return -ETIMEDOUT; 75 return -ETIMEDOUT;
74 } 76 }
@@ -79,10 +81,11 @@ int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
79 /* wait for transfer to complete */ 81 /* wait for transfer to complete */
80 start = jiffies; 82 start = jiffies;
81 while (1) { 83 while (1) {
84 err = time_after(jiffies, start + HZ/4);
82 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) 85 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
83 break; 86 break;
84 saa7146_read(dev, MC2); 87 saa7146_read(dev, MC2);
85 if (time_after(jiffies, start + HZ/4)) { 88 if (err) {
86 DEB_S(("timed out while waiting for transfer completion\n")); 89 DEB_S(("timed out while waiting for transfer completion\n"));
87 return -ETIMEDOUT; 90 return -ETIMEDOUT;
88 } 91 }
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index aa1efce6cb31..1220826696c5 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -308,6 +308,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
308{ 308{
309 unsigned long start; 309 unsigned long start;
310 u32 stat; 310 u32 stat;
311 int err;
311 312
312 if (FW_VERSION(av7110->arm_app) <= 0x261c) { 313 if (FW_VERSION(av7110->arm_app) <= 0x261c) {
313 /* not supported by old firmware */ 314 /* not supported by old firmware */
@@ -318,14 +319,14 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
318 /* new firmware */ 319 /* new firmware */
319 start = jiffies; 320 start = jiffies;
320 for (;;) { 321 for (;;) {
322 err = time_after(jiffies, start + ARM_WAIT_FREE);
321 if (down_interruptible(&av7110->dcomlock)) 323 if (down_interruptible(&av7110->dcomlock))
322 return -ERESTARTSYS; 324 return -ERESTARTSYS;
323 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 325 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
324 up(&av7110->dcomlock); 326 up(&av7110->dcomlock);
325 if ((stat & flags) == 0) { 327 if ((stat & flags) == 0)
326 break; 328 break;
327 } 329 if (err) {
328 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
329 printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n", 330 printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
330 __FUNCTION__, stat & flags); 331 __FUNCTION__, stat & flags);
331 return -ETIMEDOUT; 332 return -ETIMEDOUT;
@@ -342,6 +343,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
342 char *type = NULL; 343 char *type = NULL;
343 u16 flags[2] = {0, 0}; 344 u16 flags[2] = {0, 0};
344 u32 stat; 345 u32 stat;
346 int err;
345 347
346// dprintk(4, "%p\n", av7110); 348// dprintk(4, "%p\n", av7110);
347 349
@@ -351,8 +353,11 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
351 } 353 }
352 354
353 start = jiffies; 355 start = jiffies;
354 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { 356 while (1) {
355 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 357 err = time_after(jiffies, start + ARM_WAIT_FREE);
358 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
359 break;
360 if (err) {
356 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); 361 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
357 return -ETIMEDOUT; 362 return -ETIMEDOUT;
358 } 363 }
@@ -363,8 +368,11 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
363 368
364#ifndef _NOHANDSHAKE 369#ifndef _NOHANDSHAKE
365 start = jiffies; 370 start = jiffies;
366 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) { 371 while (1) {
367 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { 372 err = time_after(jiffies, start + ARM_WAIT_SHAKE);
373 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
374 break;
375 if (err) {
368 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); 376 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
369 return -ETIMEDOUT; 377 return -ETIMEDOUT;
370 } 378 }
@@ -401,6 +409,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
401 /* non-immediate COMMAND type */ 409 /* non-immediate COMMAND type */
402 start = jiffies; 410 start = jiffies;
403 for (;;) { 411 for (;;) {
412 err = time_after(jiffies, start + ARM_WAIT_FREE);
404 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 413 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
405 if (stat & flags[0]) { 414 if (stat & flags[0]) {
406 printk(KERN_ERR "%s: %s QUEUE overflow\n", 415 printk(KERN_ERR "%s: %s QUEUE overflow\n",
@@ -409,7 +418,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
409 } 418 }
410 if ((stat & flags[1]) == 0) 419 if ((stat & flags[1]) == 0)
411 break; 420 break;
412 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 421 if (err) {
413 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", 422 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
414 __FUNCTION__, type); 423 __FUNCTION__, type);
415 return -ETIMEDOUT; 424 return -ETIMEDOUT;
@@ -432,12 +441,13 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
432 441
433#ifdef COM_DEBUG 442#ifdef COM_DEBUG
434 start = jiffies; 443 start = jiffies;
435 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { 444 while (1) {
436 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 445 err = time_after(jiffies, start + ARM_WAIT_FREE);
446 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
447 break;
448 if (err) {
437 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n", 449 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
438 __FUNCTION__, 450 __FUNCTION__, (buf[0] >> 8) & 0xff);
439 (buf[0] >> 8) & 0xff
440 );
441 return -ETIMEDOUT; 451 return -ETIMEDOUT;
442 } 452 }
443 msleep(1); 453 msleep(1);
@@ -553,8 +563,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
553 } 563 }
554 564
555 start = jiffies; 565 start = jiffies;
556 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) { 566 while (1) {
557 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 567 err = time_after(jiffies, start + ARM_WAIT_FREE);
568 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
569 break;
570 if (err) {
558 printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); 571 printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
559 up(&av7110->dcomlock); 572 up(&av7110->dcomlock);
560 return -ETIMEDOUT; 573 return -ETIMEDOUT;
@@ -566,8 +579,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
566 579
567#ifndef _NOHANDSHAKE 580#ifndef _NOHANDSHAKE
568 start = jiffies; 581 start = jiffies;
569 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) { 582 while (1) {
570 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { 583 err = time_after(jiffies, start + ARM_WAIT_SHAKE);
584 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
585 break;
586 if (err) {
571 printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); 587 printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
572 up(&av7110->dcomlock); 588 up(&av7110->dcomlock);
573 return -ETIMEDOUT; 589 return -ETIMEDOUT;
@@ -707,12 +723,16 @@ static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
707static int FlushText(struct av7110 *av7110) 723static int FlushText(struct av7110 *av7110)
708{ 724{
709 unsigned long start; 725 unsigned long start;
726 int err;
710 727
711 if (down_interruptible(&av7110->dcomlock)) 728 if (down_interruptible(&av7110->dcomlock))
712 return -ERESTARTSYS; 729 return -ERESTARTSYS;
713 start = jiffies; 730 start = jiffies;
714 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) { 731 while (1) {
715 if (time_after(jiffies, start + ARM_WAIT_OSD)) { 732 err = time_after(jiffies, start + ARM_WAIT_OSD);
733 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
734 break;
735 if (err) {
716 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", 736 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
717 __FUNCTION__); 737 __FUNCTION__);
718 up(&av7110->dcomlock); 738 up(&av7110->dcomlock);
@@ -735,8 +755,11 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
735 return -ERESTARTSYS; 755 return -ERESTARTSYS;
736 756
737 start = jiffies; 757 start = jiffies;
738 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) { 758 while (1) {
739 if (time_after(jiffies, start + ARM_WAIT_OSD)) { 759 ret = time_after(jiffies, start + ARM_WAIT_OSD);
760 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
761 break;
762 if (ret) {
740 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", 763 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
741 __FUNCTION__); 764 __FUNCTION__);
742 up(&av7110->dcomlock); 765 up(&av7110->dcomlock);
@@ -746,8 +769,11 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
746 } 769 }
747#ifndef _NOHANDSHAKE 770#ifndef _NOHANDSHAKE
748 start = jiffies; 771 start = jiffies;
749 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) { 772 while (1) {
750 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { 773 ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
774 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
775 break;
776 if (ret) {
751 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", 777 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
752 __FUNCTION__); 778 __FUNCTION__);
753 up(&av7110->dcomlock); 779 up(&av7110->dcomlock);