Pugs continued, “Let’s build upon the USB device driver coded in our previous session, using the same
handy JetFlash pen drive from Transcend, with the vendor ID 0x058f and product ID 0x6387. For that, let’s dig further into the USB protocol, and then convert our learning into code.”
USB endpoints and their types
Depending on the type and attributes of information to be transferred, a USB device may have one or more endpoints, each belonging to one of the following four categories:
- Control — to transfer control information. Examples include resetting the device, querying information about the device, etc. All USB devices always have the default control endpoint point as zero.
- Interrupt — for small and fast data transfers, typically of up to 8 bytes. Examples include data transfer for serial ports, human interface devices (HIDs) like keyboards, mouse, etc.
- Bulk — for big but comparatively slower data transfers. A typical example is data transfers for mass-storage devices.
- Isochronous — for big data transfers with a bandwidth guarantee, though data integrity may not be guaranteed. Typical practical usage examples include transfers of time-sensitive data like audio, video, etc.
Additionally, all but control endpoints could be “in” or “out”, indicating the direction of data transfer; “in” indicates data flow from the USB device to the host machine, and “out”, the other way.
Technically, an endpoint is identified using an 8-bit number, the most significant bit (MSB) of which indicates the direction — 0 means “out”, and 1 means “in”. Control endpoints are bi-directional, and the MSB is ignored.
Figure 1 shows a typical snippet of USB device specifications for devices connected on a system.
To be specific, the E:
lines in the figure show examples of an interrupt endpoint of a UHCI Host Controller, and two bulk endpoints of the pen drive under consideration. Also, the endpoint numbers (in hex) are, respectively, 0x81
, 0x01
and 0x82
— the MSB of the first and third being 1
, indicating ‘in’ endpoints, represented by (I)
in the figure; the second is an (O)
or ‘out’ endpoint. MxPS
specifies the maximum packet size, i.e., the data size that can be transferred in a single go. Again, as expected, for the interrupt endpoint, it is 2 (<=8)
, and 64
for the bulk endpoints. Ivl
specifies the interval in milliseconds to be given between two consecutive data packet transfers for proper transfer, and is more significant for the interrupt endpoints.
Decoding a USB device section
As we have just discussed regarding the E:
line, it is the right time to decode the relevant fields of others as well. In short, these lines in a USB device section give a complete overview of the device as per the USB specifications, as discussed in our previous article.
Refer back to Figure 1. The first letter of the first line of every device section is a T
, indicating the position of the device in the USB tree, uniquely identified by the triplet <usb bus number, usb tree level, usb port>
. D
represents the device descriptor, containing at least the device version, device class/category, and the number of configurations available for this device.
There would be as many C
lines as the number of configurations, though typically, it is one. C
, the configuration descriptor, contains its index, the device attributes in this configuration, the maximum power (actually, current) the device would draw in this configuration, and the number of interfaces under this configuration.
Depending on this, there would be at least that many I
lines. There could be more in case of an interface having alternates, i.e., the same interface number but with different properties — a typical scenario for Web-cams.
I
represents the interface descriptor with its index, alternate number, the functionality class/category of this interface, the driver associated with this interface, and the number of endpoints under this interface.
The interface class may or may not be the same as that of the device class. And
depending on the number of endpoints, there would be as many E
lines, details of which have already been discussed earlier.
The *
after the C
and I
represents the currently active configuration and interface, respectively. The P
line provides the vendor ID, product ID, and the product revision. S
lines are string descriptors showing up some vendor-specific descriptive information about the device.
“Peeping into cat /proc/bus/usb/devices
is good in order to figure out whether a device has been detected or not, and possibly to get the first-cut overview of the device. But most probably this information would be required to write the driver for the device as well. So, is there a way to access it using C
code?” Shweta asked.
“Yes, definitely; that’s what I am going to tell you about, next. Do you remember that as soon as a USB device is plugged into the system, the USB host controller driver populates its information into the generic USB core layer? To be precise, it puts that into a set of structures embedded into one another, exactly as per the USB specifications,” Pugs replied.
The following are the exact data structures defined in <linux/usb.h>
, ordered here in reverse, for flow clarity:
struct usb_device { … struct usb_device_descriptor descriptor; struct usb_host_config *config, *actconfig; … }; struct usb_host_config { struct usb_config_descriptor desc; … struct usb_interface *interface[USB_MAXINTERFACES]; … }; struct usb_interface { struct usb_host_interface *altsetting /* array */, *cur_altsetting; … }; struct usb_host_interface { struct usb_interface_descriptor desc; struct usb_host_endpoint *endpoint /* array */; … }; struct usb_host_endpoint { struct usb_endpoint_descriptor desc; … };
So, with access to the struct usb_device
handle for a specific device, all the USB-specific information about the device can be decoded, as shown through the /proc
window. But how does one get the device handle?
In fact, the device handle is not available directly in a driver; rather, the per-interface handles (pointers to struct usb_interface
) are available, as USB drivers are written for device interfaces rather than the device as a whole.
Recall that the probe and disconnect callbacks, which are invoked by the USB core for every interface of the registered device, have the corresponding interface handle as their first parameter. Refer to the prototypes below:
int (*probe)(struct usb_interface *interface, const struct usb_device_id *id); void (*disconnect)(struct usb_interface *interface);
So, with the interface pointer, all information about the corresponding interface can be accessed — and to get the container device handle, the following macro comes to the rescue:
struct usb_device device = interface_to_usbdev(interface);
Adding this new learning into last month’s registration-only driver gets the following code listing (pen_info.c
):
#include <linux/module.h> #include <linux/kernel.h> #include <linux/usb.h> static struct usb_device *device; static int pen_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i; iface_desc = interface->cur_altsetting; printk(KERN_INFO "Pen i/f %d now probed: (%04X:%04X)\n", iface_desc->desc.bInterfaceNumber, id->idVendor, id->idProduct); printk(KERN_INFO "ID->bNumEndpoints: %02X\n", iface_desc->desc.bNumEndpoints); printk(KERN_INFO "ID->bInterfaceClass: %02X\n", iface_desc->desc.bInterfaceClass); for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { endpoint = &iface_desc->endpoint[i].desc; printk(KERN_INFO "ED[%d]->bEndpointAddress: 0x%02X\n", i, endpoint->bEndpointAddress); printk(KERN_INFO "ED[%d]->bmAttributes: 0x%02X\n", i, endpoint->bmAttributes); printk(KERN_INFO "ED[%d]->wMaxPacketSize: 0x%04X (%d)\n", i, endpoint->wMaxPacketSize, endpoint->wMaxPacketSize); } device = interface_to_usbdev(interface); return 0; } static void pen_disconnect(struct usb_interface *interface) { printk(KERN_INFO "Pen i/f %d now disconnected\n", interface->cur_altsetting->desc.bInterfaceNumber); } static struct usb_device_id pen_table[] = { { USB_DEVICE(0x058F, 0x6387) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, pen_table); static struct usb_driver pen_driver = { .name = "pen_driver", .probe = pen_probe, .disconnect = pen_disconnect, .id_table = pen_table, }; static int __init pen_init(void) { return usb_register(&pen_driver); } static void __exit pen_exit(void) { usb_deregister(&pen_driver); } module_init(pen_init); module_exit(pen_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Anil Kumar Pugalia <email@sarika-pugs.com>"); MODULE_DESCRIPTION("USB Pen Info Driver");
Then, the usual steps for any Linux device driver may be repeated, along with the pen drive steps:
- Build the driver (
pen_info.ko
file) by running make. - Load the driver using
insmod pen_info.ko
. - Plug in the pen drive (after making sure that the usb-storage driver is not already loaded).
- Unplug the pen drive.
- Check the output of
dmesg
for the logs. - Unload the driver using
rmmod pen_info
.
Figure 2 shows a snippet of the above steps on Pugs’ system. Remember to ensure (in the output of cat /proc/bus/usb/devices
) that the usual usb-storage
driver is not the one associated with the pen drive interface, but rather the pen_info
driver.
Summing up
Before taking another break, Pugs shared two of the many mechanisms for a driver to specify its device to the USB core, using the struct usb_device_id
table. The first one is by specifying the <vendor id, product id>
pair using the USB_DEVICE()
macro (as done above). The second one is by specifying the device class/category using the USB_DEVICE_INFO()
macro. In fact, many more macros are available in <linux/usb.h>
for various combinations. Moreover, multiple of these macros could be specified in the usb_device_id
table (terminated by a null entry), for matching with any one of the criteria, enabling to write a single driver for possibly many devices.
“Earlier, you mentioned writing multiple drivers for a single device, as well. Basically, how do we selectively register or not register a particular interface of a USB device?”, queried Shweta. “Sure. That’s next in line of our discussion, along with the ultimate task in any device driver — the data-transfer mechanisms,” replied Pugs.
[…] So I have pragmatically good Idea for USB Driver. I read Linux USB Driver from bellow:- https://www.opensourceforu.com/2011/11/usb…rs-in-linux-2/ Also Read LDD3 USB Device Driver Chapter. So Any one have good demo project code of USB Driver. […]
Dear, When I pug and unplug my USB driver. I can’t see message in dmesg as above.
My dmesg as follow:
SELinux: initialized (dev sdd1, type vfat), uses genfs_contexts
usb 2-1: USB disconnect, address 5
SELinux: initialized (dev sdb4, type fuseblk), uses genfs_contexts
lo: Disabled Privacy Extensions
SELinux: initialized (dev proc, type proc), uses genfs_contexts
lo: Disabled Privacy Extensions
SELinux: initialized (dev proc, type proc), uses genfs_contexts
lo: Disabled Privacy Extensions
SELinux: initialized (dev proc, type proc), uses genfs_contexts
lo: Disabled Privacy Extensions
SELinux: initialized (dev proc, type proc), uses genfs_contexts
usbcore: deregistering interface driver pen_driver
usbcore: registered new interface driver pen_driver
usb 2-1: new high speed USB device using ehci_hcd and address 6
usb 2-1: New USB device found, idVendor=1221, idProduct=3234
usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-1: Product: Udisk 2.0
usb 2-1: Manufacturer: Udisk
usb 2-1: SerialNumber: 00000000295B
usb 2-1: configuration #1 chosen from 1 choice
scsi8 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 6
usb-storage: waiting for device to settle before scanning
usb-storage: device scan complete
scsi 8:0:0:0: Direct-Access Udisk Udisk 2.0 3.00 PQ: 0 ANSI: 2
sd 8:0:0:0: Attached scsi generic sg5 type 0
sd 8:0:0:0: [sdd] 16384000 512-byte logical blocks: (8.38 GB/7.81 GiB)
sd 8:0:0:0: [sdd] Write Protect is off
sd 8:0:0:0: [sdd] Mode Sense: 0b 00 00 08
sd 8:0:0:0: [sdd] Assuming drive cache: write through
sd 8:0:0:0: [sdd] Assuming drive cache: write through
sdd: sdd1
sdd: p1 size 16386237 exceeds device capacity, limited to end of disk
sd 8:0:0:0: [sdd] Assuming drive cache: write through
sd 8:0:0:0: [sdd] Attached SCSI removable disk
SELinux: initialized (dev sdd1, type vfat), uses genfs_contexts
usb 2-1: USB disconnect, address 6
Because the usb-storage driver is loaded. You need to make sure that is unloaded, as mentioned in the article.
Thank you. Please, how to unload usb-storage?
If it is listed in lsmod, just do a “rmmod usb-storage”. Otherwise, you’d have to recompile your kernel, by making usb-storage as a module.
go drivers path and then type rmmod usb-storage
I got an error when i tried to remove the “usb_storage”
melwin-Satellite-L640 USB_2 # rmmod usb_storage
ERROR: Module usb_storage is in use by ums_realtek
Here is the output for “lsusb”
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 005: ID 0930:0214 Toshiba Corp.
Bus 002 Device 006: ID 04f2:b1d6 Chicony Electronics Co., Ltd
solved :)
ums_realtk is a module that depends in usb_storage.
just “rmmod ums_realtk”
I’m getting the same error but on trying the same command, I got
“Error: Module ums_realtek does not exist in /proc/modules”. I also listed all the available modules & ums-realtek isn’t present there. However, it’s there in the folder. I’m a newbie. Please help.
Paste the output of lsmod.
Its Fantastic !!
Thank you for your valuable Linux device driver articles.
Could you please start the same for BSP also.
I doubt, if it would be possible, as currently doing the same for mathematics in open source.
I have tried the code in Part 11 which was working for me.
Here I am not getting the /dev/pen0 listed on my system (Linux Ubuntu 12.04), even when I copy paste the code from here….
compiled & followed all your steps accordingly..
Will you please help me in completing this ?
Check out the vendor id, device id of your pen drive, and update the code accordingly.
how to know the functions
pen_probe,pen_disconnect (where these functions available and how to find the headder files)
Those are our implementations, coded in the above article example itself
I have written code that read data about battery and light conditions from keyboard but i must detach& read & attach my keyboard and read get some time … in this time i cant write using mi keyboard(is detached) … is here some way how to do R/W without detaching device ???
Please elaborate, as not very clear on the reason for your detach & attach.
Can not we write a driver which works for all usb pendrives without actually taking vendor-id and product-id ?
In fact, that’s how the actual driver “usb-storage” is written. It works on the concept of class, i.e. the category of devices, rather than their vendor & device id. Thus, usb-storage serves all the storage class devices, including all the pen drives.
Then, how to hack “usb-storage” ?
Why do you need to hack in it? Its complete code is there part of the kernel source code.
I mean, how to understand that code and modify it for our own purpose ?
It involves understanding the USB Storage protocol, which is SCSI based.
Ok, It would be great if you could help me with that.
How do you expect me to help? You have to first read those stuff, and the easiest would be to start reading the usb-storage code itself.
Ok, thank you sir!!
Dear Anil_Pugalia,
Thank you for your really pedagogical articles. The module pen_register from Part11 worked perfectly well after addition of #include .
Unfortunatly the module pen_info from Part12 does’nt act as expected : the module usb_storage always preempt pen_info : after removing usb_storage via rmmod and adding pen_info.ko, I plug the pen drive, and usb_storage comes back after pen_info as shows lsmod. A sudo more /sys/kernel/debug/usb/devices shows that the driver of my pen drive is usb-storage. If I try to rmmod usb_storage, the answer is Error: Module usb_storage is in use.
In other words I don’t see how to avoid the automatic substitution of pen_info by usb_storage.
Thank you for any advice.
Best Regards
Try commenting the usb-storage lines in /lib/modules//modules.usbmap
But do not forget to uncomment, once you are done experimenting.
Dear anil kumar,
I am trying to write device driver for avr programmer, manufactured by ‘zhifengsoft’, for which i donot have linux driver. As part of this, first I wrote upto registering the usb devie and deregestering the usb device in init and exit functions respectavely. and an empty probe function with printk saying that my programmer is connected message.
But I am not getting the message which i gave in probe function.
Driver is compiled perfectly and regestered. The vender id and product id I collected using lsusb -v and i also verified it by connecting and checking the dmesg.
Can you please help in this context.
Thanking you sir.
This is my code snippet:
static struct usb_device_id avrProg_table [] = {
{ USB_DEVICE(AVR_PROG_VENDOR_ID, AVR_PROG_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, avrProg_table);
static int avrProg_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
/* called when a USB device is connected to the computer. */
printk(“nnnavr_programmer is connected!!!nnn”);
return 0;
}
static void avrProg_disconnect(struct usb_interface *interface)
{
/* called when unplugging a USB device. */
printk(“nnnavr_programmer is disconnected!!nnn”);
}
static struct usb_driver avrProg_driver = {
.name = “avr_programmer”,
.id_table = avrProg_table,
.probe = avrProg_probe,
.disconnect = avrProg_disconnect,
};
#endif
static int __init avrProg_init(void) {
printk(” avrProg installed!n”);
return usb_register(&avrProg_driver);;
}
static void __exit avrProg_exit(void) {
printk(” avrProg uninstalledn”);
usb_deregister(&avrProg_driver);;
}
module_init(avrProg_init);
module_exit(avrProg_exit);
Check out for any other driver owning the interface of your AVR programmer. For that you may, check the “Driver=…” entry for your device in the output of the “cat /sys/kernel/debug/usb/devices”. The debugfs should have been already mounted at /sys/kernel/debug for this.
Dear anil kumar,
I am trying to write device driver for avr programmer, manufactured by ‘zhifengsoft’, for which i donot have linux driver. As part of this, first I wrote upto registering the usb devie and deregestering the usb device in init and exit functions respectavely. and an empty probe function with printk saying that my programmer is connected message.
But I am not getting the message which i gave in probe function.
Driver is compiled perfectly and regestered. The vender id and product id I collected using lsusb -v and i also verified it by connecting and checking the dmesg.
Can you please help in this context.
Thanking you sir.
This is my code snippet:
static struct usb_device_id avrProg_table [] = {
{ USB_DEVICE(AVR_PROG_VENDOR_ID, AVR_PROG_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, avrProg_table);
static int avrProg_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
/* called when a USB device is connected to the computer. */
printk(“nnnavr_programmer is connected!!!nnn”);
return 0;
}
static void avrProg_disconnect(struct usb_interface *interface)
{
/* called when unplugging a USB device. */
printk(“nnnavr_programmer is disconnected!!nnn”);
}
static struct usb_driver avrProg_driver = {
.name = “avr_programmer”,
.id_table = avrProg_table,
.probe = avrProg_probe,
.disconnect = avrProg_disconnect,
};
#endif
static int __init avrProg_init(void) {
printk(” avrProg installed!n”);
return usb_register(&avrProg_driver);;
}
static void __exit avrProg_exit(void) {
printk(” avrProg uninstalledn”);
usb_deregister(&avrProg_driver);;
}
module_init(avrProg_init);
module_exit(avrProg_exit);
Okay, silly question. There’s no usb folder in proc/bus.
Is that the same as /sys/kernel/usb/devices ?
which linux kernel u r using Akshay oswal?
i m also facing same problem
In the latest kernels that has been deprecated. So, one should checkout the /sys/kernel/debug/usb/devices. And for that you need to make sure that the debugfs is mounted at /sys/kernel/debug
how to make pen_info module to run for any pen drive.
Try changing the USB_DEVICE() entry to USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK)
Thank you sir..
sir,
After inserting the module ie usb data transfer to and fro to usb device /dev/pen0 is created but i am not able to read or write to it.Can you tell me how to do it.
It is not expected to do actual reads/writes. For that, you will have to study the USB Storage protocol and then send the transactions, accordingly.
I want to do some changes in USB driver in my kernel 3.0.35…
So please describe me that where can I find USB driver in kernel tree/files ???
and how can I do changes into it ??
Request to please explain me in little bit.I am new to kernel programming particular to driver so..
Need a help for this issue.
Please Reply me ASAP
Thanks..
Regards
Jaymin D
In general, usb drivers could be found under drivers/usb under the kernel source tree.
Thanks a lot sir for this.but I have one Q that can I able to do some changes into it ?
Mean that ,
Can I add my source lines ??
How can I compile it after adding my custom lines ??
How can it works after I add lines and code in to tree/files ??
So sir please can you just explain above thing in little bit details..Its very helpful for me so..
Thanks a lot..
Regards
Jaymin D
Yes, you can add your source lines – after all it is just a piece of C code. Compilation has to be done from the top directory of the kernel source. If it is built as part of the kernel, then “make” would build it. If it is built as a module, then “make modules” would build it. In the first case, you will have to boot with your new kernel image, thus built. In the second case, you can just load the corresponding driver, thus built.
And, in case your are interested in monthly updates on related techie stuff, you may register yourself at http://sysplay.in/index.php?pagefile=login
Hello All,
please help me to find out the solution that,
How can I add and compile my custom application code in my kernel ??
How to add my ‘.c’ ‘.o’ file into my kernel ‘bin’ directory and compiling it ??
I made hello.c and hello.o file and I want to add these file into my
kernel such way that when kernel start this hello.o file execute and
run..
(If any makefile needed to write then also tell me that how can I do it ???)
So please give me some idea about it that how can I do it ??
Please reply me.
Thanks
Jaymin D
Easiest is to write your code as a driver. And let it load, when kernel boots up, calling the corresponding init of your driver. For details, pick up any getting started with Linux drivers tutorial. You may read the following as well: http://sysplay.in/blog/linux-device-drivers/2013/03/writing-your-first-linux-driver-in-the-classroom/.
Thanks a very lot sir for your answer and give such a good information..I will see your given link and then I will ask you about doubts if any generate….
I will ask you…
thanks a lot..
regards
Jaymin D
You are welcome.
I emulated the program with my SanDisk Cruzer Blade and my Vodafone data card, but whenever I try to register or info, the usb_storage takes over just after inserting, and dmesg shows no infomation from my programs. What am I doing wrong?
Follow the following steps:
+ Insert your device
+ Unload the usb_storage driver using rmmod
+ Load your driver using insmod
And see, if it helps.
Doesn’t help. This is the output of :~$ lsmod
usb_storage 40172 0
usblp 10651 0
binfmt_misc 6599 1
snd_intel8x0 25632 2
snd_ac97_codec 99227 1 snd_intel8x0
ac97_bus 1014 1 snd_ac97_codec
i915 290938 2
snd_pcm 71475 2 snd_intel8x0,snd_ac97_codec
snd_seq_midi 4588 0
snd_rawmidi 17783 1 snd_seq_midi
drm_kms_helper 30200 1 i915
snd_seq_midi_event 6047 1 snd_seq_midi
snd_seq 47174 2 snd_seq_midi,snd_seq_midi_event
snd_timer 19067 2 snd_pcm,snd_seq
drm 168054 2 i915,drm_kms_helper
snd_seq_device 5744 3 snd_seq_midi,snd_rawmidi,snd_seq
ppdev 5556 0
parport_pc 26058 1
intel_agp 26360 2 i915
snd 49006 11 snd_intel8x0,snd_ac97_codec,snd_pcm,snd_rawmidi,snd_seq,snd_timer,snd_seq_device
i2c_algo_bit 5168 1 i915
video 18712 1 i915
soundcore 880 1 snd
psmouse 59033 0
shpchp 29886 0
serio_raw 4022 0
snd_page_alloc 7120 2 snd_intel8x0,snd_pcm
agpgart 32011 2 drm,intel_agp
output 1883 1 video
lp 7342 0
parport 31492 3 ppdev,parport_pc,lp
8139too 19581 0
8139cp 16934 0
mii 4425 2 8139too,8139cp
Seems okay to me. Do a lsmod after rmmod of usb-storage and insmod of pen_register, and check out for no usb_storage listed there. And I assume, that you have changed the vendor id & device id in the pen_register driver for your device.
Ah, that was it. I didn’t substitute my USB device’s IDs, silly me. Now that it’s done, I see all messages I wrote in my program. Thanks to you. :-)
You are welcome.
I’m writing device driver for unknown device in linux. According to the above probe function code I must see that my device’s endpoint. If I plug the usb flash disk I can see that device’s endpoint with this code.
I’m writing driver for specific device and I write this code in probe function. But I can not see that my device’s endpoint.
for (i = 0; i desc.bNumEndpoints; i++)
{
endpoint = &iface_desc->endpoint[i].desc;
printk(KERN_INFO “ED[%d]->bEndpointAddress: 0x%02Xn”,
i, endpoint->bEndpointAddress);
printk(KERN_INFO “ED[%d]->bmAttributes: 0x%02Xn”,
i, endpoint->bmAttributes);
printk(KERN_INFO “ED[%d]->wMaxPacketSize: 0x%04X (%d)n”,
i, endpoint->wMaxPacketSize, endpoint->wMaxPacketSize);
}
I cannot enter to this for loop.
What must I do ? Will I define the endpoints manual in my C code ? Please help.
Is your probe getting called? If not check for whether you have given the right id table. If yes, then check that your unknown device’s interfaces are not acquired by another driver. If not, then check if the interface(s) has any endpoints.
I’m writing device driver for unknown device in linux.
According to the probe function code in this link I must see that device’s endpoint. If I write this code for usb flash disk and after compile this module and plug usb flash disk I can see that device’s endpoint with this code.
But If I write this code for my unknown device, after compile this module and plug my unknown device I can NOT see that my device’s endpoint with this code.
for (i = 0; i desc.bNumEndpoints; i++)
{
endpoint = &iface_desc->endpoint[i].desc;
printk(KERN_INFO “ED[%d]->bEndpointAddress: 0x%02Xn”,
i, endpoint->bEndpointAddress);
printk(KERN_INFO “ED[%d]->bmAttributes: 0x%02Xn”,
i, endpoint->bmAttributes);
printk(KERN_INFO “ED[%d]->wMaxPacketSize: 0x%04X (%d)n”,
i, endpoint->wMaxPacketSize, endpoint->wMaxPacketSize);
}
I cannot enter to this for loop.
What must I do ? Will I define the endpoints as a manually in my C code ? Please help.
For anyone not able to “rmmod usb_storage” directly, due to it being in use by “uas”, “rmmod uas” then “rmmod usb_storage”.
I did this. It’s not my question. I asked that “Will I define the endpoints as a manually in my C code ?” Please help.
Is your probe getting called? If not check for whether you have given
the right id table. If yes, then check that your unknown device’s
interfaces are not acquired by another driver. If not, then check if the interface(s) has any endpoints. Typically, you need not define endpoints manually.
if usb_storage is being used and not letting you remove it, rmmod uas first.
Then rmmod usb_storage.
Hi,
I have board which contains very basic file system and kernel. I got totally confused when i plugged my pen drive to usb port where it does not recognize it. I believe there is not any driver to recognize any usb device. Could you let me know where i can start. I mean which module do i have insert so that it will recognize usb devices.
Thanks
Rabi
Hi Anil,
First of all thanks for this excellent guide.
I have few doubts regarding the usb driver.
I insmod the pen_info.ko module and when i do dmesg , i can see the results of probe funtion call. i dont understand why usb-storage is still being registered?
I cannot see the drive being loaded as /dev/sdb but message is still seen in dmesg(last 2 lines). What is the meaning of this?
ray@shadow:~/drivers/usb$ dmesg
[ 1720.537547] usb 1-1: new high-speed USB device number 10 using xhci_hcd
[ 1720.671763] usb 1-1: New USB device found, idVendor=1ec9, idProduct=0081
[ 1720.671776] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1720.671780] usb 1-1: Product: Moser Baer Disk
[ 1720.671784] usb 1-1: Manufacturer: MBIL SSM
[ 1720.671787] usb 1-1: SerialNumber: 30002B23C965B333
[ 1720.672602] Pen i/f 0 now probed: (1EC9:0081)
[ 1720.672608] ID->bNumEndpoints: 02
[ 1720.672611] ID->bInterfaceClass: 08
[ 1720.672614] ED[0]->bEndpointAddress: 0x81
[ 1720.672617] ED[0]->bmAttributes: 0x02
[ 1720.672621] ED[0]->wMaxPacketSize: 0x0200 (512)
[ 1720.672624] ED[1]->bEndpointAddress: 0x02
[ 1720.672627] ED[1]->bmAttributes: 0x02
[ 1720.672630] ED[1]->wMaxPacketSize: 0x0200 (512)
[ 1720.689055] usbcore: registered new interface driver usb-storage
[ 1720.691061] usbcore: registered new interface driver uas
Thanks in advance
Hi,
Iam new to driver developement. I read through the article and its quite informative. I got all the point explained except one. Where is the interface(usb_interface) structure is being populated.
static int pen_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int i;
iface_desc = interface->cur_altsetting;
I dint see in teh article mentioning about where and how this structure is populated.
Could you please explain in detail how interface gets unique values in case of multifunction USB devices.
Thanks in advance
It is done by the usb core driver.
when I try to rmmod usb_storage, the answer is Error: Module usb_storage is in use by “uas”.
i have checked using lsmod command, usb_storage module is there in module list and is showing used by “uas”.
How to remove usb-storage in my module list