Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1255634
  • 博文数量: 261
  • 博客积分: 4196
  • 博客等级: 上校
  • 技术积分: 3410
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-17 17:05
文章分类

全部博文(261)

文章存档

2018年(1)

2017年(22)

2016年(2)

2015年(8)

2014年(27)

2013年(40)

2012年(161)

分类: LINUX

2013-11-06 18:26:20

原文地址:http://blog.csdn.net/rain0993/article/details/8476755

SD卡驱动分三层结构分别对应driver/mmc目录下的cardhostcore三个文件夹。其层次关系如下所示:


块设备驱动层(linux/block

内核空间file_operations调用

块设备请求处理(linux/driver/mmc/card

MMC核心层

linux/driver/mmc/core

mmc主机控制器mmc_host_ops

linux/driver/mmc/host

 

底层硬件(SD/MMC...

     分析过程分目录进行,为了与块设备层驱动接轨,这里我们以自顶向下的分析方法来处理SD卡的设备驱动。与块层联系最紧密的就是card目录,首先来看看与块设备接口的部分内容。

块请求处理(linux/driver/mmc/card)

1.     probe

       按照惯例我们还是先来看下内核地图KconfigMakefile....

kconfig所给的信息来看我们最最关心的还是第7行和第17行,config MMC_BLOCKconfig MMC_BLOCK_BOUNCE。其中config MMC_BLOCK是整个MMC层工作的核心,对应于Makefile我们关注如下两行:

obj-$(CONFIG_MMC_BLOCK)          += mmc_block.o

mmc_block-objs                   := block.o queue.o

单凭直觉我们不难发现block.c是我们整个card目录的入口,打开文件不难发现在文件末尾处module_init(mmc_blk_init);将整个card目录入口描绘的淋漓尽致。还是来看看mmc_blk_init的相关内容。

[card/block.c]

673 static int __init mmc_blk_init(void)           

674 {           

675        int res;   

676               

677        res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");   

678        if (res)   

679               goto out;

680               

681        res =mmc_register_driver(&mmc_driver); 

682        if (res)   

683               goto out2;

684               

685        return 0; 

686 out2:    

687        unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");

688 out:      

689        return res;

690 }    

667行开门见山,注册块设备驱动。相信看过LDD3的哥们都知道这个函数并无大用,他的作用也远没有他名字来的那般响亮。最多也就动态分配一个主设备号,然后在proc/device中留下点不为人知的记号,真正充NB的还是后面我们看到的add_disk

681行看似新鲜,不过看名字也就是往mmc core里注册点啥。他这一注册不打紧,关键是乱了我们的阵脚,说好了现在只说card目录的要是看了他就惹上core了,不看吧也就没法往下走了。干脆看一点点算了.....

[core/bus.c]

164 int mmc_register_driver(struct mmc_driver *drv)      

165 {    

166        drv->drv.bus = &mmc_bus_type;

167        return driver_register(&drv->drv);

168 }

166行和167知道一点点设备模型的哥们,估计在这里就要兴奋了。估计也就能猜到这个core大致都干了些啥勾当。不说别的166行的mmc_bus_type这条总线总得有人维护吧,自古以来这个又脏又累的活儿就是core干的,这里当然也不例外,不过这是后话。167行注册了个device_driver那当然也有个device了,至于他在哪我们留点神秘感以后再说。只知道有了driver_register自然会发生点啥,至少bus probe是肯定会调用的,下面就来看看这条总线究竟长啥样…

[core/bus.c]

139 static struct bus_type mmc_bus_type = {                   

140        .name             = "mmc",

141        .dev_attrs       = mmc_dev_attrs,  

142        .match            = mmc_bus_match,

143        .uevent           = mmc_bus_uevent,

144        .probe            = mmc_bus_probe,

145        .remove          = mmc_bus_remove,

146        .suspend  = mmc_bus_suspend,    

147        .resume          = mmc_bus_resume,

148 };

144probe之前先还是要match那么一下,match上了后面才会进一步去枚举。这里match方法和简单,直接返回1。全部调用probe,下面跟踪一下这个probe函数。

[core/bus.c]

99   static int mmc_bus_probe(struct device *dev)                   

100 {                  

101        struct mmc_driver *drv = to_mmc_driver(dev->driver);           

102        struct mmc_card *card = dev_to_mmc_card(dev);            

103                      

104        return drv->probe(card);             

105 }                  

101行和102行很明显mmc_driver内心都藏着一个设备模型的device_drivermmc_card怀里抱着一个设备模型的device,至于这两个结构到底长什么样,暂时还没有必要去研究,但是有一种预感mmc_card可能就是mmc_driver->driver命中注定的那个他了。

104行调用了mmc_driver中的probe方法,很显然这里就回朔到了card/block.c中刚刚注册的那个mmc_driver。原型如下:

[card/block.c]

663 static struct mmc_driver mmc_driver = {                  

664        .drv        = {

665               .name      = "mmcblk",

666        },          

667        .probe            = mmc_blk_probe,

668        .remove          = mmc_blk_remove,

669        .suspend  = mmc_blk_suspend,    

670        .resume          = mmc_blk_resume,

671 };

 

 

目光转向667行,mmc_blk_probe的实现如下:

[card/block.c]

584 static int mmc_blk_probe(struct mmc_card *card)                   

585 {                  

586        struct mmc_blk_data *md;          

587        int err;          

588                      

589        char cap_str[10];          

590                      

591        /*          

592        * Check that the card supports the command class(es) we need.             

593        */         

594        if (!(card->csd.cmdclass & CCC_BLOCK_READ))          

595               return -ENODEV; 

596                      

597        md = mmc_blk_alloc(card);        

598        if (IS_ERR(md))          

599               return PTR_ERR(md);  

600                      

601        err = mmc_blk_set_blksize(md, card);        

602        if (err)          

603               goto out;

604                      

605        string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,         

606                      cap_str, sizeof(cap_str));

607        printk(KERN_INFO "%s: %s %s %s %s\n",             

608               md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),

609               cap_str, md->read_only ? "(ro)" : ""); 

610                      

611        mmc_set_drvdata(card, md);       

612        add_disk(md->disk);            

613        return 0;        

614                      

615 out:                    

616        mmc_blk_put(md);       

617                      

618        return err;             

619 }                  

586行定义一个struct mmc_blk_data指针变量,鉴于他的重要江湖地位还是先来了解一下这个结构。

[card/block.c]

57   struct mmc_blk_data {         

58          spinlock_t       lock;

59          struct gendisk  *disk;

60          struct mmc_queue queue;     

61                 

62          unsigned int    usage;

63          unsigned int    read_only;

64   };          

58行一个自旋锁,分配请求队列以及控制队列操作时会用到,姑且先说这些。

59行块设备层中大名鼎鼎的gendisk结构,表示一个磁盘设备,当然这里一张存储卡也就对应这么一个disk了。可见其显赫的江湖地位了.....

60行看名字就知道是包装过的请求队列,不管他隐藏的有多深,我们还是要来看个究竟.....

[card/queue.h]

7    struct mmc_queue {                           

8           struct mmc_card            *card;    

9           struct task_struct    *thread;         

10          struct semaphore    thread_sem;          

11          unsigned int           flags;     

12          struct request        *req;      

13          int                 (*issue_fn)(struct mmc_queue *, struct request *);

14          void               *data;

15          struct request_queue     *queue;         

16          struct scatterlist      *sg;       

17          char               *bounce_buf;

18          struct scatterlist      *bounce_sg;          

19          unsigned int           bounce_sg_len;     

20   };   

12行和15行是块设备那边要用到的结构也是这个mmc_queue的核心,至于其他的比如9task_struct指向应用进程scatterlist散列表等我们用到再说。回到mmc_blk_data

62-63行相当于一些个flags,标示一些卡的状态。

       好了,该看的都看到了,接下来就该回到mmc_blk_probe.....

597行分配mmc_blk_data,并进行相关的初始化。跟踪源码.....

[card/block.c]

472 static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)              

473 {                  

474        struct mmc_blk_data *md;          

475        int devidx, ret;             

476                      

477        devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS);       

478        if (devidx >= MMC_NUM_MINORS)        

479               return ERR_PTR(-ENOSPC);      

480        __set_bit(devidx, dev_use);         

481                      

482        md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);           

483        if (!md) {             

484               ret = -ENOMEM;  

485               goto out;

486        }           

487                      

488                      

489        /*          

490        * Set the read-only status based on the supported commands          

491        * and the write protect switch.          

492        */         

493        md->read_only = mmc_blk_readonly(card);       

494                      

495        md->disk = alloc_disk(1 << MMC_SHIFT);             

496        if (md->disk == NULL) {           

497               ret = -ENOMEM;  

498               goto err_kfree;      

499        }           

500                      

501        spin_lock_init(&md->lock);        

502        md->usage = 1;            

503                      

504        ret = mmc_init_queue(&md->queue, card, &md->lock);          

505        if (ret)           

506               goto err_putdisk;   

507                      

508        md->queue.issue_fn = mmc_blk_issue_rq;         

509        md->queue.data = md;         

510                      

511        md->disk->major   = MMC_BLOCK_MAJOR;  

512        md->disk->first_minor = devidx << MMC_SHIFT;          

513        md->disk->fops = &mmc_bdops;        

514        md->disk->private_data = md;            

515        md->disk->queue = md->queue.queue;       

516        md->disk->driverfs_dev = &card->dev;             

517                      

518        /*          

519        * As discussed on lkml, GENHD_FL_REMOVABLE should:         

520        *          

521        * - be set for removable media with permanent block devices         

522        * - be unset for removable block devices with permanent media            

523        *          

524        * Since MMC block devices clearly fall under the second        

525        * case, we do not set GENHD_FL_REMOVABLE.  Userspace             

526        * should use the block device creation/destruction hotplug             

527        * messages to tell when the card is present.       

528        */         

529                      

530        sprintf(md->disk->disk_name, "mmcblk%d", devidx);             

531                      

532        blk_queue_logical_block_size(md->queue.queue, 512);            

533                      

534        if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {             

535               /*   

536               * The EXT_CSD sector count is in number or 512 byte   

537               * sectors.     

538               */  

539               set_capacity(md->disk, card->ext_csd.sectors);   

540        } else {         

541               /*   

542               * The CSD capacity field is in units of read_blkbits. 

543               * set_capacity takes units of 512 bytes.     

544               */  

545               set_capacity(md->disk, 

546                      card->csd.capacity << (card->csd.read_blkbits - 9));

547        }           

548        return md;            

549                      

550 err_putdisk:               

551        put_disk(md->disk);            

552 err_kfree:                  

553        kfree(md);            

554 out:                    

555        return ERR_PTR(ret);          

556 }                  

代码虽然有点长但是还算是比较简单,我们分段来看....

477-480行是linux惯用的伎俩了,早在USB中我们就见到了,无非就是从dev_use这张“位图”中找出一个没用的,填充进去。

493行获取卡的只读状态,mmc_blk_readonly(card);会返回卡读到或设置的一些状态信息,很显然程序在这之前已经读取了卡的设备,具体在什么时候进行的后面再说。

495行分配一个disk结构了,可见这个disk支持的分区数最大是(1 << MMC_SHIFT)

504行我们再说块设备驱动开发的时候已经说的很明确了,对于一个设备来讲无论采用何种方式gendiskrequest这两个是肯定要存在的。这里调用mmc_init_queue来初始化request的相关内容。具体如下:

[card/queue.c]

111 int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)  

112 {                                

113        struct mmc_host *host = card->host;                        

114        u64 limit = BLK_BOUNCE_HIGH;                         

115        int ret;                         

116                                    

117        if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)                       

118               limit = *mmc_dev(host)->dma_mask;               

119                                    

120        mq->card = card;                       

121        mq->queue =blk_init_queue(mmc_request, lock);                          

122        if (!mq->queue)                         

123               return -ENOMEM;              

124                                    

125        mq->queue->queuedata = mq;                          

126        mq->req = NULL;                      

127                                    

128        blk_queue_prep_rq(mq->queue, mmc_prep_request);                      

129        blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL);                       

130        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);                       

131                                    

132 #ifdef CONFIG_MMC_BLOCK_BOUNCE                            

133        if (host->max_hw_segs == 1) {                        

134               unsigned int bouncesz;                

135                                    

136               bouncesz = MMC_QUEUE_BOUNCESZ;                

137                                    

138               if (bouncesz > host->max_req_size)                  

139                      bouncesz = host->max_req_size;         

140               if (bouncesz > host->max_seg_size)                  

141                      bouncesz = host->max_seg_size;         

142               if (bouncesz > (host->max_blk_count * 512))                  

143                      bouncesz = host->max_blk_count * 512;            

144                                    

145               if (bouncesz > 512) {                  

146                      mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);          

147                      if (!mq->bounce_buf) {       

148                             printk(KERN_WARNING "%s: unable to " 

149                                    allocate bounce buffer\n,

150                                    mmc_card_name(card));

151                      }           

152               }                  

153                                    

154               if (mq->bounce_buf) {               

155                      blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY);         

156                      blk_queue_max_sectors(mq->queue, bouncesz / 512);       

157                      blk_queue_max_phys_segments(mq->queue, bouncesz / 512);          

158                      blk_queue_max_hw_segments(mq->queue, bouncesz / 512);            

159                      blk_queue_max_segment_size(mq->queue, bouncesz);             

160                                    

161                      mq->sg = kmalloc(sizeof(struct scatterlist),        

162                             GFP_KERNEL);   

163                      if (!mq->sg) {       

164                             ret = -ENOMEM;  

165                             goto cleanup_queue;     

166                      }           

167                      sg_init_table(mq->sg, 1);            

168                                    

169                      mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *         

170                             bouncesz / 512, GFP_KERNEL); 

171                      if (!mq->bounce_sg) {         

172                             ret = -ENOMEM;  

173                             goto cleanup_queue;     

174                      }           

175                      sg_init_table(mq->bounce_sg, bouncesz / 512);         

176               }                  

177        }                         

178 #endif                                

179                                    

180        if (!mq->bounce_buf) {                     

181               blk_queue_bounce_limit(mq->queue, limit);                    

182               blk_queue_max_sectors(mq->queue,                 

183                      min(host->max_blk_count, host->max_req_size / 512));           

184               blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);              

185               blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);                  

186               blk_queue_max_segment_size(mq->queue, host->max_seg_size);                   

187                                    

188               mq->sg = kmalloc(sizeof(struct scatterlist) *                    

189                      host->max_phys_segs, GFP_KERNEL);            

190               if (!mq->sg) {              

191                      ret = -ENOMEM;         

192                      goto cleanup_queue;            

193               }                  

194               sg_init_table(mq->sg, host->max_phys_segs);                  

195        }                         

196                                    

197        init_MUTEX(&mq->thread_sem);                           

198                                    

199        mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");                     

200        if (IS_ERR(mq->thread)) {                       

201               ret = PTR_ERR(mq->thread);                    

202               goto free_bounce_sg;                  

203        }                         

204                                    

205        return 0;                      

206 free_bounce_sg:                              

207      if (mq->bounce_sg)                           

208             kfree(mq->bounce_sg);               

209      mq->bounce_sg = NULL;                          

210 cleanup_queue:                                

211      if (mq->sg)                         

212               kfree(mq->sg);                    

213        mq->sg = NULL;                       

214        if (mq->bounce_buf)                         

215               kfree(mq->bounce_buf);                    

216        mq->bounce_buf = NULL;                        

217        blk_cleanup_queue(mq->queue);                       

218        return ret;                           

219 }    

又是一段冗长的代码,没办法既然linux说这事得说来话长那么我们也只能长话长说了。前面看过了struct mmc_queue结构,这里就不再重复了,来点实在的......

121行赫赫有名的blk_init_queue就赤裸裸地暴露在这了,而且说出mmc_request就是他的请求处理的函数这个石破天惊的秘籍。

128行我们平时用的很少,一般没有为请求队列定义准备函数。这里定义了mmc_prep_request来做之前的工作主要是为了过滤掉一些不合理的块请求,相关的代码比较简单如下:

[card/queue.c]

29   static int mmc_prep_request(struct request_queue *q, struct request *req)        

30   {           

31          /*   

32          * We only like normal block requests.

33          */  

34          if (!blk_fs_request(req)) {    

35                 blk_dump_rq_flags(req, "MMC bad request");

36                 return BLKPREP_KILL;

37          }    

38                 

39          req->cmd_flags |= REQ_DONTPREP;

40                 

41          return BLKPREP_OK;  

42   }    

129行为实现屏蔽请求服务。

132-178行是为请求平衡服务的,飘过...

181-186行根据主机控制器的特性来设置请求队列的一些属性。

189-194行散列存储结构struct scatterlist的申请与初始化。

199行创建并启动内核线程,关于这个线程所做的工作,后面我们会详细介绍。

如果不出意外,mmc_init_queue就该是返回了,重新回到mmc_blk_alloc

508行这句话单独提出来md->queue.issue_fn = mmc_blk_issue_rq,可见他的作用重大,后面讲到上面创建的那个内核进程的时候我会对他详细分析。现在留点印象....

509-516行对gendisk做些常规的赋值工作,就不再一一叙述了。

530-546行设置gendisk的名字,逻辑扇区的大小保持与硬件一致等工作,为add_disk作准备。

mmc_blk_data涵盖的内容较多,mmc_blk_alloc分配完相应的结构以后进行了必要的初始化,后面如果时机成熟驱动将调用add_disk完成mmc_blk_data->disk的真正注册。回到mmc_blk_probe....

601mmc_blk_set_blksize,跟踪源码....

[card/block.c]

558 static int               

559 mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)              

560 {                  

561        struct mmc_command cmd;         

562        int err;          

563                      

564        /* Block-addressed cards ignore MMC_SET_BLOCKLEN. */          

565        if (mmc_card_blockaddr(card))          

566               return 0; 

567                      

568        mmc_claim_host(card->host);             

569        cmd.opcode = MMC_SET_BLOCKLEN;           

570        cmd.arg = 512;            

571        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;            

572        err = mmc_wait_for_cmd(card->host, &cmd, 5);       

573        mmc_release_host(card->host);           

574                      

575        if (err) {        

576               printk(KERN_ERR "%s: unable to set block size to %d: %d\n",      

577                      md->disk->disk_name, cmd.arg, err);

578               return -EINVAL;   

579        }           

580                      

581        return 0;        

582 }           

这个函数表面上看上去平静的不得了,但是里面却是暗流汹涌。曾几何时为这个函数是否要现在分析,纠结了N久。其中的关系那是错综复杂、意乱情迷,每个函数的实现又是扑朔迷离。但有一点是肯定的,这个函数我们早晚得看,而且还要看的非常细致。不因他在整个故事发展过程中有多重要,只是他使用的手段过于犀利。好了,闲话少说....

561行又是一个新的数据结构struct mmc_command,此时此刻我是多么想说清楚这个结构的真正内涵,但现实告诉我这是说不完的,否则等整个故事讲完可能我们还停留在card目录下,总之现在还不是说它最好的时候,后面会有机会来和他做个了断。

565mmc_card_blockaddr()实则是个宏定义:

#define mmc_card_blockaddr(c)   ((c)->state & MMC_STATE_BLOCKADDR)

既然说不清struct mmc_command那也就理不顺这个的真正含义了。但是有一点是可以肯定的mmc_blk_set_blksize就是来设置SD的扇区大小的,既然人家都不支持这个功能(扇区大小设置),那这个函数继续下去也就没什么意义了。

568行这是core那边的一个函数mmc_claim_host,明理人估计一眼就看的出来这是在获取一个主机的控制器。我们知道一个控制器可能服务多个对象,现在要想使用它来对SD卡的扇区进行设置,那么首先我们必须先获得他老人家的同意。相信只要不是个强盗,这点道德还是应该懂得的。好了,至于这个中间是否还要经过九九八十一难,单凭这个函数名就不得而知了。姑且记下它,等到看到core的时候少不了和他打交道。

569-571行虽说struct mmc_command我们还没说,但是单从一点英文基础就可以看出来cmd.opcode = MMC_SET_BLOCKLEN;表示命令的操作码是设定扇区大小的。

cmd.arg = 512;参数是512

572行又是core那边的函数,名字就能看出他是把刚才这个设置扇区大小的任务交个host去完成,至于到底是怎么完成的你现在大可不必知道,谁叫俺们现在还在card目录下呢。不过要提醒一下的是,这个函数可不是一盏省油的灯。

573行见他长相和mmc_ claim _host相像,八成估计两个都是唱戏的,一个唱白脸一个唱红脸。mmc_ claim _host是要获得主机控制器,那么mmc_release_host人如其名也就是释放控制器了。

鉴于这个函数的特殊性,还是来稍稍总结一下。首先,许多SD而言这里函数可有可无,毕竟扇区不以512为大小的可能还是少数。另外,关键是里面牵扯到三个重要函数:

l  mmc_claim_host(card->host);

l  err = mmc_wait_for_cmd(card->host, &cmd, 5);

l  mmc_release_host(card->host);

走完mmc_blk_set_blksize就又该回到mmc_blk_probe了,接着往下走....

605-609string_get_size这个函数天生就是个无聊,既然存在就又价值,他就是把获取到的容量信息转化成字符串的形式放在char cap_str[10];中好让printk来打印。

611#define mmc_set_drvdata(c,d)    dev_set_drvdata(&(c)->dev, d),又是玩暧昧的,你中有我,我中有你.....

612行十月革命一声炮响,给我们送来了马克思列宁主义。而add_disk这一炮也具有跨时代的意义,给SD卡设备带来了改革开放。这也就意味着SD卡可以正式投入使用了.....

如果一切都是命中注定,那相信mmc_blk_probe也该返回了,但card目录的任务还远没有完成。

2.     do_request

       有句话说的好,“出来混,早晚是要还的”。还记得我们分析probe方法的时候中间有这么一段调用mmc_blk_probe->mmc_blk_alloc->mmc_init_queue->blk_init_queue,其调用的原型如下:

121 mq->queue = blk_init_queue(mmc_request, lock);     

122 if (!mq->queue)    

123        return -ENOMEM;

124        

125 mq->queue->queuedata = mq;

       当时说后面再详细分析,现在可谓是时机成熟。那么我们就先来一睹她的芳容....

[card/queue.c]

81   /*                 

82   * Generic MMC request handler.  This is called for any queue on a              

83   * particular host.  When the host is not busy, we look for a request              

84   * on any queue on this host, and attempt to issue it.  This may                    

85   * not be the queue we were asked to process.                  

86   */                

87   static void mmc_request(struct request_queue *q)                    

88   {                  

89          struct mmc_queue *mq = q->queuedata;            

90          struct request *req;       

91                        

92          if (!mq) {             

93                 printk(KERN_ERR "MMC: killing requests for dead queue\n");

94                 while ((req = blk_fetch_request(q)) != NULL)   

95                        __blk_end_request_all(req, -EIO);

96                 return;    

97          }           

98                        

99          if (!mq->req)        

100               wake_up_process(mq->thread);    

101 }

92-97行出错的处理我们就不多研究了.....

99-100行人分两类一类是会干活的,没话说真正的老黄牛;另一类则是会利用别人来干活的。这里的情况明显属于后者,至于这个被利用的对象就要追溯到mq->thread      这个对象了。没办法往上搜索一下mq->thread,显然在       card/queue.c199行给了我们一个天大的提示:

199 mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");

前面说过,这是创建一个内核线程与之相关的还有:

1kthread_create创建线程:

struct task_struct *kthread_create(int(*threadfn)(void *data), void *data,const char *namefmt, ...);

这个函数可以像printk一样传入某种格式的线程名线程创建后,不会马上运行,而是需要将kthread_create()返回的task_struct指针传给wake_up_process()然后通过此函数运行线程。

2. 当然,还有一个创建并启动线程的函数:kthread_run

   struct task_struct *kthread_run(int (*threadfn)(void *data),void*data,constchar *namefmt, ...);

线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。

    int kthread_stop(struct task_struct *thread);

kthread_stop() 通过发送信号给线程。

如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。

这里先来看一下mmc_queue_thread,由于源码比较长分析过程分段进行,相关源码如下:

[card/queue.c]

44   static int mmc_queue_thread(void *d)                      

45   {                         

46          struct mmc_queue *mq = d;               

47          struct request_queue *q = mq->queue;               

48                               

49          current->flags |= PF_MEMALLOC;                  

50                               

51          down(&mq->thread_sem);                 

52          do {              

53                 struct request *req = NULL;        

54                               

55                 spin_lock_irq(q->queue_lock);           

56                 set_current_state(TASK_INTERRUPTIBLE);            

57                 if (!blk_queue_plugged(q))         

58                        req = blk_fetch_request(q);  

59                 mq->req = req;            

60                 spin_unlock_irq(q->queue_lock);        

61                               

62                 if (!req) {             

63                        if (kthread_should_stop()) { 

64                               set_current_state(TASK_RUNNING);

65                               break;

66                        }    

67                        up(&mq->thread_sem); 

68                        schedule();     

69                        down(&mq->thread_sem);   

70                        continue;

71                 }           

72                 set_current_state(TASK_RUNNING);         

73                               

74                 mq->issue_fn(mq, req);       

75          } while (1);                 

76          up(&mq->thread_sem);               

77                               

78          return 0;               

79   }                         

