[usb/usbehci]
authorMichael Martin <michael.martin@reactos.org>
Sat, 3 Jul 2010 11:40:58 +0000 (11:40 +0000)
committerMichael Martin <michael.martin@reactos.org>
Sat, 3 Jul 2010 11:40:58 +0000 (11:40 +0000)
- Implement FdoDispatchInternalDeviceControl and remove IrpStub as its no longer needed.
- Implement Direct Call RemoveUsbDevice.
- Implement URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE.
- Use the port parameter in ExecuteControlRequest.
- Windows now identifies my thumb drive as a mass storage device.

svn path=/trunk/; revision=47926

reactos/drivers/usb/usbehci/fdo.c
reactos/drivers/usb/usbehci/urbreq.c
reactos/drivers/usb/usbehci/usbehci.c
reactos/drivers/usb/usbehci/usbehci.h
reactos/drivers/usb/usbehci/usbiffn.c

index c42ebfd..881e978 100644 (file)
@@ -4,7 +4,7 @@
  * FILE:        drivers/usb/usbehci/fdo.c
  * PURPOSE:     USB EHCI device driver.
  * PROGRAMMERS:
- *              Michael Martin
+ *              Michael Martin (mjmartin@reactos.org)
  */
 
 /* INCLUDES *******************************************************************/
@@ -831,3 +831,283 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
 
     return STATUS_SUCCESS;
 }
