boolean USBStandardHubConfigure (TUSBDevice *pUSBDevice) { TUSBStandardHub *pThis = (TUSBStandardHub *) pUSBDevice; assert (pThis != 0); const TUSBDeviceDescriptor *pDeviceDesc = USBDeviceGetDeviceDescriptor (&pThis->m_USBDevice); assert (pDeviceDesc != 0); if ( pDeviceDesc->bDeviceClass != USB_DEVICE_CLASS_HUB || pDeviceDesc->bDeviceSubClass != 0 || pDeviceDesc->bDeviceProtocol != 2 // hub with multiple TTs || pDeviceDesc->bNumConfigurations != 1) { LogWrite (FromHub, LOG_ERROR, "Unsupported hub (proto %u)", (unsigned) pDeviceDesc->bDeviceProtocol); return FALSE; } const TUSBConfigurationDescriptor *pConfigDesc = (TUSBConfigurationDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_CONFIGURATION); if ( pConfigDesc == 0 || pConfigDesc->bNumInterfaces != 1) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromHub); return FALSE; } const TUSBInterfaceDescriptor *pInterfaceDesc; while ((pInterfaceDesc = (TUSBInterfaceDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_INTERFACE)) != 0) { if ( pInterfaceDesc->bInterfaceClass != USB_DEVICE_CLASS_HUB || pInterfaceDesc->bInterfaceSubClass != 0 || pInterfaceDesc->bInterfaceProtocol != 2) { continue; } if (pInterfaceDesc->bNumEndpoints != 1) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromHub); return FALSE; } const TUSBEndpointDescriptor *pEndpointDesc = (TUSBEndpointDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_ENDPOINT); if ( pEndpointDesc == 0 || (pEndpointDesc->bEndpointAddress & 0x80) != 0x80 // input EP || (pEndpointDesc->bmAttributes & 0x3F) != 0x03) // interrupt EP { USBDeviceConfigurationError (&pThis->m_USBDevice, FromHub); return FALSE; } break; } if (pInterfaceDesc == 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromHub); return FALSE; } if (!USBDeviceConfigure (&pThis->m_USBDevice)) { LogWrite (FromHub, LOG_ERROR, "Cannot set configuration"); return FALSE; } TUSBHostController *pHost = USBDeviceGetHost (&pThis->m_USBDevice); assert (pHost != 0); if (pInterfaceDesc->bAlternateSetting != 0) { if (DWHCIDeviceControlMessage (pHost, USBDeviceGetEndpoint0 (&pThis->m_USBDevice), REQUEST_OUT | REQUEST_TO_INTERFACE, SET_INTERFACE, pInterfaceDesc->bAlternateSetting, pInterfaceDesc->bInterfaceNumber, 0, 0) < 0) { LogWrite (FromHub, LOG_ERROR, "Cannot set interface"); return FALSE; } } assert (pThis->m_pHubDesc == 0); pThis->m_pHubDesc = (TUSBHubDescriptor *) malloc (sizeof (TUSBHubDescriptor)); assert (pThis->m_pHubDesc != 0); if (DWHCIDeviceGetDescriptor (pHost, USBDeviceGetEndpoint0 (&pThis->m_USBDevice), DESCRIPTOR_HUB, DESCRIPTOR_INDEX_DEFAULT, pThis->m_pHubDesc, sizeof *pThis->m_pHubDesc, REQUEST_IN | REQUEST_CLASS) != (int) sizeof *pThis->m_pHubDesc) { LogWrite (FromHub, LOG_ERROR, "Cannot get hub descriptor"); free (pThis->m_pHubDesc); pThis->m_pHubDesc = 0; return FALSE; } #ifndef NDEBUG //DebugHexdump (pThis->m_pHubDesc, sizeof *pThis->m_pHubDesc, FromHub); #endif pThis->m_nPorts = pThis->m_pHubDesc->bNbrPorts; if (pThis->m_nPorts > USB_HUB_MAX_PORTS) { LogWrite (FromHub, LOG_ERROR, "Too many ports (%u)", pThis->m_nPorts); free (pThis->m_pHubDesc); pThis->m_pHubDesc = 0; return FALSE; } if (!USBStandardHubEnumeratePorts (pThis)) { LogWrite (FromHub, LOG_ERROR, "Port enumeration failed"); return FALSE; } return TRUE; }
int USPiDeviceGetInformation (unsigned nClass, unsigned nDeviceIndex, TUSPiDeviceInformation *pInfo) { assert (s_pLibrary != 0); TUSBDevice *pUSBDevice = 0; switch (nClass) { case KEYBOARD_CLASS: if (nDeviceIndex == 0) { pUSBDevice = (TUSBDevice *) s_pLibrary->pUKBD1; } break; case MOUSE_CLASS: if (nDeviceIndex == 0) { pUSBDevice = (TUSBDevice *) s_pLibrary->pUMouse1; } break; case STORAGE_CLASS: if (nDeviceIndex < MAX_DEVICES) { pUSBDevice = (TUSBDevice *) s_pLibrary->pUMSD[nDeviceIndex]; } break; case ETHERNET_CLASS: if (nDeviceIndex == 0) { pUSBDevice = (TUSBDevice *) s_pLibrary->pEth0; } break; case GAMEPAD_CLASS: if (nDeviceIndex < MAX_DEVICES) { pUSBDevice = (TUSBDevice *) s_pLibrary->pUPAD[nDeviceIndex]; } break; case MIDI_CLASS: if (nDeviceIndex == 0) { pUSBDevice = (TUSBDevice *) s_pLibrary->pMIDI1; } break; default: break; } if (pUSBDevice == 0) { return 0; } const TUSBDeviceDescriptor *pDesc = USBDeviceGetDeviceDescriptor (pUSBDevice); assert (pDesc != 0); assert (pInfo != 0); pInfo->idVendor = pDesc->idVendor; pInfo->idProduct = pDesc->idProduct; pInfo->bcdDevice = pDesc->bcdDevice; pInfo->pManufacturer = USBStringGet (&pUSBDevice->m_ManufacturerString); pInfo->pProduct = USBStringGet (&pUSBDevice->m_ProductString); return 1; }