Author: mjmartin Date: Tue Sep 14 09:46:28 2010 New Revision: 48770
URL: http://svn.reactos.org/svn/reactos?rev=48770&view=rev Log: [usb/usbehci] - Dont reset the port in the DPC after device is connected, the usbhub driver will do that later. - Implement ResetPort and create a timer to call a DPC to coplete the SCE request. - Dont queue all URBs and have seperate thread complete them as other URBs may still need to be completed. Instead only queue the SCE request and complete it when a usb device is connected or reset. - Implement RemoveURBRequest and fix bugs in URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE. - For IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO dont return the FDO in Argument2 as no upper level driver should be communicating with the FDO of the roothub. - Dont assign the usb device an address when initialized as the hub driver will do it later.
Modified: trunk/reactos/drivers/usb/usbehci/fdo.c trunk/reactos/drivers/usb/usbehci/irp.c trunk/reactos/drivers/usb/usbehci/pdo.c trunk/reactos/drivers/usb/usbehci/urbreq.c trunk/reactos/drivers/usb/usbehci/usbehci.h trunk/reactos/drivers/usb/usbehci/usbiffn.c
Modified: trunk/reactos/drivers/usb/usbehci/fdo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/fdo.c?r... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] Tue Sep 14 09:46:28 2010 @@ -12,11 +12,42 @@ #include <stdio.h>
VOID NTAPI +TimerDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) +{ + PFDO_DEVICE_EXTENSION FdoDeviceExtension; + PPDO_DEVICE_EXTENSION PdoDeviceExtension; + ULONG tmp; + ULONG Base; + LONG i; + + FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext; + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension; + + Base = (ULONG)FdoDeviceExtension->ResourceMemory; + + for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++) + { + tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i))); + + if ((tmp & 0x04) && (!(PdoDeviceExtension->Ports[i].PortChange & USB_PORT_STATUS_RESET))) + { + DPRINT("Port %x is enabled\n", i); + PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_RESET; + CompletePendingURBRequest(PdoDeviceExtension); + } + } + return; +} + +VOID NTAPI EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) { PFDO_DEVICE_EXTENSION FdoDeviceExtension; PPDO_DEVICE_EXTENSION PdoDeviceExtension; ULONG CStatus; + ULONG tmp; + ULONG Base; + LONG i;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
@@ -28,17 +59,13 @@
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
+ Base = (ULONG)FdoDeviceExtension->ResourceMemory; + CStatus = (ULONG) SystemArgument2;
/* Port Change */ if (CStatus & EHCI_STS_PCD) { - LONG i; - ULONG tmp; - ULONG Base; - - Base = (ULONG)FdoDeviceExtension->ResourceMemory; - /* Loop through the ports */ for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++) { @@ -76,13 +103,13 @@ KeStallExecutionProcessor(30);
/* As per USB 2.0 Specs, 9.1.2. Reset the port and clear the status change */ - tmp |= 0x100 | 0x02; + //tmp |= 0x100 | 0x02; /* Sanity, Disable port */ - tmp &= ~0x04; - - WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp); - - KeStallExecutionProcessor(20); + //tmp &= ~0x04; + + //WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp); + + //KeStallExecutionProcessor(20);
tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
@@ -91,8 +118,7 @@ PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_CONNECT; PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_CONNECT;
- PdoDeviceExtension->HaltQueue = FALSE; - KeSetEvent(&PdoDeviceExtension->QueueDrainedEvent, 0, FALSE); + CompletePendingURBRequest(PdoDeviceExtension); } else { @@ -164,10 +190,23 @@ }
BOOLEAN -ResetPort(PDEVICE_OBJECT DeviceObject) +ResetPort(PFDO_DEVICE_EXTENSION FdoDeviceExtension, UCHAR Port) { - /*FIXME: Implement me */ - + ULONG Base; + ULONG tmp; + LARGE_INTEGER DueTime; + + DPRINT("Reset Port %x\n", Port); + + Base = (ULONG)FdoDeviceExtension->ResourceMemory; + + tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * Port))); + tmp |= 0x100; + WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * Port)), tmp); + + DueTime.QuadPart = -100; + + KeSetTimerEx(&FdoDeviceExtension->UpdateTimer, DueTime, 0, &FdoDeviceExtension->TimerDpcObject); return TRUE; }
@@ -179,7 +218,7 @@ ULONG base; LONG tmp;
- DPRINT1("Stopping Ehci controller\n"); + DPRINT("Stopping Ehci controller\n"); FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; base = (ULONG)FdoDeviceExtension->ResourceMemory;
@@ -274,6 +313,11 @@ KeInitializeDpc(&FdoDeviceExtension->DpcObject, EhciDefferedRoutine, FdoDeviceExtension); + + KeInitializeDpc(&FdoDeviceExtension->TimerDpcObject, + TimerDefferedRoutine, + FdoDeviceExtension); +
Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt, InterruptService, @@ -361,7 +405,7 @@ PHCS = (PEHCI_HCS_CONTENT)&DeviceExtension->ECHICaps.HCSParams; if (PHCS->PortRouteRules) { - for (i = 0; i < 8; i++) + for (i = 0; i < PCap->HCSParams.PortCount; i++) { PCap->PortRoute[i] = READ_REGISTER_UCHAR((PUCHAR) (Base + 12 + i)); } @@ -595,6 +639,7 @@
PdoDeviceExtension->ControllerFdo = DeviceObject; PdoDeviceExtension->DeviceObject = Pdo; + PdoDeviceExtension->NumberOfPorts = DeviceExtension->ECHICaps.HCSParams.PortCount;
InitializeListHead(&PdoDeviceExtension->IrpQueue); KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock); @@ -765,6 +810,8 @@ FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension; RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
+ KeInitializeTimerEx(&FdoDeviceExtension->UpdateTimer, SynchronizationTimer); + FdoDeviceExtension->Common.IsFdo = TRUE; FdoDeviceExtension->DeviceObject = Fdo;
@@ -858,6 +905,8 @@ PUSB_DEVICE UsbDevice = NULL; URB *Urb;
+ /*FIXME: This should never be called by a miniport as the miniport should only be dealing with the pdo */ + FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension; PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
@@ -868,8 +917,8 @@ ASSERT(Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB);
Urb = (PURB) Stack->Parameters.Others.Argument1; - DPRINT1("Header Length %d\n", Urb->UrbHeader.Length); - DPRINT1("Header Function %d\n", Urb->UrbHeader.Function); + DPRINT("Header Length %d\n", Urb->UrbHeader.Length); + DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
UsbDevice = DeviceHandleToUsbDevice(PdoDeviceExtension, Urb->UrbHeader.UsbdDeviceHandle);
@@ -897,7 +946,7 @@ { case USB_DEVICE_DESCRIPTOR_TYPE: { - /* FIXNME: This probably not used for FDO and should be removed? */ + /* FIXME: This probably not used for FDO and should be removed? */ DPRINT1("USB DEVICE DESC\n"); break; } @@ -921,17 +970,6 @@
if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE) { - if ((Urb->UrbControlDescriptorRequest.Index != UsbDevice->DeviceDescriptor.iManufacturer) && - (UsbDevice->DeviceDescriptor.iManufacturer) && - (UsbDevice->DeviceDescriptor.iSerialNumber)) - { - DPRINT1("Invalid Index\n"); - Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER; - Status = STATUS_SUCCESS; - Information = 0; - break; - } - CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1); }
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] Tue Sep 14 09:46:28 2010 @@ -10,12 +10,17 @@ #include "usbehci.h"
VOID -RequestURBCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp) +RemoveUrbRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp) { - PPDO_DEVICE_EXTENSION PdoDeviceExtension; - - PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension; - + KIRQL OldIrql; + KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql); + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql); +} + +VOID +RequestURBCancel (PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) +{ KIRQL OldIrql = Irp->CancelIrql; IoReleaseCancelSpinLock(DISPATCH_LEVEL);
@@ -37,7 +42,6 @@
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) { - DPRINT1("Cancelled!!!!???\n"); KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql); Irp->IoStatus.Status = STATUS_CANCELLED; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -49,17 +53,483 @@ } }
+NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) +{ + NTSTATUS Status = STATUS_UNSUCCESSFUL; + ULONG_PTR Information = 0; + PIO_STACK_LOCATION Stack; + PUSB_DEVICE UsbDevice = NULL; + URB *Urb; + PFDO_DEVICE_EXTENSION FdoDeviceExtension; + FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension; + + Stack = IoGetCurrentIrpStackLocation(Irp); + ASSERT(Stack); + + Urb = (PURB) Stack->Parameters.Others.Argument1; + + ASSERT(Urb); + + Information = 0; + Status = STATUS_SUCCESS; + + DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer); + DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); + DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle); + + UsbDevice = Urb->UrbHeader.UsbdDeviceHandle; + + /* UsbdDeviceHandle of 0 is root hub */ + if (UsbDevice == NULL) + UsbDevice = PdoDeviceExtension->UsbDevices[0]; + + /* Assume URB success */ + Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; + /* Set the DeviceHandle to the Internal Device */ + Urb->UrbHeader.UsbdDeviceHandle = UsbDevice; + + switch (Urb->UrbHeader.Function) + { + case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: + { + if (&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor != Urb->UrbBulkOrInterruptTransfer.PipeHandle) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); + RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + + if (UsbDevice == PdoDeviceExtension->UsbDevices[0]) + { + if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK)) + { + LONG i; + for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++) + { + if (PdoDeviceExtension->Ports[i].PortChange) + { + DPRINT1("Inform hub driver that port %d has changed\n", i+1); + ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7); + } + } + } + else + { + Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER; + Status = STATUS_UNSUCCESSFUL; + DPRINT1("Invalid transfer flags for SCE\n"); + } + } + else + DPRINT("Interrupt Transfer not for hub\n"); + break; + } + case URB_FUNCTION_GET_STATUS_FROM_DEVICE: + { + if (Urb->UrbControlGetStatusRequest.Index == 0) + { + ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); + *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE; + } + else + { + DPRINT1("Uknown identifier\n"); + Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; + Status = STATUS_UNSUCCESSFUL; + } + break; + } + case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: + { + switch(Urb->UrbControlDescriptorRequest.DescriptorType) + { + case USB_DEVICE_DESCRIPTOR_TYPE: + { + if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR)) + { + Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); + } + ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL); + RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, + &UsbDevice->DeviceDescriptor, + Urb->UrbControlDescriptorRequest.TransferBufferLength); + break; + } + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + { + PUCHAR BufPtr; + LONG i, j; + + if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength) + { + Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength; + } + else + { + DPRINT1("TransferBufferLenth %x is too small!!!\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); + if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_CONFIGURATION_DESCRIPTOR)) + { + DPRINT("Configuration Descriptor cannot fit into given buffer!\n"); + break; + } + } + + ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); + BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer; + + /* Copy the Configuration Descriptor */ + RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); + + /* If there is no room for all the configs then bail */ + if (!(Urb->UrbControlDescriptorRequest.TransferBufferLength > sizeof(USB_CONFIGURATION_DESCRIPTOR))) + { + DPRINT("All Descriptors cannot fit into given buffer! Only USB_CONFIGURATION_DESCRIPTOR given\n"); + break; + } + + BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR); + for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++) + { + /* Copy the Interface Descriptor */ + RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR)); + BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR); + for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++) + { + /* Copy the EndPoint Descriptor */ + RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); + BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR); + } + } + + break; + } + case USB_STRING_DESCRIPTOR_TYPE: + { + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + PUSB_STRING_DESCRIPTOR StringDesc; + BOOLEAN ResultOk; + + StringDesc = (PUSB_STRING_DESCRIPTOR) Urb->UrbControlDescriptorRequest.TransferBuffer; + + if (Urb->UrbControlDescriptorRequest.Index == 0) + DPRINT("Requesting LANGID's\n"); + + + RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1); + + 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; + + ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, + Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength); + break; + } + default: + { + DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType); + } + } + break; + } + case URB_FUNCTION_SELECT_CONFIGURATION: + { + PUSBD_INTERFACE_INFORMATION InterfaceInfo; + LONG iCount, pCount; + + DPRINT("Selecting Configuration\n"); + DPRINT("Urb->UrbSelectConfiguration.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); + InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; + + for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++) + { + InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor; + InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass; + InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass; + InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol; + InterfaceInfo->Reserved = 0; + + for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++) + { + 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].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor; + if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0) + InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096; + /* InterfaceInfo->Pipes[j].PipeFlags = 0; */ + } + InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length); + } + } + else + { + /* FIXME: Set device to unconfigured state */ + } + break; + } + case URB_FUNCTION_CLASS_DEVICE: + { + switch (Urb->UrbControlVendorClassRequest.Request) + { + case USB_REQUEST_GET_DESCRIPTOR: + { + switch (Urb->UrbControlVendorClassRequest.Value >> 8) + { + case USB_DEVICE_CLASS_AUDIO: + { + DPRINT1("USB_DEVICE_CLASS_AUDIO not implemented\n"); + break; + } + case USB_DEVICE_CLASS_COMMUNICATIONS: + { + DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS not implemented\n"); + break; + } + case USB_DEVICE_CLASS_HUMAN_INTERFACE: + { + DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE not implemented\n"); + break; + } + case USB_DEVICE_CLASS_MONITOR: + { + DPRINT1("USB_DEVICE_CLASS_MONITOR not implemented\n"); + break; + } + case USB_DEVICE_CLASS_PHYSICAL_INTERFACE: + { + DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE not implemented\n"); + break; + } + case USB_DEVICE_CLASS_POWER: + { + DPRINT1("USB_DEVICE_CLASS_POWER not implemented\n"); + break; + } + case USB_DEVICE_CLASS_PRINTER: + { + DPRINT1("USB_DEVICE_CLASS_PRINTER not implemented\n"); + break; + } + case USB_DEVICE_CLASS_STORAGE: + { + DPRINT1("USB_DEVICE_CLASS_STORAGE not implemented\n"); + break; + } + case USB_DEVICE_CLASS_RESERVED: + DPRINT1("Reserved!!!\n"); + case USB_DEVICE_CLASS_HUB: + { + PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer; + + DPRINT1("Length %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength); + ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); + /* FIXME: Handle more than root hub? */ + if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR)) + { + Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR); + } + else + { + /* FIXME: Handle this correctly */ + UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); + UsbHubDescr->bDescriptorType = 0x29; + break; + } + DPRINT1("USB_DEVICE_CLASS_HUB request\n"); + UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); + UsbHubDescr->bDescriptorType = 0x29; + UsbHubDescr->bNumberOfPorts = 0x08; + UsbHubDescr->wHubCharacteristics = 0x0012; + UsbHubDescr->bPowerOnToPowerGood = 0x01; + UsbHubDescr->bHubControlCurrent = 0x00; + UsbHubDescr->bRemoveAndPowerMask[0] = 0x00; + UsbHubDescr->bRemoveAndPowerMask[1] = 0x00; + UsbHubDescr->bRemoveAndPowerMask[2] = 0xff; + break; + } + default: + { + DPRINT1("Unknown UrbControlVendorClassRequest Value\n"); + } + } + break; + } + case USB_REQUEST_GET_STATUS: + { + DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index); + if (Urb->UrbControlVendorClassRequest.Index == 1) + { + ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); + ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0; + } + break; + } + default: + { + DPRINT1("Unhandled URB request for class device\n"); + Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; + } + } + break; + } + case URB_FUNCTION_CLASS_OTHER: + { + DPRINT("URB_FUNCTION_CLASS_OTHER\n"); + /* FIXME: Each one of these needs to make sure that the index value is a valid for the number of ports and return STATUS_UNSUCCESSFUL is not */ + + switch (Urb->UrbControlVendorClassRequest.Request) + { + case USB_REQUEST_GET_STATUS: + { + 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); + DPRINT("PortChange %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange); + ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus; + ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange; + break; + } + case USB_REQUEST_CLEAR_FEATURE: + { + DPRINT("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index, + Urb->UrbControlVendorClassRequest.Value); + switch (Urb->UrbControlVendorClassRequest.Value) + { + case C_PORT_CONNECTION: + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT; + break; + case C_PORT_RESET: + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET; + break; + default: + DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); + break; + } + break; + } + case USB_REQUEST_SET_FEATURE: + { + DPRINT("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index, + Urb->UrbControlVendorClassRequest.Value); + + switch(Urb->UrbControlVendorClassRequest.Value) + { + case PORT_RESET: + { + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE; + ResetPort(FdoDeviceExtension, Urb->UrbControlVendorClassRequest.Index-1); + + break; + } + case PORT_ENABLE: + { + DPRINT1("PORT_ENABLE not implemented\n"); + break; + } + case PORT_POWER: + { + DPRINT1("PORT_POWER not implemented\n"); + break; + } + default: + { + DPRINT1("Unknown Set Feature!\n"); + break; + } + } + break; + } + case USB_REQUEST_SET_ADDRESS: + { + DPRINT1("USB_REQUEST_SET_ADDRESS\n"); + break; + } + case USB_REQUEST_GET_DESCRIPTOR: + { + DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n"); + break; + } + case USB_REQUEST_SET_DESCRIPTOR: + { + DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n"); + break; + } + case USB_REQUEST_GET_CONFIGURATION: + { + DPRINT1("USB_REQUEST_GET_CONFIGURATION\n"); + break; + } + case USB_REQUEST_SET_CONFIGURATION: + { + DPRINT1("USB_REQUEST_SET_CONFIGURATION\n"); + break; + } + case USB_REQUEST_GET_INTERFACE: + { + DPRINT1("USB_REQUEST_GET_INTERFACE\n"); + break; + } + case USB_REQUEST_SET_INTERFACE: + { + DPRINT1("USB_REQUEST_SET_INTERFACE\n"); + break; + } + case USB_REQUEST_SYNC_FRAME: + { + DPRINT1("USB_REQUEST_SYNC_FRAME\n"); + break; + } + default: + { + DPRINT1("Unknown Function Class Unknown request\n"); + break; + } + } + break; + } + default: + { + DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function); + Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; + } + + } + + 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; +} + VOID CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) { PLIST_ENTRY NextIrp = NULL; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - ULONG_PTR Information = 0; - PIO_STACK_LOCATION Stack; - PUSB_DEVICE UsbDevice = NULL; KIRQL oldIrql; PIRP Irp = NULL; - URB *Urb;
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
@@ -70,489 +540,13 @@
if (!Irp) break; - Stack = IoGetCurrentIrpStackLocation(Irp); - ASSERT(Stack); - - Urb = (PURB) Stack->Parameters.Others.Argument1; - - ASSERT(Urb); - - Information = 0; - Status = STATUS_SUCCESS; - - DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer); - DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); - DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle); - - UsbDevice = Urb->UrbHeader.UsbdDeviceHandle; - /* UsbdDeviceHandle of 0 is root hub */ - if (UsbDevice == NULL) - UsbDevice = DeviceExtension->UsbDevices[0]; - - /* Assume URB success */ - Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; - /* Set the DeviceHandle to the Internal Device */ - Urb->UrbHeader.UsbdDeviceHandle = UsbDevice; - - switch (Urb->UrbHeader.Function) - { - case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: - { - DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n"); - DPRINT("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); - DPRINT("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer); - DPRINT("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle); - DPRINT("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor); - DPRINT("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags); - ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); - RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); - - if (UsbDevice == DeviceExtension->UsbDevices[0]) - { - if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK)) - { - LONG i; - for (i = 0; i < 8; i++) - { - if (i == 0){ - DPRINT("PortStatus %x\n", DeviceExtension->Ports[i].PortStatus); - DPRINT("PortChange %x\n", DeviceExtension->Ports[i].PortChange);} - if (DeviceExtension->Ports[i].PortChange) - { - DPRINT1("Inform hub driver that port %d has changed\n", i+1); - ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7); - } - } - } - else - { - Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER; - Status = STATUS_UNSUCCESSFUL; - DPRINT1("Invalid transfer flags for SCE\n"); - } - } - else - DPRINT1("Interrupt Transfer not for hub\n"); - break; - } - case URB_FUNCTION_GET_STATUS_FROM_DEVICE: - { - DPRINT("Get Status from Device\n"); - DPRINT("Index : %d\n", Urb->UrbControlGetStatusRequest.Index); - - if (Urb->UrbControlGetStatusRequest.Index == 0) - { - ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); - *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE; - } - else - { - DPRINT1("Uknown identifier\n"); - Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; - Status = STATUS_UNSUCCESSFUL; - } - break; - } - case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: - { - switch(Urb->UrbControlDescriptorRequest.DescriptorType) - { - case USB_DEVICE_DESCRIPTOR_TYPE: - { - DPRINT1("USB DEVICE DESC\n"); - if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR)) - { - Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); - } - ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL); - RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, - &UsbDevice->DeviceDescriptor, - Urb->UrbControlDescriptorRequest.TransferBufferLength); - break; - } - case USB_CONFIGURATION_DESCRIPTOR_TYPE: - { - PUCHAR BufPtr; - LONG i, j; - - DPRINT1("USB CONFIG DESC\n"); - if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength) - { - Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength; - } - else - { - DPRINT1("TransferBufferLenth %x is too small!!!\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); - if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_CONFIGURATION_DESCRIPTOR)) - { - DPRINT1("Bail!\n"); - break; - } - } - - ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); - BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer; - - /* Copy the Configuration Descriptor */ - RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); - - /* If there is no room for all the configs then bail */ - if (!(Urb->UrbControlDescriptorRequest.TransferBufferLength > sizeof(USB_CONFIGURATION_DESCRIPTOR))) - { - DPRINT1("Bail!\n"); - break; - } - - BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR); - for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++) - { - /* Copy the Interface Descriptor */ - RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR)); - BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR); - for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++) - { - /* Copy the EndPoint Descriptor */ - RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); - BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR); - } - } - - break; - } - case USB_STRING_DESCRIPTOR_TYPE: - { - DPRINT1("Usb String Descriptor not implemented\n"); - break; - } - default: - { - DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType); - } - } - break; - } - case URB_FUNCTION_SELECT_CONFIGURATION: - { - PUSBD_INTERFACE_INFORMATION InterfaceInfo; - LONG iCount, pCount; - - DPRINT("Selecting Configuration\n"); - DPRINT("Length %x\n", Urb->UrbHeader.Length); - DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle); - - if (Urb->UrbSelectConfiguration.ConfigurationDescriptor) - { - DPRINT("ConfigurationDescriptor = %p\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor); - DPRINT(" bLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength); - DPRINT(" bDescriptorType = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType); - DPRINT(" wTotalLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength); - DPRINT(" bNumInterfaces = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces); - DPRINT(" bConfigurationValue = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue); - DPRINT(" iConfiguration = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration); - DPRINT(" bmAttributes = %04x\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes); - DPRINT(" MaxPower = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower); - - - Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor; - DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle); - InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; - - for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++) - { - DPRINT("InterfaceInformation[%d]\n", iCount); - DPRINT(" Length = %d\n", InterfaceInfo->Length); - DPRINT(" InterfaceNumber = %d\n", InterfaceInfo->InterfaceNumber); - DPRINT(" AlternateSetting = %d\n", InterfaceInfo->AlternateSetting); - DPRINT(" Class = %02x\n", (ULONG)InterfaceInfo->Class); - DPRINT(" SubClass = %02x\n", (ULONG)InterfaceInfo->SubClass); - DPRINT(" Protocol = %02x\n", (ULONG)InterfaceInfo->Protocol); - DPRINT(" Reserved = %02x\n", (ULONG)InterfaceInfo->Reserved); - DPRINT(" InterfaceHandle = %p\n", InterfaceInfo->InterfaceHandle); - DPRINT(" NumberOfPipes = %d\n", InterfaceInfo->NumberOfPipes); - InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor; - InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass; - InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass; - InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol; - InterfaceInfo->Reserved = 0; - - for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++) - { - DPRINT("Pipe[%d]\n", pCount); - DPRINT(" MaximumPacketSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumPacketSize); - DPRINT(" EndpointAddress = %d\n", InterfaceInfo->Pipes[pCount].EndpointAddress); - DPRINT(" Interval = %d\n", InterfaceInfo->Pipes[pCount].Interval); - DPRINT(" PipeType = %d\n", InterfaceInfo->Pipes[pCount].PipeType); - DPRINT(" PipeHandle = %x\n", InterfaceInfo->Pipes[pCount].PipeHandle); - DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumTransferSize); - DPRINT(" PipeFlags = %08x\n", InterfaceInfo->Pipes[pCount].PipeFlags); - 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].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor; - if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0) - InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096; - /* InterfaceInfo->Pipes[j].PipeFlags = 0; */ - } - InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length); - } - } - else - { - /* FIXME: Set device to unconfigured state */ - } - break; - } - case URB_FUNCTION_CLASS_DEVICE: - { - switch (Urb->UrbControlVendorClassRequest.Request) - { - case USB_REQUEST_GET_DESCRIPTOR: - { - DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags); - DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb->UrbControlVendorClassRequest.Value); - - switch (Urb->UrbControlVendorClassRequest.Value >> 8) - { - case USB_DEVICE_CLASS_AUDIO: - { - DPRINT1("USB_DEVICE_CLASS_AUDIO\n"); - break; - } - case USB_DEVICE_CLASS_COMMUNICATIONS: - { - DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n"); - break; - } - case USB_DEVICE_CLASS_HUMAN_INTERFACE: - { - DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n"); - break; - } - case USB_DEVICE_CLASS_MONITOR: - { - DPRINT1("USB_DEVICE_CLASS_MONITOR\n"); - break; - } - case USB_DEVICE_CLASS_PHYSICAL_INTERFACE: - { - DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n"); - break; - } - case USB_DEVICE_CLASS_POWER: - { - DPRINT1("USB_DEVICE_CLASS_POWER\n"); - break; - } - case USB_DEVICE_CLASS_PRINTER: - { - DPRINT1("USB_DEVICE_CLASS_PRINTER\n"); - break; - } - case USB_DEVICE_CLASS_STORAGE: - { - DPRINT1("USB_DEVICE_CLASS_STORAGE\n"); - break; - } - case USB_DEVICE_CLASS_RESERVED: - DPRINT1("Reserved!!!\n"); - case USB_DEVICE_CLASS_HUB: - { - - PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer; - - DPRINT1("Length %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength); - ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); - /* FIXME: Handle more than root hub? */ - if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR)) - { - Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR); - } - else - { - /* FIXME: Handle this correctly */ - UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); - UsbHubDescr->bDescriptorType = 0x29; - break; - } - DPRINT1("USB_DEVICE_CLASS_HUB request\n"); - UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); - UsbHubDescr->bDescriptorType = 0x29; - UsbHubDescr->bNumberOfPorts = 0x08; - UsbHubDescr->wHubCharacteristics = 0x0012; - UsbHubDescr->bPowerOnToPowerGood = 0x01; - UsbHubDescr->bHubControlCurrent = 0x00; - UsbHubDescr->bRemoveAndPowerMask[0] = 0x00; - UsbHubDescr->bRemoveAndPowerMask[1] = 0x00; - UsbHubDescr->bRemoveAndPowerMask[2] = 0xff; - break; - } - default: - { - DPRINT1("Unknown UrbControlVendorClassRequest Value\n"); - } - } - break; - } - case USB_REQUEST_GET_STATUS: - { - DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index); - if (Urb->UrbControlVendorClassRequest.Index == 1) - { - ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); - ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0; - } - break; - } - default: - { - DPRINT1("Unhandled URB request for class device\n"); - Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; - } - } - break; - } - case URB_FUNCTION_CLASS_OTHER: - { - - /* FIXME: Each one of these needs to make sure that the index value is a valid for a port (1-8) and return STATUS_UNSUCCESSFUL is not */ - - switch (Urb->UrbControlVendorClassRequest.Request) - { - case USB_REQUEST_GET_STATUS: - { - DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index); - ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); - DPRINT1("PortStatus %x\n", DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus); - DPRINT1("PortChange %x\n", DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange); - ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus; - ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange; - break; - } - 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: - DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT; - break; - case C_PORT_RESET: - DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET; - break; - default: - DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); - break; - } - break; - } - case USB_REQUEST_SET_FEATURE: - { - DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index, - Urb->UrbControlVendorClassRequest.Value); - - switch(Urb->UrbControlVendorClassRequest.Value) - { - case PORT_RESET: - { - DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET; - break; - } - case PORT_ENABLE: - { - DPRINT1("PORT_ENABLE not implemented\n"); - break; - } - case PORT_POWER: - { - DPRINT1("PORT_POWER not implemented\n"); - break; - } - default: - { - DPRINT1("Unknown Set Feature!\n"); - break; - } - } - break; - } - case USB_REQUEST_SET_ADDRESS: - { - DPRINT1("USB_REQUEST_SET_ADDRESS\n"); - break; - } - case USB_REQUEST_GET_DESCRIPTOR: - { - DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n"); - break; - } - case USB_REQUEST_SET_DESCRIPTOR: - { - DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n"); - break; - } - case USB_REQUEST_GET_CONFIGURATION: - { - DPRINT1("USB_REQUEST_GET_CONFIGURATION\n"); - break; - } - case USB_REQUEST_SET_CONFIGURATION: - { - DPRINT1("USB_REQUEST_SET_CONFIGURATION\n"); - break; - } - case USB_REQUEST_GET_INTERFACE: - { - DPRINT1("USB_REQUEST_GET_INTERFACE\n"); - break; - } - case USB_REQUEST_SET_INTERFACE: - { - DPRINT1("USB_REQUEST_SET_INTERFACE\n"); - break; - } - case USB_REQUEST_SYNC_FRAME: - { - DPRINT1("USB_REQUEST_SYNC_FRAME\n"); - break; - } - default: - { - DPRINT1("Unknown Function Class Unknown request\n"); - break; - } - } - break; - } - default: - { - DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function); - Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; - } - - } - - 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; - }
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); + HandleUrbRequest(DeviceExtension, Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql); - - if (DeviceExtension->HaltQueue) - break; }
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); - if (!DeviceExtension->HaltQueue) - KeSetEvent(&DeviceExtension->QueueDrainedEvent, 0, FALSE); }
Modified: trunk/reactos/drivers/usb/usbehci/pdo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/pdo.c?r... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] Tue Sep 14 09:46:28 2010 @@ -125,20 +125,56 @@ { case IOCTL_INTERNAL_USB_SUBMIT_URB: { + PUSB_DEVICE UsbDevice = NULL; URB *Urb; + ULONG i;
Urb = (PURB) Stack->Parameters.Others.Argument1;
+ UsbDevice = Urb->UrbHeader.UsbdDeviceHandle; + + if (UsbDevice == NULL) + UsbDevice = PdoDeviceExtension->UsbDevices[0]; + if ((Urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) && - (Urb->UrbHeader.UsbdDeviceHandle == PdoDeviceExtension->UsbDevices[0])) - { - PdoDeviceExtension->HaltQueue = TRUE; - } - /* Queue all request for now, kernel thread will complete them */ - QueueURBRequest(PdoDeviceExtension, Irp); - Information = 0; - IoMarkIrpPending(Irp); - Status = STATUS_PENDING; + (UsbDevice == PdoDeviceExtension->UsbDevices[0])) + { + if (Urb->UrbBulkOrInterruptTransfer.PipeHandle == &UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor) + { + DPRINT1("PipeHandle doesnt match SCE PipeHandle\n"); + } + + /* Queue the Irp first */ + QueueURBRequest(PdoDeviceExtension, Irp); + + /* Check if there is any connected devices */ + for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++) + { + if (PdoDeviceExtension->Ports[i].PortChange == 0x01) + { + DPRINT1("Inform hub driver that port %d has changed\n", i+1); + ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7); + Information = 0; + Status = STATUS_SUCCESS; + /* Assume URB success */ + Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; + /* Set the DeviceHandle to the Internal Device */ + Urb->UrbHeader.UsbdDeviceHandle = UsbDevice; + + /* Request handled, Remove it from the queue */ + RemoveUrbRequest(PdoDeviceExtension, Irp); + break; + } + } + if (Status == STATUS_SUCCESS) break; + DPRINT1("Queueing IRP\n"); + IoMarkIrpPending(Irp); + Status = STATUS_PENDING; + break; + } + + Status = HandleUrbRequest(PdoDeviceExtension, Irp); + break; } case IOCTL_INTERNAL_USB_CYCLE_PORT: @@ -222,8 +258,11 @@ DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO Arg1 %x, Arg2 %x\n", Stack->Parameters.Others.Argument1, Stack->Parameters.Others.Argument2); if (Stack->Parameters.Others.Argument1) *(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo; + + /* Windows usbehci driver gives the Pdo in both Arguments. */ if (Stack->Parameters.Others.Argument2) - *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject); + //*(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject); + *(PVOID *)Stack->Parameters.Others.Argument2 = FdoDeviceExtension->Pdo;
Information = 0; Status = STATUS_SUCCESS; @@ -378,7 +417,7 @@ /* Create the root hub */ RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
- for (i = 0; i < 8; i++) + for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++) { PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_HIGH_SPEED | 0x8000; PdoDeviceExtension->Ports[i].PortChange = 0; @@ -432,7 +471,7 @@ PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
/* Create a thread to handle the URB's */ - +/* Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle, THREAD_ALL_ACCESS, NULL, @@ -443,7 +482,7 @@
if (!NT_SUCCESS(Status)) DPRINT1("Failed Thread Creation with Status: %x\n", Status); - +*/ Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName); if (!NT_SUCCESS(Status)) {
Modified: trunk/reactos/drivers/usb/usbehci/urbreq.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/urbreq.... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/urbreq.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbehci/urbreq.c [iso-8859-1] Tue Sep 14 09:46:28 2010 @@ -144,7 +144,6 @@ QueueHead->EndPointCapabilities2.PortNumber = Port; QueueHead->EndPointCapabilities1.DeviceAddress = Address;
- CtrlSetup->bmRequestType._BM.Recipient = SetupPacket->bmRequestType._BM.Recipient; CtrlSetup->bmRequestType._BM.Type = SetupPacket->bmRequestType._BM.Type; CtrlSetup->bmRequestType._BM.Dir = SetupPacket->bmRequestType._BM.Dir; @@ -201,7 +200,7 @@ UsbCmd->Run = FALSE; WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
- if (CtrlSetup->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST) + if (SetupPacket->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST) { if ((Buffer) && (BufferLength)) { @@ -211,7 +210,6 @@ DPRINT1("Unable to copy data to buffer\n"); }
- ExReleaseFastMutex(&DeviceExtension->AsyncListMutex);
return TRUE;
Modified: trunk/reactos/drivers/usb/usbehci/usbehci.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehci... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] Tue Sep 14 09:46:28 2010 @@ -361,10 +361,13 @@ ULONG Vector; KIRQL Irql;
+ KTIMER UpdateTimer; KINTERRUPT_MODE Mode; BOOLEAN IrqShared; PKINTERRUPT EhciInterrupt; KDPC DpcObject; + KDPC TimerDpcObject; + KAFFINITY Affinity;
ULONG MapRegisters; @@ -465,13 +468,22 @@ ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength);
VOID +RequestURBCancel (PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp); + +VOID +RemoveUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp); + +VOID QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
VOID CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension);
-VOID -URBRequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS +HandleUrbRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
PUSB_DEVICE DeviceHandleToUsbDevice(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PUSB_DEVICE_HANDLE DeviceHandle); + +BOOLEAN +ResetPort(PFDO_DEVICE_EXTENSION FdoDeviceExtension, UCHAR Port);
Modified: trunk/reactos/drivers/usb/usbehci/usbiffn.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbiffn... ============================================================================== --- trunk/reactos/drivers/usb/usbehci/usbiffn.c [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbehci/usbiffn.c [iso-8859-1] Tue Sep 14 09:46:28 2010 @@ -30,7 +30,7 @@ DPRINT1("This is the root hub\n"); }
- UsbDevicePointer->Address = DeviceNumber; + UsbDevicePointer->Address = 0;// DeviceNumber; UsbDevicePointer->Port = Port; UsbDevicePointer->ParentDevice = Parent;
@@ -85,8 +85,6 @@ if (PdoDeviceExtension->UsbDevices[i] == NULL) { PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice; - PdoDeviceExtension->UsbDevices[i]->Address = i + 1; - PdoDeviceExtension->UsbDevices[i]->Port = PortNumber; break; } i++; @@ -140,6 +138,7 @@ Ptr = Buffer;
/* Set the device address */ +/* CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; CtrlSetup.bmRequestType._BM.Reserved = 0; @@ -151,6 +150,8 @@
DPRINT1("Setting Address to %x\n", UsbDevice->Address); ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, UsbDevice->Port, NULL, 0); + +*/
/* Get the Device Descriptor */ CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; @@ -536,7 +537,6 @@ Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount) { DPRINT1("Ehci: Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle); - /* FIXME: */ /* Create the Irp Queue for SCE */ /* Should queue be created for each device or each enpoint??? */