Finally finished Hub initialization!

This commit is contained in:
ergo720 2018-07-03 16:08:12 +02:00
parent 13b20e6741
commit 4e3d0b307a
7 changed files with 122 additions and 70 deletions

View File

@ -170,22 +170,16 @@ int Hub::Init(int pport)
UsbReleasePort(m_pDeviceStruct); UsbReleasePort(m_pDeviceStruct);
return rc; return rc;
} }
rc = usb_device_attach(dev); m_UsbDev->USB_DeviceAttach(m_pDeviceStruct);
if (rc != 0) {
usb_qdev_exit(qdev); return 0;
return rc;
}
} }
Hub::~Hub() Hub::~Hub()
{
HubCleanUp();
}
void Hub::HubCleanUp()
{ {
delete m_pPeripheralFuncStruct; delete m_pPeripheralFuncStruct;
delete m_pDeviceStruct; delete m_HubState->ports[0].port.Operations;
delete m_HubState;
m_pPeripheralFuncStruct = nullptr; m_pPeripheralFuncStruct = nullptr;
m_pDeviceStruct = nullptr; m_pDeviceStruct = nullptr;
} }
@ -205,7 +199,7 @@ void Hub::ClassInitFn()
m_pPeripheralFuncStruct->init = std::bind(&Hub::UsbHub_Initfn, this, _1); m_pPeripheralFuncStruct->init = std::bind(&Hub::UsbHub_Initfn, this, _1);
m_pPeripheralFuncStruct->find_device = std::bind(&Hub::UsbHub_FindDevice, this, _1, _2); m_pPeripheralFuncStruct->find_device = std::bind(&Hub::UsbHub_FindDevice, this, _1, _2);
m_pPeripheralFuncStruct->handle_reset = std::bind(&Hub::UsbHub_HandleReset, this, _1); m_pPeripheralFuncStruct->handle_reset = std::bind(&Hub::UsbHub_HandleReset, this);
m_pPeripheralFuncStruct->handle_control = std::bind(&Hub::UsbHub_HandleControl, this, _1, _2, _3, _4, _5, _6, _7); m_pPeripheralFuncStruct->handle_control = std::bind(&Hub::UsbHub_HandleControl, this, _1, _2, _3, _4, _5, _6, _7);
m_pPeripheralFuncStruct->handle_data = std::bind(&Hub::UsbHub_HandleData, this, _1, _2); m_pPeripheralFuncStruct->handle_data = std::bind(&Hub::UsbHub_HandleData, this, _1, _2);
m_pPeripheralFuncStruct->handle_destroy = std::bind(&Hub::UsbHub_HandleDestroy, this, _1); m_pPeripheralFuncStruct->handle_destroy = std::bind(&Hub::UsbHub_HandleDestroy, this, _1);
@ -283,8 +277,8 @@ void Hub::UsbReleasePort(XboxDeviceState* dev)
int Hub::UsbHub_Initfn(XboxDeviceState* dev) int Hub::UsbHub_Initfn(XboxDeviceState* dev)
{ {
USBHubState* s = container_of(dev, USBHubState, dev);
USBHubPort* port; USBHubPort* port;
USBPortOps* ops;
int i; int i;
if (dev->Port->HubCount == 5) { if (dev->Port->HubCount == 5) {
@ -294,23 +288,34 @@ int Hub::UsbHub_Initfn(XboxDeviceState* dev)
CreateSerial(dev); CreateSerial(dev);
UsbDescInit(dev); UsbDescInit(dev);
s->intr = m_UsbDev->USB_GetEP(dev, USB_TOKEN_IN, 1); m_HubState->intr = m_UsbDev->USB_GetEP(dev, USB_TOKEN_IN, 1);
ops = new USBPortOps();
{
using namespace std::placeholders;
ops->attach = std::bind(&Hub::UsbHub_Attach, this, _1);
ops->detach = std::bind(&Hub::UsbHub_Detach, this, _1);
ops->child_detach = std::bind(&Hub::UsbHub_ChildDetach, this, _1, _2);
ops->wakeup = std::bind(&Hub::UsbHub_Wakeup, this, _1);
ops->complete = std::bind(&Hub::UsbHub_Complete, this, _1, _2);
}
for (i = 0; i < NUM_PORTS; i++) { for (i = 0; i < NUM_PORTS; i++) {
port = &s->ports[i]; port = &m_HubState->ports[i];
m_UsbDev->USB_RegisterPort(&port->port, i, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); m_UsbDev->USB_RegisterPort(&port->port, i, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL, ops);
m_UsbDev->USB_PortLocation(&port->port, dev->Port, i + 1); m_UsbDev->USB_PortLocation(&port->port, dev->Port, i + 1);
} }
UsbHub_HandleReset(dev); UsbHub_HandleReset();
return 0; return 0;
} }
void Hub::UsbHub_HandleReset(XboxDeviceState* dev) void Hub::UsbHub_HandleReset()
{ {
USBHubState* s = container_of(dev, USBHubState, dev);
USBHubPort* port; USBHubPort* port;
for (int i = 0; i < NUM_PORTS; i++) { for (int i = 0; i < NUM_PORTS; i++) {
port = s->ports + i; port = m_HubState->ports + i;
port->wPortStatus = PORT_STAT_POWER; port->wPortStatus = PORT_STAT_POWER;
port->wPortChange = 0; port->wPortChange = 0;
if (port->port.Dev && port->port.Dev->Attached) { if (port->port.Dev && port->port.Dev->Attached) {

View File

@ -69,16 +69,20 @@ class Hub final : public UsbPeripheral
// see USBDeviceClass for comments about these functions // see USBDeviceClass for comments about these functions
int UsbHub_Initfn(XboxDeviceState* dev); int UsbHub_Initfn(XboxDeviceState* dev);
XboxDeviceState* UsbHub_FindDevice(XboxDeviceState* dev, uint8_t addr); XboxDeviceState* UsbHub_FindDevice(XboxDeviceState* dev, uint8_t addr);
void UsbHub_HandleReset(XboxDeviceState* dev); void UsbHub_HandleReset();
void UsbHub_HandleControl(XboxDeviceState* dev, USBPacket* p, void UsbHub_HandleControl(XboxDeviceState* dev, USBPacket* p,
int request, int value, int index, int length, uint8_t* data); int request, int value, int index, int length, uint8_t* data);
void UsbHub_HandleData(XboxDeviceState* dev, USBPacket* p); void UsbHub_HandleData(XboxDeviceState* dev, USBPacket* p);
void UsbHub_HandleDestroy(XboxDeviceState* dev); void UsbHub_HandleDestroy(XboxDeviceState* dev);
// see USBPortOps struct for info
void UsbHub_Attach(USBPort* port1);
void UsbHub_Detach(USBPort* port1);
void UsbHub_ChildDetach(USBPort* port1, XboxDeviceState* child);
void UsbHub_Wakeup(USBPort* port1);
void UsbHub_Complete(USBPort* port, USBPacket* packet);
// TODO: perhaps these can be put in UsbPeripheral or USBDevice... // TODO: perhaps these can be put in UsbPeripheral or USBDevice...
// initialize the endpoints of this peripheral // initialize the endpoints of this peripheral
void UsbEpInit(); void UsbEpInit();
// destroy hub resources
void HubCleanUp();
// reset all endpoints of this peripheral // reset all endpoints of this peripheral
void UsbEpReset(); void UsbEpReset();
// reserve a usb port for this hub // reserve a usb port for this hub

View File

@ -197,7 +197,7 @@ OHCI::OHCI(int Irq, USBDevice* UsbObj)
ops->attach = std::bind(&OHCI::OHCI_Attach, this, _1); ops->attach = std::bind(&OHCI::OHCI_Attach, this, _1);
ops->detach = std::bind(&OHCI::OHCI_Detach, this, _1); ops->detach = std::bind(&OHCI::OHCI_Detach, this, _1);
ops->child_detach = std::bind(&OHCI::OHCI_ChildDetach, this, _1); ops->child_detach = std::bind(&OHCI::OHCI_ChildDetach, this, nullptr, _2);
ops->wakeup = std::bind(&OHCI::OHCI_Wakeup, this, _1); ops->wakeup = std::bind(&OHCI::OHCI_Wakeup, this, _1);
ops->complete = std::bind(&OHCI::OHCI_AsyncCompletePacket, this, _1, _2); ops->complete = std::bind(&OHCI::OHCI_AsyncCompletePacket, this, _1, _2);
} }
@ -1448,7 +1448,7 @@ void OHCI::OHCI_Attach(USBPort* Port)
} }
} }
void OHCI::OHCI_ChildDetach(XboxDeviceState* child) void OHCI::OHCI_ChildDetach(USBPort* port, XboxDeviceState* child)
{ {
OHCI_AsyncCancelDevice(child); OHCI_AsyncCancelDevice(child);
} }

View File

@ -262,7 +262,7 @@ class OHCI
// see USBPortOps struct for info // see USBPortOps struct for info
void OHCI_Attach(USBPort* Port); void OHCI_Attach(USBPort* Port);
void OHCI_Detach(USBPort* Port); void OHCI_Detach(USBPort* Port);
void OHCI_ChildDetach(XboxDeviceState* child); void OHCI_ChildDetach(USBPort* port, XboxDeviceState* child);
void OHCI_Wakeup(USBPort* port1); void OHCI_Wakeup(USBPort* port1);
void OHCI_AsyncCompletePacket(USBPort* port, USBPacket* packet); void OHCI_AsyncCompletePacket(USBPort* port, USBPacket* packet);
}; };

