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; }
boolean USBKeyboardDeviceConfigure (TUSBDevice *pUSBDevice) { TUSBKeyboardDevice *pThis = (TUSBKeyboardDevice *) pUSBDevice; assert (pThis != 0); TUSBConfigurationDescriptor *pConfDesc = (TUSBConfigurationDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_CONFIGURATION); if ( pConfDesc == 0 || pConfDesc->bNumInterfaces < 1) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromUSBKbd); return FALSE; } TUSBInterfaceDescriptor *pInterfaceDesc; while ((pInterfaceDesc = (TUSBInterfaceDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_INTERFACE)) != 0) { if ( pInterfaceDesc->bNumEndpoints < 1 || pInterfaceDesc->bInterfaceClass != 0x03 // HID Class || pInterfaceDesc->bInterfaceSubClass != 0x01 // Boot Interface Subclass || pInterfaceDesc->bInterfaceProtocol != 0x01) // Keyboard { continue; } pThis->m_ucInterfaceNumber = pInterfaceDesc->bInterfaceNumber; pThis->m_ucAlternateSetting = pInterfaceDesc->bAlternateSetting; TUSBEndpointDescriptor *pEndpointDesc = (TUSBEndpointDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_ENDPOINT); if ( pEndpointDesc == 0 || (pEndpointDesc->bEndpointAddress & 0x80) != 0x80 // Input EP || (pEndpointDesc->bmAttributes & 0x3F) != 0x03) // Interrupt EP { continue; } assert (pThis->m_pReportEndpoint == 0); pThis->m_pReportEndpoint = malloc (sizeof (TUSBEndpoint)); assert (pThis->m_pReportEndpoint != 0); USBEndpoint2 (pThis->m_pReportEndpoint, &pThis->m_USBDevice, pEndpointDesc); break; } if (pThis->m_pReportEndpoint == 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromUSBKbd); return FALSE; } if (!USBDeviceConfigure (&pThis->m_USBDevice)) { LogWrite (FromUSBKbd, LOG_ERROR, "Cannot set configuration"); return FALSE; } if (pThis->m_ucAlternateSetting != 0) { if (DWHCIDeviceControlMessage (USBDeviceGetHost (&pThis->m_USBDevice), USBDeviceGetEndpoint0 (&pThis->m_USBDevice), REQUEST_OUT | REQUEST_TO_INTERFACE, SET_INTERFACE, pThis->m_ucAlternateSetting, pThis->m_ucInterfaceNumber, 0, 0) < 0) { LogWrite (FromUSBKbd, LOG_ERROR, "Cannot set interface"); return FALSE; } } if (DWHCIDeviceControlMessage (USBDeviceGetHost (&pThis->m_USBDevice), USBDeviceGetEndpoint0 (&pThis->m_USBDevice), REQUEST_OUT | REQUEST_CLASS | REQUEST_TO_INTERFACE, SET_PROTOCOL, BOOT_PROTOCOL, pThis->m_ucInterfaceNumber, 0, 0) < 0) { LogWrite (FromUSBKbd, LOG_ERROR, "Cannot set boot protocol"); return FALSE; } TString DeviceName; String (&DeviceName); StringFormat (&DeviceName, "ukbd%u", s_nDeviceNumber++); DeviceNameServiceAddDevice (DeviceNameServiceGet (), StringGet (&DeviceName), pThis, FALSE); _String (&DeviceName); return USBKeyboardDeviceStartRequest (pThis); }
boolean SMSC951xDeviceConfigure (TUSBDevice *pUSBDevice) { TSMSC951xDevice *pThis = (TSMSC951xDevice *) pUSBDevice; assert (pThis != 0); u8 MACAddress[MAC_ADDRESS_SIZE]; if (GetMACAddress (MACAddress)) { MACAddressSet (&pThis->m_MACAddress, MACAddress); } else { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot get MAC address"); return FALSE; } TString MACString; String (&MACString); MACAddressFormat (&pThis->m_MACAddress, &MACString); LogWrite (FromSMSC951x, LOG_DEBUG, "MAC address is %s", StringGet (&MACString)); const TUSBConfigurationDescriptor *pConfigDesc = (TUSBConfigurationDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_CONFIGURATION); if ( pConfigDesc == 0 || pConfigDesc->bNumInterfaces != 1) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } const TUSBInterfaceDescriptor *pInterfaceDesc = (TUSBInterfaceDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_INTERFACE); if ( pInterfaceDesc == 0 || pInterfaceDesc->bInterfaceNumber != 0x00 || pInterfaceDesc->bAlternateSetting != 0x00 || pInterfaceDesc->bNumEndpoints != 3) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } const TUSBEndpointDescriptor *pEndpointDesc; while ((pEndpointDesc = (TUSBEndpointDescriptor *) USBDeviceGetDescriptor (&pThis->m_USBDevice, DESCRIPTOR_ENDPOINT)) != 0) { if ((pEndpointDesc->bmAttributes & 0x3F) == 0x02) // Bulk { if ((pEndpointDesc->bEndpointAddress & 0x80) == 0x80) // Input { if (pThis->m_pEndpointBulkIn != 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } pThis->m_pEndpointBulkIn = (TUSBEndpoint *) malloc (sizeof (TUSBEndpoint)); assert (pThis->m_pEndpointBulkIn); USBEndpoint2 (pThis->m_pEndpointBulkIn, &pThis->m_USBDevice, pEndpointDesc); } else // Output { if (pThis->m_pEndpointBulkOut != 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } pThis->m_pEndpointBulkOut = (TUSBEndpoint *) malloc (sizeof (TUSBEndpoint)); assert (pThis->m_pEndpointBulkOut); USBEndpoint2 (pThis->m_pEndpointBulkOut, &pThis->m_USBDevice, pEndpointDesc); } } } if ( pThis->m_pEndpointBulkIn == 0 || pThis->m_pEndpointBulkOut == 0) { USBDeviceConfigurationError (&pThis->m_USBDevice, FromSMSC951x); _String (&MACString); return FALSE; } if (!USBDeviceConfigure (&pThis->m_USBDevice)) { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot set configuration"); _String (&MACString); return FALSE; } u8 MACAddressBuffer[MAC_ADDRESS_SIZE]; MACAddressCopyTo (&pThis->m_MACAddress, MACAddressBuffer); u16 usMACAddressHigh = *(u16 *) &MACAddressBuffer[4]; u32 nMACAddressLow = *(u32 *) &MACAddressBuffer[0]; if ( !SMSC951xDeviceWriteReg (pThis, ADDRH, usMACAddressHigh) || !SMSC951xDeviceWriteReg (pThis, ADDRL, nMACAddressLow)) { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot set MAC address"); _String (&MACString); return FALSE; } if ( !SMSC951xDeviceWriteReg (pThis, LED_GPIO_CFG, LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | LED_GPIO_CFG_FDX_LED) || !SMSC951xDeviceWriteReg (pThis, MAC_CR, MAC_CR_RCVOWN //| MAC_CR_PRMS // promiscous mode | MAC_CR_TXEN | MAC_CR_RXEN) || !SMSC951xDeviceWriteReg (pThis, TX_CFG, TX_CFG_ON)) { LogWrite (FromSMSC951x, LOG_ERROR, "Cannot start device"); _String (&MACString); return FALSE; } // TODO: check if PHY is up (wait for it) TString DeviceName; String (&DeviceName); StringFormat (&DeviceName, "eth%u", s_nDeviceNumber++); DeviceNameServiceAddDevice (DeviceNameServiceGet (), StringGet (&DeviceName), pThis, FALSE); _String (&DeviceName); _String (&MACString); return TRUE; }