kthread_run创建线程并运行,同时mq->thread_sem这个线程锁保证当前线程执行的原子性

51行获取这个线程的信号量;

56行设置当前线程运行状态为可中断的,当设置该状态以后内核在下一次调度时将该线程置为睡眠。除非其他线程唤醒。这里由于上下文处于原子态,所以只有等到68行以后内核才会发起调度。

57-58行块设备层的函数用于取出请求结构。同样55行和60行维护了一个队列锁,保证请求队列的原子性。

62-66如果请求不存在,同时其他线程发送了终止线程的请求那么直接跳出while循环也就意味着线程走到了生命的尽头。

68行如果没有请求存在,那么内核线程将进入睡眠

74行早在mmc_blk_alloc中有这么一个初始化的动作   

508                 md->queue.issue_fn = mmc_blk_issue_rq;

这里的mmc_blk_issue_rq定义在card/block.c中,原型如下:

[card/block.c]

237 static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)                      

238 {                                

239        struct mmc_blk_data *md = mq->data;                     

240        struct mmc_card *card = md->queue.card;                       

241        struct mmc_blk_request brq;                      

242        int ret = 1, disable_multi = 0;                           

243                                    

244        mmc_claim_host(card->host);                           

245                                    

246        do {                     

247               struct mmc_command cmd;                

248               u32 readcmd, writecmd, status = 0;                   

249                                    

250               memset(&brq, 0, sizeof(struct mmc_blk_request));                  

251               brq.mrq.cmd = &brq.cmd;                 

252               brq.mrq.data = &brq.data;                  

253                                    

254               brq.cmd.arg = blk_rq_pos(req);                 

255               if (!mmc_card_blockaddr(card))                

256                      brq.cmd.arg <<= 9;             

257               brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;               

258               brq.data.blksz = 512;                  

259               brq.stop.opcode = MMC_STOP_TRANSMISSION;                 

260               brq.stop.arg = 0;                 

261               brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;  

262               brq.data.blocks = blk_rq_sectors(req);               

263                                    

264               /*                 

265               * The block layer doesn't support all sector count                   

266               * restrictions, so we need to be prepared for too big               

267               * requests.                 

268               */                

269               if (brq.data.blocks > card->host->max_blk_count)                   

270                      brq.data.blocks = card->host->max_blk_count;          

271                                    

272               /*                 

273               * After a read error, we redo the request one sector at a time                 

274               * in order to accurately determine which sectors can be read                 

275               * successfully.                   

276               */                

277               if (disable_multi && brq.data.blocks > 1)                 

278                      brq.data.blocks = 1;             

279                                    

280               if (brq.data.blocks > 1) {                   

281                      /* SPI multiblock writes terminate using a special             

282                      * token, not a STOP_TRANSMISSION request.             

283                      */         

284                      if (!mmc_host_is_spi(card->host)        

285                                    || rq_data_dir(req) == READ)

286                             brq.mrq.stop = &brq.stop;    

287                      readcmd = MMC_READ_MULTIPLE_BLOCK;        

288                      writecmd = MMC_WRITE_MULTIPLE_BLOCK;            

289               } else {                

290                      brq.mrq.stop = NULL;         

291                      readcmd = MMC_READ_SINGLE_BLOCK;            

292                      writecmd = MMC_WRITE_BLOCK;          

293               }                  

294                                    

295               if (rq_data_dir(req) == READ) {               

296                      brq.cmd.opcode = readcmd;        

297                      brq.data.flags |= MMC_DATA_READ;       

298               } else {                

299                      brq.cmd.opcode = writecmd;       

300                      brq.data.flags |= MMC_DATA_WRITE;             

301               }                  

302                                    

303               mmc_set_data_timeout(&brq.data, card);                  

304                                    

305               brq.data.sg = mq->sg;                 

306               brq.data.sg_len = mmc_queue_map_sg(mq);                    

307                                    

308               /*                 

309               * Adjust the sg list so it is the same size as the                

310               * request.                   

311               */                

312               if (brq.data.blocks != blk_rq_sectors(req)) {                    

313                      int i, data_size = brq.data.blocks << 9;       

314                      struct scatterlist *sg;            

315                                    

316                      for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) {       

317                             data_size -= sg->length;

318                             if (data_size <= 0) {     

319                                    sg->length += data_size;

320                                    i++;

321                                    break;

322                             }    

323                      }           

324                      brq.data.sg_len = i;       

325               }                  

326                                    

327               mmc_queue_bounce_pre(mq);                   

328                                    

329               mmc_wait_for_req(card->host, &brq.mrq);              

330                                    

331               mmc_queue_bounce_post(mq);                  

332                                    

333               /*                 

334               * Check for errors here, but don't jump to cmd_err                

335               * until later as we need to wait for the card to leave               

336               * programming mode even when things go wrong.                 

337               */                

338               if (brq.cmd.error || brq.data.error || brq.stop.error) {                

339                      if (brq.data.blocks > 1 && rq_data_dir(req) == READ) {        

340                             /* Redo read one sector at a time */     

341                             printk(KERN_WARNING "%s: retrying using single "      

342                                    "block read\n", req->rq_disk->disk_name);   

343                             disable_multi = 1; 

344                             continue;

345                      }           

346                      status = get_card_status(card, req);             

347               }                  

348                                    

349               if (brq.cmd.error) {                    

350                      printk(KERN_ERR "%s: error %d sending read/write "           

351                             "command, response %#x, card status %#x\n",            

352                             req->rq_disk->disk_name, brq.cmd.error,            

353                             brq.cmd.resp[0], status);        

354               }                  

355                                    

356               if (brq.data.error) {                    

357                      if (brq.data.error == -ETIMEDOUT && brq.mrq.stop)            

358                             /* 'Stop' response contains card status */      

359                             status = brq.mrq.stop->resp[0];    

360                      printk(KERN_ERR "%s: error %d transferring data,"       

361                             " sector %u, nr %u, card status %#x\n",       

362                             req->rq_disk->disk_name, brq.data.error,            

363                             (unsigned)blk_rq_pos(req),           

364                             (unsigned)blk_rq_sectors(req), status);         

365               }                  

366                                    

367               if (brq.stop.error) {                    

368                      printk(KERN_ERR "%s: error %d sending stop command, "           

369                             "response %#x, card status %#x\n",             

370                             req->rq_disk->disk_name, brq.stop.error,            

371                             brq.stop.resp[0], status);        

372               }                  

373                                    

374               if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {              

375                      do {       

376                             int err;   

377                                    

378                             cmd.opcode = MMC_SEND_STATUS;

379                             cmd.arg = card->rca << 16;  

380                             cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 

381                             err = mmc_wait_for_cmd(card->host, &cmd, 5);

382                             if (err) { 

383                                    printk(KERN_ERR "%s: error %d requesting status\n",

384                                           req->rq_disk->disk_name, err);

385                                    goto cmd_err;

386                             }    

387                             /*   

388                             * Some cards mishandle the status bits,     

389                             * so make sure to check both the busy

390                             * indication and the card state.   

391                             */  

392                      } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||             

393                             (R1_CURRENT_STATE(cmd.resp[0]) == 7));    

394                                    

395 #if 0                                  

396                      if (cmd.resp[0] & ~0x00000900)        

397                             printk(KERN_ERR "%s: status = %08x\n",

398                                    req->rq_disk->disk_name, cmd.resp[0]);      

399                      if (mmc_decode_status(cmd.resp))             

400                             goto cmd_err;

401 #endif                                

402               }                  

403                                   

404               if (brq.cmd.error || brq.stop.error || brq.data.error) {                

405                      if (rq_data_dir(req) == READ) {        

406                             /*   

407                             * After an error, we redo I/O one sector at a     

408                             * time, so we only reach here after trying to     

409                             * read a single sector.  

410                             */  

411                             spin_lock_irq(&md->lock);  

412                             ret = __blk_end_request(req, -EIO, brq.data.blksz);   

413                             spin_unlock_irq(&md->lock);     

414                             continue;

415                      }           

416                      goto cmd_err;       

417               }                  

418                                    

419               /*                 

420               * A block was successfully transferred.                    

421               */                

422               spin_lock_irq(&md->lock);                

423               ret = __blk_end_request(req, 0, brq.data.bytes_xfered);                   

424               spin_unlock_irq(&md->lock);                   

425        } while (ret);                      

426                                    

427        mmc_release_host(card->host);                         

428                                    

429        return 1;                      

430                                    

431 cmd_err:                                  

432      /*                        

433       * If this is an SD card and we're writing, we can first                           

434       * mark the known good sectors as ok.                     

435       *                        

436        * If the card is not SD, we can still ok written sectors                           

437        * as reported by the controller (which might be less than                      

438        * the real number of written sectors, but never more).                          

439        */                       

440        if (mmc_card_sd(card)) {                          

441               u32 blocks;                  

442                                    

443               blocks = mmc_sd_num_wr_blocks(card);                  

444               if (blocks != (u32)-1) {               

445                      spin_lock_irq(&md->lock);         

446                      ret = __blk_end_request(req, 0, blocks << 9);           

447                      spin_unlock_irq(&md->lock);            

448               }                  

449        } else {                       

450               spin_lock_irq(&md->lock);                

451               ret = __blk_end_request(req, 0, brq.data.bytes_xfered);                   

452               spin_unlock_irq(&md->lock);                   

453        }                         

454                                    

455        mmc_release_host(card->host);                         

456                                    

457        spin_lock_irq(&md->lock);                       

458        while (ret)                          

459               ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));                   

460        spin_unlock_irq(&md->lock);                          

461                                    

462        return 0;                      

463 }                  

244mmc_claim_host之前已经简单介绍过来,后面再说。

250行出现一个struct mmc_blk_request其定义如下:

struct mmc_blk_request {

       struct mmc_request        mrq;

       struct mmc_command    cmd;

       struct mmc_command    stop;

       struct mmc_data            data;

};

struct mmc_request是将要传递给corehost层的一个mmc封装的请求,而其中的定义均为指针变量。这里正好定义一个局部的mmc_blk_request里面同时包含

struct mmc_commandstruct mmc_commandstruct mmc_data变量,当请求完成时函数结束,对应的变量也就销毁了。

251-252行正好与后面286290行相对应形成一组struct mmc_request结构。

254获取操作的开始扇区号。

256行写入命令的参数,对应SD卡地址第九位为0

259-261行对停止命令的相关设置。

262行获取要传送的扇区数目。

269-270行如果需要传输的扇区数目大于主机控制器允许的最大数目时,以硬件的最大容量为准。

277-278行当多扇区读取失败时会置位disable_multi=1,驱动会重新以单个散区的形式读取SD卡。

280-301行设置正确的读写命令,代码比较简单就不详细说明了。

303core层部分的代码,作用是根据不同的操作和卡的信息来设置适当的brq.data.timeout_ns,操作超时时间。具体的代码如下:

[core/core.c]

246 void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)         

247 {                                

248        unsigned int mult;                      

249                                    

250        /*                        

251        * SDIO cards only define an upper 1 s limit on access.                         

252        */                       

253        if (mmc_card_sdio(card)) {                       

254               data->timeout_ns = 1000000000;               

255               data->timeout_clks = 0;              

256               return;                  

257        }                         

258                                    

259        /*                        

260        * SD cards use a 100 multiplier rather than 10                       

261        */                       

262        mult = mmc_card_sd(card) ? 100 : 10;                     

263                                    

264        /*                        

265        * Scale up the multiplier (and therefore the timeout) by                        

266        * the r2w factor for writes.                      

267        */                       

268        if (data->flags & MMC_DATA_WRITE)                         

269               mult <<= card->csd.r2w_factor;                

270                                    

271        data->timeout_ns = card->csd.tacc_ns * mult;                         

272        data->timeout_clks = card->csd.tacc_clks * mult;                           

273                                    

274        /*                        

275        * SD cards also have an upper limit on the timeout.                      

276        */                       

277        if (mmc_card_sd(card)) {                          

278               unsigned int timeout_us, limit_us;              

279                                    

280               timeout_us = data->timeout_ns / 1000;              

281               timeout_us += data->timeout_clks * 1000 /               

282                      (card->host->ios.clock / 1000);           

283                                    

284               if (data->flags & MMC_DATA_WRITE)                  

285                      /*          

286                      * The limit is really 250 ms, but that is            

287                      * insufficient for some crappy cards.        

288                      */         

289                      limit_us = 300000;       

290               else               

291                      limit_us = 100000;       

292                                    

293               /*                 

294               * SDHC cards always use these fixed values.                  

295               */                

296               if (timeout_us > limit_us || mmc_card_blockaddr(card)) {               

297                      data->timeout_ns = limit_us * 1000;          

298                      data->timeout_clks = 0;       

299               }                  

300        }                         

301        /*                        

302        * Some cards need very high timeouts if driven in SPI mode.                      

303        * The worst observed timeout was 900ms after writing a                       

304        * continuous stream of data until the internal logic                        

305        * overflowed.                           

306        */                       

307        if (mmc_host_is_spi(card->host)) {                          

308               if (data->flags & MMC_DATA_WRITE) {                

309                      if (data->timeout_ns < 1000000000)          

310                             data->timeout_ns = 1000000000;  /* 1s */

311               } else {                

312                      if (data->timeout_ns < 100000000)            

313                             data->timeout_ns =  100000000; /* 100ms */

314               }                  

315        }                         

316 }                                

上面代码对时间处理比较细致,程序实现也比较简单,就不再详细说明了。重新回到mmc_blk_issue_rq....

305-306行这两行关于scatterlist的操作,比较关键。具体的实现如下:

[card/queue.c]

301 unsigned int mmc_queue_map_sg(struct mmc_queue *mq)       

302 {           

303        unsigned int sg_len;      

304        size_t buflen; 

305        struct scatterlist *sg;     

306        int i;      

307               

308        if (!mq->bounce_buf)   

309               return blk_rq_map_sg(mq->queue, mq->req, mq->sg);

310               

311        BUG_ON(!mq->bounce_sg);

312               

313        sg_len = blk_rq_map_sg(mq->queue, mq->req, mq->bounce_sg);    

314               

315        mq->bounce_sg_len = sg_len;      

316               

317        buflen = 0;    

318        for_each_sg(mq->bounce_sg, sg, sg_len, i) 

319               buflen += sg->length;

320               

321        sg_init_one(mq->sg, mq->bounce_buf, buflen); 

322               

323        return 1; 

324 }           

之前的分析中我们忽略了bounce_buf机制,所以这里真正关心的是308-309行。使用给定请求的全部段填充给定的散列表,同时内存中邻近的段在插入散布表之前被接合,对应sg_len返回的是散列表的项数。这样以后提交给coremmc_request结构中就可以直接使用scatterlist。然而对于bounce_buf机制下的scatterlist318-319行将所有的操作整合以后最终调用321行的sg_init_one只初始化一个散列表项。后面我们将看到他们跟进一步的区别。是时候回到mmc_blk_issue_rq中了。

312-325行代码比较简单,316行遍历sg list,获取其数据长度,最终根据实际请求的大小作比较,来调整sg list的大小及项数。

327331行这是和bounce_buf机制相关的,有兴趣的可以参考源码。

329行起来一个承上启下的作用,同时也将整个card目录推向了故事的高潮。与前面所说的mmc_wait_for_cmd一样,这里是很难说清楚mmc_wait_for_req的实现了。他是core层的一个接口函数,这里我们关注他说传递的两个参数mmc_wait_for_req(card->host, &brq.mrq);

card->host对应请求的主机控制器,然后,请求要做的事情就包含在brq.mrq当中了。递交完这两项内容以后,之前说过的那个内核线程就可以安然入睡了,至于什么时候被什么吵醒后面我们遇到了再来分析。

331行以后发生的故事也许就只能等到线程醒来的时候才知道了。但是有些时候还是要有点未卜先知的能力的,显然下面这段基本都是在处理出错的一些状态,还是简单分析一下....

338行这些个error不是被人干的,正是调用mmc_wait_for_req以后,底层的host主机控制器传送上来的。

343行很明显前面已经说过了,这斯出错了还不承认,还说人家让他传送的扇区多了,还有一个一个扇区来做。好吧,就给你这个机会,结果就置位了disable_multi,接着continue

346行能走到这里的哥们可能就不得不承认自己错了,好吧没有办法就去找出错的原因吧,也就只能读取设备的状态信息了。

[card/block.c]

220 static u32 get_card_status(struct mmc_card *card, struct request *req)            

221 {           

222        struct mmc_command cmd;  

223        int err;   

224               

225        memset(&cmd, 0, sizeof(struct mmc_command));     

226        cmd.opcode = MMC_SEND_STATUS;

227        if (!mmc_host_is_spi(card->host))      

228               cmd.arg = card->rca << 16;

229        cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;     

230        err = mmc_wait_for_cmd(card->host, &cmd, 0);

231        if (err)   

232               printk(KERN_ERR "%s: error %d sending status comand",

233                      req->rq_disk->disk_name, err);

234        return cmd.resp[0];

235 }

相信这段代码还是有点熟悉的了,这里就不必详说了,注意这里少了一个申请主机控制器的动作,因为前面申请到的还没释放呢。

349-372行有了出错的状态那就慢慢分析了,无非是prinkt

374-393行主要是为了满足时序上的要求,具体内容后面会根据SD spece中的内容来做分析。

404-417行如果程序执行到这里,那么这个设备可能就真没得救了。早点goto cmd_err吧。

420-424行这段是最好的结果了,           

ret = __blk_end_request(req, 0, brq.data.bytes_xfered);

提交给块层,请求处理成功。当然这也是我们最想见到的,至于cmd_err:以后的内容,这里就没有必要再详细分析了,有兴趣研究的自己琢磨。

3.     小结

       好了,card的故事该说的,能说的到这里就算是讲完了。稍微回顾一下这一层所做的工作,就是将块层递交的请求从新打包成mmc_request递交出去,其中块层请求处理为了提高性能采用了内核线程的方法。为了后面分析方便还是列出部分与core层的接口函数:

l  static inline void mmc_claim_host(struct mmc_host *host)

l  void mmc_release_host(struct mmc_host *host)

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

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

最后,带着N多的困惑与不解继续走向core层的春天.....

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

core层处理(linux/driver/mmc/core)

1.     core层初始化

一切变化逃不出Kconfig/Makefile的魔爪,这话一点也不假。同样core层的故事也将从这里拉开帷幕。二话不说先还是进到core目录下瞧瞧…

与以往所见到的Kconfig相比这里的显然少了几分生机和活力,貌似整个文件看完也难以发现令我们眼前发亮的字眼。也罢,少一个config也许就意味这我们少看几千行代码。再看看Makefile

[core/Makefile]

5    ifeq ($(CONFIG_MMC_DEBUG),y)                       

6           EXTRA_CFLAGS         += -DDEBUG      

7    endif                           

8                                

9    obj-$(CONFIG_MMC)         += mmc_core.o            

10   mmc_core-y                 := core.o bus.o host.o \ 

11                                  mmc.o mmc_ops.o sd.o sd_ops.o \

12                                  sdio.o sdio_ops.o sdio_bus.o \

13                                  sdio_cis.o sdio_io.o sdio_irq.o

14                               

15   mmc_core-$(CONFIG_DEBUG_FS)   += debugfs.o               

看到这里我们再也兴奋不起来了,好像处理debugfs.c这个文件我们可以不怎么关注外,其他的文件都是我们研究的重点了。命运本该如此,不能改变就学着去接受吧.....

知道了是那些个文件再去找入口也许就方便多了,前面我们说过module_initsubsys_initcall永远是linux内核中最“忠实”的奸臣。当然也还有其他的乱臣贼子,一张口就道出内核入口的,这里就不在一一列出了。前面说到card目录的时候,入口显然是module_init,记性稍微好点的哥们可能还记得当时是因为mmc_bus_type这条总线才让我们card的故事得以延续的。换句话来说,如果这条总线都还尚未注册,那么请问card目录又将如何利用总线mmc_bus_typeprobe方法最终走向mmc_driver->probe?无花却有果,那才真是奇了怪了。说来这么多无非是想证明其实core目录是早于card目录而生的,而我们又知道对于subsys_initcall是早于module_init调用的,那么也就不难想到core很有可能就是利用subsys_initcall来入口的了。

是不是这个理搜索一下内核代码就知道了,直接在/mmc/core目录下搜索subsys_initcall关键字,出来的不是别人真是core.c这个文件。不信邪的可以去搜索module_init,要是能搜索出东西来,那就是出了鬼了,说不好多半是上辈子造下的孽,这辈子该还了。好了,是时候进入正题了,先看subsys_initcall(mmc_init)如下:

[mmc/core/core.c]

1315      static int __init mmc_init(void)           

1316      {           

1317             int ret;    

1318                    

1319             workqueue = create_singlethread_workqueue("kmmcd");  

1320             if (!workqueue)     

1321                    return -ENOMEM;

1322                    

1323             ret = mmc_register_bus();    

1324             if (ret)    

1325                    goto destroy_workqueue;

1326                    

1327             ret = mmc_register_host_class();  

1328             if (ret)    

1329                    goto unregister_bus;

1330                    

1331             ret = sdio_register_bus();     

1332             if (ret)    

1333                    goto unregister_host_class;

1334                    

1335             return 0; 

1336                    

1337      unregister_host_class:          

1338             mmc_unregister_host_class();      

1339      unregister_bus:             

1340             mmc_unregister_bus(); 

1341      destroy_workqueue:             

1342             destroy_workqueue(workqueue);  

1343                    

1344             return ret;      

1345      }           

1319行内核时间处理机制中大名鼎鼎的工作队列就被使用在这里了。我们知道每个工作队列有一个或多个专用的进程("内核线程"),它运行提交给这个队列的函数。通常我们使用create_workqueue来创建一个工作队列,实际上他可能创建了多个线程运行在系统不同的处理器上。然而在很多情况下,我们提交的任务可能是些简单的单线程就能够完成的工作,这时候使用create_singlethread_workqueue来代替创建工作队列时在适用不过了。这里就是直接使用create_singlethread_workqueue创建一个单线程的工作队列。

1323行之前分析内核入口的时候一而再再而三的提到mmc_bus_type这么一条总线,现在她终于是有机会抛头露面了。可以猜测mmc_register_bus注册的不是别人正是垂涎已久的mmc_bus_type,不信你就来看代码。

[mmc/core/bus.c]

150 int mmc_register_bus(void)  

151 {    

152        return bus_register(&mmc_bus_type);

153 }

看这代码清晰简单,比起小葱拌豆腐还一清二白。如果你硬是说不认识bus_register那我就没辙了,回去翻翻设备模型估计第一页就有讲述他老人家的风骚故事。

1327行这句话看不看能,如果你硬是对sys目录下的那点东西怎么来的感兴趣的话,就去瞅两眼吧。一眼就够了,太多了伤身体。

1331行又来个sdio_bus注册,本来一个mmc_bus_type就折腾的够烦人的了,现在又来个sdio_bus是个什么东东,无形中给我们增加压力。不知道是什么东西就百度百科一下吧,谁知道塞翁失马焉知非福,下面来点百度的东西。其实SDIO是目前我们比较关心的技术,SDIO故名思义,就是 SD I/O接口(interface)的意思,不过这样解释可能还有点抽像。更具体的说明,SD本来是记忆卡的标准,但是现在也可以把 SD 拿来插上一些外围接口使用,这样的技术便是 SDIO。所以 SDIO本身是一种相当单纯的技术,透过 SD I/O接脚来连接外部外围,并且透过 SD上的 I/O数据接位与这些外围传输数据,而且 SD协会会员也推出很完整的 SDIO stack驱动程序,使得 SDIO外围(我们称为 SDIO卡)的开发与应用变得相当热门。现在已经有非常多的手机或是手持装置都支持 SDIO的功能(SD标准原本就是针对 mobile device而制定),而且许多 SDIO外围也都被开发出来,让手机外接外围更加容易,并且开发上更有弹性(不需要内建外围)。目前常见的 SDIO外围(SDIO卡)有:Wi-Fi card(无线网络卡)、CMOS sensor card(照相模块)、GPS card

GSM/GPRS modem cardBluetooth cardRadio/TV cardSDIO的应用将是未来嵌入式系统最重要的接口技术之一,并且也会取代目前 GPIO式的 SPI 接口。

       看完这堆科普知识,是不是有点柳暗花明又一村的感觉,其实这儿注册个sdio_bus就是为那些sdio外设服务的,就像前面我们分析的card目录使用mmc_bus说不准哪天又多出个什么wi-fi卡就要依附在这条sdio总线上,那时我们就可以像mmc_bus一样拿来用了。至少这里我们现在还不用管他,这也就是说刚才core中见到的若干个文件,只要名字带了个sdio的头的,我们八成都不用再来管他了。你说这是福还是祸,是福跑不了,是祸躲不过。

mmc_init比较简短,说到这里也就算是结束了。一般来说core层所做的初始化的工作较少,多半是为整个子系统的工作提供必要的接口,就像前面分析块层设备驱动一样。另外,前面我们说过在card层给我们core的分析留下了一些线索,下面我们就来按之前遗留下来的函数的顺序对其一一进行分析。

2.     mmc_claim_host

mmc_claim_host定义在/mmc/core/core.h中实际的代码是由__ mmc_claim_host来完成的,具体的实现如下:

