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);
}
Exemple #3
0
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;
}