2929
3030struct uhid_device {
3131 struct mutex devlock ;
32+ bool running ;
33+
34+ __u8 * rd_data ;
35+ uint rd_size ;
36+
3237 struct hid_device * hid ;
3338 struct uhid_event input_buf ;
3439
@@ -75,6 +80,136 @@ static int uhid_queue_event(struct uhid_device *uhid, __u32 event)
7580 return 0 ;
7681}
7782
83+ static int uhid_hid_start (struct hid_device * hid )
84+ {
85+ return 0 ;
86+ }
87+
88+ static void uhid_hid_stop (struct hid_device * hid )
89+ {
90+ }
91+
92+ static int uhid_hid_open (struct hid_device * hid )
93+ {
94+ return 0 ;
95+ }
96+
97+ static void uhid_hid_close (struct hid_device * hid )
98+ {
99+ }
100+
101+ static int uhid_hid_input (struct input_dev * input , unsigned int type ,
102+ unsigned int code , int value )
103+ {
104+ return 0 ;
105+ }
106+
107+ static int uhid_hid_parse (struct hid_device * hid )
108+ {
109+ return 0 ;
110+ }
111+
112+ static int uhid_hid_get_raw (struct hid_device * hid , unsigned char rnum ,
113+ __u8 * buf , size_t count , unsigned char rtype )
114+ {
115+ return 0 ;
116+ }
117+
118+ static int uhid_hid_output_raw (struct hid_device * hid , __u8 * buf , size_t count ,
119+ unsigned char report_type )
120+ {
121+ return 0 ;
122+ }
123+
124+ static struct hid_ll_driver uhid_hid_driver = {
125+ .start = uhid_hid_start ,
126+ .stop = uhid_hid_stop ,
127+ .open = uhid_hid_open ,
128+ .close = uhid_hid_close ,
129+ .hidinput_input_event = uhid_hid_input ,
130+ .parse = uhid_hid_parse ,
131+ };
132+
133+ static int uhid_dev_create (struct uhid_device * uhid ,
134+ const struct uhid_event * ev )
135+ {
136+ struct hid_device * hid ;
137+ int ret ;
138+
139+ if (uhid -> running )
140+ return - EALREADY ;
141+
142+ uhid -> rd_size = ev -> u .create .rd_size ;
143+ if (uhid -> rd_size <= 0 || uhid -> rd_size > HID_MAX_DESCRIPTOR_SIZE )
144+ return - EINVAL ;
145+
146+ uhid -> rd_data = kmalloc (uhid -> rd_size , GFP_KERNEL );
147+ if (!uhid -> rd_data )
148+ return - ENOMEM ;
149+
150+ if (copy_from_user (uhid -> rd_data , ev -> u .create .rd_data ,
151+ uhid -> rd_size )) {
152+ ret = - EFAULT ;
153+ goto err_free ;
154+ }
155+
156+ hid = hid_allocate_device ();
157+ if (IS_ERR (hid )) {
158+ ret = PTR_ERR (hid );
159+ goto err_free ;
160+ }
161+
162+ strncpy (hid -> name , ev -> u .create .name , 127 );
163+ hid -> name [127 ] = 0 ;
164+ strncpy (hid -> phys , ev -> u .create .phys , 63 );
165+ hid -> phys [63 ] = 0 ;
166+ strncpy (hid -> uniq , ev -> u .create .uniq , 63 );
167+ hid -> uniq [63 ] = 0 ;
168+
169+ hid -> ll_driver = & uhid_hid_driver ;
170+ hid -> hid_get_raw_report = uhid_hid_get_raw ;
171+ hid -> hid_output_raw_report = uhid_hid_output_raw ;
172+ hid -> bus = ev -> u .create .bus ;
173+ hid -> vendor = ev -> u .create .vendor ;
174+ hid -> product = ev -> u .create .product ;
175+ hid -> version = ev -> u .create .version ;
176+ hid -> country = ev -> u .create .country ;
177+ hid -> driver_data = uhid ;
178+ hid -> dev .parent = uhid_misc .this_device ;
179+
180+ uhid -> hid = hid ;
181+ uhid -> running = true;
182+
183+ ret = hid_add_device (hid );
184+ if (ret ) {
185+ hid_err (hid , "Cannot register HID device\n" );
186+ goto err_hid ;
187+ }
188+
189+ return 0 ;
190+
191+ err_hid :
192+ hid_destroy_device (hid );
193+ uhid -> hid = NULL ;
194+ uhid -> running = false;
195+ err_free :
196+ kfree (uhid -> rd_data );
197+ return ret ;
198+ }
199+
200+ static int uhid_dev_destroy (struct uhid_device * uhid )
201+ {
202+ if (!uhid -> running )
203+ return - EINVAL ;
204+
205+ uhid -> running = false;
206+
207+ hid_destroy_device (uhid -> hid );
208+ kfree (uhid -> rd_data );
209+
210+ return 0 ;
211+ }
212+
78213static int uhid_char_open (struct inode * inode , struct file * file )
79214{
80215 struct uhid_device * uhid ;
@@ -86,6 +221,7 @@ static int uhid_char_open(struct inode *inode, struct file *file)
86221 mutex_init (& uhid -> devlock );
87222 spin_lock_init (& uhid -> qlock );
88223 init_waitqueue_head (& uhid -> waitq );
224+ uhid -> running = false;
89225
90226 file -> private_data = uhid ;
91227 nonseekable_open (inode , file );
@@ -98,6 +234,8 @@ static int uhid_char_release(struct inode *inode, struct file *file)
98234 struct uhid_device * uhid = file -> private_data ;
99235 unsigned int i ;
100236
237+ uhid_dev_destroy (uhid );
238+
101239 for (i = 0 ; i < UHID_BUFSIZE ; ++ i )
102240 kfree (uhid -> outq [i ]);
103241
@@ -177,6 +315,12 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
177315 }
178316
179317 switch (uhid -> input_buf .type ) {
318+ case UHID_CREATE :
319+ ret = uhid_dev_create (uhid , & uhid -> input_buf );
320+ break ;
321+ case UHID_DESTROY :
322+ ret = uhid_dev_destroy (uhid );
323+ break ;
180324 default :
181325 ret = - EOPNOTSUPP ;
182326 }
0 commit comments