设为首页 加入收藏

TOP

Linux 块设备驱动 实例(四)
2014-11-24 07:23:48 来源: 作者: 【 】 浏览:11
Tags:Linux 设备驱动 实例
if (dev->users || !dev->data)
printk (KERN_WARNING "sbull: timer sanity check failed\n");
else
dev->media_change = 1;
spin_unlock(&dev->lock);
}


/*
* The ioctl() implementation
*/


int sbull_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
long size;
struct hd_geometry geo;
struct sbull_dev *dev = filp->private_data;


switch(cmd) {
case HDIO_GETGEO:
/*
* Get geometry: since we are a virtual device, we have to make
* up something plausible. So we claim 16 sectors, four heads,
* and calculate the corresponding number of cylinders. We set the
* start of data at sector four.
*/
//printk("<0>""-------------size=%d\n",size);
/****************for early version************/
//size = dev->size*(hardsect_size/KERNEL_SECTOR_SIZE);
//printk("<0>""-------------size=%d\n",size);
//geo.cylinders = (size & ~0x3f) >> 6;
//geo.cylinders=2000;
//geo.heads = 4;
//geo.sectors = 16;
//geo.sectors=2560;
//geo.start = 0;
//if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))
// return -EFAULT;
return 0;
}


return -ENOTTY; /* unknown command */
}


static int sbull_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
unsigned long size;
struct sbull_dev *pdev = bdev->bd_disk->private_data;


size = pdev->size;
geo->cylinders = (size & ~0x3f) >> 6;
geo->heads = 4;
geo->sectors = 16;
geo->start = 0;
return 0;
}



/*
* The device operations structure.
*/
static struct block_device_operations sbull_ops = {
.owner = THIS_MODULE,
.open = sbull_open,
.release = sbull_release,
.media_changed = sbull_media_changed,
.reva lidate_disk = sbull_reva lidate,
.ioctl = sbull_ioctl,
.getgeo = sbull_getgeo,
};



/*
* Set up our internal device.
*/
// 初始化设备结构体 static struct sbull_dev *Devices中的成员
static void setup_device(struct sbull_dev *dev, int which)
{
/*
* Get some memory.
*/
memset (dev, 0, sizeof (struct sbull_dev));
dev->size = nsectors*hardsect_size;
// 分配一片虚拟地址连续的内存空间,作为块设备。
dev->data = vmalloc(dev->size);
if (dev->data == NULL) {
printk (KERN_NOTICE "vmalloc failure.\n");
return;
}
spin_lock_init(&dev->lock);

/*
* The timer which "invalidates" the device.
*/
init_timer(&dev->timer);
dev->timer.data = (unsigned long) dev;
dev->timer.function = sbull_invalidate;

/*
* The I/O queue, depending on whether we are using our own
* make_request function or not.
*/
switch (request_mode) {
case RM_NOQUEUE:
dev->queue = blk_alloc_queue(GFP_KERNEL);
if (dev->queue == NULL)
goto out_vfree;
blk_queue_make_request(dev->queue, sbull_make_request);
break;


case RM_FULL:
dev->queue = blk_init_queue(sbull_full_request, &dev->lock);
if (dev->queue == NULL)
goto out_vfree;
break;


default:
printk(KERN_NOTICE "Bad request mode %d, using simple\n", request_mode);
/* fall into.. */

case RM_SIMPLE:
dev->queue = blk_init_queue(sbull_request, &dev->lock);
if (dev->queue == NULL)
goto out_v

首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux下创建进程线程以及通信技术.. 下一篇脚本--Linux下清理IPC资源

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)
·MongoDB 索引 - 菜鸟 (2025-12-25 17:19:45)
·What Is Linux (2025-12-25 16:57:17)
·Linux小白必备:超全 (2025-12-25 16:57:14)