Sequence of events when a hardware is connected to Linux Kernel - linux-kernel

Can anybody tell me sequence of common events when a hardware (Let's say USB stick or Keyboard) is connected to a machine running Linux kernel ? Actually i am new to Device Driver field and i want to know what are the common events when a hardware is connected. Any link or resource will be helpful.

Related

How is /proc/io* populated?

So if I understand things correctly, cat /proc/iomem lists the memory addresses that are mapped to this and that device register and similarily for ioports. If you pick up some book on Linux device drivers, it will state something about iomem being populated by the driver calling request_region() or something like that.
But how does the device driver know where the hardware register is located at from the get-go? For example, rtc0 seems to occupy 0070:0071 for most people - how does Linux/the device driver know that the transistors and wires of my system are hooked up so that flipping exactly those bits corresponds to reading a signal from the RTC?
If you pick up some book on Linux device drivers, it will state something about iomem being populated by the driver calling request_region() or something like that.
The information in /proc/iomem comes from drivers calling request_mem_region().
See Content of /proc/iomem.
how does the device driver know where the hardware register is located
The address of a device register is typically specified by either the board (for an external peripheral) or SoC designer (for an integrated peripheral), and then conveyed in the board or SoC documentation. Some boards (e.g. PC ISA adapter boards) may allow address specification by some DIP switches.
The writer of the device driver then can
(a) hardcode the device address in the driver itself or a board file, or
(b) retrieve the device address using some bus configuration method (e.g. PCI configuration space), or
(c) retrieve the device address using a (handwritten) configuration list (e.g. Device Tree, FEX, ATAGs), or
(d) try to probe the device at runtime.
Note that conveying the system configuration and device addresses to device drivers is a longstanding issue.
The IBM PC's method of assigned addresses that were then hardcoded eventually led to the plug and play initiative for x86 PCs.
Issues with unique Linux kernel builds for each and every ARM board led to the adoption of Device Tree (from PowerPC) for that architecture.

Keeping device functionality inside device controller rather than OS kernel. What are consequences?

A friend of mine asked me this question in the class and I could not answer it. He asked:
Since we know kernel controls the physical hardware via device drivers. What if all this functionality is kept inside the device controller itself rather than kernel managing them. What would be the consequences of such scenario? Good or Bad?
I searched online for this question but could not get information about this scenario. May be I'm not googling in the right keyword.
You insight into this will help me getting clearing my concepts.
Please answer.
Thanks.
Your question seems to propose the elimination of the "device driver" by "keeping" "control (of) the physical hardware ... inside the device controller". The premise for this seems to be:
kernel controls the physical hardware via device drivers.
That description of a device driver is something similar to what I've seem for end-user comprehension rather than from a developer's perspective. The end-user is aware of the device, and it is the device driver that takes that abstraction and can control that device down to the specific control bits of each device port.
But a device driver is responsible for mundane housekeeping tasks such as:
maintaining device status and availability;
configuring the device for operation;
managing data flow, setting-up/tearing-down data transfers, copying data between user space and kernel space;
handling interrupts and exceptions.
These tasks are integral to a device driver. These tasks cannot be transferred out of the purview of the kernel driver to a peripheral device.
Sometimes the device driver can only try to manage the device, rather than fully control it, for example, a NIC driver during a packet flood.
There is simply no possibility that you can eliminate a device driver no matter how much of "all this functionality is kept inside the device controller itself". And there would still be control directives/commands issued from the device driver to the peripheral.
The hardware device in question should be a computer peripheral device, not an autonomous robot device. The device should be designed to operate with a computer. Whatever interface there is between processor and device should be suitable for the task. If the peripheral is made more "intelligent", then perhaps the CPU can be unburdened and a high-level command interface can replace low-level sub-operation directives. But only "some" functionality can be transferred to the peripheral, not "all".

USB linux gadget zero driver communicate with Windows host

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.

How do I reset USB devices using the Windows API?

Do you know a way to use the Windows XP API to reset the USB bus? In other words, I'd like the OS to kick out any USB devices that are currently connected, and then auto-detect everything anew.
I'm aware of devcon, and I suppose I could do system calls out to it, but I'm hoping for a direct call into the API.
From kernel mode: You can force a specific USB device to be re-connected, as if it was unplugged and replugged again, by sending an IOCTL_INTERNAL_USB_CYCLE_PORT to its PDO. (This can only be done from a kernel mode, e.g. through a helper driver.) This 'cycle' operation will cause a USB reset to occur, after which the device would be re-enumerated. For example, if the device comes back with a different USB device descriptor, a different driver may be matched for it.
From user mode: You can do this by ejecting the device through the CfgMgr API. For example, to go over all USB hubs and eject all devices:
Find all devices having device interface GUID_DEVINTERFACE_USB_HUB with SetupDiGetClassDevs(... DIGCF_DEVICEINTERFACE).
Enumerate over the returned device information set (SetupDiEnumDeviceInfo).
For each device, get the DevInst member:
Invoke CM_Get_Child(DevInst) and then CM_Get_Sibling repeatedly to go over all child nodes of the hub (i.e. the USB devices).
For each child node, call CM_Request_Device_Eject.
Well, use can use the Setup API (SetupDiXXX functions) to enumerate the USB devices in the system, and then call WinUsb_ResetPipe on each one, but I'm not sure if that's what you're looking for. It's been a while since I worked with USB devices, but as I recall, there is no standard way to reset a device (i.e. simulate a power off/power on cycle). If it's possible for a particular device, you'd have to send an appropriate IOCTL (using DeviceIOControl) to the driver. The IOCTL would vary from manufacturer to manufacturer.
It's possible to cycle the parent port on the USB hub the device is attached to, as well. This will result in, among other things, apparrent unplug/replug actions, as you will see a balloon popup when this occurs.
Much of this is poorly documented, and honestly, I've gotten the impression there are only a handful of people at Microsoft who really understand it well. The design decision I've made for future devices I design is that I intend to include watchdog functionality on both sides, as well as a device-side full reset function. That way, if the device figures out it is confused, it can just cut its own power for a second and fully reset, if the host can't communicate with it, it could do the same thing, and if the device thinks everything is fine but the host knows better, the host could order it to reset.
There are at least three APIs worth looking into for this problem: the Setup API, the Config Manager API, and various WMI extensions. However, be cautious about diving into WMI if you intend to use an Embedded XP target, as you will have to include a lot of other things in your OS image you might otherwise not need.
As far as I know, there is no way to do this - you can issue a command to have PnP rescan the bus for new devices, but that isn't the same as issuing a bus reset.
Furthermore, just because from a hardware perspective you issued a bus reset doesn't mean that Windows will remove the PDOs that represent the children of the hub and redetect them; the USB bus driver can (and does) do just what I describe (i.e. issue hardware bus resets without disturbing the device tree), and only after the device doesn't respond does it issue the surprise removal and yank it from the tree.

USB Debugging

I'm looking for a very specific USB device for debugging systems that may use USB but not with a regular computer (proprietary hardware). I want a device that has a USB host controller and two USB device connections. The device to be debugged is connected to the USB host controller and one of the device connections is connected to another device with it's own host controller on it. The the other device connection is connected to a pc. The point being that all USB data travelling through the device (from the device connected to the host controller to the device connected to the first device connection) is reported to the pc.
I'll happily write software to do the logging (in fact I want to) but I can't seem to find a board like this anywhere. Can anyone help?
I have an Ellisys USB analyser, which isn't exactly what you describe internally, but does sit between a peripheral and a host and use a separate PC to collect the data.
(i.e. it has two 'B' and one 'A' connectors on it.)
Excellent product, and very helpful company.
Sniffing the USB shouldn't be too hard if you have the right hardware. And that is the tricky question. I haven't seen anything that describes the USB breakout box that you want. However I can say that this is in the realm of the following two magazines:
Nuts and Volts
Circuit Cellar
If they don't have a USB breakout box project in their archives, then at least they will have advertisements for small cheap single board computers that would have multiple USB ports that you can use for buffering the signals and reporting it back to your PC.
Alternatively is it possible to just wire your PC up to the middle of your two devices and write a custom drive that echos data back and forth while sniffing off a stream for you?
Sorry for the long delay in my reply -- I checked out one of our USB developer's toolchain, and he uses a Beagle USB Sniffer. He seems happy with it.
You're looking for a USB device with two upstream outputs. I think according to the USB spec, this is not possible. You will have two USB hosts trying to send messages and control the USB devices at the same time.
What if you were to look for a device which allowed you to view the data going through a hub via something other than a usb output?
If you're building something custom, take a look at this USB chip site. The chips are programmable via a windows application. Once you define how you want it to operate, it's saved on an EPROM on the dev board ($30-$50).
Sorry if this isn't helpful!

Resources