I have 12 USB 2.0 devices plugged into an Intel NUC D54250WYK running Ubuntu 14.04.
Running lshw -short shows two different USB buses and two host controllers (xHCI and eHCI).
All of the USB devices appear on the same bus and use xHCI regardless of the ports they are plugged into. As a result I'm seeing the following errors in dmsg:
Not enough host controller resources for new device state.
Not enough bandwidth for altsetting 0.
Is there a way to force devices to a specific bus?
I've also read that Linux can have problems with xHCI. Is there a way to force eHCI without recompiling the kernal? Intel does not provide that option in BIOS.
Last I checked on this, you're in a bit of a bind. It seems xHCI is compiled into the kernel, not as a module, and if you compile in eHCI/aHCI/oHCI and not xHCI, USB as a whole breaks, possibly due to some built-in support for on-board USB controlled BlueTooth and WIFI devices on certain mobos. DO NOT UPDATE YOUR BIOS yet... see if the option to disable xHCI still exists on yours.
At this time, it seems your best option is to disable xHCI in your BIOS. This will likely disable all USB3 controllers, but allow USB2 controllers to work without this issue impeding you.
With respect to the Intel device you described, I don't see many USB ports on it, so I assume you're using hubs. From the tech specs for your device, it looks like you'll have to get access to the internal header to get at the USB2 ports.
Good news for anyone else facing this issue. Intel released a new bios (v40) that adds back the option to disables xHCI. In my case I updated the bios, disabled xHCI, and everything works as expected.
Beware of platforms that have XHCI ONLY (Apollolake, Denverton).
You will brick your HW if you disable XHCI there.
Related
We have an embedded board that has an iMX8M-Plus Processor and Linux v5.4.161. This board has one PCIe bus and that one is connected to an FPGA. When we power up the board, the FPGA is not yet configured, so it acts as if it was not on the PCIe bus.
Once the Linux is fully booted, we configure the FPGA and only after that it starts acting as a PCIe endpoint (device).
At this point, when I run lspci -> it returns nothing.
When I first execute echo "1" > /sys/bus/pci/rescan as suggested here and here and then lspci, I still get nothing.
But if I reboot the linux without reseting the FPGA, it starts being visible in the lspci list. Rebooting the linux is not an option for us. Somehow I need to tell the linux that whatever it's doing at the boot time, please do it again at runtime. But I couldn't find a solution for this so far.
According to the Texas Instrument support forum, they said if the PCIe link is not trained at the boot time, rescan command never works.
At the boot time, while linux loads a pci driver, it tries to establish a PCIe link, I can see that with an oscilloscope, PERST pin is asserted and PCIE_CLK generated for a while and then stops if it can not detect any device. But the rescan command never does that.
Also in the system there is no pcie device to executeecho 1 > $pcidevice/remove in order to make rescan functional. Or there is no device or bus to set power off and on back like echo 0 > /sys/bus/pci/slots/.../power
I also learned that there was a method in old linux times (v2.6) called adding a Fake PCIe Device which physically doesn't exist to solve this problem. For that I took the fakephp.c driver from an old linux repo and ported it to ours. After solving a couple of deprecated function problems, it is compiled for Linux Kernel v5.4. modprobe fakephp worked and driver loaded but somehow I didn't get this fake device in my device list. Here it is mentioned that the fakephp driver was removed from mainstream linux since PCI core has similar functionality, but he never mentioned how.
Short of the story is that, I am stuck here, I need my FPGA to be visible in the lspci list without restarting the linux.
I recommend configuring the FPGA in u-boot to get away from these kinds of problems. Connect up SPI pins to FPGA's config pins & run it in Slave configuration mode.
I'm investigating options available for creating a virtual USB device (say, a keyboard or a mass storage device), so to emulate its function as needed and to allow a userspace app to emulate its insertion/removal at will.
What I am not clear about is how to go about the emulation of insertion/removal. It seems that one option is to emulate a (virtual) USB hub and have it fake the device arrival/departure events (and I would also supply the device driver for my virtual USB device and that's where my device logic will reside).
I know my way around Windows kernel (having written NDIS miniport drivers), not afraid of SoftICE, but USB is not my domain, just starting out with it.
Am I on the right track with the virtual hub approach? If so, is developing virtual hub drivers supported by WDK (it doesn't seem to be)?
Any other options?
--
(Edit) Forgot to mention - I am aware of DSF, but it is not supported on W8.
Am I on the right track with the virtual hub approach?
In short - yes, I was right.
That's how USBIP does it and it's a relatively simple way to go. Also, see this comment by Eugen.
I don't know if you are aware, but Microsoft released to Win10 the UDE (USB device emulation).
In the section Write a UDE client driver they describe exactly what you want.
I need to set up USB communication between a Windows 7 host and a Linux device for data transfer. I was able to compile the Linux kernel on the device to include the Gadget Zero driver in the kernel (not as a loadable module - Linux version 3.0.15). My project has some requirements, which also explains why I chose Gadget Zero:
1) On the Windows 7 host, a kernel mode driver must be used to communicate over the USB connection for sending and receiving bulk data. (speed is not important, not a lot of data at once).
2) On the linux device, no requirements on USB side except send and receive data easily over USB link. The data received will eventually be "unmarshalled" to call functions in another kernel module (and those responses packaged and sent back to the host).
3) Multiple linux devices will be connected to the host, so need easy way to enumerate connected devices and communicate with them.
So due to the requirements, I decided against the Gadget Serial. I'm having serious issues sending and receiving data over the virtual COM port in kernel mode (KMDF) in Win 7 host. WinUSB does not seem to want to open my attached device (I'm using KMDF windows USB driver from template in VS2012) Also, the gadget serial driver on the linux side, I cannot find the functions where the data is received and sent. Plus, any received data on the linux device seems to be echoed back to the host for some reason. (and to test this, I wrote a simple user-mode app in Windows, which is a no-no for my project).
Gadget Zero, it appears much simpler on the linux side. I can plug the USB cable to the Win7 host, and I can get the device to appear in the device manager. However, again I am having problems with getting communication going over the link. Gadget Zero has 2 bulk endpoints, so this shouldn't be an issue. Surely, someone has made data communication possible between a Windows host and a linux device using Gadget Zero? With Gadget Zero, it should be easy to enumerate the connected linux devices and communicate with them.
The trick is to keep the Windows side communication in kernel mode. Can someone point me in the right direction perhaps with Gadget Zero, Windows 7 KMDF, and some sample source code? I have a hard time believing no one has done this before because my internet searches don't turn up much. (and mostly user-mode solutions with Gadget Serial).
Thanks!
So you're writing a Win32 driver in which you want to communicate with your linuxed usb? I haven't written much win32 kernel code, but I believe I've seen a huge section in the doc, saying something like "This is how you make usb drivers"... That'd be it. In other words, when in kernel mode you have access to the full kernel usb layer. You don't need an existing driver or whatnot.
On the linux side you can use the serial gadget, in a different run mode. Only the default run mode, registers it self as VCP. There exist a more basic mode:
modprobe g_serial use_acm=0
Give it your own vendor id and you'll be able to attach your very own custom win32 driver. The 'multiple linux devices' will be handled by Windows. (Multiple instances of your driver, will be initiated.)
The echo you're seeing btw, is most likely a terminal feature. (The terminal mode on uarts will echo.) You have to disable it, when connecting. And now that you're at it, you also have to disable the xon/xoff, esc chars etc. (Standard legacy rubbish.)
And another thing. I'm not sure the gadget zero actually sends the data onto the line. It's meant for testing the gadget framework. (I could be mistaken though.)
Anyway, you've prolly solved this issue years ago. I'd be nice to know what you came up with.
I'm looking to fuzz virtual drivers, I've read the other questions about this but they don't really go anywhere. Basically looking to see if there's an obvious tool I've missed and want to know if fuzzing IOCTLs from a windows guest would work? Or if I need to write one in low level eg IN/OUT?
Any tools out there for fuzzing drivers in a windows guest to hit the hypervisor either hyper-v or VMware
There are a number of ways to exercise virtualization code.
First, of course, if you're on Windows, is the IOCTL interface.
Then you should remember that all virtual devices are emulated in some way by some code in the guest OS and in the host OS. So, accessing input devices (keyboard and mouse), video device, storage (disks), network card, communication ports (serial, parallel), standard PC devices (PIC, PIT, RTC, DMA), CPU APIC, etc etc will also exercise virtualization code.
It's also very important to remember that virtualization of the various PC devices (unless we're talking about synthetic devices working over the VMBUS in Windows) is done by intercepting, parsing and emulating/executing instructions that access device memory-mapped buffers and registers and I/O ports. This gives you yet another "interface" to pound on.
By using it you might uncover not only device-related bugs but also instruction-related bugs. If you're interested in the latter, you need to have a good understanding of how the x86 CPU works at the instruction level in various modes (real, virtual 8086, protected, 64-bit), how it handles interrupts and exceptions and you'll also need to know how to access those PC devices (how and at what memory addresses and I/O port numbers).
Btw, Windows won't let you directly access these things unless your code is running in the kernel. You may want to have a non-Windows guest VM for things like this just to avoid overprotective functionality of Windows. Look for edge cases, unusual instruction encodings (including invalid encodings) or unusual instructions for usual tasks (e.g. using FPU/MMX/SSE/etc or special protected-mode instructions (like SIDT) to access devices). Think and be naughty.
Another thing to consider is race conditions and computational or I/O load. You may have some luck exploring in that direction too.
From time to time, I need to dump USB traffic under Windows, mostly to support hardware under Linux, so my primary goal is to produce dump files for protocol analysis.
For USB traffic, it seems that SniffUsb is the clear winner... It works under Windows XP (but not later) and has a much nicer GUI than earlier versions. It produces huge dump files, but everything is there.
However, my device is in fact a USB serial device, so I turned to Portmon which can sniff serial port traffic without the USB overhead.
After five years waiting, now it's possible to sniff usb packets on windows
See http://desowin.org/usbpcap/tour.html for a quick tour. It works pretty well
Since people don't seem to realize it, Wireshark does monitor USB traffic and has a parser for it; but the catch is it only works under Linux. Wireshark on Windows will not do this.
It may be possible to plug the USB device you want to monitor, along with a Linux machine (with Wireshark running) and your Windows machine and just use the USB device under Windows.
Problem with the above? I don't know how the Linux machine or the Windows machine will detect each other.
Busdog, an open source project hosted on github, has worked well for me. It has a driver it installs to allow it to monitor USB communications. The config window allows you to reinstall or remove the device at any time.
You can select the USB device you want from an enumerated list. A nice feature is to have it automatically trace a new device that is plugged in:
Data communications to and from an SWR analyzer I was reverse engineering were captured flawlessly:
USBSnoop works too - and is free.
Or, you could buy a USB to Ethernet converter and use whatever network sniffer you prefer to see the data.
Personally, I'd use QEMU or KVM and instrument their USB passthrough code, and then use libusb to prototype the replacement driver in user space (this latter bit I've done before; writing USB device drivers in Python is fun!).
Microsoft Message Analyzer was able to capture USB traffic, with Device and Log File parser from MS: link
Update: as mentioned by #facetus, MS Message Analyzer has been retired on November 25 2019.