static int sbull_open(struct inode *inode, struct file *filp)
{
struct sbull_dev *dev = inode->i_bdev->bd_disk->private_data;
//printk("<0>" "fdfjdlksjfdlkj\n");
del_timer_sync(&dev->timer);
filp->private_data = dev;
spin_lock(&dev->lock);
if (! dev->users)
check_disk_change(inode->i_bdev);
dev->users++;
spin_unlock(&dev->lock);
return 0;
}
static int sbull_release(struct inode *inode, struct file *filp)
{
struct sbull_dev *dev = inode->i_bdev->bd_disk->private_data;
spin_lock(&dev->lock);
dev->users--;
if (!dev->users) {
dev->timer.expires = jiffies + INVALIDATE_DELAY;
add_timer(&dev->timer);
}
spin_unlock(&dev->lock);
return 0;
}
/*
* Look for a (simulated) media change.
*/
int sbull_media_changed(struct gendisk *gd)
{
struct sbull_dev *dev = gd->private_data;
return dev->media_change;
}
/*
* Revalidate. WE DO NOT TAKE THE LOCK HERE, for fear of deadlocking
* with open. That needs to be reevaluated.
*/
int sbull_revalidate(struct gendisk *gd)
{
struct sbull_dev *dev = gd->private_data;
if (dev->media_change) {
dev->media_change = 0;
memset (dev->data, 0, dev->size);
}
return 0;
}
/*
* The "invalidate" function runs out of the device timer; it sets
* a flag to simulate the removal of the media.
*/
void sbull_invalidate(unsigned long ldev)
{
struct sbull_dev *dev = (struct sbull_dev *) ldev;
spin_lock(&dev->lock);
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;
}