weixin_45400120 2021-04-08 11:23 采纳率: 0%
浏览 15

模块init的时候会注册两次, 导致模块加载不进去

static int pmem_major

static struct pmem_device *shebei;

static int __init pmem_init(void)
{
        int error;

       pmem_major = register_blkdev(0, "pmem");

        if (pmem_major < 0)
 

                return pmem_major;

        error = nd_driver_register(&nd_pmem_driver);
        if (error)

                nregister_blkdev(pmem_major, "pmem");
                return error;
        }

        return 0;
}
module_init(pmem_init);

 

struct pmem_device {
        struct request_queue    *pmem_queue;
        struct gendisk          *pmem_disk;
        struct nd_namespace_common *ndns;

        /* One contiguous memory region per device */
        phys_addr_t             phys_addr;
        /* when non-zero this device is hosting a 'pfn' instance */
        phys_addr_t             data_offset;
        void __pmem             *virt_addr;
        size_t                  size;
};

static int nd_pmem_probe(struct device *dev)
{
 extern int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns);

        struct nd_region *nd_region = to_nd_region(dev->parent);
        struct nd_namespace_common *ndns;
        struct nd_namespace_io *nsio;
        struct pmem_device  *pmem;

        ndns = nvdimm_namespace_common_probe(dev);
        if (IS_ERR(ndns))
                return PTR_ERR(ndns);

        nsio = to_nd_namespace_io(&ndns->dev);
        pmem = pmem_alloc(dev, &nsio->res, nd_region->id);
        if (IS_ERR(pmem))
                return PTR_ERR(pmem);

        pmem->ndns = ndns;
        dev_set_drvdata(dev, pmem);
        ndns->rw_bytes = pmem_rw_bytes;

        if (is_nd_btt(dev))
                return nvdimm_namespace_attach_btt(ndns);

        if (is_nd_pfn(dev))
                return nvdimm_namespace_attach_pfn(ndns);

        if (nd_btt_probe(ndns, pmem) == 0) {
                /* we'll come back as btt-pmem */
                return -ENXIO;
        }

        if (nd_pfn_probe(ndns, pmem) == 0) {
                /* we'll come back as pfn-pmem */
                return -ENXIO;
        }

        return pmem_attach_disk(dev, ndns, pmem);
}

 

static struct pmem_device *pmem_alloc(struct device *dev,
                struct resource *res, int id)
{
        struct pmem_device *pmem;

        pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
        if (!pmem)
                return ERR_PTR(-ENOMEM);

        pmem->phys_addr = res->start;
        pmem->size = resource_size(res);
        if (!arch_has_wmb_pmem())
                dev_warn(dev, "unable to guarantee persistence of writes\n");

        if (!devm_request_mem_region(dev, pmem->phys_addr, pmem->size,
                        dev_name(dev))) {
                dev_warn(dev, "could not reserve region [0x%pa:0x%zx]\n",
                                &pmem->phys_addr, pmem->size);
                return ERR_PTR(-EBUSY);
        }

        if (pmem_should_map_pages(dev))
                pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, res);
        else
                pmem->virt_addr = (void __pmem *) devm_memremap(dev,
                                pmem->phys_addr, pmem->size,
                                ARCH_MEMREMAP_PMEM);

        if (IS_ERR(pmem->virt_addr))
                return (void __force *) pmem->virt_addr;

        return pmem;
}

static int pmem_attach_disk(struct device *dev,
                struct nd_namespace_common *ndns, struct pmem_device *pmem)
{
        int nid = dev_to_node(dev);
        struct gendisk *disk;

        pmem->pmem_queue = blk_alloc_queue_node(GFP_KERNEL, nid);
        if (!pmem->pmem_queue)
                return -ENOMEM;

        blk_queue_make_request(pmem->pmem_queue, pmem_make_request);
        blk_queue_physical_block_size(pmem->pmem_queue, PAGE_SIZE);
        blk_queue_max_hw_sectors(pmem->pmem_queue, UINT_MAX);
        blk_queue_bounce_limit(pmem->pmem_queue, BLK_BOUNCE_ANY);
        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, pmem->pmem_queue);

        disk = alloc_disk_node(0, nid);
        if (!disk) {
                blk_cleanup_queue(pmem->pmem_queue);
                return -ENOMEM;
        }

        disk->major             = pmem_major;
        printk("diskmajor=%d\n",pmem_major);
        disk->first_minor       = 0;
        disk->fops              = &pmem_fops;
        disk->private_data      = pmem;
        disk->queue             = pmem->pmem_queue;
        disk->flags             = GENHD_FL_EXT_DEVT;
        nvdimm_namespace_disk_name(ndns, disk->disk_name);
        disk->driverfs_dev = dev;
        set_capacity(disk, (pmem->size - pmem->data_offset) / 512);
        pmem->pmem_disk = disk;
        shebei = pmem;   //  我在这设置了一个自己的指针指向了这个设备!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        printk("aaapmemchengg\n");

        add_disk(disk);
        revalidate_disk(disk);

        return 0;
}

 

我希望用到一个设备,他在初始化的时候调用alloc为设备分配内存.我自己在驱动之中设置了一个指针   指向了那块被初始化的地方 打算利用他 

(最后  模块没有加载进去 但是/proc/device能看到第一次载入的设备号)

  • 写回答

0条回答 默认 最新

      报告相同问题?

      悬赏问题

      • ¥15 pom文件依赖管理,未找到依赖
      • ¥15 现在后端返回给我一堆下载地址,都是一个视频切片后的,如何在uniapp安卓环境下将这些分片的视频下周并且合并成原始视频并下载到本地。
      • ¥15 Unity导出2D项目运行时图片变成马赛克
      • ¥15 关于communitytoolkit.mvvm的生成器得到的代码看起来没有被使用的问题
      • ¥15 matlab中此类型的变量不支持使用点进行索引
      • ¥15 咨询第六届工业互联网数据创新大赛原始数据
      • ¥15 Pycharm无法自动补全,识别第三方库函数接收的参数!
      • ¥15 STM32U575 pwm和DMA输出的波形少一段
      • ¥30 android百度地图SDK海量点显示标题
      • ¥15 windows导入environment.yml运行conda env create -f environment_win.yml命令报错