This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Thread deadlock in high level disk driver?


Hello everyone,

I have found something strange in de High level Disk Driver (/packages/io/disk/current/src/disk.c).
I am using this to access the mmc_spi driver and an spi driver I wrote myself.
When something goes wrong in the mmc_spi or spi driver, a deadlock occurs leaving the disk controller busy.


The functions disk_bread and disk_bwrite contains 'goto done;' statements. In the case these goto statements
are executed (probably something wrong in low level driver), the ctrl->busy is not cleared to false and any subsequent
calls to the disk driver result in a cyg_drv_cond_wait. (putting the thread it's in to sleep)


For now i have patched to code as follows below to prevent this from happening.
Maybe this code is intended to lock the disk controller when an error occurs?


Any comments anyone?
Tnx,
Kind regards,
Davy Wouters

*** disk.c Wed Dec  1 10:38:15 2010
--- _disk.c Wed Dec  1 10:37:47 2010
***************
*** 560,570 ****
--- 560,576 ----
             cyg_drv_dsr_unlock();

             if (ENOERR != res)
+             {
+     ctlr->busy = false;
+     cyg_drv_cond_signal( &ctlr->queue );
                 goto done;
+             }

             if (!info->connected)
             {
                 res = -EINVAL;
+                 ctlr->busy = false;
+                 cyg_drv_cond_signal( &ctlr->queue );
                 goto done;
             }

***************
*** 636,642 ****
             if (pos > last)
             {
                 res = -EIO;
!                 goto done;
             }

             if( tfr > info->ident.max_transfer )
--- 642,648 ----
             if (pos > last)
             {
                 res = -EIO;
!                 break;
             }

             if( tfr > info->ident.max_transfer )
***************
*** 664,674 ****
--- 670,686 ----
             cyg_drv_dsr_unlock();

             if (ENOERR != res)
+             {
+     ctlr->busy = false;
+     cyg_drv_cond_signal( &ctlr->queue );
                 goto done;
+             }

             if (!info->connected)
+     ctlr->busy = false;
+     cyg_drv_cond_signal( &ctlr->queue );
                 goto done;
             }




-- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]