150 static inline void mmc_claim_host(struct mmc_host *host)

151 {    

152        __mmc_claim_host(host, NULL);

153 }    

函数以非终止的方式调用,传递的abort实参为NULL。关于__ mmc_claim_host的内容将做详细分析,具体代码如下:

[mmc/core/core.c]

451 int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)                    

452 {                  

453        DECLARE_WAITQUEUE(wait, current);         

454        unsigned long flags;             

455        int stop;         

456                      

457        might_sleep();       

458                      

459        add_wait_queue(&host->wq, &wait);         

460        spin_lock_irqsave(&host->lock, flags);       

461        while (1) {           

462               set_current_state(TASK_UNINTERRUPTIBLE);

463               stop = abort ? atomic_read(abort) : 0;  

464               if (stop || !host->claimed || host->claimer == current) 

465                      break;

466               spin_unlock_irqrestore(&host->lock, flags);

467               schedule();     

468               spin_lock_irqsave(&host->lock, flags);

469        }           

470        set_current_state(TASK_RUNNING);         

471        if (!stop) {            

472               host->claimed = 1;

473               host->claimer = current;

474               host->claim_cnt += 1;   

475        } else            

476               wake_up(&host->wq);  

477        spin_unlock_irqrestore(&host->lock, flags);       

478        remove_wait_queue(&host->wq, &wait);           

479        if (!stop)       

480               mmc_host_enable(host);

481        return stop;           

482 }                  

453行初始化一个等待节点,后面我们将看到他的作用。

457might_sleep宏其实就是检查是否需要重新调度,如果是,则进行调度。一般都用在可能引发睡眠的上下文中,完成任务的抢占。

459行将新的等待节点加入到主机的host->wq等待对列中,主要这里只是说加入进来

464行满足以下条件之一该线程将不会睡眠直接跳出while循环,分别是设置了终止、host空闲可用或者拥有该host的是本线程。当符合以上三条中的任何一种情况,程序会跳转到470行,重新设置线程状态为运行态。下面我们在abort=0的条件下分两种情况来讨论上面的整段代码的执行情况:

l  情况一:如果此时host不是空闲状态,host-> claimed=1host->claimer != current此时按常理来说本线程将等待459行,462行以及467行这三行代码使得线程睡眠在host->wq等待队列上,什么时候唤醒后面说到。

l  情况二:此时host于空闲状态host-> claimed=0,或者host拥有者就是当前这个线程,这时程序直接跳转到470行,重新将进程状态设为运行态,当然这时的471-475行也就得以执行了。这三个变量的重新赋值意味着本线程得到了Host的控制权,当然478行的等待队列中的元素也就该删除了,480host开始工作,具体实现后面再分析。

最后,来看看这段代码的一个最特殊的情况abort=0时,这种情况本身就是个bug,既要claime然后又让人家abort,这一点我是看不穿想不透了,不过476行的代码倒是有几分的人性化,如果像前面所说的有线程睡眠在了host->wq上了,那么这个时候wake_up(&host->wq);一旦发出就回唤醒那些等待host的线程重新申请资源,毕竟这个host较少,资源还是相当紧张的。当然这是这种变态社会中的一种极其变态的情况,真正正常的wake_up可能还是要等到mmc_release_host的时候,在这里只是先提一下。

最后的最后要说的是current这个东西,这个指的不是别人,正是前面一节我们谈到的那个块请求处理的内核线程,当然早在cardprob中有个mmc_blk_set_blksize里面也使用到了这个她,那个时候到底指向的谁就确实不知道了

另外,刚才说到了mmc_host_enable这个函数,定义在/mmc/core/core.c中,还是来简单的看一下:

[mmc/core/core.c]

346 /**                       

347 *    mmc_host_enable - enable a host.              

348 *    @host: mmc host to enable                 

349 *                        

350 *    Hosts that support power saving can use the 'enable' and 'disable'              

351 *    methods to exit and enter power saving states. For more information              

352 *    see comments for struct mmc_host_ops.                    

353 */                       

354 int mmc_host_enable(struct mmc_host *host)                          

355 {                         

356        if (!(host->caps & MMC_CAP_DISABLE))              

357               return 0;        

358                             

359        if (host->en_dis_recurs)              

360               return 0;        

361                             

362        if (host->nesting_cnt++)                    

363               return 0;        

364                             

365        cancel_delayed_work_sync(&host->disable);                    

366                             

367        if (host->enabled)                

368               return 0;        

369                             

370        if (host->ops->enable) {              

371               int err;          

372                             

373               host->en_dis_recurs = 1;             

374               err = host->ops->enable(host);            

375               host->en_dis_recurs = 0;             

376                             

377               if (err) {        

378                      pr_debug("%s: enable error %d\n",     

379                             mmc_hostname(host), err);

380                      return err;      

381               }           

382        }                  

383        host->enabled = 1;               

384        return 0;               

385 }           

365行这实际上是内核维护的一个全局的工作队列,使用时不需要定义工作队列结构体,全局工作队列创建的时候可以使用如下方法:

int schedule_work(struct work_struct *work ); 
int schedule_work_on(int,struct work_struct *work ); 
int scheduled_delayed_work(struct delayed_work *dwork,unsigned long delay); 
int scheduled_delayed_work_on(int cpu,struct delayed_work *dwork,unsigned long delay); 

如果任务被延迟,调用cancel_delayed_work_sync将会终止队列中的任务或者阻塞任务直到回调结束(如果处理程序已经在处理该任务)。从这里不难发现主机处理任务的方式很有可能是利用的全局工作队列,具体如何等见到创建队列任务的时候再说。

370-382行就是调用host所提供的mmc_host_ops方法来设置了,其实整个过程是和低功耗相关的,这里就不再深入研究了。

       看完mmc_claim_host,我们乘热打铁把他的孪生兄弟mmc_release_host也给解决了。

3.     mmc_release_host

mmc_release_hostmmc_claim_host一起出生入死,始终是成对出现,执行的过程肯能在顺序上有点颠倒,上点源码如下:

[mmc/core/core.c]

575 void mmc_release_host(struct mmc_host *host)                       

576 {                         

577        WARN_ON(!host->claimed);              

578                             

579        mmc_host_lazy_disable(host);                   

580                             

581        mmc_do_release_host(host);               

582 }           

579行跟进源码:       

[mmc/core/core.c]

545 int mmc_host_lazy_disable(struct mmc_host *host)           

546 {           

547        if (!(host->caps & MMC_CAP_DISABLE))

548               return 0;

549               

550        if (host->en_dis_recurs)

551               return 0;

552               

553        if (--host->nesting_cnt) 

554               return 0;

555               

556        if (!host->enabled)

557               return 0;

558               

559        if (host->disable_delay) {     

560               mmc_schedule_delayed_work(&host->disable,

561                             msecs_to_jiffies(host->disable_delay));

562               return 0;

563        } else     

564               return mmc_host_do_disable(host, 1);

565 }    

整个过程与上面说说的mmc_host_enable正好相反。

559-560行如果主机进入低功耗有个延时过程,那么就通过全局工作队列来进行延时调度,其中mmc_schedule_delayed_work调用的不是别人正是queue_delayed_work(workqueue, work, delay),至于host->disable里面放着什么内容这是host那边的事,谈到了在论。

564行如果主机没有这个癖好直接可以disable那再好不过了,mmc_host_do_disable(host, 1);为您解决一切后顾之忧。

[mmc/core/core.c]

388 static int mmc_host_do_disable(struct mmc_host *host, int lazy)                           

389 {                         

390        if (host->ops->disable) {                    

391               int err;          

392                             

393               host->en_dis_recurs = 1;             

394               err = host->ops->disable(host, lazy);          

395               host->en_dis_recurs = 0;             

396                             

397               if (err < 0) {         

398                      pr_debug("%s: disable error %d\n",    

399                             mmc_hostname(host), err);

400                      return err;      

401               }           

402               if (err > 0) {         

403                      unsigned long delay = msecs_to_jiffies(err);

404                             

405                      mmc_schedule_delayed_work(&host->disable, delay);      

406               }           

407        }                  

408        host->enabled = 0;               

409        return 0;               

410 }                  

由此可见这个忧患也并没达到什么程度,394行爽快调用了host提供的disable方法,但是405行又再次出现一个延时调用,这个解释要想合理只有等到明年春暖花开的季节我们分析host的时候了。总之,当等到了那一天一切真相都会水落石出。

       回到mmc_release_host还剩下最后一行,mmc_do_release_host(host)

[mmc/core/core.c]

509 static void mmc_do_release_host(struct mmc_host *host)         

510 {           

511        unsigned long flags;      

512               

513        spin_lock_irqsave(&host->lock, flags);

514        if (--host->claim_cnt) {

515               /* Release for nested claim */

516               spin_unlock_irqrestore(&host->lock, flags);

517        } else {  

518               host->claimed = 0;

519               host->claimer = NULL;

520               spin_unlock_irqrestore(&host->lock, flags);

521               wake_up(&host->wq);

522        }    

523 }           

这段代码逻辑异常清晰,格式异常工整,一切犹如行云流水一般。环环相扣,句句入理。这么多的优点面前我只说一句,省的大煞风景。

521行再见了wake_up,前面说过一个变态的,这里出现的这个可是他家的正统血脉哦,一个主机控制器的releasewake_up了一批抢占他的线程,这里就是个强有力的证明。

       好了,废话加白话总之没有一句真话的把mmc_release_host讲完了,接下来该步入整个SD卡故事得正题了,别笑的太早,到时候有你好受。

4.     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 }    

我汗,这啥意思,咋整个代码比潘长江还短。罢了不管他,研究下代码。

200mmc_start_request搞了半天才开始请求,你说这急人不急人,好了看你怎个start法。

[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行以前全是debug要用的,本来就不长的代码这一缩水可真没啥分量了。

150行啥玩意,LED?都啥时候了还有这闲工夫玩这玩意。搞硬件的兄弟们总喜欢在板子上搞几个LED,弄的像不整几个上去不足以展示自己实力似的,这也就苦了这帮子写内核的哥们,既然有了个状态指示灯,总不能让它没反应吧,省的那些不懂硬件的人怀疑哪位画板子的哥们把个LED的原理图给画错了,这就麻烦大了,会死人的。好吧就加段小代码让他工作起来吧,也就有了这个led_trigger_event,当然是可配置的。如果您确实认为有必要研究一番,就劳驾自己去观摩吧,我在这里就先失陪了。

167-173行这几行什么意思我始终没能明白,也许真的到了春暖花开的季节才能明白他的良苦用心吧。没办法,现在还不能说,那就等待等待在等待吧....

176行不用我多说肯定都知道这是个什么意思,不错调用的真是host边的接口,好了不能再说了,再说就有人告我侵犯领土完整了。

       前面说了这个函数很复杂的,怎么?放心好戏在后头。好了回到mmc_wait_for_req...

202wait_for_completion(&complete);典型的complete机制,不会吧没听说过,那只能说明你out了。内核同步机制中complete可是也占了部分江山的呀,wait_for_completion以后的结果就是调用线程你可以进入冬眠了,什么时候我这边做完了会利用complete来解脱你的。好了话都说到这份上了,您自己说这个等待的过程是不是很漫长,何况也没有个期限,即使一万年也得等啊。

197-198mmc_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的那个对象,好了大胆想象吧,N年后的某个地方我们肯定会与mmc_wait_done在聚首。不信就走着瞧....

5.     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再来给他画上圆满的句号,我想只有这样才能表达我们对这个吃苦耐劳的core最崇高的敬意。

 

 

 

 

 

 

 

 

 

 

 

 

 

SD控制器之初始化(linux/driver/mmc/host)

这一层讲述硬件与硬件之间将要发生的故事,也是最底层驱动的核心。通常所谓的驱动程序设计的任务将落实到这一层上,所以关注host故事的发展也将成为移植整个SD类设备驱动的核心。在host目录中有各种平台下SD卡主机驱动器的实例,这里我们选择s3c2440平台作为分析的重点。参看KconfigMakefile即可获得相应信息,这里对应的文件即是s3cmci.c

旧瓶装新酒,还是那个module_init,不一样的是其中的入口函数。在s3cmci.c中对应的是module_init(s3cmci_init);

[host/s3cmci.c]

1920      static int __init s3cmci_init(void) 

1921      {    

1922             return platform_driver_register(&s3cmci_driver);

1923      }    

1922行注册了一个平台驱动,这个前面分析的串口驱动等是一样的原理。这是新版内核中引入的一个虚拟的平台总线。对应的平台设备早在内核启动时通过platform_add_devices加入到了内核,相关的具体内容前面已经分析的挺多了,这里就不在详细说明。1922行调用的结果会导致s3cmci_driver中的probe方法得以调用,由此也就把我们引入了host的世界。

       首先还是来大致看一下s3cmci_driver中所对应的具体内容。

[host/s3cmci.c]

1908      static struct platform_driver s3cmci_driver = {                 

1909             .driver     = { 

1910                    .name      = "s3c-sdi",

1911                    .owner    = THIS_MODULE,

1912                    .pm  = s3cmci_pm_ops,

1913             },          

1914             .id_table  = s3cmci_driver_ids,    

1915             .probe            = s3cmci_probe,

1916             .remove          = __devexit_p(s3cmci_remove),

1917             .shutdown       = s3cmci_shutdown,     

1918      };                 

1915行使我们关注的核心,由于host与硬件是直接相关的,probe接下来将做部分关于硬件初始化的工作,因此在分析下面一部分代码之前,最好能对s3c2440sdi相关的内容有所了解。下面进入到probe的相关内容,整个函数洋洋洒洒三百多行,就分段说明吧。

[host/s3cmci.c]

1548      static int __devinit s3cmci_probe(struct platform_device *pdev)                            

1549      {                                       

1550             struct s3cmci_host *host;                                  

1551             struct mmc_host     *mmc;                        

1552             int ret;                                

1553             int is2440;                                 

1554             int i;                                  

1555                                                

1556             is2440 = platform_get_device_id(pdev)->driver_data;

      /*根据设备id号判断控制器类型*/                        

1557                                                

1558             mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);                 

1559             if (!mmc) {                               

1560                    ret = -ENOMEM;                       

1561                    goto probe_out;                          

1562             }    

1558行分配一个mmc控制器,同时struct s3cmci_host结构作为一个私有数据类型将添加到struct mmc_hostprivate域。mmc_alloc_host相应的代码如下:

[host/host.c]

58   struct mmc_host *mmc_alloc_host(int extra, struct device *dev)             

59   {           

60          int err;   

61          struct mmc_host *host; 

62                 

63          if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))    

64                 return NULL;

65                 

66          host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);     

67          if (!host)

68                 return NULL;

69                 

70          spin_lock(&mmc_host_lock);      

71          err = idr_get_new(&mmc_host_idr, host, &host->index);  

72          spin_unlock(&mmc_host_lock);   

73          if (err)   

74                 goto free;

75                 

76          dev_set_name(&host->class_dev, "mmc%d", host->index);

77                 

78          host->parent = dev;      

79          host->class_dev.parent = dev;      

80          host->class_dev.class = &mmc_host_class;  

81          device_initialize(&host->class_dev);    

82                 

83          spin_lock_init(&host->lock);

84          init_waitqueue_head(&host->wq);

85          INIT_DELAYED_WORK(&host->detect, mmc_rescan);   

86          INIT_DELAYED_WORK_DEFERRABLE(&host->disable,mmc_host_deeper_disable); 

87                 

88          /*   

89          * By default, hosts do not support SGIO or large requests.      

90          * They have to set these according to their abilities.  

91          */  

92          host->max_hw_segs = 1;      

93          host->max_phys_segs = 1;    

94          host->max_seg_size = PAGE_CACHE_SIZE;    

95                 

96          host->max_req_size = PAGE_CACHE_SIZE;    

97          host->max_blk_size = 512;   

98          host->max_blk_count = PAGE_CACHE_SIZE / 512;

99                 

100        return host;    

101               

102 free:       

103        kfree(host);    

104        return NULL; 

105 }           

71行是内核的高效搜索树,将host->indexhost结构相关联,方便以后查找。

78-81行主要是初始化host->class_dev,这个日后会通过device_register注册进系统。

84行前面已经在这个等待队列上花了不少笔墨,主要是同步对host资源的竞争的。

85-86行两行调用的函数其实没有本质上的区别,这里主要是初始化两个内核的延时工作队列。通过INIT_DELAYED_WORKINIT_DELAYED_WORK_DEFERRABLE初始化以后,将延时执行的函数与struct delay_work结构相绑定,对于延时工作队列,日后通过调用schedule_delayed_work(),咱们只要传递struct work_struct的结构体参数即可,使得绑定的函数得以运行。关于这两个函数所做的工作,我们后面单独在说,先继续往下走。

92-98行这些个都是设置host的一些属性的,是与block.c中请求队列的设置相对应的。

       重新回到s3cmci_probe....

1563                                                

1564             for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {                                 

1565                    ret = gpio_request(i, dev_name(&pdev->dev));                       

1566                    if (ret) {                      

1567                           dev_err(&pdev->dev, "failed to get gpio %d\n", i);                  

1568                                                

1569                           for (i--; i >= S3C2410_GPE(5); i--)                  

1570                                  gpio_free(i);         

1571                                                

1572                           goto probe_free_host;                 

1573                    }                         

1574             }           

上面这一段申请SD卡驱动器所需的GPIO资源。

1575                                                

1576             host = mmc_priv(mmc);                                  

1577             host->mmc    = mmc;                       

1578             host->pdev     = pdev;                       

1579             host->is2440   = is2440;                     

1580

上面这段代码就是对struct s3cmci_host *host这个私有结构的配置,对于coreblock层见到的只有struct mmc_host。从另外的一个角度可以理解struct mmc_host实际上是      

struct s3cmci_host的基类,有着所有控制器所必须具有的属性。struct s3cmci_host还包含了与host硬件平台相关的特征。

1581             host->pdata = pdev->dev.platform_data;     

1582             if (!host->pdata) {                             

1583                    pdev->dev.platform_data = &s3cmci_def_pdata;                      

1584                    host->pdata = &s3cmci_def_pdata;                           

1585             }                                

1586                    

这是平台设备注册时platform_device所具有的属性,对于这里分析所使用的mini2440平台来说对应于math-mini2440.c文件中的

375    s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;      

不妨关注一下mini2440_mmc_cfg中大致的一些内容。

[arch/arm/ math-mini2440.c]

334 static struct s3c24xx_mci_pdata mini2440_mmc_cfg = {

335    .gpio_detect   = S3C2410_GPG(8),

336    .gpio_wprotect = S3C2410_GPH(8),

337    .set_power     = NULL,

338    .ocr_avail     = MMC_VDD_32_33|MMC_VDD_33_34,

339 };   

上面定义了写保护引脚、开检测以及供电范围等相关信息。                           

1587             spin_lock_init(&host->complete_lock);                                  

1588             tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);                 

1589             

tasklet就象一个内核定时器,在一个"软中断"的上下文中执行(以原子模式),常用在硬件中断处理中,使得可以使得复杂的任务安全地延后到以后的时间处理。task_init建立一个 tasklet,然后调用函数 tasklet_schedule将这个tasklet放在tasklet_vec链表的头部,并唤醒后台线程 ksoftirqd当后台线程ksoftirqd运行调用__do_softirq时,会执行在中断向量表softirq_vec中断号TASKLET_SOFTIRQ对应的 tasklet_action函数,然后 tasklet_action遍历 tasklet_vec链表,调用每个 tasklet的函数完成软中断操作,上面例子中即是pio_tasklet函数,另外软中断处理函数只能传递一个long型变量。这里是直接使用host的地址,作为传递参数。关于这个pio_tasklet现在说他还为时过早,等时辰一到自然会对他大书特书。

1590             if (is2440) {                              

1591                    host->sdiimsk = S3C2440_SDIIMSK;               

1592                    host->sdidata  = S3C2440_SDIDATA;               

1593                    host->clk_div  = 1;              

1594             } else {                              

1595                    host->sdiimsk = S3C2410_SDIIMSK;               

1596                    host->sdidata  = S3C2410_SDIDATA;               

1597                    host->clk_div  = 2;              

1598             }                                

1599             

host->sdiimskhost->sdidata分别用来存放host控制器SDI中断屏蔽寄存器和SDI数据寄存器相对SDI寄存器的偏移地址。对于s3c2440根据芯片手册SDIIntMsk偏移地址为0x3CSDIDAT偏移地址为0x40。最后host->clk_div就是指的SDI使用的时钟分频系数了。

1600             host->complete_what    = COMPLETION_NONE;                        

1601             host->pio_active    = XFER_NONE;                        

1602                    

host->complete_what是一个枚举类型变量,实际上用以标示传输完成的状态;host->pio_active标示数据传输的方向,所以在这里一起初始化为空。

关于传输完成的标示为了后面分析方便还是一起列举出来:

enum s3cmci_waitfor {

   COMPLETION_NONE,

   COMPLETION_FINALIZE,

   COMPLETION_CMDSENT,

   COMPLETION_RSPFIN,

   COMPLETION_XFERFINISH,

   COMPLETION_XFERFINISH_RSPFIN,

};              

1603      #ifdef CONFIG_MMC_S3C_PIODMA                                         

1604             host->dodma          = host->pdata->dma;                  

1605      #endif                                       

1606      

上面是同时使能了PIODMA模式的情况,这里我们对两种传输方式都做相应的分析,所以host->dodma默认为1

1607             host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);            

1608             if (!host->mem) {                             

1609                    dev_err(&pdev->dev,                         

1610                           failed to get io memory region resouce.\n);               

1611                                                

1612                    ret = -ENOENT;                        

1613                    goto probe_free_gpio;                        

1614             }                                

1615      

1616             host->mem = request_mem_region(host->mem->start,                                  

1617                                         resource_size(host->mem), pdev->name);            

1618                                                

1619             if (!host->mem) {                             

1620                    dev_err(&pdev->dev, "failed to request io memory region.\n");              

1621                    ret = -ENOENT;                        

1622                    goto probe_free_gpio;                        

1623             }                                

1624                                                

1625             host->base = ioremap(host->mem->start, resource_size(host->mem));                    

1626             if (!host->base) {                              

1627                    dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");          

1628                    ret = -EINVAL;                          

1629                    goto probe_free_mem_region;                          

1630             }                                

1631             

上面的一段代码相对比较简单,都是平台驱动设计过程中常用的几个处理函数,就不一一展开了。首先是获取IO资源,这当然即使mach-mini2440.c中所注册的IORESOURCE_MEM,

1616行会申请这个资源并检查是否可用,当然只要之前没有使用过SDI寄存器空间,这里都会申请成功。最后就是IO映射,将实地址映射为内核虚拟地址使用。最后,host->base将保持SDI寄存器基地址所对应的内核虚拟地址

1632             host->irq = platform_get_irq(pdev, 0);                            

1633             if (host->irq == 0) {                                 

1634                    dev_err(&pdev->dev, "failed to get interrupt resouce.\n");                      

1635                    ret = -EINVAL;                          

1636                    goto probe_iounmap;                         

1637             }                                

1638                                                

1639             if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {               

1640                    dev_err(&pdev->dev, "failed to request mci interrupt.\n");                     

1641                    ret = -ENOENT;                        

1642                    goto probe_iounmap;                         

1643             }                                

1644                    

上面一段是对中断资源的申请,并通过request_irq安装了中断处理函数,使能了SDI中断。在上段最为关心的是s3cmci_irq      中断处理函数及其传入的dev_id      。关于这个处理函数的分析后面讲述数据传输的时候会进行细致分析。接着向下....

1645             /* We get spurious interrupts even when we have set the IMSK                      

1646             * register to ignore everything, so use disable_irq() to make                         

1647             * ensure we don't lock the system with un-serviceable requests. */                 

1648                                                

1649             disable_irq(host->irq);                              

1650             host->irq_state = false;                              

1651             

前面我们强调了request_irq调用的结果会使能      host->irq但此时系统初始化尚未完成这时候出现的中断可能将处理器带入一个异常状态,所以1649行屏蔽中断1650行将中断状态置位无效都是有必要的。                        

1652             if (!host->pdata->no_detect) {                                 

1653                    ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");               

1654                    if (ret) {                      

1655                           dev_err(&pdev->dev, "failed to get detect gpio\n");                 

1656                           goto probe_free_irq;                   

1657                    }                         

1658                                  

如果SD卡存在的检查一般是通过读取专用引脚状态来实现的,这里如果需要做detect相关的工作的话就必须重新分配一个管脚,在当前系统中前面定义了以GPG8作为检测引脚。

1659                    host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);                    

1660                    

s3c2410_gpio_getirq是获取这个GPIO的外部中断向量号,可见后面的SD卡的检测可能会用到这个引脚的外部中断。

1661                    if (host->irq_cd >= 0) {                     

1662                           if (request_irq(host->irq_cd, s3cmci_irq_cd,                    

1663                                         IRQF_TRIGGER_RISING | 

1664                                         IRQF_TRIGGER_FALLING,      

1665                                         DRIVER_NAME, host)) {   

1666                                  dev_err(&pdev->dev,           

1667                                         can't get card detect irq.\n);  

1668                                  ret = -ENOENT;          

1669                                  goto probe_free_gpio_cd;            

1670                           }                  

1671                    } else {                       

1672                           dev_warn(&pdev->dev,               

1673                                  "host detect has no irq available\n");         

1674                           gpio_direction_input(host->pdata->gpio_detect);              

1675                    }                         

1676             } else                                 

