Sunteți pe pagina 1din 7

8/13/13

Write For Us Submit Tips

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You
Subscribe to Print Edition Search

HOME

REVIEWS

HOW-TOS

CODING

INTERVIEWS

FEATURES

OVERVIEW

BLOGS

SERIES

IT ADMIN

Device Drivers, Part 12: USB Drivers in Linux Continued


By Anil Kumar Pugalia on November 1, 2011 in Coding, Developers 11 Comments

Search for:

Search

The 12th part of the series on Linux device drivers takes you further along the path to writing your first USB driver in Linux a continuation from the previous article.
Pugs continued, Lets 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 06387. For that, lets dig further into the USB protocol, and then convert our learning into code.

Get Connected RSS Feed Twitter

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 bidirectional, and the MSB is ignored. Figure 1 shows a typical snippet of USB device specifications for devices connected on a system.

LINUX For You on

Follow

+2,490

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

1/7

8/13/13

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You
Find us on Facebook

Open Source For You


Like 252,555 people like Open Source For You.

F acebook social plugin

Popular

Comments

Tag cloud

May 6, 2013 5 Comments Priyanka Sarkar

PHP Development: A Smart Career Move


June 20, 2013 3 Comments Priyanka Sarkar

What it Takes to be an Open Source Expert


June 20, 2013 2 Comments sophie-samuel

Figure 1: USB's proc w indow snippet (click for larger view )

New and amazing features of Linux


May 6, 2013 1 Comments Deepti Sharma

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, 0 x 8 1 ,0 x 0 1and 0 x 8 2 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. M x P Sspecifies 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 6 4for the bulk endpoints. I v lspecifies the interval in milliseconds to be given between two consecutive data packet transfers for proper transfer, and is more significant for the interrupt endpoints.

A Simple guide to building your own Linux Kernel


May 6, 2013 1 Comments Prashant Phatak

Cyber Attacks Explained: Cryptographic Attacks

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 < u s bb u sn u m b e r ,u s b t r e el e v e l ,u s bp o r t > . Drepresents 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 Clines 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 Ilines. 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.
Irepresents 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 Elines, details of which have already been discussed earlier. The * after the Cand Irepresents the currently active configuration and interface, respectively. The Pline provides the vendor ID, product ID, and the product revision. Slines are string descriptors showing up some vendor-specific descriptive information about the device. Peeping into cat / p r o c / b u s / u s b / d e v i c e sis 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 Ccode? Shweta asked.

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

2/7

8/13/13

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You

Yes, definitely; thats 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 < l i n u x / u s b . h > , ordered here in reverse, for flow clarity:
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 s t r u c tu s b _ d e v i c e { s t r u c tu s b _ d e v i c e _ d e s c r i p t o rd e s c r i p t o r ; s t r u c tu s b _ h o s t _ c o n f i g* c o n f i g ,* a c t c o n f i g ; } ; s t r u c tu s b _ h o s t _ c o n f i g { s t r u c tu s b _ c o n f i g _ d e s c r i p t o rd e s c ; s t r u c tu s b _ i n t e r f a c e* i n t e r f a c e [ U S B _ M A X I N T E R F A C E S ] ; } ; s t r u c tu s b _ i n t e r f a c e { s t r u c tu s b _ h o s t _ i n t e r f a c e* a l t s e t t i n g/ *a r r a y* / ,* c u r _ a l t s e t t i n g ; } ; s t r u c tu s b _ h o s t _ i n t e r f a c e { s t r u c tu s b _ i n t e r f a c e _ d e s c r i p t o rd e s c ; s t r u c tu s b _ h o s t _ e n d p o i n t* e n d p o i n t/ *a r r a y* / ; } ; s t r u c tu s b _ h o s t _ e n d p o i n t { s t r u c tu s b _ e n d p o i n t _ d e s c r i p t o rd e s c ; } ;

So, with access to the s t r u c tu s b _ d e v i c ehandle for a specific device, all the USB-specific information about the device can be decoded, as shown through the / p r o cwindow. 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 s t r u c tu s b _ i n t e r f a c e ) 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:
i n t( * p r o b e ) ( s t r u c tu s b _ i n t e r f a c e* i n t e r f a c e ,c o n s ts t r u c tu s b _ d e v i c e _ i d* i d ) ; v o i d( * d i s c o n n e c t ) ( s t r u c tu s b _ i n t e r f a c e* i n t e r f a c e ) ;

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:
s t r u c tu s b _ d e v i c ed e v i c e=i n t e r f a c e _ t o _ u s b d e v ( i n t e r f a c e ) ;

