Commit bee3b2c5 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] ftl.c

	* switched to private queue
	* set ->queue and ->private_data
	* switched to new methods
	* switched ->open() and friends to use of ->bd_disk
	* switched request handling to use of ->rq_disk
	* cleaned up
parent 53780b94
...@@ -175,16 +175,16 @@ static int ftl_ioctl(struct inode *inode, struct file *file, ...@@ -175,16 +175,16 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg); u_int cmd, u_long arg);
static int ftl_open(struct inode *inode, struct file *file); static int ftl_open(struct inode *inode, struct file *file);
static release_t ftl_close(struct inode *inode, struct file *file); static release_t ftl_close(struct inode *inode, struct file *file);
static int ftl_revalidate(kdev_t dev); static int ftl_revalidate(struct gendisk *disk);
static void ftl_erase_callback(struct erase_info *done); static void ftl_erase_callback(struct erase_info *done);
static struct block_device_operations ftl_blk_fops = { static struct block_device_operations ftl_blk_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
open: ftl_open, .open = ftl_open,
release: ftl_close, .release = ftl_close,
ioctl: ftl_ioctl, .ioctl = ftl_ioctl,
revalidate: ftl_revalidate, .revalidate_disk= ftl_revalidate,
}; };
/*====================================================================== /*======================================================================
...@@ -823,61 +823,53 @@ static u_int32_t find_free(partition_t *part) ...@@ -823,61 +823,53 @@ static u_int32_t find_free(partition_t *part)
static int ftl_open(struct inode *inode, struct file *file) static int ftl_open(struct inode *inode, struct file *file)
{ {
int minor = minor(inode->i_rdev); partition_t *partition = inode->i_bdev->bd_disk->private_data;
partition_t *partition; if (!partition)
return -ENODEV;
if (minor>>4 >= MAX_MTD_DEVICES) if (partition->state != FTL_FORMATTED)
return -ENODEV; return -ENXIO;
partition = myparts[minor>>4];
if (!partition)
return -ENODEV;
if (partition->state != FTL_FORMATTED)
return -ENXIO;
if (get_capacity(partition->disk) == 0) if (get_capacity(partition->disk) == 0)
return -ENXIO; return -ENXIO;
if (!get_mtd_device(partition->mtd, -1)) if (!get_mtd_device(partition->mtd, -1))
return /* -E'SBUGGEREDOFF */ -ENXIO; return /* -E'SBUGGEREDOFF */ -ENXIO;
if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) { if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) {
put_mtd_device(partition->mtd); put_mtd_device(partition->mtd);
return -EROFS; return -EROFS;
} }
DEBUG(0, "ftl_cs: ftl_open(%d)\n", minor); DEBUG(0, "ftl_cs: ftl_open(%s)\n", inode->i_bdev->b_disk->disk_name);
atomic_inc(&partition->open); atomic_inc(&partition->open);
return 0; return 0;
} }
/*====================================================================*/ /*====================================================================*/
static release_t ftl_close(struct inode *inode, struct file *file) static release_t ftl_close(struct inode *inode, struct file *file)
{ {
int minor = minor(inode->i_rdev); partition_t *part = inode->i_bdev->bd_disk->private_data;
partition_t *part = myparts[minor >> 4]; int i;
int i;
DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor); DEBUG(0, "ftl_cs: ftl_close(%s)\n", inode->i_bdev->b_disk->disk_name);
/* Wait for any pending erase operations to complete */ /* Wait for any pending erase operations to complete */
if (part->mtd->sync) if (part->mtd->sync)
part->mtd->sync(part->mtd); part->mtd->sync(part->mtd);
for (i = 0; i < part->header.NumTransferUnits; i++) { for (i = 0; i < part->header.NumTransferUnits; i++) {
if (part->XferInfo[i].state == XFER_ERASED) if (part->XferInfo[i].state == XFER_ERASED)
prepare_xfer(part, i); prepare_xfer(part, i);
} }
atomic_dec(&part->open); atomic_dec(&part->open);
put_mtd_device(part->mtd); put_mtd_device(part->mtd);
release_return(0); release_return(0);
} /* ftl_close */ } /* ftl_close */
...@@ -1091,25 +1083,26 @@ static int ftl_write(partition_t *part, caddr_t buffer, ...@@ -1091,25 +1083,26 @@ static int ftl_write(partition_t *part, caddr_t buffer,
static int ftl_ioctl(struct inode *inode, struct file *file, static int ftl_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg) u_int cmd, u_long arg)
{ {
struct hd_geometry *geo = (struct hd_geometry *)arg; partition_t *part = inode->i_bdev->bd_disk->private_data;
int ret = 0, minor = minor(inode->i_rdev); struct hd_geometry *geo = (struct hd_geometry *)arg;
partition_t *part= myparts[minor >> 4]; int ret = 0;
u_long sect; u_long sect;
if (!part) if (!part)
return -ENODEV; /* How? */ return -ENODEV; /* How? */
if (cmd != HDIO_GETGEO) if (cmd != HDIO_GETGEO)
return -EINVAL; return -EINVAL;
ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo)); ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
if (ret) return ret; if (ret)
/* Sort of arbitrary: round size down to 4K boundary */ return ret;
sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; /* Sort of arbitrary: round size down to 4K boundary */
put_user(1, (char *)&geo->heads); sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
put_user(8, (char *)&geo->sectors); put_user(1, (char *)&geo->heads);
put_user((sect>>3), (short *)&geo->cylinders); put_user(8, (char *)&geo->sectors);
put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start); put_user((sect>>3), (short *)&geo->cylinders);
return 0; put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
return 0;
} /* ftl_ioctl */ } /* ftl_ioctl */
/*====================================================================== /*======================================================================
...@@ -1118,13 +1111,11 @@ static int ftl_ioctl(struct inode *inode, struct file *file, ...@@ -1118,13 +1111,11 @@ static int ftl_ioctl(struct inode *inode, struct file *file,
======================================================================*/ ======================================================================*/
static int ftl_revalidate(kdev_t dev) static int ftl_revalidate(struct gendisk *disk)
{ {
int unit = minor(dev) >> 4; partition_t *part = disk->private_data;
partition_t *part = myparts[unit];
scan_header(part); scan_header(part);
set_capacity(part->disk, set_capacity(disk, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
return 0; return 0;
} }
...@@ -1134,50 +1125,48 @@ static int ftl_revalidate(kdev_t dev) ...@@ -1134,50 +1125,48 @@ static int ftl_revalidate(kdev_t dev)
======================================================================*/ ======================================================================*/
static void do_ftl_request(request_arg_t) static struct request_queue ftl_queue;
{
int ret, minor;
partition_t *part;
do { static void do_ftl_request(struct request_queue *q)
// sti(); {
if (blk_queue_empty(QUEUE)) struct request *req;
return; partition_t *part;
int ret;
do {
// sti();
if (blk_queue_empty(q))
return;
req = elv_next_request(q);
part = req->rq_disk->private_data;
if (part) {
ret = 0;
switch (rq_data_dir(CURRENT)) {
case READ:
ret = ftl_read(part, req->buffer, req->sector,
req->current_nr_sectors);
if (ret)
printk("ftl_read returned %d\n", ret);
break;
case WRITE:
ret = ftl_write(part, req->buffer, req->sector,
req->current_nr_sectors);
if (ret)
printk("ftl_write returned %d\n", ret);
break;
default:
panic("ftl_cs: unknown block command!\n");
}
} else {
ret = 1;
printk("NULL part in ftl_request\n");
}
if (!ret)
req->sector += req->current_nr_sectors;
minor = minor(CURRENT->rq_dev); end_request(req, (ret == 0) ? 1 : 0);
} while (1);
part = myparts[minor >> 4];
if (part) {
ret = 0;
switch (rq_data_dir(CURRENT)) {
case READ:
ret = ftl_read(part, CURRENT->buffer, CURRENT->sector,
CURRENT->current_nr_sectors);
if (ret) printk("ftl_read returned %d\n", ret);
break;
case WRITE:
ret = ftl_write(part, CURRENT->buffer, CURRENT->sector,
CURRENT->current_nr_sectors);
if (ret) printk("ftl_write returned %d\n", ret);
break;
default:
panic("ftl_cs: unknown block command!\n");
}
} else {
ret = 1;
printk("NULL part in ftl_request\n");
}
if (!ret) {
CURRENT->sector += CURRENT->current_nr_sectors;
}
end_request(CURRENT, (ret == 0) ? 1 : 0);
} while (1);
} /* do_ftl_request */ } /* do_ftl_request */
/*====================================================================*/ /*====================================================================*/
...@@ -1246,6 +1235,8 @@ static void ftl_notify_add(struct mtd_info *mtd) ...@@ -1246,6 +1235,8 @@ static void ftl_notify_add(struct mtd_info *mtd)
atomic_set(&partition->open, 0); atomic_set(&partition->open, 0);
myparts[device] = partition; myparts[device] = partition;
set_capacity(disk, le32_to_cpu(partition->header.FormattedSize)/SECTOR_SIZE); set_capacity(disk, le32_to_cpu(partition->header.FormattedSize)/SECTOR_SIZE);
disk->private_data = partition;
disk->queue = &ftl_queue;
add_disk(disk); add_disk(disk);
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n", printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n",
...@@ -1287,31 +1278,29 @@ static void ftl_notify_remove(struct mtd_info *mtd) ...@@ -1287,31 +1278,29 @@ static void ftl_notify_remove(struct mtd_info *mtd)
int init_ftl(void) int init_ftl(void)
{ {
static spinlock_t lock = SPIN_LOCK_UNLOCKED; static spinlock_t lock = SPIN_LOCK_UNLOCKED;
DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n"); DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n");
if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) { if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
printk(KERN_NOTICE "ftl_cs: unable to grab major " printk(KERN_NOTICE "ftl_cs: unable to grab major "
"device number!\n"); "device number!\n");
return -EAGAIN; return -EAGAIN;
} }
blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request, &lock); blk_init_queue(&ftl_queue, &do_ftl_request, &lock);
register_mtd_user(&ftl_notifier); register_mtd_user(&ftl_notifier);
return 0;
return 0;
} }
static void __exit cleanup_ftl(void) static void __exit cleanup_ftl(void)
{ {
unregister_mtd_user(&ftl_notifier); unregister_mtd_user(&ftl_notifier);
unregister_blkdev(FTL_MAJOR, "ftl"); unregister_blkdev(FTL_MAJOR, "ftl");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR)); blk_cleanup_queue(&ftl_queue);
} }
module_init(init_ftl); module_init(init_ftl);
module_exit(cleanup_ftl); module_exit(cleanup_ftl);
MODULE_LICENSE("Dual MPL/GPL"); MODULE_LICENSE("Dual MPL/GPL");
MODULE_AUTHOR("David Hinds <dhinds@sonic.net>"); MODULE_AUTHOR("David Hinds <dhinds@sonic.net>");
MODULE_DESCRIPTION("Support code for Flash Translation Layer, used on PCMCIA devices and M-Systems DiskOnChip 1000"); MODULE_DESCRIPTION("Support code for Flash Translation Layer, used on PCMCIA devices and M-Systems DiskOnChip 1000");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment