linux块驱动设备驱动程序,linux块设备驱动与其测试

#include

#include

#include

#include

#include /* printk() */

#include /* kmalloc() */

#include /* everything... */

#include /* error codes */

#include

#include /* size_t */

#include /* O_ACCMODE */

#include /* HDIO_GETGEO */

#include

#include

#include

#include

#include /* invalidate_bdev */

#include

//块设备文件主设备号  72

#define BLOCK_DEVICEMAJOR        COMPAQ_SMART2_MAJOR

// 块设备名字

#define BLOCK_DISKNAME           "queue_block"

//块设备容量

#define BLOCK_DEV_BYTES        (1*1024*1024)   // 1M

//请求队列指针

static struct request_queue *block_request_queue;

// gendisk结构体指针变量

static struct gendisk *block_dev_disk;

//模拟磁盘空间

unsigned char block_dev_data[BLOCK_DEV_BYTES];//该函数不能由驱动自己调用 由系统调用 系统认为是时候调用的时候调用static void block_dev_do_request(struct request_queue *q)

{      //获取请求队列第一个IO请求

struct request *req =blk_fetch_request(q);

while ( req  != NULL) {

sector_t sector = blk_rq_pos(req);  //获取扇区第一个位置

unsigned long nsector = blk_rq_cur_sectors(req);//获取扇区数目

//判断是否大于总容量

if ((sector + nsector)<<9 > BLOCK_DEV_BYTES)

{

printk(KERN_ERR BLOCK_DISKNAME

": bad request: block=%llu, count=%llu\n",

(unsigned long long)sector,

(unsigned long long)nsector);

__blk_end_request_all(req, -EIO);

continue;

}

//判断数据传输方向

switch (rq_data_dir(req)) {

case READ:

memcpy(req->buffer,

block_dev_data + (sector<<9),

nsector<<9);

break;

case WRITE:

memcpy(block_dev_data + (sector<<9),

req->buffer,  nsector<<9);

break;

default:

break;

}

//通知请求队列当前IO已经处理完毕

if ( ! __blk_end_request_cur(req, 0) ) {req = blk_fetch_request(q); //继续读取下一个IO请求}

}

}

static int block_dev_open (struct block_device *device, fmode_t mode)

{

printk("open %s\n", device->bd_disk->disk_name);

return 0;

}

//  释放块设备

static int block_dev_release(struct gendisk *gendisk, fmode_t mode)

{

printk("release %s\n", gendisk->disk_name);

return 0;

}

//类似字符设备

struct block_device_operations block_dev_fops = {

.owner                = THIS_MODULE,.open=block_dev_open, .release=block_dev_release

};

static int __init block_dev_init(void)

{

int ret;

//初始化请求队列

block_request_queue = blk_init_queue(block_dev_do_request, NULL);

if (!block_request_queue) {

ret = -ENOMEM;

goto err_init_queue;

}

//分配磁盘

block_dev_disk = alloc_disk(1);

if (!block_dev_disk) {

ret = -ENOMEM;

goto err_alloc_disk;

}

strcpy(block_dev_disk->disk_name, BLOCK_DISKNAME);//设备文件名

block_dev_disk->major = BLOCK_DEVICEMAJOR;

block_dev_disk->first_minor = 0;

block_dev_disk->fops = &block_dev_fops;

block_dev_disk->queue = block_request_queue;//指定请求队列

set_capacity(block_dev_disk, BLOCK_DEV_BYTES>>9);//设置磁盘容量

add_disk(block_dev_disk);//添加磁盘

return 0;

err_alloc_disk:

blk_cleanup_queue(block_request_queue);

err_init_queue:

return ret;

}

static void __exit block_dev_exit(void)

{

del_gendisk(block_dev_disk);//删除磁盘

put_disk(block_dev_disk);//gendisk引用次数减一

blk_cleanup_queue(block_request_queue);//清除请求队列

}

module_init(block_dev_init);

module_exit(block_dev_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值