tree 45e15b799e09f6b5fe478082303a8c276529edc1
parent e161f817bebecc1c1cc461dc83cce2eafbed9ee9
author Oliver Endriss <[EMAIL PROTECTED]> Fri, 08 Jul 2005 07:58:28 -0700
committer Linus Torvalds <[EMAIL PROTECTED]> Fri, 08 Jul 2005 08:24:02 -0700

[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 <[EMAIL PROTECTED]>
Signed-off-by: Johannes Stezenbach <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>

 drivers/media/common/saa7146_core.c |   11 +++--
 drivers/media/dvb/ttpci/av7110_hw.c |   72 ++++++++++++++++++++++++------------
 2 files changed, 56 insertions(+), 27 deletions(-)

diff --git a/drivers/media/common/saa7146_core.c 
b/drivers/media/common/saa7146_core.c
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -62,13 +62,15 @@ void saa7146_setgpio(struct saa7146_dev 
 int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
 {
        unsigned long start;
+       int err;
 
        /* wait for registers to be programmed */
        start = jiffies;
        while (1) {
-                if (saa7146_read(dev, MC2) & 2)
-                        break;
-               if (time_after(jiffies, start + HZ/20)) {
+               err = time_after(jiffies, start + HZ/20);
+               if (saa7146_read(dev, MC2) & 2)
+                       break;
+               if (err) {
                        DEB_S(("timed out while waiting for registers getting 
programmed\n"));
                        return -ETIMEDOUT;
                }
@@ -79,10 +81,11 @@ int saa7146_wait_for_debi_done(struct sa
        /* wait for transfer to complete */
        start = jiffies;
        while (1) {
+               err = time_after(jiffies, start + HZ/4);
                if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
                        break;
                saa7146_read(dev, MC2);
-               if (time_after(jiffies, start + HZ/4)) {
+               if (err) {
                        DEB_S(("timed out while waiting for transfer 
completion\n"));
                        return -ETIMEDOUT;
                }
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c 
b/drivers/media/dvb/ttpci/av7110_hw.c
--- 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 *
 {
        unsigned long start;
        u32 stat;
+       int err;
 
        if (FW_VERSION(av7110->arm_app) <= 0x261c) {
                /* not supported by old firmware */
@@ -318,14 +319,14 @@ int av7110_wait_msgstate(struct av7110 *
        /* new firmware */
        start = jiffies;
        for (;;) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
                if (down_interruptible(&av7110->dcomlock))
                        return -ERESTARTSYS;
                stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
                up(&av7110->dcomlock);
-               if ((stat & flags) == 0) {
+               if ((stat & flags) == 0)
                        break;
-               }
-               if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+               if (err) {
                        printk(KERN_ERR "%s: timeout waiting for MSGSTATE 
%04x\n",
                                __FUNCTION__, stat & flags);
                        return -ETIMEDOUT;
@@ -342,6 +343,7 @@ static int __av7110_send_fw_cmd(struct a
        char *type = NULL;
        u16 flags[2] = {0, 0};
        u32 stat;
+       int err;
 
 //     dprintk(4, "%p\n", av7110);
 
@@ -351,8 +353,11 @@ static int __av7110_send_fw_cmd(struct a
        }
 
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
-               if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+                       break;
+               if (err) {
                        printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for 
COMMAND idle\n", __FUNCTION__);
                        return -ETIMEDOUT;
                }
@@ -363,8 +368,11 @@ static int __av7110_send_fw_cmd(struct a
 
 #ifndef _NOHANDSHAKE
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
-               if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+                       break;
+               if (err) {
                        printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for 
HANDSHAKE_REG\n", __FUNCTION__);
                        return -ETIMEDOUT;
                }
@@ -401,6 +409,7 @@ static int __av7110_send_fw_cmd(struct a
                /* non-immediate COMMAND type */
                start = jiffies;
                for (;;) {
+                       err = time_after(jiffies, start + ARM_WAIT_FREE);
                        stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
                        if (stat & flags[0]) {
                                printk(KERN_ERR "%s: %s QUEUE overflow\n",
@@ -409,7 +418,7 @@ static int __av7110_send_fw_cmd(struct a
                        }
                        if ((stat & flags[1]) == 0)
                                break;
-                       if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+                       if (err) {
                                printk(KERN_ERR "%s: timeout waiting on busy %s 
QUEUE\n",
                                        __FUNCTION__, type);
                                return -ETIMEDOUT;
@@ -432,12 +441,13 @@ static int __av7110_send_fw_cmd(struct a
 
 #ifdef COM_DEBUG
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
-               if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+                       break;
+               if (err) {
                        printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for 
COMMAND %d to complete\n",
-                              __FUNCTION__,
-                               (buf[0] >> 8) & 0xff
-                              );
+                              __FUNCTION__, (buf[0] >> 8) & 0xff);
                        return -ETIMEDOUT;
                }
                msleep(1);
@@ -553,8 +563,11 @@ int av7110_fw_request(struct av7110 *av7
        }
 
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) {
-               if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_FREE);
+               if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+                       break;
+               if (err) {
                        printk(KERN_ERR "%s: timeout waiting for COMMAND to 
complete\n", __FUNCTION__);
                        up(&av7110->dcomlock);
                        return -ETIMEDOUT;
@@ -566,8 +579,11 @@ int av7110_fw_request(struct av7110 *av7
 
 #ifndef _NOHANDSHAKE
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
-               if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+                       break;
+               if (err) {
                        printk(KERN_ERR "%s: timeout waiting for 
HANDSHAKE_REG\n", __FUNCTION__);
                        up(&av7110->dcomlock);
                        return -ETIMEDOUT;
@@ -707,12 +723,16 @@ static inline int SetFont(struct av7110 
 static int FlushText(struct av7110 *av7110)
 {
        unsigned long start;
+       int err;
 
        if (down_interruptible(&av7110->dcomlock))
                return -ERESTARTSYS;
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
-               if (time_after(jiffies, start + ARM_WAIT_OSD)) {
+       while (1) {
+               err = time_after(jiffies, start + ARM_WAIT_OSD);
+               if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+                       break;
+               if (err) {
                        printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for 
BUFF1_BASE == 0\n",
                               __FUNCTION__);
                        up(&av7110->dcomlock);
@@ -735,8 +755,11 @@ static int WriteText(struct av7110 *av71
                return -ERESTARTSYS;
 
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
-               if (time_after(jiffies, start + ARM_WAIT_OSD)) {
+       while (1) {
+               ret = time_after(jiffies, start + ARM_WAIT_OSD);
+               if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+                       break;
+               if (ret) {
                        printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for 
BUFF1_BASE == 0\n",
                               __FUNCTION__);
                        up(&av7110->dcomlock);
@@ -746,8 +769,11 @@ static int WriteText(struct av7110 *av71
        }
 #ifndef _NOHANDSHAKE
        start = jiffies;
-       while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
-               if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+       while (1) {
+               ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
+               if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+                       break;
+               if (ret) {
                        printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for 
HANDSHAKE_REG\n",
                               __FUNCTION__);
                        up(&av7110->dcomlock);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to