每个块设备都拥有一个操作接口:struct block_device_operations,该接口定义了open、close、ioctl等函数接口,但没有,也没有必要定义read、write函数接口。
初始化一个块设备的过程如下:
int setup_device(block_dev_t
*dev, int minor)
{
int hardsect_size = HARDSECT_SIZE;
int chunk_size;
sector_t dev_size;
/* 分配一个请求队列 */
dev->queue =
blk_alloc_queue(GFP_KERNEL);
if (dev->queue == NULL) {
printk(ERROR,
"blk_alloc_queue failure!\n");
return -ENOMEM;
}
chunk_size = dev->chunk_size >>
9; //sectors
/* 将block_make_request注册到q->make_request上 */
blk_queue_make_request(dev->queue, block_make_request);
blk_queue_max_sectors(dev->queue,
chunk_size);
blk_queue_hardsect_size(dev->queue,
hardsect_size);
blk_queue_merge_bvec(dev->queue, block_mergeable_bvec);
dev->queue->queuedata = dev;
/* 将block_unplug注册到q->unplug_fn上 */
dev->queue->unplug_fn = block_unplug;
/* 分配一个gendisk */
dev->gd = alloc_disk(1);
if (!dev->gd) {
prink(ERROR, "alloc_disk
failure!\n");
blk_cleanup_queue(dev->queue);
return -ENOMEM;
}
dev->gd->major = block_major; /* 设备的major号 */
dev->gd->first_minor = minor; /* 设备的minor号 */
dev->gd->fops = &block_ops; /* 块设备的操作接口,open、close、ioctl */
dev->gd->queue = dev->queue; /* 块设备的请求队列 */
dev->gd->private_data = dev;
snprintf(dev->gd->disk_name, 32,
dev->block_name);
dev_size = (sector_t) dev->dev_size
>> 9;
set_capacity(dev->gd, dev_size); /* 设置块设备的容量 */
add_disk(dev->gd); /* 添加块设备 */
return 0;
}
通过register_blkdev函数将块设备注册到Linux系统。示例代码如下:
static int blockdev_init(void)
{
…
block_major =
register_blkdev(block_major, "blockd");
if
(block_major <= 0) {
printk(ERROR,
"blockd: cannot get major %d\n", block_major);
return
-EFAULT;
}
…
}
通过unregister_blkdev函数清除一个块设备。示例代码如下:
static int blockdev_cleanup(void)
{
…
unregister_blkdev(block_major,
"blockd");
…
}
make_request函数是块设备中最重要的接口函数,每个块设备都需要提供make_request函数。如果块设备为有请求队列的实际设备,那么make_request函数被注册为__make_request,该函数由Linux系统提供;反之,需要用户提供私有函数。__make_request函数功能在前文已述。
在用户提供的私有make_request函数中往往对bio进行过滤处理,这样的驱动在Linux中有md(raid0、raid1、raid5),过滤处理完毕之后,私有make_request函数返回1,告诉generic_make_request函数进行bio转发。
wangxinfeng6666_749290079 2013-7-2 17:56
用户411565 2008-7-7 09:16