USB xHCI fixes for Win 8.1 by Ben Lunt.
This commit is contained in:
parent
df6246601e
commit
d621db4c81
@ -627,6 +627,28 @@ void bx_usb_xhci_c::reset_port(int p)
|
|||||||
BX_XHCI_THIS hub.usb_port[p].has_been_reset = 0;
|
BX_XHCI_THIS hub.usb_port[p].has_been_reset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bx_usb_xhci_c::reset_port_usb3(int port, const int reset_type)
|
||||||
|
{
|
||||||
|
BX_INFO(("Reset port #%i, type=%i", port + 1, reset_type));
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.pr = 0;
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].has_been_reset = 1;
|
||||||
|
if (BX_XHCI_THIS hub.usb_port[port].portsc.ccs) {
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.prc = 1;
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.pls = PLS_U0;
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.ped = 1;
|
||||||
|
if (BX_XHCI_THIS hub.usb_port[port].device != NULL) {
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].device->usb_send_msg(USB_MSG_RESET);
|
||||||
|
if (BX_XHCI_THIS hub.usb_port[port].is_usb3 && (reset_type == WARM_RESET))
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.wrc = 1;
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.prc = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.pls = PLS_RXDETECT;
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.ped = 0;
|
||||||
|
BX_XHCI_THIS hub.usb_port[port].portsc.speed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This is the Save/Restore part of the controller. The host will issue a save state
|
/* This is the Save/Restore part of the controller. The host will issue a save state
|
||||||
* (via a bit in the command register) before it powers down the controller. The controller
|
* (via a bit in the command register) before it powers down the controller. The controller
|
||||||
* will use the scratch pad buffers (or its own memory if HCSPARAMS2:ScratchPadRestore == 0)
|
* will use the scratch pad buffers (or its own memory if HCSPARAMS2:ScratchPadRestore == 0)
|
||||||
@ -1367,7 +1389,6 @@ bx_bool bx_usb_xhci_c::write_handler(bx_phy_address addr, unsigned len, void *da
|
|||||||
const Bit32u offset = (Bit32u) (addr - BX_XHCI_THIS pci_base_address[0]);
|
const Bit32u offset = (Bit32u) (addr - BX_XHCI_THIS pci_base_address[0]);
|
||||||
Bit32u temp;
|
Bit32u temp;
|
||||||
int i;
|
int i;
|
||||||
bx_bool reset_type;
|
|
||||||
|
|
||||||
// modify val and val_hi per len of data to write
|
// modify val and val_hi per len of data to write
|
||||||
switch (len) {
|
switch (len) {
|
||||||
@ -1462,6 +1483,13 @@ bx_bool bx_usb_xhci_c::write_handler(bx_phy_address addr, unsigned len, void *da
|
|||||||
if (BX_XHCI_THIS hub.op_regs.HcCommand.hcrst) {
|
if (BX_XHCI_THIS hub.op_regs.HcCommand.hcrst) {
|
||||||
BX_XHCI_THIS reset_hc();
|
BX_XHCI_THIS reset_hc();
|
||||||
BX_XHCI_THIS hub.op_regs.HcCommand.hcrst = 0;
|
BX_XHCI_THIS hub.op_regs.HcCommand.hcrst = 0;
|
||||||
|
// the controller will send a reset to all USB 3.0 ports,
|
||||||
|
// enabling the port if a device is attached.
|
||||||
|
for (int port=0; port<USB_XHCI_PORTS; port++) {
|
||||||
|
if (BX_XHCI_THIS hub.usb_port[port].is_usb3) {
|
||||||
|
reset_port_usb3(port, HOT_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if run/stop bit cleared, stop command ring
|
// if run/stop bit cleared, stop command ring
|
||||||
@ -1617,7 +1645,7 @@ bx_bool bx_usb_xhci_c::write_handler(bx_phy_address addr, unsigned len, void *da
|
|||||||
if (BX_XHCI_THIS hub.usb_port[port].is_usb3) {
|
if (BX_XHCI_THIS hub.usb_port[port].is_usb3) {
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.wpr = (value & (1 << 31)) ? 1 : 0;
|
BX_XHCI_THIS hub.usb_port[port].portsc.wpr = (value & (1 << 31)) ? 1 : 0;
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.cec = (value & (1 << 23)) ? 1 : 0;
|
BX_XHCI_THIS hub.usb_port[port].portsc.cec = (value & (1 << 23)) ? 1 : 0;
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.wrc = (value & (1 << 20)) ? 0 : BX_XHCI_THIS hub.usb_port[port].portsc.wrc;
|
BX_XHCI_THIS hub.usb_port[port].portsc.wrc = (value & (1 << 19)) ? 0 : BX_XHCI_THIS hub.usb_port[port].portsc.wrc;
|
||||||
if (value & (1<<18))
|
if (value & (1<<18))
|
||||||
BX_ERROR(("Write to USB3 port: bit 18"));
|
BX_ERROR(("Write to USB3 port: bit 18"));
|
||||||
} else {
|
} else {
|
||||||
@ -1669,25 +1697,7 @@ bx_bool bx_usb_xhci_c::write_handler(bx_phy_address addr, unsigned len, void *da
|
|||||||
// if port reset bit is set, reset the port, then enable the port (if ccs == 1).
|
// if port reset bit is set, reset the port, then enable the port (if ccs == 1).
|
||||||
if (((value & (1 << 31)) && BX_XHCI_THIS hub.usb_port[port].is_usb3) ||
|
if (((value & (1 << 31)) && BX_XHCI_THIS hub.usb_port[port].is_usb3) ||
|
||||||
(value & (1 << 4))) {
|
(value & (1 << 4))) {
|
||||||
reset_type = (value & (1 << 4)) ? HOT_RESET : WARM_RESET;
|
reset_port_usb3(port, (value & (1 << 4)) ? HOT_RESET : WARM_RESET);
|
||||||
BX_INFO(("Reset port #%i, type=%i", port + 1, reset_type));
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.pr = 0;
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].has_been_reset = 1;
|
|
||||||
if (BX_XHCI_THIS hub.usb_port[port].portsc.ccs) {
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.prc = 1;
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.pls = PLS_U0;
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.ped = 1;
|
|
||||||
if (BX_XHCI_THIS hub.usb_port[port].device != NULL) {
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].device->usb_send_msg(USB_MSG_RESET);
|
|
||||||
if (BX_XHCI_THIS hub.usb_port[port].is_usb3 && (reset_type == WARM_RESET))
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.wrc = 1;
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.prc = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.pls = PLS_RXDETECT;
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.ped = 0;
|
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.speed = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
BX_XHCI_THIS hub.usb_port[port].portsc.pp = 0;
|
BX_XHCI_THIS hub.usb_port[port].portsc.pp = 0;
|
||||||
@ -2053,25 +2063,26 @@ void bx_usb_xhci_c::process_transfer_ring(const int slot, const int ep)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Event TRB
|
// Event TRB
|
||||||
|
// xHCI version 1.10 (Nov 2017), page 184
|
||||||
case EVENT_DATA:
|
case EVENT_DATA:
|
||||||
if (!spd_occurred || (spd_occurred && !first_event_trb_encountered)) {
|
if (!spd_occurred || (spd_occurred && !first_event_trb_encountered)) {
|
||||||
comp_code = (spd_occurred) ? SHORT_PACKET : TRB_SUCCESS;
|
comp_code = (spd_occurred) ? SHORT_PACKET : TRB_SUCCESS;
|
||||||
if (spd_occurred && !first_event_trb_encountered) {
|
write_event_TRB(int_target, trb.parameter,
|
||||||
write_event_TRB(int_target, trb.parameter,
|
TRB_SET_COMP_CODE(comp_code) | (BX_XHCI_THIS hub.slots[slot].ep_context[ep].edtla & 0x00FFFFFF),
|
||||||
TRB_SET_COMP_CODE(comp_code) | (BX_XHCI_THIS hub.slots[slot].ep_context[ep].edtla & 0x00FFFFFF),
|
TRB_SET_SLOT(slot) | TRB_SET_EP(ep) | TRB_SET_TYPE(TRANS_EVENT) | (1<<2),
|
||||||
TRB_SET_SLOT(slot) | TRB_SET_EP(ep) | TRB_SET_TYPE(TRANS_EVENT) | (1<<2),
|
ioc);
|
||||||
ioc);
|
|
||||||
} else {
|
|
||||||
write_event_TRB(int_target, trb.parameter, TRB_SET_COMP_CODE(comp_code),
|
|
||||||
TRB_SET_SLOT(slot) | TRB_SET_EP(ep) | TRB_SET_TYPE(TRANS_EVENT) | (1<<2),
|
|
||||||
ioc);
|
|
||||||
}
|
|
||||||
BX_XHCI_THIS hub.slots[slot].ep_context[ep].edtla = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in version 1.00+, we need to check the PARSE_ALL_EVENT bit
|
||||||
|
// to see if we parse all of them
|
||||||
|
#if (((VERSION_MAJOR == 1) && (VERSION_MINOR >= 0x00)) && PARSE_ALL_EVENT)
|
||||||
|
first_event_trb_encountered = 0;
|
||||||
|
#else
|
||||||
if (spd_occurred)
|
if (spd_occurred)
|
||||||
first_event_trb_encountered = 1;
|
first_event_trb_encountered = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
BX_DEBUG(("0x" FORMATADDRESS ": Transfer Ring (slot = %i) (ep = %i) (trnsfrd = %i): Found EVENT_DATA TRB: (returning %i)",
|
BX_DEBUG(("0x" FORMATADDRESS ": Transfer Ring (slot = %i) (ep = %i) (trnsfrd = %i): Found EVENT_DATA TRB: (returning %i)",
|
||||||
(bx_phy_address) org_addr, slot, ep, BX_XHCI_THIS hub.slots[slot].ep_context[ep].edtla, comp_code));
|
(bx_phy_address) org_addr, slot, ep, BX_XHCI_THIS hub.slots[slot].ep_context[ep].edtla, comp_code));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// $Id$
|
// $Id$
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2010-2016 Benjamin D Lunt (fys [at] fysnet [dot] net)
|
// Copyright (C) 2010-2017 Benjamin D Lunt (fys [at] fysnet [dot] net)
|
||||||
// 2011-2017 The Bochs Project
|
// 2011-2017 The Bochs Project
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
@ -558,6 +558,7 @@ private:
|
|||||||
|
|
||||||
static void reset_hc();
|
static void reset_hc();
|
||||||
static void reset_port(int);
|
static void reset_port(int);
|
||||||
|
static void reset_port_usb3(int, const int);
|
||||||
static bx_bool save_hc_state(void);
|
static bx_bool save_hc_state(void);
|
||||||
static bx_bool restore_hc_state(void);
|
static bx_bool restore_hc_state(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user