diff options
author | Arnd Bergmann <arnd@arndb.de> | 2007-10-09 07:23:55 -0400 |
---|---|---|
committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2007-10-10 03:26:00 -0400 |
commit | 9617db085c119879cd371e3212806a15596e121a (patch) | |
tree | 17db98cd2d195105124f1d8a96f249ca073918cd /block/compat_ioctl.c | |
parent | 171044d449611c6e5040b37210ff6aba47f33ee4 (diff) |
compat_ioctl: move hdio calls to block/compat_ioctl.c
These are common to multiple block drivers, so they should
be handled by the block layer.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/compat_ioctl.c')
-rw-r--r-- | block/compat_ioctl.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 219b7e76e8ad..5c6dafaad938 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -36,6 +36,62 @@ static int compat_put_u64(unsigned long arg, u64 val) | |||
36 | return put_user(val, (compat_u64 __user *)compat_ptr(arg)); | 36 | return put_user(val, (compat_u64 __user *)compat_ptr(arg)); |
37 | } | 37 | } |
38 | 38 | ||
39 | struct compat_hd_geometry { | ||
40 | unsigned char heads; | ||
41 | unsigned char sectors; | ||
42 | unsigned short cylinders; | ||
43 | u32 start; | ||
44 | }; | ||
45 | |||
46 | static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev, | ||
47 | struct compat_hd_geometry __user *ugeo) | ||
48 | { | ||
49 | struct hd_geometry geo; | ||
50 | int ret; | ||
51 | |||
52 | if (!ugeo) | ||
53 | return -EINVAL; | ||
54 | if (!disk->fops->getgeo) | ||
55 | return -ENOTTY; | ||
56 | |||
57 | /* | ||
58 | * We need to set the startsect first, the driver may | ||
59 | * want to override it. | ||
60 | */ | ||
61 | geo.start = get_start_sect(bdev); | ||
62 | ret = disk->fops->getgeo(bdev, &geo); | ||
63 | if (ret) | ||
64 | return ret; | ||
65 | |||
66 | ret = copy_to_user(ugeo, &geo, 4); | ||
67 | ret |= __put_user(geo.start, &ugeo->start); | ||
68 | if (ret) | ||
69 | ret = -EFAULT; | ||
70 | |||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | static int compat_hdio_ioctl(struct inode *inode, struct file *file, | ||
75 | struct gendisk *disk, unsigned int cmd, unsigned long arg) | ||
76 | { | ||
77 | mm_segment_t old_fs = get_fs(); | ||
78 | unsigned long kval; | ||
79 | unsigned int __user *uvp; | ||
80 | int error; | ||
81 | |||
82 | set_fs(KERNEL_DS); | ||
83 | error = blkdev_driver_ioctl(inode, file, disk, | ||
84 | cmd, (unsigned long)(&kval)); | ||
85 | set_fs(old_fs); | ||
86 | |||
87 | if (error == 0) { | ||
88 | uvp = compat_ptr(arg); | ||
89 | if (put_user(kval, uvp)) | ||
90 | error = -EFAULT; | ||
91 | } | ||
92 | return error; | ||
93 | } | ||
94 | |||
39 | #define BLKBSZGET_32 _IOR(0x12, 112, int) | 95 | #define BLKBSZGET_32 _IOR(0x12, 112, int) |
40 | #define BLKBSZSET_32 _IOW(0x12, 113, int) | 96 | #define BLKBSZSET_32 _IOW(0x12, 113, int) |
41 | #define BLKGETSIZE64_32 _IOR(0x12, 114, int) | 97 | #define BLKGETSIZE64_32 _IOR(0x12, 114, int) |
@@ -93,6 +149,18 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, | |||
93 | int ret; | 149 | int ret; |
94 | 150 | ||
95 | switch (arg) { | 151 | switch (arg) { |
152 | case HDIO_GET_UNMASKINTR: | ||
153 | case HDIO_GET_MULTCOUNT: | ||
154 | case HDIO_GET_KEEPSETTINGS: | ||
155 | case HDIO_GET_32BIT: | ||
156 | case HDIO_GET_NOWERR: | ||
157 | case HDIO_GET_DMA: | ||
158 | case HDIO_GET_NICE: | ||
159 | case HDIO_GET_WCACHE: | ||
160 | case HDIO_GET_ACOUSTIC: | ||
161 | case HDIO_GET_ADDRESS: | ||
162 | case HDIO_GET_BUSSTATE: | ||
163 | return compat_hdio_ioctl(inode, file, disk, cmd, arg); | ||
96 | /* | 164 | /* |
97 | * No handler required for the ones below, we just need to | 165 | * No handler required for the ones below, we just need to |
98 | * convert arg to a 64 bit pointer. | 166 | * convert arg to a 64 bit pointer. |
@@ -266,6 +334,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
266 | struct gendisk *disk = bdev->bd_disk; | 334 | struct gendisk *disk = bdev->bd_disk; |
267 | 335 | ||
268 | switch (cmd) { | 336 | switch (cmd) { |
337 | case HDIO_GETGEO: | ||
338 | return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); | ||
269 | case BLKFLSBUF: | 339 | case BLKFLSBUF: |
270 | case BLKROSET: | 340 | case BLKROSET: |
271 | /* | 341 | /* |