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

模块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能看到第一次载入的设备号)

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答