块设备学习
块设备的注册
int register_blkdev(unsigned int major, const char *name)
注册块设备时需要指定快设备的主设备号和设备的名字。
int unregister_blkdev(unsigned int major, const char *name)
块设备注销的时候也是同样需要注明块设备号和设备的名字。
结构体
static struct blk_major_name {
struct blk_major_name *next;
int major;
char name[16];
} *major_names[MAX_PROBE_HASH];
设备的存储在major_names, 一个指针数组。每个指针指向一组块设备驱动,这一组块设备驱动的共同点就是major%255 相同。
Source Code
为了让结构更清楚一些,去掉了一些出错的处理。内存申请blk_major_name, 并接入major_names指针数组中。
int register_blkdev(unsigned int major, const char *name)
{
/* temporary */
if (major == 0) {
for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
if (major_names[index] == NULL)
break;
}
major = index;
ret = major;
}
p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);
p->major = major;
strlcpy(p->name, name, sizeof(p->name));
p->next = 0;
index = major_to_index(major);
spin_lock_irqsave(&major_names_lock, flags);
for (n = &major_names[index]; *n; n = &(*n)->next) {
if ((*n)->major == major)
break;
}
if (!*n)
*n = p;
else
ret = -EBUSY;
}
int unregister_blkdev(unsigned int major, const char *name)
{
struct blk_major_name **n;
struct blk_major_name *p = NULL;
int index = major_to_index(major);
unsigned long flags;
int ret = 0;
down_write(&block_subsys.rwsem);
spin_lock_irqsave(&major_names_lock, flags);
for (n = &major_names[index]; *n; n = &(*n)->next)
if ((*n)->major == major)
break;
if (!*n || strcmp((*n)->name, name))
ret = -EINVAL;
else {
p = *n;
*n = p->next;
}
spin_unlock_irqrestore(&major_names_lock, flags);
up_write(&block_subsys.rwsem);
kfree(p);
return ret;
}