I have two USB devices (host and device) that both support high speed. I am trying to emulate a legacy device on gadgetfs which is full speed. The host device unfortunately complains that there is something odd when it connects to the high speed device. I cannot change anything on the host. my device is a Raspberry Pi zero W.
I can not find any way to restrict the gadgetfs device to connect (negotiate?) as a full speed device. Short term I am using a usb 1.1 hub to sovle the problem. Long term this is not a viable solution.
The only reference I have found for this is in Limit USB gadget driver speed, and I would prefer not to have go into the kernel and modify the drivers.
Does anyone have any suggestion on how I could achieve this?
Related
I want to learn how Linux OS understands the underlying hardware.Can anyone suggest me where to start for getting this understanding,As of now i just know the '/dev' sub-directory plays a vital role in that.
It has the device special files which are like a portal to the device driver which then takes it to the physical device.
I read somewhere that Udev daemon listens to the netlink socket to collect this information and Udev device manager detects addition and removal of devices as they occur.
But with these i am just not satisfied with the thought of how Linux reads the hardware.
Please let me know where to start to understand this, i am so thankful to anyone trying to help.
I think at first you need to find out how the memory mapping works. What is the address space and how it relates to physical memory. Then you could read about how the hardware is mapped in address space and how to access it. It is a big amount of docs to read.
Some of those information are in Linux Documentation Project.
Additionally some knowledge about electronic would be helpful.
In general - Linux for communication with devices needs some "channel" of communication. This channel may be for example ISA, PCI, USB, etc bus. For example PCI devices are memory mapped devices and Linux kernel communicates with them via memory accesses. So first Linux needs to see given device in some memory area and then it is able to configure this device and do some communication with it.
In case of USB devices it is a little bit complicated because USB devices are not memory mapped. You need to configure USB host first to be able to communicate with USB devices. Every communication with USB device is achieved via USB host.
There are also devices which are not connected via ISA, PCI or USB. They are connected directly to the processor and visible under some memory address. This solution is usually implemented in embedded devices. For example ARM processors use this approach.
Regarding udev - it is user-space application which listens for events from Linux kernel and helps other applications with recognizing device addition and configuration.
I'm trying to find a way to send/receive data through USB port of an ARM processor on a zynq board (ZC706) running petalinux.
I searched on the net and I'm totally confused where to begin. I found solutions but those did not consider USB to be connected to ARM processor, high-speed data transfer or petalinux.
I know how to write simple linux kernel codes and I know how to work with zynq board.
To be specific, I want to know how to write a piece of code, better to say a library of functions, in petalinux to read and write to usb port connected to ARM as high-speed as possible.
Seems like you are trying to do some quite sophisticated thing.
First I would like to say that USB is not some kind of port which you can read data "byte after byte" like in case of serial or parallel ports.
I would recommend you to start with reading about USB 2.0 and EHCI documentation (it take some time). Additionally you need to know what kind of USB is your board - is it host or device USB type? In case of usb device type - probably you need to write your own driver for this board and connect it to some USB host (PC for example). Then you need to create some communication protocol over USB. Luckily on the PC side you would use the libusb library for this. I mean you need to write program which uses libusb library for communication with your board.
Quite a lot of work to do.
I've got usb cable plugged to my computer, which D+ and D- pins are connected to multimeter. I want to send some raw bytes to get some voltage.. is it possible at all?
I'm 99% sure that usb port I've plugged cable in is something like /dev/bus/usb/002
I know that there was possibility to do the same with LPT or RS232 ports.
RS232 and LPT are not bus ! USB devices need to be addressed in order to become reachable.
Maybe unloading and reloading usb driver that drive your usb host... or trying to make a reset on usb hub host...
For doing this kind of operation on usb port, you have to break usb kernel driver and whipe all addressing operation to address directly the chipset...
At all, due to USB concept, I'm not sure you may successfully hold some power state on outlet.
For playing with that kind of physical IO, two solution:
Install a low-cost RS-232 <-> USB adapter
or better
Buy an Arduino micro-controller for prototyping and development.
I'm nearly 100% sure that you can't send anything down your USB lead unless you actually have a device at the other end. If you still want to play with this, get a cheap memory stick, break the casing off it [not too roughly], and measure whilst doing a large file-transfer to the memory stick, or some such.
But I'm not sure your multimeter will show much, as they tend to be a bit slow, compared to USB rates.
USB uses pull-up / pull-down resistors on the data lines to detect whether or not a port is connected (1.5k pull-up to 3.3v on the device side, 15k pull-down on the host side IIRC). The exact connection depends on the device speed.
So if you connect an appropriate resistor, the host should attempt to start signalling. Because of the data-rate, you might not be able to see that on a multimeter; an oscilloscope would be more appropriate.
If you want to by-pass the normal USB protocol and just blindly send data, I think you'll need to get your hands dirty and write code to bypass the usual device drivers and access the USB hardware directly. Even then I'm not sure what's possible - the USB hardware is a lot smarter than good ol' LPT and RS232 ports, which might get in the way of doing this sort of low level stuff.
tl;dr: How do I compel Linux to reject high-speed USB connections so that it defaults to full speed?
Full explanation:
I'm writing a USB gadget driver based on Linux gadget zero. The hardware I'm testing on has high speed capable USB which won't be the case of the actual product. For some reason, the gadget (although it has no high speed descriptors on any configuration) is being reported as a high speed gadget
(struct usb_gadget->speed==USB_SPEED_HIGH on set_config function of composite gadget).
This makes the driver fail miserably just before configuration bind (trying to load a high speed configuration that obviously doesn’t exist).
I'm looking for a way to inform Linux that the gadget is not high speed capable so that when a host connects the switch from fullspeed to highspeed is denied (or something that would produce a similar results).
uhci and ohci kernel modules drive USB 1.X controllers.
ehci modules drives USB 2.0 controller.
If you unload one of these, you enforce a restriction to the other.
enum usb_device_speed speed;
enum usb_device_speed max_speed;
you can setup usb_composite_driver
I have two legacy machines connected to a Linux box with USB using the ftdi_sio driver, to /dev/ttyUSB0 and /dev/ttyUSB1. The Linux box is relaying and analyzing the traffic between the machines. When the Linux box boots up, the machines are connected to the files pretty much randomly. The problem is to know which one is which.
I could just ask the devices, of course, but I'd like to avoid the risk of malfunction due to sending wrong data to the wrong device. Is there a way to figure out, for example, the id of the device connected to a tty file?
Check this Using Linux USB page.
/proc/bus/usb/devices lists information about the devices currently attached to the USB bus. This is very useful when trying to figure out if the device is correctly enumerated.
Maybe you can use the output from lsusb -v and look at iProduct + iSerial to determine the order the devices are attached.