From a885c8c4316e1c1d2d2c8755da3f3d14f852528d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 8 Jan 2006 01:02:50 -0800 Subject: [PATCH] Add block_device_operations.getgeo block device method HDIO_GETGEO is implemented in most block drivers, and all of them have to duplicate the code to copy the structure to userspace, as well as getting the start sector. This patch moves that to common code [1] and adds a ->getgeo method to fill out the raw kernel hd_geometry structure. For many drivers this means ->ioctl can go away now. [1] the s390 block drivers are odd in this respect. xpram sets ->start to 4 always which seems more than odd, and the dasd driver shifts the start offset around, probably because of it's non-standard sector size. Signed-off-by: Christoph Hellwig Cc: Jens Axboe Cc: Cc: Jeff Dike Cc: Paolo Giarrusso Cc: Bartlomiej Zolnierkiewicz Cc: Neil Brown Cc: Markus Lidel Cc: Russell King Cc: David Woodhouse Cc: Martin Schwidefsky Cc: James Bottomley Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/cpqarray.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers/block/cpqarray.c') diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 9bddb6874873..9f0664dd3800 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -160,6 +160,7 @@ static int sendcmd( static int ida_open(struct inode *inode, struct file *filep); static int ida_release(struct inode *inode, struct file *filep); static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); +static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); static void do_ida_request(request_queue_t *q); @@ -199,6 +200,7 @@ static struct block_device_operations ida_fops = { .open = ida_open, .release = ida_release, .ioctl = ida_ioctl, + .getgeo = ida_getgeo, .revalidate_disk= ida_revalidate, }; @@ -1124,6 +1126,23 @@ static void ida_timer(unsigned long tdata) h->misc_tflags = 0; } +static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) +{ + drv_info_t *drv = get_drv(bdev->bd_disk); + + if (drv->cylinders) { + geo->heads = drv->heads; + geo->sectors = drv->sectors; + geo->cylinders = drv->cylinders; + } else { + geo->heads = 0xff; + geo->sectors = 0x3f; + geo->cylinders = drv->nr_blks / (0xff*0x3f); + } + + return 0; +} + /* * ida_ioctl does some miscellaneous stuff like reporting drive geometry, * setting readahead and submitting commands from userspace to the controller. @@ -1133,27 +1152,10 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); int error; - int diskinfo[4]; - struct hd_geometry __user *geo = (struct hd_geometry __user *)arg; ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; ida_ioctl_t *my_io; switch(cmd) { - case HDIO_GETGEO: - if (drv->cylinders) { - diskinfo[0] = drv->heads; - diskinfo[1] = drv->sectors; - diskinfo[2] = drv->cylinders; - } else { - diskinfo[0] = 0xff; - diskinfo[1] = 0x3f; - diskinfo[2] = drv->nr_blks / (0xff*0x3f); - } - put_user(diskinfo[0], &geo->heads); - put_user(diskinfo[1], &geo->sectors); - put_user(diskinfo[2], &geo->cylinders); - put_user(get_start_sect(inode->i_bdev), &geo->start); - return 0; case IDAGETDRVINFO: if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t))) return -EFAULT; -- cgit v1.2.3-59-g8ed1b