Adding this new learning into last months registration-only driver gets the following code listing (p e n _ i n f o . c ):
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 # i n c l u d e< l i n u x / m o d u l e . h > # i n c l u d e< l i n u x / k e r n e l . h > # i n c l u d e< l i n u x / u s b . h > s t a t i cs t r u c tu s b _ d e v i c e* d e v i c e ; s t a t i ci n tp e n _ p r o b e ( s t r u c tu s b _ i n t e r f a c e* i n t e r f a c e ,c o n s ts t r u c tu s b _ d e v i c e _ i d* i d ) { s t r u c tu s b _ h o s t _ i n t e r f a c e* i f a c e _ d e s c ; s t r u c tu s b _ e n d p o i n t _ d e s c r i p t o r* e n d p o i n t ; i n ti ; i f a c e _ d e s c=i n t e r f a c e > c u r _ a l t s e t t i n g ; p r i n t k ( K E R N _ I N F O" P e ni / f% dn o wp r o b e d :( % 0 4 X : % 0 4 X ) \ n " , i f a c e _ d e s c > d e s c . b I n t e r f a c e N u m b e r ,i d > i d V e n d o r ,i d > i d P r o d u c t ) ; p r i n t k ( K E R N _ I N F O" I D > b N u m E n d p o i n t s :% 0 2 X \ n " , i f a c e _ d e s c > d e s c . b N u m E n d p o i n t s ) ; p r i n t k ( K E R N _ I N F O" I D > b I n t e r f a c e C l a s s :% 0 2 X \ n " , i f a c e _ d e s c > d e s c . b I n t e r f a c e C l a s s ) ; f o r( i=0 ;i<i f a c e _ d e s c > d e s c . b N u m E n d p o i n t s ;i + + ) { e n d p o i n t=& i f a c e _ d e s c > e n d p o i n t [ i ] . d e s c ; p r i n t k ( K E R N _ I N F O" E D [ % d ] > b E n d p o i n t A d d r e s s :0 x % 0 2 X \ n " , i ,e n d p o i n t > b E n d p o i n t A d d r e s s ) ; p r i n t k ( K E R N _ I N F O" E D [ % d ] > b m A t t r i b u t e s :0 x % 0 2 X \ n " , i ,e n d p o i n t > b m A t t r i b u t e s ) ; p r i n t k ( K E R N _ I N F O" E D [ % d ] > w M a x P a c k e t S i z e :0 x % 0 4 X( % d ) \ n " , i ,e n d p o i n t > w M a x P a c k e t S i z e ,e n d p o i n t > w M a x P a c k e t S i z e ) ;

d e v i c e=i n t e r f a c e _ t o _ u s b d e v ( i n t e r f a c e ) ;

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

3/7

8/13/13
3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 6 0 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 7 0 7 1 7 2 7 3 } r e t u r n0 ;

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You

s t a t i cv o i dp e n _ d i s c o n n e c t ( s t r u c tu s b _ i n t e r f a c e* i n t e r f a c e ) { p r i n t k ( K E R N _ I N F O" P e ni / f% dn o wd i s c o n n e c t e d \ n " , i n t e r f a c e > c u r _ a l t s e t t i n g > d e s c . b I n t e r f a c e N u m b e r ) ; } s t a t i cs t r u c tu s b _ d e v i c e _ i dp e n _ t a b l e [ ]= { {U S B _ D E V I C E ( 0 x 0 5 8 F ,0 x 6 3 8 7 )} , { }/ *T e r m i n a t i n ge n t r y* / } ; M O D U L E _ D E V I C E _ T A B L E( u s b ,p e n _ t a b l e ) ; s t a t i cs t r u c tu s b _ d r i v e rp e n _ d r i v e r= { . n a m e=" p e n _ d r i v e r " , . p r o b e=p e n _ p r o b e , . d i s c o n n e c t=p e n _ d i s c o n n e c t , . i d _ t a b l e=p e n _ t a b l e , } ; s t a t i ci n t_ _ i n i tp e n _ i n i t ( v o i d ) { r e t u r nu s b _ r e g i s t e r ( & p e n _ d r i v e r ) ; } s t a t i cv o i d_ _ e x i tp e n _ e x i t ( v o i d ) { u s b _ d e r e g i s t e r ( & p e n _ d r i v e r ) ; } m o d u l e _ i n i t ( p e n _ i n i t ) ; m o d u l e _ e x i t ( p e n _ e x i t ) ; M O D U L E _ L I C E N S E ( " G P L " ) ; M O D U L E _ A U T H O R ( " A n i lK u m a rP u g a l i a< e m a i l @ s a r i k a p u g s . c o m > " ) ; M O D U L E _ D E S C R I P T I O N ( " U S BP e nI n f oD r i v e r " ) ;