1677                    host->irq_cd = -1;                      

1678                    

上面的这段代码意图很明显就是要申请这个中断了,s3cmci_irq_cd是其处理函数。对像SD卡这种可移出设备来作为块设备存储介质的话,大多会涉及到媒体切换,具体这方面的内容后面用到的时候也会有个详细分析。                   

1679             if (!host->pdata->no_wprotect) {                             

1680                    ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");               

1681                    if (ret) {                      

1682                           dev_err(&pdev->dev, "failed to get writeprotect\n");                

1683                           goto probe_free_irq_cd;              

1684                    }                         

1685                                                

1686                    gpio_direction_input(host->pdata->gpio_wprotect);                        

1687             }                                

1688      

与检测的管脚类似,这里就不详说了

1689             /* depending on the dma state, get a dma channel to use. */                                  

1690                                                

1691             if (s3cmci_host_usedma(host)) {                              

1692                    host->dma = s3c2410_dma_request(DMACH_SDI, &s3cmci_dma_client,

1693                                                host);

1694                    if (host->dma < 0) {                          

1695                           dev_err(&pdev->dev, "cannot get DMA channel.\n");               

1696                           if (!s3cmci_host_canpio()) {               

1697                                  ret = -EBUSY;             

1698                                  goto probe_free_gpio_wp;           

1699                           } else {                

1700                                  dev_warn(&pdev->dev, "falling back to PIO.\n");            

1701                                  host->dodma = 0;         

1702                           }                  

1703                    }                         

1704             }                                

1705             

1691行这个我们之前就默认为TURE了,所以接下来的几行代码是免不了。

1692s3c2410_dma_request申请DMA通道,对s3c2440平台有4通道的DMA。而DMACH_SDI是一个虚拟的通道号,由于这部分代码是和硬件紧密相关的,而且整个DMA的管理相对来讲比较复杂,所以这里只是粗略了解一下。

[plat-s3c24xx/dma.c]

715 int s3c2410_dma_request(unsigned int channel,                       

716                      struct s3c2410_dma_client *client,      

717                      void *dev)     

718 {                         

719        struct s3c2410_dma_chan *chan;                

720        unsigned long flags;                    

721        int err;                 

722                             

723        pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",                

724               channel, client->name, dev);             

725                            

726        local_irq_save(flags);                  

727                             

728        chan = s3c2410_dma_map_channel(channel);                   

729        if (chan == NULL) {                  

730               local_irq_restore(flags);       

731               return -EBUSY;           

732        }                  

733                             

734        dbg_showchan(chan);                 

735                             

736        chan->client = client;                  

737        chan->in_use = 1;                

738                             

739        if (!chan->irq_claimed) {                   

740               pr_debug("dma%d: %s : requesting irq %d\n",          

741                      channel, __func__, chan->irq);  

742                             

743               chan->irq_claimed = 1;        

744               local_irq_restore(flags);       

745                             

746               err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,        

747                               client->name, (void *)chan);

748                             

749               local_irq_save(flags);           

750                             

751               if (err) {        

752                      chan->in_use = 0;  

753                      chan->irq_claimed = 0; 

754                      local_irq_restore(flags);

755                             

756                      printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n", 

757                             client->name, chan->irq, chan->number);     

758                      return err;      

760                             

761               chan->irq_enabled = 1;        

762        }                  

763                             

764        local_irq_restore(flags);              

765                             

766        /* need to setup */               

767                             

768        pr_debug("%s: channel initialised, %p\n", __func__, chan);                   

769                             

770        return chan->number | DMACH_LOW_LEVEL;              

771 }                         

728行是问题的关键,调用s3c2410_dma_map_channel为虚拟的DMA通道寻找一个物理的空闲通道。相应的代码如下:

1388      static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)                    

1389      {                         

1390             struct s3c24xx_dma_order_ch *ord = NULL;                   

1391             struct s3c24xx_dma_map *ch_map;                   

1392             struct s3c2410_dma_chan *dmach;                    

1393             int ch;                  

1394                                  

1395             if (dma_sel.map == NULL || channel > dma_sel.map_size)              

1396                    return NULL;        

1397                                  

1398             ch_map = dma_sel.map + channel;                    

1399                                  

1400             /* first, try the board mapping */               

1401                                  

1402             if (dma_order) {                 

1403                    ord = &dma_order->channels[channel];             

1404                                  

1405                    for (ch = 0; ch < dma_channels; ch++) {           

1406                           if (!is_channel_valid(ord->list[ch]))    

1407                                  continue;

1408                                  

1409                           if (s3c2410_chans[ord->list[ch]].in_use == 0) { 

1410                                  ch = ord->list[ch] & ~DMA_CH_VALID;

1411                                  goto found;

1412                           }    

1413                    }           

1414                                  

1415                    if (ord->flags & DMA_CH_NEVER)         

1416                           return NULL; 

1417             }                  

1418                                  

1419             /* second, search the channel map for first free */                    

1420                                 

1421             for (ch = 0; ch < dma_channels; ch++) {                  

1422                    if (!is_channel_valid(ch_map->channels[ch]))           

1423                           continue;

1424                                  

1425                    if (s3c2410_chans[ch].in_use == 0) {         

1426                           printk("mapped channel %d to %d\n", channel, ch);  

1427                           break;    

1428                    }           

1429             }                  

1430                                  

1431             if (ch >= dma_channels)                    

1432                    return NULL;        

1433                                  

1434             /* update our channel mapping */               

1435                                  

1436      found:                       

1437             dmach = &s3c2410_chans[ch];                  

1438             dmach->map = ch_map;              

1439             dmach->req_ch = channel;                 

1440             s3c_dma_chan_map[channel] = dmach;                    

1441                                  

1442             /* select the channel */                

1443                                  

1444             (dma_sel.select)(dmach, ch_map);              

1445                                  

1446             return dmach;              

1447      }                         

从上面的代码可以看到有两种策略来寻找一个空闲的通道,找到以后就走到了found以后的代码了,1444行就是对这个找的通道进行适当的初始化。

1706             host->clk = clk_get(&pdev->dev, "sdi");                                 

1707             if (IS_ERR(host->clk)) {                                 

1708                    dev_err(&pdev->dev, "failed to find clock source.\n");                           

1709                    ret = PTR_ERR(host->clk);                       

1710                    host->clk = NULL;                     

1711                    goto probe_free_dma;                        

1712             }                                

1713                                                

1714             ret = clk_enable(host->clk);                              

1715             if (ret) {                             

1716                    dev_err(&pdev->dev, "failed to enable clock source.\n");                       

1717                    goto clk_free;                     

1718             }                                

1719                                                

1720             host->clk_rate = clk_get_rate(host->clk);                                

1721             

以上是关于sdi时钟和波特率的有关设置,都是内核提供的一些简单的函数调用,相关的内容不是现在研究的重点就不再详细分析了。                               

1722             mmc->ops     = &s3cmci_ops;           

1723             mmc->ocr_avail     = MMC_VDD_32_33 | MMC_VDD_33_34;                    

1724      #ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ                                       

1725             mmc->caps     = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;           

1726      #else                                         

1727             mmc->caps     = MMC_CAP_4_BIT_DATA;                           

1728      #endif                                       

1729             mmc->f_min = host->clk_rate / (host->clk_div * 256);                         

1730             mmc->f_max        = host->clk_rate / host->clk_div;                      

1731                                                

1732             if (host->pdata->ocr_avail)                               

1733                    mmc->ocr_avail = host->pdata->ocr_avail;                      

1734                                                

1735             mmc->max_blk_count   = 4095;                       

1736             mmc->max_blk_size      = 4095;                       

1737             mmc->max_req_size      = 4095 * 512;                     

1738             mmc->max_seg_size      = mmc->max_req_size;                      

1739                                                

1740             mmc->max_phys_segs   = 128;                         

1741             mmc->max_hw_segs     = 128;                         

1742                                                

1743             dbg(host, dbg_debug,                               

1744                 "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n",  

1745                 (host->is2440?"2440":""),                                

1746                 host->base, host->irq, host->irq_cd, host->dma);                            

1747             

上面就是对这个将要出嫁的mmc_host进行最后的设置,mmc->ops   = &s3cmci_ops;就是一直以来向core层提供的接口函数集。后面的分析可能部分是围绕它其中的函数展开的。

1748             ret = s3cmci_cpufreq_register(host);                                

1749             if (ret) {                             

1750                    dev_err(&pdev->dev, "failed to register cpufreq\n");                       

1751                    goto free_dmabuf;                      

1752             }                                

1753                    

这里使用的是Linux的通告机制,s3cmci_cpufreq_register相对应的代码如下:

1398      static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)    

1399      {    

1400             host->freq_transition.notifier_call = s3cmci_cpufreq_transition;

1401             

1402             return cpufreq_register_notifier(&host->freq_transition,

1403                    CPUFREQ_TRANSITION_NOTIFIER);

1404      }      

cpufreq_register_notifier cpu是将host->freq_transition注册到CPU频率通告链上,这个是由内核维护的,cpu频率改变时将会调用上面注册的s3cmci_cpufreq_transition的内容。

1754             ret = mmc_add_host(mmc);                              

1755             if (ret) {                             

1756                    dev_err(&pdev->dev, "failed to add mmc host.\n");                        

1757                    goto free_cpufreq;                      

1758             }                                

1759             

mmc_add_host这是core层的函数,他保存了所有平台通用的代码。同时看上去简简单单的一个mmc_add_host,可能蕴藏着天大的玄机。为此我们将为mmc_add_host另分一章,作为core层的续集,专门讲述mmc_add_host过程中发生的点点滴滴....

      在开始分析mmc_add_host之前,让我们还是结束SD主机控制器的probe函数,接下来到了1760....

1760             s3cmci_debugfs_attach(host);                                  

1761                                                

1762             platform_set_drvdata(pdev, mmc);                                  

1763             dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),

1764                    s3cmci_host_usedma(host) ? "dma" : "pio",                           

1765                    mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");                        

1766                                                

1767             return 0;                             

1768                                                

1769      free_cpufreq:                                         

1770             s3cmci_cpufreq_deregister(host);                             

1771                                                

1772      free_dmabuf:                                         

1773             clk_disable(host->clk);                              

1774                                                

1775      clk_free:                                         

1776             clk_put(host->clk);                            

1777                                                

1778      probe_free_dma:                                    

1779             if (s3cmci_host_usedma(host))                                 

1780                    s3c2410_dma_free(host->dma, &s3cmci_dma_client);                           

1781                                                

1782      probe_free_gpio_wp:                                     

1783             if (!host->pdata->no_wprotect)                                

1784                    gpio_free(host->pdata->gpio_wprotect);                          

1785                                                

1786      probe_free_gpio_cd:                                      

1787             if (!host->pdata->no_detect)                             

1788                    gpio_free(host->pdata->gpio_detect);                       

1789                                                

1790      probe_free_irq_cd:                                        

1791             if (host->irq_cd >= 0)                               

1792                    free_irq(host->irq_cd, host);                      

1793                                                

1794      probe_free_irq:                                      

1795             free_irq(host->irq, host);                                  

1796                                                

1797      probe_iounmap:                                     

1798             iounmap(host->base);                               

1799                                                

1800      probe_free_mem_region:                                       

1801             release_mem_region(host->mem->start, resource_size(host->mem));              

1802                                                

1803      probe_free_gpio:                                    

1804             for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)                             

1805                    gpio_free(i);                       

1806                                               

1807      probe_free_host:                                     

1808             mmc_free_host(mmc);                              

1809                                                

1810      probe_out:                                      

1811             return ret;                                  

1812      }                         

      上面的一段除了1760行是debugefs相关的,其他都是出错的处理了,那么也就没有必要纠结于此了,赶快开启新的生活吧....

 

core层续集之mmc_add_host

 [core/host.c]

117    int mmc_add_host(struct mmc_host *host)                

118    {                

119             int err;         

120                      

121             WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&     

122                      !host->ops->enable_sdio_irq);

123                      

124             led_trigger_register_simple(dev_name(&host->class_dev), &host->led);      

125                      

126             err = device_add(&host->class_dev);      

127             if (err)

128                      return err;

129                      

130    #ifdef CONFIG_DEBUG_FS               

131             mmc_add_host_debugfs(host);     

132    #endif         

133                      

134             mmc_start_host(host);      

135                      

136             return 0;      

137    }                

124行还是前面所说的那个LED,这里不做研究。

126行设备注册,这个host->class_dev在很早以前我们就对他进行过初始化了,其中并没有给他关联到某某总线或是驱动上,所以实际上这段代码产生的效果就是在sysfs中留下自己走过的痕迹。

130-132debug相关的可以跳过了。

134行是时候开启主机控制器了,这也是core层的函数具体的方法如下:

[core/core.c]

1118   void mmc_start_host(struct mmc_host *host)   

1119   {       

1120           mmc_power_off(host);

1121           mmc_detect_change(host, 0);

1122   }       

代码精炼到了极致,首先来看一下mmc_power_off,内容如下:

[core/core.c]

911    static void mmc_power_off(struct mmc_host *host)              

912    {                

913             host->ios.clock = 0;

914             host->ios.vdd = 0;  

915             if (!mmc_host_is_spi(host)) {      

916                      host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;

917                      host->ios.chip_select = MMC_CS_DONTCARE;

918             }       

919             host->ios.power_mode = MMC_POWER_OFF;        

920             host->ios.bus_width = MMC_BUS_WIDTH_1;         

921             host->ios.timing = MMC_TIMING_LEGACY;

922             mmc_set_ios(host); 

923    }

关心最多的就是host->ios当中的内容,前段的赋值真正作用在硬件上是调用host层向上提供的struct mmc_host_ops接口。这里922行实际上就是完成了这个工作。

      回到mmc_start_host1121行这一行的作用显然是意义重大,看名字就知道是用来检测SD卡的,内容如下:

[core/core.c]

1023   void mmc_detect_change(struct mmc_host *host, unsigned long delay)                

1024   {                

1025   #ifdef CONFIG_MMC_DEBUG           

1026           unsigned long flags;

1027           spin_lock_irqsave(&host->lock, flags);   

1028           WARN_ON(host->removed);       

1029           spin_unlock_irqrestore(&host->lock, flags);      

1030   #endif         

1031                    

1032           mmc_schedule_delayed_work(&host->detect, delay);   

1033   }

除了1032行说了句人话,其他的百分之九十九的都是废话。曾几何时我们说过内核有个延时工作队列,没错就是他了。当然这可不是随便拿来玩的,与之对应的初始化前面已经说过即INIT_DELAYED_WORK(&host->detect, mmc_rescan);

好了1032行作用的结果估计大家都能猜到了,就是延时delay时间后就会去调用mmc_rescan了。前面我们传递的delay=0,那么这里就没有延时了,既然驱动都等不及要rescan了,我们也就不再卖关子了,直接mmc_rescan

[core/core.c]

1038   void mmc_rescan(struct work_struct *work)                        

1039   {                         

1040           struct mmc_host *host =            

1041                    container_of(work, struct mmc_host, detect.work);      

1042           u32 ocr;                

1043           int err;                  

1044                              

1045           mmc_bus_get(host);         

1046                              

1047           /* if there is a card registered, check whether it is still present */                

1048           if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)             

1049                    host->bus_ops->detect(host);       

1050                              

1051           mmc_bus_put(host);                  

1052                              

1053                              

1054           mmc_bus_get(host);         

1055                              

1056           /* if there still is a card present, stop here */              

1057           if (host->bus_ops != NULL) {              

1058                    mmc_bus_put(host);         

1059                    goto out;     

1060           }                

1061                              

1062           /* detect a newly inserted card */           

1063                              

1064           /*               

1065           * Only we can add a new handler, so it's safe to                 

1066           * release the lock here.              

1067           */             

1068           mmc_bus_put(host);                  

1069                              

1070           if (host->ops->get_cd && host->ops->get_cd(host) == 0)               

1071                    goto out;     

1072                              

1073           mmc_claim_host(host);              

1074                              

1075           mmc_power_up(host);                

1076           mmc_go_idle(host);         

1077                              

1078           mmc_send_if_cond(host, host->ocr_avail);                

1079                              

1080           /*               

1081           * First we search for SDIO...              

1082           */             

1083           err = mmc_send_io_op_cond(host, 0, &ocr);              

1084           if (!err) {               

1085                    if (mmc_attach_sdio(host, ocr))    

1086                              mmc_power_off(host);

1087                    goto out;     

1088           }                

1089                              

1090           /*               

1091           * ...then normal SD...              

1092           */             

1093           err = mmc_send_app_op_cond(host, 0, &ocr);            

1094           if (!err) {               

1095                    if (mmc_attach_sd(host, ocr))      

1096                              mmc_power_off(host);

1097                    goto out;     

1098           }                

1099                              

1100           /*               

1101           * ...and finally MMC.              

1102           */             

1103           err = mmc_send_op_cond(host, 0, &ocr);                  

1104           if (!err) {               

1105                    if (mmc_attach_mmc(host, ocr))   

1106                              mmc_power_off(host);

1107                    goto out;     

1108           }                

1109                              

1110           mmc_release_host(host);             

1111           mmc_power_off(host);               

1112                              

1113   out:                      

1114           if (host->caps & MMC_CAP_NEEDS_POLL)           

1115                    mmc_schedule_delayed_work(&host->detect, HZ);      

1116   }                         

又是一个core层的函数,这可不好host表示“host很生气,后果很严重”。但是这也没办法阿,现实就是这么残酷,谁叫人家是core呢。这里又出现了个新名词bus_ops,不过我可以相当负责任的告诉你,现在我们还用不到。那么我们就直接跳到了1070行检测SD卡是否存在。那么host->ops->get_cd(host)将是我们关注的重点,他依然是那个宝刀未老的struct mmc_host_ops结构。get_cd方法正好对应函数.get_cd= s3cmci_card_present。既然都走到这来了就干脆先看完源码再说。

[host/s3cmci.c]

1177   static int s3cmci_card_present(struct mmc_host *mmc)         

1178   {                

1179           struct s3cmci_host *host = mmc_priv(mmc);    

1180           struct s3c24xx_mci_pdata *pdata = host->pdata;         

1181           int ret;         

1182                    

1183           if (pdata->gpio_detect == 0)        

1184                    return -ENOSYS;

1185                    

1186           ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;        

1187           return ret ^ pdata->detect_invert;  

1188   }                

这是利用了SD卡座的一个机械检测方法,当SD插入以后SD卡的11脚会连接到低电平,从而得到卡插入的状态。对SD卡本身来说只能利用SD3引脚来做相应的判断。1186行就是读取检测引脚的值。

      回到mmc_rescan中,继续往下....

1073行获得主机控制权,这个函数的实现前面已经详细分析过了。

1075行设置并开启主机控制器。

[core/core.c]

865 static void mmc_power_up(struct mmc_host *host)           

866 {           

867        int bit;    

868               

869        /* If ocr is set, we use it */   

870        if (host->ocr) 

871               bit = ffs(host->ocr) - 1;

872        else 

873               bit = fls(host->ocr_avail) - 1;

874               

875        host->ios.vdd = bit;      

876        if (mmc_host_is_spi(host)) {

877               host->ios.chip_select = MMC_CS_HIGH;

878               host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;

879        } else {  

880               host->ios.chip_select = MMC_CS_DONTCARE;

881               host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;

882        }    

883        host->ios.power_mode = MMC_POWER_UP;   

884        host->ios.bus_width = MMC_BUS_WIDTH_1;  

885        host->ios.timing = MMC_TIMING_LEGACY;   

886        mmc_set_ios(host);

887               

888        /*   

889        * This delay should be sufficient to allow the power supply     

890        * to reach the minimum voltage.

891        */  

892        mmc_delay(10);    

893               

894        if (host->f_min > 400000) { 

895               pr_warning("%s: Minimum clock frequency too high for "

896               

897               host->ios.clock = host->f_min;

898        } else     

899               host->ios.clock = 400000;

900               

901        host->ios.power_mode = MMC_POWER_ON;   

902        mmc_set_ios(host);

903               

904        /*   

905        * This delay must be at least 74 clock sizes, or 1 ms, or the     

906        * time required to reach a stable voltage.   

907        */  

908        mmc_delay(10);    

909 }           

上面代码比较简单,894行这里是对初始化阶段的时钟进行相应的控制,不能高于400K,否则有初始化失败的风险。其他的就是mmc_set_ios的工作了,这个我们后面分析mmc_host_ops的时候再来一起说。

      另外,SD卡的初始化一般分为几个阶段如下所示:

1076行使SD卡进入idle状态。

[core/mmc_ops.c]

96   int mmc_go_idle(struct mmc_host *host)                         

97   {                         

98          int err;                 

99          struct mmc_command cmd;                

100                             

101        /*                 

102        * Non-SPI hosts need to prevent chipselect going active during                    

103        * GO_IDLE; that would put chips into SPI mode.  Remind them of                   

104        * that in case of hardware that won't pull up DAT3/nCS otherwise.               

105        *                 

106        * SPI hosts ignore ios.chip_select; it's managed according to                 

107        * rules that must accomodate non-MMC slaves which this layer                    

108        * won't even know about.                 

109        */                

110        if (!mmc_host_is_spi(host)) {                    

111               mmc_set_chip_select(host, MMC_CS_HIGH);          

112               mmc_delay(1);             

113        }                  

114                             

115        memset(&cmd, 0, sizeof(struct mmc_command));                   

116                             

117        cmd.opcode = MMC_GO_IDLE_STATE;                  

118        cmd.arg = 0;                

119        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;             

120                             

121        err = mmc_wait_for_cmd(host, &cmd, 0);                

122                             

123        mmc_delay(1);                    

124                             

125        if (!mmc_host_is_spi(host)) {                    

126               mmc_set_chip_select(host, MMC_CS_DONTCARE);       

127               mmc_delay(1);             

128        }                  

129                             

130        host->use_spi_crc = 0;                

131                             

132        return err;                    

133 }                  

110-112行由于SD卡会根据初始化过程中CS引脚的状态来判断所采用的传输模式,这里如果不使用SPI传输,那么一定要就CS引脚置位高电平。SD卡不同传输模式下引脚的定义如下所示:

   

117-119行设置命令格式,MMC_GO_IDLE_STATE对应CMD0,然后调用121行的函数mmc_wait_for_cmd来执行命令。

125-128行将110-112行置位的引脚复位到输入状态,因为在硬件上不确定输入输出关系的引脚都应将其设置为输入,以免引起冲突。

 

      

下面就到了mmc_rescan1078....

 [core/sd_ops.c]

196 int mmc_send_if_cond(struct mmc_host *host, u32 ocr)    

197 {    

198        struct mmc_command cmd;

199        int err;

200        static const u8 test_pattern = 0xAA;

201        u8 result_pattern;

202        

203        /*

204        * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND

205        * before SD_APP_OP_COND. This command will harmlessly fail for

206        * SD 1.0 cards.

207        */

208        cmd.opcode = SD_SEND_IF_COND;

209        cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;

210        cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR;

211        

212        err = mmc_wait_for_cmd(host, &cmd, 0);  

213        if (err)   

214               return err;

215               

216        if (mmc_host_is_spi(host))   

217               result_pattern = cmd.resp[1] & 0xFF;

218        else 

219               result_pattern = cmd.resp[0] & 0xFF;

220               

221        if (result_pattern != test_pattern)  

222               return -EIO;

223               

224        return 0; 

225 }           

这是为了实现对SD 2.0的支持,因为SD 2.0在发送设置SD卡的工作电压之前必须先发送CMD8命令,对于SD1.1来说,这个命令式得不到响应的。SD 2.0版和1.1版在很多地方都有很大的不同的,相关的内容可以参考spece。具体实现的代码与mmc_go_idle类似这里就不再分析了。

 

 

mmc_rescan1083-1088行,这小段是搜索SDIO设备....

1093行是对SD卡的设置,跟踪源码:

[core/sd_ops.c]

151 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)                      

152 {                         

153        struct mmc_command cmd;                

154        int i, err = 0;                

155                             

156        BUG_ON(!host);                 

157                             

158        memset(&cmd, 0, sizeof(struct mmc_command));                   

159                             

160        cmd.opcode = SD_APP_OP_COND;                 

161        if (mmc_host_is_spi(host))                 

162               cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */        

163        else               

164               cmd.arg = ocr;             

165        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;                 

166                             

167        for (i = 100; i; i--) {                   

168               err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); 

169               if (err)          

170                      break;    

171                             

172               /* if we're just probing, do a single pass */         

173               if (ocr == 0)         

174                      break;    

175                             

176               /* otherwise wait until reset completes */           

177               if (mmc_host_is_spi(host)) {       

178                      if (!(cmd.resp[0] & R1_SPI_IDLE))   

179                             break;

180               } else {         

181                      if (cmd.resp[0] & MMC_CARD_BUSY)    

182                             break;

183               }           

184                             

185               err = -ETIMEDOUT;           

186                             

187               mmc_delay(10);           

188        }                  

189                             

190        if (rocr && !mmc_host_is_spi(host))                

191               *rocr = cmd.resp[0];            

192                             

193        return err;                    

194 }                  

160-165行还是设置cmd结构,根据我们前面所说的SD卡初始化过程,这里应该是设置目标的工作电压也就是ACMD41

167行表示mmc_wait_for_app_cmd最多重复做一百次,下面来分析一下她所做的具体工作。

[core/sd-ops.c]

65   int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,                 

66          struct mmc_command *cmd, int retries)                          

67   {                                

68          struct mmc_request mrq;                           

69                                      

70          int i, err;                     

71                                      

72          BUG_ON(!cmd);                       

73          BUG_ON(retries < 0);                       

74                                      

75          err = -EIO;                         

76                                      

77          /*                        

78          * We have to resend MMC_APP_CMD for each attempt so                          

79          * we cannot use the retries field in mmc_command.                      

80          */                       

81          for (i = 0;i <= retries;i++) {                      

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

83                                      

84                 err = mmc_app_cmd(host, card);               

85                 if (err) {               

86                        /* no point in retrying; no APP commands allowed */       

87                        if (mmc_host_is_spi(host)) {       

88                               if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)      

89                                      break;

90                        }           

91                        continue;       

92                 }                  

93                                      

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

95                                      

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

97                 cmd->retries = 0;                

98                                      

99                 mrq.cmd = cmd;                 

100               cmd->data = NULL;                   

101                                    

102               mmc_wait_for_req(host, &mrq);               

103                                    

104               err = cmd->error;                

105               if (!cmd->error)                  

106                      break;           

107                                    

108               /* no point in retrying illegal APP commands */               

109               if (mmc_host_is_spi(host)) {              

110                      if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)             

111                             break;    

112               }                  

113        }                         

114                                    

115        return err;                           

116 }                                

上面的代码我们分为两部分来看,81-92行为第一部分,94-113行为第二部分。同样mmc_app_cmd被重复了retries次。不妨看下84行的代码:

[core/sd-ops.c]

23   static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)                      

24   {                                

25          int err;                        

26          struct mmc_command cmd;                       

27                                      

28          BUG_ON(!host);                        

29          BUG_ON(card && (card->host != host));                        

30                                      

31          cmd.opcode = MMC_APP_CMD;                     

32                                      

33          if (card) {                           

34                 cmd.arg = card->rca << 16;                

35                 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;            

36          } else {                       

37                 cmd.arg = 0;                

38                 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_BCR;          

39          }                         

40                                      

41          err = mmc_wait_for_cmd(host, &cmd, 0);                       

42          if (err)                        

43                 return err;                    

44                                      

45          /* Check that card supported application commands */                           

46          if (!mmc_host_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD))                        

47                 return -EOPNOTSUPP;              

48                                      

49          return 0;                      

50   }                                

和前面所分析的情况一致,这里最后还是在调用mmc_wait_for_cmd实现MMC_APP_CMACMD55)命令,根据前面的流程图我们知道在非SPI模式下设置ACMD41命令之前,必须先发送ACMD55命令进入AMD模式。因此这里的处理时为了保证ACMD41命令的成功执行。回到mmc_wait_for_app_cmd函数中来....

 

94-112行前面传递过来的ACMD41命令这里就会重新组装成struct mmc_request结构,然后调用mmc_wait_for_cmd(host, &cmd, 0);来执行。

109-112行作为SPI传输来讲这些个命令式被忽略的,所以出现了错误,只要状态指明了R1_SPI_ILLEGAL_COMMAND就不用在重试了。回到mmc_send_app_op_cond函数....

 

177-183行对于非SPI模式,通过判断返回的状态寄存器rSDIRSP0的第三十一位是否为1,来决定SD卡进入了ready状态。1ready0busy

190-191行这是返回的电压范围。如果一切正常认为初始化的第二阶段已经完成了,就该回到mmc_rescan1095mmc_attach_sd函数了。

[core/sd.c]

658 int mmc_attach_sd(struct mmc_host *host, u32 ocr)                 

659 {                  

660        int err;          

661                      

662        BUG_ON(!host);          

663        WARN_ON(!host->claimed);       

664                      

665        mmc_sd_attach_bus_ops(host);           

666                      

667        /*          

668        * We need to get OCR a different way for SPI.        

669        */         

670        if (mmc_host_is_spi(host)) {       

671               mmc_go_idle(host);      

672                      

673               err = mmc_spi_read_ocr(host, 0, &ocr);     

674               if (err)   

675                      goto err;

676        }           

677                      

678        /*          

679        * Sanity check the voltages that the card claims to           

680        * support.           

681        */         

682        if (ocr & 0x7F) {         

683               printk(KERN_WARNING "%s: card claims to support voltages "     

684                      "below the defined range. These will be ignored.\n",    

685                      mmc_hostname(host));   

686               ocr &= ~0x7F;      

687        }           

688                      

689        if (ocr & MMC_VDD_165_195) {             

690               printk(KERN_WARNING "%s: SD card claims to support the "

691                      "incompletely defined 'low voltage range'. This "  

692                      "will be ignored.\n", mmc_hostname(host)); 

693               ocr &= ~MMC_VDD_165_195;  

694        }           

695                      

696        host->ocr = mmc_select_voltage(host, ocr);       

697                      

698        /*          

699        * Can we support the voltage(s) of the card(s)?        

700        */         

701        if (!host->ocr) {           

702               err = -EINVAL;    

703               goto err; 

704        }           

705                      

706        /*          

707        * Detect and init the card.          

708        */         

709        err = mmc_sd_init_card(host, host->ocr, NULL);       

710        if (err)          

711               goto err; 

712                      

713        mmc_release_host(host);             

714                      

715        err = mmc_add_card(host->card);       

716        if (err)          

717               goto remove_card; 

718                      

719        return 0;        

720                      

721 remove_card:               

722        mmc_remove_card(host->card);          

723        host->card = NULL;            

724        mmc_claim_host(host);        

725 err:               

726        mmc_detach_bus(host);        

727        mmc_release_host(host);             

728                      

729        printk(KERN_ERR "%s: error %d whilst initialising SD card\n",            

730               mmc_hostname(host), err);   

731                      

732        return err;             

733 }                  

这个函数开始对SD的初始化,下面我们来详细分析。

665行完成bus_opsSD卡的绑定,这也就是我们之间所见到的内容,其对应的实现如下:

[core/sd.c]

642 static void mmc_sd_attach_bus_ops(struct mmc_host *host)             

643 {           

644        const struct mmc_bus_ops *bus_ops;   

645               

646        if (host->caps & MMC_CAP_NONREMOVABLE)    

647               bus_ops = &mmc_sd_ops_unsafe;

648        else 

649               bus_ops = &mmc_sd_ops;

650        mmc_attach_bus(host, bus_ops);  

651 }           

646-649行设置了bus_ops对应的方法,这里我们选择mmc_sd_ops,里面对应的具体内容我们用到的时候在去分析。

650行是总线方法和host绑定的过程,中间的内容比较简单就是将bus_ops关联到host->bus_ops上,同时对总线的引用计数进行初始化。相应的代码如下:

[core/core.c]

968 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops)       

969 {           

970        unsigned long flags;      

971               

972        BUG_ON(!host);   

973        BUG_ON(!ops);    

974               

975        WARN_ON(!host->claimed);

976               

977        spin_lock_irqsave(&host->lock, flags);

978               

979        BUG_ON(host->bus_ops);   

980        BUG_ON(host->bus_refs);   

981               

982        host->bus_ops = ops;    

983        host->bus_refs = 1;

984        host->bus_dead = 0;

985        

986        spin_unlock_irqrestore(&host->lock, flags);

987 }    

 

这个总线绑定的过程一旦完成就又重新回到了mmc_attach_sd

670-676行我们前面分析获取工作电压范围的过程是针对非SPI模式的,这里对于SPI模式我们需要重新获取。

671行首先重新进入idle状态,这个无论哪种工作模式都是一样的。

673行是获取ocr的区别,对于spi使用的命令字为ACMD58,其他的就和一般的命令发送大相径庭了。

[core/mmc_ops.c]

355 int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)    

356 {    

357        struct mmc_command cmd;

358        int err;

359        

360        memset(&cmd, 0, sizeof(struct mmc_command));

361        

362        cmd.opcode = MMC_SPI_READ_OCR;

363        cmd.arg = highcap ? (1 << 30) : 0;

364        cmd.flags = MMC_RSP_SPI_R3;

365        

366        err = mmc_wait_for_cmd(host, &cmd, 0);

367        

368        *ocrp = cmd.resp[1];

369        return err;

370 }    

上面一段代码注意368行获取ocr的差异。

 

       回到mmc_attach_sd696mmc_select_voltage(host, ocr),这是根据host的电压范围和读取到的SD卡工作电压,来判断工作电压是否匹配。函数内容如下:

[core/core.c]

822 u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)                      

823 {                         

824        int bit;                  

825                             

826        ocr &= host->ocr_avail;              

827                             

828        bit = ffs(ocr);               

829        if (bit) {               

830               bit -= 1;        

831                             

832               ocr &= 3 << bit;          

833                             

834               host->ios.vdd = bit;             

835               mmc_set_ios(host);       

836        } else {                

837               pr_warning("%s: host doesn't support card's voltages\n",           

838                             mmc_hostname(host));

839               ocr = 0;         

840        }                  

841                             

842        return ocr;                   

843 }                         

host->ocr_avail前面我们已经进行了相应的初始化。

.ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34

 

 

      回到mmc_attach_sd函数中,下面就到了整个mmc_rescan的高潮部分了,也就是一直在说的初始化SD卡,对应709err = mmc_sd_init_card(host, host->ocr, NULL);这个函数完成了整个SD卡初始化的全动作,下面来看代码:

[core/sd.c]

332 static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,     

333        struct mmc_card *oldcard)

334 {    

335        struct mmc_card *card;

336        int err;

337        u32 cid[4];

338        unsigned int max_dtr;

339        

340        BUG_ON(!host);

341        WARN_ON(!host->claimed);

342        

343        /*

344        * Since we're changing the OCR value, we seem to

345        * need to tell some cards to go back to the idle

346        * state.  We wait 1ms to give cards time to

347        * respond.

348        */  

349        mmc_go_idle(host);      

350               

351        /*   

352        * If SD_SEND_IF_COND indicates an SD 2.0 

353        * compliant card and we should set bit 30 

354        * of the ocr to indicate that we can handle 

355        * block-addressed SDHC cards.  

356        */  

357        err = mmc_send_if_cond(host, ocr);    

358        if (!err)  

359               ocr |= 1 << 30;

360               

361        err = mmc_send_app_op_cond(host, ocr, NULL);      

362        if (err)   

363               goto err;

364                      

365        /*          

366        *Fetch CID from card.             

367        */         

368        if (mmc_host_is_spi(host))          

369               err = mmc_send_cid(host, cid);    

370        else        

371               err =mmc_all_send_cid(host, cid);     

372        if (err)          

373               goto err; 

374                      

375        if (oldcard) {        

376               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {    

377                      err = -ENOENT;

378                      goto err;

379               }    

380                      

381               card = oldcard;      

382        } else {         

383               /*   

384               * Allocate card structure.    

385               */  

386               card =mmc_alloc_card(host, &sd_type);    

387               if (IS_ERR(card)) {     

388                      err = PTR_ERR(card);

389                      goto err;

390               }    

391                      

392               card->type = MMC_TYPE_SD;   

393               memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); 

394        }           

395                      

396        /*          

397        * For native busses:  get card RCA and quit open drain mode.       

398        */         

399        if (!mmc_host_is_spi(host)) {             

400               err = mmc_send_relative_addr(host, &card->rca);     

401               if (err)   

402                      goto free_card;

403                      

404               mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);    

405        }           

406                      

407        if (!oldcard) {       

408               /*   

409               * Fetch CSD from card.     

410               */  

411               err = mmc_send_csd(card, card->raw_csd); 

412               if (err)   

413                      goto free_card;

414                      

415               err = mmc_decode_csd(card);      

416               if (err)   

417                      goto free_card;

418                      

419               mmc_decode_cid(card);

420        }           

421                      

422        /*          

423        * Select card, as all following commands rely on that.            

424        */         

425        if (!mmc_host_is_spi(host)) {             

426               err = mmc_select_card(card);      

427               if (err)   

428                      goto free_card;

429        }           

430                      

431        if (!oldcard) {       

432               /*   

433               * Fetch SCR from card.     

434               */  

435               err = mmc_app_send_scr(card, card->raw_scr);  

436               if (err)   

437                      goto free_card;

438                      

439               err = mmc_decode_scr(card);      

440               if (err < 0)     

441                      goto free_card;

442                      

443               /*   

444               * Fetch switch information from card.      

445               */  

446               err = mmc_read_switch(card);     

447               if (err)   

448                      goto free_card;

449        }           

450                      

451        /*          

452        * For SPI, enable CRC as appropriate.             

453        * This CRC enable is located AFTER the reading of the          

454        * card registers because some SDHC cards are not able           

455        * to provide valid CRCs for non-512-byte blocks.           

456        */         

457        if (mmc_host_is_spi(host)) {       

458               err = mmc_spi_set_crc(host, use_spi_crc);  

459               if (err)   

460                      goto free_card;

461        }           

462                      

463        /*          

464        * Attempt to change to high-speed (if supported)            

465        */         

466        err = mmc_switch_hs(card);        

467        if (err)          

468               goto free_card;      

469                      

470        /*          

471        * Compute bus speed.        

472        */         

473        max_dtr = (unsigned int)-1;         

474                      

475        if (mmc_card_highspeed(card)) {        

476               if (max_dtr > card->sw_caps.hs_max_dtr)  

477                      max_dtr = card->sw_caps.hs_max_dtr;

478        } else if (max_dtr > card->csd.max_dtr) {         

479               max_dtr = card->csd.max_dtr;     

480        }           

481                      

482        mmc_set_clock(host, max_dtr);          

483                      

484        /*          

485        * Switch to wider bus (if supported).        

486        */         

487        if ((host->caps & MMC_CAP_4_BIT_DATA) &&            

488               (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {    

489               err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);  

490               if (err)   

491                      goto free_card;

492                             

493               mmc_set_bus_width(host, MMC_BUS_WIDTH_4);          

494        }                  

495                             

496        /*                 

497        * Check if read-only switch is active.               

498        */                

499        if (!oldcard) {              

500               if (!host->ops->get_ro || host->ops->get_ro(host) < 0) {           

501                      printk(KERN_WARNING "%s: host does not "  

502                             support reading read-only

503                             switch. assuming write-enable.\n,

504                             mmc_hostname(host));

505               } else {         

506                      if (host->ops->get_ro(host) > 0)  

507                             mmc_card_set_readonly(card);

508               }

509        }    

510               

511        if (!oldcard)   

512               host->card = card;

513               

514        return 0; 

515               

516 free_card:             

517        if (!oldcard)   

518               mmc_remove_card(card);

519 err:        

520               

521        return err;      

522 }           

这段代码洋洋洒洒二百余行,着实有点难看。但是没关系,深呼吸一下继续来看代码...

349行再见了mmc_go_idle(host),话可以乱说但是代码可不能乱写。这个函数在这里不为别的,只因前面修改了ocr的值。所以必须让大家都回到idle状态。

357行还是那个熟悉的背影,依旧是为SD 2.0而生。

361行还是前面花了大力气分析过的函数,这里就不必要重申了。

 

再继续向前之前还是要去瞅瞅我们之前贴出来的那张初始化流程图,下面的时间该到获取卡的身份信息了,由此SD卡将步入identification时代,使用的命令是CMD2

368-371行我们选择err = mmc_all_send_cid(host, cid),跟踪源码:

[/core/mmc_ops.c]

177 int mmc_all_send_cid(struct mmc_host *host, u32 *cid)           

178 {           

179        int err;   

180        struct mmc_command cmd;  

181               

182        BUG_ON(!host);   

183        BUG_ON(!cid);    

184               

185        memset(&cmd, 0, sizeof(struct mmc_command));     

186               

187        cmd.opcode = MMC_ALL_SEND_CID;     

188        cmd.arg = 0;  

189        cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;      

190               

191        err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);     

192        if (err)   

193               return err;

194               

195        memcpy(cid, cmd.resp, sizeof(u32) * 4);    

196               

197        return 0; 

198 }           

187行跟据#define MMC_ALL_SEND_CID     2可以确定,此刻的SD卡即将进入激动人心的时刻identification

195行回复的就是我们一直想得到的身份信息了。

       函数的其他内容就是炒剩饭了,所有的罪就让mmc_wait_for_cmd来背吧。

飘啊飘,总算是飘到了386mmc_alloc_card,这个函数就是为了分配一个struct mmc_card结构,相信读过card部分的朋友对她应该是不再陌生了。打个比方来说这个函数就好比领身份证SD卡都已经走到了identification这一步了,却还没有一个东西能证明他的身份的,您说她冤不冤。好了,就发个证件给她吧,于是乎聪明的内核开发者就想到了mmc_alloc_card。具体是怎么工作的就只能看源码啦!

[core/bus.c]

199 struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type)     

200 {           

201        struct mmc_card *card; 

202               

203        card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); 

204        if (!card)

205               return ERR_PTR(-ENOMEM);

206               

207        card->host = host; 

208               

209        device_initialize(&card->dev);     

210               

211        card->dev.parent = mmc_classdev(host);     

212        card->dev.bus = &mmc_bus_type;      

213        card->dev.release = mmc_release_card;

214        card->dev.type = type;  

215               

216        return card;    

217 }           

207行吃水不忘挖井人,辛辛苦苦为SD卡操劳了N久的host总算还是被struct mmc_host第一个给记下了。当然后面对这个SD卡的所有操作也就顺理成章的交给了card->host

209-214行您是否还依稀记得早在分析card目录的时候,讲到一个driver的注册,却始终未见他命中注定的那个device那么现在我以一种极其负责任的态度来告诉您,在不久以后的某个黄道吉日,您眼前的这个device将和前面那位苦苦等待他的driver一起步入婚姻的殿堂。当然为这对新人牵线搭桥的还有mmc_bus_type这条总线。这一切过后是时候返回了。

392-393行是对这个新生的card做对应的初始化。

       始终不忘的是那张动情的SD卡初始化流程图,indentification过后就到了设置RCA阶段了,mmc_send_relative_addr最终将不辱使命,内容如下:

[core/sd_ops.c]

227 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)           

228 {           

229        int err;   

230        struct mmc_command cmd;  

231               

232        BUG_ON(!host);   

233        BUG_ON(!rca);    

234               

235        memset(&cmd, 0, sizeof(struct mmc_command));     

236               

237        cmd.opcode = SD_SEND_RELATIVE_ADDR;  

238        cmd.arg = 0;  

239        cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;      

240               

241        err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);     

242        if (err)   

243               return err;

244               

245        *rca = cmd.resp[0] >> 16;    

246               

247        return 0; 

248 }           

237行设置的正是CMD3,这个函数过后SD卡将转入stand-by状态SD卡最终要到的西方极乐世界是transfer,现在距离他也就真的只有一步之遥了。好了,回到mmc_sd_init_card再接再厉...

 

404mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);实总线就两种模式要么open drain也就是漏极开路或者push-pull上拉。现在都开始要传输数据了,您说该是哪种模式呢。对于host总线的设置还是利用host->ops->set_ios实现的,具体代码如下:

[core/core.c]

630 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)      

631 {    

632        host->ios.bus_mode = mode;

633        mmc_set_ios(host);

634 }    

 

上面所做的工作全部完成以后,接下来就是通过CMD9读取卡的CSD寄存器。从CSD寄存器中,获知卡容量,支持的命令集等重要参数了。411-419为您解决了一切后顾之忧,显然mmc_send_csd是来发送csd命令的。

[core/mmc_ops.c]

310 int mmc_send_csd(struct mmc_card *card, u32 *csd)                      

311 {                         

312        int ret, i;               

313                             

314        if (!mmc_host_is_spi(card->host))                    

315               return mmc_send_cxd_native(card->host, card->rca << 16,             

316                             csd, MMC_SEND_CSD);

317                             

318        ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);                    

319        if (ret)                  

320               return ret;             

321                             

322        for (i = 0;i < 4;i++)                    

323               csd[i] = be32_to_cpu(csd[i]);       

324                             

325        return 0;               

326 }

对于我们一直跟踪的非SPI模式,315行成了整个函数的焦点。MMC_SEND_CSD对应的是CMD9mmc_send_cxd_native的内容如下:

[core/mmc_ops.c]

222 mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)       

223 {           

224        int err;   

225        struct mmc_command cmd;  

226               

227        BUG_ON(!host);   

228        BUG_ON(!cxd);   

229               

230        memset(&cmd, 0, sizeof(struct mmc_command));     

231               

232        cmd.opcode = opcode;  

233        cmd.arg = arg;      

234        cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; 

235               

236        err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);     

237        if (err)   

238               return err;

239               

240        memcpy(cxd, cmd.resp, sizeof(u32) * 4);   

241               

242        return 0; 

243 }           

与其他设置命令类的函数一样mmc_send_cxd_native依然具有着足够清晰地脉络,有着永远不变的调用顺序。这个函数返回以后整个获取CSD的工作就做完了,结果保存在传递的cxd变量中。回到mmc_init_card...

416取出了CSD的参数,但是哪些个字段表示什么意思就得decode了,下面来看mmc_decode_csd

[core/sd.c]

90   static int mmc_decode_csd(struct mmc_card *card)                  

91   {                  

92          struct mmc_csd *csd = &card->csd;           

93          unsigned int e, m, csd_struct;       

94          u32 *resp = card->raw_csd;         

95                        

96          csd_struct = UNSTUFF_BITS(resp, 126, 2);             

97                        

98          switch (csd_struct) {            

99          case 0:           

100               m = UNSTUFF_BITS(resp, 115, 4);    

101               e = UNSTUFF_BITS(resp, 112, 3);     

102               csd->tacc_ns   = (tacc_exp[e] * tacc_mant[m] + 9) / 10;

103               csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;

104                      

105               m = UNSTUFF_BITS(resp, 99, 4);     

106               e = UNSTUFF_BITS(resp, 96, 3);      

107               csd->max_dtr    = tran_exp[e] * tran_mant[m];

108               csd->cmdclass   = UNSTUFF_BITS(resp, 84, 12);

109                      

110               e = UNSTUFF_BITS(resp, 47, 3);      

111               m = UNSTUFF_BITS(resp, 62, 12);   

112               csd->capacity    = (1 + m) << (e + 2);

113                      

114               csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);    

115               csd->read_partial = UNSTUFF_BITS(resp, 79, 1);    

116               csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);

117               csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); 

118               csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);      

119               csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);   

120               csd->write_partial = UNSTUFF_BITS(resp, 21, 1);   

121               break;    

122        case 1:           

123               /*   

124               * This is a block-addressed SDHC card. Most   

125               * interesting fields are unused and have fixed   

126               * values. To avoid getting tripped by buggy cards,   

127               * we assume those fixed values ourselves. 

128               */  

129               mmc_card_set_blockaddr(card);   

130                      

131               csd->tacc_ns   = 0; /* Unused */

132               csd->tacc_clks = 0; /* Unused */

133                      

134               m = UNSTUFF_BITS(resp, 99, 4);     

135               e = UNSTUFF_BITS(resp, 96, 3);      

136               csd->max_dtr    = tran_exp[e] * tran_mant[m];

137               csd->cmdclass   = UNSTUFF_BITS(resp, 84, 12);

138                      

139               m = UNSTUFF_BITS(resp, 48, 22);   

140               csd->capacity     = (1 + m) << 10;   

141                      

142               csd->read_blkbits = 9;  

143               csd->read_partial = 0;   

144               csd->write_misalign = 0;      

145               csd->read_misalign = 0;

146               csd->r2w_factor = 4; /* Unused */      

147               csd->write_blkbits = 9; 

148               csd->write_partial = 0;  

149               break;    

150        default:         

151               printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",      

152                      mmc_hostname(card->host), csd_struct);

153               return -EINVAL;   

154        }           

155                      

156        return 0;        

157 }                  

在分析上面的函数之前,首先还是来给出一张寄存器表,如下:

首先来看一下96行频频出现的UNSTUFF_BITS,其实他是个宏定义,具体的形式如下:

[core/sd.c]

44   #define UNSTUFF_BITS(resp,start,size)                                 \                          

45          ({                                                     \

46                 const int __size = size;                        \                   

47                 const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;     \                          

48                 const int __off = 3 - ((start) / 32);               \                          

49                 const int __shft = (start) & 31;                    \                          

50                 u32 __res;                                         \     

51                                                                  \

52                 __res = resp[__off] >> __shft;                           \                   

53                 if (__size + __shft > 32)                            \                   

54                        __res |= resp[__off-1] << ((32 - __shft) % 32);   \                                 

55                 __res & __mask;                                       \     

56          })                                                    

上面一段代码纠结于C语言各种运算符,但是总的来说还是比较清晰地。为了对应背景我们就以resp[4]为例来说明。首先明确这个宏中resp[4]是当做一个4*32bit的数据来对待的,高位地址resp数组的第四个数据占据最高位,start指的是4*32bit中从哪一位起始,size是指提取几位的数据。UNSTUFF_BITS(resp, 126, 2);就是指提取resp数组中的126127位。对照上面的表可以看出取出的正是csd struct

