diff options
author | Arnd Bergmann <arnd@arndb.de> | 2007-10-09 07:23:52 -0400 |
---|---|---|
committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2007-10-10 03:26:00 -0400 |
commit | 7199d4cdd8485f802df3e1bc131245c69009b9a4 (patch) | |
tree | d4a0a46192724a2e5ce25beb80cc5de40dcb6c8a /block/compat_ioctl.c | |
parent | f58c4c0a17e500e767473598b3deafaa1d64051d (diff) |
compat_ioctl: add compat_blkdev_driver_ioctl()
Handle those blockdev ioctl calls that are compatible
directly from the compat_blkdev_ioctl() function, instead
of having to go through the compat_ioctl hash lookup.
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 | 121 |
1 files changed, 120 insertions, 1 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index d20fdb436f68..500cc9e761c1 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -40,6 +40,122 @@ static int compat_put_u64(unsigned long arg, u64 val) | |||
40 | #define BLKBSZSET_32 _IOW(0x12, 113, int) | 40 | #define BLKBSZSET_32 _IOW(0x12, 113, int) |
41 | #define BLKGETSIZE64_32 _IOR(0x12, 114, int) | 41 | #define BLKGETSIZE64_32 _IOR(0x12, 114, int) |
42 | 42 | ||
43 | static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, | ||
44 | struct gendisk *disk, unsigned cmd, unsigned long arg) | ||
45 | { | ||
46 | int ret; | ||
47 | |||
48 | switch (arg) { | ||
49 | /* | ||
50 | * No handler required for the ones below, we just need to | ||
51 | * convert arg to a 64 bit pointer. | ||
52 | */ | ||
53 | case BLKSECTSET: | ||
54 | /* | ||
55 | * 0x03 -- HD/IDE ioctl's used by hdparm and friends. | ||
56 | * Some need translations, these do not. | ||
57 | */ | ||
58 | case HDIO_GET_IDENTITY: | ||
59 | case HDIO_DRIVE_TASK: | ||
60 | case HDIO_DRIVE_CMD: | ||
61 | case HDIO_SCAN_HWIF: | ||
62 | /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */ | ||
63 | case 0x330: | ||
64 | /* 0x02 -- Floppy ioctls */ | ||
65 | case FDMSGON: | ||
66 | case FDMSGOFF: | ||
67 | case FDSETEMSGTRESH: | ||
68 | case FDFLUSH: | ||
69 | case FDWERRORCLR: | ||
70 | case FDSETMAXERRS: | ||
71 | case FDGETMAXERRS: | ||
72 | case FDGETDRVTYP: | ||
73 | case FDEJECT: | ||
74 | case FDCLRPRM: | ||
75 | case FDFMTBEG: | ||
76 | case FDFMTEND: | ||
77 | case FDRESET: | ||
78 | case FDTWADDLE: | ||
79 | case FDFMTTRK: | ||
80 | case FDRAWCMD: | ||
81 | /* CDROM stuff */ | ||
82 | case CDROMPAUSE: | ||
83 | case CDROMRESUME: | ||
84 | case CDROMPLAYMSF: | ||
85 | case CDROMPLAYTRKIND: | ||
86 | case CDROMREADTOCHDR: | ||
87 | case CDROMREADTOCENTRY: | ||
88 | case CDROMSTOP: | ||
89 | case CDROMSTART: | ||
90 | case CDROMEJECT: | ||
91 | case CDROMVOLCTRL: | ||
92 | case CDROMSUBCHNL: | ||
93 | case CDROMMULTISESSION: | ||
94 | case CDROM_GET_MCN: | ||
95 | case CDROMRESET: | ||
96 | case CDROMVOLREAD: | ||
97 | case CDROMSEEK: | ||
98 | case CDROMPLAYBLK: | ||
99 | case CDROMCLOSETRAY: | ||
100 | case CDROM_DISC_STATUS: | ||
101 | case CDROM_CHANGER_NSLOTS: | ||
102 | case CDROM_GET_CAPABILITY: | ||
103 | /* Ignore cdrom.h about these next 5 ioctls, they absolutely do | ||
104 | * not take a struct cdrom_read, instead they take a struct cdrom_msf | ||
105 | * which is compatible. | ||
106 | */ | ||
107 | case CDROMREADMODE2: | ||
108 | case CDROMREADMODE1: | ||
109 | case CDROMREADRAW: | ||
110 | case CDROMREADCOOKED: | ||
111 | case CDROMREADALL: | ||
112 | /* DVD ioctls */ | ||
113 | case DVD_READ_STRUCT: | ||
114 | case DVD_WRITE_STRUCT: | ||
115 | case DVD_AUTH: | ||
116 | arg = (unsigned long)compat_ptr(arg); | ||
117 | /* These intepret arg as an unsigned long, not as a pointer, | ||
118 | * so we must not do compat_ptr() conversion. */ | ||
119 | case HDIO_SET_MULTCOUNT: | ||
120 | case HDIO_SET_UNMASKINTR: | ||
121 | case HDIO_SET_KEEPSETTINGS: | ||
122 | case HDIO_SET_32BIT: | ||
123 | case HDIO_SET_NOWERR: | ||
124 | case HDIO_SET_DMA: | ||
125 | case HDIO_SET_PIO_MODE: | ||
126 | case HDIO_SET_NICE: | ||
127 | case HDIO_SET_WCACHE: | ||
128 | case HDIO_SET_ACOUSTIC: | ||
129 | case HDIO_SET_BUSSTATE: | ||
130 | case HDIO_SET_ADDRESS: | ||
131 | case CDROMEJECT_SW: | ||
132 | case CDROM_SET_OPTIONS: | ||
133 | case CDROM_CLEAR_OPTIONS: | ||
134 | case CDROM_SELECT_SPEED: | ||
135 | case CDROM_SELECT_DISC: | ||
136 | case CDROM_MEDIA_CHANGED: | ||
137 | case CDROM_DRIVE_STATUS: | ||
138 | case CDROM_LOCKDOOR: | ||
139 | case CDROM_DEBUG: | ||
140 | break; | ||
141 | default: | ||
142 | /* unknown ioctl number */ | ||
143 | return -ENOIOCTLCMD; | ||
144 | } | ||
145 | |||
146 | if (disk->fops->unlocked_ioctl) | ||
147 | return disk->fops->unlocked_ioctl(file, cmd, arg); | ||
148 | |||
149 | if (disk->fops->ioctl) { | ||
150 | lock_kernel(); | ||
151 | ret = disk->fops->ioctl(inode, file, cmd, arg); | ||
152 | unlock_kernel(); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | return -ENOTTY; | ||
157 | } | ||
158 | |||
43 | static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, | 159 | static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, |
44 | struct block_device *bdev, | 160 | struct block_device *bdev, |
45 | unsigned cmd, unsigned long arg) | 161 | unsigned cmd, unsigned long arg) |
@@ -117,5 +233,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
117 | ret = disk->fops->compat_ioctl(file, cmd, arg); | 233 | ret = disk->fops->compat_ioctl(file, cmd, arg); |
118 | unlock_kernel(); | 234 | unlock_kernel(); |
119 | 235 | ||
120 | return ret; | 236 | if (ret != -ENOIOCTLCMD) |
237 | return ret; | ||
238 | |||
239 | return compat_blkdev_driver_ioctl(inode, file, disk, cmd, arg); | ||
121 | } | 240 | } |