blob: fb555d2a42d524fd57d1614904450ba1b3df71a6 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001#include <stdio.h>
2#include <stdlib.h>
Olivier Baillyb93e5812010-11-17 11:47:23 -08003#include <stdint.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08004#include <fcntl.h>
Olivier Baillyb93e5812010-11-17 11:47:23 -08005#include <getopt.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08006#include <string.h>
7#include <linux/kd.h>
8#include <linux/vt.h>
9#include <errno.h>
10#include <pthread.h>
Olivier Baillyb93e5812010-11-17 11:47:23 -080011#include <sys/ioctl.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080012
13int ioctl_main(int argc, char *argv[])
14{
15 int c;
16 int fd;
17 int res;
18
19 int read_only = 0;
20 int length = -1;
21 int arg_size = 4;
22 int direct_arg = 0;
23 uint32_t ioctl_nr;
24 void *ioctl_args;
25 uint8_t *ioctl_argp;
26 uint8_t *ioctl_argp_save;
27 int rem;
28
29 do {
30 c = getopt(argc, argv, "rdl:a:h");
31 if (c == EOF)
32 break;
33 switch (c) {
34 case 'r':
35 read_only = 1;
36 break;
37 case 'd':
38 direct_arg = 1;
39 break;
40 case 'l':
41 length = strtol(optarg, NULL, 0);
42 break;
43 case 'a':
44 arg_size = strtol(optarg, NULL, 0);
45 break;
46 case 'h':
47 fprintf(stderr, "%s [-l <length>] [-a <argsize>] [-rdh] <device> <ioctlnr>\n"
48 " -l <lenght> Length of io buffer\n"
49 " -a <argsize> Size of each argument (1-8)\n"
50 " -r Open device in read only mode\n"
51 " -d Direct argument (no iobuffer)\n"
52 " -h Print help\n", argv[0]);
53 return -1;
54 case '?':
55 fprintf(stderr, "%s: invalid option -%c\n",
56 argv[0], optopt);
57 exit(1);
58 }
59 } while (1);
60
61 if(optind + 2 > argc) {
62 fprintf(stderr, "%s: too few arguments\n", argv[0]);
63 exit(1);
64 }
65
66 fd = open(argv[optind], O_RDWR | O_SYNC);
67 if (fd < 0) {
68 fprintf(stderr, "cannot open %s\n", argv[optind]);
69 return 1;
70 }
71 optind++;
72
73 ioctl_nr = strtol(argv[optind], NULL, 0);
74 optind++;
75
76 if(direct_arg) {
77 arg_size = 4;
78 length = 4;
79 }
80
81 if(length < 0) {
82 length = (argc - optind) * arg_size;
83 }
84 if(length) {
85 ioctl_args = calloc(1, length);
86
87 ioctl_argp_save = ioctl_argp = ioctl_args;
88 rem = length;
89 while(optind < argc) {
90 uint64_t tmp = strtoull(argv[optind], NULL, 0);
91 if(rem < arg_size) {
92 fprintf(stderr, "%s: too many arguments\n", argv[0]);
93 exit(1);
94 }
95 memcpy(ioctl_argp, &tmp, arg_size);
96 ioctl_argp += arg_size;
97 rem -= arg_size;
98 optind++;
99 }
100 }
101 printf("sending ioctl 0x%x", ioctl_nr);
102 rem = length;
103 while(rem--) {
104 printf(" 0x%02x", *ioctl_argp_save++);
105 }
106 printf("\n");
107
108 if(direct_arg)
109 res = ioctl(fd, ioctl_nr, *(uint32_t*)ioctl_args);
110 else if(length)
111 res = ioctl(fd, ioctl_nr, ioctl_args);
112 else
113 res = ioctl(fd, ioctl_nr, 0);
114 if (res < 0) {
115 fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res);
116 return 1;
117 }
118 if(length) {
119 printf("return buf:");
120 ioctl_argp = ioctl_args;
121 rem = length;
122 while(rem--) {
123 printf(" %02x", *ioctl_argp++);
124 }
125 printf("\n");
126 }
127 return 0;
128}