Packet processing stuff and refactored USBDevice class (WIP)
This commit is contained in:
parent
8ca5cff089
commit
0b5c2c911c
|
@ -105,9 +105,9 @@
|
|||
|
||||
/* Bitfields for the first word of an ED */
|
||||
#define OHCI_ED_FA_SHIFT 0
|
||||
#define OHCI_ED_FA_MASK (0x7F<<OHCI_ED_FA_SHIFT)
|
||||
#define OHCI_ED_FA_MASK (0x7F<<OHCI_ED_FA_SHIFT) // FunctionAddress
|
||||
#define OHCI_ED_EN_SHIFT 7
|
||||
#define OHCI_ED_EN_MASK (0xF<<OHCI_ED_EN_SHIFT)
|
||||
#define OHCI_ED_EN_MASK (0xF<<OHCI_ED_EN_SHIFT) // EndpointNumber
|
||||
#define OHCI_ED_D_SHIFT 11
|
||||
#define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT) // Direction
|
||||
#define OHCI_ED_S (1<<13)
|
||||
|
@ -163,20 +163,6 @@
|
|||
#define OHCI_CC_BUFFEROVERRUN 0xC
|
||||
#define OHCI_CC_BUFFERUNDERRUN 0xD
|
||||
|
||||
#define USB_TOKEN_SETUP 0x2D
|
||||
#define USB_TOKEN_IN 0x69 // device -> host
|
||||
#define USB_TOKEN_OUT 0xE1 // host -> device
|
||||
|
||||
#define USB_RET_SUCCESS (0)
|
||||
#define USB_RET_NODEV (-1)
|
||||
#define USB_RET_NAK (-2)
|
||||
#define USB_RET_STALL (-3)
|
||||
#define USB_RET_BABBLE (-4)
|
||||
#define USB_RET_IOERROR (-5)
|
||||
#define USB_RET_ASYNC (-6)
|
||||
#define USB_RET_ADD_TO_QUEUE (-7)
|
||||
#define USB_RET_REMOVE_FROM_QUEUE (-8)
|
||||
|
||||
#define USB_HZ 12000000
|
||||
|
||||
#define USB_SPEED_LOW 0
|
||||
|
@ -191,12 +177,13 @@ typedef enum _USB_SPEED
|
|||
USB_SPEED;
|
||||
|
||||
|
||||
OHCI::OHCI(int Irq)
|
||||
OHCI::OHCI(int Irq, USBDevice* UsbObj)
|
||||
{
|
||||
m_IrqNum = Irq;
|
||||
m_UsbDevice = UsbObj;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
USB_RegisterPort(&m_Registers.RhPort[i].UsbPort, i, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
|
||||
m_UsbDevice->USB_RegisterPort(&m_Registers.RhPort[i].UsbPort, i, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
|
||||
}
|
||||
OHCI_PacketInit(&m_UsbPacket);
|
||||
|
||||
|
@ -479,7 +466,7 @@ int OHCI::OHCI_ServiceEDlist(xbaddr Head, int Completion)
|
|||
if (m_AsyncTD && addr == m_AsyncTD) {
|
||||
usb_cancel_packet(&ohci->usb_packet);
|
||||
m_AsyncTD = xbnull;
|
||||
USB_DeviceEPstopped(m_UsbPacket.Endpoint->Dev, m_UsbPacket.Endpoint);
|
||||
m_UsbDevice->USB_DeviceEPstopped(m_UsbPacket.Endpoint->Dev, m_UsbPacket.Endpoint);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -530,7 +517,7 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
int pid;
|
||||
int ret;
|
||||
int i;
|
||||
USBDev* dev;
|
||||
XboxDevice* dev;
|
||||
USBEndpoint* ep;
|
||||
OHCI_TD td;
|
||||
xbaddr addr;
|
||||
|
@ -566,6 +553,16 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
direction = OHCI_BM(td.Flags, TD_DP);
|
||||
}
|
||||
|
||||
// Info: Each USB transaction consists of a
|
||||
// 1. Token Packet, (Header defining what it expects to follow).
|
||||
// 2. Optional Data Packet, (Containing the payload).
|
||||
// 3. Status Packet, (Used to acknowledge transactions and to provide a means of error correction).
|
||||
|
||||
// There are three types of token packets:
|
||||
// In - Informs the USB device that the host wishes to read information.
|
||||
// Out - Informs the USB device that the host wishes to send information.
|
||||
// Setup - Used to begin control transfers.
|
||||
|
||||
switch (direction) {
|
||||
case OHCI_TD_DIR_IN:
|
||||
#ifdef DEBUG_PACKET
|
||||
|
@ -645,9 +642,9 @@ int OHCI::OHCI_ServiceTD(OHCI_ED* Ed)
|
|||
DbgPrintf("Too many pending packets\n");
|
||||
return 1;
|
||||
}
|
||||
dev = ohci_find_device(ohci, OHCI_BM(Ed->Flags, ED_FA));
|
||||
ep = usb_ep_get(dev, pid, OHCI_BM(Ed->Flags, ED_EN));
|
||||
usb_packet_setup(&m_UsbPacket, pid, ep, 0, addr, !flag_r, OHCI_BM(td.Flags, TD_DI) == 0);
|
||||
dev = OHCI_FindDevice(OHCI_BM(Ed->Flags, ED_FA));
|
||||
ep = m_UsbDevice->USB_GetEP(dev, pid, OHCI_BM(Ed->Flags, ED_EN));
|
||||
m_UsbDevice->USB_PacketSetup(&m_UsbPacket, pid, ep, 0, addr, !flag_r, OHCI_BM(td.Flags, TD_DI) == 0);
|
||||
usb_packet_addbuf(&m_UsbPacket, ohci->usb_buf, packetlen);
|
||||
usb_handle_packet(dev, &m_UsbPacket);
|
||||
#ifdef DEBUG_PACKET
|
||||
|
@ -764,6 +761,24 @@ exit_no_retire:
|
|||
return OHCI_BM(td.Flags, TD_CC) != OHCI_CC_NOERROR;
|
||||
}
|
||||
|
||||
XboxDevice* OHCI::OHCI_FindDevice(uint8_t Addr)
|
||||
{
|
||||
XboxDevice* dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if ((m_Registers.RhPort[i].HcRhPortStatus & OHCI_PORT_PES) == 0) {
|
||||
continue; // port is disabled
|
||||
}
|
||||
dev = m_UsbDevice->USB_FindDevice(&m_Registers.RhPort[i].UsbPort, Addr);
|
||||
if (dev != nullptr) {
|
||||
return dev; // return found device
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OHCI::OHCI_StateReset()
|
||||
{
|
||||
// The usb state can be USB_Suspend if it is a software reset, and USB_Reset if it is a hardware
|
||||
|
@ -806,7 +821,7 @@ void OHCI::OHCI_StateReset()
|
|||
OHCIPort* Port = &m_Registers.RhPort[i];
|
||||
Port->HcRhPortStatus = 0;
|
||||
if (Port->UsbPort.Dev && Port->UsbPort.Dev->Attached) {
|
||||
USB_PortReset(&Port->UsbPort);
|
||||
m_UsbDevice->USB_PortReset(&Port->UsbPort);
|
||||
}
|
||||
}
|
||||
if (m_AsyncTD) {
|
||||
|
@ -1174,16 +1189,16 @@ uint32_t OHCI::OHCI_GetFrameRemaining()
|
|||
|
||||
void OHCI::OHCI_StopEndpoints()
|
||||
{
|
||||
USBDev* dev;
|
||||
XboxDevice* dev;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
dev = m_Registers.RhPort[i].UsbPort.Dev;
|
||||
if (dev && dev->Attached) {
|
||||
USB_DeviceEPstopped(dev, &dev->EP_ctl);
|
||||
m_UsbDevice->USB_DeviceEPstopped(dev, &dev->EP_ctl);
|
||||
for (j = 0; j < USB_MAX_ENDPOINTS; j++) {
|
||||
USB_DeviceEPstopped(dev, &dev->EP_in[j]);
|
||||
USB_DeviceEPstopped(dev, &dev->EP_out[j]);
|
||||
m_UsbDevice->USB_DeviceEPstopped(dev, &dev->EP_in[j]);
|
||||
m_UsbDevice->USB_DeviceEPstopped(dev, &dev->EP_out[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1269,7 +1284,7 @@ void OHCI::OHCI_PortSetStatus(int PortNum, uint32_t Value)
|
|||
|
||||
if (OHCI_PortSetIfConnected(PortNum, Value & OHCI_PORT_PRS)) {
|
||||
DbgPrintf("Ohci: port %d: RESET\n", PortNum);
|
||||
USB_DeviceReset(port->UsbPort.Dev);
|
||||
m_UsbDevice->USB_DeviceReset(port->UsbPort.Dev);
|
||||
port->HcRhPortStatus &= ~OHCI_PORT_PRS;
|
||||
// ??? Should this also set OHCI_PORT_PESC
|
||||
port->HcRhPortStatus |= OHCI_PORT_PES | OHCI_PORT_PRSC;
|
||||
|
@ -1371,63 +1386,3 @@ void OHCI::OHCI_Attach(USBPort* Port)
|
|||
}
|
||||
}
|
||||
|
||||
void OHCI::USB_RegisterPort(USBPort* Port, int Index, int SpeedMask)
|
||||
{
|
||||
Port->PortIndex = Index;
|
||||
Port->SpeedMask = SpeedMask;
|
||||
Port->HubCount = 0;
|
||||
std::snprintf(Port->Path, sizeof(Port->Path), "%d", Index + 1);
|
||||
}
|
||||
|
||||
void OHCI::USB_DeviceEPstopped(USBDev* Dev, USBEndpoint* EP)
|
||||
{
|
||||
// This seems to be a nop in XQEMU since it doesn't assign the EP_Stopped function (it's nullptr)
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(Dev);
|
||||
if (klass->EP_Stopped) {
|
||||
klass->EP_Stopped(Dev, EP);
|
||||
}
|
||||
}
|
||||
|
||||
void OHCI::USB_PortReset(USBPort* Port)
|
||||
{
|
||||
USBDev* dev = Port->Dev;
|
||||
|
||||
assert(dev != nullptr);
|
||||
USB_Detach(Port);
|
||||
USB_Attach(Port);
|
||||
USB_DeviceReset(dev);
|
||||
}
|
||||
|
||||
void OHCI::USB_Detach(USBPort* Port)
|
||||
{
|
||||
USBDev* dev = Port->Dev;
|
||||
|
||||
assert(dev != nullptr);
|
||||
assert(dev->State != USB_STATE_NOTATTACHED);
|
||||
OHCI_Detach(Port);
|
||||
dev->State = USB_STATE_NOTATTACHED;
|
||||
}
|
||||
|
||||
void OHCI::USB_Attach(USBPort* Port)
|
||||
{
|
||||
USBDev *dev = Port->Dev;
|
||||
|
||||
assert(dev != nullptr);
|
||||
assert(dev->Attached);
|
||||
assert(dev->State == USB_STATE_NOTATTACHED);
|
||||
OHCI_Attach(Port);
|
||||
dev->State = USB_STATE_ATTACHED;
|
||||
usb_device_handle_attach(dev);
|
||||
}
|
||||
|
||||
void OHCI::USB_DeviceReset(USBDev* dev)
|
||||
{
|
||||
if (dev == nullptr || !dev->Attached) {
|
||||
return;
|
||||
}
|
||||
|
||||
dev->RemoteWakeup = 0;
|
||||
dev->Addr = 0;
|
||||
dev->State = USB_STATE_DEFAULT;
|
||||
usb_device_handle_reset(dev);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,20 @@
|
|||
#include "USBDevice.h"
|
||||
#include "..\CxbxKrnl\Timer.h"
|
||||
|
||||
#define USB_TOKEN_SETUP 0x2D
|
||||
#define USB_TOKEN_IN 0x69 // device -> host
|
||||
#define USB_TOKEN_OUT 0xE1 // host -> device
|
||||
|
||||
#define USB_RET_SUCCESS (0)
|
||||
#define USB_RET_NODEV (-1)
|
||||
#define USB_RET_NAK (-2)
|
||||
#define USB_RET_STALL (-3)
|
||||
#define USB_RET_BABBLE (-4)
|
||||
#define USB_RET_IOERROR (-5)
|
||||
#define USB_RET_ASYNC (-6)
|
||||
#define USB_RET_ADD_TO_QUEUE (-7)
|
||||
#define USB_RET_REMOVE_FROM_QUEUE (-8)
|
||||
|
||||
|
||||
// Abbreviations used:
|
||||
// OHCI: Open Host Controller Interface; the standard used on the Xbox to comunicate with the usb devices
|
||||
|
@ -140,7 +154,7 @@ class OHCI
|
|||
{
|
||||
public:
|
||||
// constructor
|
||||
OHCI(int Irqn);
|
||||
OHCI(int Irqn, USBDevice* UsbObj);
|
||||
// destructor
|
||||
~OHCI() {}
|
||||
// read a register
|
||||
|
@ -150,6 +164,8 @@ class OHCI
|
|||
|
||||
|
||||
private:
|
||||
// pointer to g_USB0 or g_USB1
|
||||
USBDevice* m_UsbDevice;
|
||||
// all the registers available on the OHCI standard
|
||||
OHCI_Registers m_Registers;
|
||||
// end-of-frame timer
|
||||
|
@ -239,25 +255,8 @@ class OHCI
|
|||
int OHCI_ServiceEDlist(xbaddr Head, int Completion);
|
||||
// process a TD. Returns nonzero to terminate processing of this endpoint
|
||||
int OHCI_ServiceTD(OHCI_ED* Ed);
|
||||
|
||||
// register a port with the HC
|
||||
void USB_RegisterPort(USBPort* Port, int Index, int SpeedMask);
|
||||
//
|
||||
void USB_DeviceEPstopped(USBDev* Dev, USBEndpoint* Ep);
|
||||
// reset a usb port
|
||||
void USB_PortReset(USBPort* Port);
|
||||
// a device is attched
|
||||
void USB_Attach(USBPort* Port);
|
||||
// a device is detached
|
||||
void USB_Detach(USBPort* Port);
|
||||
// a device downstream from the device attached to the port (attached through a hub) is detached
|
||||
void ChildDetach(USBPort* Port, USBDev* Child);
|
||||
// TODO
|
||||
void Wakeup(USBPort* Port);
|
||||
// TODO
|
||||
void Complete(USBPort* Port, USBPacket *P);
|
||||
// reset a device
|
||||
void USB_DeviceReset(USBDev* Dev);
|
||||
// find the usb device with the supplied address
|
||||
XboxDevice* OHCI::OHCI_FindDevice(uint8_t Addr);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,11 +52,11 @@ void USBDevice::Init(unsigned int address)
|
|||
m_VendorId = PCI_VENDOR_ID_NVIDIA;
|
||||
|
||||
if (address == USB0_BASE) {
|
||||
m_pHostController1 = new OHCI(1);
|
||||
m_pHostController1 = new OHCI(1, this);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pHostController2 = new OHCI(9);
|
||||
m_pHostController2 = new OHCI(9, this);
|
||||
}
|
||||
|
||||
uint32_t USBDevice::MMIORead(int barIndex, uint32_t addr, unsigned size)
|
||||
|
@ -89,3 +89,124 @@ void USBDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned
|
|||
// USB1 queried
|
||||
m_pHostController2->OHCI_WriteRegister(addr, value);
|
||||
}
|
||||
|
||||
void USBDevice::USB_RegisterPort(USBPort* Port, int Index, int SpeedMask)
|
||||
{
|
||||
Port->PortIndex = Index;
|
||||
Port->SpeedMask = SpeedMask;
|
||||
Port->HubCount = 0;
|
||||
std::snprintf(Port->Path, sizeof(Port->Path), "%d", Index + 1);
|
||||
}
|
||||
|
||||
void USBDevice::USB_DeviceEPstopped(XboxDevice* Dev, USBEndpoint* EP)
|
||||
{
|
||||
// This seems to be a nop in XQEMU since it doesn't assign the EP_Stopped function (it's nullptr)
|
||||
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(Dev);
|
||||
if (klass->EP_Stopped) {
|
||||
klass->EP_Stopped(Dev, EP);
|
||||
}
|
||||
}
|
||||
|
||||
void USBDevice::USB_PortReset(USBPort* Port)
|
||||
{
|
||||
XboxDevice* dev = Port->Dev;
|
||||
|
||||
assert(dev != nullptr);
|
||||
USB_Detach(Port);
|
||||
USB_Attach(Port);
|
||||
USB_DeviceReset(dev);
|
||||
}
|
||||
|
||||
void USBDevice::USB_Detach(USBPort* Port)
|
||||
{
|
||||
XboxDevice* dev = Port->Dev;
|
||||
|
||||
assert(dev != nullptr);
|
||||
assert(dev->State != USB_STATE_NOTATTACHED);
|
||||
OHCI_Detach(Port);
|
||||
dev->State = USB_STATE_NOTATTACHED;
|
||||
}
|
||||
|
||||
void USBDevice::USB_Attach(USBPort* Port)
|
||||
{
|
||||
XboxDevice *dev = Port->Dev;
|
||||
|
||||
assert(dev != nullptr);
|
||||
assert(dev->Attached);
|
||||
assert(dev->State == USB_STATE_NOTATTACHED);
|
||||
OHCI_Attach(Port);
|
||||
dev->State = USB_STATE_ATTACHED;
|
||||
usb_device_handle_attach(dev);
|
||||
}
|
||||
|
||||
void USBDevice::USB_DeviceReset(XboxDevice* dev)
|
||||
{
|
||||
if (dev == nullptr || !dev->Attached) {
|
||||
return;
|
||||
}
|
||||
|
||||
dev->RemoteWakeup = 0;
|
||||
dev->Addr = 0;
|
||||
dev->State = USB_STATE_DEFAULT;
|
||||
usb_device_handle_reset(dev);
|
||||
}
|
||||
|
||||
XboxDevice* USBDevice::USB_FindDevice(USBPort* Port, uint8_t Addr)
|
||||
{
|
||||
XboxDevice* dev = Port->Dev;
|
||||
|
||||
if (dev == nullptr || !dev->Attached || dev->State != USB_STATE_DEFAULT) {
|
||||
return nullptr;
|
||||
}
|
||||
if (dev->Addr == Addr) {
|
||||
return dev;
|
||||
}
|
||||
|
||||
return USB_DeviceFindDevice(dev, Addr);
|
||||
}
|
||||
|
||||
XboxDevice* USBDevice::USB_DeviceFindDevice(XboxDevice* Dev, uint8_t Addr)
|
||||
{
|
||||
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(Dev);
|
||||
if (klass->find_device) {
|
||||
return klass->find_device(Dev, Addr); // TODO: usb_hub_find_device
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
USBEndpoint* USBDevice::USB_GetEP(XboxDevice* Dev, int Pid, int Ep)
|
||||
{
|
||||
USBEndpoint* eps;
|
||||
|
||||
if (Dev == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
eps = (Pid == USB_TOKEN_IN) ? Dev->EP_in : Dev->EP_out;
|
||||
if (Ep == 0) {
|
||||
return &Dev->EP_ctl; // EndpointNumber zero represents the default control endpoint
|
||||
}
|
||||
assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
|
||||
assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
|
||||
|
||||
return eps + Ep - 1;
|
||||
}
|
||||
|
||||
void USBDevice::USB_PacketSetup(USBPacket* p, int Pid, USBEndpoint* Ep, unsigned int Stream,
|
||||
uint64_t Id, bool ShortNotOK, bool IntReq)
|
||||
{
|
||||
assert(!usb_packet_is_inflight(p));
|
||||
assert(p->iov.iov != NULL);
|
||||
p->Id = Id;
|
||||
p->Pid = Pid;
|
||||
p->Endpoint = Ep;
|
||||
p->Stream = Stream;
|
||||
p->Status = USB_RET_SUCCESS;
|
||||
p->ActualLength = 0;
|
||||
p->Parameter = 0;
|
||||
p->ShortNotOK = ShortNotOK;
|
||||
p->IntReq = IntReq;
|
||||
p->Combined = NULL;
|
||||
qemu_iovec_reset(&p->iov);
|
||||
usb_packet_set_state(p, USB_PACKET_SETUP);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define USBDEVICE_H_
|
||||
|
||||
#include "..\PCIDevice.h"
|
||||
#include "..\devices\video\queue.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define USB_MAX_ENDPOINTS 15
|
||||
|
@ -73,6 +74,9 @@ typedef struct _IOVector
|
|||
}
|
||||
IOVector;
|
||||
|
||||
typedef struct _USBPacket USBPacket;
|
||||
typedef struct _XboxDevice XboxDevice;
|
||||
|
||||
/* USB endpoint */
|
||||
typedef struct _USBEndpoint
|
||||
{
|
||||
|
@ -83,13 +87,13 @@ typedef struct _USBEndpoint
|
|||
int max_packet_size;
|
||||
bool pipeline;
|
||||
bool halted;
|
||||
USBDev* Dev; // device this endpoint belongs to
|
||||
//QTAILQ_HEAD(, USBPacket) queue;
|
||||
XboxDevice* Dev; // device this endpoint belongs to
|
||||
QTAILQ_HEAD(, _USBPacket) Queue; // queue of packets to this endpoint
|
||||
}
|
||||
USBEndpoint;
|
||||
|
||||
/* definition of a USB device */
|
||||
typedef struct _USBDev
|
||||
/* definition of an Xbox usb device */
|
||||
typedef struct _XboxDevice
|
||||
{
|
||||
DeviceState qdev;
|
||||
USBPort *port;
|
||||
|
@ -102,25 +106,25 @@ typedef struct _USBDev
|
|||
int speed;
|
||||
// Supported speeds, not in info because it may be variable (hostdevs)
|
||||
int speedmask;
|
||||
uint8_t Addr; // device address
|
||||
uint8_t Addr; // device function address
|
||||
char product_desc[32];
|
||||
int auto_attach;
|
||||
int Attached; // device is attached
|
||||
int Attached; // device is attached
|
||||
|
||||
int32_t State; // current state of device
|
||||
int32_t State; // current state of device
|
||||
uint8_t setup_buf[8];
|
||||
uint8_t data_buf[4096];
|
||||
int32_t RemoteWakeup; // wakeup flag
|
||||
int32_t RemoteWakeup; // wakeup flag
|
||||
int32_t setup_state;
|
||||
int32_t setup_len;
|
||||
int32_t setup_index;
|
||||
|
||||
USBEndpoint EP_ctl;
|
||||
USBEndpoint EP_in[USB_MAX_ENDPOINTS];
|
||||
USBEndpoint EP_out[USB_MAX_ENDPOINTS];
|
||||
USBEndpoint EP_ctl; // endpoints for SETUP tokens
|
||||
USBEndpoint EP_in[USB_MAX_ENDPOINTS]; // endpoints for OUT tokens
|
||||
USBEndpoint EP_out[USB_MAX_ENDPOINTS]; // endpoints for IN tokens
|
||||
|
||||
//QLIST_HEAD(, USBDescString) strings;
|
||||
const USBDesc *usb_desc; // Overrides class usb_desc if not NULL
|
||||
const USBDesc *usb_desc; // Overrides class usb_desc if not NULL
|
||||
const USBDescDevice *device;
|
||||
|
||||
int configuration;
|
||||
|
@ -129,8 +133,9 @@ typedef struct _USBDev
|
|||
const USBDescConfig *config;
|
||||
const USBDescIface *ifaces[USB_MAX_INTERFACES];
|
||||
}
|
||||
USBDev;
|
||||
XboxDevice;
|
||||
|
||||
// ergo720: this could be merged in the OHCI or USBDevice class if possible
|
||||
typedef struct USBDeviceClass
|
||||
{
|
||||
DeviceClass parent_class;
|
||||
|
@ -183,30 +188,29 @@ typedef struct USBDeviceClass
|
|||
USBDeviceClass;
|
||||
|
||||
/* Structure used to hold information about an active USB packet */
|
||||
typedef struct _USBPacket
|
||||
struct _USBPacket
|
||||
{
|
||||
// Data fields for use by the driver
|
||||
int Pid;
|
||||
uint64_t Id;
|
||||
USBEndpoint* Endpoint; // endpoint of the packet
|
||||
unsigned int stream;
|
||||
IOVector IoVec; // used to perform vectored I/O
|
||||
uint64_t parameter; // control transfers
|
||||
bool short_not_ok;
|
||||
bool int_req;
|
||||
int status; // USB_RET_* status code
|
||||
int actual_length; // Number of bytes actually transferred
|
||||
int Pid; // Packet ID
|
||||
uint32_t Id; // Paddr of the TD for this packet
|
||||
USBEndpoint* Endpoint; // endpoint this packet is transferred to
|
||||
unsigned int Stream;
|
||||
IOVector IoVec; // used to perform vectored I/O
|
||||
uint64_t Parameter; // control transfers
|
||||
bool ShortNotOK; // the bufferRounding mode of the TD for this packet
|
||||
bool IntReq; // whether or not to generate an interrupt for this packet (DelayInterrupt of the TD is zero)
|
||||
int Status; // USB_RET_* status code
|
||||
int ActualLength; // Number of bytes actually transferred
|
||||
// Internal use by the USB layer
|
||||
USBPacketState state;
|
||||
USBCombinedPacket *combined;
|
||||
//QTAILQ_ENTRY(USBPacket) queue;
|
||||
//QTAILQ_ENTRY(USBPacket) combined_entry;
|
||||
}
|
||||
USBPacket;
|
||||
USBPacketState State;
|
||||
//USBCombinedPacket *Combined;
|
||||
QTAILQ_ENTRY(_USBPacket) Queue;
|
||||
QTAILQ_ENTRY(_USBPacket) CombinedEntry;
|
||||
};
|
||||
|
||||
/* Struct describing the status of a usb port */
|
||||
typedef struct _USBPort {
|
||||
USBDev* Dev; // usb device (if present)
|
||||
XboxDevice* Dev; // usb device (if present)
|
||||
int SpeedMask; // usb speeds supported
|
||||
int HubCount; // number of hubs attached
|
||||
char Path[16]; // the number of the port
|
||||
|
@ -233,9 +237,38 @@ class USBDevice : public PCIDevice {
|
|||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
|
||||
|
||||
// USBDevice-specific functions/variables
|
||||
// pointers to the two USB host controllers available on the Xbox
|
||||
OHCI* m_pHostController1 = nullptr;
|
||||
OHCI* m_pHostController2 = nullptr;
|
||||
|
||||
// register a port with the HC
|
||||
void USB_RegisterPort(USBPort* Port, int Index, int SpeedMask);
|
||||
//
|
||||
void USB_DeviceEPstopped(XboxDevice* Dev, USBEndpoint* Ep);
|
||||
// reset a usb port
|
||||
void USB_PortReset(USBPort* Port);
|
||||
// a device is attched
|
||||
void USB_Attach(USBPort* Port);
|
||||
// a device is detached
|
||||
void USB_Detach(USBPort* Port);
|
||||
// a device downstream from the device attached to the port (attached through a hub) is detached
|
||||
void ChildDetach(USBPort* Port, XboxDevice* Child);
|
||||
// TODO
|
||||
void Wakeup(USBPort* Port);
|
||||
// TODO
|
||||
void Complete(USBPort* Port, USBPacket *P);
|
||||
// reset a device
|
||||
void USB_DeviceReset(XboxDevice* Dev);
|
||||
// find the usb device with the supplied address
|
||||
XboxDevice* USB_FindDevice(USBPort* Port, uint8_t Addr);
|
||||
// ergo720: can probably be removed by calling directly usb_hub_find_device
|
||||
XboxDevice* USB_DeviceFindDevice(XboxDevice* Dev, uint8_t Addr);
|
||||
// find the requested endpoint in the supplied device
|
||||
USBEndpoint* USB_GetEP(XboxDevice* Dev, int Pid, int Ep);
|
||||
// setup a packet for transfer
|
||||
void USB_PacketSetup(USBPacket* p, int Pid, USBEndpoint* Ep, unsigned int Stream,
|
||||
uint64_t Id, bool ShortNotOK, bool IntReq);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue