• do_write_buffer()超时的补丁


    最近测试发现写flash文件时报错:

    MTD do_write_buffer(): software timeout
    Write of 839 bytes at 0x00017dac failed. returned -5, retlen 596

    从网上找了个补丁,不知道是否管用

    From: Markus Niebel <list-09_linux_mtd <at> tqsc.de>
    Subject: [PATCH 2.6.34 1/2] cfi_cmdset_0002.c: Read max timeouts from cfi query data
    Newsgroups: gmane.linux.drivers.mtd
    Date: 2011-03-25 07:52:39 GMT (3 weeks, 3 days, 21 hours and 59 minutes ago)

    The max timeouts are coded in the electronic flash data sheet (CFI query
    data). Read the timeouts and store them in the chips structure table.

    Signed-off-by: Markus Niebel <markus.niebel <at> tqs.de>
    ---

    drivers/mtd/chips/cfi_cmdset_0002.c | 21 +++++++++++++++++++++
    1 files changed, 21 insertions(+), 0 deletions(-)

    diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c
    b/drivers/mtd/chips/cfi_cmdset_0002.c
    index 38c47b0..1eb8bfa 100644
    --- a/drivers/mtd/chips/cfi_cmdset_0002.c
    +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
    @@ -429,6 +429,27 @@ struct mtd_info *cfi_cmdset_0002(struct map_info
    *map, int primary)
    cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
    cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
    cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
    +
    + /* FIXME: use also max times, verify if valid */
    + cfi->chips[i].word_write_time_max =
    + (1<<(cfi->cfiq->WordWriteTimeoutTyp)) *
    + (1<<(cfi->cfiq->WordWriteTimeoutMax));
    + cfi->chips[i].buffer_write_time_max =
    + (1<<(cfi->cfiq->BufWriteTimeoutTyp)) *
    + (1<<(cfi->cfiq->BufWriteTimeoutMax));
    + cfi->chips[i].erase_time_max =
    + (1<<(cfi->cfiq->BlockEraseTimeoutTyp)) *
    + (1<<(cfi->cfiq->BlockEraseTimeoutMax));
    +
    + printk(KERN_INFO "MTD: %s erase time %u / %u ms\n", __func__,
    + cfi->chips[i].erase_time, cfi->chips[i].erase_time_max);
    + printk(KERN_INFO "MTD: %s word time %u / %u us\n", __func__,
    + cfi->chips[i].word_write_time,
    + cfi->chips[i].word_write_time_max);
    + printk(KERN_INFO "MTD: %s buffer time %u / %u us\n", __func__,
    + cfi->chips[i].buffer_write_time,
    + cfi->chips[i].buffer_write_time_max);
    +
    cfi->chips[i].ref_point_counter = 0;
    init_waitqueue_head(&(cfi->chips[i].wq));
    }

    From: Markus Niebel <list-09_linux_mtd <at> tqsc.de>
    Subject: [PATCH 2.6.34 2/2] cfi_cmdset_0002.c: Use maxtimeouts for erase and program instead of hardcoded values
    Newsgroups: gmane.linux.drivers.mtd
    Date: 2011-03-25 07:56:04 GMT (3 weeks, 3 days, 21 hours and 56 minutes ago)
    Maximum timeouts are read from the CFI query structure and stored in the
    chips structure table. Use the timeouts for erase and program instead of
    fixed values.

    Signed-off-by: Markus Niebel <markus.niebel <at> tqs.de>
    ---

    drivers/mtd/chips/cfi_cmdset_0002.c | 47
    +++++++++++++++++------------------
    1 files changed, 23 insertions(+), 24 deletions(-)

    diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c
    b/drivers/mtd/chips/cfi_cmdset_0002.c
    index 1eb8bfa..d64939f 100644
    --- a/drivers/mtd/chips/cfi_cmdset_0002.c
    +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
    @@ -1074,17 +1074,13 @@ static int cfi_amdstd_secsi_read (struct
    mtd_info *mtd, loff_t from, size_t len,
    static int __xipram do_write_oneword(struct map_info *map, struct
    flchip *chip, unsigned long adr, map_word datum)
    {
    struct cfi_private *cfi = map->fldrv_priv;
    - unsigned long timeo = jiffies + HZ;
    - /*
    - * We use a 1ms + 1 jiffies generic timeout for writes (most devices
    - * have a max write time of a few hundreds usec). However, we should
    - * use the maximum timeout value given by the chip at probe time
    - * instead. Unfortunately, struct flchip does have a field for
    - * maximum timeout, only for typical which can be far too short
    - * depending of the conditions. The ' + 1' is to avoid having a
    - * timeout of 0 jiffies if HZ is smaller than 1000.
    + unsigned long timeo;
    +
    + /* use the max timeout read from cfi, increase by one to make sure it's
    + * not zero
    */
    - unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
    + unsigned long write_timeout =
    usecs_to_jiffies(chip->word_write_time_max) + 1;
    +
    int ret = 0;
    map_word oldd;
    int retry_cnt = 0;
    @@ -1129,7 +1125,7 @@ static int __xipram do_write_oneword(struct
    map_info *map, struct flchip *chip,
    chip->word_write_time);

    /* See comment above for timeout value. */
    - timeo = jiffies + uWriteTimeout;
    + timeo = jiffies + write_timeout;
    for (;;) {
    if (chip->state != FL_WRITING) {
    /* Someone's suspended the write. Sleep */
    @@ -1140,7 +1136,7 @@ static int __xipram do_write_oneword(struct
    map_info *map, struct flchip *chip,
    spin_unlock(chip->mutex);
    schedule();
    remove_wait_queue(&chip->wq, &wait);
    - timeo = jiffies + (HZ / 2); /* FIXME */
    + timeo = jiffies + write_timeout;
    spin_lock(chip->mutex);
    continue;
    }
    @@ -1329,9 +1325,9 @@ static int __xipram do_write_buffer(struct
    map_info *map, struct flchip *chip,
    int len)
    {
    struct cfi_private *cfi = map->fldrv_priv;
    - unsigned long timeo = jiffies + HZ;
    - /* see comments in do_write_oneword() regarding uWriteTimeo. */
    - unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
    + unsigned long timeo;
    + /* see comments in do_write_oneword() regarding write_timeout. */
    + unsigned long write_timeout =
    usecs_to_jiffies(chip->buffer_write_time_max) + 1;
    int ret = -EIO;
    unsigned long cmd_adr;
    int z, words;
    @@ -1387,9 +1383,9 @@ static int __xipram do_write_buffer(struct
    map_info *map, struct flchip *chip,

    INVALIDATE_CACHE_UDELAY(map, chip,
    adr, map_bankwidth(map),
    - chip->word_write_time);
    + chip->buffer_write_time);

    - timeo = jiffies + uWriteTimeout;
    + timeo = jiffies + write_timeout;

    for (;;) {
    if (chip->state != FL_WRITING) {
    @@ -1401,7 +1397,7 @@ static int __xipram do_write_buffer(struct
    map_info *map, struct flchip *chip,
    spin_unlock(chip->mutex);
    schedule();
    remove_wait_queue(&chip->wq, &wait);
    - timeo = jiffies + (HZ / 2); /* FIXME */
    + timeo = jiffies + write_timeout;
    spin_lock(chip->mutex);
    continue;
    }
    @@ -1523,7 +1519,8 @@ static int cfi_amdstd_write_buffers(struct
    mtd_info *mtd, loff_t to, size_t len,
    static int __xipram do_erase_chip(struct map_info *map, struct flchip
    *chip)
    {
    struct cfi_private *cfi = map->fldrv_priv;
    - unsigned long timeo = jiffies + HZ;
    + unsigned long wait_time = msecs_to_jiffies(chip->erase_time_max) + 1;
    + unsigned long timeo;
    unsigned long int adr;
    DECLARE_WAITQUEUE(wait, current);
    int ret = 0;
    @@ -1559,7 +1556,7 @@ static int __xipram do_erase_chip(struct map_info
    *map, struct flchip *chip)
    adr, map->size,
    chip->erase_time*500);

    - timeo = jiffies + (HZ*20);
    + timeo = jiffies + wait_time;

    for (;;) {
    if (chip->state != FL_ERASING) {
    @@ -1575,7 +1572,7 @@ static int __xipram do_erase_chip(struct map_info
    *map, struct flchip *chip)
    if (chip->erase_suspended) {
    /* This erase was suspended and resumed.
    Adjust the timeout */
    - timeo = jiffies + (HZ*20); /* FIXME */
    + timeo = jiffies + wait_time;
    chip->erase_suspended = 0;
    }

    @@ -1613,7 +1610,8 @@ static int __xipram do_erase_chip(struct map_info
    *map, struct flchip *chip)
    static int __xipram do_erase_oneblock(struct map_info *map, struct
    flchip *chip, unsigned long adr, int len, void *thunk)
    {
    struct cfi_private *cfi = map->fldrv_priv;
    - unsigned long timeo = jiffies + HZ;
    + unsigned long timeo;
    + unsigned long wait_time = msecs_to_jiffies(chip->erase_time_max) + 1;
    DECLARE_WAITQUEUE(wait, current);
    int ret = 0;

    @@ -1644,11 +1642,12 @@ static int __xipram do_erase_oneblock(struct
    map_info *map, struct flchip *chip,
    chip->erase_suspended = 0;
    chip->in_progress_block_addr = adr;

    + /* FIXME: erase time is in msec, so timeout is half of the typical
    erase time? */
    INVALIDATE_CACHE_UDELAY(map, chip,
    adr, len,
    chip->erase_time*500);

    - timeo = jiffies + (HZ*20);
    + timeo = jiffies + wait_time;

    for (;;) {
    if (chip->state != FL_ERASING) {
    @@ -1664,7 +1663,7 @@ static int __xipram do_erase_oneblock(struct
    map_info *map, struct flchip *chip,
    if (chip->erase_suspended) {
    /* This erase was suspended and resumed.
    Adjust the timeout */
    - timeo = jiffies + (HZ*20); /* FIXME */
    + timeo = jiffies + wait_time;
    chip->erase_suspended = 0;
    }
    if (time_after(jiffies, timeo) && !chip_good(map, adr,
    map_word_ff(map))) {

    ______________________________________________________
    Linux MTD discussion mailing list
    http://lists.infradead.org/mailman/listinfo/linux-mtd/

  • 相关阅读:
    jhljx跑跑跑(找规律)
    FFT教你做乘法(FFT傅里叶变换)
    寻找最远点对(凸包求解)
    捡火柴的Nova君(n个线段相交问题)
    生命游戏/Game of Life的Java实现
    如果看了此文你还不懂傅里叶变换,那就过来掐死我吧【完整版】(转)
    北航第十一届程序设计竞赛网络预赛题解
    LeetCode 3 Longest Substring Without Repeating Characters(最长不重复子序列)
    UVa 112
    LeetCode 2 Add Two Numbers(链表操作)
  • 原文地址:https://www.cnblogs.com/GoodGoodWorkDayDayUp/p/2021043.html
Copyright © 2020-2023  润新知