BenLunt wrote:Hi guys,
Sorry I haven't been around this forum too much lately. I have been quite busy with other things as well as a new job.
As for the xHCI, make sure that your Slot and EP contexts are properly aligned and formatted. I have found that even a slight irregularity in the EP context will make a device stall.
Also, is your keyboard really a full-speed device? That would surprise me. A mouse and a keyboard should be a low-speed device. Make sure you have indicated this correctly in the Slot and EP context data. This will make a difference in the xHCI's bandwidth calculations.
Sorry I don't have much more time to help you with this. Hopefully things start to slow down a bit and I can come back to this forum more frequently.
Ben
-
http://www.fysnet.net/the_universal_serial_bus.htm
Here's my Input Context initialization (I've created a struct with bitfileds for debugging):
Code: Select all
bool createSlotContext(size_t portspeed, xhci_port_info* pinfo)
{
//Allocate input context
paddr_t incontext = pmmngr_allocate(1);
volatile input_context* mapincontxt = (input_context*)find_free_paging(PAGESIZE);
paging_map((void*)mapincontxt, incontext, PAGESIZE, PAGE_ATTRIBUTE_WRITABLE | PAGE_ATTRIBUTE_NO_CACHING);
memset((void*)mapincontxt, 0, PAGESIZE);
//Set input control context
mapincontxt->AddContext = 3;
//Setup slot context
mapincontxt->SlotContext.rootHubPort = pinfo->portindex;
mapincontxt->SlotContext.routeString = 0;
mapincontxt->SlotContext.ContextEntries = 1;
mapincontxt->SlotContext.speed = portspeed;
//Initialise endpoint 0 context
//Control endpoint, CErr = 3
mapincontxt->EndpointContexts[0].MaxPacketSize = max_packet_size(portSpeed(portspeed));
mapincontxt->EndpointContexts[0].EPType = 4; //Control
mapincontxt->EndpointContexts[0].TRDequeuePtr = pinfo->cmdring.getBaseAddress() | 1;
mapincontxt->EndpointContexts[0].Cerr = 3;
mapincontxt->EndpointContexts[0].AvgTRBLength = 8;
mapincontxt->EndpointContexts[0].MaxBurstSize = 0;
mapincontxt->EndpointContexts[0].MaxESITPayloadLow = mapincontxt->EndpointContexts[0].MaxPacketSize * (mapincontxt->EndpointContexts[0].MaxBurstSize + 1);
//Allocate device context
paddr_t dctxt = pmmngr_allocate(1);
void* mapdctxt = find_free_paging(PAGESIZE);
paging_map(mapdctxt, dctxt, PAGESIZE, PAGE_ATTRIBUTE_WRITABLE | PAGE_ATTRIBUTE_NO_CACHING);
memset(mapdctxt, 0, PAGESIZE);
//Write to device context array slot
*raw_offset<volatile uint64_t*>(devctxt, pinfo->slotid * 8) = dctxt;
//Issue address device command
void* last_command = cmdring.enqueue(create_address_command(true, incontext, pinfo->slotid));
uint64_t* curevt = (uint64_t*)waitComplete(last_command, 1000);
if (get_trb_completion_code(curevt) != XHCI_COMPLETION_SUCCESS)
{
kprintf(u"Error addressing device\n");
return false;
}
pinfo->device_context = mapdctxt;
//If the device is full speed, we need to work out the correct packet size
if (portSpeed(portspeed) == FULL_SPEED)
{
//kprintf(u"Full speed device, calculating packet size\n");
if (!update_packet_size_fs(pinfo))
return false;
}
last_command = cmdring.enqueue(create_address_command(false, incontext, pinfo->slotid));
curevt = (uint64_t*)waitComplete(last_command, 1000);
if (get_trb_completion_code(curevt) != XHCI_COMPLETION_SUCCESS)
{
kprintf(u"Error addressing device\n");
return false;
}
return true;
}
Alignment can't be an issue, give that it's page aligned. Regarding the speed of my keyboard, HwInfo reports the following on Windows:
Device Manufacturer: E-Signal
Product Name: USB Gaming Keyboard
Serial Number: N/A
USB Version Supported: 2.00
USB Device Speed: USB 1.1 Full-speed
Driver Description: USB Composite Device
Hardware ID: USB\VID_0518&PID_5111