From cfc7748e23fe5dddd673a43e081e4080fa29fec4 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sat, 3 Jul 2010 11:40:58 +0000 Subject: [PATCH] [usb/usbehci] - 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 | 282 +++++++++++++++++++++++++- reactos/drivers/usb/usbehci/urbreq.c | 9 +- reactos/drivers/usb/usbehci/usbehci.c | 27 +-- reactos/drivers/usb/usbehci/usbehci.h | 5 +- reactos/drivers/usb/usbehci/usbiffn.c | 72 ++++++- 5 files changed, 359 insertions(+), 36 deletions(-) diff --git a/reactos/drivers/usb/usbehci/fdo.c b/reactos/drivers/usb/usbehci/fdo.c index c42ebfd1f56..881e97809de 100644 --- a/reactos/drivers/usb/usbehci/fdo.c +++ b/reactos/drivers/usb/usbehci/fdo.c @@ -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; +} diff --git a/reactos/drivers/usb/usbehci/urbreq.c b/reactos/drivers/usb/usbehci/urbreq.c index cbd18452757..e5af47ee954 100644 --- a/reactos/drivers/usb/usbehci/urbreq.c +++ b/reactos/drivers/usb/usbehci/urbreq.c @@ -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; diff --git a/reactos/drivers/usb/usbehci/usbehci.c b/reactos/drivers/usb/usbehci/usbehci.c index 0f35a318f02..398f3b46bcb 100644 --- a/reactos/drivers/usb/usbehci/usbehci.c +++ b/reactos/drivers/usb/usbehci/usbehci.c @@ -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); } diff --git a/reactos/drivers/usb/usbehci/usbehci.h b/reactos/drivers/usb/usbehci/usbehci.h index 56f03b5b491..f5977412db7 100644 --- a/reactos/drivers/usb/usbehci/usbehci.h +++ b/reactos/drivers/usb/usbehci/usbehci.h @@ -9,7 +9,7 @@ #include #include -#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); diff --git a/reactos/drivers/usb/usbehci/usbiffn.c b/reactos/drivers/usb/usbehci/usbiffn.c index 4dd98f4212d..95cbbaab156 100644 --- a/reactos/drivers/usb/usbehci/usbiffn.c +++ b/reactos/drivers/usb/usbehci/usbiffn.c @@ -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; }