modify the bug about host-state error
authorxbw <xbw@rock-chips.com>
Wed, 31 Aug 2011 06:34:13 +0000 (14:34 +0800)
committerxbw <xbw@rock-chips.com>
Wed, 31 Aug 2011 06:34:13 +0000 (14:34 +0800)
drivers/mmc/core/core.c [changed mode: 0644->0755]
drivers/mmc/host/rk29_sdmmc.c
include/linux/mmc/host.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index dd2a7a0..519722a
@@ -195,6 +195,7 @@ static void mmc_wait_done(struct mmc_request *mrq)
  */
 void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
 {
+    unsigned long waittime;
        DECLARE_COMPLETION_ONSTACK(complete);
 
        mrq->done_data = &complete;
@@ -203,7 +204,12 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
        mmc_start_request(host, mrq);
 
 #if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
-    wait_for_completion_timeout(&complete,HZ*3); //for cmd dead. Modifyed by xbw at 2011-06-02
+    waittime = wait_for_completion_timeout(&complete,HZ*7); //for cmd dead. Modifyed by xbw at 2011-06-02
+    if(waittime <= 1)
+    {
+        host->doneflag = 0;
+        printk("%s...%d..  =====!!!!!!!!!CMD%d timeout ===xbw===\n",__FUNCTION__, __LINE__, mrq->cmd->opcode);
+    }
 #else    
        wait_for_completion(&complete);
 #endif
index c8c42ffde1e608055fe8d8e3488a1a152908b8b6..6db516289c73213c43535d2dbe07b33e7c731303 100755 (executable)
@@ -72,7 +72,7 @@ int debug_level = 7;
 #define RK29_SDMMC_WAIT_DTO_INTERNVAL   1500  //The time interval from the CMD_DONE_INT to DTO_INT
 #define RK29_SDMMC_REMOVAL_DELAY        2000  //The time interval from the CD_INT to detect_timer react.
 
-#define RK29_SDMMC_VERSION "Ver.2.04 The last modify date is 2011-08-24,modifyed by XBW." 
+#define RK29_SDMMC_VERSION "Ver.2.05 The last modify date is 2011-08-29,modifyed by XBW." 
 
 #define RK29_CTRL_SDMMC_ID   0  //mainly used by SDMMC
 #define RK29_CTRL_SDIO1_ID   1  //mainly used by sdio-wifi
@@ -196,6 +196,7 @@ struct rk29_sdmmc {
 
     unsigned int            oldstatus;
     unsigned int            complete_done;
+    unsigned int            retryfunc;
 #ifdef CONFIG_PM
     int gpio_irq;
        int gpio_det;
@@ -209,6 +210,8 @@ static struct rk29_sdmmc    *globalSDhost[3];
 
 #define rk29_sdmmc_test_and_clear_pending(host, event)         \
        test_and_clear_bit(event, &host->pending_events)
+#define rk29_sdmmc_test_pending(host, event)           \
+       test_bit(event, &host->pending_events)
 #define rk29_sdmmc_set_completed(host, event)                  \
        set_bit(event, &host->completed_events)
 
@@ -677,7 +680,8 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command
                host->errorstep = 0x1;
                return SDM_WAIT_FOR_CMDSTART_TIMEOUT;
        }
-
+    host->mmc->doneflag = 1;
+    
        return SDM_SUCCESS;
 }
 
@@ -732,7 +736,7 @@ static int rk29_sdmmc_wait_unbusy(struct rk29_sdmmc *host)
 
 static void send_stop_cmd(struct rk29_sdmmc *host)
 {
-    mod_timer(&host->request_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_SEND_START_TIMEOUT+250));
+    mod_timer(&host->request_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_SEND_START_TIMEOUT+600));
                
     host->stopcmd.opcode = MMC_STOP_TRANSMISSION;
     host->stopcmd.flags  = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;;
@@ -1681,7 +1685,6 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
        mrq = host->new_mrq;
        cmd = mrq->cmd;
        cmd->error = 0;
-       host->complete_done = 0;
        
        cmdr = rk29_sdmmc_prepare_command(cmd);
        ret = SDM_SUCCESS;
@@ -1735,6 +1738,8 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
        
        host->errorstep = 0;
        host->dodma = 0;
+    host->complete_done = 0;
+    host->retryfunc = 0;
 
     if(RK29_CTRL_SDMMC_ID == host->pdev->id)
     {
@@ -2381,11 +2386,12 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
        struct rk29_sdmmc       *host = (struct rk29_sdmmc *)priv;
        struct mmc_data         *data = host->cmd->data;
        enum rk29_sdmmc_state   state = host->state;
-
+       int pending_flag;
+    
        spin_lock(&host->lock);
-
-       state = host->state;
        
+       state = host->state;
+       pending_flag = 0;
        do 
        {
         switch (state) 
@@ -2419,7 +2425,7 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
                                                        __FUNCTION__, __LINE__,host->cmd->opcode,host->dma_name);
                     
                     host->complete_done = 1;
-                    goto unlock;
+                    break;//goto unlock;
                 }
 
                 if(host->cmd->error)