View File

@ -116,14 +116,14 @@ void USBDevice::USB_Detach(USBPort* Port)
void USBDevice::USB_Attach(USBPort* Port) void USBDevice::USB_Attach(USBPort* Port)
{ {
XboxDeviceState *dev = Port->Dev; XboxDeviceState* dev = Port->Dev;
assert(dev != nullptr); assert(dev != nullptr);
assert(dev->Attached); assert(dev->Attached);
assert(dev->State == USB_STATE_NOTATTACHED); assert(dev->State == USB_STATE_NOTATTACHED);
m_HostController->OHCI_Attach(Port); Port->Operations->attach(Port);
dev->State = USB_STATE_ATTACHED; dev->State = USB_STATE_ATTACHED;
usb_device_handle_attach(dev); USB_DeviceHandleAttach(dev);
} }
void USBDevice::USB_DeviceReset(XboxDeviceState* dev) void USBDevice::USB_DeviceReset(XboxDeviceState* dev)
@ -506,6 +506,48 @@ int USBDevice::USB_DeviceInit(XboxDeviceState* dev)
return 0; return 0;
} }
XboxDeviceState* USBDevice::USB_DeviceFindDevice(XboxDeviceState* dev, uint8_t Addr)
{
USBDeviceClass* klass = dev->klass;
if (klass->find_device) {
return klass->find_device(dev, Addr);
}
return nullptr;
}
void USBDevice::USB_DeviceCancelPacket(XboxDeviceState* dev, USBPacket* p)
{
USBDeviceClass* klass = dev->klass;
if (klass->cancel_packet) {
klass->cancel_packet(dev, p);
}
}
void USBDevice::USB_DeviceHandleDestroy(XboxDeviceState* dev)
{
USBDeviceClass* klass = dev->klass;
if (klass->handle_destroy) {
klass->handle_destroy(dev);
}
}
void USBDevice::USB_DeviceHandleAttach(XboxDeviceState* dev)
{
USBDeviceClass* klass = dev->klass;
if (klass->handle_attach) {
klass->handle_attach(dev);
}
}
void USBDevice::USB_DeviceHandleReset(XboxDeviceState* dev)
{
USBDeviceClass* klass = dev->klass;
if (klass->handle_reset) {
klass->handle_reset(dev);
}
}
void USBDevice::USB_DeviceHandleControl(XboxDeviceState* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data) void USBDevice::USB_DeviceHandleControl(XboxDeviceState* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data)
{ {
USBDeviceClass* klass = dev->klass; USBDeviceClass* klass = dev->klass;
@ -522,6 +564,14 @@ void USBDevice::USB_DeviceHandleData(XboxDeviceState* dev, USBPacket* p)
} }
} }
void USBDevice::USB_DeviceSetInterface(XboxDeviceState* dev, int iface, int alt_old, int alt_new)
{
USBDeviceClass* klass = dev->klass;
if (klass->set_interface) {
klass->set_interface(dev, iface, alt_old, alt_new);
}
}
void USBDevice::USB_DeviceFlushEPqueue(XboxDeviceState* dev, USBEndpoint* ep) void USBDevice::USB_DeviceFlushEPqueue(XboxDeviceState* dev, USBEndpoint* ep)
{ {
USBDeviceClass *klass = dev->klass; USBDeviceClass *klass = dev->klass;
@ -530,24 +580,6 @@ void USBDevice::USB_DeviceFlushEPqueue(XboxDeviceState* dev, USBEndpoint* ep)
} }
} }
void USBDevice::USB_DeviceCancelPacket(XboxDeviceState* dev, USBPacket* p)
{
USBDeviceClass* klass = dev->klass;
if (klass->cancel_packet) {
klass->cancel_packet(dev, p);
}
}
XboxDeviceState* USBDevice::USB_DeviceFindDevice(XboxDeviceState* dev, uint8_t Addr)
{
USBDeviceClass* klass = dev->klass;
if (klass->find_device) {
return klass->find_device(dev, Addr);
}
return nullptr;
}
void USBDevice::USB_DeviceEPstopped(XboxDeviceState* dev, USBEndpoint* EP) void USBDevice::USB_DeviceEPstopped(XboxDeviceState* dev, USBEndpoint* EP)
{ {
USBDeviceClass* klass = dev->klass; USBDeviceClass* klass = dev->klass;
@ -556,14 +588,6 @@ void USBDevice::USB_DeviceEPstopped(XboxDeviceState* dev, USBEndpoint* EP)
} }
} }
void USBDevice::USB_DeviceSetInterface(XboxDeviceState* dev, int iface, int alt_old, int alt_new)
{
USBDeviceClass* klass = dev->klass;
if (klass->set_interface) {
klass->set_interface(dev, iface, alt_old, alt_new);
}
}
void USBDevice::USB_CancelPacket(USBPacket* p) void USBDevice::USB_CancelPacket(USBPacket* p)
{ {
bool callback = (p->State == USB_PACKET_ASYNC); bool callback = (p->State == USB_PACKET_ASYNC);
@ -608,4 +632,15 @@ void USBDevice::USB_PortLocation(USBPort* downstream, USBPort* upstream, int por
std::snprintf(downstream->Path, sizeof(downstream->Path), "%d", portnr); std::snprintf(downstream->Path, sizeof(downstream->Path), "%d", portnr);
downstream->HubCount = 0; downstream->HubCount = 0;
} }
} }
void USBDevice::USB_DeviceAttach(XboxDeviceState* dev)
{
USBPort* port = dev->Port;
assert(port != nullptr);
assert(!dev->Attached);
dev->Attached++;
USB_Attach(port);
}