接下来就是根据csd_struct的情况来决定是SD1.1还是SD2.0标准。这里我们关注SD2.0的情况。

129行设置了设备的状态为MMC_STATE_BLOCKADDR,这是SD卡版本所决定的。记性好的朋友可能还记得在card中有一个叫做mmc_blk_set_blksize的函数,里面会使用

#define mmc_card_blockaddr(c)   ((c)->state & MMC_STATE_BLOCKADDR)判断是否设置块大小,这个依据出现在这里。

136max. data transfer rate最大数据传输率定义在96-106bit,这里也就能够简单地得到了。

137card command classes指明SD卡所属的指令集,它使用的是84位以后的12bit来表示。

其他的内容就比较明确了,这里就不一一列出了。

回到mmc_init_card中接下来就该解码CID了,所用的函数即mmc_decode_cid。代码如下:

[core/sd.c]

61   static void mmc_decode_cid(struct mmc_card *card)                      

62   {                         

63          u32 *resp = card->raw_cid;                

64                               

65          memset(&card->cid, 0, sizeof(struct mmc_cid));              

66                               

67          /*                 

68          * SD doesn't currently have a version field so we will                    

69          * have to assume we can parse this.                 

70          */                

71          card->cid.manfid           = UNSTUFF_BITS(resp, 120, 8);

72          card->cid.oemid                   = UNSTUFF_BITS(resp, 104, 16);

73          card->cid.prod_name[0]        = UNSTUFF_BITS(resp, 96, 8);  

74          card->cid.prod_name[1]        = UNSTUFF_BITS(resp, 88, 8);  

75          card->cid.prod_name[2]        = UNSTUFF_BITS(resp, 80, 8);  

76          card->cid.prod_name[3]        = UNSTUFF_BITS(resp, 72, 8);  

77          card->cid.prod_name[4]        = UNSTUFF_BITS(resp, 64, 8);  

78          card->cid.hwrev                   = UNSTUFF_BITS(resp, 60, 4);

79          card->cid.fwrev                   = UNSTUFF_BITS(resp, 56, 4);

80          card->cid.serial             = UNSTUFF_BITS(resp, 24, 32);

81          card->cid.year               = UNSTUFF_BITS(resp, 12, 8);

82          card->cid.month                   = UNSTUFF_BITS(resp, 8, 4);

83                               

84          card->cid.year += 2000; /* SD cards year offset */                  

85   }                         

CSD一样,首先来看看它的家谱图如下:

里面始终使用的是UNSTUFF_BITS这个宏定义,具体的内容参照上面的图应该比较清晰就不下详述了。

       清醒一下重新回到我们一直讨论的主旋律——SD卡初始化。依旧是那张唠叨了千遍地流程图,好了下一步我们该大步迈进选择SD卡阶段了,这个黑暗的时刻过后,SD卡将走上新的人生轨道,transfer397行判断传输模式,对于SPI而言,有一个大名鼎鼎的CS信号,所以做法就稍微有点不一样了。我们只谈if (!mmc_host_is_spi(host))成立的时候,那么走进mmc_select_card是必然的趋势了。

[core/mmc_ops.c]

48   int mmc_select_card(struct mmc_card *card)     

49   {    

50          BUG_ON(!card);

51          

52          return _mmc_select_card(card->host, card);

53   }    

目光投向_mmc_select_card,其实聪明的你早就应该猜到这个函数是怎么做的了,还是来看看源码:

[core/mmc_ops.c]

22   static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)                  

23   {                         

24          int err;                 

25          struct mmc_command cmd;                

26                               

27          BUG_ON(!host);                 

28                               

29          memset(&cmd, 0, sizeof(struct mmc_command));                   

30                               

31          cmd.opcode = MMC_SELECT_CARD;                    

32                               

33          if (card) {                    

34                 cmd.arg = card->rca << 16;         

35                 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;        

36          } else {                

37                 cmd.arg = 0;         

38                 cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;          

39          }                  

40                               

41          err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);                   

42          if (err)                 

43                 return err;             

44                               

45          return 0;               

46   }                         

依旧是那张熟悉的脸,前面见多了,这里就不想在分析了。

回到mmc_sd_init_card436行开始就要获取SD卡的SCR寄存器了,SCR寄存器共64位,是关于这个SD卡的特殊功能的特性信息。关于这个用的比较少我们就不进去研究了,有兴趣的朋友可以自己看看源码。

447行是用来切换SD卡至高速模式,使用命令CMD6CMD6SD卡用来扩展功能的一条重要命令。在SD协议1.002.00的版本是,该命令主要用于切换卡进入高速模式。CMD6命令共有查询模式和设置模式两种。查询模式主要用于查询是否支持该功能,而设置模式主要用于对该功能的设置。我们采取的流程是先查询,后设置。根据SPEC,因此,我们第一次发送的命令参数应该为:0x00, 0xff, 0xff, 0xf1。该命令的作用是查询AccessMode是否支持High-Speed。命令发送完毕,这里需要注意的是CMD6并不是用命令总线,而是用数据总线来进行应答。在命令发送完毕时,我们会从数据总线上接收到64Byte的数据。根据SPEC,我们判断第17Byte的低4Bit(是否等于1。是则继续,否则表示不支持高速模式。

有了这个背景下面分析一下它相关的源码:

[core/sd.c]

188 static int mmc_read_switch(struct mmc_card *card)                 

189 {                  

190        int err;          

191        u8 *status;            

192                      

193        if (card->scr.sda_vsn < SCR_SPEC_VER_1)            

194               return 0; 

195                      

196        if (!(card->csd.cmdclass & CCC_SWITCH)) {          

197               printk(KERN_WARNING "%s: card lacks mandatory switch "  

198                      function, performance might suffer.\n,

199                      mmc_hostname(card->host));

200               return 0; 

201        }           

202                      

203        err = -EIO;           

204                      

205        status = kmalloc(64, GFP_KERNEL);        

206        if (!status) {          

207               printk(KERN_ERR "%s: could not allocate a buffer for "  

208                      switch capabilities.\n, mmc_hostname(card->host));

209               return -ENOMEM;

210        }           

211                      

212        err = mmc_sd_switch(card, 0, 0, 1, status);        

213        if (err) {        

214               /* If the host or the card can't do the switch,

215               * fail more gracefully. */    

216               if ((err != -EINVAL)    

217               && (err != -ENOSYS)      

218               && (err != -EFAULT))      

219                      goto out;

220                      

221               printk(KERN_WARNING "%s: problem reading switch " 

222                      capabilities, performance might suffer.\n,

223                      mmc_hostname(card->host));

224               err = 0;  

225                      

226               goto out;

227        }           

228                      

229        if (status[13] & 0x02)          

230               card->sw_caps.hs_max_dtr = 50000000;     

231                      

232 out:               

233        kfree(status);         

234                      

235        return err;             

236 }                  

193行如果通过scr判断是ver1.1版,那么这里就没有必要继续做后面的工作了。

205行根据前面的描述,cmd6会利用数据线返回64个字节的信息,这个就是为了存放读取的状态值的。

212行是整个命令设置的重点,源码如下:

[core/sd_ops.c]

302 int mmc_sd_switch(struct mmc_card *card, int mode, int group,                    

303        u8 value, u8 *resp)       

304 {                  

305        struct mmc_request mrq;             

306        struct mmc_command cmd;         

307        struct mmc_data data;          

308        struct scatterlist sg;       

309                      

310        BUG_ON(!card);         

311        BUG_ON(!card->host);       

312                      

313        /* NOTE: caller guarantees resp is heap-allocated */          

314                      

315        mode = !!mode;           

316        value &= 0xF;             

317                      

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

319        memset(&cmd, 0, sizeof(struct mmc_command));            

320        memset(&data, 0, sizeof(struct mmc_data));       

321                      

322        mrq.cmd = &cmd;        

323        mrq.data = &data;        

324                      

325        cmd.opcode = SD_SWITCH;       

326        cmd.arg = mode << 31 | 0x00FFFFFF;       

327        cmd.arg &= ~(0xF << (group * 4));           

328        cmd.arg |= value << (group * 4);        

329        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;       

330                      

331        data.blksz = 64;            

332        data.blocks = 1;            

333        data.flags = MMC_DATA_READ;       

334        data.sg = &sg;       

335        data.sg_len = 1;            

336                      

337        sg_init_one(&sg, resp, 64);         

338                      

339        mmc_set_data_timeout(&data, card);          

340                      

341        mmc_wait_for_req(card->host, &mrq);             

342                      

343        if (cmd.error)       

344               return cmd.error;   

345        if (data.error)        

346               return data.error;   

347                      

348        return 0;        

349 }                 

这条命令由于有数据的返回所以设计上较设置命令稍稍复杂一些,并由 mmc_wait_for_req来完成整个命令请求的。前面在分析card目录过程当中我们对数据的传输请求做了详细的分析,这里请求与之前见到的一致需要一个struct mmc_request结构,并初始化正确的struct mmc_data同时struct scatterlist散列结构也是必须的,并利用337 sg_init_one(&sg, resp, 64);初始化了一个散列入口。

339mmc_set_data_timeout(&data, card);      设置底层处理超时的参数,这个后面在分析host_ops中会提到。

341mmc_wait_for_req就是整个函数期待的核心了。如果没有错误mmc_sd_switch就带着返回的数据高高兴兴的返回到mmc_read_switch的怀抱。 

       还剩下最后要说的两行229-230,根据返回设置卡允许的最大数据传输速率

继续向下,mmc_sd_init_card 467行,前面我们说过一旦支持高速模式,那么就会利用CMD6来设置高速模式。

[core/sd.c]

241 static int mmc_switch_hs(struct mmc_card *card)                    

242 {                  

243        int err;          

244        u8 *status;            

245                      

246        if (card->scr.sda_vsn < SCR_SPEC_VER_1)            

247               return 0; 

248                      

249        if (!(card->csd.cmdclass & CCC_SWITCH))             

250               return 0; 

251                      

252        if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))       

253               return 0; 

254                      

255        if (card->sw_caps.hs_max_dtr == 0)          

256               return 0; 

257                      

258        err = -EIO;           

259                      

260        status = kmalloc(64, GFP_KERNEL);        

261        if (!status) {          

262               printk(KERN_ERR "%s: could not allocate a buffer for "  

263                      switch capabilities.\n, mmc_hostname(card->host));

264               return -ENOMEM;

265        }           

266                      

267        err = mmc_sd_switch(card, 1, 0, 1, status);        

268        if (err)          

269               goto out;

270                      

271        if ((status[16] & 0xF) != 1) {             

272               printk(KERN_WARNING "%s: Problem switching card " 

273                      into high-speed mode!\n,

274                      mmc_hostname(card->host));

275        } else {         

276               mmc_card_set_highspeed(card);   

277               mmc_set_timing(card->host, MMC_TIMING_SD_HS);    

278        }           

279                      

280 out:               

281        kfree(status);         

282                      

283        return err;             

284 }                  

前面已经说过,第二个设置阶段所做的事情还是一样,所以仍然调用了mmc_sd_switch,但是请注意传递的参数是有区别的。

271行根据返回的statue决定判断是否转化状态。

276mmc_card_set_highspeed(card);就是将这个好消息,记录在card当中。

#define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)

277行就是对SD控制器进行设置了。

[core/core.c]

848 void mmc_set_timing(struct mmc_host *host, unsigned int timing)          

849 {           

850        host->ios.timing = timing;    

851        mmc_set_ios(host);

852 }           

回到mmc_sd_init_card中来,476-481行最终会得到一个合适的max_dtr。然后调用mmc_set_clock对主机控制器的时钟进行设置。

[core/core.c]

616 void mmc_set_clock(struct mmc_host *host, unsigned int hz)          

617 {           

618        WARN_ON(hz < host->f_min);   

619               

620        if (hz > host->f_max)   

621               hz = host->f_max;

622               

623        host->ios.clock = hz;    

624        mmc_set_ios(host);

625 }           

最后一段将会设置DATA总线宽度。这个依然使用我们前面所说的CMD6命令,调用的函数是mmc_app_set_bus_width,源码如下:

[core/sd_ops.c]

120 int mmc_app_set_bus_width(struct mmc_card *card, int width)       

121 {           

122        int err;   

123        struct mmc_command cmd;  

124               

125        BUG_ON(!card);  

126        BUG_ON(!card->host);

127               

128        memset(&cmd, 0, sizeof(struct mmc_command));     

129               

130        cmd.opcode = SD_APP_SET_BUS_WIDTH;     

131        cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 

132               

133        switch (width) {    

134        case MMC_BUS_WIDTH_1:

135               cmd.arg = SD_BUS_WIDTH_1;

136               break;

137        case MMC_BUS_WIDTH_4:

138               cmd.arg = SD_BUS_WIDTH_4;

139               break;

140        default:  

141               return -EINVAL;

142        }    

143               

144        err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);  

145        if (err)   

146               return err;

147               

148        return 0; 

149 }           

130行的命令正是CMD6,同样144行的代码也是我们讲过N次的老朋友了。设置完SD卡,接下来该到SD控制器了,不然两边对不上,岂不就麻烦大了....

一旦SD卡接受了这个宽总线的命运,那么SD控制器也将不得不支持,因此497行将是对SD控制器的数据宽度进行设置,调用mmc_set_bus_width如下:

[core/core.c]

639 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)             

640 {           

641        host->ios.bus_width = width;

642        mmc_set_ios(host);

643 }           

最后一点细节,所有准备工作都做好了,对于SD卡是否还应该检测一下有没有写保护不然折腾了半天,最后被保护起来了那就丢大了。好了,500-508行通过调用host_ops中的检测只读函数,获取了卡的写保护状态并设置到card->state中以便日后使用。

#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)

       回头对照一下SD卡初始化的流程图,总线宽度设置结束以后,初始化的过程就完成了。SD卡也就真正进入了数据传输的时代。同时mmc_sd_init_card也就走到了他生命的尽头....

 

 

       mmc_sd_init_card中走了很久很久,已经记不清来时的路了。也许好像大概,我们回到了mmc_attach_sd....

714行对于SD卡而言,主机为我们做了初始化中他所有能做的事情,该放他回家休息了,一句mmc_release_host(host);带着无限的感激释放了SD卡控制器。

716行对于SD卡驱动来说有着特殊的意义.....

[core/bus.c]

222 int mmc_add_card(struct mmc_card *card)               

223 {                  

224        int ret;           

225        const char *type;          

226                      

227        dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca);   

228                      

229        switch (card->type) {           

230        case MMC_TYPE_MMC:            

231               type = "MMC";     

232               break;    

233        case MMC_TYPE_SD:        

234               type = "SD";  

235               if (mmc_card_blockaddr(card))   

236                      type = "SDHC";

237               break;    

238        case MMC_TYPE_SDIO:            

239               type = "SDIO";     

240               break;    

241        default:         

242               type = "?";     

243               break;    

244        }           

245                      

246        if (mmc_host_is_spi(card->host)) {            

247               printk(KERN_INFO "%s: new %s%s card on SPI\n",

248                      mmc_hostname(card->host),

249                      mmc_card_highspeed(card) ? "high speed " : "",

250                      type);

251        } else {         

252               printk(KERN_INFO "%s: new %s%s card at address %04x\n", 

253                      mmc_hostname(card->host),

254                      mmc_card_highspeed(card) ? "high speed " : "",

255                      type, card->rca);

256        }           

257                      

258        ret = device_add(&card->dev);           

259        if (ret)           

260               return ret;      

261                      

262 #ifdef CONFIG_DEBUG_FS                    

263        mmc_add_card_debugfs(card);           

264 #endif                  

265                      

266        mmc_card_set_present(card);       

267                      

268        return 0;        

269 }                  

如果让我选出SD卡子系统中最美丽的一个函数的话,我愿意说是mmc_add_card,但时也是最八卦的一个函数。整个函数一共50余行,却单单只说了一句有意义的话:

258        ret = device_add(&card->dev);  

还记得申请这个card时我说过的话吗?我说card->dev早晚得和他命中注定的那个她步入婚礼的殿堂,今天便是我说的那个黄道吉日。也就是因为这句话才让我们早在card中所说的res = mmc_register_driver(&mmc_driver);有了probe成功的那一天,然后才进一步加深了SD卡与块设备驱动的联系。

 

好了,再美丽的函数我们也只能欣赏到这了,循着来时的路我们走到了mmc_attach_sd的尽头,等着我们的依旧是哪个不老的传说——mmc_rescan

一旦mmc_attach_sd成功走出,我们的目光将跳转到1113....

我们知道像SD卡的这种设备,永远是个风流的主。他也许不会永远守护在你的身边,那么就需要你时时刻刻去关心一下,他是否还在你身边停留。没办法那就没隔1S钟检测一次吧。好了,这下子问题就上来了。我们知道每当调用

mmc_schedule_delayed_work(&host->detect, HZ);的时候,每过后1秒钟都会去执行mmc_rescan那么是否每隔1S正常工作的SD卡都要被初始化一次呢?要是SD卡一旦拔出,那么谁又将为这种不负责任的行为埋单呢?

       为了找到这个幕后的真凶,看来我们又不得不重入mmc_rescan的代码了。代码就不贴了,用到了再说,只要您不是太健忘,估计还是能找到他的出生地的。

1045行,第一次看这个函数的时候,我们说还用不上,但是现在情况可就不一样了,谁叫我们都是经历了初始化的人啊。在mmc_rescan调用mmc_attach_sd的过程中曾经出现了这么一个函数的身影,那便是mmc_sd_attach_bus_ops。对就是他使得我们的hostbus_ops有染,为了找出这个关联的对象我们不惜再次贴出mmc_sd_attach_bus_ops的代码。

[core/sd.c]

642 static void mmc_sd_attach_bus_ops(struct mmc_host *host)             

643 {           

644        const struct mmc_bus_ops *bus_ops;   

645               

646        if (host->caps & MMC_CAP_NONREMOVABLE)    

647               bus_ops = &mmc_sd_ops_unsafe;

648        else 

649               bus_ops = &mmc_sd_ops;

650        mmc_attach_bus(host, bus_ops);  

651 }           

bus_ops = &mmc_sd_ops;立即吸引了我们的眼球,那么干脆坚持到底,看看他是些什么东西。

[core/sd.c]

627 static const struct mmc_bus_ops mmc_sd_ops = {      

628        .remove = mmc_sd_remove,

629        .detect = mmc_sd_detect,

630        .suspend = NULL,

631        .resume = NULL,

632        .power_restore = mmc_sd_power_restore,

633 };          

好了,有了这个基础我们继续回到mmc_rescan,那么1045行也就是增加这条总线的引用计数了。

1048-1049行这时候这两行的内容就不容轻易飘过了,host->bus_ops意味这这个SD卡已经注册在案了,那么是否他还依然守候着卡槽呢?那可不一定调用host->bus_ops->detect(host);检查一下,结果就到了上面的.detect = mmc_sd_detect,进入mmc_sd_detect

[core/sd.c]

540 static void mmc_sd_detect(struct mmc_host *host)            

541 {           

542        int err;   

543               

544        BUG_ON(!host);   

545        BUG_ON(!host->card);

546               

547        mmc_claim_host(host); 

548               

549        /*   

550        * Just check if our card has been removed.

551        */  

552        err = mmc_send_status(host->card, NULL);

553               

554        mmc_release_host(host);      

555               

556        if (err) { 

557               mmc_sd_remove(host);

558               

559               mmc_claim_host(host);

560               mmc_detach_bus(host);

561               mmc_release_host(host);

562        }    

563 }           

这里检测SD卡是否存在的方法很简单,直接查询状态,如果出错,那对不起接下来发生的一切就让人难以接受了。之前初始化的一切都将付之一炬….

556行会令这张风光一时的SD卡彻底消失,代码如下:

[core/sd.c]

528 static void mmc_sd_remove(struct mmc_host *host)  

529 {    

530        BUG_ON(!host);

531        BUG_ON(!host->card);

532        

533        mmc_remove_card(host->card);

534        host->card = NULL;

535 }    

重点来看532mmc_remove_card….

 

[core/bus.c]

275 void mmc_remove_card(struct mmc_card *card)                     

276 {                         

277 #ifdef CONFIG_DEBUG_FS                           

278        mmc_remove_card_debugfs(card);                    

279 #endif                         

280                             

281        if (mmc_card_present(card)) {                   

282               if (mmc_host_is_spi(card->host)) {            

283                      printk(KERN_INFO "%s: SPI card removed\n",

284                             mmc_hostname(card->host));

285               } else {         

286                      printk(KERN_INFO "%s: card %04x removed\n",    

287                             mmc_hostname(card->host), card->rca);

288               }           

289               device_del(&card->dev);             

290        }                  

291                             

292        put_device(&card->dev);                   

293 }                         

289292行将SD在设备模型的中的所有记录将全部销毁,同时card目录下驱动对应的remove函数也将做相应的清理工作,这里就不详细诉了。回到mmc_sd_remove…

       最后,host解除了与card之间的约定,使得host->card = NULL;。那么悲剧的mmc_sd_remove函数也就悄悄谢幕了

       接下来就是对这条bus_ops的操作了,mmc_detach_bus相关内容如下:

[core/core.c]

993 void mmc_detach_bus(struct mmc_host *host)   

994 {    

995        unsigned long flags;

996        

997        BUG_ON(!host);

998        

999        WARN_ON(!host->claimed);

1000             WARN_ON(!host->bus_ops);

1001             

1002             spin_lock_irqsave(&host->lock, flags);

1003             

1004             host->bus_dead = 1;

1005             

1006             spin_unlock_irqrestore(&host->lock, flags);

1007             

1008             mmc_power_off(host);

1009             

1010             mmc_bus_put(host);

1011      }    

10041010行使得bus_opscard彻底绝交,伤心的card从新回到mmc_rescan….

 

1057行这时候如果成立说明卡依然存在,初始化的过程就直接跳过,进入下一轮的mmc_schedule_delayed_work(&host->detect, HZ);否则就必须开始新一轮的检测了,后面的内容就和我们之前分析的一致了。所以到这里您到可放心,只要卡不离槽,驱动是决计不会实施第二轮的初始化的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SD控制器之真正的硬件操作

早在SD控制器之初始化篇中,就对SD卡控制器有了一个基本的介绍。其实SD控制器层更过的意义是为core层提供一种操作SD卡硬件的一种方法,当然不同的控制器对硬件控制的方法不尽相同,但是他们最终都能像core层提交一个统一的封装有操作方法的数据结构,那便是即将闪亮登场的struct mmc_host_ops....

依旧是以s3c2440为例,对应的host文件为s3cmci.c。接下来就来揭开与之对应的struct mmc_host_ops结构的神秘面纱....

[host/s3cmci.c]

1355      static struct mmc_host_ops s3cmci_ops = {               

1356             .request   = s3cmci_request,  

1357             .set_ios    = s3cmci_set_ios,  

1358             .get_ro           = s3cmci_get_ro,

1359             .get_cd           = s3cmci_card_present,

1360             .enable_sdio_irq = s3cmci_enable_sdio_irq,       

1361      };   

在讲述每个方法具体的实现之前,先来对struct mmc_host_ops结构中的各个成员有个简单的认识。

request方法:无论是前面所说的单纯的命令传输,还是带有数据的传输过程,无一例外最终都是调用request来实现的,那么如您所想,他也将成为这个舞台万众瞩目的焦点。

set_ios方法:用于设置SD卡控制器,前面我们所见到的设置控制器时钟,数据线宽度等等一系列操作最终就是通过他来实现的。

get_ro方法:获取卡的写保护状态,前面所过,SD卡初始化完成以后,我们进行的一个最后的工作便是检测卡的写保护状态,其实就是调用get_ro方法。

get_cd方法:检测卡是否在卡槽之中,它所对应的函数前面已经在初始化中分析过了,这里不再单独列来。

enable_sdio_irq方法:就是使能SDIO卡的中断,这个是对sdio卡而言的,这里将不做重点分析。

       有了一个初步的了解之后,接下来的时间就来各个击破了,本着由浅入深的原则我们先来看看s3cmci_get_ro

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.     s3cmci_get_ro

SD卡结构上来说有个写保护的开关,这就使得判断SD卡是否写保护可以从其机械特征上入手,从而特殊设计的SD卡槽为我们提供了方便。在这里采用的方法正是利用了这种特殊设计的SD卡槽带来的优势,因此只需要读取SD卡槽的SD写保护引脚的状态就能判定卡写保护的情况。实现的代码如下:

[host/s3cmci.c]

1298      static int s3cmci_get_ro(struct mmc_host *mmc)       

1299      {           

1300             struct s3cmci_host *host = mmc_priv(mmc);      

1301             struct s3c24xx_mci_pdata *pdata = host->pdata; 

1302             int ret;    

1303                    

1304             if (pdata->no_wprotect)

1305                    return 0;

1306                    

1307             ret = s3c2410_gpio_getpin(pdata->gpio_wprotect);    

1308                    

1309             if (pdata->wprotect_invert)  

1310                    ret = !ret;

1311                    

1312             return ret;      

1313      }    

