Chinaunix首页 | 论坛 | 博客
  • 博客访问: 24282
  • 博文数量: 7
  • 博客积分: 495
  • 博客等级: 下士
  • 技术积分: 125
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-15 15:50
文章分类
文章存档

2008年(7)

我的朋友
最近访客

分类: LINUX

2008-03-19 16:38:50

something mass...............


1.
#define to_platform_device(x) container_of((x), struct platform_device, dev)

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

2.sdio driver module

platform device:

struct platform_device {
        const char      * name;
        u32             id;
        struct device   dev;
        u32             num_resources;
        struct resource * resource;
};


static struct platform_device mmc1_device = {
        .name           =       "mmc_controller",
        .id             =       0,
        .resource       = mmc1_resources,
        .num_resources  = ARRAY_SIZE(mmc1_resources),
        .dev            = {
                .dma_mask          =    &pxa_mmc_controller_dmamask,
                .release           =    pxa_mmc_controller_release,
                .coherent_dma_mask =    0xffffffff,
        },
};


platform driver:

static struct device_driver pxa_mss_host_driver = {
        .name           =       "mmc_controller",
        .bus            =       &platform_bus_type,
        .probe          =       pxa_mss_host_probe,
        .remove         =       pxa_mss_host_remove,
        .shutdown       =       pxa_mss_host_shutdown,
        .suspend        =       pxa_mss_host_suspend,
        .resume         =       pxa_mss_host_resume,
};
               



3.define a new type bus: mmc_bus.  pluged in the platform bus?


static struct bus_type mmc_bus_type = {
        .name           =       "mmc_bus",
        .match          =       mmc_bus_match,
        .hotplug        =       mmc_bus_hotplug,
        .suspend        =       mmc_bus_suspend,s
        .resume         =       mmc_bus_resume,
};

protocol struct:

struct mss_prot_driver {
        char                    *name;                  /* protocol name */
        struct list_head        node;

        int     (*prot_entry)(struct mss_card *, unsigned int, void *, void *);
        int     (*attach_card) (struct mss_card *);
        void    (*detach_card) (struct mss_card *);
        int     (*get_errno) (struct mss_card *);
};



A:
for the condition the card insert before the driver was insmod, the flow as below:

1.in the platform driver probe function,when we init the slots of the host,
  we have request the irq for the insert action:
   
   
           request_irq(irq, pxa_slot_gpio_irq, 0,
                "MMC card detection", (void *)slot);
the irq was associated with a slot, so we send (void *)slot to the irq func.

2.when the card was inserted ,in the irq func ,we queued the delayed work:
          
        queue_delayed_work(pxa_host->work_queue, &pxa_slot->card_change, 20);

and int the bottom half:           mss_scan_slot(slot);

note when we detected the state of the slot, we should down the seamphone of the slot,to lock.

int the mss_scan_slot, we deterimned the real state of the slot,if the slot is empty, we call the func
               
                  mss_insert_card(slot);


3.before this step, the card which the slot point to is NULL. in the insert card func, we should give it
a new real card which have the "dev" in it struct.and we go to the more precise func:
               
                 _mss_insert_card(card);

in the _mss_insert_card(card),first, we find which protocol the card follow, SD memory or SDIO.
we loop all the protocol_struct stuff and find one if there is.the protocol driver was inserted in
the protocol driver list when the protocol driver module_init.
   
    mss_attach_protocol(card)
    {
    list_for_entry(protocol_driver_list)
       
       
       
        {
        sdio_prot_attach(card)-->  //create a sdio_card structure   
               
        sdio_prot_entry(card, MSS_RECOGNIZE_CARD, NULL, NULL)
        //call the new sdio_protocol entry func,to send some cmd from the mmc_host,
        //detrimine if the card is a sdio card from the cmd response,so we need to
        //claim host here, be careful the lock           
        }

     card->prot_driver = pdrv;
        //reutrn with the new found sdio protocol driver     

    return 0;   
    }

4.    card->prot_driver->prot_entry(card, MSS_INIT_CARD, NULL, NULL);
   
    we init the card from sdio_prot entry func.

    send_cmd_5 ,wait for completion--->
    host_write_cmd5 to register --->
    host_get_response_irq, complete --->
    prot_entry return.
   
5.    register the recoginezed card to mmc bus, by invoke :
   
    card->dev.release = mss_card_device_release;
        card->dev.parent = card->slot->host->dev;
        /* set bus_id and name */
        snprintf(&card->dev.bus_id[0], sizeof(card->dev.bus_id), "mmc%d%d",
                        card->slot->host->id, card->slot->id);
        card->dev.bus = &mmc_bus_type;

    device_register(card->dev);  //the card structure contains of the dev structure

   
6.     when the device_register was called, and the dev.bus==mmc_bus_type, the "match"
    func of the mmc_bus was invoked.

    in the mss_core.c, in the module_init,we call the bus_register to create a new type bus:
   
static struct bus_type mmc_bus_type = {
        .name           =       "mmc_bus",
        .match          =       mmc_bus_match,
        .hotplug        =       mmc_bus_hotplug,
        .suspend        =       mmc_bus_suspend,
        .resume         =       mmc_bus_resume,
};


7.    in the "match" func,all the drivers whose bus type is "mmc_bus" was tested, to see if the driver
    colud deal with the device "card->dev"

        if(card->card_type  == MSS_SDIO_CARD && driver->driver_type == 2)
        {
                printk("SDIO CARD INSERTED!\n");
                return 0;
        }
   
    if the "match" func return 0, means match ok. than the "probe" func of the driver was invoked,
    and go on..



8.    if no match, then sometims later, we inserted a new driver, and when driver_register(cmmb_driver),
      the "match" func was invoked ag.

9.     when the new driver we make for the sdio-device, we read and write the device just by
       prot_entry to send cmd to the protocol driver.



            [platform driver]                                 [platform device]


                                                 [platform bus]









                         

阅读(1758) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-09-10 16:45:29

分析得很不错,我也在研究sdio,有问题可以一起讨论。 rocky1972@126.com