Index: drivers/usb/usbhub/fdo.c =================================================================== --- drivers/usb/usbhub/fdo.c (revision 70327) +++ drivers/usb/usbhub/fdo.c (working copy) @@ -12,7 +12,7 @@ #include -#define NDEBUG +//#define NDEBUG #include NTSTATUS @@ -669,6 +669,8 @@ return STATUS_INSUFFICIENT_RESOURCES; } + RtlZeroMemory(StringDesc, sizeof(USB_STRING_DESCRIPTOR)); + // // Get the index string descriptor length // FIXME: Implement LangIds @@ -1049,7 +1051,7 @@ UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR); ExFreePool(SerialBuffer); - DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount); + DPRINT("usInstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount); return Status; } } @@ -1073,7 +1075,7 @@ RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR)); UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR); - DPRINT("usDeviceId %wZ\n", &UsbChildExtension->usInstanceId); + DPRINT("usInstanceId %wZ\n", &UsbChildExtension->usInstanceId); return STATUS_SUCCESS; } @@ -1883,7 +1885,7 @@ } // init root hub notification - if (HubDeviceExtension->HubInterface.RootHubInitNotification) + if (0)//HubDeviceExtension->HubInterface.RootHubInitNotification) { Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext, DeviceObject, Index: drivers/usb/usbhub/pdo.c =================================================================== --- drivers/usb/usbhub/pdo.c (revision 70327) +++ drivers/usb/usbhub/pdo.c (working copy) @@ -13,7 +13,7 @@ #include -#define NDEBUG +//#define NDEBUG #include #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003) @@ -291,8 +291,17 @@ case URB_FUNCTION_VENDOR_DEVICE: DPRINT("URB_FUNCTION_VENDOR_DEVICE\n"); break; + case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: + DPRINT("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n"); + break; + case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT: //0x24 + DPRINT("URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT\n"); + break; + case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE: //0x28 + DPRINT("URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n"); + break; default: - DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function); + DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Unknown Function %x\n", Urb->UrbHeader.Function); break; } Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle; Index: drivers/usb/usbuhci/hardware.cpp =================================================================== --- drivers/usb/usbuhci/hardware.cpp (revision 70327) +++ drivers/usb/usbuhci/hardware.cpp (working copy) @@ -10,7 +10,7 @@ #include "usbuhci.h" -#define NDEBUG +//#define NDEBUG #include typedef VOID __stdcall HD_INIT_CALLBACK(IN PVOID CallBackContext); 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) @@ -10,7 +10,7 @@ #include "usbuhci.h" -#define NDEBUG +//#define NDEBUG #include class CUSBQueue : public IUHCIQueue @@ -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) @@ -10,7 +10,7 @@ #include "usbuhci.h" -#define NDEBUG +//#define NDEBUG #include class CUSBRequest : public IUHCIRequest @@ -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,6 +165,10 @@ PC_ASSERT(DmaManager); PC_ASSERT(SetupPacket); + DPRINT("InitializeWithSetupPacket: TransferBufferLength %x, EndpointDescriptor %x\n", TransferBufferLength, EndpointDescriptor); + + Device->GetDeviceDescriptor(&DeviceDescriptor); + // // initialize packet // @@ -172,6 +180,7 @@ m_EndpointDescriptor = EndpointDescriptor; m_TotalBytesTransferred = 0; m_DeviceSpeed = Device->GetSpeed(); + m_MaxPacketSize0 = DeviceDescriptor.bMaxPacketSize0; // // Set Length Completed to 0 @@ -443,10 +452,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); @@ -735,11 +755,6 @@ } // - // store buffer size - // - Descriptor->BufferSize = BufferLength; - - // // is there a buffer // if(BufferLength) @@ -747,7 +762,7 @@ // // store buffer length // - Descriptor->Token = (BufferLength - 1) << TD_TOKEN_MAXLEN_SHIFT; + Descriptor->MaximumLength = BufferLength - 1; } else { @@ -754,7 +769,7 @@ // // no buffer magic constant // - Descriptor->Token = TD_TOKEN_NULL_DATA; + Descriptor->MaximumLength = 0x7FF; //FIXME: CONSTANT } // @@ -811,7 +826,7 @@ if (GetDeviceSpeed() == UsbLowSpeed) { // - // low speed use max 8 bytes + // low speed use only max 8 bytes // MaxPacketSize = 8; } @@ -827,9 +842,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 +1012,7 @@ // // free buffer // - m_DmaManager->Release(Descriptor->BufferLogical, Descriptor->BufferSize); + m_DmaManager->Release(Descriptor->BufferLogical, Descriptor->MaximumLength + 1); } // @@ -1058,7 +1087,6 @@ return STATUS_SUCCESS; } - NTSTATUS CUSBRequest::BuildControlTransferDescriptor( IN PUHCI_QUEUE_HEAD * OutQueueHead) @@ -1068,6 +1096,7 @@ BOOLEAN Direction; NTSTATUS Status; ULONG ChainDescriptorLength; + UCHAR DataToggle; // // create queue head @@ -1155,7 +1184,7 @@ &FirstDescriptor, &LastDescriptor, &ChainDescriptorLength, - NULL); + &DataToggle); if (!NT_SUCCESS(Status)) { // @@ -1271,29 +1300,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) @@ -10,7 +10,7 @@ #include "libusb.h" -#define NDEBUG +//#define NDEBUG #include VOID NTAPI StatusChangeEndpointCallBack( @@ -2097,6 +2097,11 @@ DPRINT1("[%s] URB_FUNCTION_CLEAR_STALL Status %x\n", m_USBType, Status); // + // pause after + // + KeStallExecutionProcessor(2000); //FIXME: select min time + + // // done // return Status; Index: lib/drivers/libusb/usb_device.cpp =================================================================== --- lib/drivers/libusb/usb_device.cpp (revision 70327) +++ lib/drivers/libusb/usb_device.cpp (working copy) @@ -10,7 +10,7 @@ #include "libusb.h" -#define NDEBUG +//#define NDEBUG #include class CUSBDevice : public IUSBDevice