What's different in USB class when the devices are modem? - linux

Every USB device has to come under some USB device class definition based on the device driver will get use on the Linux system.. that part i understood.
but I can't understand something. For example, mostly all USB modem come under communication device class.. I have one 3G USB modem and one 3G USB dongle (e.g.,tata photon), both come under the same communication class but 3G USB modem uses CDC-ACM driver and 3G dongle uses serial converter driver(USB-Serial). What makes these devices differs?
Can anyone explain this?

The source code of Linux is available so you can look to see how it works. Here is the source code of the cdc-acm USB driver you mentioned:
http://lxr.linux.no/linux+v3.12.2/drivers/usb/class/cdc-acm.c
Look at the acm_ids[] array near line 1516. This is a big array of structs that describe which USB devices the cdc-acm driver will match to. It looks like the array starts with quirky devices and then at the end has more standard, generic devices. See if you can find the line that matches each device you have! This array is passed to some more general USB code in the kernel that takes care of matching USB devices to drivers.

The USB device dictates what type of driver will load. If it presents itself with CDC Class descriptors then it will load a CDC class driver (the same goes for other types of devices such as USBAudio, HID Keyboard/Mouse, etc.).
If the USB device presents itself with vendor specific descriptors then it will need to do matching on the VID and PID to determine which vendor specific driver to load. In the case of USB to serial bridges there are many vendors, so the driver loaded depends on your specific cable. You can find the source for the usbserial based drivers in root/drivers/usb/serial/, and from there you can grep for the VID/PID of your device to find out which driver is being loaded for that interface.
It looks like there was a recent commit for a 3G dongle, maybe this is what you are looking for?

The source code for all Linux drivers is available... you could see for yourself by looking at the source code.

Related

difference between a pci device driver with "module_pci_driver" and a pci driver with "__init()" but without "module_pci_driver()" in Linux

I have seen in pci device drivers this line
module_pci_driver(cp_driver);
But in other pci device drivers this like
module_init(rtl8139_init_module);
both lines found at the end of driver's .c file in different drivers
What I know is: I can create a pci device driver with __init but I can also create a pci device driver without __init
i.e.
[Realtek Ethernet has two drivers in Linux source
1) 139cp.c (without __init)
2) 8139too.c with __init].
I assume that the main difference between the two is simply that if I have to use a pci device driver right after loading of the driver module with insmod command so I use an implementation of a device driver with __init.
Question
On the contrary, if I just want to load the pci device driver but not use it, Then should I create a pci device driver with module_pci_driver() (So no need to add __init)? And what does it do(module_pci_driver)? How its different from pci driver with __init
I like to know I may have a misconception anyone please clarify. Also does the probe function of both type of drivers will run when I load the driver with insmod command? When? if yes than what's the difference since most configuring of device is done in proble function
To sum up
When initialization happens in driver with module_pci_driver(cp_driver); since they dont have __init implemented. What command used
module_pci_driver() is a helper meant for drivers that don't do anything special in their module init and exit (i.e. modules whose init and exit functions just register/unregister).
It generates the init and exit functions for you, reducing some boilerplate.
In this specific case, the 8139too driver might do something in addition to registering the driver (in this case, logging the driver name), so isn't using module_pci_driver()
The probe function is called for existing or new devices that match the ID table and aren't already owned (see How To Write Linux PCI Drivers for details).
It returns a value indicating if the driver will be taking ownership of the device (either 0 or an error code).

LInux Device Driver Layering Confusion

