diff --git a/drivers/usb/usbehci_new/hub_controller.cpp b/drivers/usb/usbehci_new/hub_controller.cpp index 4dc153a9392..9e57952d202 100644 --- a/drivers/usb/usbehci_new/hub_controller.cpp +++ b/drivers/usb/usbehci_new/hub_controller.cpp @@ -1050,7 +1050,7 @@ CHubController::HandleClassDevice( // // FIXME: retrieve values // - UsbHubDescriptor->bNumberOfPorts = PortCount; + UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount; UsbHubDescriptor->wHubCharacteristics = 0x0012; UsbHubDescriptor->bPowerOnToPowerGood = 0x01; UsbHubDescriptor->bHubControlCurrent = 0x00; @@ -1842,8 +1842,6 @@ USBHI_GetUsbDescriptors( { PUSBDEVICE UsbDevice; CHubController * Controller; - NTSTATUS Status; - PURB Urb; DPRINT1("USBHI_GetUsbDescriptors\n"); @@ -1851,7 +1849,10 @@ USBHI_GetUsbDescriptors( // sanity check // PC_ASSERT(DeviceDescriptorBuffer); + PC_ASSERT(DeviceDescriptorBufferLength); PC_ASSERT(*DeviceDescriptorBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR)); + PC_ASSERT(ConfigDescriptorBufferLength); + PC_ASSERT(*ConfigDescriptorBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR)); // // first get controller @@ -1890,54 +1891,14 @@ USBHI_GetUsbDescriptors( *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); // - // allocate urb + // get configuration descriptor // - Urb = (PURB)ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), TAG_USBEHCI); - if (!Urb) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // zero request - // - RtlZeroMemory(Urb, sizeof(URB)); - - // - // initialize request - // - Urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE; - Urb->UrbHeader.Length = sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST); - Urb->UrbControlDescriptorRequest.DescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE; - Urb->UrbControlDescriptorRequest.TransferBuffer = ConfigDescriptorBuffer; - Urb->UrbControlDescriptorRequest.TransferBufferLength = *ConfigDescriptorBufferLength; - - // - // submit urb - // - //Status = UsbDevice->SubmitUrb(Urb); - UNIMPLEMENTED - - if (NT_SUCCESS(Status)) - { - // - // TransferBufferLength holds the number of bytes transferred - // - *ConfigDescriptorBufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; - } - - // - // free urb - // - ExFreePoolWithTag(Urb, TAG_USBEHCI); + UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer, *ConfigDescriptorBufferLength, ConfigDescriptorBufferLength); // // complete the request // - return Status; + return STATUS_SUCCESS; } NTSTATUS @@ -2195,7 +2156,11 @@ USBHI_GetControllerInformation( // set length returned // *LengthReturned = ControllerInfo->ActualLength; - return STATUS_NOT_IMPLEMENTED; + + // + // done + // + return STATUS_SUCCESS; } NTSTATUS diff --git a/drivers/usb/usbehci_new/interfaces.h b/drivers/usb/usbehci_new/interfaces.h index 26c757b9fe5..c85dab68d41 100644 --- a/drivers/usb/usbehci_new/interfaces.h +++ b/drivers/usb/usbehci_new/interfaces.h @@ -748,6 +748,15 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown) virtual NTSTATUS SubmitIrp(PIRP Urb) = 0; +//----------------------------------------------------------------------------------------- +// +// GetConfigurationDescriptors +// +// Description: returns one or more configuration descriptors + + virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, + IN ULONG BufferLength, + OUT PULONG OutBufferLength) = 0; }; typedef IUSBDevice *PUSBDEVICE; diff --git a/drivers/usb/usbehci_new/usb_device.cpp b/drivers/usb/usbehci_new/usb_device.cpp index f900f7dc65d..30dea3a8749 100644 --- a/drivers/usb/usbehci_new/usb_device.cpp +++ b/drivers/usb/usbehci_new/usb_device.cpp @@ -65,6 +65,8 @@ public: virtual void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor); virtual UCHAR GetConfigurationValue(); virtual NTSTATUS SubmitIrp(PIRP Irp); + virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, IN ULONG BufferLength, OUT PULONG OutBufferLength); + // local function virtual NTSTATUS CommitIrp(PIRP Irp); @@ -113,7 +115,6 @@ CUSBDevice::Initialize( IN ULONG PortStatus) { NTSTATUS Status; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; // // initialize members @@ -835,6 +836,36 @@ CUSBDevice::CreateConfigurationDescriptor( // return Status; } +//---------------------------------------------------------------------------------------- +VOID +CUSBDevice::GetConfigurationDescriptors( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, + IN ULONG BufferLength, + OUT PULONG OutBufferLength) +{ + // + // sanity check + // + PC_ASSERT(BufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR)); + PC_ASSERT(ConfigDescriptorBuffer); + PC_ASSERT(OutBufferLength); + + // + // FIXME: support multiple configurations + // + PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); + + // + // copy first configuration descriptor + // + RtlCopyMemory(ConfigDescriptorBuffer, &m_ConfigurationDescriptors[0].ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); + + // + // store length + // + *OutBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); +} + //---------------------------------------------------------------------------------------- NTSTATUS diff --git a/drivers/usb/usbehci_new/usb_request.cpp b/drivers/usb/usbehci_new/usb_request.cpp index 680cd6bc722..a02b7e7fbad 100644 --- a/drivers/usb/usbehci_new/usb_request.cpp +++ b/drivers/usb/usbehci_new/usb_request.cpp @@ -56,6 +56,7 @@ public: NTSTATUS CreateQueueHead(PQUEUE_HEAD *OutQueueHead); ULONG GetDeviceAddress(); NTSTATUS BuildSetupPacket(); + NTSTATUS BuildSetupPacketFromURB(); // constructor / destructor CUSBRequest(IUnknown *OuterUnknown){} @@ -84,7 +85,6 @@ protected: // PMDL m_TransferBufferMDL; - // // caller provided setup packet // @@ -181,7 +181,6 @@ CUSBRequest::InitializeWithIrp( { PIO_STACK_LOCATION IoStack; PURB Urb; - NTSTATUS Status; // // sanity checks @@ -409,6 +408,10 @@ CUSBRequest::GetQueueHead( DPRINT1("USB_ENDPOINT_TYPE_ISOCHRONOUS not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break; + default: + PC_ASSERT(FALSE); + Status = STATUS_NOT_IMPLEMENTED; + break; } if (NT_SUCCESS(Status)) @@ -837,11 +840,6 @@ CUSBRequest::BuildSetupPacket() NTSTATUS Status; PHYSICAL_ADDRESS PhysicalAddress; - // - // FIXME: generate setup packet from urb request - // - PC_ASSERT(m_SetupPacket); - // // allocate common buffer setup packet // @@ -862,6 +860,13 @@ CUSBRequest::BuildSetupPacket() RtlCopyMemory(m_DescriptorPacket, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); m_DescriptorSetupPacket = PhysicalAddress; } + else + { + // + // build setup packet from urb + // + Status = BuildSetupPacketFromURB(); + } // // done @@ -869,6 +874,156 @@ CUSBRequest::BuildSetupPacket() return Status; } + +NTSTATUS +CUSBRequest::BuildSetupPacketFromURB() +{ + PIO_STACK_LOCATION IoStack; + PURB Urb; + NTSTATUS Status = STATUS_NOT_IMPLEMENTED; + + // + // sanity checks + // + PC_ASSERT(m_Irp); + PC_ASSERT(m_DescriptorPacket); + + // + // get stack location + // + IoStack = IoGetCurrentIrpStackLocation(m_Irp); + + // + // get urb + // + Urb = (PURB)IoStack->Parameters.Others.Argument1; + + // + // zero descriptor packet + // + RtlZeroMemory(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); + + + switch (Urb->UrbHeader.Function) + { + /* CLEAR FEATURE */ + case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: + case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: + case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: + UNIMPLEMENTED + break; + + /* GET CONFIG */ + case URB_FUNCTION_GET_CONFIGURATION: + m_DescriptorPacket->bRequest = USB_REQUEST_GET_CONFIGURATION; + m_DescriptorPacket->bmRequestType.B = 0x80; + m_DescriptorPacket->wLength = 1; + break; + + /* GET DESCRIPTOR */ + case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: + m_DescriptorPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR; + m_DescriptorPacket->wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; + m_DescriptorPacket->wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; + m_DescriptorPacket->wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; + m_DescriptorPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; + m_DescriptorPacket->bmRequestType.B = 0x80; + break; + + /* GET INTERFACE */ + case URB_FUNCTION_GET_INTERFACE: + m_DescriptorPacket->bRequest = USB_REQUEST_GET_CONFIGURATION; + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x80; + m_DescriptorPacket->wLength = 1; + break; + + /* GET STATUS */ + case URB_FUNCTION_GET_STATUS_FROM_DEVICE: + m_DescriptorPacket->bRequest = USB_REQUEST_GET_STATUS; + ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x80; + m_DescriptorPacket->wLength = 2; + break; + + case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: + m_DescriptorPacket->bRequest = USB_REQUEST_GET_STATUS; + ASSERT(Urb->UrbControlGetStatusRequest.Index != 0); + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x81; + m_DescriptorPacket->wLength = 2; + break; + + case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: + m_DescriptorPacket->bRequest = USB_REQUEST_GET_STATUS; + ASSERT(Urb->UrbControlGetStatusRequest.Index != 0); + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x82; + m_DescriptorPacket->wLength = 2; + break; + + /* SET ADDRESS */ + + /* SET CONFIG */ + case URB_FUNCTION_SELECT_CONFIGURATION: + m_DescriptorPacket->bRequest = USB_REQUEST_SET_CONFIGURATION; + m_DescriptorPacket->wValue.W = Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue; + m_DescriptorPacket->wIndex.W = 0; + m_DescriptorPacket->wLength = 0; + m_DescriptorPacket->bmRequestType.B = 0x00; + break; + + /* SET DESCRIPTOR */ + case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE: + case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE: + case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT: + UNIMPLEMENTED + break; + + /* SET FEATURE */ + case URB_FUNCTION_SET_FEATURE_TO_DEVICE: + m_DescriptorPacket->bRequest = USB_REQUEST_SET_FEATURE; + ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x80; + break; + + case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: + m_DescriptorPacket->bRequest = USB_REQUEST_SET_FEATURE; + ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x81; + break; + + case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: + m_DescriptorPacket->bRequest = USB_REQUEST_SET_FEATURE; + ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); + m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; + m_DescriptorPacket->bmRequestType.B = 0x82; + break; + + /* SET INTERFACE*/ + case URB_FUNCTION_SELECT_INTERFACE: + m_DescriptorPacket->bRequest = USB_REQUEST_SET_INTERFACE; + m_DescriptorPacket->wValue.W = Urb->UrbSelectInterface.Interface.AlternateSetting; + m_DescriptorPacket->wIndex.W = Urb->UrbSelectInterface.Interface.InterfaceNumber; + m_DescriptorPacket->wLength = 0; + m_DescriptorPacket->bmRequestType.B = 0x01; + break; + + /* SYNC FRAME */ + case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: + UNIMPLEMENTED + break; + default: + UNIMPLEMENTED + break; + } + + return Status; +} + //---------------------------------------------------------------------------------------- VOID CUSBRequest::GetResultStatus(