Implemented most of the roothub.
There remains only one issue: reading the Port registers seem to return a bogus value (0). I need to find out what's causing it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18918 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
36020a912d
commit
2159acc7d9
@ -108,9 +108,6 @@ ohci_add_to(Stack *stack)
|
||||
return status;
|
||||
}
|
||||
TRACE(("usb_ohci init_hardware(): Setting up hardware\n"));
|
||||
//
|
||||
// TODO: in the future we might want to support multiple host controllers.
|
||||
//
|
||||
item = new pci_info;
|
||||
for ( i = 0 ; OHCI::pci_module->get_nth_pci_info( i , item ) == B_OK ; i++ ) {
|
||||
if ( ( item->class_base == PCI_serial_bus ) && ( item->class_sub == PCI_usb )
|
||||
@ -121,20 +118,28 @@ ohci_add_to(Stack *stack)
|
||||
continue;
|
||||
}
|
||||
TRACE(("USB OHCI: init_hardware(): found at IRQ %u \n", item->u.h0.interrupt_line));
|
||||
OHCI *bus = new OHCI( item , stack );
|
||||
if ( bus->InitCheck() != B_OK ) {
|
||||
delete bus;
|
||||
break;
|
||||
OHCI *bus = new(std::nothrow) OHCI(item, stack);
|
||||
|
||||
if (!bus) {
|
||||
delete item;
|
||||
OHCI::pci_module = NULL;
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (bus->InitCheck() != B_OK) {
|
||||
TRACE(("usb_ohci: bus failed to initialize...\n"));
|
||||
delete bus;
|
||||
continue;
|
||||
}
|
||||
|
||||
bus->Start();
|
||||
stack->AddBusManager( bus );
|
||||
bus->Start();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( found == false ) {
|
||||
if (!found) {
|
||||
TRACE(("USB OHCI: init hardware(): no devices found\n"));
|
||||
free( item );
|
||||
put_module( B_PCI_MODULE_NAME );
|
||||
@ -184,7 +189,10 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
fHccaArea(-1),
|
||||
fDummyControl(0),
|
||||
fDummyBulk(0),
|
||||
fDummyIsochronous(0)
|
||||
fDummyIsochronous(0),
|
||||
fRootHub(0),
|
||||
fRootHubAddress(0),
|
||||
fNumPorts(0)
|
||||
{
|
||||
fPcii = info;
|
||||
fStack = stack;
|
||||
@ -321,9 +329,7 @@ OHCI::OHCI(pci_info *info, Stack *stack)
|
||||
uint32 interval = OHCI_GET_IVAL(frameinterval);
|
||||
WriteReg(OHCI_PERIODIC_START, OHCI_PERIODIC(interval));
|
||||
|
||||
|
||||
m_roothub_base = 255; //Invalidate the Root Hub address
|
||||
|
||||
fInitOK = true;
|
||||
}
|
||||
|
||||
OHCI::~OHCI()
|
||||
@ -338,18 +344,140 @@ OHCI::~OHCI()
|
||||
FreeEndpoint(fDummyBulk);
|
||||
if (fDummyIsochronous)
|
||||
FreeEndpoint(fDummyIsochronous);
|
||||
if (fRootHub)
|
||||
delete fRootHub;
|
||||
for (int i = 0; i < OHCI_NO_EDS; i++)
|
||||
if (fInterruptEndpoints[i])
|
||||
FreeEndpoint(fInterruptEndpoints[i]);
|
||||
}
|
||||
|
||||
status_t
|
||||
OHCI::Start()
|
||||
{
|
||||
if (!(ReadReg(OHCI_CONTROL) & OHCI_HCFS_OPERATIONAL)) {
|
||||
TRACE(("USB OHCI::Start(): Controller not started. TODO: find out what happens.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fRootHubAddress = AllocateAddress();
|
||||
fNumPorts = OHCI_GET_PORT_COUNT(ReadReg(OHCI_RH_DESCRIPTOR_A));
|
||||
|
||||
fRootHub = new(std::nothrow) OHCIRootHub(this, fRootHubAddress);
|
||||
if (!fRootHub) {
|
||||
TRACE_ERROR(("USB OHCI::Start(): no memory to allocate root hub\n"));
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (fRootHub->InitCheck() < B_OK) {
|
||||
TRACE_ERROR(("USB OHCI::Start(): root hub failed init check\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
SetRootHub(fRootHub);
|
||||
TRACE(("USB OHCI::Start(): Succesful start\n"));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t OHCI::SubmitTransfer( Transfer *t )
|
||||
{
|
||||
TRACE(("usb OHCI::SubmitTransfer: called for device %d\n", t->TransferPipe()->DeviceAddress()));
|
||||
|
||||
if (t->TransferPipe()->DeviceAddress() == fRootHubAddress)
|
||||
return fRootHub->ProcessTransfer(t, this);
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
status_t
|
||||
OHCI::GetPortStatus(uint8 index, usb_port_status *status)
|
||||
{
|
||||
if (index > fNumPorts)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
status->status = status->change = 0;
|
||||
uint32 portStatus = ReadReg(OHCI_RH_PORT_STATUS(index));
|
||||
|
||||
TRACE(("OHCIRootHub::GetPortStatus: Port %i Value 0x%lx\n", OHCI_RH_PORT_STATUS(index), portStatus));
|
||||
|
||||
// status
|
||||
if (portStatus & OHCI_PORTSTATUS_CCS)
|
||||
status->status |= PORT_STATUS_CONNECTION;
|
||||
if (portStatus & OHCI_PORTSTATUS_PES)
|
||||
status->status |= PORT_STATUS_ENABLE;
|
||||
if (portStatus & OHCI_PORTSTATUS_PRS)
|
||||
status->status |= PORT_STATUS_RESET;
|
||||
if (portStatus & OHCI_PORTSTATUS_LSDA)
|
||||
status->status |= PORT_STATUS_LOW_SPEED;
|
||||
if (portStatus & OHCI_PORTSTATUS_PSS)
|
||||
status->status |= PORT_STATUS_SUSPEND;
|
||||
if (portStatus & OHCI_PORTSTATUS_POCI)
|
||||
status->status |= PORT_STATUS_OVER_CURRENT;
|
||||
if (portStatus & OHCI_PORTSTATUS_PPS)
|
||||
status->status |= PORT_STATUS_POWER;
|
||||
|
||||
|
||||
// change
|
||||
if (portStatus & OHCI_PORTSTATUS_CSC)
|
||||
status->change |= PORT_STATUS_CONNECTION;
|
||||
if (portStatus & OHCI_PORTSTATUS_PESC)
|
||||
status->change |= PORT_STATUS_ENABLE;
|
||||
if (portStatus & OHCI_PORTSTATUS_PSSC)
|
||||
status->change |= PORT_STATUS_SUSPEND;
|
||||
if (portStatus & OHCI_PORTSTATUS_OCIC)
|
||||
status->change |= PORT_STATUS_OVER_CURRENT;
|
||||
if (portStatus & OHCI_PORTSTATUS_PRSC)
|
||||
status->change |= PORT_STATUS_RESET;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
OHCI::SetPortFeature(uint8 index, uint16 feature)
|
||||
{
|
||||
if (index > fNumPorts)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
switch (feature) {
|
||||
case PORT_RESET:
|
||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_PORTSTATUS_PRS);
|
||||
return B_OK;
|
||||
|
||||
case PORT_POWER:
|
||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_PORTSTATUS_PPS);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
status_t
|
||||
OHCI::ClearPortFeature(uint8 index, uint16 feature)
|
||||
{
|
||||
if (index > fNumPorts)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
switch (feature) {
|
||||
case C_PORT_RESET:
|
||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_PORTSTATUS_CSC);
|
||||
return B_OK;
|
||||
|
||||
case C_PORT_CONNECTION:
|
||||
WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_PORTSTATUS_CSC);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
Endpoint *
|
||||
OHCI::AllocateEndpoint()
|
||||
{
|
||||
Endpoint *endpoint = new Endpoint;
|
||||
void *phy;
|
||||
if (fStack->AllocateChunk((void **)&endpoint->ed, &phy, sizeof(ohci_endpoint_descriptor)) != B_OK)
|
||||
if (fStack->AllocateChunk((void **)&endpoint->ed, &phy, sizeof(ohci_endpoint_descriptor)) != B_OK) {
|
||||
TRACE(("OHCI::AllocateEndpoint(): Error Allocating Endpoint\n"));
|
||||
return 0;
|
||||
}
|
||||
endpoint->physicaladdress = (addr_t)phy;
|
||||
|
||||
memset((void *)endpoint->ed, 0, sizeof(ohci_endpoint_descriptor));
|
||||
@ -364,17 +492,6 @@ OHCI::FreeEndpoint(Endpoint *end)
|
||||
delete end;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// OHCI:: Submit a transfer
|
||||
//
|
||||
// parameters:
|
||||
// - t: pointer to a transfer instance
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
status_t OHCI::SubmitTransfer( Transfer *t )
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
pci_module_info *OHCI::pci_module = 0;
|
||||
|
||||
|
@ -48,13 +48,20 @@ public:
|
||||
|
||||
OHCI(pci_info *info, Stack *stack);
|
||||
~OHCI();
|
||||
status_t Start();
|
||||
status_t SubmitTransfer(Transfer *t); //Override from BusManager.
|
||||
static pci_module_info *pci_module; // Global data for the module.
|
||||
|
||||
status_t GetPortStatus(uint8 index, usb_port_status *status);
|
||||
status_t ClearPortFeature(uint8 index, uint16 feature);
|
||||
status_t SetPortFeature(uint8 index, uint16 feature);
|
||||
|
||||
uint8 PortCount() { return fNumPorts; };
|
||||
|
||||
private:
|
||||
inline void WriteReg(uint32 reg, uint32 value);
|
||||
inline uint32 ReadReg(uint32 reg);
|
||||
|
||||
private:
|
||||
|
||||
// Global
|
||||
pci_info *fPcii; // pci-info struct
|
||||
Stack *fStack; // Pointer to the stack
|
||||
@ -69,8 +76,9 @@ private:
|
||||
Endpoint *fDummyBulk;
|
||||
Endpoint *fDummyIsochronous;
|
||||
// Root Hub
|
||||
OHCIRootHub *m_roothub; // the root hub
|
||||
addr_t m_roothub_base; // Base address of the root hub
|
||||
OHCIRootHub *fRootHub; // the root hub
|
||||
uint8 fRootHubAddress; // the usb address of the roothub
|
||||
uint8 fNumPorts; // the number of ports
|
||||
// functions
|
||||
Endpoint *AllocateEndpoint(); // allocate memory for an endpoint
|
||||
void FreeEndpoint(Endpoint *end); //Free endpoint
|
||||
@ -85,12 +93,8 @@ private:
|
||||
class OHCIRootHub : public Hub
|
||||
{
|
||||
public:
|
||||
OHCIRootHub( OHCI *ohci , int8 devicenum );
|
||||
status_t SubmitTransfer( Transfer *t );
|
||||
void UpdatePortStatus();
|
||||
private:
|
||||
usb_port_status m_hw_port_status[2]; // the port status (maximum of two)
|
||||
OHCI *m_ohci; // needed because of internal data
|
||||
OHCIRootHub(OHCI *ohci, int8 deviceAddress);
|
||||
status_t ProcessTransfer(Transfer *t, OHCI *ohci);
|
||||
};
|
||||
|
||||
//
|
||||
@ -110,6 +114,4 @@ struct Endpoint
|
||||
};
|
||||
};
|
||||
|
||||
#define OHCI_DEBUG
|
||||
|
||||
#endif // OHCI_H
|
||||
|
@ -189,7 +189,7 @@
|
||||
// --------------------------------
|
||||
|
||||
#define OHCI_RH_DESCRIPTOR_A 0x48
|
||||
#define OHCI_GET_NDP(s) ((s) & 0xff)
|
||||
#define OHCI_GET_PORT_COUNT(s) ((s) & 0xff)
|
||||
#define OHCI_PSM 0x0100 // Power Switching Mode
|
||||
#define OHCI_NPS 0x0200 // No Power Switching
|
||||
#define OHCI_DT 0x0400 // Device Type
|
||||
@ -220,6 +220,18 @@
|
||||
// --------------------------------
|
||||
|
||||
#define OHCI_RH_PORT_STATUS(n) (0x50 + (n)*4) // 1 based indexing
|
||||
#define OHCI_PORTSTATUS_CCS 0x00000001 // Current Connection Status
|
||||
#define OHCI_PORTSTATUS_PES 0x00000002 // Port Enable Status
|
||||
#define OHCI_PORTSTATUS_PSS 0x00000004 // Port Suspend Status
|
||||
#define OHCI_PORTSTATUS_POCI 0x00000008 // Port Overcurrent Indicator
|
||||
#define OHCI_PORTSTATUS_PRS 0x00000010 // Port Reset Status
|
||||
#define OHCI_PORTSTATUS_PPS 0x00000100 // Port Power Status
|
||||
#define OHCI_PORTSTATUS_LSDA 0x00000200 // Low Speed Device Attached
|
||||
#define OHCI_PORTSTATUS_CSC 0x00010000 // Connection Status Change
|
||||
#define OHCI_PORTSTATUS_PESC 0x00020000 // Port Enable Status Change
|
||||
#define OHCI_PORTSTATUS_PSSC 0x00040000 // Port Suspend Status change
|
||||
#define OHCI_PORTSTATUS_OCIC 0x00080000 // Port Overcurrent Change
|
||||
#define OHCI_PORTSTATUS_PRSC 0x00100000 // Port Reset Status Change
|
||||
|
||||
// --------------------------------
|
||||
// ????
|
||||
|
@ -22,9 +22,8 @@
|
||||
|
||||
|
||||
#include "ohci.h"
|
||||
#include <PCI.h>
|
||||
|
||||
usb_device_descriptor ohci_devd =
|
||||
static usb_device_descriptor sOHCIRootHubDevice =
|
||||
{
|
||||
0x12, //Descriptor size
|
||||
USB_DESCRIPTOR_DEVICE , //Type of descriptor
|
||||
@ -40,65 +39,231 @@ usb_device_descriptor ohci_devd =
|
||||
1 //Number of configurations
|
||||
};
|
||||
|
||||
usb_configuration_descriptor ohci_confd =
|
||||
{
|
||||
0x09, //Size
|
||||
USB_DESCRIPTOR_CONFIGURATION ,
|
||||
25 , //Total size (taken from BSD source)
|
||||
1 , //Number interfaces
|
||||
1 , //Value of configuration
|
||||
0 , //Number of configuration
|
||||
0x40 , //Self powered
|
||||
0 //Max power (0, because of self power)
|
||||
struct ohci_root_hub_configuration_s {
|
||||
usb_configuration_descriptor configuration;
|
||||
usb_interface_descriptor interface;
|
||||
usb_endpoint_descriptor endpoint;
|
||||
usb_hub_descriptor hub;
|
||||
} _PACKED;
|
||||
|
||||
static ohci_root_hub_configuration_s sOHCIRootHubConfig = {
|
||||
{ // configuration descriptor
|
||||
9, //Size
|
||||
USB_DESCRIPTOR_CONFIGURATION,
|
||||
34, //Total size of the configuration
|
||||
1, //Number interfaces
|
||||
1, //Value of configuration
|
||||
0, //Number of configuration
|
||||
0x40, //Self powered
|
||||
0 //Max power (0, because of self power)
|
||||
},
|
||||
|
||||
{ // interface descriptor
|
||||
9, //Size
|
||||
USB_DESCRIPTOR_INTERFACE,
|
||||
0, //Interface number
|
||||
0, //Alternate setting
|
||||
1, //Num endpoints
|
||||
0x09, //Interface class
|
||||
0, //Interface subclass
|
||||
0, //Interface protocol
|
||||
0 //Interface
|
||||
},
|
||||
|
||||
{ // endpoint descriptor
|
||||
7, //Size
|
||||
USB_DESCRIPTOR_ENDPOINT,
|
||||
USB_REQTYPE_DEVICE_IN | 1, //1 from freebsd driver
|
||||
0x3, // Interrupt
|
||||
8, // Max packet size
|
||||
0xFF // Interval 256
|
||||
},
|
||||
|
||||
{
|
||||
9, //Including deprecated powerctrlmask
|
||||
USB_DESCRIPTOR_HUB,
|
||||
0, //Number of ports
|
||||
0x0000, //Hub characteristics FIXME
|
||||
50, //Power on to power good
|
||||
0, // Current
|
||||
0x00, //Both ports are removable
|
||||
0xff // Depricated power control mask
|
||||
}
|
||||
};
|
||||
|
||||
usb_interface_descriptor ohci_intd =
|
||||
{
|
||||
0x09 , //Size
|
||||
USB_DESCRIPTOR_INTERFACE ,
|
||||
0 , //Interface number
|
||||
0 , //Alternate setting
|
||||
1 , //Num endpoints
|
||||
0x09 , //Interface class
|
||||
0 , //Interface subclass
|
||||
0 , //Interface protocol
|
||||
0 , //Interface
|
||||
struct ohci_root_hub_string_s {
|
||||
uint8 length;
|
||||
uint8 descriptor_type;
|
||||
uint16 unicode_string[12];
|
||||
} _PACKED;
|
||||
|
||||
|
||||
static ohci_root_hub_string_s sOHCIRootHubStrings[3] = {
|
||||
{
|
||||
4, // Descriptor length
|
||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
||||
{
|
||||
0x0409 // Supported language IDs (English US)
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
22, // Descriptor length
|
||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
||||
{
|
||||
'H', 'A', 'I', 'K', 'U', // Characters
|
||||
' ', 'I', 'n', 'c', '.'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
26, // Descriptor length
|
||||
USB_DESCRIPTOR_STRING, // Descriptor type
|
||||
{
|
||||
'O', 'H', 'C', 'I', ' ', // Characters
|
||||
'R', 'o', 'o', 't', 'H',
|
||||
'u', 'b'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
usb_endpoint_descriptor ohci_endd =
|
||||
{
|
||||
0x07 , //Size
|
||||
USB_DESCRIPTOR_ENDPOINT,
|
||||
USB_REQTYPE_DEVICE_IN | 1, //1 from freebsd driver
|
||||
0x3 , // Interrupt
|
||||
8 , // Max packet size
|
||||
0xFF // Interval 256
|
||||
};
|
||||
|
||||
usb_hub_descriptor ohci_hubd =
|
||||
OHCIRootHub::OHCIRootHub(OHCI *ohci, int8 deviceAddress)
|
||||
: Hub(ohci->RootObject(), sOHCIRootHubDevice, deviceAddress , USB_SPEED_FULLSPEED )
|
||||
{
|
||||
0x09 , //Including deprecated powerctrlmask
|
||||
USB_DESCRIPTOR_HUB,
|
||||
1, //Number of ports
|
||||
0x02 | 0x01 , //Hub characteristics FIXME
|
||||
50 , //Power on to power good
|
||||
0, // Current
|
||||
0x00 //Both ports are removable
|
||||
};
|
||||
|
||||
//Implementation
|
||||
OHCIRootHub::OHCIRootHub( OHCI *ohci , int8 devicenum )
|
||||
: Hub( ohci->RootObject() , ohci_devd , devicenum , USB_SPEED_FULLSPEED )
|
||||
{
|
||||
m_ohci = ohci;
|
||||
}
|
||||
|
||||
status_t OHCIRootHub::SubmitTransfer( Transfer *t )
|
||||
status_t
|
||||
OHCIRootHub::ProcessTransfer(Transfer *t, OHCI *ohci)
|
||||
{
|
||||
if ((t->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
|
||||
return B_ERROR;
|
||||
|
||||
usb_request_data *request = t->RequestData();
|
||||
TRACE(("OHCIRootHub::ProcessTransfer(): request: %d\n", request->Request));
|
||||
|
||||
uint32 status = B_USB_STATUS_DEVICE_TIMEOUT;
|
||||
size_t actualLength = 0;
|
||||
switch (request->Request) {
|
||||
case USB_REQUEST_GET_STATUS: {
|
||||
if (request->Index == 0) {
|
||||
// get hub status
|
||||
actualLength = MIN(sizeof(usb_port_status),
|
||||
t->DataLength());
|
||||
// the hub reports whether the local power failed (bit 0)
|
||||
// and if there is a over-current condition (bit 1).
|
||||
// everything as 0 means all is ok.
|
||||
// TODO (?) actually check for the value
|
||||
memset(t->Data(), 0, actualLength);
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
usb_port_status portStatus;
|
||||
if (ohci->GetPortStatus(request->Index, &portStatus) >= B_OK) {
|
||||
actualLength = MIN(sizeof(usb_port_status), t->DataLength());
|
||||
memcpy(t->Data(), (void *)&portStatus, actualLength);
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_REQUEST_SET_ADDRESS:
|
||||
if (request->Value >= 128) {
|
||||
status = B_USB_STATUS_DEVICE_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE(("OHCIRootHub::ProcessTransfer(): set address: %d\n", request->Value));
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case USB_REQUEST_GET_DESCRIPTOR:
|
||||
TRACE(("OHCIRootHub::ProcessTransfer(): get descriptor: %d\n", request->Value >> 8));
|
||||
|
||||
switch (request->Value >> 8) {
|
||||
case USB_DESCRIPTOR_DEVICE: {
|
||||
actualLength = MIN(sizeof(usb_device_descriptor),
|
||||
t->DataLength());
|
||||
memcpy(t->Data(), (void *)&sOHCIRootHubDevice,
|
||||
actualLength);
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_DESCRIPTOR_CONFIGURATION: {
|
||||
//Make sure we have the correct number of ports
|
||||
sOHCIRootHubConfig.hub.num_ports = ohci->PortCount();
|
||||
|
||||
actualLength = MIN(sizeof(sOHCIRootHubConfig),
|
||||
t->DataLength());
|
||||
memcpy(t->Data(), (void *)&(sOHCIRootHubConfig),
|
||||
actualLength);
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_DESCRIPTOR_STRING: {
|
||||
uint8 index = request->Value & 0x00ff;
|
||||
if (index > 2)
|
||||
break;
|
||||
|
||||
actualLength = MIN(sOHCIRootHubStrings[index].length,
|
||||
t->DataLength());
|
||||
memcpy(t->Data(), (void *)&sOHCIRootHubStrings[index],
|
||||
actualLength);
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_DESCRIPTOR_HUB: {
|
||||
//Make sure we have the correct number of ports
|
||||
sOHCIRootHubConfig.hub.num_ports = ohci->PortCount();
|
||||
|
||||
actualLength = MIN(sizeof(usb_hub_descriptor),
|
||||
t->DataLength());
|
||||
memcpy(t->Data(), (void *)&sOHCIRootHubConfig.hub,
|
||||
actualLength);
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQUEST_SET_CONFIGURATION:
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case USB_REQUEST_CLEAR_FEATURE: {
|
||||
if (request->Index == 0) {
|
||||
// we don't support any hub changes
|
||||
TRACE_ERROR(("OHCIRootHub::ProcessTransfer(): clear feature: no hub changes\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE(("OHCIRootHub::ProcessTransfer(): clear feature: %d\n", request->Value));
|
||||
if (ohci->ClearPortFeature(request->Index, request->Value) >= B_OK)
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_REQUEST_SET_FEATURE: {
|
||||
if (request->Index == 0) {
|
||||
// we don't support any hub changes
|
||||
TRACE_ERROR(("OHCIRootHub::ProcessTransfer(): set feature: no hub changes\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE(("OHCIRootHub::ProcessTransfer(): set feature: %d\n", request->Value));
|
||||
if (ohci->SetPortFeature(request->Index, request->Value) >= B_OK)
|
||||
status = B_USB_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
t->Finished(status, actualLength);
|
||||
delete t;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void OHCIRootHub::UpdatePortStatus(void)
|
||||
{
|
||||
// nothing yet
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user