加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

无法识别apacer CF(compact flash)

发布时间:2020-12-15 06:16:30 所属栏目:百科 来源:网络整理
导读:最近测试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 = { ?? ?.o

最近测试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 %sn",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 %sn",dev->bus_id,
?? ??? ??????? drv->name);
?? ??? ?if (pcmcia_devmatch(p_dev,did)) {
?? ??? ??? ?ds_dbg(0,"matched %s to %sn",
?? ??? ??? ??????? 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 "
?? ??? ??????? "interactionn",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 CISn",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)

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读