+
+NTSTATUS NTAPI
+FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PIO_STACK_LOCATION Stack = NULL;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    ULONG_PTR Information = 0;
+    PUSB_DEVICE UsbDevice = NULL;
+    URB *Urb;
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+    ASSERT(FdoDeviceExtension->Common.IsFdo == TRUE);
+
+    Stack =  IoGetCurrentIrpStackLocation(Irp);
+
+    ASSERT(Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB);
+
+    Urb = (PURB) Stack->Parameters.Others.Argument1;
+    DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
+    DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
+
+    UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
+
+    switch (Urb->UrbHeader.Function)
+    {
+        case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
+        {
+            DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
+            break;
+        }
+        case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
+        {
+            DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
+            break;
+        }
+        case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+        {
+            switch(Urb->UrbControlDescriptorRequest.DescriptorType)
+            {
+                case USB_DEVICE_DESCRIPTOR_TYPE:
+                {
+                    /* FIXNME: This probably not used for FDO and should be removed? */
+                    DPRINT1("USB DEVICE DESC\n");
+                    break;
+                }
+                case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+                    DPRINT1("USB CONFIG DESC\n");
+                case USB_STRING_DESCRIPTOR_TYPE:
+                    DPRINT1("Usb String Descriptor\n");
+                {
+                    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+                    BOOLEAN ResultOk;
+
+                    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+                    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+                    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;
+                    if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE)
+                        CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+                    else
+                        CtrlSetup.wIndex.W = 0;
+                    CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
+
+                    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port,
+                                Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength);
+
+                    Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
+                    Status = STATUS_SUCCESS;
+
+                    break;
+                }
+                default:
+                {
+                    DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType);
+                }
+            }
+            break;
+        }
+        case URB_FUNCTION_SELECT_CONFIGURATION:
+        {
+            DPRINT1("Selecting Configuration\n");
+            DPRINT1("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+            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:
+                        {
+                            DPRINT1("USB_DEVICE_CLASS_HUB request\n");
+                            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);
+                    break;
+                }
+                default:
+                {
+                    DPRINT1("Unhandled URB request for class device\n");
+                    //Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+                }
+            }
+            break;
+        }
+        case URB_FUNCTION_CLASS_OTHER:
+        {
+            switch (Urb->UrbControlVendorClassRequest.Request)
+            {
+                case USB_REQUEST_GET_STATUS:
+                {
+                    DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
+                    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:
+                            DPRINT1("Clearing Connect\n");
+                            break;
+                        case C_PORT_RESET:
+                            DPRINT1("Clearing Reset\n");
+                            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:
+                        {
+                            DPRINT1("Port reset\n");
+                            break;
+                        }
+                        case PORT_ENABLE:
+                        {
+                            DPRINT1("Unhandled Set Feature\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.Information = Information;
+
+    if (Status != STATUS_PENDING)
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return Status;
+}
index cbd1845..e5af47e 100644 (file)
@@ -4,7 +4,7 @@
  * FILE:        drivers/usb/usbehci/urbreq.c
  * PURPOSE:     URB Related Functions.
  * PROGRAMMERS:
- *              Michael Martin
+ *              Michael Martin (mjmartin@reactos.org)
  */
 
 #include "usbehci.h"
@@ -135,6 +135,9 @@ ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_S
                                          (PVOID)&CtrlData,
                                          BufferLength);
 
+    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;
@@ -144,10 +147,6 @@ ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_S
     CtrlSetup->wIndex.W = SetupPacket->wIndex.W;
     CtrlSetup->wLength = SetupPacket->wLength;
 
-
-    QueueHead->EndPointCapabilities1.DeviceAddress = Address;
-    //QueueHead->EndPointCapabilities2.PortNumber = Port;
-
     tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
     UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
     UsbCmd->Run = FALSE;
index 0f35a31..398f3b4 100644 (file)
@@ -4,33 +4,12 @@
  * FILE:        drivers/usb/usbehci/usbehci.c
  * PURPOSE:     USB EHCI device driver.
  * PROGRAMMERS:
- *              Michael Martin
+ *              Michael Martin (mjmartin@reactos.com)
  */
 
 /* DEFINES *******************************************************************/
 #include "usbehci.h"
 
-static NTSTATUS NTAPI
-IrpStub(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
-    NTSTATUS Status;
-
-    if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
-    {
-        DPRINT1("ehci: FDO stub for major function 0x%lx\n",
-            IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
-        return ForwardIrpAndForget(DeviceObject, Irp);
-    }
-
-    /* We are lower driver, So complete */
-    DPRINT1("ehci: PDO stub for major function 0x%lx\n",
-    IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
-
-    Status = Irp->IoStatus.Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
-}
-
 NTSTATUS NTAPI
 DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
 {
@@ -47,7 +26,9 @@ DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
 {
     DPRINT("DispatchInternalDeviceControl\n");
     if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
-        return IrpStub(DeviceObject, Irp);
+    {
+        return FdoDispatchInternalDeviceControl(DeviceObject, Irp);
+    }
     else
         return PdoDispatchInternalDeviceControl(DeviceObject, Irp);
 }
index 56f03b5..f597741 100644 (file)
@@ -9,7 +9,7 @@
 #include <usbioctl.h>
 #include <usb.h>
 
-#define USB_POOL_TAG (ULONG)'UsbR'
+#define USB_POOL_TAG (ULONG)'ebsu'
 
 #define        DEVICEINTIALIZED                0x01
 #define        DEVICESTARTED                   0x02
@@ -463,6 +463,9 @@ GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject);
 NTSTATUS NTAPI
 PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
+NTSTATUS NTAPI
+FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
 BOOLEAN
 ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength);
 
index 4dd98f4..95cbbaa 100644 (file)
@@ -4,7 +4,7 @@
  * FILE:        drivers/usb/usbehci/usbiffn.c
  * PURPOSE:     Direct Call Interface Functions.
  * PROGRAMMERS:
- *              Michael Martin
+ *              Michael Martin (mjmartin@reactos.org)
  */
 
 #include "usbehci.h"
@@ -98,11 +98,13 @@ CreateUsbDevice(PVOID BusContext,
             PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice;
             PdoDeviceExtension->UsbDevices[i]->Address = i + 1;
             PdoDeviceExtension->UsbDevices[i]->Port = PortNumber;
-            break; 
+            break;
         }
         i++;
     }
 
+    PdoDeviceExtension->Ports[PortNumber - 1].PortStatus = PortStatus;
+
     /* Return it */
     *NewDevice = UsbDevice;
     return STATUS_SUCCESS;
@@ -140,6 +142,7 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
     }
 
     Ptr = Buffer;
+
     /* Set the device address */
     CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
     CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
@@ -149,6 +152,7 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
     CtrlSetup.wIndex.W = 0;
     CtrlSetup.wLength = 0;
 
+    DPRINT1("Setting Address to %x\n", UsbDevice->Address);
     ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, 0, NULL, 0);
 
     /* Get the Device Descriptor */
@@ -161,11 +165,15 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
     CtrlSetup.wIndex.W = 0;
     CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
 
-    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, 
+    DPRINT1("Requesting Descriptor\n");
+    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port,
                                      &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
 
+
     DPRINT1("bLength %x\n", UsbDevice->DeviceDescriptor.bLength);
     DPRINT1("bDescriptorType %x\n", UsbDevice->DeviceDescriptor.bDescriptorType);
+    DPRINT1("idVendor %x\n", UsbDevice->DeviceDescriptor.idVendor);
+    DPRINT1("idProduct %x\n", UsbDevice->DeviceDescriptor.idProduct);
     DPRINT1("bNumDescriptors %x\n", UsbDevice->DeviceDescriptor.bNumConfigurations);
 
     if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0)
