USB Handshake Not Received (EHCI USB 2.0)
Posted: Tue May 17, 2022 2:32 pm
Hello, I was recently working on a USB Driver, I started with EHCI, I've read the entire EHCI Spec from Intel and everything seems to works fine. I have an initial queue head for control transfers (setup on startup before Controller Enabling) with 1 QTD (SETUP_PID "2") . I tested it on qemu and everything works fine.
I Send the SETUP_TOKEN_PACKET and there is no error.
After that, I send the DEVICE_REQUEST with (Request = GET_DESCRIPTOR, ReqType = 0x80, Value = 1 << 8, Length = 0x12).
and also if I try and mess with qemu by setting DEVICE_REQUEST.Value = 0. It gives me this error message "usb_desc_get_descriptor: 0 unknown type 0 (len 18)" Which means that everything works fine.
To now everything is fine, but I do not get a handshake (PID = 0 And all that buffer is 0). here is a code trying to fetch close buffer:
Here is the code for the control transfer :
Here is structures :
I Send the SETUP_TOKEN_PACKET and there is no error.
After that, I send the DEVICE_REQUEST with (Request = GET_DESCRIPTOR, ReqType = 0x80, Value = 1 << 8, Length = 0x12).
and also if I try and mess with qemu by setting DEVICE_REQUEST.Value = 0. It gives me this error message "usb_desc_get_descriptor: 0 unknown type 0 (len 18)" Which means that everything works fine.
To now everything is fine, but I do not get a handshake (PID = 0 And all that buffer is 0). here is a code trying to fetch close buffer:
Code: Select all
USB_HANDSHAKE_PACKET* Handshake = (USB_HANDSHAKE_PACKET*)((UINT64)Transfer->Qtd->BufferPointer0 | ((UINT64)Transfer->Qtd->ExtendedBufferPointer0 << 32));
// Trying to see if the handshake is somewhere on the buffer
SystemDebugPrint(L"SETUP_TOKEN SENT. PID : %x, FIRST : %x SECOND : %x", Handshake->Pid, *(UINT64*)((UINT64)Transfer->Qtd->BufferPointer0 - 8), *(UINT64*)((UINT64)Transfer->Qtd->BufferPointer0));
Code: Select all
int EhciControlDeviceRequest(RFEHCI_ASYNC_TRANSFER Transfer, USB_DEVICE_REQUEST* DeviceRequest, UINT NumBytes /*For Buffer*/, void* Buffer){
Transfer->Qtd->PidCode = EHCI_SETUP;
ZeroMemory(Transfer->Buffer, 0x1000);
Transfer->Qtd->BufferPointer0 &= ~(0xfff);
USB_TOKEN_PACKET* Setup = Transfer->Buffer;
Setup->Pid = USB_PID_SETUP;
Setup->DeviceAddress = 0;
// Setup->SyncField = 1;
Transfer->Qtd->TotalBytesToTransfer = 8;
Transfer->Qtd->Active = 1;
while(Transfer->Qtd->Active);
memcpy((void*)((char*)Transfer->Buffer + 8), DeviceRequest, 8);
Transfer->Qtd->TotalBytesToTransfer = 8;
// Transfer->Qtd->DataToggle = 1;
Transfer->Qtd->Active = 1;
while(Transfer->Qtd->Active);
USB_HANDSHAKE_PACKET* Handshake = (USB_HANDSHAKE_PACKET*)((UINT64)Transfer->Qtd->BufferPointer0 | ((UINT64)Transfer->Qtd->ExtendedBufferPointer0 << 32));
SystemDebugPrint(L"SETUP_TOKEN SENT. PID : %x, FIRST : %x SECOND : %x", Handshake->Pid, *(UINT64*)((UINT64)Transfer->Qtd->BufferPointer0 - 8), *(UINT64*)((UINT64)Transfer->Qtd->BufferPointer0));
while(1);
return 0;
}
Code: Select all
#pragma pack(push, 1)
typedef struct _USB_TOKEN_PACKET{
UINT64 SyncField : 32;
UINT64 Pid : 8; // Packet Id
UINT64 DeviceAddress : 7;
UINT64 Endpoint : 4;
UINT64 CRC5 : 5; // Cyclic Redundancy Check
} USB_TOKEN_PACKET;
typedef struct _USB_DATA_PACKET{
UINT32 SyncField;
UINT8 Pid;
char Data[8]; // [8] Just temporarely
UINT16 CRC16;
UINT16 EOP;
} USB_DATA_PACKET;
typedef struct _USB_HANDSHAKE_PACKET{
UINT64 SyncField : 32;
UINT64 Pid : 8;
} USB_HANDSHAKE_PACKET;
typedef struct _USB_SOF_PACKET{
UINT64 SyncField : 32;
UINT64 Pid : 8;
UINT64 FrameNumber : 11;
UINT64 CRC5 : 5;
} USB_SOF_PACKET;
typedef struct _USB_DEVICE_REQUEST{
unsigned char RequestType;
unsigned char Request;
unsigned short Value;
unsigned short Index;
unsigned short Length;
} USB_DEVICE_REQUEST;
typedef enum _USB_DESCRIPTOR_TYPE{
USB_DESCRIPTOR_TYPE_DEVICE = 1,
USB_DESCRIPTOR_TYPE_CONFIGURATION = 2,
USB_DESCRIPTOR_TYPE_STRING = 3,
USB_DESCRIPTOR_TYPE_INTERFACE = 4,
USB_DESCRIPTOR_TYPE_ENDPOINT = 5,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER = 6,
USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION = 7,
USB_DESCRIPTOR_TYPE_INTERFACE_POWER = 8
} USB_DESCRIPTOR_TYPE;
typedef struct _USB_DEVICE_DESCRIPTOR{
UINT8 Length;
UINT8 DescriptorType;
UINT16 UsbSpecificationReleaseNumber;
UINT8 DeviceClass;
UINT8 DeviceSubclass;
UINT8 DeviceProtocol;
UINT8 Endpoint0MaxPacketSize;
UINT16 VendorId;
UINT16 ProductId;
UINT16 DeviceRelease;
UCHAR Manufacturer; // index of string descriptor
UCHAR Product;
UCHAR SerialNumber;
UINT8 NumConfigurations;
} USB_DEVICE_DESCRIPTOR;
#pragma pack(pop)