@@ -315,11 +315,93 @@ static void pci_xhci_update_ep_ring(struct pci_xhci_vdev *xdev,
315
315
struct xhci_endp_ctx * ep_ctx ,
316
316
uint32_t streamid , uint64_t ringaddr ,
317
317
int ccs );
318
+ static void pci_xhci_init_port (struct pci_xhci_vdev * xdev , int portn );
319
+ static struct pci_xhci_dev_emu * pci_xhci_dev_create (struct pci_xhci_vdev *
320
+ xdev , void * dev_data );
321
+ static void pci_xhci_dev_destroy (struct pci_xhci_dev_emu * de );
318
322
319
323
static int
320
324
pci_xhci_native_usb_dev_conn_cb (void * hci_data , void * dev_data )
321
325
{
326
+ struct pci_xhci_dev_emu * de ;
327
+ struct pci_xhci_vdev * xdev ;
328
+ struct usb_devemu * ue ;
329
+ int port_start , port_end ;
330
+ int slot_start , slot_end ;
331
+ int port , slot ;
332
+ void * ud ;
333
+ uint8_t native_bus , native_pid , native_port ;
334
+ uint16_t native_vid ;
335
+
336
+ xdev = hci_data ;
337
+
338
+ assert (xdev );
339
+ assert (dev_data );
340
+ assert (xdev -> devices );
341
+ assert (xdev -> slots );
342
+
343
+ de = pci_xhci_dev_create (xdev , dev_data );
344
+ if (!de ) {
345
+ UPRINTF (LFTL , "fail to create device\r\n" );
346
+ return -1 ;
347
+ }
348
+
349
+ /* find free port and slot for the new usb device */
350
+ ud = de -> dev_instance ;
351
+ ue = de -> dev_ue ;
352
+
353
+ assert (ud );
354
+ assert (ue );
355
+
356
+ /* print physical information about new device */
357
+ ue -> ue_info (ud , USB_INFO_BUS , & native_bus , sizeof (native_bus ));
358
+ ue -> ue_info (ud , USB_INFO_PORT , & native_port , sizeof (native_port ));
359
+ ue -> ue_info (ud , USB_INFO_VID , & native_vid , sizeof (native_vid ));
360
+ ue -> ue_info (ud , USB_INFO_PID , & native_pid , sizeof (native_pid ));
361
+ UPRINTF (LDBG , "%X:%X %d-%d connecting.\r\n" ,
362
+ native_vid , native_pid , native_bus , native_port );
363
+
364
+ if (ue -> ue_usbver == 2 )
365
+ port_start = xdev -> usb2_port_start ;
366
+ else
367
+ port_start = xdev -> usb3_port_start ;
368
+
369
+ slot_start = 1 ;
370
+ port_end = port_start + (XHCI_MAX_DEVS / 2 );
371
+ slot_end = XHCI_MAX_SLOTS ;
372
+
373
+ /* find free port */
374
+ for (port = port_start ; port < port_end ; port ++ )
375
+ if (!xdev -> devices [port ])
376
+ break ;
377
+
378
+ /* find free slot */
379
+ for (slot = slot_start ; slot < slot_end ; slot ++ )
380
+ if (!xdev -> slots [slot ])
381
+ break ;
382
+
383
+ if (port >= port_end || slot >= slot_end ) {
384
+ UPRINTF (LFTL , "no free resource: port %d slot %d\r\n" ,
385
+ port , slot );
386
+ goto errout ;
387
+ }
388
+
389
+ /* use index of devices as port number */
390
+ xdev -> devices [port ] = de ;
391
+ xdev -> slots [slot ] = de ;
392
+ xdev -> ndevices ++ ;
393
+
394
+ pci_xhci_reset_slot (xdev , slot );
395
+ pci_xhci_init_port (xdev , port );
396
+
397
+ UPRINTF (LDBG , "%X:%X %d-%d locates in slot %d port %d.\r\n" ,
398
+ native_vid , native_pid , native_bus , native_port ,
399
+ slot , port );
400
+
322
401
return 0 ;
402
+ errout :
403
+ pci_xhci_dev_destroy (de );
404
+ return -1 ;
323
405
}
324
406
325
407
static int
@@ -328,6 +410,86 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
328
410
return 0 ;
329
411
}
330
412
413
+ static struct pci_xhci_dev_emu *
414
+ pci_xhci_dev_create (struct pci_xhci_vdev * xdev , void * dev_data )
415
+ {
416
+ struct usb_devemu * ue = NULL ;
417
+ struct pci_xhci_dev_emu * de = NULL ;
418
+ void * ud = NULL ;
419
+ int rc ;
420
+
421
+ assert (xdev );
422
+ assert (dev_data );
423
+
424
+ ue = calloc (1 , sizeof (struct usb_devemu ));
425
+ if (!ue )
426
+ return NULL ;
427
+
428
+ /* TODO: following function pointers will be populated in future */
429
+ ue -> ue_init = usb_dev_init ;
430
+ ue -> ue_request = NULL ;
431
+ ue -> ue_data = NULL ;
432
+ ue -> ue_info = usb_dev_info ;
433
+ ue -> ue_reset = NULL ;
434
+ ue -> ue_remove = NULL ;
435
+ ue -> ue_stop = NULL ;
436
+ ue -> ue_deinit = usb_dev_deinit ;
437
+
438
+ ud = ue -> ue_init (dev_data , NULL );
439
+ if (!ud )
440
+ goto errout ;
441
+
442
+ rc = ue -> ue_info (ud , USB_INFO_VERSION , & ue -> ue_usbver ,
443
+ sizeof (ue -> ue_usbver ));
444
+ if (rc < 0 )
445
+ goto errout ;
446
+
447
+ rc = ue -> ue_info (ud , USB_INFO_SPEED , & ue -> ue_usbspeed ,
448
+ sizeof (ue -> ue_usbspeed ));
449
+ if (rc < 0 )
450
+ goto errout ;
451
+
452
+ de = calloc (1 , sizeof (struct pci_xhci_dev_emu ));
453
+ if (!de )
454
+ goto errout ;
455
+
456
+ de -> xdev = xdev ;
457
+ de -> dev_ue = ue ;
458
+ de -> dev_instance = ud ;
459
+ de -> hci .dev = NULL ;
460
+ de -> hci .hci_intr = NULL ;
461
+ de -> hci .hci_event = NULL ;
462
+ de -> hci .hci_address = 0 ;
463
+
464
+ return de ;
465
+
466
+ errout :
467
+ if (ud )
468
+ ue -> ue_deinit (ud );
469
+
470
+ free (ue );
471
+ free (de );
472
+ return NULL ;
473
+ }
474
+
475
+ static void
476
+ pci_xhci_dev_destroy (struct pci_xhci_dev_emu * de )
477
+ {
478
+ struct usb_devemu * ue ;
479
+ struct usb_dev * ud ;
480
+
481
+ if (de ) {
482
+ ue = de -> dev_ue ;
483
+ ud = de -> dev_instance ;
484
+ if (ue ) {
485
+ assert (ue -> ue_deinit );
486
+ ue -> ue_deinit (ud );
487
+ }
488
+ free (ue );
489
+ free (de );
490
+ }
491
+ }
492
+
331
493
static void
332
494
pci_xhci_set_evtrb (struct xhci_trb * evtrb , uint64_t port , uint32_t errcode ,
333
495
uint32_t evtype )
@@ -2797,7 +2959,15 @@ pci_xhci_parse_opts(struct pci_xhci_vdev *xdev, char *opts)
2797
2959
calloc (XHCI_MAX_DEVS , sizeof (struct pci_xhci_portregs ));
2798
2960
2799
2961
if (xdev -> ndevices > 0 ) {
2800
- /* port and slot numbering start from 1 */
2962
+ /* port and slot numbering start from 1
2963
+ *
2964
+ * TODO: This code is really dangerous...
2965
+ * xdev->devices[0] and xdev->slots[0] are point to one
2966
+ * invalid address. Only xdev->slots[1] is the real first
2967
+ * item. Just use this design now due to the original xhci.c
2968
+ * and the usb_mouse.c depend on it and it will be fixed
2969
+ * in future.
2970
+ */
2801
2971
xdev -> devices -- ;
2802
2972
xdev -> portregs -- ;
2803
2973
xdev -> slots -- ;
0 commit comments