diff options
author | Christoph Hellwig <hch@lst.de> | 2006-01-08 04:02:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:13:54 -0500 |
commit | a885c8c4316e1c1d2d2c8755da3f3d14f852528d (patch) | |
tree | e4f4e7a7657c0944d11c259f8f17ffcd6b2da0f5 /drivers/s390 | |
parent | 5b0ed2c64d8fdafb5fcfb3baabdd288628b1ff9b (diff) |
[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 <hch@lst.de>
Cc: Jens Axboe <axboe@suse.de>
Cc: <mike.miller@hp.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Paolo Giarrusso <blaisorblade@yahoo.it>
Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Cc: Neil Brown <neilb@cse.unsw.edu.au>
Cc: Markus Lidel <Markus.Lidel@shadowconnect.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 23 | ||||
-rw-r--r-- | drivers/s390/block/dasd_ioctl.c | 28 | ||||
-rw-r--r-- | drivers/s390/block/xpram.c | 18 |
3 files changed, 30 insertions, 39 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index f779f674dfa0..2472fa1a1be1 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/major.h> | 18 | #include <linux/major.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
21 | #include <linux/hdreg.h> | ||
21 | 22 | ||
22 | #include <asm/ccwdev.h> | 23 | #include <asm/ccwdev.h> |
23 | #include <asm/ebcdic.h> | 24 | #include <asm/ebcdic.h> |
@@ -1723,12 +1724,34 @@ dasd_release(struct inode *inp, struct file *filp) | |||
1723 | return 0; | 1724 | return 0; |
1724 | } | 1725 | } |
1725 | 1726 | ||
1727 | /* | ||
1728 | * Return disk geometry. | ||
1729 | */ | ||
1730 | static int | ||
1731 | dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
1732 | { | ||
1733 | struct dasd_device *device; | ||
1734 | |||
1735 | device = bdev->bd_disk->private_data; | ||
1736 | if (!device) | ||
1737 | return -ENODEV; | ||
1738 | |||
1739 | if (!device->discipline || | ||
1740 | !device->discipline->fill_geometry) | ||
1741 | return -EINVAL; | ||
1742 | |||
1743 | device->discipline->fill_geometry(device, geo); | ||
1744 | geo->start = get_start_sect(bdev) >> device->s2b_shift; | ||
1745 | return 0; | ||
1746 | } | ||
1747 | |||
1726 | struct block_device_operations | 1748 | struct block_device_operations |
1727 | dasd_device_operations = { | 1749 | dasd_device_operations = { |
1728 | .owner = THIS_MODULE, | 1750 | .owner = THIS_MODULE, |
1729 | .open = dasd_open, | 1751 | .open = dasd_open, |
1730 | .release = dasd_release, | 1752 | .release = dasd_release, |
1731 | .ioctl = dasd_ioctl, | 1753 | .ioctl = dasd_ioctl, |
1754 | .getgeo = dasd_getgeo, | ||
1732 | }; | 1755 | }; |
1733 | 1756 | ||
1734 | 1757 | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 044b75371990..8e4dcd58599e 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -486,33 +486,6 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | |||
486 | } | 486 | } |
487 | 487 | ||
488 | /* | 488 | /* |
489 | * Return disk geometry. | ||
490 | */ | ||
491 | static int | ||
492 | dasd_ioctl_getgeo(struct block_device *bdev, int no, long args) | ||
493 | { | ||
494 | struct hd_geometry geo = { 0, }; | ||
495 | struct dasd_device *device; | ||
496 | |||
497 | device = bdev->bd_disk->private_data; | ||
498 | if (device == NULL) | ||
499 | return -ENODEV; | ||
500 | |||
501 | if (device == NULL || device->discipline == NULL || | ||
502 | device->discipline->fill_geometry == NULL) | ||
503 | return -EINVAL; | ||
504 | |||
505 | geo = (struct hd_geometry) {}; | ||
506 | device->discipline->fill_geometry(device, &geo); | ||
507 | geo.start = get_start_sect(bdev) >> device->s2b_shift; | ||
508 | if (copy_to_user((struct hd_geometry __user *) args, &geo, | ||
509 | sizeof (struct hd_geometry))) | ||
510 | return -EFAULT; | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /* | ||
516 | * List of static ioctls. | 489 | * List of static ioctls. |
517 | */ | 490 | */ |
518 | static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = | 491 | static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = |
@@ -528,7 +501,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = | |||
528 | { BIODASDPRRST, dasd_ioctl_reset_profile }, | 501 | { BIODASDPRRST, dasd_ioctl_reset_profile }, |
529 | { BLKROSET, dasd_ioctl_set_ro }, | 502 | { BLKROSET, dasd_ioctl_set_ro }, |
530 | { DASDAPIVER, dasd_ioctl_api_version }, | 503 | { DASDAPIVER, dasd_ioctl_api_version }, |
531 | { HDIO_GETGEO, dasd_ioctl_getgeo }, | ||
532 | { -1, NULL } | 504 | { -1, NULL } |
533 | }; | 505 | }; |
534 | 506 | ||
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index bf3a67c3cc5e..54ecd548c318 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -328,31 +328,27 @@ fail: | |||
328 | return 0; | 328 | return 0; |
329 | } | 329 | } |
330 | 330 | ||
331 | static int xpram_ioctl (struct inode *inode, struct file *filp, | 331 | static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
332 | unsigned int cmd, unsigned long arg) | ||
333 | { | 332 | { |
334 | struct hd_geometry __user *geo; | ||
335 | unsigned long size; | 333 | unsigned long size; |
336 | if (cmd != HDIO_GETGEO) | 334 | |
337 | return -EINVAL; | ||
338 | /* | 335 | /* |
339 | * get geometry: we have to fake one... trim the size to a | 336 | * get geometry: we have to fake one... trim the size to a |
340 | * multiple of 64 (32k): tell we have 16 sectors, 4 heads, | 337 | * multiple of 64 (32k): tell we have 16 sectors, 4 heads, |
341 | * whatever cylinders. Tell also that data starts at sector. 4. | 338 | * whatever cylinders. Tell also that data starts at sector. 4. |
342 | */ | 339 | */ |
343 | geo = (struct hd_geometry __user *) arg; | ||
344 | size = (xpram_pages * 8) & ~0x3f; | 340 | size = (xpram_pages * 8) & ~0x3f; |
345 | put_user(size >> 6, &geo->cylinders); | 341 | geo->cylinders = size >> 6; |
346 | put_user(4, &geo->heads); | 342 | geo->heads = 4; |
347 | put_user(16, &geo->sectors); | 343 | geo->sectors = 16; |
348 | put_user(4, &geo->start); | 344 | geo->start = 4; |
349 | return 0; | 345 | return 0; |
350 | } | 346 | } |
351 | 347 | ||
352 | static struct block_device_operations xpram_devops = | 348 | static struct block_device_operations xpram_devops = |
353 | { | 349 | { |
354 | .owner = THIS_MODULE, | 350 | .owner = THIS_MODULE, |
355 | .ioctl = xpram_ioctl, | 351 | .getgeo = xpram_getgeo, |
356 | }; | 352 | }; |
357 | 353 | ||
358 | /* | 354 | /* |