@@ -246,10 +254,10 @@ GetUsbDescriptors(PVOID BusContext,
                   PULONG ConfigDescriptorBufferLength)
 {
     PUSB_DEVICE UsbDevice;
-    DPRINT1("GetUsbDescriptor %x, %d, %x, %d\n", DeviceDescriptorBuffer, DeviceDescriptorBufferLength, ConfigDescriptorBuffer, ConfigDescriptorBufferLength);
+    DPRINT1("GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer, *DeviceDescriptorBufferLength, ConfigDescriptorBuffer, *ConfigDescriptorBufferLength);
 
     UsbDevice = (PUSB_DEVICE) DeviceHandle;
-
+    DPRINT1("DeviceHandle %x\n", UsbDevice);
     if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength))
     {
         RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
@@ -268,7 +276,59 @@ NTSTATUS
 USB_BUSIFFN
 RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
 {
-    DPRINT1("RemoveUsbDevice called\n");
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PUSB_DEVICE UsbDevice;
+    LONG i, j, k;
+
+    DPRINT1("RemoveUsbDevice called, DeviceHandle %x, Flags %x\n", DeviceHandle, Flags);
+
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
+
+    /* FIXME: Implement DeviceHandleToUsbDevice to validate handles */
+    //UsbDevice = DeviceHandleToUsbDevice(PdoDeviceExtension, DeviceHandle);
+
+    UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+   if (!UsbDevice)
+        return STATUS_DEVICE_NOT_CONNECTED;
+
+    switch (Flags)
+    {
+       case 0:
+            DPRINT1("Number of Configurations %d\n", UsbDevice->DeviceDescriptor.bNumConfigurations);
+            for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
+            {
+                for (j = 0; j < UsbDevice->Configs[i]->ConfigurationDescriptor.bNumInterfaces; j++)
+                {
+                    for (k = 0; k < UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor.bNumEndpoints; k++)
+                    {
+                        ExFreePool(UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]);
+                    }
+                    ExFreePool(UsbDevice->Configs[i]->Interfaces[j]);
+                }
+                ExFreePool(UsbDevice->Configs[i]);
+            }
+
+            for (i = 0; i < 127; i++)
+            {
+                if (PdoDeviceExtension->UsbDevices[i] == UsbDevice)
+                    PdoDeviceExtension->UsbDevices[i] = NULL;
+            }
+
+            ExFreePool(UsbDevice);
+
+            /* DeConfig Device */
+            break;
+       case USBD_KEEP_DEVICE_DATA:
+            DPRINT("USBD_KEEP_DEVICE_DATA Not implemented!\n");
+            break;
+
+        case USBD_MARK_DEVICE_BUSY:
+            DPRINT("USBD_MARK_DEVICE_BUSY Not implemented!\n");
+            break;
+        default:
+            DPRINT1("Unknown Remove Flags %x\n", Flags);
+    }
     return STATUS_SUCCESS;
 }