@@ -245,15 +245,110 @@ virtio_input_notify_event_vq(void *vdev, struct virtio_vq_info *vq)
245
245
static void
246
246
virtio_input_notify_status_vq (void * vdev , struct virtio_vq_info * vq )
247
247
{
248
- /* to be implemented */
248
+ struct virtio_input * vi ;
249
+ struct virtio_input_event event ;
250
+ struct input_event host_event ;
251
+ struct iovec iov ;
252
+ int n , len ;
253
+ uint16_t idx ;
254
+
255
+ vi = vdev ;
256
+
257
+ while (vq_has_descs (vq )) {
258
+ n = vq_getchain (vq , & idx , & iov , 1 , NULL );
259
+ assert (n == 1 );
260
+
261
+ memcpy (& event , iov .iov_base , sizeof (event ));
262
+ host_event .type = event .type ;
263
+ host_event .code = event .code ;
264
+ host_event .value = event .value ;
265
+ len = write (vi -> fd , & host_event , sizeof (host_event ));
266
+ if (len == -1 )
267
+ WPRINTF (("%s: write failed, len = %d, errno = %d\n" ,
268
+ __func__ , len , errno ));
269
+ vq_relchain (vq , idx , sizeof (event )); /* Release the chain */
270
+ }
271
+ vq_endchains (vq , 1 ); /* Generate interrupt if appropriate. */
272
+ }
273
+
274
+ static void
275
+ virtio_input_send_event (struct virtio_input * vi ,
276
+ struct virtio_input_event * event )
277
+ {
278
+ struct virtio_vq_info * vq ;
279
+ struct iovec iov ;
280
+ int n , i ;
281
+ uint16_t idx ;
282
+
283
+ if (!vi -> ready )
284
+ return ;
285
+
286
+ if (vi -> event_qindex == vi -> event_qsize ) {
287
+ vi -> event_qsize ++ ;
288
+ vi -> event_queue = realloc (vi -> event_queue ,
289
+ vi -> event_qsize *
290
+ sizeof (struct virtio_input_event_elem ));
291
+ assert (vi -> event_queue );
292
+ }
293
+ vi -> event_queue [vi -> event_qindex ].event = * event ;
294
+ vi -> event_qindex ++ ;
295
+
296
+ if (event -> type != EV_SYN || event -> code != SYN_REPORT )
297
+ return ;
298
+
299
+ vq = & vi -> queues [VIRTIO_INPUT_EVENT_QUEUE ];
300
+ for (i = 0 ; i < vi -> event_qindex ; i ++ ) {
301
+ if (!vq_has_descs (vq )) {
302
+ while (i -- > 0 )
303
+ vq_retchain (vq );
304
+ WPRINTF (("%s: not enough avail descs, dropped:%d\n" ,
305
+ __func__ , vi -> event_qindex ));
306
+ goto out ;
307
+ }
308
+ n = vq_getchain (vq , & idx , & iov , 1 , NULL );
309
+ assert (n == 1 );
310
+ vi -> event_queue [i ].iov = iov ;
311
+ vi -> event_queue [i ].idx = idx ;
312
+ }
313
+
314
+ for (i = 0 ; i < vi -> event_qindex ; i ++ ) {
315
+ memcpy (vi -> event_queue [i ].iov .iov_base ,
316
+ & vi -> event_queue [i ].event ,
317
+ sizeof (struct virtio_input_event ));
318
+ vq_relchain (vq , vi -> event_queue [i ].idx ,
319
+ sizeof (struct virtio_input_event ));
320
+ }
321
+
322
+ out :
323
+ vi -> event_qindex = 0 ;
324
+ vq_endchains (vq , 1 );
249
325
}
250
326
251
327
static void
252
328
virtio_input_read_event (int fd __attribute__((unused )),
253
329
enum ev_type t __attribute__((unused )),
254
330
void * arg )
255
331
{
256
- /* to be implemented */
332
+ struct virtio_input * vi = arg ;
333
+ struct virtio_input_event event ;
334
+ struct input_event host_event ;
335
+ int len ;
336
+
337
+ while (1 ) {
338
+ len = read (vi -> fd , & host_event , sizeof (host_event ));
339
+ if (len != sizeof (host_event )) {
340
+ if (len == -1 && errno != EAGAIN )
341
+ WPRINTF (("vtinput: host read failed! "
342
+ "len = %d, errno = %d\n" ,
343
+ len , errno ));
344
+ break ;
345
+ }
346
+
347
+ event .type = host_event .type ;
348
+ event .code = host_event .code ;
349
+ event .value = host_event .value ;
350
+ virtio_input_send_event (vi , & event );
351
+ }
257
352
}
258
353
259
354
static bool
0 commit comments