1307行正是获取SD写保护引脚的值,当然由于硬件设计上的不同可能带来状态上的取反,所以这里有个pdata->wprotect_invert标记决定是否应该反相。对于只读来说应该返回1,否则该方法的返回值为0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.     s3cmci_set_ios

根据我们前面所见到的种种设置,这里的ioset可能会相对烦锁一些,具体的代码如下:

[host/s3cmci.c]

1229      static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)                

1230      {                  

1231             struct s3cmci_host *host = mmc_priv(mmc);             

1232             u32 mci_con;        

1233                           

1234             /* Set the power state */       

1235                           

1236             mci_con = readl(host->base + S3C2410_SDICON);          

1237                           

1238             switch (ios->power_mode) {       

1239             case MMC_POWER_ON:           

1240             case MMC_POWER_UP:            

1241                    s3c2410_gpio_cfgpin(S3C2410_GPE(5), S3C2410_GPE5_SDCLK);      

1242                    s3c2410_gpio_cfgpin(S3C2410_GPE(6), S3C2410_GPE6_SDCMD);     

1243                    s3c2410_gpio_cfgpin(S3C2410_GPE(7), S3C2410_GPE7_SDDAT0);     

1244                    s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);     

1245                    s3c2410_gpio_cfgpin(S3C2410_GPE(9), S3C2410_GPE9_SDDAT2);     

1246                    s3c2410_gpio_cfgpin(S3C2410_GPE(10), S3C2410_GPE10_SDDAT3); 

1247                           

1248                    if (host->pdata->set_power) 

1249                           host->pdata->set_power(ios->power_mode, ios->vdd);

1250                           

1251                    if (!host->is2440)  

1252                           mci_con |= S3C2410_SDICON_FIFORESET;

1253                           

1254                    break;    

1255                           

1256             case MMC_POWER_OFF:          

1257             default:         

1258                    gpio_direction_output(S3C2410_GPE(5), 0);     

1259                           

1260                    if (host->is2440)   

1261                           mci_con |= S3C2440_SDICON_SDRESET;

1262                           

1263                    if (host->pdata->set_power) 

1264                           host->pdata->set_power(ios->power_mode, ios->vdd);

1265                           

1266                    break;    

1267             }           

1268                           

1269             s3cmci_set_clk(host, ios);            

1270                           

1271             /* Set CLOCK_ENABLE */        

1272             if (ios->clock)       

1273                    mci_con |= S3C2410_SDICON_CLOCKTYPE;  

1274             else        

1275                    mci_con &= ~S3C2410_SDICON_CLOCKTYPE;     

1276                           

1277             writel(mci_con, host->base + S3C2410_SDICON);           

1278                           

1279             if ((ios->power_mode == MMC_POWER_ON) ||             

1280                 (ios->power_mode == MMC_POWER_UP)) {          

1281                    dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",    

1282                           host->real_rate/1000, ios->clock/1000);

1283             } else {         

1284                    dbg(host, dbg_conf, "powered down.\n");   

1285             }           

1286                           

1287             host->bus_width = ios->bus_width;            

1288      }           

1236行对SD卡控制器的设置最直接的莫过于对寄存器S3C2410_SDICON的访问了,为了保证后面不改变其他无关位的值,这里先读取S3C2410_SDICON中的当前值保存。

1238-1267行是SD控制器工作状态的设定,对ioset来说,swith无疑是他最好的朋友,当MMC_POWER_UP时,SD控制器的相应管脚会得到正确的初始化。其他的如fifo也将被正确复位。

1269-1275行就是对sd控制器时钟的设置,最终一切ioset的成功归功于1277行将重新设置的S3C2410_SDICON状态写入寄存器,从此新的控制器状态生效。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.     s3cmci_request之命令处理

都说前世的五百次回眸,才换来今生的一次擦肩而过。我们苦苦等待的s3cmci_request,在历经千百次的磨难之后也终究在我们面前揭开了她神秘的面纱....

[host/s3cmci.c]

1190      static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)               

1191      {                                                     

1192             struct s3cmci_host *host = mmc_priv(mmc);                                                

1193                                                              

1194             host->status = "mmc request";                                               

1195             host->cmd_is_stop = 0;                                           

1196             host->mrq = mrq;                                            

1197                                                              

1198             if (s3cmci_card_present(mmc) == 0) {                                          

1199                    dbg(host, dbg_err, "%s: no medium present\n", __func__);                            

1200                    host->mrq->cmd->error = -ENOMEDIUM;                                   

1201                    mmc_request_done(mmc, mrq);                                      

1202             } else                                               

1203                    s3cmci_send_request(mmc);                                    

1204      }                                                     

1198行判断SD卡是否还在卡槽之中,如果已经拔出,那不客气mmc_request_done将帮您结束这个请求。怎么个解决法还是先看看mmc_request_done的代码:

[core/core.c]

75   void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)                  

76   {                         

77   ): %d, retrying...\n",            

87                        mmc_hostname(host), cmd->opcode, err);  

88                               

89                 cmd->retries--;             

90                 cmd->error = 0;           

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

92          } else {                

93                 led_trigger_event(host->led, LED_OFF);           

94                               

95                 pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",           

96                        mmc_hostname(host), cmd->opcode, err,    

97                        cmd->resp[0], cmd->resp[1],

98                        cmd->resp[2], cmd->resp[3]);     

99                               

100               if (mrq->data) {           

101                      pr_debug("%s:     %d bytes transferred: %d\n",     

102                             mmc_hostname(host),

103                             mrq->data->bytes_xfered, mrq->data->error);

104               }           

105                             

106               if (mrq->stop) {           

107                      pr_debug("%s:     (CMD%u): %d: %08x %08x %08x %08x\n",  

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

109                             mrq->stop->error,

110                             mrq->stop->resp[0], mrq->stop->resp[1],

111                             mrq->stop->resp[2], mrq->stop->resp[3]);

112               }           

113                             

114               if (mrq->done)             

115                      mrq->done(mrq);  

116        }                  

117 }           

80-83行如果是SPI传输出现错误,而且还有重试的机会,那么只要SPI不忽略这个命令,那么就还是给他重试的机会,也就到了85-91行继续调用host->ops->request(host, mrq);提交请求,否则既然是SPI忽略了这个命令,无论重试多少次都不会有结果,那么就干脆一不做二不休cmd->retries = 0;

85-91行就是只要设备有重生的机会就还是继续拯救...

92-115行如果传输无误或者重试次数到了,就会执行。其中多半是调试信息。

114-115行许下的承诺就好比欠下的债,前面我们讨论mmc_wait_for_req的时候有这么两句:

197        mrq->done_data = &complete;    

198        mrq->done = mmc_wait_done;    

然后我们说N年以后的某一天我们会和mmc_wait_done再聚首,这里115行便是调用的mmc_wait_done。内容如下:

[core/core.c]

179 static void mmc_wait_done(struct mmc_request *mrq)      

180 {    

181        complete(mrq->done_data);

182 }    

还记得mmc_wait_for_req中为了你苦苦等待的那个wait_for_completion(&complete),因为等待,所以她进入了睡眠。现在事情做完了,他重新回来调用complete(mrq->done_data)唤醒这个沉睡的内核精灵。说到这好奇的人难免会问,那要是一直出错又该是谁来唤醒他呢?带着疑问我们继续向前....

       回到s3cmci_request如果卡还存在的话1203s3cmci_send_request将真正开始这个请求的处理。

[host/s3cmci.c]

1125      static void s3cmci_send_request(struct mmc_host *mmc)                 

1126      {                  

1127             struct s3cmci_host *host = mmc_priv(mmc);             

1128             struct mmc_request *mrq = host->mrq;             

1129             struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;          

1130                           

1131             host->ccnt++;       

1132             prepare_dbgmsg(host, cmd, host->cmd_is_stop);       

1133                           

1134             /* Clear command, data and fifo status registers         

1135                Fifo clear only necessary on 2440, but doesn't hurt on 2410        

1136             */          

1137             writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);         

1138             writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);         

1139             writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);         

1140                           

1141             if (cmd->data) {           

1142                    int res = s3cmci_setup_data(host, cmd->data);    

1143                           

1144                    host->dcnt++;

1145                           

1146                    if (res) { 

1147                           dbg(host, dbg_err, "setup data error %d\n", res);

1148                           cmd->error = res;

1149                           cmd->data->error = res;

1150                           

1151                           mmc_request_done(mmc, mrq);

1152                           return;

1153                    }    

1154                           

1155                    if (s3cmci_host_usedma(host))     

1156                           res = s3cmci_prepare_dma(host, cmd->data);

1157                    else 

1158                           res = s3cmci_prepare_pio(host, cmd->data);

1159                           

1160                    if (res) { 

1161                           dbg(host, dbg_err, "data prepare error %d\n", res);

1162                           cmd->error = res;

1163                           cmd->data->error = res;

1164                           

1165                           mmc_request_done(mmc, mrq);

1166                           return;

1167                    }    

1168             }           

1169                           

1170             /* Send command */            

1171             s3cmci_send_command(host, cmd);            

1172                           

1173             /* Enable Interrupt */          

1174             s3cmci_enable_irq(host, true);            

1175      }

1137-1139行全部写入1,是为了清除之前传输的SDI命令状态寄存器、SDI数据状态寄存器以及SDI FIFO状态寄存器。这是在一次新的传输之前所必须有的初始化工作,否则可能出现未知的状态错误。

1141cmd->data实际上就是mmc_request->data,前面没少对他进行介绍。与之相类似的还有stop->data。这里我们姑且不说带有数据的传输过程,先来看看SD卡命令的实现。也就是1171       s3cmci_send_command(host, cmd);

[host/s3cmci.c]

939 static void s3cmci_send_command(struct s3cmci_host *host,                                 

940                                    struct mmc_command *cmd)

941 {                                

942        u32 ccon, imsk;                          

943                                    

944        imsk  = S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_CMDTIMEOUT |

945               S3C2410_SDIIMSK_RESPONSEND |S3C2410_SDIIMSK_CMDSENT |     

946               S3C2410_SDIIMSK_RESPONSECRC;                    

947                                    

948        enable_imask(host, imsk);                         

949                                    

950        if (cmd->data)                           

951               host->complete_what = COMPLETION_XFERFINISH_RSPFIN;                  

952        else if (cmd->flags & MMC_RSP_PRESENT)                        

953               host->complete_what = COMPLETION_RSPFIN;                   

954        else                      

955               host->complete_what = COMPLETION_CMDSENT;              

956                                    

957        writel(cmd->arg, host->base + S3C2410_SDICMDARG);                      

958                                    

959        ccon  = cmd->opcode & S3C2410_SDICMDCON_INDEX;                         

960 ccon|=S3C2410_SDICMDCON_SENDERHOST|S3C2410_SDICMDCON_CMDSTART;

961                                    

962        if (cmd->flags & MMC_RSP_PRESENT)                       

963               ccon |= S3C2410_SDICMDCON_WAITRSP;                   

964                                    

965        if (cmd->flags & MMC_RSP_136)                          

966               ccon |= S3C2410_SDICMDCON_LONGRSP;                  

967                                    

968        writel(ccon, host->base + S3C2410_SDICMDCON);                      

969 }                                

944-948行是使能相应的中断,其中包括CRC校验错误、命令超时、收到命令响应等等。具体的中断屏蔽寄存器的内容可以参考S3C2440用户手册。

950-955行实际上指当前的这个命令结束时候应该所处的状态,中断处理函数将实际硬件的完成情况与这个状态相比较,最终得到这个命令执行的结果。而cmd->flags正是前面提交命令之前根据不同命令的实际情况来设置的,比如具有应答数据的命令可能需要设置cmd->flags |= MMC_RSP_PRESENT。然后对应的结束状态也就应该是COMPLETION_RSPFIN收到应答。前面说过host->complete_what是个枚举类型的变量包含了整个命令过程的各个阶段,内容如下:

11   enum s3cmci_waitfor {                             

12          COMPLETION_NONE,                           

13          COMPLETION_FINALIZE,                     

14          COMPLETION_CMDSENT,                     

15          COMPLETION_RSPFIN,                         

16          COMPLETION_XFERFINISH,                        

17          COMPLETION_XFERFINISH_RSPFIN,                        

18   };

一般的命令可能无应答阶段,我们默认数据传输正确完成以后即认为命令执行完成也就是955行对应的host->complete_what = COMPLETION_CMDSENT;       

957行是对命令命令参数寄存器的设置,cmd->arg是一个32bit的整数,这里如实填写即可。

959行之后的内容就是对控制寄存器的设置了,由于控制寄存器比较重要,这里列出他寄存器位的信息如下:

对照上表应该不难分析函数中所设置的每一位的具体含义,这里就不再一一解释了。SDICmdCon[8]的置位使得SD控制器开始发送命令。回到s3cmci_send_request....

1174s3cmci_enable_irq(host, true);就是使能SDI控制器的中断。然而s3cmci_send_command中间的944行设置imr|=S3C2410_SDIIMSK_CMDSENT命中注定命令发出以后产生一个相应的中断,接下来就进入probe阶段所注册的那个SDI中断request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)

 

[host/s3cmci.c]

550 static irqreturn_t s3cmci_irq(int irq, void *dev_id)                         

551 {                         

552        struct s3cmci_host *host = dev_id;                    

553        struct mmc_command *cmd;              

554        u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;                  

555        u32 mci_cclear = 0, mci_dclear;                

556        unsigned long iflags;                   

557                             

558        mci_dsta = readl(host->base + S3C2410_SDIDSTA);               

559        mci_imsk = readl(host->base + host->sdiimsk);                

560                             

561        if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {                    

562               if (mci_imsk & S3C2410_SDIIMSK_SDIOIRQ) {           

563                      mci_dclear = S3C2410_SDIDSTA_SDIOIRQDETECT;    

564                      writel(mci_dclear, host->base + S3C2410_SDIDSTA);      

565                             

566                      mmc_signal_sdio_irq(host->mmc);     

567                      return IRQ_HANDLED;      

568               }           

569        }                  

570                             

571        spin_lock_irqsave(&host->complete_lock, iflags);                   

572                             

573        mci_csta = readl(host->base + S3C2410_SDICMDSTAT);               

574        mci_dcnt = readl(host->base + S3C2410_SDIDCNT);              

575        mci_fsta = readl(host->base + S3C2410_SDIFSTA);                

576        mci_dclear = 0;                   

577                             

578        if ((host->complete_what == COMPLETION_NONE) ||                  

579            (host->complete_what == COMPLETION_FINALIZE)) {               

580               host->status ="nothing to complete";         

581               clear_imask(host);        

582               goto irq_out;         

583        }                  

584                             

585        if (!host->mrq) {                 

586               host->status = "no active mrq";           

587               clear_imask(host);        

588               goto irq_out;         

589        }                  

590                             

591        cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd;                   

592                             

593        if (!cmd) {                  

594               host->status = "no active cmd";           

595               clear_imask(host);        

596               goto irq_out;         

597        }                  

598                             

599        if (!s3cmci_host_usedma(host)) {               

600               if ((host->pio_active == XFER_WRITE) &&           

601                   (mci_fsta & S3C2410_SDIFSTA_TFDET)) {            

602                             

603                      disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);

604                      tasklet_schedule(&host->pio_tasklet);  

605                      host->status = "pio tx"; 

606               }           

607                             

608               if ((host->pio_active == XFER_READ) &&             

609                   (mci_fsta & S3C2410_SDIFSTA_RFDET)) {           

610                             

611                      disable_imask(host,      

612                                   S3C2410_SDIIMSK_RXFIFOHALF |

613                                   S3C2410_SDIIMSK_RXFIFOLAST);

614                             

615                      tasklet_schedule(&host->pio_tasklet);  

616                      host->status = "pio rx"; 

617               }           

618        }                  

619                             

620        if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {                  

621               dbg(host, dbg_err, "CMDSTAT: error CMDTIMEOUT\n");       

622               cmd->error = -ETIMEDOUT;            

623               host->status = "error: command timeout";          

624               goto fail_transfer;         

625        }                  

626                             

627        if (mci_csta & S3C2410_SDICMDSTAT_CMDSENT) {                 

628               if (host->complete_what == COMPLETION_CMDSENT) {            

629                      host->status ="ok: command sent";     

630                      goto close_transfer;      

631               }           

632                             

633               mci_cclear |= S3C2410_SDICMDSTAT_CMDSENT;        

634        }                  

635                             

636        if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) {                    

637               if (cmd->flags & MMC_RSP_CRC) {        

638                      if (host->mrq->cmd->flags & MMC_RSP_136) {      

639                             dbg(host, dbg_irq,

640                                 "fixup: ignore CRC fail with long rsp\n");

641                      } else {  

642                             /* note, we used to fail the transfer

643                             * here, but it seems that this is just

644                             * the hardware getting it wrong.

645                             *

646                             * cmd->error = -EILSEQ;

647                             * host->status = "error: bad command crc";

648                             * goto fail_transfer;

649                             */

650                      }    

651               }           

652                             

653               mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;          

654        }                  

655                             

656        if (mci_csta & S3C2410_SDICMDSTAT_RSPFIN) {               

657               if (host->complete_what == COMPLETION_RSPFIN) {         

658                      host->status = "ok: command response received";      

659                      goto close_transfer;      

660               }           

661                             

662               if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)           

663                      host->complete_what = COMPLETION_XFERFINISH;   

664                             

665               mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN;            

666        }                  

667                             

668        /* errors handled after this point are only relevant                    

669           when a data transfer is in progress */                   

670                             

671        if (!cmd->data)                   

672               goto clear_status_bits;          

673                             

674        /* Check for FIFO failure */               

675        if (host->is2440) {              

676               if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {            

677                      dbg(host, dbg_err, "FIFO failure\n");  

678                      host->mrq->data->error = -EILSEQ;   

679                      host->status = "error: 2440 fifo failure";     

680                      goto fail_transfer;  

681               }           

682        } else {                

683               if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) {           

684                      dbg(host, dbg_err, "FIFO failure\n");  

685                      cmd->data->error = -EILSEQ;    

686                      host->status = "error:  fifo failure";   

687                      goto fail_transfer;  

688               }           

689        }                  

690                             

691        if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {              

692               dbg(host, dbg_err, "bad data crc (outgoing)\n");        

693               cmd->data->error = -EILSEQ;           

694               host->status = "error: bad data crc (outgoing)";         

695               goto fail_transfer;         

696        }                  

697                             

698        if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) {                   

699               dbg(host, dbg_err, "bad data crc (incoming)\n");       

700               cmd->data->error = -EILSEQ;           

701               host->status = "error: bad data crc (incoming)";         

702               goto fail_transfer;         

703        }                  

704                             

705        if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {                 

706               dbg(host, dbg_err, "data timeout\n");          

707               cmd->data->error = -ETIMEDOUT;          

708               host->status = "error: data timeout";           

709               goto fail_transfer;         

710        }                  

711                             

712        if (mci_dsta & S3C2410_SDIDSTA_XFERFINISH) {                    

713               if (host->complete_what == COMPLETION_XFERFINISH) {        

714                      host->status = "ok: data transfer completed";      

715                      goto close_transfer;      

716               }           

717                             

718               if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)           

719                      host->complete_what = COMPLETION_RSPFIN;     

720                            

721               mci_dclear |= S3C2410_SDIDSTA_XFERFINISH;          

722        }                  

723                             

724 clear_status_bits:                        

725        writel(mci_cclear, host->base + S3C2410_SDICMDSTAT);                    

726        writel(mci_dclear, host->base + S3C2410_SDIDSTA);                    

727                             

728        goto irq_out;                

729                             

730 fail_transfer:                       

731        host->pio_active = XFER_NONE;                    

732                             

733 close_transfer:                     

734        host->complete_what = COMPLETION_FINALIZE;               

735                             

736        clear_imask(host);               

737        tasklet_schedule(&host->pio_tasklet);                

738                             

739        goto irq_out;                

740                             

741 irq_out:                       

742        dbg(host, dbg_irq,               

743            "csta:0x%08x dsta:0x%08x fsta:0x%08x dcnt:0x%08x status:%s.\n",              

744            mci_csta, mci_dsta, mci_fsta, mci_dcnt, host->status);                    

745                             

746        spin_unlock_irqrestore(&host->complete_lock, iflags);                   

747        return IRQ_HANDLED;                    

748                             

749 }

558-570行是判断SDIO所触发的中断,与我们说说的无关。飘过....

573-576行分别读取命令状态、尚未完成传输的数据大小以及FIFO的状态的值。

578-583行就是之前所分析的host->complete_what,如果设备无欲无求host->complete_what == COMPLETION_NONE,即使连最基本的命令发送也不要求完成的话,那就没什么意义了,直接清除IMASK,返回。

[host/s3cmci.c]

226 static inline void clear_imask(struct s3cmci_host *host)                   

227 {                  

228        u32 mask = readl(host->base + host->sdiimsk);         

229                      

230        /* preserve the SDIO IRQ mask state */             

231        mask &= S3C2410_SDIIMSK_SDIOIRQ;         

232        writel(mask, host->base + host->sdiimsk);         

233 }                  

上面的代码只保留了SDIO IRQ状态,其他的中断都是被屏蔽了的。由此足见其对SDIO设备的偏心程度

585-589行尽然玩丢了host->mrq,无论是命令还是数据请求,我们都是递交了struct mmc_request结构的,所以驱动很气愤,直接返回。

591行前面我们看到struct mmc_request中包含了两种类型的struct mmc_cmd一个是所谓的cmd另外一个就是stop了,当然选择哪一个也不是他自己说来算了,当然有主机的host->cmd_is_stop来决定了。

599-618行是PIO模式下数据传输的,我们姑且先放着,等说完CMD回头再看。

620-625行命令超时以后就会跳转到fail_transfer,至于fail_transfer又干了些啥好事我们走到那里了再说,继续前进...

627-631行命令发送成功以后所产生的中断,如果host->complete_what也正好只要求传输成功即COMPLETION_CMDSENT,那正好完成工作,goto close_transfer

636-654行是CRC错误,忽略。

656-660命令相应接收成功,那么依旧goto close_transfer

662-665行至今尚未发现一个所谓的COMPLETION_XFERFINISH_RSPFIN最多也就数据传输成功那么修改一下这个脑残host->complete_what = COMPLETION_XFERFINISH;

671-672行如果没有数据传输,那么接下来就可以进行状态清理工作了。

675-722行是检查FIFO信息的,回头说到PIO传输的时候在来分析它。

725-726行意图很明确,显然是毁尸灭迹,清除状态。

       最后可以看到无论是先前的fail_transfer:还是后来的close_transfer,最总都会去调用737行的tasklet_schedule(&host->pio_tasklet),是什么赋予这个函数如此强大的魅力,且听下回分解...

      

 

 

 

 

 

 

4.     s3cmci_request之数据传输

是时候该看点实际的数据传输了,前面说过s3cmci_send_request中的if (cmd->data)是区分命令是否有数据阶段的关键标志。如果有数据传输的,那么就到了1142s3cmci_setup_data

[host/s3cmci.c]

971 static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)               

972 {                  

973        u32 dcon, imsk, stoptries = 3;             

974                      

975        /* write DCON register */           

976                      

977        if (!data) {            

978               writel(0, host->base + S3C2410_SDIDCON);    

979               return 0; 

980        }           

981                      

982        if ((data->blksz & 3) != 0) {       

983               /* We cannot deal with unaligned blocks with more than   

984               * one block being transfered. */ 

985                      

986               if (data->blocks > 1) {  

987 pr_warning("%s:can'tdonon-wordsizedblock transfers (blksz %d)\n", __func__, data->blksz);

988                      return -EINVAL;

989               }    

990        }           

991                      

992        while (readl(host->base + S3C2410_SDIDSTA) &            

993               (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {

994                     

995               dbg(host, dbg_err, 

996                   "mci_setup_data() transfer stillin progress.\n");  

997                      

998               writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON); 

999               s3cmci_reset(host);

1000                           

1001                    if ((stoptries--) == 0) { 

1002                           dbg_dumpregs(host, "DRF");

1003                           return -EINVAL;

1004                    }    

1005             }           

1006                           

1007             dcon  = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;         

1008                           

1009             if (s3cmci_host_usedma(host))            

1010                    dcon |= S3C2410_SDIDCON_DMAEN;     

1011                           

1012             if (host->bus_width == MMC_BUS_WIDTH_4)       

1013                    dcon |= S3C2410_SDIDCON_WIDEBUS;  

1014                           

1015             if (!(data->flags & MMC_DATA_STREAM))            

1016                    dcon |= S3C2410_SDIDCON_BLOCKMODE;   

1017                           

1018             if (data->flags & MMC_DATA_WRITE) {         

1019                    dcon |= S3C2410_SDIDCON_TXAFTERRESP; 

1020                    dcon |= S3C2410_SDIDCON_XFER_TXSTART;      

1021             }           

1022                           

1023             if (data->flags & MMC_DATA_READ) {          

1024                    dcon |= S3C2410_SDIDCON_RXAFTERCMD; 

1025                    dcon |= S3C2410_SDIDCON_XFER_RXSTART;      

1026             }           

1027                           

1028             if (host->is2440) {       

1029                    dcon |= S3C2440_SDIDCON_DS_WORD; 

1030                    dcon |= S3C2440_SDIDCON_DATSTART; 

1031             }           

1032                           

1033             writel(dcon, host->base + S3C2410_SDIDCON);             

1034                           

1035             /* write BSIZE register */           

1036                           

1037             writel(data->blksz, host->base + S3C2410_SDIBSIZE);           

1038                           

1039             /* add to IMASK register */        

1040             imsk = S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |          

1041                    S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;          

1042                           

1043             enable_imask(host, imsk);           

1044                           

1045             /* write TIMER register */          

1046                           

1047             if (host->is2440) {       

1048                    writel(0x007FFFFF, host->base + S3C2410_SDITIMER); 

1049             } else {         

1050                    writel(0x0000FFFF, host->base + S3C2410_SDITIMER); 

1051                           

1052                    /* FIX: set slow clock to prevent timeouts on read */ 

1053                    if (data->flags & MMC_DATA_READ)      

1054                           writel(0xFF, host->base + S3C2410_SDIPRE);

1055             }           

1056                           

1057             return 0;        

1058      }                  

977-980行如果data不存在,接下来就无事可做了。

982-991行块大小是4字节对齐的,如果data->blksz不满足,那么返回错误。

992-1005行读取数据状态寄存器,如果正在发送或接收数据,则s3cmci_reset(host);复位SD控制器。

[host/s3cmci.c]

1290      static void s3cmci_reset(struct s3cmci_host *host)             

1291      {           

1292             u32 con = readl(host->base + S3C2410_SDICON);    

1293                    

1294             con |= S3C2440_SDICON_SDRESET;

1295             writel(con, host->base + S3C2410_SDICON);    

1296      }           

1007-1033行根据数据特征、主机总线宽度等信息设置数据控制寄存器

1037行设置SD控制器块大小寄存器。这是上层设置下来的值,一般为512

1040-1043行设置中断屏蔽寄存器,使能数据传输完成中断、超时等。

1047-1054行是关于读写超时的处理。接着返回到s3cmci_send_request....

如果不出什么问题,应该就到了1155行。

s3cmci_prepare_dma(host, cmd->data);DMA传输的处理,

s3cmci_prepare_pio(host, cmd->data);PIO方式的处理,下面我们先来关注PIO方式的数据传输。

[host/s3cmci.c]

1062      static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)             

