diff --git a/reactos/drivers/usb/usbuhci/hcd_controller.cpp b/reactos/drivers/usb/usbuhci/hcd_controller.cpp index 277adbff2fd..4f50c53ccfb 100644 --- a/reactos/drivers/usb/usbuhci/hcd_controller.cpp +++ b/reactos/drivers/usb/usbuhci/hcd_controller.cpp @@ -234,7 +234,7 @@ CHCDController::HandleDeviceControl( // PC_ASSERT(DeviceExtension->IsFDO); - DPRINT1("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n", + DPRINT("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength); @@ -394,7 +394,7 @@ CHCDController::HandlePnp( { case IRP_MN_START_DEVICE: { - DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO\n"); + DPRINT("CHCDController::HandlePnp IRP_MN_START FDO\n"); // // first start lower device object @@ -423,12 +423,12 @@ CHCDController::HandlePnp( Status = SetSymbolicLink(TRUE); } - DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status); + DPRINT("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status); break; } case IRP_MN_QUERY_DEVICE_RELATIONS: { - DPRINT1("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type); + DPRINT("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type); if (m_HubController == NULL) { @@ -502,14 +502,13 @@ CHCDController::HandlePnp( // // not supported // - PC_ASSERT(0); Status = STATUS_NOT_SUPPORTED; } break; } case IRP_MN_STOP_DEVICE: { - DPRINT1("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n"); + DPRINT("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n"); if (m_Hardware) { @@ -535,9 +534,34 @@ CHCDController::HandlePnp( } break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + { + // + // sure + // + Irp->IoStatus.Status = STATUS_SUCCESS; + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(m_NextDeviceObject, Irp); + } case IRP_MN_REMOVE_DEVICE: { - DPRINT1("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n"); + DPRINT("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n"); + + // + // delete the symbolic link + // + SetSymbolicLink(FALSE); + + // + // forward irp to next device object + // + IoSkipCurrentIrpStackLocation(Irp); + IoCallDriver(m_NextDeviceObject, Irp); // // detach device from device stack @@ -549,8 +573,7 @@ CHCDController::HandlePnp( // IoDeleteDevice(m_FunctionalDeviceObject); - Status = STATUS_SUCCESS; - break; + return STATUS_SUCCESS; } default: { @@ -650,7 +673,7 @@ CHCDController::CreateFDO( // m_FDODeviceNumber = UsbDeviceNumber; - DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName); + DPRINT("CreateFDO: DeviceName %wZ\n", &DeviceName); /* done */ return Status; diff --git a/reactos/drivers/usb/usbuhci/hub_controller.cpp b/reactos/drivers/usb/usbuhci/hub_controller.cpp index 2d8727d5f94..18bd88e74b6 100644 --- a/reactos/drivers/usb/usbuhci/hub_controller.cpp +++ b/reactos/drivers/usb/usbuhci/hub_controller.cpp @@ -70,6 +70,9 @@ public: NTSTATUS HandleClassEndpoint(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); + NTSTATUS HandleSyncResetAndClearStall(IN OUT PIRP Irp, PURB Urb); + NTSTATUS HandleAbortPipe(IN OUT PIRP Irp, PURB Urb); friend VOID StatusChangeEndpointCallBack(PVOID Context); @@ -190,7 +193,7 @@ CHubController::Initialize( USHORT VendorID, DeviceID; ULONG Dummy1; - DPRINT1("CHubController::Initialize\n"); + DPRINT("CHubController::Initialize\n"); // // initialize members @@ -305,7 +308,7 @@ CHubController::QueryStatusChageEndpoint( // Get the number of ports and check each one for device connected // m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL); - DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL); + DPRINT("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL); TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer; @@ -316,7 +319,7 @@ CHubController::QueryStatusChageEndpoint( { m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange); - DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange); + DPRINT("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange); // @@ -427,16 +430,25 @@ CHubController::HandlePnp( { case IRP_MN_START_DEVICE: { - DPRINT1("CHubController::HandlePnp IRP_MN_START_DEVICE\n"); + DPRINT("CHubController::HandlePnp IRP_MN_START_DEVICE\n"); // // register device interface // Status = SetDeviceInterface(TRUE); break; } + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + { + // + // sure + // + Status = STATUS_SUCCESS; + break; + } case IRP_MN_QUERY_ID: { - DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType); + DPRINT("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType); if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID) { @@ -462,7 +474,7 @@ CHubController::HandlePnp( swprintf(Buffer, L"USB\\ROOT_HUB"); } - DPRINT1("Name %S\n", Buffer); + DPRINT("Name %S\n", Buffer); // // calculate length @@ -539,7 +551,7 @@ CHubController::HandlePnp( Index++; - DPRINT1("Name %S\n", Buffer); + DPRINT("Name %S\n", Buffer); // // allocate buffer @@ -573,7 +585,7 @@ CHubController::HandlePnp( } case IRP_MN_QUERY_CAPABILITIES: { - DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n"); + DPRINT("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n"); DeviceCapabilities = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities; @@ -593,7 +605,7 @@ CHubController::HandlePnp( DeviceCapabilities->HardwareDisabled = FALSE; DeviceCapabilities->NoDisplayInUI = FALSE; DeviceCapabilities->DeviceState[0] = PowerDeviceD0; - for (Index = 0; Index < PowerSystemMaximum; Index++) + for (Index = 1; Index < PowerSystemMaximum; Index++) DeviceCapabilities->DeviceState[Index] = PowerDeviceD3; DeviceCapabilities->DeviceWake = PowerDeviceUnspecified; DeviceCapabilities->D1Latency = 0; @@ -605,7 +617,7 @@ CHubController::HandlePnp( } case IRP_MN_QUERY_INTERFACE: { - DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n"); + DPRINT("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n"); // // handle device interface requests @@ -615,7 +627,7 @@ CHubController::HandlePnp( } case IRP_MN_REMOVE_DEVICE: { - DPRINT1("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n"); + DPRINT("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n"); // // deactivate device interface for BUS PDO @@ -645,7 +657,7 @@ CHubController::HandlePnp( } case IRP_MN_QUERY_DEVICE_RELATIONS: { - DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", IoStack->Parameters.QueryDeviceRelations.Type); + DPRINT("CHubController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", IoStack->Parameters.QueryDeviceRelations.Type); if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) { @@ -686,7 +698,7 @@ CHubController::HandlePnp( } case IRP_MN_QUERY_BUS_INFORMATION: { - DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n"); + DPRINT("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n"); // // allocate buffer for bus information @@ -719,7 +731,7 @@ CHubController::HandlePnp( } case IRP_MN_STOP_DEVICE: { - DPRINT1("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n"); + DPRINT("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n"); // // stop device // @@ -790,7 +802,15 @@ CHubController::HandleIsochronousTransfer( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleIsochronousTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -827,7 +847,7 @@ CHubController::HandleBulkOrInterruptTransfer( // // Else pend the IRP, to be completed when a device connects or disconnects. // - DPRINT1("Pending SCE Irp\n");; + DPRINT("Pending SCE Irp\n");; m_PendingSCEIrp = Irp; IoMarkIrpPending(Irp); return STATUS_PENDING; @@ -847,7 +867,15 @@ CHubController::HandleBulkOrInterruptTransfer( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleBuldOrInterruptTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -984,7 +1012,6 @@ CHubController::HandleClassOther( // reset port feature // Status = m_Hardware->SetPortFeature(PortId, PORT_RESET); - PC_ASSERT(Status == STATUS_SUCCESS); break; } default: @@ -1057,7 +1084,15 @@ CHubController::HandleSelectConfiguration( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleSelectConfiguration invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1099,7 +1134,15 @@ CHubController::HandleSelectInterface( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleSelectInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1149,7 +1192,15 @@ CHubController::HandleGetStatusFromDevice( // // check if this is a valid usb device handle // - ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleGetStatusFromDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1172,7 +1223,7 @@ CHubController::HandleGetStatusFromDevice( // Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer); ASSERT(Status == STATUS_SUCCESS); - DPRINT1("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus); + DPRINT("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus); // // done @@ -1205,7 +1256,15 @@ CHubController::HandleClassDevice( // // check if this is a valid usb device handle // - ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("USB_REQUEST_GET_STATUS invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1311,7 +1370,15 @@ CHubController::HandleGetDescriptorFromInterface( // // check if this is a valid usb device handle // - ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleGetDescriptorFromInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1381,7 +1448,15 @@ CHubController::HandleGetDescriptor( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleGetDescriptor invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1452,7 +1527,15 @@ CHubController::HandleGetDescriptor( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("USB_CONFIGURATION_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1494,11 +1577,18 @@ CHubController::HandleGetDescriptor( PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength); - // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("USB_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1552,7 +1642,15 @@ CHubController::HandleClassEndpoint( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleClassEndpoint invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1573,12 +1671,21 @@ CHubController::HandleClassEndpoint( // // initialize setup packet // - CtrlSetup.bmRequestType.B = 0xa2; //FIXME: Const. + CtrlSetup.bmRequestType.B = 0x22; //FIXME: Const. 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.B |= 0x80; + } + + // // issue request // @@ -1596,6 +1703,196 @@ CHubController::HandleClassEndpoint( return Status; } +NTSTATUS +CHubController::HandleSyncResetAndClearStall( + IN OUT PIRP Irp, + IN OUT PURB Urb) +{ + NTSTATUS Status = STATUS_SUCCESS; + PUSB_ENDPOINT EndpointDescriptor; + ULONG Type; + + // + // sanity check + // + PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); + PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); + PC_ASSERT(Urb->UrbPipeRequest.PipeHandle); + + // + // check if this is a valid usb device handle + // + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } + + // + // get endpoint descriptor + // + EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle; + + // + // abort pipe + // + Status = HandleAbortPipe(Irp, Urb); + if (!NT_SUCCESS(Status)) + { + // + // abort pipe failed + // + DPRINT1("[USBOHCI] AbortPipe failed with %x\n", Status); + } + + // + // get type + // + Type = (EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK); + if (Type != USB_ENDPOINT_TYPE_ISOCHRONOUS) + { + // + // clear stall + // + Status = HandleClearStall(Irp, Urb); + } + DPRINT1("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL Status %x\n", Status); + + // + // reset data toggle + // + EndpointDescriptor->DataToggle = 0; + + // + // done + // + return Status; +} + +NTSTATUS +CHubController::HandleAbortPipe( + IN OUT PIRP Irp, + IN OUT PURB Urb) +{ + NTSTATUS Status; + PUSBDEVICE UsbDevice; + PUSB_ENDPOINT EndpointDescriptor; + + // + // sanity check + // + PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); + PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); + PC_ASSERT(Urb->UrbPipeRequest.PipeHandle); + + // + // check if this is a valid usb device handle + // + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } + + // + // get endpoint descriptor + // + EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle; + + // + // get device + // + UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); + + + // + // issue request + // + Status = UsbDevice->AbortPipe(EndpointDescriptor); + DPRINT1("URB_FUNCTION_ABORT_PIPE Status %x\n", Status); + + // + // done + // + return Status; +} + + +//----------------------------------------------------------------------------------------- +NTSTATUS +CHubController::HandleClearStall( + IN OUT PIRP Irp, + IN OUT PURB Urb) +{ + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + NTSTATUS Status; + PUSBDEVICE UsbDevice; + PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor; + + + // + // sanity check + // + PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); + PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); + PC_ASSERT(Urb->UrbPipeRequest.PipeHandle); + + // + // check if this is a valid usb device handle + // + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleClearStall invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } + + // + // get endpoint descriptor + // + EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle; + + // + // get device + // + UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); + DPRINT1("URB_FUNCTION_SYNC_CLEAR_STALL\n"); + + // + // initialize setup packet + // + CtrlSetup.bmRequestType.B = 0x02; + CtrlSetup.bRequest = USB_REQUEST_CLEAR_FEATURE; + CtrlSetup.wValue.W = USB_FEATURE_ENDPOINT_STALL; + CtrlSetup.wIndex.W = EndpointDescriptor->bEndpointAddress; + CtrlSetup.wLength = 0; + CtrlSetup.wValue.W = 0; + + // + // issue request + // + Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, 0, 0); + + DPRINT1("URB_FUNCTION_CLEAR_STALL Status %x\n", Status); + + // + // done + // + return Status; +} + + //----------------------------------------------------------------------------------------- NTSTATUS CHubController::HandleClassInterface( @@ -1616,7 +1913,15 @@ CHubController::HandleClassInterface( // // check if this is a valid usb device handle // - PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))); + if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) + { + DPRINT1("HandleClassInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); + + // + // invalid device handle + // + return STATUS_DEVICE_NOT_CONNECTED; + } // // get device @@ -1634,21 +1939,23 @@ CHubController::HandleClassInterface( DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value); DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index); - if (Urb->UrbControlVendorClassRequest.TransferBufferLength == 0) - { - DPRINT1("Invalid request length\n"); - return STATUS_SUCCESS; - } - // // initialize setup packet // - CtrlSetup.bmRequestType.B = 0xa1; + CtrlSetup.bmRequestType.B = 0x21; 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.B |= 0x80; + } + // // issue request // @@ -1657,8 +1964,13 @@ CHubController::HandleClassInterface( // // assert on failure // - PC_ASSERT(NT_SUCCESS(Status)); - + if (!NT_SUCCESS(Status)) + { + // + // display error + // + DPRINT1("URB_FUNCTION_CLASS_INTERFACE failed with Urb Status %x\n", Urb->UrbHeader.Status); + } // // done @@ -1702,6 +2014,16 @@ CHubController::HandleDeviceControl( switch (Urb->UrbHeader.Function) { + case URB_FUNCTION_SYNC_RESET_PIPE: + case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: + Status = HandleSyncResetAndClearStall(Irp, Urb); + break; + case URB_FUNCTION_ABORT_PIPE: + Status = HandleAbortPipe(Irp, Urb); + break; + case URB_FUNCTION_SYNC_CLEAR_STALL: + Status = HandleClearStall(Irp, Urb); + break; case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE: Status = HandleGetDescriptorFromInterface(Irp, Urb); break; @@ -2132,7 +2454,7 @@ USBI_InterfaceReference( { CHubController * Controller = (CHubController*)BusContext; - DPRINT1("USBH_InterfaceReference\n"); + DPRINT("USBH_InterfaceReference\n"); // // add reference @@ -2147,7 +2469,7 @@ USBI_InterfaceDereference( { CHubController * Controller = (CHubController*)BusContext; - DPRINT1("USBH_InterfaceDereference\n"); + DPRINT("USBH_InterfaceDereference\n"); // // release @@ -2171,7 +2493,7 @@ USBHI_CreateUsbDevice( CHubController * Controller; NTSTATUS Status; - DPRINT1("USBHI_CreateUsbDevice\n"); + DPRINT("USBHI_CreateUsbDevice PortStatus %x\n", PortStatus); // // first get hub controller @@ -2261,7 +2583,7 @@ USBHI_InitializeUsbDevice( NTSTATUS Status; ULONG Index = 0; - DPRINT1("USBHI_InitializeUsbDevice\n"); + DPRINT("USBHI_InitializeUsbDevice\n"); // // first get controller @@ -2357,7 +2679,7 @@ USBHI_GetUsbDescriptors( PUSBDEVICE UsbDevice; CHubController * Controller; - DPRINT1("USBHI_GetUsbDescriptors\n"); + DPRINT("USBHI_GetUsbDescriptors\n"); // // sanity check @@ -2426,7 +2748,7 @@ USBHI_RemoveUsbDevice( CHubController * Controller; NTSTATUS Status; - DPRINT1("USBHI_RemoveUsbDevice\n"); + DPRINT("USBHI_RemoveUsbDevice\n"); // // first get controller @@ -2499,7 +2821,7 @@ USBHI_RestoreUsbDevice( PUSBDEVICE OldUsbDevice, NewUsbDevice; CHubController * Controller; - DPRINT1("USBHI_RestoreUsbDevice\n"); + DPRINT("USBHI_RestoreUsbDevice\n"); // // first get controller @@ -2521,8 +2843,8 @@ USBHI_RestoreUsbDevice( PC_ASSERT(Controller->ValidateUsbDevice(NewUsbDevice)); PC_ASSERT(Controller->ValidateUsbDevice(OldUsbDevice)); - DPRINT1("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress()); - DPRINT1("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress()); + DPRINT("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress()); + DPRINT("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress()); // // remove old device handle @@ -2545,7 +2867,7 @@ USBHI_QueryDeviceInformation( PUSBDEVICE UsbDevice; CHubController * Controller; - DPRINT1("USBHI_QueryDeviceInformation %p\n", BusContext); + DPRINT("USBHI_QueryDeviceInformation %p\n", BusContext); // // sanity check @@ -2667,7 +2989,7 @@ USBHI_GetControllerInformation( { PUSB_CONTROLLER_INFORMATION_0 ControllerInfo; - DPRINT1("USBHI_GetControllerInformation\n"); + DPRINT("USBHI_GetControllerInformation\n"); // // sanity checks @@ -2730,7 +3052,7 @@ USBHI_GetExtendedHubInformation( USHORT Dummy1; NTSTATUS Status; - DPRINT1("USBHI_GetExtendedHubInformation\n"); + DPRINT("USBHI_GetExtendedHubInformation\n"); // // sanity checks @@ -2909,7 +3231,7 @@ USBHI_SetDeviceHandleData( // looks like we need apply a dragon voodoo to fixup the device stack // otherwise usbhub will cause a bugcheck // - DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo); + DPRINT("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo); // // sanity check @@ -2946,7 +3268,7 @@ USBDI_GetUSBDIVersion( ULONG Speed, Dummy2; USHORT Dummy1; - DPRINT1("USBDI_GetUSBDIVersion\n"); + DPRINT("USBDI_GetUSBDIVersion\n"); // // get controller @@ -3026,7 +3348,7 @@ USBDI_IsDeviceHighSpeed( ULONG Speed, Dummy2; USHORT Dummy1; - DPRINT1("USBDI_IsDeviceHighSpeed\n"); + DPRINT("USBDI_IsDeviceHighSpeed\n"); // // get controller @@ -3287,7 +3609,7 @@ CHubController::SetDeviceInterface( // // done // - return Status; + return STATUS_SUCCESS; } NTSTATUS @@ -3349,7 +3671,7 @@ CHubController::CreatePDO( } } - DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName); + DPRINT("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName); // // fixup device stack voodoo part #1 @@ -3407,7 +3729,7 @@ VOID StatusChangeEndpointCallBack(PVOID Context) Irp = This->m_PendingSCEIrp; if (!Irp) { - DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n"); + DPRINT("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n"); return; } diff --git a/reactos/drivers/usb/usbuhci/interfaces.h b/reactos/drivers/usb/usbuhci/interfaces.h index c86e9501922..d9dec6eee43 100644 --- a/reactos/drivers/usb/usbuhci/interfaces.h +++ b/reactos/drivers/usb/usbuhci/interfaces.h @@ -38,6 +38,7 @@ // a list of registered controllers and provides support functions for the host controllers struct IHCDController; +struct _USB_ENDPOINT; DECLARE_INTERFACE_(IRootHCDController, IUnknown) { @@ -359,8 +360,8 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown) virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, + IN OPTIONAL struct _USB_ENDPOINT *EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, - IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer) = 0; @@ -436,7 +437,6 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown) // Description: returns device speed virtual USB_DEVICE_SPEED GetDeviceSpeed() = 0; - }; @@ -497,6 +497,15 @@ DECLARE_INTERFACE_(IUSBQueue, IUnknown) virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0; + +//----------------------------------------------------------------------------------------- +// +// AbortDevicePipe +// +// Description: aborts all pending requsts of an device + + virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN struct _USB_ENDPOINT * EndpointDescriptor) = 0; + }; typedef IUSBQueue *PUSBQUEUE; @@ -750,6 +759,16 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown) virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION Interface) = 0; + +//----------------------------------------------------------------------------------------- +// +// AbortPipe +// +// Description: aborts all pending requsts of an device + + virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor) = 0; + + }; typedef IUSBDevice *PUSBDEVICE; diff --git a/reactos/drivers/usb/usbuhci/memory_manager.cpp b/reactos/drivers/usb/usbuhci/memory_manager.cpp index a9cd88cb615..f21a9f64d38 100644 --- a/reactos/drivers/usb/usbuhci/memory_manager.cpp +++ b/reactos/drivers/usb/usbuhci/memory_manager.cpp @@ -271,7 +271,7 @@ CDMAMemoryManager::Release( IN ULONG Size) { KIRQL OldLevel; - ULONG BlockOffset = 0, BlockLength; + ULONG BlockOffset = 0, BlockLength, BlockCount; // // sanity checks @@ -301,15 +301,26 @@ CDMAMemoryManager::Release( // Size = (Size + m_BlockSize - 1) & ~(m_BlockSize - 1); + // + // convert to blocks + // + BlockCount = Size / m_BlockSize; + ASSERT(BlockCount); + // // acquire lock // KeAcquireSpinLock(m_Lock, &OldLevel); + // + // sanity check + // + ASSERT(RtlAreBitsSet(&m_Bitmap, BlockOffset, BlockCount)); + // // release buffer // - RtlClearBits(&m_Bitmap, BlockOffset, Size); + RtlClearBits(&m_Bitmap, BlockOffset, BlockCount); // // release lock diff --git a/reactos/drivers/usb/usbuhci/usb_device.cpp b/reactos/drivers/usb/usbuhci/usb_device.cpp index 057f792af3e..3bd4d29a2a5 100644 --- a/reactos/drivers/usb/usbuhci/usb_device.cpp +++ b/reactos/drivers/usb/usbuhci/usb_device.cpp @@ -52,18 +52,20 @@ public: virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, OUT ULONG BufferLength, OUT PVOID Buffer); virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSBD_INTERFACE_INFORMATION Interface, OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle); virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION Interface); + virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor); + // local function virtual NTSTATUS CommitIrp(PIRP Irp); - virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl); - virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex); + virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl); + virtual NTSTATUS CreateConfigurationDescriptor(UCHAR ConfigurationIndex); virtual NTSTATUS CreateDeviceDescriptor(); virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor); virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor); // constructor / destructor CUSBDevice(IUnknown *OuterUnknown){} - virtual ~CUSBDevice(){} + virtual ~CUSBDevice(); protected: LONG m_Ref; @@ -79,9 +81,77 @@ protected: ULONG m_PortStatus; PUSBQUEUE m_Queue; PDMAMEMORYMANAGER m_DmaManager; - PUSB_CONFIGURATION_DESCRIPTOR *m_ConfigurationDescriptors; + + PUSB_CONFIGURATION m_ConfigurationDescriptors; }; +CUSBDevice::~CUSBDevice() +{ + ULONG Index, InterfaceIndex, EndpointIndex; + //NTSTATUS Status; + + if (!m_ConfigurationDescriptors) + { + // + // nothing to do + // + return; + } + + + // + // clean up resources + // + for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++) + { + for(InterfaceIndex = 0; InterfaceIndex < m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) + { + // + // are there any endpoint descriptors + // + for(EndpointIndex = 0; EndpointIndex < m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints; EndpointIndex++) + { + // + // abort pipe + // + //Status = AbortPipe((PUSB_ENDPOINT_DESCRIPTOR)&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndpointIndex]); + //DPRINT1("[USBOHCI] Deleting Device Abort Pipe Status %x\n", Status); + } + + if (m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints) + { + // + // free endpoints + // + ExFreePool(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints); + } + } + + if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces) + { + // + // free interface descriptors + // + ExFreePool(m_ConfigurationDescriptors[Index].Interfaces); + } + + if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor) + { + // + // free configuration descriptor + // + ExFreePool(m_ConfigurationDescriptors[Index].ConfigurationDescriptor); + } + } + + // + // free configuration descriptor + // + ExFreePool(m_ConfigurationDescriptors); +} + + + //---------------------------------------------------------------------------------------- NTSTATUS STDMETHODCALLTYPE @@ -267,7 +337,7 @@ CUSBDevice::GetType() } DPRINT1("CUSBDevice::GetType Unknown bcdUSB Type %x\n", m_DeviceDescriptor.bcdUSB); - PC_ASSERT(FALSE); + //PC_ASSERT(FALSE); return Usb11Device; } @@ -299,7 +369,7 @@ CUSBDevice::SetDeviceAddress( PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; NTSTATUS Status; UCHAR OldAddress; - ULONG Index; + UCHAR Index; DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress); @@ -381,12 +451,12 @@ CUSBDevice::SetDeviceAddress( // // allocate configuration descriptor // - m_ConfigurationDescriptors = (PUSB_CONFIGURATION_DESCRIPTOR*) ExAllocatePoolWithTag(NonPagedPool, sizeof(PUSB_CONFIGURATION_DESCRIPTOR) * m_DeviceDescriptor.bNumConfigurations, TAG_USBOHCI); + m_ConfigurationDescriptors = (PUSB_CONFIGURATION) ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations, TAG_USBOHCI); // // zero configuration descriptor // - RtlZeroMemory(m_ConfigurationDescriptors, sizeof(PUSB_CONFIGURATION_DESCRIPTOR) * m_DeviceDescriptor.bNumConfigurations); + RtlZeroMemory(m_ConfigurationDescriptors, sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations); // // retrieve the configuration descriptors @@ -518,7 +588,7 @@ CUSBDevice::SubmitIrp( NTSTATUS CUSBDevice::CommitSetupPacket( IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, - IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, + IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl) { @@ -550,7 +620,7 @@ CUSBDevice::CommitSetupPacket( // // initialize request // - Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, GetSpeed(), EndpointDescriptor, BufferLength, Mdl); + Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, (struct _USB_ENDPOINT*)EndpointDescriptor, GetSpeed(), BufferLength, Mdl); if (!NT_SUCCESS(Status)) { // @@ -598,11 +668,24 @@ CUSBDevice::CreateDeviceDescriptor() USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; PMDL Mdl; NTSTATUS Status; + PVOID DeviceDescriptor; + + // + // allocate descriptor page aligned + // + DeviceDescriptor = ExAllocatePool(NonPagedPool, PAGE_SIZE); + if (!DeviceDescriptor) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } // // zero descriptor // - RtlZeroMemory(&m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + RtlZeroMemory(DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); // @@ -616,7 +699,7 @@ CUSBDevice::CreateDeviceDescriptor() // // allocate mdl describing the device descriptor // - Mdl = IoAllocateMdl(&m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR), FALSE, FALSE, 0); + Mdl = IoAllocateMdl(DeviceDescriptor, PAGE_SIZE, FALSE, FALSE, 0); if (!Mdl) { // @@ -645,9 +728,15 @@ CUSBDevice::CreateDeviceDescriptor() // // informal dbg print // + RtlCopyMemory(&m_DeviceDescriptor, DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); DumpDeviceDescriptor(&m_DeviceDescriptor); } + // + // free buffer + // + ExFreePool(DeviceDescriptor); + // // done // @@ -658,13 +747,16 @@ CUSBDevice::CreateDeviceDescriptor() //---------------------------------------------------------------------------------------- NTSTATUS CUSBDevice::CreateConfigurationDescriptor( - ULONG Index) + UCHAR Index) { PVOID Buffer; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; NTSTATUS Status; PMDL Mdl; + ULONG InterfaceIndex, EndPointIndex; PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + PUSB_ENDPOINT_DESCRIPTOR EndPointDescriptor; // @@ -684,11 +776,6 @@ CUSBDevice::CreateConfigurationDescriptor( return STATUS_INSUFFICIENT_RESOURCES; } - // - // zero buffer - // - RtlZeroMemory(Buffer, PAGE_SIZE); - // // build setup packet // @@ -697,15 +784,11 @@ CUSBDevice::CreateConfigurationDescriptor( CtrlSetup.bmRequestType._BM.Reserved = 0; CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; - CtrlSetup.wValue.LowByte = 0; + CtrlSetup.wValue.LowByte = Index; CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; CtrlSetup.wIndex.W = 0; CtrlSetup.wLength = PAGE_SIZE; - // - // FIXME: where put configuration index? - // - // // now build MDL describing the buffer // @@ -761,9 +844,124 @@ CUSBDevice::CreateConfigurationDescriptor( PC_ASSERT(ConfigurationDescriptor->bNumInterfaces); // - // store configuration descriptor + // request is complete, initialize configuration descriptor // - m_ConfigurationDescriptors[Index] = ConfigurationDescriptor; + m_ConfigurationDescriptors[Index].ConfigurationDescriptor = ConfigurationDescriptor; + + // + // now allocate interface descriptors + // + m_ConfigurationDescriptors[Index].Interfaces = (PUSB_INTERFACE)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_INTERFACE) * ConfigurationDescriptor->bNumInterfaces, TAG_USBOHCI); + if (!m_ConfigurationDescriptors[Index].Interfaces) + { + // + // failed to allocate interface descriptors + // + ExFreePool(Buffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // zero interface descriptor + // + RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces, sizeof(USB_INTERFACE) * ConfigurationDescriptor->bNumInterfaces); + + // + // get first interface descriptor + // + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)(ConfigurationDescriptor + 1); + + // + // setup interface descriptors + // + for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) + { + while(InterfaceDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE && InterfaceDescriptor->bLength != sizeof(USB_INTERFACE_DESCRIPTOR)) + { + // + // move to next descriptor + // + ASSERT(InterfaceDescriptor->bLength); + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + } + + // + // sanity checks + // + ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); + ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); + ASSERT(InterfaceDescriptor->bNumEndpoints); + + // + // copy current interface descriptor + // + RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor, InterfaceDescriptor, InterfaceDescriptor->bLength); + + // + // allocate end point descriptors + // + m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints = (PUSB_ENDPOINT)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints, TAG_USBOHCI); + if (!m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints) + { + // + // failed to allocate endpoint + // + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + // + // zero memory + // + RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints, sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints); + + // + // initialize end point descriptors + // + EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)(InterfaceDescriptor + 1); + + for(EndPointIndex = 0; EndPointIndex < InterfaceDescriptor->bNumEndpoints; EndPointIndex++) + { + // + // skip other descriptors + // + while(EndPointDescriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE && EndPointDescriptor->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR)) + { + // + // assert when next interface descriptor is reached before the next endpoint + // + ASSERT(EndPointDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE); + ASSERT(EndPointDescriptor->bLength); + + DPRINT1("InterfaceDescriptor bNumEndpoints %x EndpointIndex %x Skipping Descriptor Type %x\n", InterfaceDescriptor->bNumEndpoints, EndPointIndex, EndPointDescriptor->bDescriptorType); + // + // move to next descriptor + // + EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor + EndPointDescriptor->bLength); + } + + // + // sanity check + // + ASSERT(EndPointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE); + ASSERT(EndPointDescriptor->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR)); + + // + // copy endpoint descriptor + // + RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndPointIndex].EndPointDescriptor, EndPointDescriptor, EndPointDescriptor->bLength); + + // + // move to next offset + // + EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor + EndPointDescriptor->bLength); + } + + // + // update interface descriptor offset + // + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)EndPointDescriptor; + } // // done @@ -797,8 +995,8 @@ CUSBDevice::GetConfigurationDescriptors( // // copy configuration descriptor // - RtlCopyMemory(ConfigDescriptorBuffer, m_ConfigurationDescriptors[0], min(m_ConfigurationDescriptors[0]->wTotalLength, BufferLength)); - *OutBufferLength = m_ConfigurationDescriptors[0]->wTotalLength; + RtlCopyMemory(ConfigDescriptorBuffer, m_ConfigurationDescriptors[0].ConfigurationDescriptor, min(m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength, BufferLength)); + *OutBufferLength = m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength; } //---------------------------------------------------------------------------------------- @@ -809,11 +1007,7 @@ CUSBDevice::GetConfigurationDescriptorsLength() // FIXME: support multiple configurations // PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); - - ASSERT(m_ConfigurationDescriptors[0]); - ASSERT(m_ConfigurationDescriptors[0]->wTotalLength); - - return m_ConfigurationDescriptors[0]->wTotalLength; + return m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength; } //---------------------------------------------------------------------------------------- VOID @@ -858,27 +1052,40 @@ CUSBDevice::SubmitSetupPacket( OUT PVOID Buffer) { NTSTATUS Status; - PMDL Mdl; + PMDL Mdl = NULL; - // - // allocate mdl - // - Mdl = IoAllocateMdl(Buffer, BufferLength, FALSE, FALSE, 0); + if (BufferLength) + { + // + // allocate mdl + // + Mdl = IoAllocateMdl(Buffer, BufferLength, FALSE, FALSE, 0); + if (!Mdl) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } - // - // HACK HACK HACK: assume the buffer is build from non paged pool - // - MmBuildMdlForNonPagedPool(Mdl); + // + // HACK HACK HACK: assume the buffer is build from non paged pool + // + MmBuildMdlForNonPagedPool(Mdl); + } // // commit setup packet // Status = CommitSetupPacket(SetupPacket, 0, BufferLength, Mdl); - // - // free mdl - // - IoFreeMdl(Mdl); + if (Mdl != NULL) + { + // + // free mdl + // + IoFreeMdl(Mdl); + } // // done @@ -896,94 +1103,25 @@ CUSBDevice::SelectConfiguration( ULONG InterfaceIndex, PipeIndex; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; NTSTATUS Status; - PUSB_CONFIGURATION_DESCRIPTOR CurrentConfigurationDescriptor; - PUSB_INTERFACE_DESCRIPTOR CurrentInterfaceDescriptor; - PUSB_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor; - PVOID StartPosition; + UCHAR bConfigurationValue = 0; - // - // FIXME: support multiple configurations - // - ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); - ASSERT(m_ConfigurationDescriptors[0]); - CurrentConfigurationDescriptor = m_ConfigurationDescriptors[0]; - - // - // sanity check - // - PC_ASSERT(ConfigurationDescriptor->iConfiguration == CurrentConfigurationDescriptor->iConfiguration); - PC_ASSERT(ConfigurationDescriptor->bNumInterfaces <= CurrentConfigurationDescriptor->bNumInterfaces); - DPRINT1("CUSBDevice::SelectConfiguration NumInterfaces %lu\n", ConfigurationDescriptor->bNumInterfaces); - - - // - // copy interface info and pipe info - // - for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) + if (ConfigurationDescriptor) { // - // find interface descriptor + // sanity checks // - CurrentInterfaceDescriptor = USBD_ParseConfigurationDescriptor(CurrentConfigurationDescriptor, InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting); + ASSERT(ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations); + ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->iConfiguration); // // sanity check // - ASSERT(CurrentInterfaceDescriptor); - ASSERT(CurrentInterfaceDescriptor->bLength != 0); - ASSERT(InterfaceInfo->NumberOfPipes == CurrentInterfaceDescriptor->bNumEndpoints); - ASSERT(InterfaceInfo->Length != 0); -#ifdef _MSC_VER - PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); -#endif - - DPRINT1("CUSBDevice::SelectConfiguration InterfaceNumber %lu AlternativeSetting %lu bNumEndpoints %lu\n", InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting, CurrentInterfaceDescriptor->bNumEndpoints); + ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->bNumInterfaces); // - // copy interface info + // get configuration value // - InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)CurrentInterfaceDescriptor; - InterfaceInfo->Class = CurrentInterfaceDescriptor->bInterfaceClass; - InterfaceInfo->SubClass = CurrentInterfaceDescriptor->bInterfaceSubClass; - InterfaceInfo->Protocol = CurrentInterfaceDescriptor->bInterfaceProtocol; - InterfaceInfo->Reserved = 0; - - // - // copy endpoint info - // - StartPosition = CurrentInterfaceDescriptor; - for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) - { - // - // find corresponding endpoint descriptor - // - CurrentEndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(CurrentConfigurationDescriptor, CurrentConfigurationDescriptor->wTotalLength, StartPosition, USB_ENDPOINT_DESCRIPTOR_TYPE); - - // - // sanity checks - // - ASSERT(CurrentEndpointDescriptor); - ASSERT(CurrentEndpointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE); - - // - // copy pipe info - // - InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = CurrentEndpointDescriptor->wMaxPacketSize; - InterfaceInfo->Pipes[PipeIndex].EndpointAddress = CurrentEndpointDescriptor->bEndpointAddress; - InterfaceInfo->Pipes[PipeIndex].Interval = CurrentEndpointDescriptor->bInterval; - InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)CurrentEndpointDescriptor->bmAttributes; - InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)CurrentEndpointDescriptor; - - // - // move start position beyond the current endpoint descriptor - // - StartPosition = (PVOID)(CurrentEndpointDescriptor + 1); - } - - // - // move offset - // - InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) + InterfaceInfo->Length); + bConfigurationValue = ConfigurationDescriptor->bConfigurationValue; } // @@ -991,29 +1129,92 @@ CUSBDevice::SelectConfiguration( // RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION; - CtrlSetup.wValue.W = ConfigurationDescriptor->bConfigurationValue; + CtrlSetup.wValue.W = bConfigurationValue; // // select configuration // Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0); + if (!ConfigurationDescriptor) + { + // + // unconfigure request + // + 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", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status); - - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { // - // store configuration device index + // failed // - m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration; + return Status; + } + + // + // store configuration device index + // + m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration; + + // + // store configuration handle + // + *ConfigurationHandle = &m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration]; + + // + // copy interface info and pipe info + // + for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) + { + // + // sanity check: is the info pre-layed out + // + PC_ASSERT(InterfaceInfo->NumberOfPipes == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints); + PC_ASSERT(InterfaceInfo->Length != 0); +#ifdef _MSC_VER + PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); +#endif // - // store configuration handle + // copy interface info // - *ConfigurationHandle = m_ConfigurationDescriptors[0]; + InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex]; + InterfaceInfo->Class = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceClass; + InterfaceInfo->SubClass = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceSubClass; + InterfaceInfo->Protocol = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceProtocol; + InterfaceInfo->Reserved = 0; + + // + // copy endpoint info + // + for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) + { + // + // copy pipe info + // + InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize; + InterfaceInfo->Pipes[PipeIndex].EndpointAddress = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress; + InterfaceInfo->Pipes[PipeIndex].Interval = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bInterval; + InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes; + InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor; + + // + // data toggle is reset on configuration requests + // + m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].DataToggle = FALSE; + } + + // + // move offset + // + InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) + InterfaceInfo->Length); } // @@ -1028,49 +1229,31 @@ CUSBDevice::SelectInterface( IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo) { - PUSB_CONFIGURATION_DESCRIPTOR Configuration; + PUSB_CONFIGURATION Configuration; ULONG PipeIndex; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; NTSTATUS Status; - PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; - PUSB_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor; - PVOID StartPosition; - - // - // FIXME support multiple configurations - // - PC_ASSERT(m_ConfigurationDescriptors[0] == (PUSB_CONFIGURATION_DESCRIPTOR)ConfigurationHandle); // // get configuration struct // - Configuration = (PUSB_CONFIGURATION_DESCRIPTOR)ConfigurationHandle; + Configuration = (PUSB_CONFIGURATION)ConfigurationHandle; // - // sanity checks + // sanity check // - PC_ASSERT(Configuration->bNumInterfaces > InterfaceInfo->InterfaceNumber); -#ifdef _MSC_VER - //PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); -#endif - - // - // FIXME: check bandwidth - // - - // - // find interface number - // - InterfaceDescriptor = USBD_ParseConfigurationDescriptor(Configuration, InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting); - ASSERT(InterfaceDescriptor); + ASSERT(Configuration->ConfigurationDescriptor->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE); + ASSERT(Configuration->ConfigurationDescriptor->bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR)); + ASSERT(Configuration->ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations); + ASSERT(&m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration] == Configuration); // // initialize setup packet // RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE; - CtrlSetup.wValue.W = InterfaceDescriptor->bAlternateSetting; - CtrlSetup.wIndex.W = InterfaceDescriptor->bInterfaceNumber; + CtrlSetup.wValue.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bAlternateSetting; + CtrlSetup.wIndex.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bInterfaceNumber; CtrlSetup.bmRequestType.B = 0x01; // @@ -1082,61 +1265,81 @@ CUSBDevice::SelectInterface( // informal debug print // DPRINT1("CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x Status %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber, Status); - DPRINT1("CUSBDevice::SelectInterface bInterfaceNumber %u bAlternateSetting %u NumberOfPipes %u Length %lu\n", - InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, InterfaceInfo->NumberOfPipes, InterfaceInfo->Length); - InterfaceInfo->InterfaceHandle = InterfaceDescriptor; - InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints; - - // - // are there end points - // - if (InterfaceDescriptor->bNumEndpoints) + if (!NT_SUCCESS(Status)) { // - // sanity check + // failed to select interface // - ASSERT(InterfaceInfo->Length == sizeof(USBD_INTERFACE_INFORMATION) + (InterfaceDescriptor->bNumEndpoints > 1 ? sizeof(USBD_PIPE_INFORMATION) * (InterfaceDescriptor->bNumEndpoints - 1) : 0)); + return Status; + } + + + // + // sanity checks + // + PC_ASSERT(Configuration->ConfigurationDescriptor->bNumInterfaces > InterfaceInfo->InterfaceNumber); + PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bNumEndpoints == InterfaceInfo->NumberOfPipes); +#ifdef _MSC_VER + PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); +#endif + + // + // copy pipe handles + // + for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) + { + // + // copy pipe handle + // + DPRINT1("PipeIndex %lu\n", PipeIndex); + DPRINT1("EndpointAddress %x\n", InterfaceInfo->Pipes[PipeIndex].EndpointAddress); + DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval); + DPRINT1("MaximumPacketSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize); + DPRINT1("MaximumTransferSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize); + DPRINT1("PipeFlags %d\n", InterfaceInfo->Pipes[PipeIndex].PipeFlags); + DPRINT1("PipeType %dd\n", InterfaceInfo->Pipes[PipeIndex].PipeType); + DPRINT1("UsbEndPoint %x\n", Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress); + PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress == InterfaceInfo->Pipes[PipeIndex].EndpointAddress); + + InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor; // - // store number of pipes + // data toggle is reset on select interface requests // - InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints; + m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].DataToggle = FALSE; - StartPosition = InterfaceDescriptor; - for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) + if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT)) { // - // find corresponding endpoint descriptor + // FIXME: check if enough bandwidth is available // - CurrentEndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(Configuration, Configuration->wTotalLength, StartPosition, USB_ENDPOINT_DESCRIPTOR_TYPE); - - // - // sanity checks - // - ASSERT(CurrentEndpointDescriptor); - ASSERT(CurrentEndpointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE); - - // - // copy pipe info - // - InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = CurrentEndpointDescriptor->wMaxPacketSize; - InterfaceInfo->Pipes[PipeIndex].EndpointAddress = CurrentEndpointDescriptor->bEndpointAddress; - InterfaceInfo->Pipes[PipeIndex].Interval = CurrentEndpointDescriptor->bInterval; - InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)CurrentEndpointDescriptor->bmAttributes; - InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)CurrentEndpointDescriptor; - - // - // move start position beyond the current endpoint descriptor - // - StartPosition = (PVOID)(CurrentEndpointDescriptor + 1); } } + + // // done // return Status; } +NTSTATUS +CUSBDevice::AbortPipe( + IN struct _USB_ENDPOINT *EndpointDescriptor) +{ + // + // let it handle usb queue + // + ASSERT(m_Queue); + ASSERT(m_DeviceAddress); + + // + // done + // + return m_Queue->AbortDevicePipe(m_DeviceAddress, EndpointDescriptor); +} + + //---------------------------------------------------------------------------------------- NTSTATUS CreateUSBDevice( diff --git a/reactos/drivers/usb/usbuhci/usb_queue.cpp b/reactos/drivers/usb/usbuhci/usb_queue.cpp index 784240c8c24..51c17c558b9 100644 --- a/reactos/drivers/usb/usbuhci/usb_queue.cpp +++ b/reactos/drivers/usb/usbuhci/usb_queue.cpp @@ -39,6 +39,8 @@ public: virtual NTSTATUS AddUSBRequest(IUSBRequest * Request); virtual NTSTATUS CancelRequests(); virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest); + virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN struct _USB_ENDPOINT * EndpointDescriptor); + // local VOID LinkQueueHead(PUHCI_QUEUE_HEAD QueueHead, PUHCI_QUEUE_HEAD NextQueueHead); @@ -203,6 +205,16 @@ CUSBQueue::CancelRequests() return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +CUSBQueue::AbortDevicePipe( + IN UCHAR DeviceAddress, + IN struct _USB_ENDPOINT *EndpointDescriptor) +{ + UNIMPLEMENTED + ASSERT(FALSE); + return STATUS_NOT_IMPLEMENTED; +} + NTSTATUS CUSBQueue::CreateUSBRequest( IUSBRequest **OutRequest) diff --git a/reactos/drivers/usb/usbuhci/usb_request.cpp b/reactos/drivers/usb/usbuhci/usb_request.cpp index 9562df5f21a..5e6187a2594 100644 --- a/reactos/drivers/usb/usbuhci/usb_request.cpp +++ b/reactos/drivers/usb/usbuhci/usb_request.cpp @@ -36,7 +36,7 @@ public: } // IUSBRequest interface functions - virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN USB_DEVICE_SPEED DeviceSpeed, IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer); + virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer); virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp, IN USB_DEVICE_SPEED DeviceSpeed); virtual BOOLEAN IsRequestComplete(); virtual ULONG GetTransferType(); @@ -119,7 +119,7 @@ protected: // // store end point address // - PUSB_ENDPOINT_DESCRIPTOR m_EndpointDescriptor; + PUSB_ENDPOINT m_EndpointDescriptor; // // allocated setup packet from the DMA pool @@ -156,8 +156,8 @@ CUSBRequest::InitializeWithSetupPacket( IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, + IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, - IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer) { @@ -321,7 +321,7 @@ CUSBRequest::InitializeWithIrp( // // get endpoint descriptor // - m_EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbIsochronousTransfer.PipeHandle; + m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbIsochronousTransfer.PipeHandle; // // completed initialization @@ -396,7 +396,7 @@ CUSBRequest::InitializeWithIrp( // // get endpoint descriptor // - m_EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle; + m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbBulkOrInterruptTransfer.PipeHandle; } break; @@ -461,19 +461,19 @@ CUSBRequest::GetMaxPacketSize() // // return max packet size // - return m_EndpointDescriptor->wMaxPacketSize; + return m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize; } UCHAR CUSBRequest::GetInterval() { ASSERT(m_EndpointDescriptor); - ASSERT((m_EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT); + ASSERT((m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT); // // return interrupt interval // - return m_EndpointDescriptor->bInterval; + return m_EndpointDescriptor->EndPointDescriptor.bInterval; } UCHAR @@ -493,7 +493,7 @@ CUSBRequest::GetEndpointAddress() // // endpoint number is between 1-15 // - return (m_EndpointDescriptor->bEndpointAddress & 0xF); + return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0xF); } //---------------------------------------------------------------------------------------- @@ -512,7 +512,7 @@ CUSBRequest::InternalGetTransferType() // // end point is defined in the low byte of bmAttributes // - TransferType = (m_EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK); + TransferType = (m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK); } else { @@ -536,7 +536,7 @@ CUSBRequest::InternalGetPidDirection() // // end point direction is highest bit in bEndpointAddress // - return (m_EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7; + return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7; } else { diff --git a/reactos/drivers/usb/usbuhci/usbuhci.h b/reactos/drivers/usb/usbuhci/usbuhci.h index 59d27b9bcc4..a4545e40001 100644 --- a/reactos/drivers/usb/usbuhci/usbuhci.h +++ b/reactos/drivers/usb/usbuhci/usbuhci.h @@ -107,4 +107,26 @@ NTSTATUS CreateUSBQueue(PUSBQUEUE *OutUsbQueue); // NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest); + +typedef struct _USB_ENDPOINT +{ + USB_ENDPOINT_DESCRIPTOR EndPointDescriptor; + UCHAR HubAddress; + UCHAR HubPort; + UCHAR DataToggle; +} USB_ENDPOINT, *PUSB_ENDPOINT; + +typedef struct _USB_INTERFACE +{ + USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + USB_ENDPOINT *EndPoints; +} USB_INTERFACE, *PUSB_INTERFACE; + +typedef struct _USB_CONFIGURATION +{ + PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; + USB_INTERFACE *Interfaces; +} USB_CONFIGURATION, *PUSB_CONFIGURATION; + + #endif