Re: [BUG: barebox-git] failure at common/block.c:248/block_put()!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



More information ...
 
I am pretty sure we need to switch to 1BIT transfer and/or using the SDHCI_BROKEN_TIMEOUT_VAL quirk. I'll try to find out if I can add this functionality to barebox, unless you believe there's something else which causes this behaviour.

I'll keep investigating ...

Added more debugging information, which pretty much pinpoints the culprit from a software point of view: 

diff --git a/common/block.c b/common/block.c
index 4253fc4..5e0b50a 100644
--- a/common/block.c
+++ b/common/block.c
@@ -142,6 +142,7 @@ static int block_cache(struct block_device *blk, int block)
        num_blocks = min(blk->rdbufsize, blk->num_blocks - chunk->block_start);
 
        ret = blk->ops->read(blk, chunk->data, chunk->block_start, num_blocks);
+       printf("%s: blk->ops->read returned %d\n", __func__, ret);
        if (ret) {
                list_add_tail(&chunk->list, &blk->idle_blocks);
                return ret;
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index ae3c805..024e18e 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -24,6 +24,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
+
+#define DEBUG
+
 #include <config.h>
 #include <common.h>
 #include <driver.h>
@@ -239,6 +242,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data
        struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
        struct fsl_esdhc *regs = host->regs;
        int ret;
+       int loop;
 
        esdhc_write32(&regs->irqstat, -1);
 
@@ -280,6 +284,18 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *dat
        /* Wait for the command to complete */
        ret = wait_on_timeout(100 * MSECOND,
                        esdhc_read32(&regs->irqstat) & IRQSTAT_CC);
+       loop = 1;
+       while (ret && loop <=10) {
+               printf("%s: busy loop %d start\n", __func__, loop);
+               ret = wait_on_timeout(100 * MSECOND,
+                       esdhc_read32(&regs->irqstat) & IRQSTAT_CC);
+               printf("%s: busy loop %d end, cap=0x%08x, irqstat=0x%08x, prsstat=0x%08x\n",
+                       __func__, loop,
+                       esdhc_read32(&host->regs->hostcapblt),
+                       esdhc_read32(&regs->irqstat),
+                       esdhc_read32(&regs->prsstat));
+               loop++;
+       }
        if (ret) {
                dev_err(host->dev, "timeout 1\n");
                return -ETIMEDOUT;

It clearly hangs because the IRQSTAT_CC is never set in &regs->irqstat. Now, I am not familiar enough with the quirks of the ESDHC technology to know why the host never receives or sees the IRQ of a command complete, however this behaviour pretty much renders my eSDHC interface unusable. See output below:

sid1-noah:/ mount /dev/disk0.0 fat /mnt
block_cache: blk->ops->read returned 0
sid1-noah:/ cp /mnt/conblock_cache: blk->ops->read returned 0
sole_image.jffs2 /mnt/console_image.jffs2-backup
block_cache: blk->ops->read returned 0
block_cache: blk->ops->read returned 0
block_cache: blk->ops->read returned 0
block_cache: blk->ops->read returned 0
block_cache: blk->ops->read returned 0
block_cache: blk->ops->read returned 0

Data Write Failed in PIO Mode.imx-esdhc@imx-esdhc0: timeout 2
esdhc_send_cmd: busy loop 1 start
esdhc_send_cmd: busy loop 1 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 2 start
esdhc_send_cmd: busy loop 2 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 3 start
esdhc_send_cmd: busy loop 3 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 4 start
esdhc_send_cmd: busy loop 4 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 5 start
esdhc_send_cmd: busy loop 5 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 6 start
esdhc_send_cmd: busy loop 6 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 7 start
esdhc_send_cmd: busy loop 7 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 8 start
esdhc_send_cmd: busy loop 8 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 9 start
esdhc_send_cmd: busy loop 9 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 10 start
esdhc_send_cmd: busy loop 10 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
imx-esdhc@imx-esdhc0: timeout 1
esdhc_send_cmd: busy loop 1 start
esdhc_send_cmd: busy loop 1 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 2 start
esdhc_send_cmd: busy loop 2 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 3 start
esdhc_send_cmd: busy loop 3 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 4 start
esdhc_send_cmd: busy loop 4 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 5 start
esdhc_send_cmd: busy loop 5 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 6 start
esdhc_send_cmd: busy loop 6 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 7 start
esdhc_send_cmd: busy loop 7 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 8 start
esdhc_send_cmd: busy loop 8 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 9 start
esdhc_send_cmd: busy loop 9 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 10 start
esdhc_send_cmd: busy loop 10 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
imx-esdhc@imx-esdhc0: timeout 1
esdhc_send_cmd: busy loop 1 start
esdhc_send_cmd: busy loop 1 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 2 start
esdhc_send_cmd: busy loop 2 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 3 start
esdhc_send_cmd: busy loop 3 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 4 start
esdhc_send_cmd: busy loop 4 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 5 start
esdhc_send_cmd: busy loop 5 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 6 start
esdhc_send_cmd: busy loop 6 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 7 start
esdhc_send_cmd: busy loop 7 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 8 start
esdhc_send_cmd: busy loop 8 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 9 start
esdhc_send_cmd: busy loop 9 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
esdhc_send_cmd: busy loop 10 start
esdhc_send_cmd: busy loop 10 end, cap=0x07f30000, irqstat=0x00000000, prsstat=0xf7880587
imx-esdhc@imx-esdhc0: timeout 1
block_cache: blk->ops->read returned -110
BUG: failure at common/block.c:249/block_put()!
BUG!
[<83f349a4>] (unwind_backtrace+0x0/0x9c) from [<83f1c094>] (panic+0x28/0x3c)
[<83f1c094>] (panic+0x28/0x3c) from [<83f05900>] (block_put+0x48/0x8c)
[<83f05900>] (block_put+0x48/0x8c) from [<83f059ec>] (block_write+0xa8/0x120)
[<83f059ec>] (block_write+0xa8/0x120) from [<83f2d478>] (cdev_write+0x30/0x34)
[<83f2d478>] (cdev_write+0x30/0x34) from [<83f30970>] (disk_write+0x24/0x30)
[<83f30970>] (disk_write+0x24/0x30) from [<83f2fabc>] (f_write+0x160/0x27c)
[<83f2fabc>] (f_write+0x160/0x27c) from [<83f30730>] (fat_write+0x18/0x30)
[<83f30730>] (fat_write+0x18/0x30) from [<83f31220>] (write+0xac/0xd0)
[<83f31220>] (write+0xac/0xd0) from [<83f21864>] (copy_file+0xec/0x17c)
[<83f21864>] (copy_file+0xec/0x17c) from [<83f191e0>] (do_cp+0x124/0x158)
[<83f191e0>] (do_cp+0x124/0x158) from [<83f07bb0>] (execute_command+0x38/0x7c)
[<83f07bb0>] (execute_command+0x38/0x7c) from [<83f03bc8>] (run_list_real+0x8a0/0x998)
[<83f03bc8>] (run_list_real+0x8a0/0x998) from [<83f03e04>] (parse_stream_outer+0x144/0x240)
[<83f03e04>] (parse_stream_outer+0x144/0x240) from [<83f041fc>] (run_shell+0x3c/0x5c)
[<83f041fc>] (run_shell+0x3c/0x5c) from [<83f09640>] (start_barebox+0xd4/0x110)
[<83f09640>] (start_barebox+0xd4/0x110) from [<8010206c>] (0x8010206c)

Removing the loop<=10 limit throws the code into a livelock.

Any suggestions?

Cheers
Roberto
_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox

[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux