Skip to content

Commit 17d4e9a

Browse files
xiaoguangwulijinxia
authored andcommitted
DM USB: xHCI: implement connect callbacks for USB port mapper
Allocate an emulated USB instance in connect callback function. This instance is the entity of virtual USB device which will be enumerated by the UOS. Change-Id: I948d2ce9eca7e9d5bbab673f2505efc0a03c03b4 Signed-off-by: Wu, Xiaoguang <xiaoguang.wu@intel.com> Reviewed-by: Shuo Liu <shuo.a.liu@intel.com> Reviewed-by: Yu Wang <yu1.wang@intel.com> Reviewed-by: Zhao Yakui <yakui.zhao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent aa0480f commit 17d4e9a

File tree

1 file changed

+171
-1
lines changed

1 file changed

+171
-1
lines changed

devicemodel/hw/pci/xhci.c

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,93 @@ static void pci_xhci_update_ep_ring(struct pci_xhci_vdev *xdev,
315315
struct xhci_endp_ctx *ep_ctx,
316316
uint32_t streamid, uint64_t ringaddr,
317317
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);
318322

319323
static int
320324
pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
321325
{
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+
322401
return 0;
402+
errout:
403+
pci_xhci_dev_destroy(de);
404+
return -1;
323405
}
324406

325407
static int
@@ -328,6 +410,86 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
328410
return 0;
329411
}
330412

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+
331493
static void
332494
pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port, uint32_t errcode,
333495
uint32_t evtype)
@@ -2797,7 +2959,15 @@ pci_xhci_parse_opts(struct pci_xhci_vdev *xdev, char *opts)
27972959
calloc(XHCI_MAX_DEVS, sizeof(struct pci_xhci_portregs));
27982960

27992961
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+
*/
28012971
xdev->devices--;
28022972
xdev->portregs--;
28032973
xdev->slots--;

0 commit comments

Comments
 (0)