Page 1 of 1

Major XHCI Problems

Posted: Wed May 01, 2019 3:42 am
by bellezzasolo
Ive been writing an XHCI driver. This is my first USB host controller driver, so I haven't seperated USB stuff from the host controller stuff, yet. Not that there's much specific USB stuff anyway.
On QEMU, I am able to reset the controller, and get device descriptors and strings.
Capture.jpg
However, on real hardware, I seem to be losing interrupts, causing hangs (when enabling the device slot, or addressing the device). Before refactoring, sometimes I would be able to get a device string from my first device (Logitech USB 1 speakers). However, I then got stall conditions from my keyboard (and every other device), which is a Full Speed USB 2.0 device.
Clearly, I'm doing something wrong, but I cannot figure out what it is.
Update: the lack of interrupt was because I was doing read-modify-write on the CRCR. However, the stall condition remains.
https://github.com/ChaiSoft/ChaiOS/blob ... l/xhci.cpp
This is the log output from QEMU:
QEMU XHCI.txt
(27.9 KiB) Downloaded 48 times

Re: Major XHCI Problems

Posted: Wed May 01, 2019 6:44 pm
by BenLunt
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

Re: Major XHCI Problems

Posted: Thu May 02, 2019 5:19 am
by bellezzasolo
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
FA68D294-6CFA-401C-9742-07C9295C9429.jpeg

Re: Major XHCI Problems

Posted: Thu May 02, 2019 7:51 am
by BenLunt
Hi,
bellezzasolo wrote: Alignment can't be an issue, give that it's page aligned.
Remember that there is a machine page, which probably is 4096 in size, and there is an xHCI page, which might be 4096 bytes in size, but could be different. The xHCI will indicate the size for you.
bellezzasolo wrote: Regarding the speed of my keyboard, HwInfo reports the following on Windows:
USB Version Supported: 2.00
USB Device Speed: USB 1.1 Full-speed
I wouldn't trust this. Windows is probably just indicating that it is of the Low-, Full-speed era of the USB. USB 1.1 had a max speed of Full-speed, so it displays that.

You need to check the port bits at reset. (It has been a while since I have actually done anything with it, I don't remember exactly which bits. I would actually have to look it up.)

Ben

Re: Major XHCI Problems

Posted: Fri May 03, 2019 11:16 am
by bellezzasolo
I've had a dig through what Linux puts out wrt my USB.

Code: Select all

May  3 17:55:49 nathaniel-desktoplin kernel: [    1.383751] xhci_hcd 0000:00:14.0: xHCI Host Controller
May  3 17:55:49 nathaniel-desktoplin kernel: [    1.383753] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 1
May  3 17:55:49 nathaniel-desktoplin kernel: [    1.384822] xhci_hcd 0000:00:14.0: hcc params 0x200077c1 hci version 0x110 quirks 0x0000000000009810
May  3 17:55:49 nathaniel-desktoplin kernel: [    1.384829] xhci_hcd 0000:00:14.0: cache line size of 64 is not supported

May  3 17:55:49 nathaniel-desktoplin kernel: [    1.724050] usb 1-3: new full-speed USB device number 2 using xhci_hcd

May  3 17:55:49 nathaniel-desktoplin kernel: [    1.878006] usb 1-3: New USB device found, idVendor=1130, idProduct=1620, bcdDevice= 1.87
May  3 17:55:49 nathaniel-desktoplin kernel: [    1.878007] usb 1-3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
May  3 17:55:49 nathaniel-desktoplin kernel: [    1.878008] usb 1-3: Product: USB  AUDIO 

May  3 17:55:49 nathaniel-desktoplin kernel: [    2.004052] usb 1-7: new full-speed USB device number 3 using xhci_hcd

May  3 17:55:49 nathaniel-desktoplin kernel: [    2.158641] usb 1-7: New USB device found, idVendor=0518, idProduct=5111, bcdDevice= 2.01
May  3 17:55:49 nathaniel-desktoplin kernel: [    2.158642] usb 1-7: New USB device strings: Mfr=1, Product=2, SerialNumber=0
May  3 17:55:49 nathaniel-desktoplin kernel: [    2.158642] usb 1-7: Product: USB Gaming Keyboard
May  3 17:55:49 nathaniel-desktoplin kernel: [    2.158643] usb 1-7: Manufacturer: E-Signal

May  3 17:55:49 nathaniel-desktoplin kernel: [    2.288149] usb 1-8: new full-speed USB device number 4 using xhci_hcd

May  3 17:55:49 nathaniel-desktoplin kernel: [    3.086150] usb 1-8: New USB device found, idVendor=04d9, idProduct=a0d6, bcdDevice= 1.05
May  3 17:55:49 nathaniel-desktoplin kernel: [    3.086150] usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=0
May  3 17:55:49 nathaniel-desktoplin kernel: [    3.086151] usb 1-8: Product: USB Gaming Mouse
May  3 17:55:49 nathaniel-desktoplin kernel: [    3.086152] usb 1-8: Manufacturer: E-Signal/A-One
The quirks are:
XHCI_SPURIOUS_SUCCESS, XHCI_LPM_SUPPORT, XHCI_INTEL_HOST, XHCI_AVOID_BEI

So it looks like I'm reading the full speed correctly. My full speed packet size code works for the speakers (setting a default of 64 leads to a babble condition, 8 does not, and then I update the context). It seems to fall down with the keyboard though.