Index: drivers/hid/hidusb/hidusb.c =================================================================== --- drivers/hid/hidusb/hidusb.c (revision 70327) +++ drivers/hid/hidusb/hidusb.c (working copy) @@ -10,6 +10,9 @@ #include "hidusb.h" +//#define NDEBUG +#include + PUSBD_PIPE_INFORMATION HidUsb_GetInputInterruptInterfaceHandle( PUSBD_INTERFACE_INFORMATION InterfaceInformation) Index: drivers/usb/usbuhci/hardware.h =================================================================== --- drivers/usb/usbuhci/hardware.h (revision 70327) +++ drivers/usb/usbuhci/hardware.h (working copy) @@ -83,22 +83,64 @@ #define NUMBER_OF_FRAMES 1024 #define MAX_AVAILABLE_BANDWIDTH 900 // Microseconds -// Represents a Transfer Descriptor (TD) -typedef struct _UHCI_TRANSFER_DESCRIPTOR -{ - ULONG LinkPhysical; // Link to next transfer descriptor / queue head - ULONG Status; // status - ULONG Token; // packet header - ULONG BufferPhysical; // pointer to the buffer +typedef struct _UHCI_TRANSFER_DESCRIPTOR { // represents a Transfer Descriptor (TD). Must be aligned on a 16-byte boundary - // Software part - ULONG PhysicalAddress; // Physical address of this descriptor - PVOID NextLogicalDescriptor; - ULONG BufferSize; // Size of the buffer - PVOID BufferLogical; // Logical pointer to the buffer - PVOID UserBuffer; -}UHCI_TRANSFER_DESCRIPTOR, *PUHCI_TRANSFER_DESCRIPTOR; + // + // h/w part + // + ULONG LinkPhysical; // TD Link Pointer (link to next TD/QH) + union { // TD Control and Status + struct { + USHORT ActualLength :11; + USHORT Reserved1 :5; + union { // :8 + struct { + UCHAR Reserved2 :1; + UCHAR BitstuffError :1; + UCHAR CRCTimeOutError :1; + UCHAR NAKReceived :1; + UCHAR BabbleDetected :1; + UCHAR DataBufferError :1; + UCHAR Stalled :1; + UCHAR Active :1; + }; + UCHAR TDStatus; + }; + UCHAR InterruptOnComplete :1; + UCHAR IsochronousSelect :1; + UCHAR LowSpeedDevice :1; + UCHAR ErrorCounter :2; + UCHAR ShortPacketDetect :1; + UCHAR Reserved3 :2; + }; + ULONG Status; + }; + + union { // TD Token (Packet Header) + struct { + ULONG Pid :8; + ULONG DeviceAddress :7; + ULONG Endpoint :4; + ULONG DataToggle :1; + ULONG Reserved :1; + ULONG MaximumLength :11; + }; + ULONG Token; + }; + + ULONG BufferPhysical; // TD Buffer Pointer (data buffer pointer for this transaction) + + // + // software part + // + ULONG PhysicalAddress; // physical address of this TD + PVOID NextLogicalDescriptor; + PVOID BufferLogical; // pointer to the logical buffer + PVOID UserBuffer; + +} UHCI_TRANSFER_DESCRIPTOR, *PUHCI_TRANSFER_DESCRIPTOR; + #define TD_NEXT_IS_QH 0x02 // Control and Status @@ -163,20 +205,21 @@ return Length; } -// Represents a Queue Head (QH) -typedef struct _UHCI_QUEUE_HEAD -{ +typedef struct _UHCI_QUEUE_HEAD { // Represents a Queue Head (QH). Must be aligned on a 16-byte boundary + // hardware part - ULONG LinkPhysical; // address - ULONG ElementPhysical; // next descriptor + ULONG LinkPhysical; // address + ULONG ElementPhysical; // next descriptor // Software part - ULONG PhysicalAddress; - PVOID NextLogicalDescriptor; - PVOID Request; - PVOID NextElementDescriptor; -}UHCI_QUEUE_HEAD, *PUHCI_QUEUE_HEAD; + ULONG PhysicalAddress; + PVOID NextLogicalDescriptor; + PVOID Request; + PVOID NextElementDescriptor; + ULONG Padded[2]; +} UHCI_QUEUE_HEAD, *PUHCI_QUEUE_HEAD; + #define QH_TERMINATE 0x01 #define QH_NEXT_IS_QH 0x02 #define QH_LINK_MASK 0xfffffff0 Index: drivers/usb/usbuhci/usb_queue.cpp =================================================================== --- drivers/usb/usbuhci/usb_queue.cpp (revision 70327) +++ drivers/usb/usbuhci/usb_queue.cpp (working copy) @@ -327,7 +327,7 @@ // // descriptor is still active // - DPRINT("Descriptor %p is active Status %x BufferSize %lu\n", Descriptor, Descriptor->Status, Descriptor->BufferSize); + DPRINT("Descriptor %p is active Status %x MaximumLength %lu\n", Descriptor, Descriptor->Status, Descriptor->MaximumLength); return FALSE; } Index: drivers/usb/usbuhci/usb_request.cpp =================================================================== --- drivers/usb/usbuhci/usb_request.cpp (revision 70327) +++ drivers/usb/usbuhci/usb_request.cpp (working copy) @@ -133,6 +133,8 @@ // base PVOID m_Base; + // bMaxPacketSize0 for EndPoint 0 + UCHAR m_MaxPacketSize0; }; //---------------------------------------------------------------------------------------- @@ -155,6 +157,8 @@ IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer) { + USB_DEVICE_DESCRIPTOR DeviceDescriptor; + // // sanity checks // @@ -161,18 +165,25 @@ PC_ASSERT(DmaManager); PC_ASSERT(SetupPacket); + DPRINT("InitializeWithSetupPacket: TransferBufferLength %x, EndpointDescriptor %x\n", TransferBufferLength, EndpointDescriptor); + + Device->GetDeviceDescriptor(&DeviceDescriptor); + // // initialize packet // - m_DmaManager = DmaManager; - m_SetupPacket = SetupPacket; - m_TransferBufferLength = TransferBufferLength; - m_TransferBufferMDL = TransferBuffer; - m_DeviceAddress = Device->GetDeviceAddress(); - m_EndpointDescriptor = EndpointDescriptor; + m_DmaManager = DmaManager; + m_SetupPacket = SetupPacket; + m_TransferBufferLength = TransferBufferLength; + m_TransferBufferMDL = TransferBuffer; + m_DeviceAddress = Device->GetDeviceAddress(); + m_EndpointDescriptor = EndpointDescriptor; m_TotalBytesTransferred = 0; - m_DeviceSpeed = Device->GetSpeed(); + m_DeviceSpeed = Device->GetSpeed(); + m_MaxPacketSize0 = DeviceDescriptor.bMaxPacketSize0; + //DPRINT("InitializeWithSetupPacket: m_MaxPacketSize0 %x\n", m_MaxPacketSize0); + // // Set Length Completed to 0 // @@ -443,10 +454,21 @@ { if (!m_EndpointDescriptor) { - // - // control request - // - return 0; + if (m_DeviceSpeed == UsbLowSpeed) + { + // + // control pipes use 8 bytes packets + // + return 8; + } + else + { + // + // must be full speed + // + ASSERT(m_DeviceSpeed == UsbFullSpeed); + return 64; //FIXME: may be 8,16,32 or 64 //m_MaxPacketSize0 ? + } } ASSERT(m_Irp); @@ -737,7 +759,7 @@ // // store buffer size // - Descriptor->BufferSize = BufferLength; + //Descriptor->BufferSize = BufferLength; // // is there a buffer @@ -747,7 +769,8 @@ // // store buffer length // - Descriptor->Token = (BufferLength - 1) << TD_TOKEN_MAXLEN_SHIFT; + //Descriptor->Token = (BufferLength - 1) << TD_TOKEN_MAXLEN_SHIFT; + Descriptor->MaximumLength = BufferLength - 1; } else { @@ -754,7 +777,8 @@ // // no buffer magic constant // - Descriptor->Token = TD_TOKEN_NULL_DATA; + //Descriptor->Token = TD_TOKEN_NULL_DATA; + Descriptor->MaximumLength = 0x7FF; //FIXME: CONSTANT } // @@ -811,7 +835,7 @@ if (GetDeviceSpeed() == UsbLowSpeed) { // - // low speed use max 8 bytes + // low speed use only max 8 bytes // MaxPacketSize = 8; } @@ -827,9 +851,23 @@ else { // - // use max 64 bytes + // use endpoint0 size // - MaxPacketSize = 64; + if (m_MaxPacketSize0) + { + // + // use bMaxPacketSize0 from USB_DEVICE_DESCRIPTOR + // + MaxPacketSize = m_MaxPacketSize0; + + } + else + { + // + // m_MaxPacketSize0 == 0 (not received USB_DEVICE_DESCRIPTOR) FIXME: may be 8,16,32 or 64 + // + MaxPacketSize = 64; + } } } @@ -983,7 +1021,8 @@ // // free buffer // - m_DmaManager->Release(Descriptor->BufferLogical, Descriptor->BufferSize); + //m_DmaManager->Release(Descriptor->BufferLogical, Descriptor->BufferSize); + m_DmaManager->Release(Descriptor->BufferLogical, Descriptor->MaximumLength + 1); } // @@ -1058,7 +1097,6 @@ return STATUS_SUCCESS; } - NTSTATUS CUSBRequest::BuildControlTransferDescriptor( IN PUHCI_QUEUE_HEAD * OutQueueHead) @@ -1068,6 +1106,7 @@ BOOLEAN Direction; NTSTATUS Status; ULONG ChainDescriptorLength; + UCHAR DataToggle; // // create queue head @@ -1155,7 +1194,7 @@ &FirstDescriptor, &LastDescriptor, &ChainDescriptorLength, - NULL); + &DataToggle); if (!NT_SUCCESS(Status)) { // @@ -1201,6 +1240,7 @@ *OutQueueHead = QueueHead; return STATUS_SUCCESS; } + USB_DEVICE_SPEED CUSBRequest::GetDeviceSpeed() { @@ -1271,29 +1311,44 @@ // DPRINT1("[USBUHCI] Babble detected in descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_BABBLE_DETECTED; + m_NtStatusCode = STATUS_UNSUCCESSFUL; //FIXME best status } else { - // - // stall detected - // - DPRINT1("[USBUHCI] Stall detected Descriptor %p Index %lu\n", Descriptor, Index); - m_UrbStatusCode = USBD_STATUS_STALL_PID; + // + // stall detected + // + DPRINT1("[USBUHCI] Stall detected Descriptor %p Index %lu\n", Descriptor, Index); + m_UrbStatusCode = USBD_STATUS_STALL_PID; + m_NtStatusCode = STATUS_UNSUCCESSFUL; //FIXME best status } } else { // - // FIXME detect actual length + // no errors (TD_ERROR_MASK) // if (Descriptor->UserBuffer) { - // - // copy contents back - // - RtlCopyMemory(Descriptor->UserBuffer, Descriptor->BufferLogical, Descriptor->BufferSize); + if (Descriptor->MaximumLength != Descriptor->ActualLength) + { + // + // if length received data != length requested data + // + DPRINT("FreeEndpointDescriptor: MaximumLength(%x) != ActualLength(%x)\n", Descriptor->MaximumLength, Descriptor->ActualLength); + //FIXME: need call ErrorHandler() ? + } + + if (Descriptor->ActualLength < 0x7FF) //FIXME: CONSTANT + { + // + // copy contents from buffer + // + RtlCopyMemory(Descriptor->UserBuffer, Descriptor->BufferLogical, (Descriptor->ActualLength + 1)); + } } } + // // move to next descriptor // Index: lib/drivers/libusb/hub_controller.cpp =================================================================== --- lib/drivers/libusb/hub_controller.cpp (revision 70327) +++ lib/drivers/libusb/hub_controller.cpp (working copy) @@ -352,6 +352,7 @@ return STATUS_SUCCESS; } + //----------------------------------------------------------------------------------------- NTSTATUS CHubController::GetHubControllerSymbolicLink( @@ -2035,7 +2036,6 @@ return Status; } - //----------------------------------------------------------------------------------------- NTSTATUS CHubController::HandleClearStall( @@ -2097,12 +2097,16 @@ DPRINT1("[%s] URB_FUNCTION_CLEAR_STALL Status %x\n", m_USBType, Status); // + // pause after + // + KeStallExecutionProcessor(2000); //FIXME: select min time + + // // done // return Status; } - //----------------------------------------------------------------------------------------- NTSTATUS CHubController::HandleClassInterface( @@ -2422,6 +2426,7 @@ // return DeviceAddress; } + //----------------------------------------------------------------------------------------- VOID CHubController::ReleaseDeviceAddress( @@ -2454,6 +2459,7 @@ // KeReleaseSpinLock(&m_Lock, OldLevel); } + //----------------------------------------------------------------------------------------- NTSTATUS CHubController::RemoveUsbDevice( @@ -2522,6 +2528,7 @@ // return Status; } + //----------------------------------------------------------------------------------------- BOOLEAN CHubController::ValidateUsbDevice(PUSBDEVICE UsbDevice) @@ -2685,6 +2692,7 @@ // Controller->Release(); } + //================================================================================================= // // USB Hub Interface functions @@ -3940,8 +3948,6 @@ return Status; } - - NTSTATUS NTAPI CreateHubController(