View File

@ -70,13 +70,13 @@ class USBDevice : public PCIDevice {
// register a port with the HC // register a port with the HC
void USB_RegisterPort(USBPort* Port, int Index, int SpeedMask, USBPortOps* Ops); void USB_RegisterPort(USBPort* Port, int Index, int SpeedMask, USBPortOps* Ops);
//
void USB_DeviceEPstopped(XboxDeviceState* Dev, USBEndpoint* Ep);
// reset a usb port // reset a usb port
void USB_PortReset(USBPort* Port); void USB_PortReset(USBPort* Port);
// a device is attached // update device status during an attach
void USB_DeviceAttach(XboxDeviceState* dev);
// update port status when a device is attached
void USB_Attach(USBPort* Port); void USB_Attach(USBPort* Port);
// a device is detached // update port status when a device is detached
void USB_Detach(USBPort* Port); void USB_Detach(USBPort* Port);
// a device downstream from the device attached to the port (attached through a hub) is detached // a device downstream from the device attached to the port (attached through a hub) is detached
void ChildDetach(USBPort* Port, XboxDeviceState* Child); void ChildDetach(USBPort* Port, XboxDeviceState* Child);
@ -86,8 +86,6 @@ class USBDevice : public PCIDevice {
void Complete(USBPort* Port, USBPacket *P); void Complete(USBPort* Port, USBPacket *P);
// reset a device // reset a device
void USB_DeviceReset(XboxDeviceState* Dev); void USB_DeviceReset(XboxDeviceState* Dev);
// find the usb device with the supplied address
XboxDeviceState* USB_FindDevice(USBPort* Port, uint8_t Addr);
// //
XboxDeviceState* USB_DeviceFindDevice(XboxDeviceState* Dev, uint8_t Addr); XboxDeviceState* USB_DeviceFindDevice(XboxDeviceState* Dev, uint8_t Addr);
// find the requested endpoint in the supplied device // find the requested endpoint in the supplied device
@ -122,16 +120,26 @@ class USBDevice : public PCIDevice {
void USB_QueueOne(USBPacket* p); void USB_QueueOne(USBPacket* p);
// call usb class init function // call usb class init function
int USB_DeviceInit(XboxDeviceState* dev); int USB_DeviceInit(XboxDeviceState* dev);
// call usb class find_device function
XboxDeviceState* USB_FindDevice(USBPort* Port, uint8_t Addr);
// call usb class cancel_packet function
void USB_DeviceCancelPacket(XboxDeviceState* dev, USBPacket* p);
// call usb class handle_destroy function
void USB_DeviceHandleDestroy(XboxDeviceState* dev);
// call usb class handle_attach function
void USB_DeviceHandleAttach(XboxDeviceState* dev);
// call usb class handle_reset function
void USB_DeviceHandleReset(XboxDeviceState* dev);
// call usb class handle_control function // call usb class handle_control function
void USB_DeviceHandleControl(XboxDeviceState* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data); void USB_DeviceHandleControl(XboxDeviceState* dev, USBPacket* p, int request, int value, int index, int length, uint8_t* data);
// call usb class handle_data function // call usb class handle_data function
void USB_DeviceHandleData(XboxDeviceState* dev, USBPacket* p); void USB_DeviceHandleData(XboxDeviceState* dev, USBPacket* p);
// call usb class flush_ep_queue function
void USB_DeviceFlushEPqueue(XboxDeviceState* dev, USBEndpoint* ep);
// call usb class cancel_packet function
void USB_DeviceCancelPacket(XboxDeviceState* dev, USBPacket* p);
// call usb class set_interface function // call usb class set_interface function
void USB_DeviceSetInterface(XboxDeviceState* dev, int iface, int alt_old, int alt_new); void USB_DeviceSetInterface(XboxDeviceState* dev, int iface, int alt_old, int alt_new);
// call usb class flush_ep_queue function
void USB_DeviceFlushEPqueue(XboxDeviceState* dev, USBEndpoint* ep);
// call usb class ep_stopped function
void USB_DeviceEPstopped(XboxDeviceState* Dev, USBEndpoint* Ep);
// set the type of the endpoint // set the type of the endpoint
void USB_EPsetType(XboxDeviceState* dev, int pid, int ep, uint8_t type); void USB_EPsetType(XboxDeviceState* dev, int pid, int ep, uint8_t type);
// set the interface number of the endpoint // set the interface number of the endpoint

View File

@ -256,13 +256,13 @@ struct USBPacket {
}; };
struct USBPortOps { struct USBPortOps {
std::function<void(USBPort*port)> attach; std::function<void(USBPort* port)> attach;
std::function<void(USBPort *port)> detach; std::function<void(USBPort* port)> detach;
/* /*
* This gets called when a device downstream from the device attached to * This gets called when a device downstream from the device attached to
* the port (attached through a hub) gets detached. * the port (attached through a hub) gets detached.
*/ */
std::function<void(XboxDeviceState* child)> child_detach; std::function<void(USBPort* port, XboxDeviceState* child)> child_detach;
std::function<void(USBPort* port)> wakeup; std::function<void(USBPort* port)> wakeup;
/* /*
* Note that port->dev will be different then the device from which * Note that port->dev will be different then the device from which