DM USB: introduce data structure and APIs for USB port mapper

Introduce the struct usb_dev which is used to abstract the physical USB
devices. And APIs for external call are also provided.

Change-Id: Ia25d52a6c670040da787f82b3bea34eee9f3d04d
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>
This commit is contained in:
Wu, Xiaoguang 2018-04-15 17:59:21 +08:00 committed by lijinxia
parent 51f7633f82
commit 1816d3e608
6 changed files with 338 additions and 1 deletions

View File

@ -57,6 +57,7 @@ SRCS += hw/uart_core.c
SRCS += hw/pci/virtio/virtio.c SRCS += hw/pci/virtio/virtio.c
SRCS += hw/pci/virtio/virtio_kernel.c SRCS += hw/pci/virtio/virtio_kernel.c
SRCS += hw/platform/usb_mouse.c SRCS += hw/platform/usb_mouse.c
SRCS += hw/platform/usb_pmapper.c
SRCS += hw/platform/atkbdc.c SRCS += hw/platform/atkbdc.c
SRCS += hw/platform/ps2mouse.c SRCS += hw/platform/ps2mouse.c
SRCS += hw/platform/rtc.c SRCS += hw/platform/rtc.c

View File

@ -48,6 +48,7 @@
#include "pci_core.h" #include "pci_core.h"
#include "xhci.h" #include "xhci.h"
#include "usb_core.h" #include "usb_core.h"
#include "usb_pmapper.h"
#undef LOG_TAG #undef LOG_TAG
#define LOG_TAG "xHCI: " #define LOG_TAG "xHCI: "
@ -315,6 +316,18 @@ static void pci_xhci_update_ep_ring(struct pci_xhci_vdev *xdev,
uint32_t streamid, uint64_t ringaddr, uint32_t streamid, uint64_t ringaddr,
int ccs); int ccs);
static int
pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
{
return 0;
}
static int
pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
{
return 0;
}
static void static void
pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port, uint32_t errcode, pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port, uint32_t errcode,
uint32_t evtype) uint32_t evtype)
@ -2842,6 +2855,19 @@ pci_xhci_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
else else
error = 0; error = 0;
/*
* TODO:
* Will add command line option in subsequent patches for calling
* usb_dev_sys_init if new parameters are used.
*/
if (xdev->ndevices == 0)
if (usb_dev_sys_init(pci_xhci_native_usb_dev_conn_cb,
pci_xhci_native_usb_dev_disconn_cb,
NULL, NULL, xdev,
usb_get_log_level()) < 0) {
goto done;
}
xdev->caplength = XHCI_SET_CAPLEN(XHCI_CAPLEN) | xdev->caplength = XHCI_SET_CAPLEN(XHCI_CAPLEN) |
XHCI_SET_HCIVERSION(0x0100); XHCI_SET_HCIVERSION(0x0100);
xdev->hcsparams1 = XHCI_SET_HCSP1_MAXPORTS(XHCI_MAX_DEVS) | xdev->hcsparams1 = XHCI_SET_HCSP1_MAXPORTS(XHCI_MAX_DEVS) |

View File

@ -0,0 +1,164 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "usb.h"
#include "usbdi.h"
#include "usb_core.h"
#include "usb_pmapper.h"
#undef LOG_TAG
#define LOG_TAG "USBPM: "
static struct usb_dev_sys_ctx_info g_ctx;
static void *
usb_dev_sys_thread(void *arg)
{
struct timeval t = {1, 0};
while (g_ctx.thread_exit == 0 &&
libusb_handle_events_timeout(g_ctx.libusb_ctx, &t) >= 0)
; /* nothing */
UPRINTF(LINF, "poll thread exit\n\r");
return NULL;
}
static int
usb_dev_native_sys_conn_cb(struct libusb_context *ctx, struct libusb_device
*ldev, libusb_hotplug_event event, void *pdata)
{
UPRINTF(LDBG, "connect event\r\n");
if (!ctx || !ldev) {
UPRINTF(LFTL, "connect callback fails!\n");
return -1;
}
if (g_ctx.conn_cb)
g_ctx.conn_cb(g_ctx.hci_data, ldev);
return 0;
}
static int
usb_dev_native_sys_disconn_cb(struct libusb_context *ctx, struct libusb_device
*ldev, libusb_hotplug_event event, void *pdata)
{
UPRINTF(LDBG, "disconnect event\r\n");
if (!ctx || !ldev) {
UPRINTF(LFTL, "disconnect callback fails!\n");
return -1;
}
if (g_ctx.disconn_cb)
g_ctx.disconn_cb(g_ctx.hci_data, NULL);
return 0;
}
int
usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
usb_dev_sys_cb notify_cb, usb_dev_sys_cb intr_cb,
void *hci_data, int log_level)
{
libusb_hotplug_event native_conn_evt;
libusb_hotplug_event native_disconn_evt;
libusb_hotplug_flag flags;
libusb_hotplug_callback_handle native_conn_handle;
libusb_hotplug_callback_handle native_disconn_handle;
int native_pid, native_vid, native_cls, rc;
assert(conn_cb);
assert(disconn_cb);
usb_set_log_level(log_level);
if (g_ctx.libusb_ctx) {
UPRINTF(LFTL, "port mapper is already initialized.\r\n");
return -1;
}
rc = libusb_init(&g_ctx.libusb_ctx);
if (rc < 0) {
UPRINTF(LFTL, "libusb_init fails, rc:%d\r\n", rc);
return -1;
}
g_ctx.hci_data = hci_data;
g_ctx.conn_cb = conn_cb;
g_ctx.disconn_cb = disconn_cb;
native_conn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
native_disconn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
native_pid = LIBUSB_HOTPLUG_MATCH_ANY;
native_vid = LIBUSB_HOTPLUG_MATCH_ANY;
native_cls = LIBUSB_HOTPLUG_MATCH_ANY;
flags = 0;
/* register connect callback */
rc = libusb_hotplug_register_callback(g_ctx.libusb_ctx, native_conn_evt,
flags, native_vid, native_pid, native_cls,
usb_dev_native_sys_conn_cb, NULL, &native_conn_handle);
if (rc != LIBUSB_SUCCESS)
goto errout;
/* register disconnect callback */
rc = libusb_hotplug_register_callback(g_ctx.libusb_ctx,
native_disconn_evt, flags, native_vid, native_pid,
native_cls, usb_dev_native_sys_disconn_cb, NULL,
&native_disconn_handle);
if (rc != LIBUSB_SUCCESS) {
libusb_hotplug_deregister_callback(g_ctx.libusb_ctx,
native_conn_handle);
goto errout;
}
if (pthread_create(&g_ctx.thread, NULL, usb_dev_sys_thread, NULL)) {
libusb_hotplug_deregister_callback(g_ctx.libusb_ctx,
native_conn_handle);
libusb_hotplug_deregister_callback(g_ctx.libusb_ctx,
native_disconn_handle);
goto errout;
}
return 0;
errout:
if (g_ctx.libusb_ctx)
libusb_exit(g_ctx.libusb_ctx);
g_ctx.libusb_ctx = NULL;
return -1;
}

