无法识别apacer CF(compact flash)

原创 2012年03月25日 21:11:08

最近测试CF卡,发现apacer牌子的CF卡无法识别,于是跟踪原因 ,现把分析过程写下,以备参考。

kernel verison 2.6.25.8

在文件

linux-2.6.25.8/drivers/ide/legacy/ide-cs.c

里面注册 pcmcia driver,
static struct pcmcia_driver ide_cs_driver = {
    .owner        = THIS_MODULE,
    .drv        = {
        .name    = "ide-cs",
    },
    .probe        = ide_probe,
    .remove        = ide_detach,
    .id_table       = ide_ids,
};

static int __init init_ide_cs(void)
{
    return pcmcia_register_driver(&ide_cs_driver);
}


//pcmcia_register_driver 的实现。

在 linux-2.6.25.8/drivers/pcmcia/ds.c
int pcmcia_register_driver(struct pcmcia_driver *driver)
{
    int error;

    if (!driver)
        return -EINVAL;

    pcmcia_check_driver(driver);

    /* initialize common fields */
    driver->drv.bus = &pcmcia_bus_type;
    driver->drv.owner = driver->owner;
    spin_lock_init(&driver->dynids.lock);
    INIT_LIST_HEAD(&driver->dynids.list);

    ds_dbg(3, "registering driver %s\n", driver->drv.name);

    error = driver_register(&driver->drv);
    if (error < 0)
        return error;

    error = pcmcia_create_newid_file(driver);
    if (error)
        driver_unregister(&driver->drv);

    return error;

}


//pcmcia driver和device  对应bus 实现


struct bus_type pcmcia_bus_type = {
    .name = "pcmcia",
    .uevent = pcmcia_bus_uevent,
    .match = pcmcia_bus_match,
    .dev_attrs = pcmcia_dev_attrs,
    .probe = pcmcia_device_probe,
    .remove = pcmcia_device_remove,
    .suspend = pcmcia_dev_suspend,
    .resume = pcmcia_dev_resume,
};

//检查设备是否匹配
static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
 ................

    while (did && did->match_flags) {
        ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
               drv->name);
        if (pcmcia_devmatch(p_dev, did)) {
            ds_dbg(0, "matched %s to %s\n", dev->bus_id,
                   drv->name);
            return 1;
        }
        did++;
    }
....
}


//具体匹配函数,此函数会遍历 drivers/ide/legacy/ ide-cs.c 里面的 ide_ids


static inline int pcmcia_devmatch(struct pcmcia_device *dev,
                  struct pcmcia_device_id *did)
{

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) {
        if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id))
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID) {
        if ((!dev->has_card_id) || (dev->card_id != did->card_id))
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION) {
        if (dev->func != did->function)
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1) {
        if (!dev->prod_id[0])
            return 0;
        if (strcmp(did->prod_id[0], dev->prod_id[0]))
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2) {
        if (!dev->prod_id[1])
            return 0;
        if (strcmp(did->prod_id[1], dev->prod_id[1]))
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3) {
        if (!dev->prod_id[2])
            return 0;
        if (strcmp(did->prod_id[2], dev->prod_id[2]))
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4) {
        if (!dev->prod_id[3])
            return 0;
        if (strcmp(did->prod_id[3], dev->prod_id[3]))
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
        if (dev->device_no != did->device_no)
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
        if ((!dev->has_func_id) || (dev->func_id != did->func_id))
            return 0;

        /* if this is a pseudo-multi-function device,
         * we need explicit matches */
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
            return 0;
        if (dev->device_no)
            return 0;

        /* also, FUNC_ID matching needs to be activated by userspace
         * after it has re-checked that there is no possible module
         * with a prod_id/manf_id/card_id match.
         */
        ds_dbg(0, "skipping FUNC_ID match for %s until userspace "
               "interaction\n", dev->dev.bus_id);
        if (!dev->allow_func_id_match)
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
        ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id);
        if (!dev->socket->fake_cis)
            pcmcia_load_firmware(dev, did->cisfile);

        if (!dev->socket->fake_cis)
            return 0;
    }

    if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
        int i;
        for (i=0; i<4; i++)
            if (dev->prod_id[i])
                return 0;
        if (dev->has_manf_id || dev->has_card_id || dev->has_func_id)
            return 0;
    }

    dev->dev.driver_data = (void *) did;

    return 1;
}