1063      {                  

1064             int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;            

1065                           

1066             BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);          

1067                           

1068             host->pio_sgptr = 0;            

1069             host->pio_bytes = 0;            

1070             host->pio_count = 0;           

1071             host->pio_active = rw ? XFER_WRITE : XFER_READ;         

1072                           

1073             if (rw) {        

1074                    do_pio_write(host);      

1075                    enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); 

1076             } else {         

1077                    enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF   

1078                                | S3C2410_SDIIMSK_RXFIFOLAST);

1079             }           

1080                           

1081             return 0;        

1082      }    

?  PIO写数据

这个函数分两部分来看,首先对于写来说会调用1074do_pio_write(host);来做写入的前期工作,如果是读SD卡就只需要使能接收FIFO相关的中断即可。那么我们先对写的情况做简单的分析:

[host/s3cmci.c]

443 static void do_pio_write(struct s3cmci_host *host)                                               

444 {                                              

445        void __iomem *to_ptr;                                    

446        int res;                                      

447        u32 fifo;                                    

448        u32 *ptr;                                   

449                                                  

450        to_ptr = host->base + host->sdidata;                                       

451                                                  

452        while ((fifo = fifo_free(host)) > 3) {                                      

453               if (!host->pio_bytes) {                              

454                      res = get_data_buffer(host, &host->pio_bytes,                         

455                                                  &host->pio_ptr);

456                      if (res) {                      

457                             dbg(host, dbg_pio,              

458                                 "pio_write(): complete (no more data).\n");              

459                             host->pio_active = XFER_NONE;                    

460                                                  

461                             return;                  

462                      }                         

463                                                  

464                      dbg(host, dbg_pio,                     

465                          "pio_write(): new source: [%i]@[%p]\n",                        

466                          host->pio_bytes, host->pio_ptr);                       

467                                                  

468               }                                

469                                                  

470               /* If we have reached the end of the block, we have to                                  

471               * write exactly the remaining number of bytes.  If we                                

472               * in the middle of the block, we have to write full                               

473               * words, so round down to an even multiple of 4. */                            

474               if (fifo >= host->pio_bytes)                              

475                      fifo = host->pio_bytes;                      

476               else                             

477                      fifo -= fifo & 3;                         

478                                                  

479               host->pio_bytes -= fifo;                            

480               host->pio_count += fifo;                                  

481                                                  

482               fifo = (fifo + 3) >> 2;                               

483               ptr = host->pio_ptr;                                  

484               while (fifo--)                             

485                      writel(*ptr++, to_ptr);                       

486               host->pio_ptr = ptr;                                  

487        }                                       

488                                                  

489        enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);                                    

490 }

452行是对发送FIFO剩余空间的判断,方法比较简单直接读取FIFO状态寄存器即可获得。

[host/s3cmci.c]

294 static inline u32 fifo_free(struct s3cmci_host *host)                                             

295 {                                              

296        u32 fifostat = readl(host->base + S3C2410_SDIFSTA);                                        

297                                                  

298        fifostat &= S3C2410_SDIFSTA_COUNTMASK;                                         

299        return 63 - fifostat;                                   

300 }

当发送FIFO的容量大于三个字节时程序将向FIFO中写入数据,此时while循环得以执行。

454取出要发送的数据地址以及数据长度get_data_buffer的内容如下:

[host/s3cmci.c]

257 static inline int get_data_buffer(struct s3cmci_host *host,                       

258                               u32 *bytes, u32 **pointer)

259 {                         

260        struct scatterlist *sg;                   

261                             

262        if (host->pio_active == XFER_NONE)                    

263               return -EINVAL;          

264                             

265        if ((!host->mrq) || (!host->mrq->data))              

266               return -EINVAL;          

267                             

268        if (host->pio_sgptr >= host->mrq->data->sg_len) {                 

269               dbg(host, dbg_debug, "no more buffers (%i/%i)\n",         

270                     host->pio_sgptr, host->mrq->data->sg_len);          

271               return -EBUSY;           

272        }                  

273        sg = &host->mrq->data->sg[host->pio_sgptr];                  

274                             

275        *bytes = sg->length;                   

276        *pointer = sg_virt(sg);                

277                             

278        host->pio_sgptr++;              

279                             

280        dbg(host, dbg_sg, "new buffer (%i/%i)\n",               

281            host->pio_sgptr, host->mrq->data->sg_len);              

282                             

283        return 0;               

284 }    

273行很明显是对每个散列表单独操作的,275行对应当前散列项的长度,276sg_virt用于获取其所对应的内核虚拟地址,最后host->pio_sgptr++移动指针到下一项。

       回到do_pio_write474-477行就是取出剩余的空间,如果剩余空间大于要发送的长度就直接全部发送,否则留三个字节空闲。

4824个字节对齐的,也就是说后面实际上传输的字节数应该是(((fifo + 3) >> 2)<<2),那么这个值与host->pio_bytes -= fifo;中的fifo相比是很有可能不相等的。换句话说实际传输的字节说与记录的大小不等,看上去是个bug,其实前面我们说过,所有走到这一步的数据长度都已经是4字节对齐了,所以这里这样处理就不会有问题了。

       s3cmci_prepare_pio返回以后就到了1171s3cmci_send_command(host, cmd);这里发送的将是写扇区命令,从而开启了真正的PIO数据传输

       对于PIO方式来说,一旦命令写入,数据传输立即就开始了。如果发送FIFO中的数据低于FIFO空闲中断的阈值,将触发控制器产生中断,从而就满足了s3cmci_irq中断处理函数的599-606行的条件。

[s3cmci_irq]

599 if (!s3cmci_host_usedma(host)) {                                           

600        if ((host->pio_active == XFER_WRITE) &&                                       

601            (mci_fsta & S3C2410_SDIFSTA_TFDET)) {                                        

602                                                  

603               disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);                            

604               tasklet_schedule(&host->pio_tasklet);                              

605               host->status = "pio tx";                             

606        }                                       

于是tasklet_schedule(&host->pio_tasklet)被调用,同时724-728行将帮助清除中断标志。

724 clear_status_bits:                        

725        writel(mci_cclear, host->base + S3C2410_SDICMDSTAT);                    

726        writel(mci_dclear, host->base + S3C2410_SDIDSTA);                    

727                             

728        goto irq_out;

       又见了tasklet_schedule(&host->pio_tasklet),他不是什么天外飞仙,一切因果只因s3cmci.c中的1588  tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);          

从中断函数返回以后,目光投向pio_tasklet,对应的内容如下:

[host/s3cmci.c]

492 static void pio_tasklet(unsigned long data)                       

493 {                         

494        struct s3cmci_host *host = (struct s3cmci_host *) data;                    

495                             

496        s3cmci_disable_irq(host, true);                  

497        udelay(50);                  

498                             

499        if (host->pio_active == XFER_WRITE)                   

500               do_pio_write(host);             

501                             

502        if (host->pio_active == XFER_READ)              

503               do_pio_read(host);       

504                             

505        if (host->complete_what == COMPLETION_FINALIZE) {                    

506               clear_imask(host);        

507               if (host->pio_active != XFER_NONE) {           

508                      dbg(host, dbg_err, "unfinished %s "    

509                          "- pio_count:[%u] pio_bytes:[%u]\n", 

510                          (host->pio_active == XFER_READ) ? "read" : "write",    

511                          host->pio_count, host->pio_bytes);     

512                             

513                      if (host->mrq->data)     

514                             host->mrq->data->error = -EINVAL;

515               }           

516                             

517               s3cmci_enable_irq(host, false);           

518               finalize_request(host);          

519        } else                   

520               s3cmci_enable_irq(host, true);            

521 }                         

函数格式比较工整,如果host->pio_active继续保持XFER_WRITE的话,就会再次调用do_pio_write(host)来继续向发送FIFO中填入数据。

505行是传输完成以后设置的,传输完成以后会调用finalize_request(host);束这次请求。

[host/s3cmci.c]

822 static void finalize_request(struct s3cmci_host *host)                      

823 {                         

824        struct mmc_request *mrq = host->mrq;                    

825        struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;          

826        int debug_as_failure = 0;                    

827                             

828        if (host->complete_what != COMPLETION_FINALIZE)                

829               return;           

830                             

831        if (!mrq)              

832               return;           

833                            

834        if (cmd->data && (cmd->error == 0) &&                

835            (cmd->data->error == 0)) {                

836               if (s3cmci_host_usedma(host) && (!host->dma_complete)) {          

837                      dbg(host, dbg_dma, "DMA Missing (%d)!\n",    

838                          host->dma_complete);  

839                      return;    

840               }           

841        }                  

842                             

843        /* Read response from controller. */                  

844        cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);                

845        cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);                

846        cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);                

847        cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);                

848                             

849        writel(host->prescaler, host->base + S3C2410_SDIPRE);                

850                             

851        if (cmd->error)                   

852               debug_as_failure = 1;          

853                             

854        if (cmd->data && cmd->data->error)         

855               debug_as_failure = 1;   

856                      

857        dbg_dumpcmd(host, cmd, debug_as_failure);            

858                      

859        /* Cleanup controller */       

860        writel(0, host->base + S3C2410_SDICMDARG);             

861        writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);        

862        writel(0, host->base + S3C2410_SDICMDCON);             

863        clear_imask(host);        

864                      

865        if (cmd->data && cmd->error)           

866               cmd->data->error = cmd->error;  

867                      

868        if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) {           

869               host->cmd_is_stop = 1; 

870               s3cmci_send_request(host->mmc);      

871               return;    

872        }           

873                      

874        /* If we have no data transfer we are finished here */        

875        if (!mrq->data)            

876               goto request_done;

877                      

878        /* Calulate the amout of bytes transfer if there was no error */         

879        if (mrq->data->error == 0) {       

880               mrq->data->bytes_xfered =  

881                      (mrq->data->blocks * mrq->data->blksz);

882        } else {         

883               mrq->data->bytes_xfered = 0;     

884        }           

885                      

886        /* If we had an error while transfering data we flush the           

887        * DMA channel and the fifo to clear out any garbage. */         

888        if (mrq->data->error != 0) {        

889               if (s3cmci_host_usedma(host))     

890                      s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);

891                      

892               if (host->is2440) {

893                      /* Clear failure register and reset fifo. */

894                      writel(S3C2440_SDIFSTA_FIFORESET |

895                             S3C2440_SDIFSTA_FIFOFAIL,

896                             host->base + S3C2410_SDIFSTA);

897               } else {  

898                      u32 mci_con;

899                      

900                      /* reset fifo */

901                      mci_con = readl(host->base + S3C2410_SDICON);

902                      mci_con |= S3C2410_SDICON_FIFORESET;

903                      

904                      writel(mci_con, host->base + S3C2410_SDICON);

905               }    

906        }           

907                      

908 request_done:               

909        host->complete_what = COMPLETION_NONE;       

910        host->mrq = NULL;            

911                      

912        s3cmci_check_sdio_irq(host);             

913        mmc_request_done(host->mmc, mrq);        

914 }    

843-847行是发送读写命令以后SD卡回复的信息,这个信息在block层中将作为请求完成情况的一个依据。

860-863行是完成任务后对控制器做清理工作。

868-872行这个是对于多扇区的读写还应该有一个结束命令,以结束此次操作。在mmc_blk_issue_rq中就已经对这个stop命令设置好了,如下:

[card/block.c]

259               brq.stop.opcode = MMC_STOP_TRANSMISSION;                 

260               brq.stop.arg = 0;                 

261               brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;  

。。。。。

284                      if (!mmc_host_is_spi(card->host)        

285                                    || rq_data_dir(req) == READ)

286                             brq.mrq.stop = &brq.stop;    

287                      readcmd = MMC_READ_MULTIPLE_BLOCK;        

288                      writecmd = MMC_WRITE_MULTIPLE_BLOCK;            

289               } else {                

290                      brq.mrq.stop = NULL;         

291                      readcmd = MMC_READ_SINGLE_BLOCK;            

292                      writecmd = MMC_WRITE_BLOCK;          

293               }                  

259MMC_STOP_TRANSMISSION就正好是CMD12命令,最终结束命令也就是由s3cmci_send_request发出了。

879-884行如果传输没有发生错误,传输的字节数将被正确记载,否则传输数据长度将为0,暗示此次数据传输失败。

888-904行传输有错误,便要重新刷新DMA控制器或者是复位FIFO

909-901host的工作完成以后host内部相应的对象应该复位,以便重新接受请求。

913mmc_request_done前面分析过,如果出错可能会引发重试,否则调用complete(mrq->done_data);通知等待该请求的进程

       好了,以上说分析的就是PIO写数据部分的情况了,接下来看下PIO读是如何工作的。。。

 

 

?  PIO读数据

依然回到s3cmci_send_request中,还是看s3cmci_prepare_pio的内容。

前面的分析我们知道对于PIO的写数据来说必须先填充其FIFO,否则可能写命令发出以后,主机无法发送数据导致命令失败。然而读数据却只能有中断引发,因此当主机发送读命令之前s3cmci_prepare_pio必须设置好相应的中断使能,enable_imask(host,

S3C2410_SDIIMSK_RXFIFOHALF|S3C2410_SDIIMSK_RXFIFOLAST);当接收FIFO有较多数据时将以中断形式通知主机。同样s3cmci_send_request中的s3cmci_send_command(host, cmd);发送读命令开启了读SD卡数据的新时代。

一旦FIFO中的数据达到接收阈值将触发中断,接下来就进入了s3cmci_irq608-609行。

608               if ((host->pio_active == XFER_READ) &&             

609                   (mci_fsta & S3C2410_SDIFSTA_RFDET)) {           

610                             

611                      disable_imask(host,      

612                                   S3C2410_SDIIMSK_RXFIFOHALF |

613                                   S3C2410_SDIIMSK_RXFIFOLAST);

614                             

615                      tasklet_schedule(&host->pio_tasklet);  

616                      host->status = "pio rx"; 

617               }           

618        }                  

与写SD相同,读SD卡也将调用tasklet_schedule,然后进入pio_tasklet502-503行。do_pio_read(host);将读取fifo中的数据。

[host/s3cmci.c]

360 static void do_pio_read(struct s3cmci_host *host)                                  

361 {                                

362        int res;                        

363        u32 fifo;                      

364        u32 *ptr;                     

365        u32 fifo_words;                         

366        void __iomem *from_ptr;                         

367                                    

368        /* write real prescaler to host, it might be set slow to fix */                     

369        writel(host->prescaler, host->base + S3C2410_SDIPRE);                       

370                                    

371        from_ptr = host->base + host->sdidata;                     

372                                    

373        while ((fifo = fifo_count(host))) {                           

374               if (!host->pio_bytes) {                

375                      res = get_data_buffer(host, &host->pio_bytes,           

376                                          &host->pio_ptr);

377                      if (res) {        

378                             host->pio_active = XFER_NONE;      

379                             host->complete_what = COMPLETION_FINALIZE; 

380                                    

381                             dbg(host, dbg_pio, "pio_read(): " 

382                                 "complete (no more data).\n");    

383                             return;    

384                      }           

385                                    

386                      dbg(host, dbg_pio,       

387                          "pio_read(): new target: [%i]@[%p]\n",            

388                          host->pio_bytes, host->pio_ptr);         

389               }                  

390                                    

391               dbg(host, dbg_pio,              

392                   "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",                 

393                   fifo, host->pio_bytes,                 

394                   readl(host->base + S3C2410_SDIDCNT));                

395                                    

396               /* If we have reached the end of the block, we can                   

397               * read a word and get 1 to 3 bytes.  If we in the                   

398               * middle of the block, we have to read full words,                 

399               * otherwise we will write garbage, so round down to              

400               * an even multiple of 4. */                

401               if (fifo >= host->pio_bytes)                

402                      fifo = host->pio_bytes;        

403               else               

404                      fifo -= fifo & 3;           

405                                    

406               host->pio_bytes -= fifo;              

407               host->pio_count += fifo;                    

408                                    

409               fifo_words = fifo >> 2;               

410               ptr = host->pio_ptr;                    

411               while (fifo_words--)                   

412                      *ptr++ = readl(from_ptr);           

413               host->pio_ptr = ptr;                    

414                                    

415               if (fifo & 3) {              

416                      u32 n = fifo & 3;         

417                      u32 data = readl(from_ptr);         

418                      u8 *p = (u8 *)host->pio_ptr;       

419                                    

420                      while (n--) {         

421                             *p++ = data;  

422                             data >>= 8;    

423                      }           

424               }                  

425        }                         

426                                    

427        if (!host->pio_bytes) {                       

428               res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr);                    

429               if (res) {               

430                      dbg(host, dbg_pio,       

431                          "pio_read(): complete (no more buffers).\n");           

432                      host->pio_active = XFER_NONE;             

433                      host->complete_what = COMPLETION_FINALIZE;        

434                                    

435                      return;           

436               }                  

437        }                         

438                                    

439        enable_imask(host,                     

440        S3C2410_SDIIMSK_RXFIFOHALF| S3C2410_SDIIMSK_RXFIFOLAST);

441 }                                

373行读取FIFO中数据的长度。

[host/s3cmci.c]

286 static inline u32 fifo_count(struct s3cmci_host *host)                             

287 {                                

288        u32 fifostat = readl(host->base + S3C2410_SDIFSTA);                          

289                                    

290        fifostat &= S3C2410_SDIFSTA_COUNTMASK;                           

291        return fifostat;                     

292 }

375-376行和写操作中的作用是相同的,获取scatterlist表项对应的数据长度及内核虚拟地址。

401-425行整个过程与PIO写的过程是完全相反的,代码比较简单就不再分析了。其他的内容就和写过程是一样的了。

?  DMA传输

最后还有关于DMA方式下的代码,其中只有s3cmci_prepare_dma和中断处理不一致。对于DMA来说内核为其维护了一个回调函数。这里我们只是简单分析一下,就不深入到S3C2440 DMA的管理机制里面去了。首先还是来看s3cmci_prepare_dma

[host/s3cmci.c]

1018      static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)     

1019      {                                

1020             int dma_len, i;                           

1021             int rw = data->flags & MMC_DATA_WRITE;                         

1022                                         

1023             BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);                        

1024                                         

1025             s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW);                      

1026             s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);                         

1027                                         

1028             dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,                      

1029                                rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);             

1030                                         

1031             if (dma_len == 0)                       

1032                    return -ENOMEM;              

1033                                         

1034             host->dma_complete = 0;                          

1035             host->dmatogo = dma_len;                        

1036                                         

1037             for (i = 0; i < dma_len; i++) {                          

1038                    int res;                 

1039                                         

1040                    dbg(host, dbg_dma, "enqueue %i: %08x@%u\n", i,                

1041                        sg_dma_address(&data->sg[i]),                  

1042                        sg_dma_len(&data->sg[i]));               

1043                                         

1044                    res = s3c2410_dma_enqueue(host->dma, host,                  

1045                                           sg_dma_address(&data->sg[i]),

1046                                           sg_dma_len(&data->sg[i]));

1047                                         

1048                    if (res) {               

1049                           s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);           

1050                           return -EBUSY;           

1051                    }                  

1052             }                         

1053                                         

1054             s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START);                          

1055                                        

1056             return 0;                      

1057      }    

1025行对申请到的DMA通道进行设置。代码如下:

[host/s3cmci.c]

916 static void s3cmci_dma_setup(struct s3cmci_host *host,                                

917                           enum s3c2410_dmasrc source)          

918 {                                

919        static enum s3c2410_dmasrc last_source = -1;                         

920        static int setup_ok;                      

921                                    

922        if (last_source == source)                          

923               return;                  

924                                    

925        last_source = source;                          

926                                    

927        s3c2410_dma_devconfig(host->dma, source,                           

928                            host->mem->start + host->sdidata);        

929                                    

930        if (!setup_ok) {                          

931               s3c2410_dma_config(host->dma, 4);                 

932               s3c2410_dma_set_buffdone_fn(host->dma,               

933                                        s3cmci_dma_done_callback);

934               s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART);             

935               setup_ok = 1;               

936        }                         

937 }

927行配置了DMA的源和目的的硬件地址及类型。     

931行配置了DMA传输的单元大小为4字节。

932-933行设置DMA通道对应的回调函数s3cmci_dma_done_callback,这个我们后面再说。回到s3cmci_prepare_dma...

1092行刷新DMA通道,清除状态信息。

1094行映射一个发散/汇聚列表的DMA的映射,对于2440来说DMA不支持散列地址,所以1103-1118行对每段映射进行了处理,将其加入到DMA队列当中。

1120行开启了DMA传输通道,一旦SD控制发送命令以后,DMA通道不断地将数据发送到(或接收从)SD控制器的数据寄存器中,最终完成数据的传输。

一旦DMA数据传输完成,回调函数s3cmci_dma_done_callback将开始工作。

[host/s3cmci.c]

766 static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,                  

767                                  void *buf_id, int size,

768                                  enum s3c2410_dma_buffresult result)

769 {                         

770        struct s3cmci_host *host = buf_id;                    

771        unsigned long iflags;                   

772        u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt;                    

773                             

774        mci_csta = readl(host->base + S3C2410_SDICMDSTAT);               

775        mci_dsta = readl(host->base + S3C2410_SDIDSTA);               

776        mci_fsta = readl(host->base + S3C2410_SDIFSTA);                

777        mci_dcnt = readl(host->base + S3C2410_SDIDCNT);              

778                             

779        BUG_ON(!host->mrq);               

780        BUG_ON(!host->mrq->data);                    

781        BUG_ON(!host->dmatogo);               

782                                    

783        spin_lock_irqsave(&host->complete_lock, iflags);                          

784                                    

785        if (result != S3C2410_RES_OK) {                           

786               dbg(host, dbg_fail, "DMA FAILED: csta=0x%08x dsta=0x%08x "                 

787                      fsta=0x%08x dcnt:0x%08x result:0x%08x toGo:%u\n,             

788                      mci_csta, mci_dsta, mci_fsta,             

789                      mci_dcnt, result, host->dmatogo);       

790                                    

791               goto fail_request;                

792        }                         

793                                    

794        host->dmatogo--;                       

795        if (host->dmatogo) {                         

796               dbg(host, dbg_dma, "DMA DONE  Size:%i DSTA:[%08x] "                

797                      DCNT:[%08x] toGo:%u\n,          

798                      size, mci_dsta, mci_dcnt, host->dmatogo);  

799                             

800               goto out;       

801        }                  

802                             

803        dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n",              

804               size, mci_dsta, mci_dcnt);           

805                             

806        host->dma_complete = 1;                   

807        host->complete_what = COMPLETION_FINALIZE;               

808                             

809 out:                      

810        tasklet_schedule(&host->pio_tasklet);                

811        spin_unlock_irqrestore(&host->complete_lock, iflags);                   

812        return;                  

813                             

814 fail_request:                        

815        host->mrq->data->error = -EINVAL;                

816        host->complete_what = COMPLETION_FINALIZE;               

817        clear_imask(host);               

818                             

819        goto out;              

820 }                         

实际长上面的函数中我们不难发现DMA完成以后,仍然是调用tasklet_schedule(&host->pio_tasklet);来完成结束工作。

阅读(4790) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~