/**
* 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(, baseminor, count, name);
if (IS_ERR(cd))
return PTR_ERR(cd);
*dev = MKDEV(cd->major, cd->baseminor);
return ;
}
 static struct char_device_struct *
__register_chrdev_region(unsigned int major, unsigned int baseminor,
int minorct, const char *name)
{
struct char_device_struct *cd, **cp;
int ret = ;
int i; cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
if (cd == NULL)
return ERR_PTR(-ENOMEM); mutex_lock(&chrdevs_lock); /* temporary */
if (major == ) {
for (i = ARRAY_SIZE(chrdevs)-; i > ; i--) {
if (chrdevs[i] == NULL)
break;
} if (i == ) {
ret = -EBUSY;
goto out;
}
major = i;
ret = major;
} cd->major = major;
cd->baseminor = baseminor;
cd->minorct = minorct;
strlcpy(cd->name, name, sizeof(cd->name)); i = major_to_index(major); for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major > major ||
((*cp)->major == major &&
(((*cp)->baseminor >= baseminor) ||
((*cp)->baseminor + (*cp)->minorct > baseminor))))
break; /* Check for overlapping minor ranges. */
if (*cp && (*cp)->major == major) {
int old_min = (*cp)->baseminor;
int old_max = (*cp)->baseminor + (*cp)->minorct - ;
int new_min = baseminor;
int new_max = baseminor + minorct - ; /* New driver overlaps from the left. */
if (new_max >= old_min && new_max <= old_max) {
ret = -EBUSY;
goto out;
} /* New driver overlaps from the right. */
if (new_min <= old_max && new_min >= old_min) {
ret = -EBUSY;
goto out;
}
} cd->next = *cp;
*cp = cd;
mutex_unlock(&chrdevs_lock);
return cd;
out:
mutex_unlock(&chrdevs_lock);
kfree(cd);
return ERR_PTR(ret);
}

最新文章

  1. CentOS下yum安装LAMP
  2. nginx和tomcat的区别
  3. Nginx配置upstream实现负载均衡
  4. 生成短链(网址) ShortUrlLink
  5. JavaMail接、收邮件
  6. eclipse中建python项目并运行
  7. c signal
  8. Spring学习笔记之BeanFactory
  9. php大力力 [015节]兄弟连高洛峰php教程(土豆网栏目地址)
  10. requestscope.contextpath和&lt;%=request.getContextPath()%&gt;有何区别?(待解答)
  11. Oracle 基础——索引
  12. struts2.1笔记01:MVC框架思想浅层理解
  13. 对css中的浮动属性float刨根解牛
  14. springMVC整合memcached,以注解形式使用
  15. chrome使用技巧(转)good
  16. EasyUI 使用tabs切换后datagrid显示不了内容
  17. MVCC(Multi-version Cocurrent Control)多版本并发控制协议
  18. idea调试代码跟踪到tomcat代码里面
  19. scp 的用法
  20. Java虚拟机六 堆溢出的处理

热门文章

  1. Codeforces #480 Tutorial
  2. 某考试 T1 lcm
  3. 【可持久化Trie】bzoj3261 最大异或和
  4. 【分块】bzoj2453 维护队列
  5. 【权值分块】bzoj1503 [NOI2004]郁闷的出纳员
  6. OC语言基础之类的本质
  7. How to Analyze &quot;Deadlocked Schedulers&quot; Dumps?---WINDBG
  8. MySQL Workbench 工具
  9. 一道综合练习题实践list及dictionary集合类
  10. NTFS数据流和web安全