ioctl32.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:29k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  3.  *
  4.  * Copyright (C) 2000 Silicon Graphics, Inc.
  5.  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
  6.  * Copyright (C) 2000 Ralf Baechle
  7.  *
  8.  * Mostly stolen from the sparc64 ioctl32 implementation.
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/types.h>
  12. #include <linux/kernel.h>
  13. #include <linux/sched.h>
  14. #include <linux/if.h>
  15. #include <linux/mm.h>
  16. #include <linux/mtio.h>
  17. #include <linux/init.h>
  18. #include <linux/file.h>
  19. #include <linux/fs.h>
  20. #include <linux/ppp_defs.h>
  21. #include <linux/if_ppp.h>
  22. #include <linux/if_pppox.h>
  23. #include <linux/cdrom.h>
  24. #include <linux/loop.h>
  25. #include <linux/vt.h>
  26. #include <linux/kd.h>
  27. #include <linux/netdevice.h>
  28. #include <linux/route.h>
  29. #include <linux/hdreg.h>
  30. #include <linux/blkpg.h>
  31. #include <linux/blkdev.h>
  32. #include <linux/elevator.h>
  33. #include <linux/auto_fs.h>
  34. #include <linux/ext2_fs.h>
  35. #include <linux/raid/md_u.h>
  36. #include <scsi/scsi.h>
  37. #undef __KERNEL__ /* This file was born to be ugly ...  */
  38. #include <scsi/scsi_ioctl.h>
  39. #define __KERNEL__
  40. #include <asm/types.h>
  41. #include <asm/uaccess.h>
  42. #include <linux/rtc.h>
  43. long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
  44. static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
  45. {
  46. mm_segment_t old_fs = get_fs();
  47. int err;
  48. unsigned long val;
  49. set_fs (KERNEL_DS);
  50. err = sys_ioctl(fd, cmd, (unsigned long)&val);
  51. set_fs (old_fs);
  52. if (!err && put_user((unsigned int) val, (u32 *)arg))
  53. return -EFAULT;
  54. return err;
  55. }
  56. static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
  57. {
  58. mm_segment_t old_fs = get_fs();
  59. int err;
  60. unsigned long val;
  61. if (get_user(val, (u32 *)arg))
  62. return -EFAULT;
  63. set_fs(KERNEL_DS);
  64. err = sys_ioctl(fd, cmd, (unsigned long)&val);
  65. set_fs (old_fs);
  66. if (!err && put_user(val, (u32 *)arg))
  67. return -EFAULT;
  68. return err;
  69. }
  70. #define A(__x) ((unsigned long)(__x))
  71. struct timeval32 {
  72. int tv_sec;
  73. int tv_usec;
  74. };
  75. static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
  76. {
  77. struct timeval32 *up = (struct timeval32 *)arg;
  78. struct timeval ktv;
  79. mm_segment_t old_fs = get_fs();
  80. int err;
  81. set_fs(KERNEL_DS);
  82. err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
  83. set_fs(old_fs);
  84. if (!err) {
  85. err = put_user(ktv.tv_sec, &up->tv_sec);
  86. err |= __put_user(ktv.tv_usec, &up->tv_usec);
  87. }
  88. return err;
  89. }
  90. #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
  91. #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
  92. #define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
  93. #define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
  94. struct ifmap32 {
  95. unsigned int mem_start;
  96. unsigned int mem_end;
  97. unsigned short base_addr;
  98. unsigned char irq;
  99. unsigned char dma;
  100. unsigned char port;
  101. };
  102. struct ifreq32 {
  103. #define IFHWADDRLEN     6
  104. #define IFNAMSIZ        16
  105.         union {
  106.                 char    ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
  107.         } ifr_ifrn;
  108.         union {
  109.                 struct  sockaddr ifru_addr;
  110.                 struct  sockaddr ifru_dstaddr;
  111.                 struct  sockaddr ifru_broadaddr;
  112.                 struct  sockaddr ifru_netmask;
  113.                 struct  sockaddr ifru_hwaddr;
  114.                 short   ifru_flags;
  115.                 int     ifru_ivalue;
  116.                 int     ifru_mtu;
  117.                 struct  ifmap32 ifru_map;
  118.                 char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
  119. char ifru_newname[IFNAMSIZ];
  120.                 __kernel_caddr_t32 ifru_data;
  121.         } ifr_ifru;
  122. };
  123. struct ifconf32 {
  124.         int     ifc_len;                        /* size of buffer       */
  125.         __kernel_caddr_t32  ifcbuf;
  126. };
  127. #ifdef CONFIG_NET
  128. static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
  129. {
  130. struct ireq32 *uir32 = (struct ireq32 *)arg;
  131. struct net_device *dev;
  132. struct ifreq32 ifr32;
  133. if (copy_from_user(&ifr32, uir32, sizeof(struct ifreq32)))
  134. return -EFAULT;
  135. read_lock(&dev_base_lock);
  136. dev = __dev_get_by_index(ifr32.ifr_ifindex);
  137. if (!dev) {
  138. read_unlock(&dev_base_lock);
  139. return -ENODEV;
  140. }
  141. strcpy(ifr32.ifr_name, dev->name);
  142. read_unlock(&dev_base_lock);
  143. if (copy_to_user(uir32, &ifr32, sizeof(struct ifreq32)))
  144.     return -EFAULT;
  145. return 0;
  146. }
  147. static inline int dev_ifconf(unsigned int fd, unsigned int cmd,
  148.      unsigned long arg)
  149. {
  150. struct ioconf32 *uifc32 = (struct ioconf32 *)arg;
  151. struct ifconf32 ifc32;
  152. struct ifconf ifc;
  153. struct ifreq32 *ifr32;
  154. struct ifreq *ifr;
  155. mm_segment_t old_fs;
  156. int len;
  157. int err;
  158. if (copy_from_user(&ifc32, uifc32, sizeof(struct ifconf32)))
  159. return -EFAULT;
  160. if(ifc32.ifcbuf == 0) {
  161. ifc32.ifc_len = 0;
  162. ifc.ifc_len = 0;
  163. ifc.ifc_buf = NULL;
  164. } else {
  165. ifc.ifc_len = ((ifc32.ifc_len / sizeof (struct ifreq32))) *
  166. sizeof (struct ifreq);
  167. ifc.ifc_buf = kmalloc (ifc.ifc_len, GFP_KERNEL);
  168. if (!ifc.ifc_buf)
  169. return -ENOMEM;
  170. }
  171. ifr = ifc.ifc_req;
  172. ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
  173. len = ifc32.ifc_len / sizeof (struct ifreq32);
  174. while (len--) {
  175. if (copy_from_user(ifr++, ifr32++, sizeof (struct ifreq32))) {
  176. err = -EFAULT;
  177. goto out;
  178. }
  179. }
  180. old_fs = get_fs();
  181. set_fs (KERNEL_DS);
  182. err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
  183. set_fs (old_fs);
  184. if (err)
  185. goto out;
  186. ifr = ifc.ifc_req;
  187. ifr32 = (struct ifreq32 *)A(ifc32.ifcbuf);
  188. len = ifc.ifc_len / sizeof (struct ifreq);
  189. ifc32.ifc_len = len * sizeof (struct ifreq32);
  190. while (len--) {
  191. if (copy_to_user(ifr32++, ifr++, sizeof (struct ifreq32))) {
  192. err = -EFAULT;
  193. goto out;
  194. }
  195. }
  196. if (copy_to_user(uifc32, &ifc32, sizeof(struct ifconf32))) {
  197. err = -EFAULT;
  198. goto out;
  199. }
  200. out:
  201. if(ifc.ifc_buf != NULL)
  202. kfree (ifc.ifc_buf);
  203. return err;
  204. }
  205. static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
  206. {
  207. struct ifreq ifr;
  208. mm_segment_t old_fs;
  209. int err;
  210. switch (cmd) {
  211. case SIOCSIFMAP:
  212. err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name));
  213. err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
  214. err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
  215. err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
  216. err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
  217. err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
  218. err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
  219. if (err)
  220. return -EFAULT;
  221. break;
  222. default:
  223. if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
  224. return -EFAULT;
  225. break;
  226. }
  227. old_fs = get_fs();
  228. set_fs (KERNEL_DS);
  229. err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
  230. set_fs (old_fs);
  231. if (!err) {
  232. switch (cmd) {
  233. case SIOCGIFFLAGS:
  234. case SIOCGIFMETRIC:
  235. case SIOCGIFMTU:
  236. case SIOCGIFMEM:
  237. case SIOCGIFHWADDR:
  238. case SIOCGIFINDEX:
  239. case SIOCGIFADDR:
  240. case SIOCGIFBRDADDR:
  241. case SIOCGIFDSTADDR:
  242. case SIOCGIFNETMASK:
  243. case SIOCGIFTXQLEN:
  244. if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
  245. return -EFAULT;
  246. break;
  247. case SIOCGIFMAP:
  248. err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
  249. err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
  250. err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end));
  251. err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr));
  252. err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
  253. err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
  254. err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
  255. if (err)
  256. err = -EFAULT;
  257. break;
  258. }
  259. }
  260. return err;
  261. }
  262. struct rtentry32
  263. {
  264. unsigned int rt_pad1;
  265. struct sockaddr rt_dst; /* target address */
  266. struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
  267. struct sockaddr rt_genmask; /* target network mask (IP) */
  268. unsigned short rt_flags;
  269. short rt_pad2;
  270. unsigned int rt_pad3;
  271. unsigned int rt_pad4;
  272. short rt_metric; /* +1 for binary compatibility! */
  273. unsigned int rt_dev; /* forcing the device at add */
  274. unsigned int rt_mtu; /* per route MTU/Window  */
  275. #ifndef __KERNEL__
  276. #define rt_mss rt_mtu /* Compatibility :-(            */
  277. #endif
  278. unsigned int rt_window; /* Window clamping  */
  279. unsigned short rt_irtt; /* Initial RTT */
  280. };
  281. static inline int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
  282. {
  283. struct rtentry32 *ur = (struct rtentry32 *)arg;
  284. struct rtentry r;
  285. char devname[16];
  286. u32 rtdev;
  287. int ret;
  288. mm_segment_t old_fs = get_fs();
  289. ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr));
  290. ret |= __get_user (r.rt_flags, &(ur->rt_flags));
  291. ret |= __get_user (r.rt_metric, &(ur->rt_metric));
  292. ret |= __get_user (r.rt_mtu, &(ur->rt_mtu));
  293. ret |= __get_user (r.rt_window, &(ur->rt_window));
  294. ret |= __get_user (r.rt_irtt, &(ur->rt_irtt));
  295. ret |= __get_user (rtdev, &(ur->rt_dev));
  296. if (rtdev) {
  297. ret |= copy_from_user (devname, (char *)A(rtdev), 15);
  298. r.rt_dev = devname; devname[15] = 0;
  299. } else
  300. r.rt_dev = 0;
  301. if (ret)
  302. return -EFAULT;
  303. set_fs (KERNEL_DS);
  304. ret = sys_ioctl (fd, cmd, (long)&r);
  305. set_fs (old_fs);
  306. return ret;
  307. }
  308. #endif /* CONFIG_NET */
  309. static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
  310. {
  311. /* These are just misnamed, they actually get/put from/to user an int */
  312. switch (cmd) {
  313. case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break;
  314. case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break;
  315. case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break;
  316. case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break;
  317. }
  318. return sys_ioctl(fd, cmd, arg);
  319. }
  320. struct hd_geometry32 {
  321. unsigned char heads;
  322. unsigned char sectors;
  323. unsigned short cylinders;
  324. u32 start;
  325. };
  326. static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
  327. {
  328. mm_segment_t old_fs = get_fs();
  329. struct hd_geometry geo;
  330. int err;
  331. set_fs (KERNEL_DS);
  332. err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
  333. set_fs (old_fs);
  334. if (!err) {
  335. err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
  336. err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
  337. }
  338. return err ? -EFAULT : 0;
  339. }
  340. static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
  341. {
  342. mm_segment_t old_fs = get_fs();
  343. unsigned long kval;
  344. unsigned int *uvp;
  345. int error;
  346. set_fs(KERNEL_DS);
  347. error = sys_ioctl(fd, cmd, (long)&kval);
  348. set_fs(old_fs);
  349. if (error == 0) {
  350. uvp = (unsigned int *)arg;
  351. if (put_user(kval, uvp))
  352. error = -EFAULT;
  353. }
  354. return error;
  355. }
  356. static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
  357. {
  358. return -EINVAL;
  359. }
  360. struct blkpg_ioctl_arg32 {
  361. int op;
  362. int flags;
  363. int datalen;
  364. u32 data;
  365. };
  366. static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd,
  367.                              struct blkpg_ioctl_arg32 *arg)
  368. {
  369. struct blkpg_ioctl_arg a;
  370. struct blkpg_partition p;
  371. int err;
  372. mm_segment_t old_fs = get_fs();
  373. err = get_user(a.op, &arg->op);
  374. err |= __get_user(a.flags, &arg->flags);
  375. err |= __get_user(a.datalen, &arg->datalen);
  376. err |= __get_user((long)a.data, &arg->data);
  377. if (err) return err;
  378. switch (a.op) {
  379. case BLKPG_ADD_PARTITION:
  380. case BLKPG_DEL_PARTITION:
  381. if (a.datalen < sizeof(struct blkpg_partition))
  382. return -EINVAL;
  383.                 if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
  384. return -EFAULT;
  385. a.data = &p;
  386. set_fs (KERNEL_DS);
  387. err = sys_ioctl(fd, cmd, (unsigned long)&a);
  388. set_fs (old_fs);
  389. default:
  390. return -EINVAL;
  391. }
  392. return err;
  393. }
  394. struct mtget32 {
  395. __u32 mt_type;
  396. __u32 mt_resid;
  397. __u32 mt_dsreg;
  398. __u32 mt_gstat;
  399. __u32 mt_erreg;
  400. __kernel_daddr_t32 mt_fileno;
  401. __kernel_daddr_t32 mt_blkno;
  402. };
  403. #define MTIOCGET32 _IOR('m', 2, struct mtget32)
  404. struct mtpos32 {
  405. __u32 mt_blkno;
  406. };
  407. #define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
  408. struct mtconfiginfo32 {
  409. __u32 mt_type;
  410. __u32 ifc_type;
  411. __u16 irqnr;
  412. __u16 dmanr;
  413. __u16 port;
  414. __u32 debug;
  415. __u32 have_dens:1;
  416. __u32 have_bsf:1;
  417. __u32 have_fsr:1;
  418. __u32 have_bsr:1;
  419. __u32 have_eod:1;
  420. __u32 have_seek:1;
  421. __u32 have_tell:1;
  422. __u32 have_ras1:1;
  423. __u32 have_ras2:1;
  424. __u32 have_ras3:1;
  425. __u32 have_qfa:1;
  426. __u32 pad1:5;
  427. char reserved[10];
  428. };
  429. #define MTIOCGETCONFIG32 _IOR('m', 4, struct mtconfiginfo32)
  430. #define MTIOCSETCONFIG32 _IOW('m', 5, struct mtconfiginfo32)
  431. static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
  432. {
  433. mm_segment_t old_fs = get_fs();
  434. struct mtconfiginfo info;
  435. struct mtget get;
  436. struct mtpos pos;
  437. unsigned long kcmd;
  438. void *karg;
  439. int err = 0;
  440. switch(cmd) {
  441. case MTIOCPOS32:
  442. kcmd = MTIOCPOS;
  443. karg = &pos;
  444. break;
  445. case MTIOCGET32:
  446. kcmd = MTIOCGET;
  447. karg = &get;
  448. break;
  449. case MTIOCGETCONFIG32:
  450. kcmd = MTIOCGETCONFIG;
  451. karg = &info;
  452. break;
  453. case MTIOCSETCONFIG32:
  454. kcmd = MTIOCSETCONFIG;
  455. karg = &info;
  456. err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
  457. err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
  458. err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
  459. err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
  460. err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
  461. err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
  462. err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
  463.      (char *)&((struct mtconfiginfo32 *)arg)->debug
  464.      + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
  465. if (err)
  466. return -EFAULT;
  467. break;
  468. default:
  469. do {
  470. static int count = 0;
  471. if (++count <= 20)
  472. printk("mt_ioctl: Unknown cmd fd(%d) "
  473.        "cmd(%08x) arg(%08x)n",
  474.        (int)fd, (unsigned int)cmd, (unsigned int)arg);
  475. } while(0);
  476. return -EINVAL;
  477. }
  478. set_fs (KERNEL_DS);
  479. err = sys_ioctl (fd, kcmd, (unsigned long)karg);
  480. set_fs (old_fs);
  481. if (err)
  482. return err;
  483. switch (cmd) {
  484. case MTIOCPOS32:
  485. err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
  486. break;
  487. case MTIOCGET32:
  488. err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
  489. err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
  490. err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
  491. err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
  492. err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
  493. err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
  494. err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
  495. break;
  496. case MTIOCGETCONFIG32:
  497. err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
  498. err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
  499. err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
  500. err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
  501. err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
  502. err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
  503. err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
  504.         + sizeof(((struct mtconfiginfo32 *)arg)->debug),
  505.    (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
  506. break;
  507. case MTIOCSETCONFIG32:
  508. break;
  509. }
  510. return err ? -EFAULT: 0;
  511. }
  512. #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
  513. static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
  514. {
  515. return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
  516. }
  517. struct ioctl32_handler {
  518. unsigned int cmd;
  519. int (*function)(unsigned int, unsigned int, unsigned long);
  520. };
  521. struct ioctl32_list {
  522. struct ioctl32_handler handler;
  523. struct ioctl32_list *next;
  524. };
  525. #define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 }
  526. #define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 }
  527. static struct ioctl32_list ioctl32_handler_table[] = {
  528. IOCTL32_DEFAULT(TCGETA),
  529. IOCTL32_DEFAULT(TCSETA),
  530. IOCTL32_DEFAULT(TCSETAW),
  531. IOCTL32_DEFAULT(TCSETAF),
  532. IOCTL32_DEFAULT(TCSBRK),
  533. IOCTL32_DEFAULT(TCXONC),
  534. IOCTL32_DEFAULT(TCFLSH),
  535. IOCTL32_DEFAULT(TCGETS),
  536. IOCTL32_DEFAULT(TCSETS),
  537. IOCTL32_DEFAULT(TCSETSW),
  538. IOCTL32_DEFAULT(TCSETSF),
  539. IOCTL32_DEFAULT(TIOCLINUX),
  540. IOCTL32_DEFAULT(TIOCGETD),
  541. IOCTL32_DEFAULT(TIOCSETD),
  542. IOCTL32_DEFAULT(TIOCEXCL),
  543. IOCTL32_DEFAULT(TIOCNXCL),
  544. IOCTL32_DEFAULT(TIOCCONS),
  545. IOCTL32_DEFAULT(TIOCGSOFTCAR),
  546. IOCTL32_DEFAULT(TIOCSSOFTCAR),
  547. IOCTL32_DEFAULT(TIOCSWINSZ),
  548. IOCTL32_DEFAULT(TIOCGWINSZ),
  549. IOCTL32_DEFAULT(TIOCMGET),
  550. IOCTL32_DEFAULT(TIOCMBIC),
  551. IOCTL32_DEFAULT(TIOCMBIS),
  552. IOCTL32_DEFAULT(TIOCMSET),
  553. IOCTL32_DEFAULT(TIOCPKT),
  554. IOCTL32_DEFAULT(TIOCNOTTY),
  555. IOCTL32_DEFAULT(TIOCSTI),
  556. IOCTL32_DEFAULT(TIOCOUTQ),
  557. IOCTL32_DEFAULT(TIOCSPGRP),
  558. IOCTL32_DEFAULT(TIOCGPGRP),
  559. IOCTL32_DEFAULT(TIOCSCTTY),
  560. IOCTL32_DEFAULT(TIOCGPTN),
  561. IOCTL32_DEFAULT(TIOCSPTLCK),
  562. IOCTL32_DEFAULT(TIOCGSERIAL),
  563. IOCTL32_DEFAULT(TIOCSSERIAL),
  564. IOCTL32_DEFAULT(TIOCSERGETLSR),
  565. IOCTL32_DEFAULT(FIOCLEX),
  566. IOCTL32_DEFAULT(FIONCLEX),
  567. IOCTL32_DEFAULT(FIOASYNC),
  568. IOCTL32_DEFAULT(FIONBIO),
  569. IOCTL32_DEFAULT(FIONREAD),
  570. /* Big K */
  571. IOCTL32_DEFAULT(PIO_FONT),
  572. IOCTL32_DEFAULT(GIO_FONT),
  573. IOCTL32_DEFAULT(KDSIGACCEPT),
  574. IOCTL32_DEFAULT(KDGETKEYCODE),
  575. IOCTL32_DEFAULT(KDSETKEYCODE),
  576. IOCTL32_DEFAULT(KIOCSOUND),
  577. IOCTL32_DEFAULT(KDMKTONE),
  578. IOCTL32_DEFAULT(KDGKBTYPE),
  579. IOCTL32_DEFAULT(KDSETMODE),
  580. IOCTL32_DEFAULT(KDGETMODE),
  581. IOCTL32_DEFAULT(KDSKBMODE),
  582. IOCTL32_DEFAULT(KDGKBMODE),
  583. IOCTL32_DEFAULT(KDSKBMETA),
  584. IOCTL32_DEFAULT(KDGKBMETA),
  585. IOCTL32_DEFAULT(KDGKBENT),
  586. IOCTL32_DEFAULT(KDSKBENT),
  587. IOCTL32_DEFAULT(KDGKBSENT),
  588. IOCTL32_DEFAULT(KDSKBSENT),
  589. IOCTL32_DEFAULT(KDGKBDIACR),
  590. IOCTL32_DEFAULT(KDSKBDIACR),
  591. IOCTL32_DEFAULT(KDGKBLED),
  592. IOCTL32_DEFAULT(KDSKBLED),
  593. IOCTL32_DEFAULT(KDGETLED),
  594. IOCTL32_DEFAULT(KDSETLED),
  595. IOCTL32_DEFAULT(GIO_SCRNMAP),
  596. IOCTL32_DEFAULT(PIO_SCRNMAP),
  597. IOCTL32_DEFAULT(GIO_UNISCRNMAP),
  598. IOCTL32_DEFAULT(PIO_UNISCRNMAP),
  599. IOCTL32_DEFAULT(PIO_FONTRESET),
  600. IOCTL32_DEFAULT(PIO_UNIMAPCLR),
  601. /* Big S */
  602. IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN),
  603. IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK),
  604. IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK),
  605. IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY),
  606. IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_ENABLE),
  607. IOCTL32_DEFAULT(SCSI_IOCTL_TAGGED_DISABLE),
  608. IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER),
  609. IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND),
  610. /* Big V */
  611. IOCTL32_DEFAULT(VT_SETMODE),
  612. IOCTL32_DEFAULT(VT_GETMODE),
  613. IOCTL32_DEFAULT(VT_GETSTATE),
  614. IOCTL32_DEFAULT(VT_OPENQRY),
  615. IOCTL32_DEFAULT(VT_ACTIVATE),
  616. IOCTL32_DEFAULT(VT_WAITACTIVE),
  617. IOCTL32_DEFAULT(VT_RELDISP),
  618. IOCTL32_DEFAULT(VT_DISALLOCATE),
  619. IOCTL32_DEFAULT(VT_RESIZE),
  620. IOCTL32_DEFAULT(VT_RESIZEX),
  621. IOCTL32_DEFAULT(VT_LOCKSWITCH),
  622. IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
  623. #ifdef CONFIG_NET
  624. /* Socket level stuff */
  625. IOCTL32_DEFAULT(FIOSETOWN),
  626. IOCTL32_DEFAULT(SIOCSPGRP),
  627. IOCTL32_DEFAULT(FIOGETOWN),
  628. IOCTL32_DEFAULT(SIOCGPGRP),
  629. IOCTL32_DEFAULT(SIOCATMARK),
  630. IOCTL32_DEFAULT(SIOCSIFLINK),
  631. IOCTL32_DEFAULT(SIOCSIFENCAP),
  632. IOCTL32_DEFAULT(SIOCGIFENCAP),
  633. IOCTL32_DEFAULT(SIOCSIFBR),
  634. IOCTL32_DEFAULT(SIOCGIFBR),
  635. IOCTL32_DEFAULT(SIOCSARP),
  636. IOCTL32_DEFAULT(SIOCGARP),
  637. IOCTL32_DEFAULT(SIOCDARP),
  638. IOCTL32_DEFAULT(SIOCSRARP),
  639. IOCTL32_DEFAULT(SIOCGRARP),
  640. IOCTL32_DEFAULT(SIOCDRARP),
  641. IOCTL32_DEFAULT(SIOCADDDLCI),
  642. IOCTL32_DEFAULT(SIOCDELDLCI),
  643. /* SG stuff */
  644. IOCTL32_DEFAULT(SG_SET_TIMEOUT),
  645. IOCTL32_DEFAULT(SG_GET_TIMEOUT),
  646. IOCTL32_DEFAULT(SG_EMULATED_HOST),
  647. IOCTL32_DEFAULT(SG_SET_TRANSFORM),
  648. IOCTL32_DEFAULT(SG_GET_TRANSFORM),
  649. IOCTL32_DEFAULT(SG_SET_RESERVED_SIZE),
  650. IOCTL32_DEFAULT(SG_GET_RESERVED_SIZE),
  651. IOCTL32_DEFAULT(SG_GET_SCSI_ID),
  652. IOCTL32_DEFAULT(SG_SET_FORCE_LOW_DMA),
  653. IOCTL32_DEFAULT(SG_GET_LOW_DMA),
  654. IOCTL32_DEFAULT(SG_SET_FORCE_PACK_ID),
  655. IOCTL32_DEFAULT(SG_GET_PACK_ID),
  656. IOCTL32_DEFAULT(SG_GET_NUM_WAITING),
  657. IOCTL32_DEFAULT(SG_SET_DEBUG),
  658. IOCTL32_DEFAULT(SG_GET_SG_TABLESIZE),
  659. IOCTL32_DEFAULT(SG_GET_COMMAND_Q),
  660. IOCTL32_DEFAULT(SG_SET_COMMAND_Q),
  661. IOCTL32_DEFAULT(SG_GET_VERSION_NUM),
  662. IOCTL32_DEFAULT(SG_NEXT_CMD_LEN),
  663. IOCTL32_DEFAULT(SG_SCSI_RESET),
  664. IOCTL32_DEFAULT(SG_IO),
  665. IOCTL32_DEFAULT(SG_GET_REQUEST_TABLE),
  666. IOCTL32_DEFAULT(SG_SET_KEEP_ORPHAN),
  667. IOCTL32_DEFAULT(SG_GET_KEEP_ORPHAN),
  668. /* PPP stuff */
  669. IOCTL32_DEFAULT(PPPIOCGFLAGS),
  670. IOCTL32_DEFAULT(PPPIOCSFLAGS),
  671. IOCTL32_DEFAULT(PPPIOCGASYNCMAP),
  672. IOCTL32_DEFAULT(PPPIOCSASYNCMAP),
  673. IOCTL32_DEFAULT(PPPIOCGUNIT),
  674. IOCTL32_DEFAULT(PPPIOCGRASYNCMAP),
  675. IOCTL32_DEFAULT(PPPIOCSRASYNCMAP),
  676. IOCTL32_DEFAULT(PPPIOCGMRU),
  677. IOCTL32_DEFAULT(PPPIOCSMRU),
  678. IOCTL32_DEFAULT(PPPIOCSMAXCID),
  679. IOCTL32_DEFAULT(PPPIOCGXASYNCMAP),
  680. IOCTL32_DEFAULT(PPPIOCSXASYNCMAP),
  681. IOCTL32_DEFAULT(PPPIOCXFERUNIT),
  682. IOCTL32_DEFAULT(PPPIOCGNPMODE),
  683. IOCTL32_DEFAULT(PPPIOCSNPMODE),
  684. IOCTL32_DEFAULT(PPPIOCGDEBUG),
  685. IOCTL32_DEFAULT(PPPIOCSDEBUG),
  686. IOCTL32_DEFAULT(PPPIOCNEWUNIT),
  687. IOCTL32_DEFAULT(PPPIOCATTACH),
  688. IOCTL32_DEFAULT(PPPIOCGCHAN),
  689. /* PPPOX */
  690. IOCTL32_DEFAULT(PPPOEIOCSFWD),
  691. IOCTL32_DEFAULT(PPPOEIOCDFWD),
  692. /* CDROM stuff */
  693. IOCTL32_DEFAULT(CDROMPAUSE),
  694. IOCTL32_DEFAULT(CDROMRESUME),
  695. IOCTL32_DEFAULT(CDROMPLAYMSF),
  696. IOCTL32_DEFAULT(CDROMPLAYTRKIND),
  697. IOCTL32_DEFAULT(CDROMREADTOCHDR),
  698. IOCTL32_DEFAULT(CDROMREADTOCENTRY),
  699. IOCTL32_DEFAULT(CDROMSTOP),
  700. IOCTL32_DEFAULT(CDROMSTART),
  701. IOCTL32_DEFAULT(CDROMEJECT),
  702. IOCTL32_DEFAULT(CDROMVOLCTRL),
  703. IOCTL32_DEFAULT(CDROMSUBCHNL),
  704. IOCTL32_DEFAULT(CDROMEJECT_SW),
  705. IOCTL32_DEFAULT(CDROMMULTISESSION),
  706. IOCTL32_DEFAULT(CDROM_GET_MCN),
  707. IOCTL32_DEFAULT(CDROMRESET),
  708. IOCTL32_DEFAULT(CDROMVOLREAD),
  709. IOCTL32_DEFAULT(CDROMSEEK),
  710. IOCTL32_DEFAULT(CDROMPLAYBLK),
  711. IOCTL32_DEFAULT(CDROMCLOSETRAY),
  712. IOCTL32_DEFAULT(CDROM_SET_OPTIONS),
  713. IOCTL32_DEFAULT(CDROM_CLEAR_OPTIONS),
  714. IOCTL32_DEFAULT(CDROM_SELECT_SPEED),
  715. IOCTL32_DEFAULT(CDROM_SELECT_DISC),
  716. IOCTL32_DEFAULT(CDROM_MEDIA_CHANGED),
  717. IOCTL32_DEFAULT(CDROM_DRIVE_STATUS),
  718. IOCTL32_DEFAULT(CDROM_DISC_STATUS),
  719. IOCTL32_DEFAULT(CDROM_CHANGER_NSLOTS),
  720. IOCTL32_DEFAULT(CDROM_LOCKDOOR),
  721. IOCTL32_DEFAULT(CDROM_DEBUG),
  722. IOCTL32_DEFAULT(CDROM_GET_CAPABILITY),
  723. /* DVD ioctls */
  724. IOCTL32_DEFAULT(DVD_READ_STRUCT),
  725. IOCTL32_DEFAULT(DVD_WRITE_STRUCT),
  726. IOCTL32_DEFAULT(DVD_AUTH),
  727. /* Big L */
  728. IOCTL32_DEFAULT(LOOP_SET_FD),
  729. IOCTL32_DEFAULT(LOOP_CLR_FD),
  730. /* And these ioctls need translation */
  731. IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
  732. IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
  733. IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
  734. IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc),
  735. IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc),
  736. IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc),
  737. IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc),
  738. IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc),
  739. IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc),
  740. IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc),
  741. IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc),
  742. IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc),
  743. IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc),
  744. IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc),
  745. IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc),
  746. IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc),
  747. IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc),
  748. IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc),
  749. IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc),
  750. IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc),
  751. IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc),
  752. IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc),
  753. IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc),
  754. IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc),
  755. IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc),
  756. IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc),
  757. IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc),
  758. IOCTL32_HANDLER(SIOCGPPPSTATS, dev_ifsioc),
  759. IOCTL32_HANDLER(SIOCGPPPCSTATS, dev_ifsioc),
  760. IOCTL32_HANDLER(SIOCGPPPVER, dev_ifsioc),
  761. IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc),
  762. IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc),
  763. IOCTL32_HANDLER(SIOCADDRT, routing_ioctl),
  764. IOCTL32_HANDLER(SIOCDELRT, routing_ioctl),
  765. /*
  766.  * Note SIOCRTMSG is no longer, so this is safe and * the user would
  767.  * have seen just an -EINVAL anyways.
  768.  */
  769. IOCTL32_HANDLER(SIOCRTMSG, ret_einval),
  770. IOCTL32_HANDLER(SIOCGSTAMP, do_siocgstamp),
  771. #endif /* CONFIG_NET */
  772. IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
  773. IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
  774. IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
  775. IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
  776. IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls  */
  777. IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
  778. IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
  779. // HDIO_OBSOLETE_IDENTITY
  780. IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
  781. IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans),
  782. IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans),
  783. IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans),
  784. IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans),
  785. IOCTL32_DEFAULT(HDIO_GET_IDENTITY),
  786. IOCTL32_DEFAULT(HDIO_DRIVE_RESET),
  787. // HDIO_TRISTATE_HWIF /* not implemented */
  788. // HDIO_DRIVE_TASK /* To do, need specs */
  789. IOCTL32_DEFAULT(HDIO_DRIVE_CMD),
  790. IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT),
  791. IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR),
  792. IOCTL32_DEFAULT(HDIO_SET_KEEPSETTINGS),
  793. IOCTL32_DEFAULT(HDIO_SET_32BIT),
  794. IOCTL32_DEFAULT(HDIO_SET_NOWERR),
  795. IOCTL32_DEFAULT(HDIO_SET_DMA),
  796. IOCTL32_DEFAULT(HDIO_SET_PIO_MODE),
  797. IOCTL32_DEFAULT(HDIO_SCAN_HWIF),
  798. IOCTL32_DEFAULT(HDIO_SET_NICE),
  799. //HDIO_UNREGISTER_HWIF
  800. IOCTL32_DEFAULT(BLKROSET), /* fs.h ioctls  */
  801. IOCTL32_DEFAULT(BLKROGET),
  802. IOCTL32_DEFAULT(BLKRRPART),
  803. IOCTL32_HANDLER(BLKGETSIZE, w_long),
  804. IOCTL32_DEFAULT(BLKFLSBUF),
  805. IOCTL32_DEFAULT(BLKRASET),
  806. IOCTL32_HANDLER(BLKRAGET, w_long),
  807. IOCTL32_DEFAULT(BLKFRASET),
  808. IOCTL32_HANDLER(BLKFRAGET, w_long),
  809. IOCTL32_DEFAULT(BLKSECTSET),
  810. IOCTL32_HANDLER(BLKSECTGET, w_long),
  811. IOCTL32_DEFAULT(BLKSSZGET),
  812. IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
  813. IOCTL32_DEFAULT(BLKELVGET),
  814. IOCTL32_DEFAULT(BLKELVSET),
  815. IOCTL32_DEFAULT(BLKBSZGET),
  816. IOCTL32_DEFAULT(BLKBSZSET),
  817. #ifdef CONFIG_MD
  818. /* status */
  819. IOCTL32_DEFAULT(RAID_VERSION),
  820. IOCTL32_DEFAULT(GET_ARRAY_INFO),
  821. IOCTL32_DEFAULT(GET_DISK_INFO),
  822. IOCTL32_DEFAULT(PRINT_RAID_DEBUG),
  823. IOCTL32_DEFAULT(RAID_AUTORUN),
  824. /* configuration */
  825. IOCTL32_DEFAULT(CLEAR_ARRAY),
  826. IOCTL32_DEFAULT(ADD_NEW_DISK),
  827. IOCTL32_DEFAULT(HOT_REMOVE_DISK),
  828. IOCTL32_DEFAULT(SET_ARRAY_INFO),
  829. IOCTL32_DEFAULT(SET_DISK_INFO),
  830. IOCTL32_DEFAULT(WRITE_RAID_INFO),
  831. IOCTL32_DEFAULT(UNPROTECT_ARRAY),
  832. IOCTL32_DEFAULT(PROTECT_ARRAY),
  833. IOCTL32_DEFAULT(HOT_ADD_DISK),
  834. IOCTL32_DEFAULT(SET_DISK_FAULTY),
  835. /* usage */
  836. IOCTL32_DEFAULT(RUN_ARRAY),
  837. IOCTL32_DEFAULT(START_ARRAY),
  838. IOCTL32_DEFAULT(STOP_ARRAY),
  839. IOCTL32_DEFAULT(STOP_ARRAY_RO),
  840. IOCTL32_DEFAULT(RESTART_ARRAY_RW),
  841. #endif /* CONFIG_MD */
  842. IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls  */
  843. IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
  844. IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans),
  845. IOCTL32_HANDLER(MTIOCGETCONFIG32, mt_ioctl_trans),
  846. IOCTL32_HANDLER(MTIOCSETCONFIG32, mt_ioctl_trans),
  847. // MTIOCRDFTSEG
  848. // MTIOCWRFTSEG
  849. // MTIOCVOLINFO
  850. // MTIOCGETSIZE
  851. // MTIOCFTFORMAT
  852. // MTIOCFTCMD
  853. IOCTL32_DEFAULT(AUTOFS_IOC_READY), /* auto_fs.h ioctls */
  854. IOCTL32_DEFAULT(AUTOFS_IOC_FAIL),
  855. IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC),
  856. IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER),
  857. IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
  858. IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE),
  859. /* Little p (/dev/rtc, /dev/envctrl, etc.) */
  860. IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */
  861. IOCTL32_DEFAULT(_IOW('p', 21, int[7])), /* RTCSET */
  862. IOCTL32_DEFAULT(RTC_AIE_ON),
  863. IOCTL32_DEFAULT(RTC_AIE_OFF),
  864. IOCTL32_DEFAULT(RTC_UIE_ON),
  865. IOCTL32_DEFAULT(RTC_UIE_OFF),
  866. IOCTL32_DEFAULT(RTC_PIE_ON),
  867. IOCTL32_DEFAULT(RTC_PIE_OFF),
  868. IOCTL32_DEFAULT(RTC_WIE_ON),
  869. IOCTL32_DEFAULT(RTC_WIE_OFF),
  870. IOCTL32_DEFAULT(RTC_ALM_SET),
  871. IOCTL32_DEFAULT(RTC_ALM_READ),
  872. IOCTL32_DEFAULT(RTC_RD_TIME),
  873. IOCTL32_DEFAULT(RTC_SET_TIME),
  874. IOCTL32_DEFAULT(RTC_WKALM_SET),
  875. IOCTL32_DEFAULT(RTC_WKALM_RD)
  876. };
  877. #define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) /
  878.  sizeof(ioctl32_handler_table[0]))
  879. static struct ioctl32_list *ioctl32_hash_table[1024];
  880. static inline int ioctl32_hash(unsigned int cmd)
  881. {
  882. return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
  883. }
  884. int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned int arg)
  885. {
  886. int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
  887. struct file *filp;
  888. struct ioctl32_list *l;
  889. int error;
  890. l = ioctl32_hash_table[ioctl32_hash(cmd)];
  891. error = -EBADF;
  892. filp = fget(fd);
  893. if (!filp)
  894. return error;
  895. if (!filp->f_op || !filp->f_op->ioctl) {
  896. error = sys_ioctl (fd, cmd, arg);
  897. goto out;
  898. }
  899. while (l && l->handler.cmd != cmd)
  900. l = l->next;
  901. if (l) {
  902. handler = (void *)l->handler.function;
  903. error = handler(fd, cmd, arg, filp);
  904. } else {
  905. error = -EINVAL;
  906. printk("unknown ioctl: %08xn", cmd);
  907. }
  908. out:
  909. fput(filp);
  910. return error;
  911. }
  912. static void ioctl32_insert(struct ioctl32_list *entry)
  913. {
  914. int hash = ioctl32_hash(entry->handler.cmd);
  915. if (!ioctl32_hash_table[hash])
  916. ioctl32_hash_table[hash] = entry;
  917. else {
  918. struct ioctl32_list *l;
  919. l = ioctl32_hash_table[hash];
  920. while (l->next)
  921. l = l->next;
  922. l->next = entry;
  923. entry->next = 0;
  924. }
  925. }
  926. static int __init init_ioctl32(void)
  927. {
  928. int i;
  929. for (i = 0; i < NR_IOCTL32_HANDLERS; i++)
  930. ioctl32_insert(&ioctl32_handler_table[i]);
  931. return 0;
  932. }
  933. __initcall(init_ioctl32);