Then, the usual steps for any Linux device driver may be repeated, along with the pen drive steps: Build the driver (p e n _ i n f o . k ofile) by running make. Load the driver using i n s m o dp e n _ i n f o . k o . 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 d m e s gfor the logs. Unload the driver using r m m o dp e n _ i n f o . Figure 2 shows a snippet of the above steps on Pugs system. Remember to ensure (in the output of c a t/ p r o c / b u s / u s b / d e v i c e s ) that the usual u s b s t o r a g edriver is not the one associated with the pen drive interface, but rather the p e n _ i n f odriver.

Figure 2: Output of dmesg

Summing up
Before taking another break, Pugs shared two of the many mechanisms for a driver to specify its

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

4/7

8/13/13

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You

device to the USB core, using the s t r u c tu s b _ d e v i c e _ i dtable. The first one is by specifying the < v e n d o ri d ,p r o d u c ti d >pair using the U S B _ D E V I C E ( )macro (as done above). The second one is by specifying the device class/category using the U S B _ D E V I C E _ I N F O ( )macro. In fact, many more macros are available in < l i n u x / u s b . h >for various combinations. Moreover, multiple of these macros could be specified in the u s b _ d e v i c e _ i dtable (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. Thats next in line of our discussion, along with the ultimate task in any device driver the data-transfer mechanisms, replied Pugs.

Related Posts:
Device Drivers, Part 11: USB Drivers in Linux Device Drivers, Part 13: Data Transfer to and from USB Devices Device Drivers, Part 6: Decoding Character Device File Operations Device Drivers, Part 5: Character Device Files Creation & Operations Device Drivers, Part 4: Linux Character Drivers
Tags: LFY November 2011, linux device drivers, Linux Device Drivers Series, mass storage devices, serial ports, usb device driver, usb devices, USB host controller driver, usb protocol

Article written by:


Anil Kumar Pugalia
The author is a freelance trainer in Linux internals, Linux device drivers, embedded Linux and related topics. Prior to this, he had worked at Intel and Nvidia. He has been exploring Linux since 1994. A gold medallist from the Indian Institute of Science, Linux and knowledge-sharing are two of his many passions. Connect with him: Website - Twitter - Facebook - Google+

Previous Post

Next Post

Agile Software Development Made Faster, More Secure

Lisp: Tears of Joy, Part 6

11 comments Leave a message...


Newest Community anil k umar

Share

18 days ago

how to know the functions pen_probe,pen_disconnect (where these functions available and how to find the headder files)
Reply

Share

aadhirai

2 months ago

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 ?
1

Reply

Share

David

3 months ago

Its Fantastic !! Thank you for your valuable Linux device driver articles.

Could you please start the same for BSP also.


Reply Share

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

5/7

8/13/13
anil_pugalia

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You

> David

2 months ago

I doubt, if it would be possible, as currently doing the same for mathematics in open source.
Reply

Share

ME LW IN JOS E

7 months ago

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
Reply Share

ME LW IN JOS E

> MELWIN JOSE

7 months ago


MenDuong

solved :) ums_realtk is a module that depends in usb_storage. just "rmmod ums_realtk"


Reply Share

8 months ago

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

see more

Reply

Share

anil_pugalia

> MenDuong
Share

8 months ago

Because the usb-storage driver is loaded. You need to make sure that is unloaded, as mentioned in the article.
Reply

MenDuong

> anil_pugalia
Share

8 months ago

Thank you. Please, how to unload usb-storage?


Reply mic heal

> MenDuong
Reply

7 months ago

go drivers path and then type rmmod usb-storage


Share

anil_pugalia

> MenDuong

8 months ago

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.
2

Reply

Share

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

6/7

8/13/13

Device Drivers, Part 12: USB Drivers in Linux Continued - LINUX For You

C o m m e n t fe e d

Su b s cri b e vi a e m a i l

Reviews

How-Tos

Coding

Interviews

Features

Overview

Blogs

Search
Popular tags
Linux , ubuntu, Java, MySQL, Google, python, Fedora, Android, PHP, C, html, w eb applications , India, Microsoft, unix , Window s , Red Hat, Oracle, Security , Apache, xml, LFY April 2012, FOSS, GNOME, http, JavaScript, LFY June 2011, open source, RAM, operating systems

For You & Me Developers Sysadmins Open Gurus CXOs Columns

All published articles are released under Creative Commons Attribution-NonCommercial 3.0 Unported License, unless otherw ise noted. LINUX For You is pow ered by WordPress, w hich gladly sits on top of a CentOS-based LEMP stack.

www.linuxforu.com/2011/11/usb-drivers-in-linux-2/

7/7

S-ar putea să vă placă și