View File

@ -24,6 +24,57 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/*
* USB emulation designed as following diagram. It devided into three layers:
* HCD: USB host controller device layer, like xHCI, eHCI...
* USB core: middle abstraction layer for USB statck.
* USB Port Mapper: This layer supports to share physical USB
* devices(physical ports) to spcified virtual USB port of
* HCD DM. All the commands and data transfers are through
* Libusb to access native USB stack.
*
* +---------------+
* | |
* +----------+----------+ |
* | ACRN DM | |
* | +-----------------+ | |
* | | HCD (xHCI) | | |
* | +-----------------+ | |
* | | | |
* | +-----------------+ | |
* | | USB Core | | |
* | +-----------------+ | |
* | | | |
* | +-----------------+ | |
* | | USB Port Mapper | | |
* | +-----------------+ | |
* | | | |
* | +-----------------+ | |
* | | Libusb | | |
* | +-----------------+ | |
* +---------------------+ |
* Service OS User Space | User OS User Space
* |
* -------------------------- | ---------------------------
* |
* Service OS Kernel Space | User OS Kernel Space
* |
* | +-----------------+
* | | USB Core |
* | +-----------------+
* | |
* | +-----------------+
* | | HCD |
* | | (xHCI/uHCI/...) |
* | +--------+--------+
* | |
* +-------------+
* Current distribution:
* HCD: xhci.{h,c}
* USB core: usb_core.{h,c}
* USB device: usb_mouse.c usb_pmapper.{h,c}
*/
#include <sys/cdefs.h> #include <sys/cdefs.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>

View File

@ -62,7 +62,7 @@ struct usb_devemu {
#define USB_EMUL_SET(x) DATA_SET(usb_emu_set, x) #define USB_EMUL_SET(x) DATA_SET(usb_emu_set, x)
/* /*
* USB device events to notify HCI when state changes * USB device events to notify HCD when state changes
*/ */
enum hci_usbev { enum hci_usbev {
USBDEV_ATTACH, USBDEV_ATTACH,

View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _USB_DEVICE_H
#define _USB_DEVICE_H
#include <libusb-1.0/libusb.h>
#define USB_NUM_INTERFACE 16
#define USB_NUM_ENDPOINT 15
struct usb_dev_ep {
uint8_t pid;
uint8_t type;
};
struct usb_dev {
/* physical device info */
int addr;
int version;
int speed;
int configuration;
uint8_t port;
/* interface info */
int if_num;
int alts[USB_NUM_INTERFACE];
/* endpoints info */
struct usb_dev_ep epc;
struct usb_dev_ep epi[USB_NUM_ENDPOINT];
struct usb_dev_ep epo[USB_NUM_ENDPOINT];
/* libusb data */
libusb_device *ldev;
libusb_device_handle *handle;
};
/* callback type used by code from HCD layer */
typedef int (*usb_dev_sys_cb)(void *hci_data, void *dev_data);
struct usb_dev_sys_ctx_info {
/*
* Libusb related global variables
*/
libusb_context *libusb_ctx;
pthread_t thread;
int thread_exit;
/*
* The following callback funtions will be registered by
* the code from HCD(eg: XHCI, EHCI...) emulation layer.
*/
usb_dev_sys_cb conn_cb;
usb_dev_sys_cb disconn_cb;
/*
* private data from HCD layer
*/
void *hci_data;
};
/* intialize the usb_dev subsystem and register callbacks for HCD layer */
int usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
usb_dev_sys_cb notify_cb, usb_dev_sys_cb intr_cb,
void *hci_data, int log_level);
#endif