linux - 主次设备号自动申请

alloc_chrdev_region 原型如下,该函数向内核申请一个空闲的主设备号。

alloc_chrdev_region(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, "aputriger0");

第四个参数是我们使用cat /proc/devices 看到的名称

/**
 * alloc_chrdev_region() - register a range of char device numbers
 * @dev: output parameter for first assigned number
 * @baseminor: first of the requested range of minor numbers
 * @count: the number of minor numbers required
 * @name: the name of the associated device or driver
 *
 * Allocates a range of char device numbers.  The major number will be
 * chosen dynamically, and returned (along with the first minor number)
 * in @dev.  Returns zero or a negative error code.
 */
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
			const char *name)
{
	struct char_device_struct *cd;
	cd = __register_chrdev_region(0, baseminor, count, name);
	if (IS_ERR(cd))
		return PTR_ERR(cd);
	*dev = MKDEV(cd->major, cd->baseminor);
	return 0;
}

如果我们的设备不止一个,次设备号我们也希望是自动申请而不是人为指定的,那么可以使用ida_simple_get来申请,原型如下:

minor = ida_simple_get(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, GFP_KERNEL);

#define ida_simple_get(ida, start, end, gfp)	\
			ida_alloc_range(ida, start, (end) - 1, gfp)


/**
 * ida_alloc_range() - Allocate an unused ID.
 * @ida: IDA handle.
 * @min: Lowest ID to allocate.
 * @max: Highest ID to allocate.
 * @gfp: Memory allocation flags.
 *
 * Allocate an ID between @min and @max, inclusive.  The allocated ID will
 * not exceed %INT_MAX, even if @max is larger.
 *
 * Context: Any context.
 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
 * or %-ENOSPC if there are no free IDs.
 */
int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max,
			gfp_t gfp)
{
	int id = 0;
	unsigned long flags;

	if ((int)min < 0)
		return -ENOSPC;

	if ((int)max < 0)
		max = INT_MAX;

again:
	xa_lock_irqsave(&ida->ida_rt, flags);
	id = ida_get_new_above(ida, min);
	if (id > (int)max) {
		ida_remove(ida, id);
		id = -ENOSPC;
	}
	xa_unlock_irqrestore(&ida->ida_rt, flags);

	if (unlikely(id == -EAGAIN)) {
		if (!ida_pre_get(ida, gfp))
			return -ENOMEM;
		goto again;
	}

	return id;
}

创建设备示例:

	cur_dev->ida = minor;
	parent = dev->lpdev->dev;

	/* Add to system */
	if (cdev_add(&cur_dev->cdev, MKDEV(MAJOR(g_aputriger_dev), minor), 1)) {
		pr_err("%s cdev add failed\n", cdev_name);
		goto err_class_destr;
	}

	memset(cur_dev->nodename, 0, NAME_LEN_MAX);
    snprintf(cur_dev->nodename, NAME_LEN_MAX, "%s/%d/%s", DEVICE_NAME, dev->lpdev->dev_id, "aputriger");

	/* devices create */
	cur_dev->dev = device_create(g_aputriger_class, parent, MKDEV(cur_dev->major, minor), cur_dev, cdev_name);
	if (IS_ERR(cur_dev->dev)) {
		pr_err("%s failed to create device\n", cdev_name);
		goto err_cdev_del;
	}

 

相关推荐

  1. Linux 设置自动挂载磁盘

    2024-05-11 03:18:08       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-11 03:18:08       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-11 03:18:08       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-11 03:18:08       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-11 03:18:08       20 阅读

热门阅读

  1. 开源模型应用落地-模型记忆增强-概念篇(一)

    2024-05-11 03:18:08       10 阅读
  2. (数据结构)快速了解时间复杂度和空间复杂度

    2024-05-11 03:18:08       10 阅读
  3. QT--5

    QT--5

    2024-05-11 03:18:08      9 阅读
  4. 网络面试题目

    2024-05-11 03:18:08       11 阅读
  5. MySQL数据库——23.元数据

    2024-05-11 03:18:08       10 阅读
  6. android 获取唯一设备id

    2024-05-11 03:18:08       10 阅读
  7. k8s deployment

    2024-05-11 03:18:08       8 阅读
  8. typescript 命名空间、装饰器

    2024-05-11 03:18:08       10 阅读
  9. warm-up结合CosineAnnealingLR

    2024-05-11 03:18:08       14 阅读
  10. Hive优化(2)——join优化

    2024-05-11 03:18:08       11 阅读