[CMAKE]
[reactos.git] / drivers / usb / usbehci / usbiffn.c
index 4dd98f4..5b4c5b4 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"
@@ -38,27 +38,6 @@ PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent
     return UsbDevicePointer;
 }
 
-BOOLEAN
-IsHandleValid(PVOID BusContext,
-              PUSB_DEVICE_HANDLE DeviceHandle)
-{
-    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
-    LONG i;
-
-    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) BusContext;
-
-    if (!DeviceHandle)
-        return FALSE;
-
-    for (i = 0; i < 128; i++)
-    {
-        if (PdoDeviceExtension->UsbDevices[i] == DeviceHandle)
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
 VOID
 USB_BUSIFFN
 InterfaceReference(PVOID BusContext)
@@ -86,10 +65,19 @@ CreateUsbDevice(PVOID BusContext,
     PUSB_DEVICE UsbDevice;
     LONG i = 0;
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
-    DPRINT1("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
+    DPRINT("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
+
+    if (PdoDeviceExtension->UsbDevices[0] != HubDeviceHandle)
+    {
+        DPRINT1("Not a valid HubDeviceHandle\n");
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
 
     UsbDevice = InternalCreateUsbDevice(PdoDeviceExtension->ChildDeviceCount, PortNumber, HubDeviceHandle, FALSE);
 
+    if (!UsbDevice)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
     /* Add it to the list */
     while (TRUE)
     {
@@ -98,11 +86,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;
@@ -129,7 +119,14 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
     DPRINT1("InitializeUsbDevice called, device %x\n", DeviceHandle);
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
     FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
-    UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+    UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
+
+    if (!UsbDevice)
+    {
+        DPRINT1("Invalid DeviceHandle or device not connected\n");
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
 
     Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG);
 
@@ -140,6 +137,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,7 +147,8 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
     CtrlSetup.wIndex.W = 0;
     CtrlSetup.wLength = 0;
 
-    ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, 0, NULL, 0);
+    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;
@@ -161,15 +160,22 @@ 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)
+    {
+        DPRINT1("No Configurations. That cant be good!\n");
         return STATUS_DEVICE_DATA_ERROR;
+    }
 
     UsbDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
                                                sizeof(PVOID) * UsbDevice->DeviceDescriptor.bNumConfigurations,
@@ -246,9 +252,15 @@ 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;
+    UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
+
+    if (!UsbDevice)
+    {
+        DPRINT1("Invalid DeviceHandle or device not connected\n");
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
 
     if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength))
     {
@@ -268,7 +280,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;
+
+    UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
+
+    if (!UsbDevice)
+    {
+        DPRINT1("Invalid DeviceHandle or device not connected\n");
+        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:
+            DPRINT1("USBD_KEEP_DEVICE_DATA Not implemented!\n");
+            break;
+
+        case USBD_MARK_DEVICE_BUSY:
+            DPRINT1("USBD_MARK_DEVICE_BUSY Not implemented!\n");
+            break;
+        default:
+            DPRINT1("Unknown Remove Flags %x\n", Flags);
+    }
     return STATUS_SUCCESS;
 }
 
@@ -297,17 +361,18 @@ QueryDeviceInformation(PVOID BusContext,
                        PULONG LengthReturned)
 {
     PUSB_DEVICE_INFORMATION_0 DeviceInfo = DeviceInformationBuffer;
-    PUSB_DEVICE UsbDevice = (PUSB_DEVICE) DeviceHandle;
+    PUSB_DEVICE UsbDevice;
     ULONG SizeNeeded;
     LONG i;
 
     DPRINT1("QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, DeviceInformationBufferLength, LengthReturned);
 
-    /* Search for a valid usb device in this BusContext */
-    if (!IsHandleValid(BusContext, DeviceHandle))
+    UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
+
+    if (!UsbDevice)
     {
-        DPRINT1("Not a valid DeviceHandle\n");
-        return STATUS_INVALID_PARAMETER;
+        DPRINT1("Invalid DeviceHandle or device not connected\n");
+        return STATUS_DEVICE_NOT_CONNECTED;
     }
 
     SizeNeeded = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints]);
@@ -445,7 +510,17 @@ PVOID
 USB_BUSIFFN
 GetDeviceBusContext(PVOID HubBusContext, PVOID DeviceHandle)
 {
+    PUSB_DEVICE UsbDevice;
+
     DPRINT1("GetDeviceBusContext called\n");
+    UsbDevice = DeviceHandleToUsbDevice(HubBusContext, DeviceHandle);
+
+    if (!UsbDevice)
+    {
+        DPRINT1("Invalid DeviceHandle or device not connected\n");
+        return NULL;
+    }
+
     return NULL;
 }
 
@@ -489,6 +564,14 @@ VOID
 USB_BUSIFFN
 FlushTransfers(PVOID BusContext, PVOID DeviceHandle)
 {
+    PUSB_DEVICE UsbDevice;
+    UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
+
+    if (!UsbDevice)
+    {
+        DPRINT1("Invalid DeviceHandle or device not connected\n");
+    }
+
     DPRINT1("FlushTransfers\n");
 }
 
@@ -551,5 +634,5 @@ USB_BUSIFFN
 EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2)
 {
     DPRINT1("EnumLogEntry called\n");
-    return STATUS_NOT_SUPPORTED;
+    return STATUS_SUCCESS;
 }