//通过跟踪发现,apacer CF卡 无法匹配到任何的匹配方式,因为drivers/ide/legacy/ ide-cs.c 里面的 

ide_ids 没有对应的匹配项。


而通过如下命令
#cd /sys/devices/platform/pxa2xx-pcmcia/1.0/
#cat manf_id
0x00bf
#cat card_id

0x0001


可以查到device的 manufactute id 和 card id 可以查询出来。


故在static struct pcmcia_device_id ide_ids[] 添加如下一行

PCMCIA_DEVICE_MANF_CARD(0x00bf, 0x0001)

顺利实现匹配。目前需要进一步确认是否只有这种匹配方式,其它方式是否可行。



如何在WinCE 5.0中安装 .Net Compact Framework?

你下载的 NETCFSetupv2.msi(.NET Compact Framework 2.0 Service Pack 2 Redistributable)文件是要求安装在PC机上的,即在PC机上...
  • wxljmy
  • wxljmy
  • 2013年12月26日 19:04
  • 2233

CF卡技术详解——笔记

知识太全面了,摘抄摘不完,还是粘过来加上注释和笔记吧。 重点以及断句用加粗,注释用红括号。 一.CF卡技术及规格 一.CF卡技术及规格   ...
  • huqinweI987
  • huqinweI987
  • 2013年12月04日 21:45
  • 15879

stm32神州开发板,SPI Flash使用分析。

对于STM32开发板例子,采用SPI访问Flash的方式,觉得比较困惑,特做深入分析。基本源码如下,分析内容以黑色字体标注。 开始非常疑惑为什么连接Flash设备的引脚采用GPIO引脚,实际是:GO...
  • zhangym365
  • zhangym365
  • 2011年09月09日 15:06
  • 3859

php compact 把变量都变成数据,或是把数组都合一起的函数

$firstname = "Peter"; $lastname = "Griffin"; $age = "38"; $name = array("firstname", "lastn...
  • a9254778
  • a9254778
  • 2013年02月04日 15:59
  • 1568

Compact 命令压缩和解压缩文件

  Compact.exe 是 Windows 2000 中文件和文件夹压缩功能的命令行版本。使用 Compact 可压缩或解压缩 NTFS 文件系统格式的卷上的文件和文件夹,或者显示这些文件和文件夹...
  • dawnangel
  • dawnangel
  • 2008年03月04日 12:08
  • 2578

java NIO(十) 缓冲区——compact方法介绍

注意java6帮助文档对compact方法的介绍 compact public abstract ByteBuffer compact()压缩此缓冲区(可选操作)。 将缓冲区的当前位置和界限之间的...
  • u014783753
  • u014783753
  • 2015年02月27日 11:07
  • 2338

iOS8--关于regular和compact的理解

随着iPhone设备的不断更新,出现了很多不同尺寸的iPhone和iPad,之前的硬编码就有了很大的局限性,iOS6之后苹果就推出了AutoLayout的适配方式,随着iOS8的推出,苹果对部分iPa...
  • Friday_Holiday
  • Friday_Holiday
  • 2015年12月03日 17:49
  • 1140

MongoDB碎片整理之compact详解

MongoDB碎片整理之compact详解
  • php521php
  • php521php
  • 2015年03月27日 17:05
  • 5280

Hbase compact以及split跟踪

为了准确了解HBASE内部工作原理,我们需要做一些测试,在大量数据插入的情况下,HBASE内部到底有什么表现?  比如插入速度,  hstore compact,split等相关活动,了解了这些才能更...
  • tom_fans
  • tom_fans
  • 2017年06月30日 10:13
  • 330

php compact函数

compact() $firstname = "Peter"; $lastname = "Griffin"; $age = "41";$result = compact("firstname", "...
  • u010265663
  • u010265663
  • 2017年01月14日 21:20
  • 1233
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:无法识别apacer CF(compact flash)
举报原因:
原因补充:

(最多只允许输入30个字)