国嵌深入班-块设备驱动程序设计

块设备是需要分扇区的


(req->sector + req->current_nr_sectors) <<9:每个扇区是512个字节所以需要左移9位算出扇区的大小

RAMDISK,取内存中的一块出来模拟块设备的卡的读写操作
 
 
#define SIMP_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR
#define SIMP_BLKDEV_DISKNAME 	"simp_blkdev"
#define SIMP_BLKDEV_BYTES 16*1024*1024
 
static struct request_queue * simp_blkdev_queue;
static struct gendisk * simp_blkdev_disk;
unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];
 
static void simp_blkdev_do_request(struct request_queue *q)
{	Struct request *req;
	While((req=elv_next_request(q)) != NULL){
		If((req->sector + req->current_nr_sectors) <<9) > SIMP_BLKDEV_TYTES{
		Printk(KERN_ERR_SIMP_BLKDEV_DISKNAME”:bad request :block=%11u,count=%u\n”,
		(unsigned long long)req->sector,req->current_ar_sectors);
		End_request(req,0)
		Continue;
  	}
  	Switch(rq_data_dir(req)){
 	Case READ:
  		Memcpy(req->buffer, simp_blkdev_data + (req->sector <<9),
			 req->current_nr_sectors<<9);
  		End_request(req,1);
  	Break;
  	Case WRITE:
  		Memcpy(simp_blkdev_data + (req->sector <<9), 
			req->buffer,req->current_nr_sectors<<9);
  	End_request(req,1);
  		Break;
  	Default:
  		Break;
  	}
	}
}
 
struct block_device_operations simp_blkdev_fops = {
	.owner = THIS_MODULE,
};
 
static int __init simp_blkdev_init(void)
{
	int ret;
	simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request,NULL);
	if(!simp_blkdev_queue){
		ret = -ENOMEM;
		goto err_init_queue;
	}
	simp_blkdev_disk = alloc_disk(1);
	if(!simp_blkdev_disk){
		ret = -ENOMEM;
		goto err_alloc_disk;
	}
 
	strcpy(simp_blkdev_disk->disk_name, SIMP_BLKDEV_DISKNAME);
	simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
	simp_blkdev_disk->first_minor = 0;
	simp_blkdev_disk->fops = &simp_blkdev_fops;
	simp_bldkev_disk->queue = simp_blkdev_queue;
	set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES >>9 );
	add_disk(simp_blkdev_disk);
 
	return 0;
 
err_alloc_disk:
	blk_cleanup_queue(simp_blkdev_queue);
err_init_queue:
	return ret;
}
 
static void __exit simp_blkdev_exit(void){
	del_gendisk(simp_blkdev_disk);
	put_disk(simp_blkdev_disk);
	blk_cleanup_queue(simp_blkdev_queue);
}
 
module_init(simp_blkdev_init);
module_exit(simp_blkdev_exit);

应该考虑,frn和__make_request两个函数的关系
 

这里块设备I/O请求可以是,对某个扇区某块区域的请求

 

bi_io_vec更多是关于来自用户的信息内容
 

static int simp_blkdev_make_request(struct request_queue *q, struct bio * bio)
{
	struct bio_vec *bvec;
	int i;
	void * dsk_mem;
 
	if((bio->bi_sector<<9) + bio->bi_size>SIMP_BLKDEV_BYTES){
		printk(KERN_ERR SIMP_BLKDEV_DISKNAME":bad request:block=%11u,count = %u\n"),
		(unsigned long long )bio->bi_sector,bio->bi_size);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
		bio_endio(bio,0,-EIO);
#else
		bio_endio(bio,-EIO);
#endif
		return 0;
	}
	dsk_mem = simp_blkdev_data + (bio->bi-sector <<9);
	
	bio_for_each_segment(bvec, bio, i){
		void * iovec_mem;
		
		switch(bio_rw(bio)):{
		case READ:
		case READA:
			iovec_mem = kmap(bvec->bv_page) + bvec->bv_offset;//因为操作的是页指针所以需要映射
			memcpy(iovec_mem, dsk_mem, bvec->bv_len);
			kunmap(bvec->bv_page);
			break;
		case WRITE:	
			iovec_mem = kmap(bvec->bv_page) + bvec->bv_offset;
			memcpy(dsk_mem, iovec_mem, bvec->bv_len);
			kunmap(bvec->bv_page);
			break;
		default:
			printk(KERN_ERR SIMP_BLKDEV_DISKNAME) ":unknown value bio_rw :%		
		lu\n",bio_rw(bio));
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
			bio_endio(bio,0,-EIO);
#else
			bio_endio(bio,-EIO);
#endif
		
			return 0;
 
		}
	}
 
}
 
static int __init simp_blkdev_init(void)
{
	int ret;
	simp_blkdev_queue = blk_alloc_queue(GFP_KERNEL);
	if(!simp_blkdev_queue){
		ret = -ENOMEM;
		goto err_init_queue;
	}
 
	blk_queue_make_request(simp_blkdev_queue,simp_blkdev_make,request); //这个和第一段程序不同的地方在于blk_init_queue内部先找到__make_request,然后再找到simp_blkdev_do_request;而这里是直接给队列分配处理函数simp_blkdev_make
	simp_blkdev_disk = alloc_disk(1);
	...
	...
	...
	return ret;
}
几个代码树结构:

\blk_init_queue(rfn,lock)
    \blk_init_queue_node(rfn,lock,-1)
        \q->request_fn = rfn;
        \blk_queue_make_request(q,__make_request)
            \q->make_request_fn=__make_request;

blk_init_queue是和blk_cleanup_queue搭配使用的

猜你喜欢

转载自blog.csdn.net/zjy900507/article/details/81283949
今日推荐