Author: mjmartin Date: Thu Jan 6 18:29:52 2011 New Revision: 50303
URL: http://svn.reactos.org/svn/reactos?rev=50303&view=rev Log: [usb/usbehci]: - Implement URB_FUNCTION_SELECT_INTERFACE. - Add missing IoMarkIrpPending before calling SubmitControlRequest. - Now use BuildSetupPacketFromURB for creating the CtrlSetup data structure. - When selecting configuration, make the ConfigurationHandle from the related UsbDevice instead of always the RootHub device. - Fix typo that caused all pipes to be marked as interrupt type. - Change CompletePendingURBRequest to only complete one SCE request Irp.
Modified: trunk/reactos/drivers/usb/usbehci/irp.c
Modified: trunk/reactos/drivers/usb/usbehci/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/irp.c?r... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] Thu Jan 6 18:29:52 2011 @@ -139,20 +139,21 @@ } } else - DPRINT("Interrupt Transfer not for hub\n"); + DPRINT1("Interrupt Transfer not for hub\n"); break; } case URB_FUNCTION_GET_STATUS_FROM_DEVICE: { DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n"); - if (Urb->UrbControlGetStatusRequest.Index == 0) + /* If for the hub device */ + if ((Urb->UrbControlGetStatusRequest.Index == 0) && (UsbDevice == PdoDeviceExtension->UsbDevices[0])) { ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); - *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE; + *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT /*| USB_PORT_STATUS_ENABLE*/; } else { - DPRINT1("Uknown identifier\n"); + DPRINT1("UsbDeviceHandle %x, Index %x not implemented yet\n", UsbDevice, Urb->UrbControlGetStatusRequest.Index); Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; Status = STATUS_UNSUCCESSFUL; } @@ -189,15 +190,14 @@
ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL);
- DPRINT("Calling BuildSetUpPacketFromUrb\n"); BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup); - DPRINT("SubmitControlTransfer\n"); + IoMarkIrpPending(Irp); + Status = STATUS_PENDING; SubmitControlTransfer(&FdoDeviceExtension->hcd, &CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength, Irp); - break; } case USB_CONFIGURATION_DESCRIPTOR_TYPE: @@ -267,24 +267,15 @@ if (Urb->UrbControlDescriptorRequest.Index == 0) DPRINT1("Requesting LANGID's\n");
- CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; - CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; - CtrlSetup.bmRequestType._BM.Reserved = 0; - CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; - CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; - CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; - CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; - CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; - CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; + BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup); + IoMarkIrpPending(Irp); + Status = STATUS_PENDING;
SubmitControlTransfer(&FdoDeviceExtension->hcd, &CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength, Irp); - - IoMarkIrpPending(Irp); - Status = STATUS_PENDING; break; } default: @@ -301,11 +292,11 @@
DPRINT1("Selecting Configuration\n"); DPRINT1("ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle); - if (Urb->UrbSelectConfiguration.ConfigurationDescriptor) { - Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&PdoDeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor; - DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle); + Urb->UrbSelectConfiguration.ConfigurationHandle = &UsbDevice->ActiveConfig->ConfigurationDescriptor; + DPRINT1("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle); + ASSERT(FALSE); InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
DPRINT1("Length %x\n", InterfaceInfo->Length); @@ -324,7 +315,7 @@ InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.wMaxPacketSize; InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bEndpointAddress; InterfaceInfo->Pipes[pCount].Interval = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bInterval; - InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt; + InterfaceInfo->Pipes[pCount].PipeType = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bmAttributes; InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor; if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0) InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096; @@ -337,7 +328,37 @@ else { /* FIXME: Set device to unconfigured state */ - } + DPRINT1("Setting device to unconfigured state not implemented!\n"); + } + break; + } + case URB_FUNCTION_SELECT_INTERFACE: + { + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + PUSBD_INTERFACE_INFORMATION InterfaceInfo; + int i; + + DPRINT1("Select Interface!\n"); + DPRINT1("Config Handle %x\n", Urb->UrbSelectInterface.ConfigurationHandle); + + InterfaceInfo = &Urb->UrbSelectInterface.Interface; + DPRINT1("InterfaceNumber %x\n", InterfaceInfo->InterfaceNumber); + DPRINT1("AlternateSetting %x\n", InterfaceInfo->AlternateSetting); + DPRINT1("NumPipes %x\n", InterfaceInfo->NumberOfPipes); + for (i=0;i<InterfaceInfo->NumberOfPipes;i++) + { + InterfaceInfo->Pipes[i].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor; + } + + BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup); + IoMarkIrpPending(Irp); + Status = STATUS_PENDING; + + SubmitControlTransfer(&FdoDeviceExtension->hcd, + &CtrlSetup, + NULL, + 0, + Irp); break; } case URB_FUNCTION_CLASS_DEVICE: @@ -456,7 +477,7 @@ { case USB_REQUEST_GET_STATUS: { - DPRINT1("USB_REQUEST_GET_STATUS Port %d\n", Urb->UrbControlVendorClassRequest.Index); + DPRINT("USB_REQUEST_GET_STATUS Port %d\n", Urb->UrbControlVendorClassRequest.Index);
ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); DPRINT("PortStatus %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus); @@ -467,23 +488,21 @@ } case USB_REQUEST_CLEAR_FEATURE: { - DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index, - Urb->UrbControlVendorClassRequest.Value); switch (Urb->UrbControlVendorClassRequest.Value) { case C_PORT_CONNECTION: - DPRINT1("C_PORT_CONNECTION\n"); + DPRINT("C_PORT_CONNECTION\n"); PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT; break; case C_PORT_RESET: - DPRINT1("C_PORT_RESET\n"); + DPRINT("C_PORT_RESET\n"); PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET; + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE; break; default: - DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); - break; - } - CompletePendingURBRequest(PdoDeviceExtension); + DPRINT("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); + break; + } break; } case USB_REQUEST_SET_FEATURE: @@ -495,18 +514,10 @@ { case PORT_RESET: { - //PWORKITEMDATA WorkItemData; - - PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE; + DPRINT("Port Reset %d\n", Urb->UrbControlVendorClassRequest.Index-1); PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET; - + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus &= ~USB_PORT_STATUS_ENABLE; ResetPort(&FdoDeviceExtension->hcd, Urb->UrbControlVendorClassRequest.Index-1); - //WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEMDATA)); - //WorkItemData->Context = PdoDeviceExtension; - //ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)WorkerThread, (PVOID) WorkItemData) - //ExQueueWorkItem(&WorkItemData->WorkItem, DelayedWorkQueue); - //IoMarkIrpPending(Irp); - //Status = STATUS_PENDING; break; } case PORT_ENABLE: @@ -525,7 +536,10 @@ break; } } - CompletePendingURBRequest(PdoDeviceExtension); + + if (!(PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus & 0x8000)) + CompletePendingURBRequest(PdoDeviceExtension); + break; } case USB_REQUEST_SET_ADDRESS: @@ -577,6 +591,23 @@ } break; } + case URB_FUNCTION_CONTROL_TRANSFER: + { + DPRINT1("URB_FUNCTION_CONTROL_TRANSFER\n"); + DPRINT1("PipeHandle %x\n", Urb->UrbControlTransfer.PipeHandle); + DPRINT1("TransferFlags %x\n", Urb->UrbControlTransfer.TransferFlags); + DPRINT1("TransferLength %x\n", Urb->UrbControlTransfer.TransferBufferLength); + DPRINT1("TransferBuffer %x\n", Urb->UrbControlTransfer.TransferBuffer); + DPRINT1("TransferMDL %x\n", Urb->UrbControlTransfer.TransferBufferMDL); + DPRINT1("SetupPacket %x\n", Urb->UrbControlTransfer.SetupPacket); + ASSERT(FALSE); + break; + } + case URB_FUNCTION_CLASS_INTERFACE: + { + DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n"); + break; + } default: { DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function); @@ -586,14 +617,6 @@
Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Information; - - if (Urb->UrbHeader.Status == USBD_STATUS_SUCCESS) - { - /* Fake a successful Control Transfer */ - Urb->UrbHeader.Function = 0x08; - Urb->UrbHeader.UsbdFlags = 0; - } - return Status; }
@@ -606,23 +629,25 @@
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
- while (!IsListEmpty(&DeviceExtension->IrpQueue)) + if (IsListEmpty(&DeviceExtension->IrpQueue)) { - NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue); - Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry); - - if (!Irp) - { - DPRINT1("No IRP\n"); - break; - } - IoSetCancelRoutine(Irp, NULL); + DPRINT1("There should have been one SCE request pending\n"); KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); - HandleUrbRequest(DeviceExtension, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql); + return; } - + NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue); + Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry); + + if (!Irp) + { + DPRINT1("No Irp\n"); + return; + } + + IoSetCancelRoutine(Irp, NULL); KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); + + HandleUrbRequest(DeviceExtension, Irp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); }