I have recently been reading about Linux Driver and Device Model. I wanted to understand how the following works in linux in the driver subsystem. So lets say my device tree looks as follows
To be concrete lets assume Bus1 is a PCI bus, Bus2 is ISA and Bus3 is USB. Buses are connected with each other using bridges.
Linux will identify this device tree through the enumeration process and through enumeration and probing mechanism suitable usb driver for terminal device would be identified.
Now lets assume a Tx operation to this terminal device. The terminal device usb driver would end up doing a urb_submit(dev, write_buffer).
My question is in order for the URB to reach the terminal device, theoretically it would have to be enveloped in Bus2 and Bus1 envelopes. So theoretically speaking the outgoing packet has to look something like this
So at some after the urb_submit happens in the driver, does some kernel code walk up the device tree structure and invoke the bus drivers in order (bus 2 driver and then bus 1 driver) to create this envelope structure.
Can anyone point me to the code in the linux kernel where this happens? I tried to follow urb_submit but could not figure this out.
Thanks a bunch!
For device drivers that have memory-mapped registers, the device's private data struct contains the addresses assigned by enumeration for each device and they directly write to the registers.
For device drivers that go through layers, as you describe above, the enumeration tells each driver who its parent is, and the driver saves this in its private data when it is instantiated. Then the read or write call of the driver formats the request properly for the device type and invokes the read or write method of the parent driver. For example, a USB disk read might call the read method in the file_operations block of its parent which would be https://elixir.bootlin.com/linux/v4.19.107/source/drivers/usb/core/devio.c#L2614

Preventing usbhid from claiming device

In order for my USB driver's _probe function to be called, I need to prevent usbhid from claiming it first. To do this I wrote a UDEV rule which unbinds the device.
SUBSYSTEM=="usb", DRIVER=="usbhid", ATTRS{idVendor}=="ffff",
ATTRS{idProduct}=="ffff", RUN="/bin/sh -c 'echo -n $id:1.0 >
/sys/bus/usb/drivers/usbhid/unbind'"
While this works, what is the standard practice for distributing drivers? Do I have to also package this rule? Is there any way for my own driver to take priority over usbhid?
The kernel selects the drivers for each device based on the MODULE_DEVICE_TABLEs. The HID device table is considered more specific than the generic USB device table, so if your device claims USB HID device class, then your driver should probably include a HID class MODULE_DEVICE_TABLE too.
The matching algorithm favors specific matches over generic class-based ones, so if your device table entry includes some USB or HID device attributes unique to it, your driver should get priority over the generic usbhid driver.
If your idVendor and idProduct identifiers are actually both 0xffff, then I guess you're dealing with a prototype device that does not yet have proper USB vendor/device identifiers. You'll want to fix that.

Is there a USB device descriptor to determine if a device is HID or keyboard emulation?

Does anyone know how to determine from the USB device descriptor or other USB descriptors if a USB device is HID or keyboard emulation? I'm looking to interface to a family of magtek magcard swipe readers and they can be configured to operate as HID or keyboard emulation. The magtek PID will tell me but what happens if someone plugs in a different manufacture? I'm looking for a univseral way of determining this. I'm using the libudev library to interface to my USB.
Also, does Linux have a universal routine to decode keyboard emulation scan codes. I've got my own look-up table which works fine but I was just wondering.
Steve
The only way you can tell what a device is, is by using the PID/VID of the USB device (and the Class, but I believe both modes are declared as HID-class devices anyway).
So, if you plug in a new manufacturer, you'll have to manually add support for it. From my experience (I did not use a magtek reader, but a tmsr33), no reader behave the same way in both HID or emulation mode. Generally speaking, I'd say it is better to use HID mode, as bytes exposed will need less conversion.
AFAICT, I went into the same trouble and I basically copy pasted the keycodes/keylayout from the kernel sources to my own code. If you prefer, you can link directly to the kernel's source code to get the tables.
https://github.com/MicahCarrick/magtek-pyusb
https://github.com/guyzmo/tmsr33-pyusb‎
HTH

Linux Uart driver modification

I want to modify my linux kernel's (2.6.32) UART driver. I am using the standard uart driver for ttyS2 I dont know the exact files. The problem is Simple, setting and keeping a gpio pin high during transmission and while receving it must be low.
Which files should i refer to ? And any ideas about bitbanging gpio s from uart driver are wellcome...
Regards.
Try to understand how the Linux Serial Driver Layers are working and organized .
Determine which serial chip (driver) your device is using.
Hack the bit-banging GPIO into the low-lever driver.
OR:
Maybe you can abuse another signal line instead of a GPIO. If you operate your UART in RS485 mode, mostly the RTS behaves like you want -> high during transmission. I'm not sure if the rest of the communication would be rs232-compliant, but why not just try.

Resources