注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

嵌入式开发实战4——内核的编译之十八MMC(SD、SDIO)卡的驱动说明7  

2012-08-27 21:04:18|  分类: ARM开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 

接着上回,说mmc_wait_for_req这个函数,这个函数看上去很简单:

mmc/core/core.c

184  /**         

185  *    mmc_wait_for_req - start a request and wait for completion     

186  *    @host: MMC host to start command    

187  *    @mrq: MMC request to start

188  *          

189  *    Start a new MMC custom command request for a host, and wait

190  *    for the command to complete. Does not attempt to parse the     

191  *    response.

192  */         

193  void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)            

194  {           

195         DECLARE_COMPLETION_ONSTACK(complete);  

196               

197         mrq->done_data = &complete;    

198         mrq->done = mmc_wait_done;    

199               

200         mmc_start_request(host, mrq);

201        

202         wait_for_completion(&complete);

203  }    

少吧,不过,历来的经验告诉我们,越简单的,恐怕越不简单.先看第200行mmc_start_request

mmc/core/core.c

121  static void                    

122  mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)                   

123  {                  

124  #ifdef CONFIG_MMC_DEBUG                

125         unsigned int i, sz;         

126         struct scatterlist *sg;            

127  #endif                  

128                      

129         pr_debug("%s: starting CMD%u arg %08x flags %08x\n",       

130                mmc_hostname(host), mrq->cmd->opcode,      

131                mrq->cmd->arg, mrq->cmd->flags); 

132                      

133         if (mrq->data) {           

134                pr_debug("%s:     blksz %d blocks %d flags %08x "     

135                       tsac %d ms nsac %d\n,

136                       mmc_hostname(host), mrq->data->blksz,

137                       mrq->data->blocks, mrq->data->flags,

138                       mrq->data->timeout_ns / 1000000,

139                       mrq->data->timeout_clks);

140         }           

141                      

142         if (mrq->stop) {           

143                pr_debug("%s:     CMD%u arg %08x flags %08x\n",    

144                       mmc_hostname(host), mrq->stop->opcode,

145                       mrq->stop->arg, mrq->stop->flags);

146         }           

147                      

148         WARN_ON(!host->claimed);       

149                      

150         led_trigger_event(host->led, LED_FULL);         

151                      

152         mrq->cmd->error = 0;         

153         mrq->cmd->mrq = mrq;             

154         if (mrq->data) {           

155                BUG_ON(mrq->data->blksz > host->max_blk_size); 

156                BUG_ON(mrq->data->blocks > host->max_blk_count);    

157                BUG_ON(mrq->data->blocks * mrq->data->blksz >  

158                       host->max_req_size);

159                      

160  #ifdef CONFIG_MMC_DEBUG                

161                sz = 0;    

162                for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i)      

163                       sz += sg->length;

164                BUG_ON(sz != mrq->data->blocks * mrq->data->blksz);  

165  #endif                  

166                      

167                mrq->cmd->data = mrq->data;    

168                mrq->data->error = 0;  

169                mrq->data->mrq = mrq;

170                if (mrq->stop) {    

171                       mrq->data->stop = mrq->stop;

172                       mrq->stop->error = 0;

173                       mrq->stop->mrq = mrq;

174                }    

175         }           

176         host->ops->request(host, mrq);           

177  }    

149行以前的代码基本是为了调试输出用的.不管他.

150 LED是为了用LED灯来控制一些具体的硬件的工作状态.

/* Simple LED Tigger Interface */

 

void led_trigger_event(struct led_trigger *trigger,

                     enum led_brightness brightness)

{

       struct list_head *entry;

 

       if (!trigger)

              return;

 

       read_lock(&trigger->leddev_list_lock);

       list_for_each(entry, &trigger->led_cdevs) {

              struct led_classdev *led_cdev;

 

              led_cdev = list_entry(entry, struct led_classdev, trig_list);

              led_set_brightness(led_cdev, brightness);

       }

       read_unlock(&trigger->leddev_list_lock);

}

回到mmc_wait_for_req

202行wait_for_completion(&complete);典型的complete机制, wait_for_completion以后的结果就是调用线程你可以进入冬眠了,什么时候儿需要了,会呼唤你.当然,会同时放开同步机制.

197-198行mmc_wait_done等待完成,进去看看

mmc/core/core.c

179  static void mmc_wait_done(struct mmc_request *mrq)      

180  {    

181         complete(mrq->done_data);

182  }    

181行确是complete,而且complete就是wait_for_completion的那个对象 mmc_wait_for_cmd

该轮到mmc_wait_for_cmd了,他的源码:

mmc/core/core.c

217  int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)

218  {                  

219         struct mmc_request mrq;             

220                      

221         WARN_ON(!host->claimed);       

222                      

223         memset(&mrq, 0, sizeof(struct mmc_request));         

224                      

225         memset(cmd->resp, 0, sizeof(cmd->resp));        

226         cmd->retries = retries;         

227                      

228         mrq.cmd = cmd;          

229         cmd->data = NULL;            

230                      

231         mmc_wait_for_req(host, &mrq);        

232                      

233         return cmd->error;       

234  }           

命令的提交形式与数据请求的有点区别,至少没能构建一个完整的struct mmc_request结构。但是最终却都是调用了mmc_wait_for_req。至于这些个struct mmc_command 、

struct mmc_reques现在确实不方便也没办法说清楚,说到真正作用在硬件上的传输过程之时,也将是揭开他神秘面纱之日。

       到这里,基本就讲完一小段了,再讲CORE,就得等HOST讲完了。不能厚此薄彼。

 

时间过得真快啊,这个月就又要过去了。

  评论这张
 
阅读(1684)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017