Updated logging
This commit is contained in:
parent
2680f4b6e8
commit
7bb0ebddd5
|
@ -514,7 +514,7 @@ void Hub::UsbHub_HandleData(XboxDeviceState* dev, USBPacket* p)
|
|||
}
|
||||
if (status != 0) {
|
||||
n = (NUM_PORTS + 1 + 7) / 8;
|
||||
if (p->IoVec.Size == 1) { /* FreeBSD workaround */
|
||||
if (p->IoVec.Size == 1) { // FreeBSD workaround
|
||||
n = 1;
|
||||
}
|
||||
else if (n > p->IoVec.Size) {
|
||||
|
@ -528,7 +528,7 @@ void Hub::UsbHub_HandleData(XboxDeviceState* dev, USBPacket* p)
|
|||
m_UsbDev->USB_PacketCopy(p, buf, n);
|
||||
}
|
||||
else {
|
||||
p->Status = USB_RET_NAK; /* usb11 11.13.1 */
|
||||
p->Status = USB_RET_NAK; // usb11 11.13.1
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "OHCI.h"
|
||||
#include "CxbxKrnl\EmuKrnl.h" // For HalSystemInterrupt
|
||||
|
||||
#define LOG_STR_OHCI "Ohci"
|
||||
|
||||
/* These macros are used to access the bits of the various registers */
|
||||
// HcControl
|
||||
#define OHCI_CTL_CBSR ((1<<0)|(1<<1)) // ControlBulkServiceRatio
|
||||
|
@ -228,7 +230,7 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
OHCI_HCCA hcca;
|
||||
|
||||
if (OHCI_ReadHCCA(m_Registers.HcHCCA, &hcca)) {
|
||||
EmuWarning("Ohci: HCCA read error at physical address 0x%X", m_Registers.HcHCCA);
|
||||
EmuWarning("%s: HCCA read error at physical address 0x%X", m_Registers.HcHCCA, LOG_STR_OHCI);
|
||||
OHCI_FatalError();
|
||||
return;
|
||||
}
|
||||
|
@ -269,7 +271,7 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
if (!m_Registers.HcDoneHead) {
|
||||
// From the standard: "This is set to zero whenever HC writes the content of this
|
||||
// register to HCCA. It also sets the WritebackDoneHead of HcInterruptStatus."
|
||||
CxbxKrnlCleanup("Ohci: HcDoneHead is zero but WritebackDoneHead interrupt is not set!\n");
|
||||
CxbxKrnlCleanup("%s: HcDoneHead is zero but WritebackDoneHead interrupt is not set!\n", LOG_STR_OHCI);
|
||||
}
|
||||
|
||||
if (m_Registers.HcInterrupt & m_Registers.HcInterruptStatus) {
|
||||
|
@ -296,7 +298,7 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
|
||||
// Writeback HCCA
|
||||
if (OHCI_WriteHCCA(m_Registers.HcHCCA, &hcca)) {
|
||||
EmuWarning("Ohci: HCCA write error at physical address 0x%X", m_Registers.HcHCCA);
|
||||
EmuWarning("%s: HCCA write error at physical address 0x%X", LOG_STR_OHCI, m_Registers.HcHCCA);
|
||||
OHCI_FatalError();
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +311,7 @@ void OHCI::OHCI_FatalError()
|
|||
|
||||
OHCI_SetInterrupt(OHCI_INTR_UE);
|
||||
OHCI_BusStop();
|
||||
DbgPrintf("Ohci: an unrecoverable error occoured!\n");
|
||||
DbgPrintf("%s: an unrecoverable error occoured!\n", LOG_STR_OHCI);
|
||||
}
|
||||
|
||||
bool OHCI::OHCI_ReadHCCA(xbaddr Paddr, OHCI_HCCA* Hcca)
|
||||
|
@ -510,7 +512,7 @@ int OHCI::OHCI_ServiceEDlist(xbaddr Head, int Completion)
|
|||
|
||||
for (current = Head; current; current = next_ed) {
|
||||
if (OHCI_ReadED(current, &ed)) {
|
||||
EmuWarning("Ohci: ED read error at physical address 0x%X", current);
|
||||
EmuWarning("%s: ED read error at physical address 0x%X", LOG_STR_OHCI, current);
|
||||
OHCI_FatalError();
|
||||
return 0;
|
||||
}
|
||||
|
@ -551,8 +553,9 @@ int OHCI::OHCI_ServiceEDlist(xbaddr Head, int Completion)
|
|||
}
|
||||
else {
|
||||
// Handle isochronous endpoints
|
||||
if (OHCI_ServiceIsoTD(&ed, Completion))
|
||||
if (OHCI_ServiceIsoTD(&ed, Completion)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,7 +594,7 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
return 1;
|
||||
}
|
||||
if (OHCI_ReadTD(addr, &td)) {
|
||||
EmuWarning("Ohci: TD read error at physical address 0x%X", addr);
|
||||
EmuWarning("%s: TD read error at physical address 0x%X", LOG_STR_OHCI, addr);
|
||||
OHCI_FatalError();
|
||||
return 0;
|
||||
}
|
||||
|
@ -639,7 +642,7 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
pid = USB_TOKEN_SETUP;
|
||||
break;
|
||||
default:
|
||||
EmuWarning("Ohci: bad direction");
|
||||
EmuWarning("%s: bad direction", LOG_STR_OHCI);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -691,7 +694,7 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
// From XQEMU: "??? The hardware should allow one active packet per endpoint.
|
||||
// We only allow one active packet per controller. This should be sufficient
|
||||
// as long as devices respond in a timely manner."
|
||||
DbgPrintf("Ohci: too many pending packets\n");
|
||||
DbgPrintf("%s: too many pending packets\n", LOG_STR_OHCI);
|
||||
return 1;
|
||||
}
|
||||
dev = OHCI_FindDevice(OHCI_BM(Ed->Flags, ED_FA));
|
||||
|
@ -765,29 +768,29 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
}
|
||||
else {
|
||||
if (ret >= 0) {
|
||||
DbgPrintf("Ohci: Underrun\n");
|
||||
DbgPrintf("%s: Underrun\n", LOG_STR_OHCI);
|
||||
OHCI_SET_BM(td.Flags, TD_CC, OHCI_CC_DATAUNDERRUN);
|
||||
}
|
||||
else {
|
||||
switch (ret) {
|
||||
case USB_RET_IOERROR:
|
||||
case USB_RET_NODEV:
|
||||
DbgPrintf("Ohci: Received DEV ERROR\n");
|
||||
DbgPrintf("%s: Received DEV ERROR\n", LOG_STR_OHCI);
|
||||
OHCI_SET_BM(td.Flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING);
|
||||
break;
|
||||
case USB_RET_NAK:
|
||||
DbgPrintf("Ohci: Received NAK\n");
|
||||
DbgPrintf("%s: Received NAK\n", LOG_STR_OHCI);
|
||||
return 1;
|
||||
case USB_RET_STALL:
|
||||
DbgPrintf("Ohci: Received STALL\n");
|
||||
DbgPrintf("%s: Received STALL\n", LOG_STR_OHCI);
|
||||
OHCI_SET_BM(td.Flags, TD_CC, OHCI_CC_STALL);
|
||||
break;
|
||||
case USB_RET_BABBLE:
|
||||
DbgPrintf("Ohci: Received BABBLE\n");
|
||||
DbgPrintf("%s: Received BABBLE\n", LOG_STR_OHCI);
|
||||
OHCI_SET_BM(td.Flags, TD_CC, OHCI_CC_DATAOVERRUN);
|
||||
break;
|
||||
default:
|
||||
DbgPrintf("Ohci: Bad device response %d\n", ret);
|
||||
DbgPrintf("%s: Bad device response %d\n", LOG_STR_OHCI, ret);
|
||||
OHCI_SET_BM(td.Flags, TD_CC, OHCI_CC_UNDEXPETEDPID);
|
||||
OHCI_SET_BM(td.Flags, TD_EC, 3);
|
||||
}
|
||||
|
@ -887,7 +890,7 @@ void OHCI::OHCI_StateReset()
|
|||
|
||||
OHCI_StopEndpoints();
|
||||
|
||||
DbgPrintf("Ohci: Reset mode event.\n");
|
||||
DbgPrintf("%s: Reset mode event.\n", LOG_STR_OHCI);
|
||||
}
|
||||
|
||||
void OHCI::OHCI_BusStart()
|
||||
|
@ -895,7 +898,7 @@ void OHCI::OHCI_BusStart()
|
|||
// Create the EOF timer. Let's try a factor of 50 (1 virtual ms -> 50 real ms)
|
||||
m_pEOFtimer = Timer_Create(OHCI_FrameBoundaryWrapper, this, 50);
|
||||
|
||||
DbgPrintf("Ohci: Operational mode event\n");
|
||||
DbgPrintf("%s: Operational mode event\n", LOG_STR_OHCI);
|
||||
|
||||
// SOF event
|
||||
OHCI_SOF(true);
|
||||
|
@ -942,11 +945,11 @@ void OHCI::OHCI_ChangeState(uint32_t Value)
|
|||
|
||||
case Suspend:
|
||||
OHCI_BusStop();
|
||||
DbgPrintf("Ohci: Suspend mode event\n");
|
||||
DbgPrintf("%s: Suspend mode event\n", LOG_STR_OHCI);
|
||||
break;
|
||||
|
||||
case Resume:
|
||||
DbgPrintf("Ohci: Resume mode event\n");
|
||||
DbgPrintf("%s: Resume mode event\n", LOG_STR_OHCI);
|
||||
break;
|
||||
|
||||
case Reset:
|
||||
|
@ -954,7 +957,7 @@ void OHCI::OHCI_ChangeState(uint32_t Value)
|
|||
break;
|
||||
|
||||
default:
|
||||
EmuWarning("Ohci: Unknown USB mode!");
|
||||
EmuWarning("%s: Unknown USB mode!", LOG_STR_OHCI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -973,7 +976,7 @@ uint32_t OHCI::OHCI_ReadRegister(xbaddr Addr)
|
|||
|
||||
if (Addr & 3) {
|
||||
// The standard allows only aligned reads to the registers
|
||||
DbgPrintf("Ohci: Unaligned read. Ignoring.\n");
|
||||
DbgPrintf("%s: Unaligned read. Ignoring.\n", LOG_STR_OHCI);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
|
@ -1070,7 +1073,7 @@ uint32_t OHCI::OHCI_ReadRegister(xbaddr Addr)
|
|||
break;
|
||||
|
||||
default:
|
||||
EmuWarning("Ohci: Read register operation with bad offset %u. Ignoring.", Addr >> 2);
|
||||
EmuWarning("%s: Read register operation with bad offset %u. Ignoring.", LOG_STR_OHCI, Addr >> 2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1080,7 +1083,7 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value)
|
|||
{
|
||||
if (Addr & 3) {
|
||||
// The standard allows only aligned writes to the registers
|
||||
DbgPrintf("Ohci: Unaligned write. Ignoring.\n");
|
||||
DbgPrintf("%s: Unaligned write. Ignoring.\n", LOG_STR_OHCI);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
@ -1157,7 +1160,7 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value)
|
|||
case 13: // HcFmInterval
|
||||
{
|
||||
if ((Value & OHCI_FMI_FIT) != (m_Registers.HcFmInterval & OHCI_FMI_FIT)) {
|
||||
DbgPrintf("Ohci: Changing frame interval duration. New value is %u\n", Value & OHCI_FMI_FI);
|
||||
DbgPrintf("%s: Changing frame interval duration. New value is %u\n", LOG_STR_OHCI, Value & OHCI_FMI_FI);
|
||||
}
|
||||
m_Registers.HcFmInterval = Value & ~0xC000;
|
||||
}
|
||||
|
@ -1201,7 +1204,7 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value)
|
|||
break;
|
||||
|
||||
default:
|
||||
EmuWarning("Ohci: Write register operation with bad offset %u. Ignoring.", Addr >> 2);
|
||||
EmuWarning("%s: Write register operation with bad offset %u. Ignoring.", LOG_STR_OHCI, Addr >> 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1277,7 +1280,7 @@ void OHCI::OHCI_SetHubStatus(uint32_t Value)
|
|||
for (i = 0; i < 2; i++) {
|
||||
OHCI_PortPower(i, 0);
|
||||
}
|
||||
DbgPrintf("Ohci: powered down all ports\n");
|
||||
DbgPrintf("%s: powered down all ports\n", LOG_STR_OHCI);
|
||||
}
|
||||
|
||||
if (Value & OHCI_RHS_LPSC) {
|
||||
|
@ -1286,7 +1289,7 @@ void OHCI::OHCI_SetHubStatus(uint32_t Value)
|
|||
for (i = 0; i < 2; i++) {
|
||||
OHCI_PortPower(i, 1);
|
||||
}
|
||||
DbgPrintf("Ohci: powered up all ports\n");
|
||||
DbgPrintf("%s: powered up all ports\n", LOG_STR_OHCI);
|
||||
}
|
||||
|
||||
if (Value & OHCI_RHS_DRWE) {
|
||||
|
@ -1335,11 +1338,11 @@ void OHCI::OHCI_PortSetStatus(int PortNum, uint32_t Value)
|
|||
OHCI_PortSetIfConnected(PortNum, Value & OHCI_PORT_PES);
|
||||
|
||||
if (OHCI_PortSetIfConnected(PortNum, Value & OHCI_PORT_PSS)) {
|
||||
DbgPrintf("Ohci: port %d: SUSPEND\n", PortNum);
|
||||
DbgPrintf("%s: port %d: SUSPEND\n", LOG_STR_OHCI, PortNum);
|
||||
}
|
||||
|
||||
if (OHCI_PortSetIfConnected(PortNum, Value & OHCI_PORT_PRS)) {
|
||||
DbgPrintf("Ohci: port %d: RESET\n", PortNum);
|
||||
DbgPrintf("%s: port %d: RESET\n", LOG_STR_OHCI, PortNum);
|
||||
m_UsbDevice->USB_DeviceReset(port->UsbPort.Dev);
|
||||
port->HcRhPortStatus &= ~OHCI_PORT_PRS;
|
||||
// ??? Should this also set OHCI_PORT_PESC
|
||||
|
@ -1407,7 +1410,7 @@ void OHCI::OHCI_Detach(USBPort* Port)
|
|||
port->HcRhPortStatus |= OHCI_PORT_PESC;
|
||||
}
|
||||
|
||||
DbgPrintf("Ohci: Detached port %d\n", Port->PortIndex);
|
||||
DbgPrintf("%s: Detached port %d\n", LOG_STR_OHCI, Port->PortIndex);
|
||||
|
||||
if (old_state != port->HcRhPortStatus) {
|
||||
OHCI_SetInterrupt(OHCI_INTR_RHSC);
|
||||
|
@ -1435,7 +1438,7 @@ void OHCI::OHCI_Attach(USBPort* Port)
|
|||
OHCI_SetInterrupt(OHCI_INTR_RD);
|
||||
}
|
||||
|
||||
DbgPrintf("Ohci: Attached port %d\n", Port->PortIndex);
|
||||
DbgPrintf("%s: Attached port %d\n", LOG_STR_OHCI, Port->PortIndex);
|
||||
|
||||
if (old_state != port->HcRhPortStatus) {
|
||||
OHCI_SetInterrupt(OHCI_INTR_RHSC);
|
||||
|
@ -1452,14 +1455,14 @@ void OHCI::OHCI_Wakeup(USBPort* port1)
|
|||
OHCIPort* port = &m_Registers.RhPort[port1->PortIndex];
|
||||
uint32_t intr = 0;
|
||||
if (port->HcRhPortStatus & OHCI_PORT_PSS) {
|
||||
DbgPrintf("Ohci: port %d: wakeup\n", port1->PortIndex);
|
||||
DbgPrintf("%s: port %d: wakeup\n", LOG_STR_OHCI, port1->PortIndex);
|
||||
port->HcRhPortStatus |= OHCI_PORT_PSSC;
|
||||
port->HcRhPortStatus &= ~OHCI_PORT_PSS;
|
||||
intr = OHCI_INTR_RHSC;
|
||||
}
|
||||
// Note that the controller can be suspended even if this port is not
|
||||
if ((m_Registers.HcControl & OHCI_CTL_HCFS) == Suspend) {
|
||||
DbgPrintf("Ohci: remote-wakeup: SUSPEND->RESUME\n");
|
||||
DbgPrintf("%s: remote-wakeup: SUSPEND->RESUME\n", LOG_STR_OHCI);
|
||||
// From the standard: "The only interrupts possible in the USBSUSPEND state are ResumeDetected (the
|
||||
// Host Controller will have changed the HostControllerFunctionalState to the USBRESUME state)
|
||||
// and OwnershipChange."
|
||||
|
@ -1494,8 +1497,8 @@ void OHCI::OHCI_ProcessLists(int completion)
|
|||
// Only process the control list if it is enabled (HcControl) and has available TD's (HcCommandStatus)
|
||||
if ((m_Registers.HcControl & OHCI_CTL_CLE) && (m_Registers.HcCommandStatus & OHCI_STATUS_CLF)) {
|
||||
if (m_Registers.HcControlCurrentED && m_Registers.HcControlCurrentED != m_Registers.HcControlHeadED) {
|
||||
DbgPrintf("Ohci: head 0x%X, current 0x%X\n",
|
||||
m_Registers.HcControlHeadED, m_Registers.HcControlCurrentED);
|
||||
DbgPrintf("%s: head 0x%X, current 0x%X\n",
|
||||
LOG_STR_OHCI, m_Registers.HcControlHeadED, m_Registers.HcControlCurrentED);
|
||||
}
|
||||
if (!OHCI_ServiceEDlist(m_Registers.HcControlHeadED, completion)) {
|
||||
m_Registers.HcControlCurrentED = 0;
|
||||
|
@ -1535,7 +1538,7 @@ int OHCI::OHCI_ServiceIsoTD(OHCI_ED* ed, int completion)
|
|||
addr = ed->HeadP & OHCI_DPTR_MASK;
|
||||
|
||||
if (OHCI_ReadIsoTD(addr, &iso_td)) {
|
||||
DbgPrintf("Ohci: ISO_TD read error at physical address 0x%X\n", addr);
|
||||
DbgPrintf("%s: ISO_TD read error at physical address 0x%X\n", LOG_STR_OHCI, addr);
|
||||
OHCI_FatalError();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1566,13 +1569,13 @@ int OHCI::OHCI_ServiceIsoTD(OHCI_ED* ed, int completion)
|
|||
if (relative_frame_number < 0) {
|
||||
// From the standard: "If the relative frame number is negative, then the current frame is earlier than the 0th frame
|
||||
// of the Isochronous TD and the Host Controller advances to the next ED."
|
||||
DbgPrintf("Ohci: ISO_TD R=%d < 0\n", relative_frame_number);
|
||||
DbgPrintf("%s: ISO_TD R=%d < 0\n", LOG_STR_OHCI, relative_frame_number);
|
||||
return 1;
|
||||
}
|
||||
else if (relative_frame_number > frame_count) {
|
||||
// From the standard: "If the relative frame number is greater than
|
||||
// FrameCount, then the Isochronous TD has expired and a error condition exists."
|
||||
DbgPrintf("Ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number, frame_count);
|
||||
DbgPrintf("%s: ISO_TD R=%d > FC=%d\n", LOG_STR_OHCI, relative_frame_number, frame_count);
|
||||
OHCI_SET_BM(iso_td.Flags, TD_CC, OHCI_CC_DATAOVERRUN);
|
||||
ed->HeadP &= ~OHCI_DPTR_MASK;
|
||||
ed->HeadP |= (iso_td.NextTD & OHCI_DPTR_MASK);
|
||||
|
@ -1613,12 +1616,12 @@ int OHCI::OHCI_ServiceIsoTD(OHCI_ED* ed, int completion)
|
|||
pid = USB_TOKEN_SETUP;
|
||||
break;
|
||||
default:
|
||||
EmuWarning("Ohci: Bad direction %d", dir);
|
||||
EmuWarning("%s: Bad direction %d", LOG_STR_OHCI, dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!iso_td.BufferPage0 || !iso_td.BufferEnd) {
|
||||
DbgPrintf("Ohci: ISO_TD bp 0x%.8X be 0x%.8X\n", iso_td.BufferPage0, iso_td.BufferEnd);
|
||||
DbgPrintf("%s: ISO_TD bp 0x%.8X be 0x%.8X\n", LOG_STR_OHCI, iso_td.BufferPage0, iso_td.BufferEnd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1636,12 +1639,12 @@ int OHCI::OHCI_ServiceIsoTD(OHCI_ED* ed, int completion)
|
|||
if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xE) ||
|
||||
((relative_frame_number < frame_count) &&
|
||||
!(OHCI_BM(next_offset, TD_PSW_CC) & 0xE))) {
|
||||
DbgPrintf("Ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n", start_offset, next_offset);
|
||||
DbgPrintf("%s: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n", LOG_STR_OHCI, start_offset, next_offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
|
||||
printf("Ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n", start_offset, next_offset);
|
||||
printf("%s: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n", LOG_STR_OHCI, start_offset, next_offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1739,12 +1742,12 @@ int OHCI::OHCI_ServiceIsoTD(OHCI_ED* ed, int completion)
|
|||
else {
|
||||
// Handle the error condition
|
||||
if (ret > static_cast<ptrdiff_t>(len)) { // Sequence Error
|
||||
DbgPrintf("Ohci: DataOverrun %d > %zu\n", ret, len);
|
||||
DbgPrintf("%s: DataOverrun %d > %zu\n", LOG_STR_OHCI, ret, len);
|
||||
OHCI_SET_BM(iso_td.Offset[relative_frame_number], TD_PSW_CC, OHCI_CC_DATAOVERRUN);
|
||||
OHCI_SET_BM(iso_td.Offset[relative_frame_number], TD_PSW_SIZE, len);
|
||||
}
|
||||
else if (ret >= 0) { // Sequence Error
|
||||
DbgPrintf("Ohci: DataUnderrun %d\n", ret);
|
||||
DbgPrintf("%s: DataUnderrun %d\n", LOG_STR_OHCI, ret);
|
||||
OHCI_SET_BM(iso_td.Offset[relative_frame_number], TD_PSW_CC, OHCI_CC_DATAUNDERRUN);
|
||||
}
|
||||
else {
|
||||
|
@ -1756,12 +1759,12 @@ int OHCI::OHCI_ServiceIsoTD(OHCI_ED* ed, int completion)
|
|||
break;
|
||||
case USB_RET_NAK: // NAK and STALL
|
||||
case USB_RET_STALL:
|
||||
DbgPrintf("Ohci: got NAK/STALL %d\n", ret);
|
||||
DbgPrintf("%s: got NAK/STALL %d\n", LOG_STR_OHCI, ret);
|
||||
OHCI_SET_BM(iso_td.Offset[relative_frame_number], TD_PSW_CC, OHCI_CC_STALL);
|
||||
OHCI_SET_BM(iso_td.Offset[relative_frame_number], TD_PSW_SIZE, 0);
|
||||
break;
|
||||
default: // Unknown Error
|
||||
DbgPrintf("Ohci: Bad device response %d\n", ret);
|
||||
DbgPrintf("%s: Bad device response %d\n", LOG_STR_OHCI, ret);
|
||||
OHCI_SET_BM(iso_td.Offset[relative_frame_number], TD_PSW_CC, OHCI_CC_UNDEXPETEDPID);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "OHCI.h"
|
||||
#include "CxbxKrnl\EmuKrnl.h" // For EmuWarning
|
||||
|
||||
#define LOG_STR_USB "Usb"
|
||||
|
||||
#define SETUP_STATE_IDLE 0
|
||||
#define SETUP_STATE_SETUP 1
|
||||
#define SETUP_STATE_DATA 2
|
||||
|
@ -130,7 +132,7 @@ void USBDevice::USB_Detach(USBPort* Port)
|
|||
|
||||
assert(dev != nullptr);
|
||||
assert(dev->State != USB_STATE_NOTATTACHED);
|
||||
m_HostController->OHCI_Detach(Port);
|
||||
Port->Operations->detach(Port);
|
||||
dev->State = USB_STATE_NOTATTACHED;
|
||||
}
|
||||
|
||||
|
@ -238,8 +240,7 @@ void USBDevice::USB_HandlePacket(XboxDeviceState* dev, USBPacket* p)
|
|||
// hcd drivers cannot handle async for isoc
|
||||
assert(p->Endpoint->Type != USB_ENDPOINT_XFER_ISOC);
|
||||
// using async for interrupt packets breaks migration
|
||||
assert(p->Endpoint->Type != USB_ENDPOINT_XFER_INT ||
|
||||
(dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
|
||||
assert(p->Endpoint->Type != USB_ENDPOINT_XFER_INT);
|
||||
p->State = USB_PACKET_ASYNC;
|
||||
QTAILQ_INSERT_TAIL(&p->Endpoint->Queue, p, Queue);
|
||||
}
|
||||
|
@ -249,7 +250,7 @@ void USBDevice::USB_HandlePacket(XboxDeviceState* dev, USBPacket* p)
|
|||
else {
|
||||
// When pipelining is enabled usb-devices must always return async,
|
||||
// otherwise packets can complete out of order!
|
||||
assert(p->stream || !p->Endpoint->pipeline ||
|
||||
assert(p->Stream || !p->Endpoint->Pipeline ||
|
||||
QTAILQ_EMPTY(&p->Endpoint->Queue));
|
||||
if (p->Status != USB_RET_NAK) {
|
||||
p->State = USB_PACKET_COMPLETE;
|
||||
|
@ -274,7 +275,7 @@ void USBDevice::USB_PacketCheckState(USBPacket* p, USBPacketState expected)
|
|||
return;
|
||||
}
|
||||
|
||||
EmuWarning("Usb: packet state check failed!");
|
||||
EmuWarning("%s: packet state check failed!", LOG_STR_USB);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
@ -295,15 +296,21 @@ void USBDevice::USB_ProcessOne(USBPacket* p)
|
|||
return;
|
||||
}
|
||||
switch (p->Pid) {
|
||||
case USB_TOKEN_SETUP:
|
||||
case USB_TOKEN_SETUP: {
|
||||
USB_DoTokenSetup(dev, p);
|
||||
break;
|
||||
case USB_TOKEN_IN:
|
||||
}
|
||||
|
||||
case USB_TOKEN_IN: {
|
||||
DoTokenIn(dev, p);
|
||||
break;
|
||||
case USB_TOKEN_OUT:
|
||||
}
|
||||
|
||||
case USB_TOKEN_OUT: {
|
||||
DoTokenOut(dev, p);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
p->Status = USB_RET_STALL;
|
||||
}
|
||||
|
@ -331,7 +338,7 @@ void USBDevice::USB_DoParameter(XboxDeviceState* s, USBPacket* p)
|
|||
index = (s->SetupBuffer[5] << 8) | s->SetupBuffer[4];
|
||||
|
||||
if (s->SetupLength > sizeof(s->DataBuffer)) {
|
||||
DbgPrintf("Usb: ctrl buffer too small (%d > %zu)\n", s->SetupLength, sizeof(s->DataBuffer));
|
||||
DbgPrintf("%s: ctrl buffer too small (%d > %zu)\n", LOG_STR_USB, s->SetupLength, sizeof(s->DataBuffer));
|
||||
p->Status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
@ -389,7 +396,6 @@ void USBDevice::USB_DoTokenSetup(XboxDeviceState* s, USBPacket* p)
|
|||
if (p->Status != USB_RET_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->ActualLength < s->SetupLength) {
|
||||
s->SetupLength = p->ActualLength;
|
||||
}
|
||||
|
@ -397,7 +403,7 @@ void USBDevice::USB_DoTokenSetup(XboxDeviceState* s, USBPacket* p)
|
|||
}
|
||||
else {
|
||||
if (s->SetupLength > sizeof(s->DataBuffer)) {
|
||||
DbgPrintf("Usb: ctrl buffer too small (%d > %zu)\n", s->SetupLength, sizeof(s->DataBuffer));
|
||||
DbgPrintf("%s: ctrl buffer too small (%d > %zu)\n", LOG_STR_USB, s->SetupLength, sizeof(s->DataBuffer));
|
||||
p->Status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
@ -416,7 +422,7 @@ void USBDevice::DoTokenIn(XboxDeviceState* s, USBPacket* p)
|
|||
{
|
||||
int request, value, index;
|
||||
|
||||
assert(p->ep->nr == 0);
|
||||
assert(p->Endpoint->Num == 0);
|
||||
|
||||
request = (s->SetupBuffer[0] << 8) | s->SetupBuffer[1];
|
||||
value = (s->SetupBuffer[3] << 8) | s->SetupBuffer[2];
|
||||
|
@ -458,16 +464,16 @@ void USBDevice::DoTokenIn(XboxDeviceState* s, USBPacket* p)
|
|||
|
||||
void USBDevice::DoTokenOut(XboxDeviceState* s, USBPacket* p)
|
||||
{
|
||||
assert(p->ep->nr == 0);
|
||||
assert(p->Endpoint->Num == 0);
|
||||
|
||||
switch (s->SetupState) {
|
||||
case SETUP_STATE_ACK:
|
||||
if (s->SetupBuffer[0] & USB_DIR_IN) {
|
||||
s->SetupState = SETUP_STATE_IDLE;
|
||||
/* transfer OK */
|
||||
// transfer OK
|
||||
}
|
||||
else {
|
||||
/* ignore additional output */
|
||||
// ignore additional output
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -508,7 +514,7 @@ void USBDevice::USB_PacketCopy(USBPacket* p, void* ptr, size_t bytes)
|
|||
IoVecFromBuffer(iov->IoVecStruct, iov->IoVecNumber, p->ActualLength, ptr, bytes);
|
||||
break;
|
||||
default:
|
||||
CxbxKrnlCleanup("Usb: %s has an invalid pid: %x\n", __func__, p->Pid);
|
||||
CxbxKrnlCleanup("%s: %s has an invalid pid: %x\n", LOG_STR_USB, __func__, p->Pid);
|
||||
}
|
||||
p->ActualLength += bytes;
|
||||
}
|
||||
|
@ -545,7 +551,7 @@ void USBDevice::USB_DeviceHandleDestroy(XboxDeviceState* dev)
|
|||
{
|
||||
USBDeviceClass* klass = dev->klass;
|
||||
if (klass->handle_destroy) {
|
||||
klass->handle_destroy(dev);
|
||||
klass->handle_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,7 +765,7 @@ void USBDevice::USBDesc_SetDefaults(XboxDeviceState* dev)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
EmuWarning("Unknown speed parameter %d set in %s", dev->ProductDesc.c_str());
|
||||
EmuWarning("%s: unknown speed parameter %d set in %s", LOG_STR_USB, dev->ProductDesc.c_str());
|
||||
}
|
||||
USBDesc_SetConfig(dev, 0);
|
||||
}
|
||||
|
@ -878,7 +884,7 @@ int USBDevice::USBDesc_HandleControl(XboxDeviceState* dev, USBPacket *p,
|
|||
// From the standard: "This request sets the device address for all future device accesses.
|
||||
// The wValue field specifies the device address to use for all subsequent accesses"
|
||||
dev->Addr = value;
|
||||
DbgPrintf("Address 0x%X set for device %s\n", dev->Addr, dev->ProductDesc.c_str());
|
||||
DbgPrintf("%s: address 0x%X set for device %s\n", LOG_STR_USB, dev->Addr, dev->ProductDesc.c_str());
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -904,8 +910,8 @@ int USBDevice::USBDesc_HandleControl(XboxDeviceState* dev, USBPacket *p,
|
|||
// From the standard: "This request sets the device configuration. The lower byte of the wValue field specifies the desired configuration.
|
||||
// This configuration value must be zero or match a configuration value from a configuration descriptor"
|
||||
ret = USBDesc_SetConfig(dev, value);
|
||||
DbgPrintf("Received standard SetConfiguration() request for device at address 0x%X. Configuration selected is %d and returned %d\n",
|
||||
dev->Addr, value, ret);
|
||||
DbgPrintf("%s: received standard SetConfiguration() request for device at address 0x%X. Configuration selected is %d and returned %d\n",
|
||||
LOG_STR_USB, dev->Addr, value, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -938,8 +944,8 @@ int USBDevice::USBDesc_HandleControl(XboxDeviceState* dev, USBPacket *p,
|
|||
dev->RemoteWakeup = 0;
|
||||
ret = 0;
|
||||
}
|
||||
DbgPrintf("Received standard ClearFeature() request for device at address 0x%X. Feature selected is %d and returned %d\n",
|
||||
dev->Addr, value, ret);
|
||||
DbgPrintf("%s: received standard ClearFeature() request for device at address 0x%X. Feature selected is %d and returned %d\n",
|
||||
LOG_STR_USB, dev->Addr, value, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -950,8 +956,8 @@ int USBDevice::USBDesc_HandleControl(XboxDeviceState* dev, USBPacket *p,
|
|||
dev->RemoteWakeup = 1;
|
||||
ret = 0;
|
||||
}
|
||||
DbgPrintf("Received standard SetFeature() request for device at address 0x%X. Feature selected is %d and returned %d\n",
|
||||
dev->Addr, value, ret);
|
||||
DbgPrintf("%s: received standard SetFeature() request for device at address 0x%X. Feature selected is %d and returned %d\n",
|
||||
LOG_STR_USB, dev->Addr, value, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -971,8 +977,8 @@ int USBDevice::USBDesc_HandleControl(XboxDeviceState* dev, USBPacket *p,
|
|||
// From the standard: "This request allows the host to select an alternate setting for the specified interface"
|
||||
// wValue = Alternative Setting; wIndex = Interface
|
||||
ret = USBDesc_SetInterface(dev, index, value);
|
||||
DbgPrintf("Received standard SetInterface() request for device at address 0x%X. Interface selected is %d, Alternative Setting \
|
||||
is %d and returned %d\n", dev->Addr, index, value, ret);
|
||||
DbgPrintf("%s; received standard SetInterface() request for device at address 0x%X. Interface selected is %d, Alternative Setting \
|
||||
is %d and returned %d\n", LOG_STR_USB, dev->Addr, index, value, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -999,7 +1005,7 @@ int USBDevice::USBDesc_HandleStandardGetDescriptor(XboxDeviceState* dev, USBPack
|
|||
switch (type) {
|
||||
case USB_DT_DEVICE: {
|
||||
ret = USB_ReadDeviceDesc(&desc->id, dev->Device, buf, sizeof(buf));
|
||||
DbgPrintf("Read operation of device descriptor of device 0x%X returns %d\n", dev->Addr, ret);
|
||||
DbgPrintf("%s: read operation of device descriptor of device 0x%X returns %d\n", LOG_STR_USB, dev->Addr, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1007,13 +1013,13 @@ int USBDevice::USBDesc_HandleStandardGetDescriptor(XboxDeviceState* dev, USBPack
|
|||
if (index < dev->Device->bNumConfigurations) {
|
||||
ret = USB_ReadConfigurationDesc(dev->Device->confs + index, flags, buf, sizeof(buf));
|
||||
}
|
||||
DbgPrintf("Read operation of configuration descriptor %d of device 0x%X returns %d\n", index, dev->Addr, ret);
|
||||
DbgPrintf("%s: read operation of configuration descriptor %d of device 0x%X returns %d\n", LOG_STR_USB, index, dev->Addr, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_DT_STRING: {
|
||||
ret = USB_ReadStringDesc(dev, index, buf, sizeof(buf));
|
||||
DbgPrintf("Read operation of string descriptor %d of device 0x%X returns %d\n", index, dev->Addr, ret);
|
||||
DbgPrintf("%s: read operation of string descriptor %d of device 0x%X returns %d\n", LOG_STR_USB, index, dev->Addr, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1027,7 @@ int USBDevice::USBDesc_HandleStandardGetDescriptor(XboxDeviceState* dev, USBPack
|
|||
// USB_DT_BOS (15) and USB_DT_DEBUG (10) -> usb 3.0 only
|
||||
|
||||
default:
|
||||
EmuWarning("%s: device address %d unknown type %d (len %zd)", __func__, dev->Addr, type, len);
|
||||
EmuWarning("%s: %s has a device address %d of unknown type %d (len %zd)", LOG_STR_USB, __func__, dev->Addr, type, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -330,8 +330,7 @@ struct USBEndpoint {
|
|||
struct XboxDeviceState {
|
||||
USBPort* Port; // usb port struct of this device
|
||||
int PortPath; // port index to which this device is attached to
|
||||
char* Serial;
|
||||
uint32_t flags;
|
||||
char* Serial;
|
||||
USBDeviceClass* klass; // usb class struct of this device
|
||||
|
||||
int Speed; // actual speed of the connected device
|
||||
|
@ -344,7 +343,7 @@ struct XboxDeviceState {
|
|||
uint8_t SetupBuffer[8]; // setup packet buffer - 8 bytes (control transfers only)
|
||||
uint8_t DataBuffer[4096]; // buffer where to write the data requested during usb requests
|
||||
int32_t RemoteWakeup; // wakeup flag
|
||||
int32_t SetupState; // result of a setup tken processing operation
|
||||
int32_t SetupState; // result of a control transfer processing operation
|
||||
int32_t SetupLength; // this field specifies the length of the data transferred during the second phase of the control transfer
|
||||
int32_t SetupIndex; // index of the parameter in a setup token?
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "XidGamepad.h"
|
||||
#include "USBDevice.h"
|
||||
|
||||
#define LOG_STR_GAMEPAD "Gamepad"
|
||||
|
||||
#define USB_CLASS_XID 0x58
|
||||
#define USB_DT_XID 0x42
|
||||
|
||||
|
@ -290,7 +292,7 @@ void XidGamepad::UsbXid_Attach(XboxDeviceState* dev)
|
|||
|
||||
void XidGamepad::UsbXid_HandleReset()
|
||||
{
|
||||
DbgPrintf("Gamepad reset event\n");
|
||||
DbgPrintf("%s reset event\n", LOG_STR_GAMEPAD);
|
||||
}
|
||||
|
||||
void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
||||
|
@ -298,7 +300,7 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
{
|
||||
int ret = m_UsbDev->USBDesc_HandleControl(dev, p, request, value, index, length, data);
|
||||
if (ret >= 0) {
|
||||
DbgPrintf("Gamepad handled by USBDesc_HandleControl, ret is %d\n", ret);
|
||||
DbgPrintf("%s handled by USBDesc_HandleControl, ret is %d\n", LOG_STR_GAMEPAD, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -308,7 +310,7 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
// From the HID standard: "The Get_Report request allows the host to receive a report via the Control pipe.
|
||||
// The wValue field specifies the Report Type in the high byte and the Report ID in the low byte. Set Report ID
|
||||
// to 0 (zero) if Report IDs are not used. 01 = input, 02 = output, 03 = feature, 04-FF = reserved"
|
||||
DbgPrintf("Gamepad GET_REPORT 0x%X\n", value);
|
||||
DbgPrintf("%s GET_REPORT 0x%X\n", LOG_STR_GAMEPAD, value);
|
||||
if (value == 0x100) {
|
||||
assert(m_XidState->in_state.bLength <= length);
|
||||
// m_XidState->in_state.bReportId++; /* FIXME: I'm not sure if bReportId is just a counter */
|
||||
|
@ -326,7 +328,7 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
// setting the state of input, output, or feature controls. The meaning of the request fields for the Set_Report
|
||||
// request is the same as for the Get_Report request, however the data direction is reversed and the Report
|
||||
// Data is sent from host to device."
|
||||
DbgPrintf("Gamepad SET_REPORT 0x%X\n", value);
|
||||
DbgPrintf("%s SET_REPORT 0x%X\n", LOG_STR_GAMEPAD, value);
|
||||
if (value == 0x200) {
|
||||
// Read length, then the entire packet
|
||||
std::memcpy(&m_XidState->out_state, data, sizeof(m_XidState->out_state));
|
||||
|
@ -346,7 +348,7 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
|
||||
// XID-specific requests
|
||||
case VendorInterfaceRequest | USB_REQ_GET_DESCRIPTOR: {
|
||||
DbgPrintf("Gamepad GET_DESCRIPTOR 0x%x\n", value);
|
||||
DbgPrintf("%s GET_DESCRIPTOR 0x%x\n", LOG_STR_GAMEPAD, value);
|
||||
if (value == 0x4200) {
|
||||
assert(m_XidState->xid_desc->bLength <= length);
|
||||
std::memcpy(data, m_XidState->xid_desc, m_XidState->xid_desc->bLength);
|
||||
|
@ -359,7 +361,7 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
}
|
||||
|
||||
case VendorInterfaceRequest | XID_GET_CAPABILITIES: {
|
||||
DbgPrintf("Gamepad XID_GET_CAPABILITIES 0x%x\n", value);
|
||||
DbgPrintf("%s XID_GET_CAPABILITIES 0x%x\n", LOG_STR_GAMEPAD, value);
|
||||
/* FIXME: ! */
|
||||
p->Status = USB_RET_STALL;
|
||||
//assert(false);
|
||||
|
@ -368,7 +370,7 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
|
||||
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8) | USB_REQ_GET_DESCRIPTOR: {
|
||||
/* FIXME: ! */
|
||||
DbgPrintf("Gamepad unknown xpad request 0x%X: value = 0x%X\n", request, value);
|
||||
DbgPrintf("%s unknown xpad request 0x%X: value = 0x%X\n", LOG_STR_GAMEPAD, request, value);
|
||||
std::memset(data, 0x00, length);
|
||||
//FIXME: Intended for the hub: usbd_get_hub_descriptor, UT_READ_CLASS?!
|
||||
p->Status = USB_RET_STALL;
|
||||
|
@ -378,14 +380,14 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
|
||||
case ((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) << 8) | USB_REQ_CLEAR_FEATURE: {
|
||||
/* FIXME: ! */
|
||||
DbgPrintf("Gamepad unknown xpad request 0x%X: value = 0x%X\n", request, value);
|
||||
DbgPrintf("%s unknown xpad request 0x%X: value = 0x%X\n", LOG_STR_GAMEPAD, request, value);
|
||||
std::memset(data, 0x00, length);
|
||||
p->Status = USB_RET_STALL;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DbgPrintf("Gamepad USB stalled on request 0x%X value 0x%X\n", request, value);
|
||||
DbgPrintf("%s USB stalled on request 0x%X value 0x%X\n", LOG_STR_GAMEPAD, request, value);
|
||||
p->Status = USB_RET_STALL;
|
||||
assert(0);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue