lkml.org 
[lkml]   [2005]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[DVB patch 3/8] ttpci: fix timeout handling to be save with PREEMPT
    From: Oliver Endriss <o.endriss@gmx.de>

    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>

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

    Index: linux-2.6.13-rc1-mm1/drivers/media/common/saa7146_core.c
    ===================================================================
    --- linux-2.6.13-rc1-mm1.orig/drivers/media/common/saa7146_core.c 2005-07-02 03:22:09.000000000 +0200
    +++ linux-2.6.13-rc1-mm1/drivers/media/common/saa7146_core.c 2005-07-02 03:22:28.000000000 +0200
    @@ -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;
    }
    Index: linux-2.6.13-rc1-mm1/drivers/media/dvb/ttpci/av7110_hw.c
    ===================================================================
    --- linux-2.6.13-rc1-mm1.orig/drivers/media/dvb/ttpci/av7110_hw.c 2005-07-02 03:22:09.000000000 +0200
    +++ linux-2.6.13-rc1-mm1/drivers/media/dvb/ttpci/av7110_hw.c 2005-07-02 03:22:28.000000000 +0200
    @@ -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 linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-07-02 04:11    [W:0.033 / U:214.108 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site