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?…
==============================================================================
--- 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?…
==============================================================================
--- 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?…
==============================================================================
--- 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/usbehc…
==============================================================================
--- 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/usbiff…
==============================================================================
--- 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??? */