mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-06-08 10:04:42 +00:00
DM USB: xHCI: DM USB: xHCI: Support port change event for hot connection
This patch implements the port change event related function, it triggered when USB device be hot plugged in. Change-Id: I065c1e93779f85f8ee6031960e129b59146e1bb7 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:
@@ -319,6 +319,9 @@ static void pci_xhci_init_port(struct pci_xhci_vdev *xdev, int portn);
|
|||||||
static struct pci_xhci_dev_emu *pci_xhci_dev_create(struct pci_xhci_vdev *
|
static struct pci_xhci_dev_emu *pci_xhci_dev_create(struct pci_xhci_vdev *
|
||||||
xdev, void *dev_data);
|
xdev, void *dev_data);
|
||||||
static void pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de);
|
static void pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de);
|
||||||
|
static int pci_xhci_port_chg(struct pci_xhci_vdev *xdev, int port, int conn);
|
||||||
|
static void pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port,
|
||||||
|
uint32_t errcode, uint32_t evtype);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
|
pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
|
||||||
@@ -398,6 +401,10 @@ pci_xhci_native_usb_dev_conn_cb(void *hci_data, void *dev_data)
|
|||||||
native_vid, native_pid, native_bus, native_port,
|
native_vid, native_pid, native_bus, native_port,
|
||||||
slot, port);
|
slot, port);
|
||||||
|
|
||||||
|
/* Trigger port change event for the arriving device */
|
||||||
|
if (pci_xhci_port_chg(xdev, port, 1))
|
||||||
|
UPRINTF(LFTL, "fail to report port event\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
errout:
|
errout:
|
||||||
pci_xhci_dev_destroy(de);
|
pci_xhci_dev_destroy(de);
|
||||||
@@ -490,6 +497,56 @@ pci_xhci_dev_destroy(struct pci_xhci_dev_emu *de)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
pci_xhci_is_valid_portnum(int n)
|
||||||
|
{
|
||||||
|
return n > 0 && n < XHCI_MAX_DEVS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pci_xhci_port_chg(struct pci_xhci_vdev *xdev, int port, int conn)
|
||||||
|
{
|
||||||
|
int speed, error;
|
||||||
|
struct xhci_trb evtrb;
|
||||||
|
struct pci_xhci_portregs *reg;
|
||||||
|
struct pci_xhci_dev_emu *dev;
|
||||||
|
|
||||||
|
assert(xdev != NULL);
|
||||||
|
|
||||||
|
reg = XHCI_PORTREG_PTR(xdev, port);
|
||||||
|
dev = XHCI_DEVINST_PTR(xdev, port);
|
||||||
|
if (!dev || !dev->dev_ue || !reg) {
|
||||||
|
UPRINTF(LWRN, "find nullptr with port %d\r\n", port);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: add USB 3.0 port state */
|
||||||
|
if (conn == 0) {
|
||||||
|
reg->portsc &= ~XHCI_PS_CCS;
|
||||||
|
reg->portsc |= (XHCI_PS_CSC |
|
||||||
|
XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET));
|
||||||
|
} else {
|
||||||
|
speed = dev->dev_ue->ue_usbspeed;
|
||||||
|
reg->portsc = XHCI_PS_CCS | XHCI_PS_PP | XHCI_PS_CSC;
|
||||||
|
reg->portsc |= XHCI_PS_SPEED_SET(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* make an event for the guest OS */
|
||||||
|
pci_xhci_set_evtrb(&evtrb,
|
||||||
|
port,
|
||||||
|
XHCI_TRB_ERROR_SUCCESS,
|
||||||
|
XHCI_TRB_EVENT_PORT_STS_CHANGE);
|
||||||
|
|
||||||
|
/* put it in the event ring */
|
||||||
|
error = pci_xhci_insert_event(xdev, &evtrb, 1);
|
||||||
|
if (error != XHCI_TRB_ERROR_SUCCESS)
|
||||||
|
UPRINTF(LWRN, "fail to report port change\r\n");
|
||||||
|
|
||||||
|
UPRINTF(LDBG, "%s: port %d:%08X\r\n", __func__, port, reg->portsc);
|
||||||
|
return (error == XHCI_TRB_ERROR_SUCCESS) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user