[LIBUSB]
authorThomas Faber <thomas.faber@reactos.org>
Sat, 26 May 2012 17:19:41 +0000 (17:19 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sat, 26 May 2012 17:19:41 +0000 (17:19 +0000)
- Implement URB_FUNCTION_VENDOR_DEVICE
- Sensibly handle unknown requests in HandleClassDevice
- DPRINT fixes

svn path=/trunk/; revision=56660

reactos/drivers/usb/usbhub/pdo.c
reactos/lib/drivers/libusb/hub_controller.cpp
reactos/lib/drivers/libusb/usb_device.cpp

index 21bea27..939a9f3 100644 (file)
@@ -27,7 +27,7 @@ UrbCompletion(
     // Get the original Irp
     //
     OriginalIrp = (PIRP)Context;
-    
+
     //
     // Update it to match what was returned for the IRP that was passed to RootHub
     //
@@ -224,7 +224,7 @@ USBHUB_PdoHandleInternalDeviceControl(
             //
             Urb = (PURB)Stack->Parameters.Others.Argument1;
             ASSERT(Urb);
-            
+
             //
             // Set the real device handle
             //
@@ -274,11 +274,14 @@ USBHUB_PdoHandleInternalDeviceControl(
                     }
                 */
                     break;
-                            
+
                 }
                 case URB_FUNCTION_CLASS_INTERFACE:
                     DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
                     break;
+                case URB_FUNCTION_VENDOR_DEVICE:
+                    DPRINT1("URB_FUNCTION_VENDOR_DEVICE\n");
+                    break;
                 default:
                     DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
                     break;
@@ -323,11 +326,11 @@ USBHUB_PdoHandleInternalDeviceControl(
                         *PortStatusBits +=
                             (((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2)) +
                             (((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
-                        
+
                     }
                 }
             }
-            
+
             DPRINT1("Arg1 %x\n", *PortStatusBits);
             Status = STATUS_SUCCESS;
             break;
@@ -609,7 +612,7 @@ USBHUB_PdoHandlePnp(
         case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
         {
             DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
-            
+
             Information = Irp->IoStatus.Information;
             Status = Irp->IoStatus.Status;
             break;
index 6441b0d..6a96048 100644 (file)
@@ -69,6 +69,7 @@ public:
     NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleVendorDevice(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClearStall(IN OUT PIRP Irp, PURB Urb);
@@ -94,7 +95,7 @@ protected:
     PDEVICE_OBJECT m_HubControllerDeviceObject;
     PDRIVER_OBJECT m_DriverObject;
 
-    PVOID m_HubCallbackContext; 
+    PVOID m_HubCallbackContext;
     PRH_INIT_CALLBACK m_HubCallbackRoutine;
 
     USB_DEVICE_DESCRIPTOR m_DeviceDescriptor;
@@ -433,7 +434,7 @@ CHubController::HandlePnp(
         {
             DPRINT("[USBLIB] HandlePnp IRP_MN_START_DEVICE\n");
             //
-            // register device interface 
+            // register device interface
             //
             Status = SetDeviceInterface(TRUE);
             break;
@@ -776,7 +777,7 @@ CHubController::HandlePower(
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleIsochronousTransfer(
-    IN OUT PIRP Irp, 
+    IN OUT PIRP Irp,
     PURB Urb)
 {
     PUSBDEVICE UsbDevice;
@@ -825,7 +826,7 @@ CHubController::HandleIsochronousTransfer(
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleBulkOrInterruptTransfer(
-    IN OUT PIRP Irp, 
+    IN OUT PIRP Irp,
     PURB Urb)
 {
     PUSBDEVICE UsbDevice;
@@ -889,7 +890,7 @@ CHubController::HandleBulkOrInterruptTransfer(
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleClassOther(
-    IN OUT PIRP Irp, 
+    IN OUT PIRP Irp,
     PURB Urb)
 {
     NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
@@ -1032,7 +1033,7 @@ CHubController::HandleClassOther(
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleSelectConfiguration(
-    IN OUT PIRP Irp, 
+    IN OUT PIRP Irp,
     PURB Urb)
 {
     PUSBDEVICE UsbDevice;
@@ -1110,7 +1111,7 @@ CHubController::HandleSelectConfiguration(
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleSelectInterface(
-    IN OUT PIRP Irp, 
+    IN OUT PIRP Irp,
     PURB Urb)
 {
     PUSBDEVICE UsbDevice;
@@ -1160,7 +1161,7 @@ CHubController::HandleSelectInterface(
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleGetStatusFromDevice(
-    IN OUT PIRP Irp, 
+    IN OUT PIRP Irp,
     PURB Urb)
 {
     PUSHORT DeviceStatus;
@@ -1381,7 +1382,52 @@ CHubController::HandleClassDevice(
             break;
         }
         default:
-            DPRINT1("[USBLIB] HandleClassDevice Type %x not implemented\n", Urb->UrbControlVendorClassRequest.Request);
+        {
+            //
+            // check if this is a valid usb device handle
+            //
+            if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+            {
+                DPRINT1("HandleClassDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                //
+                // invalid device handle
+                //
+                return STATUS_DEVICE_NOT_CONNECTED;
+            }
+
+            //
+            // get device
+            //
+            UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+            //
+            // generate setup packet
+            //
+            CtrlSetup.bmRequestType.B = 0;
+            CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+            CtrlSetup.bmRequestType._BM.Type = BMREQUEST_CLASS;
+            CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
+            CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+            CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+            CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
+
+            if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+            {
+                //
+                // data direction is device to host
+                //
+                CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+            }
+
+            //
+            // submit setup packet
+            //
+            Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+            ASSERT(Status == STATUS_SUCCESS);
+
+            break;
+        }
     }
 
     return Status;
@@ -1740,6 +1786,70 @@ CHubController::HandleClassEndpoint(
     return Status;
 }
 
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleVendorDevice(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+    PUSBDEVICE UsbDevice;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+
+    DPRINT("CHubController::HandleVendorDevice Request %x\n", Urb->UrbControlVendorClassRequest.Request);
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("[USBLIB] HandleVendorDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+    //
+    // initialize setup packet
+    //
+    CtrlSetup.bmRequestType.B = 0;
+    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_VENDOR;
+    CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
+    CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+    CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+    CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
+
+    if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+    {
+        //
+        // data direction is device to host
+        //
+        CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+    }
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
+    PC_ASSERT(NT_SUCCESS(Status));
+
+    return Status;
+}
+
+//-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleSyncResetAndClearStall(
     IN OUT PIRP Irp,
@@ -1780,7 +1890,7 @@ CHubController::HandleSyncResetAndClearStall(
         //
         DPRINT1("[USBLIB] failed to reset pipe %x\n", Status);
     }
+
 
     //
     // get endpoint descriptor
@@ -1812,6 +1922,7 @@ CHubController::HandleSyncResetAndClearStall(
     return Status;
 }
 
+//-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleAbortPipe(
     IN OUT PIRP Irp,
@@ -2098,6 +2209,9 @@ CHubController::HandleDeviceControl(
                 case URB_FUNCTION_CLASS_ENDPOINT:
                     Status = HandleClassEndpoint(Irp, Urb);
                     break;
+                case URB_FUNCTION_VENDOR_DEVICE:
+                    Status = HandleVendorDevice(Irp, Urb);
+                    break;
                 default:
                     DPRINT1("[USBLIB] IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
                     break;
@@ -2167,7 +2281,7 @@ CHubController::HandleDeviceControl(
 
             //
             // after IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO is delivered, the usbhub driver
-            // requests this ioctl to deliver the number of presents. 
+            // requests this ioctl to deliver the number of presents.
 
             if (IoStack->Parameters.Others.Argument1)
             {
@@ -3097,7 +3211,7 @@ USBHI_GetExtendedHubInformation(
 
     //
     // sanity checks
-    // 
+    //
     PC_ASSERT(HubInformationBuffer);
     PC_ASSERT(HubInformationBufferLength == sizeof(USB_EXTHUB_INFORMATION_0));
     PC_ASSERT(LengthReturned);
@@ -3427,8 +3541,8 @@ USBDI_IsDeviceHighSpeed(
 NTSTATUS
 USB_BUSIFFN
 USBDI_EnumLogEntry(
-    PVOID BusContext, 
-    ULONG DriverTag, 
+    PVOID BusContext,
+    ULONG DriverTag,
     ULONG EnumTag,
     ULONG P1,
     ULONG P2)
index de0abab..2dc0fa6 100644 (file)
@@ -76,7 +76,7 @@ protected:
     LONG m_Ref;
     PHUBCONTROLLER m_HubController;
     PUSBHARDWAREDEVICE m_Device;
-    PVOID m_Parent; 
+    PVOID m_Parent;
     ULONG m_Port;
     UCHAR m_DeviceAddress;
     PVOID m_Data;
@@ -103,9 +103,9 @@ CUSBDevice::QueryInterface(
 //----------------------------------------------------------------------------------------
 NTSTATUS
 CUSBDevice::Initialize(
-    IN PHUBCONTROLLER HubController, 
-    IN PUSBHARDWAREDEVICE Device, 
-    IN PVOID Parent, 
+    IN PHUBCONTROLLER HubController,
+    IN PUSBHARDWAREDEVICE Device,
+    IN PVOID Parent,
     IN ULONG Port,
     IN ULONG PortStatus)
 {
@@ -309,7 +309,7 @@ CUSBDevice::SetDeviceAddress(
     UCHAR OldAddress;
     UCHAR Index;
 
-    DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress);
+    DPRINT1("CUSBDevice::SetDeviceAddress> Address %x\n", DeviceAddress);
 
     CtrlSetup = (PUSB_DEFAULT_PIPE_SETUP_PACKET)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET), TAG_USBLIB);
     if (!CtrlSetup)
@@ -332,7 +332,7 @@ CUSBDevice::SetDeviceAddress(
     if (!NT_SUCCESS(Status))
     {
         // failed to set device address
-        DPRINT1("CUSBDevice::SetDeviceAddress> failed to set device address with %x Address %x\n", Status, DeviceAddress);
+        DPRINT1("CUSBDevice::SetDeviceAddress> failed to set device address with %lx Address %x\n", Status, DeviceAddress);
         return Status;
     }
 
@@ -349,7 +349,7 @@ CUSBDevice::SetDeviceAddress(
     Status = CreateDeviceDescriptor();
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("CUSBbDevice::SetDeviceAddress> failed to retrieve device descriptor with device address set Error %x\n", Status);
+        DPRINT1("CUSBDevice::SetDeviceAddress> failed to retrieve device descriptor with device address set Error %lx\n", Status);
         // return error status
         return Status;
     }
@@ -360,7 +360,7 @@ CUSBDevice::SetDeviceAddress(
         m_DeviceDescriptor.bNumConfigurations == 0)
     {
         // failed to retrieve device descriptor
-        DPRINT1("CUSBbDevice::SetDeviceAddress> device returned bogus device descriptor\n");
+        DPRINT1("CUSBDevice::SetDeviceAddress> device returned bogus device descriptor\n");
         DumpDeviceDescriptor(&m_DeviceDescriptor);
 
         // return error status
@@ -430,7 +430,7 @@ CUSBDevice::CommitIrp(
         //
         // no queue, wtf?
         //
-        DPRINT1("CUSBDevice::CommitUrb> no queue / dma !!!\n");
+        DPRINT1("CUSBDevice::CommitIrp> no queue / dma !!!\n");
         return STATUS_UNSUCCESSFUL;
     }
 
@@ -443,7 +443,7 @@ CUSBDevice::CommitIrp(
         //
         // failed to build request
         //
-        DPRINT1("CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with %x\n", Status);
+        DPRINT1("CUSBDevice::CommitIrp> CreateUSBRequest failed with %lx\n", Status);
         return Status;
     }
 
@@ -466,7 +466,7 @@ CUSBDevice::CommitIrp(
         //
         // failed to add request
         //
-        DPRINT1("CUSBDevice::CommitSetupPacket> failed add request to queue with %x\n", Status);
+        DPRINT1("CUSBDevice::CommitIrp> failed add request to queue with %lx\n", Status);
         Request->Release();
         return Status;
     }
@@ -502,12 +502,13 @@ CUSBDevice::SubmitIrp(
 
     return Status;
 }
+
 //----------------------------------------------------------------------------------------
 NTSTATUS
 CUSBDevice::CommitSetupPacket(
     IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet,
     IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor,
-    IN ULONG BufferLength, 
+    IN ULONG BufferLength,
     IN OUT PMDL Mdl)
 {
     NTSTATUS Status;
@@ -669,7 +670,7 @@ CUSBDevice::CreateDeviceDescriptor()
 //----------------------------------------------------------------------------------------
 NTSTATUS
 CUSBDevice::GetConfigurationDescriptor(
-    IN UCHAR ConfigurationIndex, 
+    IN UCHAR ConfigurationIndex,
     IN USHORT BufferSize,
     IN PVOID Buffer)
 {
@@ -873,8 +874,8 @@ CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR Configurat
 //----------------------------------------------------------------------------------------
 NTSTATUS
 CUSBDevice::SubmitSetupPacket(
-    IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, 
-    IN OUT ULONG BufferLength, 
+    IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
+    IN OUT ULONG BufferLength,
     OUT PVOID Buffer)
 {
     NTSTATUS Status;
@@ -965,7 +966,7 @@ CUSBDevice::BuildInterfaceDescriptor(
             if (EndpointDescriptor->bLength == 0 || EndpointDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
             {
                 // bogus configuration descriptor
-                DPRINT1("[USBEHCI] Bogus descriptor found in InterfaceNumber %x Alternate %x EndpointIndex %x bLength %x bDescriptorType %x\n", InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, PipeIndex,
+                DPRINT1("[USBLIB] Bogus descriptor found in InterfaceNumber %x Alternate %x EndpointIndex %x bLength %x bDescriptorType %x\n", InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, PipeIndex,
                        EndpointDescriptor->bLength, EndpointDescriptor->bDescriptorType);
 
                 // failed
@@ -1037,7 +1038,7 @@ CUSBDevice::SelectConfiguration(
 
         if (!Found)
         {
-            DPRINT1("[USBUHCI] invalid configuration value %lu\n", ConfigurationDescriptor->bConfigurationValue);
+            DPRINT1("[USBLIB] invalid configuration value %lu\n", ConfigurationDescriptor->bConfigurationValue);
             return STATUS_INVALID_PARAMETER;
         }
 
@@ -1059,13 +1060,13 @@ CUSBDevice::SelectConfiguration(
     if (!ConfigurationDescriptor)
     {
         // unconfigure request
-        DPRINT1("CUsbDevice::SelectConfiguration Unconfigure Request Status %x\n", Status);
+        DPRINT1("CUSBDevice::SelectConfiguration Unconfigure Request Status %x\n", Status);
         m_ConfigurationIndex = 0;
         return Status;
     }
 
     // informal debug print
-    DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationIndex, m_ConfigurationIndex, Status);
+    DPRINT1("CUSBDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationIndex, m_ConfigurationIndex, Status);
     if (!NT_SUCCESS(Status))
     {
         //
@@ -1161,7 +1162,7 @@ CUSBDevice::SelectInterface(
     if (!Found)
     {
         // invalid handle passed
-        DPRINT1("[USBEHCI] Invalid configuration handle passed %p\n", ConfigurationHandle);
+        DPRINT1("[USBLIB] Invalid configuration handle passed %p\n", ConfigurationHandle);
         return STATUS_INVALID_PARAMETER;
     }