mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-25 19:29:30 +00:00
Flat Mode for hub emulation means DM emulates USB devices under hub but hide hub itself. Under this design the Guest OS cannot see any emulated hub. So in the perspective of Guest OS, all the emulated devices are under root hub. This patch is used to enable feature as mentioned above. And please NOTE, it is the initial version of hub flat Mode hub emulation, there are one limitation: only one physical hub is supported. If second physical hub is connected, the connect and disconnect behavior in second hub may affect the function of first emulated hub. The USB HUB device model should be the final long term solution, but it is very complex. Use flat mode HUB emulation as the short term solution first to support some USB touch devices which integrated internal HUB. Signed-off-by: Liang Yang <liang3.yang@intel.com> Reviewed-by: Xiaoguang Wu <xiaoguang.wu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com> Tracked-On: #1243
138 lines
3.1 KiB
C
138 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2018 Intel Corporation. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
*/
|
|
|
|
#ifndef _USB_DEVICE_H
|
|
#define _USB_DEVICE_H
|
|
#include <libusb-1.0/libusb.h>
|
|
#include "usb_core.h"
|
|
|
|
#define USB_NUM_INTERFACE 16
|
|
#define USB_NUM_ENDPOINT 15
|
|
|
|
#define USB_EP_ADDR(d) ((d)->bEndpointAddress)
|
|
#define USB_EP_ATTR(d) ((d)->bmAttributes)
|
|
#define USB_EP_PID(d) (USB_EP_ADDR(d) & USB_DIR_IN ? TOKEN_IN : TOKEN_OUT)
|
|
#define USB_EP_TYPE(d) (USB_EP_ATTR(d) & 0x3)
|
|
#define USB_EP_NR(d) (USB_EP_ADDR(d) & 0xF)
|
|
#define USB_EP_ERR_TYPE 0xFF
|
|
|
|
/* hub port start address */
|
|
#define PORT_HUB_BASE 0x0A
|
|
|
|
enum {
|
|
USB_INFO_VERSION,
|
|
USB_INFO_SPEED,
|
|
USB_INFO_BUS,
|
|
USB_INFO_PORT,
|
|
USB_INFO_VID,
|
|
USB_INFO_PID
|
|
};
|
|
|
|
enum usb_native_dev_type {
|
|
ROOT_HUB,
|
|
USB_HUB,
|
|
USB_DEV,
|
|
USB_VALID_SUB_DEV,
|
|
USB_INVALID_SUB_DEV,
|
|
USB_TYPE_INVALID
|
|
};
|
|
|
|
struct usb_dev_ep {
|
|
uint8_t pid;
|
|
uint8_t type;
|
|
};
|
|
|
|
struct usb_dev {
|
|
/* physical device info */
|
|
struct usb_native_devinfo info;
|
|
int addr;
|
|
int version;
|
|
int configuration;
|
|
|
|
/* 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_handle *handle;
|
|
};
|
|
|
|
/*
|
|
* The purpose to implement struct usb_dev_req is to adapt
|
|
* struct usb_data_xfer to make a proper data format to talk
|
|
* with libusb.
|
|
*/
|
|
struct usb_dev_req {
|
|
struct usb_dev *udev;
|
|
int in;
|
|
int seq;
|
|
/*
|
|
* buffer could include data from multiple
|
|
* usb_data_xfer_block, so here need some
|
|
* data to record it.
|
|
*/
|
|
uint8_t *buffer;
|
|
int buf_length;
|
|
int blk_start;
|
|
int blk_count;
|
|
|
|
struct usb_data_xfer *xfer;
|
|
struct libusb_transfer *libusb_xfer;
|
|
struct usb_data_xfer_block *setup_blk;
|
|
};
|
|
|
|
/* 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;
|
|
|
|
/* handles of callback */
|
|
libusb_hotplug_callback_handle conn_handle;
|
|
libusb_hotplug_callback_handle disconn_handle;
|
|
|
|
/*
|
|
* 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;
|
|
usb_dev_sys_cb notify_cb;
|
|
usb_dev_sys_cb intr_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);
|
|
void usb_dev_sys_deinit(void);
|
|
void *usb_dev_init(void *pdata, char *opt);
|
|
void usb_dev_deinit(void *pdata);
|
|
int usb_dev_info(void *pdata, int type, void *value, int size);
|
|
int usb_dev_request(void *pdata, struct usb_data_xfer *xfer);
|
|
int usb_dev_reset(void *pdata);
|
|
int usb_dev_data(void *pdata, struct usb_data_xfer *xfer, int dir, int epctx);
|
|
enum usb_native_dev_type usb_get_parent_dev_type(void *pdata, uint16_t *bus,
|
|
uint16_t *port);
|
|
int usb_dev_is_hub(void *pdata);
|
|
#endif
|