@@ -2440,7 +2446,7 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
                 }
 
 
-                state = STATE_DATA_BUSY; 
+                state = STATE_DATA_BUSY;
                 /* fall through */
             }
 
@@ -2465,7 +2471,7 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
                     if(!( (MMC_READ_SINGLE_BLOCK == host->cmd->opcode)&&( -EIO == data->error))) //deal with START_BIT_ERROR
                     {
                        host->complete_done = 1;
-                       goto unlock;
+                       break;//goto unlock;
                     }
 
                 }
@@ -2491,11 +2497,22 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
                 rk29_sdmmc_request_end(host, host->cmd);
                 
                 host->complete_done = 1;
-                goto unlock;
+                break;//goto unlock;
             }
                
         }
-       } while(0);
+
+        pending_flag = (1==host->complete_done) && (host->retryfunc<50) \
+                       && (rk29_sdmmc_test_pending(host, EVENT_CMD_COMPLETE)|| rk29_sdmmc_test_pending(host, EVENT_DATA_COMPLETE) );
+        if(pending_flag)
+        {
+            printk("%s..%d...  cmd=%d(arg=0x%x),retrycount=%d, host->state=0x%x,\n   pendingEvent=0x%lu, completeEvents=0x%lu ====xbw[%s]====\n",\
+                __FUNCTION__, __LINE__,host->cmd->opcode,host->cmd->arg, host->retryfunc, host->state,  \
+                host->pending_events,host->completed_events,host->dma_name);
+            cpu_relax();
+        }
+                        
+       } while(pending_flag && ++host->retryfunc); //while(0);
 
        host->state = state;
                
@@ -2509,7 +2526,7 @@ unlock:
         host->state = STATE_IDLE;
         spin_unlock(&host->lock);
 
-        if(host->mrq)
+        if(host->mrq && host->mmc->doneflag)
         {
            mmc_request_done(host->mmc, host->mrq);
         }
@@ -2620,6 +2637,9 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
 
         rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_SDIO);
         mmc_signal_sdio_irq(host->mmc);
+
+        spin_unlock_irqrestore(&host->lock, iflags);
+        return IRQ_HANDLED;
     }
 
 
@@ -2810,6 +2830,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
        host->error_times = 0;
        host->state = STATE_IDLE;
        host->complete_done = 0;
+       host->retryfunc = 0;
        host->mrq = NULL;
        host->new_mrq = NULL;
        
@@ -2871,6 +2892,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
                      | MMC_VDD_31_32|MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_34_35| MMC_VDD_35_36;    ///set valid volage 2.7---3.6v
        mmc->caps = pdata->host_caps;
        mmc->re_initialized_flags = 1;
+       mmc->doneflag = 1;
 
     /*
         * We can do SGIO
@@ -2902,6 +2924,11 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
 
        tasklet_init(&host->tasklet, rk29_sdmmc_tasklet_func, (unsigned long)host);
 
+    /* Create card detect handler thread  */
+       setup_timer(&host->detect_timer, rk29_sdmmc_detect_change,(unsigned long)host);
+       setup_timer(&host->request_timer,rk29_sdmmc_INT_CMD_DONE_timeout,(unsigned long)host);
+       setup_timer(&host->DTO_timer,rk29_sdmmc_INT_DTO_timeout,(unsigned long)host);
+
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
        {
@@ -2991,10 +3018,6 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
         }
     }
 
-    /* Create card detect handler thread  */
-       setup_timer(&host->detect_timer, rk29_sdmmc_detect_change,(unsigned long)host);
-       setup_timer(&host->request_timer,rk29_sdmmc_INT_CMD_DONE_timeout,(unsigned long)host);
-       setup_timer(&host->DTO_timer,rk29_sdmmc_INT_DTO_timeout,(unsigned long)host);
 
        platform_set_drvdata(pdev, mmc);        
 
old mode 100644 (file)
new mode 100755 (executable)
index f19c1cf..4125ef5
@@ -204,6 +204,7 @@ struct mmc_host {
 #define MMC_BUSRESUME_NEEDS_RESUME     (1 << 1)
 
     unsigned int               re_initialized_flags; //in order to begin the rescan ;  added by xbw@2011-04-07
+    unsigned int        doneflag;//added by xbw at 2011-08-27
 
        unsigned int            sdio_irqs;
        struct task_struct      *sdio_irq_thread;