Blame view

Documentation/DocBook/writing_usb_driver.tmpl 17 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
  	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
  
  <book id="USBDeviceDriver">
   <bookinfo>
    <title>Writing USB Device Drivers</title>
    
    <authorgroup>
     <author>
      <firstname>Greg</firstname>
      <surname>Kroah-Hartman</surname>
      <affiliation>
       <address>
        <email>greg@kroah.com</email>
       </address>
      </affiliation>
     </author>
    </authorgroup>
  
    <copyright>
     <year>2001-2002</year>
     <holder>Greg Kroah-Hartman</holder>
    </copyright>
  
    <legalnotice>
     <para>
       This documentation is free software; you can redistribute
       it and/or modify it under the terms of the GNU General Public
       License as published by the Free Software Foundation; either
       version 2 of the License, or (at your option) any later
       version.
     </para>
        
     <para>
       This program is distributed in the hope that it will be
       useful, but WITHOUT ANY WARRANTY; without even the implied
       warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       See the GNU General Public License for more details.
     </para>
        
     <para>
       You should have received a copy of the GNU General Public
       License along with this program; if not, write to the Free
       Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
       MA 02111-1307 USA
     </para>
        
     <para>
       For more details see the file COPYING in the source
       distribution of Linux.
     </para>
  
     <para>
       This documentation is based on an article published in 
       Linux Journal Magazine, October 2001, Issue 90.
     </para>
    </legalnotice>
   </bookinfo>
  
  <toc></toc>
  
    <chapter id="intro">
        <title>Introduction</title>
    <para>
        The Linux USB subsystem has grown from supporting only two different
        types of devices in the 2.2.7 kernel (mice and keyboards), to over 20
        different types of devices in the 2.4 kernel. Linux currently supports
        almost all USB class devices (standard types of devices like keyboards,
        mice, modems, printers and speakers) and an ever-growing number of
        vendor-specific devices (such as USB to serial converters, digital
        cameras, Ethernet devices and MP3 players). For a full list of the
        different USB devices currently supported, see Resources.
    </para>
    <para>
        The remaining kinds of USB devices that do not have support on Linux are
        almost all vendor-specific devices. Each vendor decides to implement a
        custom protocol to talk to their device, so a custom driver usually needs
        to be created. Some vendors are open with their USB protocols and help
        with the creation of Linux drivers, while others do not publish them, and
        developers are forced to reverse-engineer. See Resources for some links
        to handy reverse-engineering tools.
    </para>
    <para>
        Because each different protocol causes a new driver to be created, I have
        written a generic USB driver skeleton, modeled after the pci-skeleton.c
        file in the kernel source tree upon which many PCI network drivers have
        been based. This USB skeleton can be found at drivers/usb/usb-skeleton.c
        in the kernel source tree. In this article I will walk through the basics
        of the skeleton driver, explaining the different pieces and what needs to
        be done to customize it to your specific device.
    </para>
    </chapter>
  
    <chapter id="basics">
        <title>Linux USB Basics</title>
    <para>
        If you are going to write a Linux USB driver, please become familiar with
        the USB protocol specification. It can be found, along with many other
        useful documents, at the USB home page (see Resources). An excellent
        introduction to the Linux USB subsystem can be found at the USB Working
        Devices List (see Resources). It explains how the Linux USB subsystem is
838cb6aba   Robert P. J. Day   DOC: A couple co...
103
104
        structured and introduces the reader to the concept of USB urbs
        (USB Request Blocks), which are essential to USB drivers.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    </para>
    <para>
        The first thing a Linux USB driver needs to do is register itself with
        the Linux USB subsystem, giving it some information about which devices
        the driver supports and which functions to call when a device supported
        by the driver is inserted or removed from the system. All of this
        information is passed to the USB subsystem in the usb_driver structure.
        The skeleton driver declares a usb_driver as:
    </para>
    <programlisting>
  static struct usb_driver skel_driver = {
          .name        = "skeleton",
          .probe       = skel_probe,
          .disconnect  = skel_disconnect,
          .fops        = &amp;skel_fops,
          .minor       = USB_SKEL_MINOR_BASE,
          .id_table    = skel_table,
  };
    </programlisting>
    <para>
        The variable name is a string that describes the driver. It is used in
        informational messages printed to the system log. The probe and
        disconnect function pointers are called when a device that matches the
        information provided in the id_table variable is either seen or removed.
    </para>
    <para>
        The fops and minor variables are optional. Most USB drivers hook into
        another kernel subsystem, such as the SCSI, network or TTY subsystem.
        These types of drivers register themselves with the other kernel
        subsystem, and any user-space interactions are provided through that
        interface. But for drivers that do not have a matching kernel subsystem,
        such as MP3 players or scanners, a method of interacting with user space
        is needed. The USB subsystem provides a way to register a minor device
        number and a set of file_operations function pointers that enable this
        user-space interaction. The skeleton driver needs this kind of interface,
        so it provides a minor starting number and a pointer to its
        file_operations functions.
    </para>
    <para>
        The USB driver is then registered with a call to usb_register, usually in
        the driver's init function, as shown here:
    </para>
    <programlisting>
  static int __init usb_skel_init(void)
  {
          int result;
  
          /* register this driver with the USB subsystem */
          result = usb_register(&amp;skel_driver);
          if (result &lt; 0) {
                  err(&quot;usb_register failed for the &quot;__FILE__ &quot;driver.&quot;
                      &quot;Error number %d&quot;, result);
                  return -1;
          }
  
          return 0;
  }
  module_init(usb_skel_init);
    </programlisting>
    <para>
838cb6aba   Robert P. J. Day   DOC: A couple co...
165
166
        When the driver is unloaded from the system, it needs to deregister
        itself with the USB subsystem. This is done with the usb_deregister
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
        function:
    </para>
    <programlisting>
  static void __exit usb_skel_exit(void)
  {
          /* deregister this driver with the USB subsystem */
          usb_deregister(&amp;skel_driver);
  }
  module_exit(usb_skel_exit);
    </programlisting>
    <para>
       To enable the linux-hotplug system to load the driver automatically when
       the device is plugged in, you need to create a MODULE_DEVICE_TABLE. The
       following code tells the hotplug scripts that this module supports a
       single device with a specific vendor and product ID:
    </para>
    <programlisting>
  /* table of devices that work with this driver */
  static struct usb_device_id skel_table [] = {
          { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
          { }                      /* Terminating entry */
  };
  MODULE_DEVICE_TABLE (usb, skel_table);
    </programlisting>
    <para>
       There are other macros that can be used in describing a usb_device_id for
       drivers that support a whole class of USB drivers. See usb.h for more
       information on this.
    </para>
    </chapter>
  
    <chapter id="device">
        <title>Device operation</title>
    <para>
       When a device is plugged into the USB bus that matches the device ID
       pattern that your driver registered with the USB core, the probe function
       is called. The usb_device structure, interface number and the interface ID
       are passed to the function:
    </para>
    <programlisting>
  static int skel_probe(struct usb_interface *interface,
      const struct usb_device_id *id)
    </programlisting>
    <para>
       The driver now needs to verify that this device is actually one that it
       can accept. If so, it returns 0.
       If not, or if any error occurs during initialization, an errorcode
       (such as <literal>-ENOMEM</literal> or <literal>-ENODEV</literal>)
       is returned from the probe function.
    </para>
    <para>
       In the skeleton driver, we determine what end points are marked as bulk-in
       and bulk-out. We create buffers to hold the data that will be sent and
       received from the device, and a USB urb to write data to the device is
       initialized.
    </para>
    <para>
       Conversely, when the device is removed from the USB bus, the disconnect
       function is called with the device pointer. The driver needs to clean any
       private data that has been allocated at this time and to shut down any
bf6ee0ae4   Adrian Bunk   remove mentioning...
227
       pending urbs that are in the USB system.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
    </para>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
234
    <para>
       Now that the device is plugged into the system and the driver is bound to
       the device, any of the functions in the file_operations structure that
       were passed to the USB subsystem will be called from a user program trying
       to talk to the device. The first function called will be open, as the
       program tries to open the device for I/O. We increment our private usage
838cb6aba   Robert P. J. Day   DOC: A couple co...
235
       count and save a pointer to our internal structure in the file
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
       structure. This is done so that future calls to file operations will
       enable the driver to determine which device the user is addressing.  All
       of this is done with the following code:
    </para>
    <programlisting>
  /* increment our usage count for the module */
  ++skel->open_count;
  
  /* save our object in the file's private structure */
  file->private_data = dev;
    </programlisting>
    <para>
       After the open function is called, the read and write functions are called
       to receive and send data to the device. In the skel_write function, we
       receive a pointer to some data that the user wants to send to the device
       and the size of the data. The function determines how much data it can
       send to the device based on the size of the write urb it has created (this
       size depends on the size of the bulk out end point that the device has).
       Then it copies the data from user space to kernel space, points the urb to
838cb6aba   Robert P. J. Day   DOC: A couple co...
255
256
       the data and submits the urb to the USB subsystem.  This can be seen in
       the following code:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
    </para>
    <programlisting>
  /* we can only write as much as 1 urb will hold */
  bytes_written = (count > skel->bulk_out_size) ? skel->bulk_out_size : count;
  
  /* copy the data from user space into our urb */
  copy_from_user(skel->write_urb->transfer_buffer, buffer, bytes_written);
  
  /* set up our urb */
  usb_fill_bulk_urb(skel->write_urb,
                    skel->dev,
                    usb_sndbulkpipe(skel->dev, skel->bulk_out_endpointAddr),
                    skel->write_urb->transfer_buffer,
                    bytes_written,
                    skel_write_bulk_callback,
                    skel);
  
  /* send the data out the bulk port */
  result = usb_submit_urb(skel->write_urb);
  if (result) {
          err(&quot;Failed submitting write urb, error %d&quot;, result);
  }
    </programlisting>
    <para>
       When the write urb is filled up with the proper information using the
       usb_fill_bulk_urb function, we point the urb's completion callback to call our
       own skel_write_bulk_callback function. This function is called when the
       urb is finished by the USB subsystem. The callback function is called in
       interrupt context, so caution must be taken not to do very much processing
       at that time. Our implementation of skel_write_bulk_callback merely
       reports if the urb was completed successfully or not and then returns.
    </para>
    <para>
       The read function works a bit differently from the write function in that
       we do not use an urb to transfer data from the device to the driver.
       Instead we call the usb_bulk_msg function, which can be used to send or
       receive data from a device without having to create urbs and handle
       urb completion callback functions. We call the usb_bulk_msg function,
       giving it a buffer into which to place any data received from the device
       and a timeout value. If the timeout period expires without receiving any
       data from the device, the function will fail and return an error message.
       This can be shown with the following code:
    </para>
    <programlisting>
  /* do an immediate bulk read to get data from the device */
  retval = usb_bulk_msg (skel->dev,
                         usb_rcvbulkpipe (skel->dev,
                         skel->bulk_in_endpointAddr),
                         skel->bulk_in_buffer,
                         skel->bulk_in_size,
                         &amp;count, HZ*10);
  /* if the read was successful, copy the data to user space */
  if (!retval) {
          if (copy_to_user (buffer, skel->bulk_in_buffer, count))
                  retval = -EFAULT;
          else
                  retval = count;
  }
    </programlisting>
    <para>
       The usb_bulk_msg function can be very useful for doing single reads or
       writes to a device; however, if you need to read or write constantly to a
       device, it is recommended to set up your own urbs and submit them to the
       USB subsystem.
    </para>
    <para>
       When the user program releases the file handle that it has been using to
       talk to the device, the release function in the driver is called. In this
       function we decrement our private usage count and wait for possible
       pending writes:
    </para>
    <programlisting>
  /* decrement our usage count for the device */
  --skel->open_count;
    </programlisting>
    <para>
       One of the more difficult problems that USB drivers must be able to handle
       smoothly is the fact that the USB device may be removed from the system at
       any point in time, even if a program is currently talking to it. It needs
       to be able to shut down any current reads and writes and notify the
       user-space programs that the device is no longer there. The following
       code (function <function>skel_delete</function>)
       is an example of how to do this: </para>
    <programlisting>
  static inline void skel_delete (struct usb_skel *dev)
  {
a3a3395e4   Jesper Juhl   [PATCH] Driver Co...
343
      kfree (dev->bulk_in_buffer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
      if (dev->bulk_out_buffer != NULL)
997ea58eb   Daniel Mack   USB: rename usb_b...
345
          usb_free_coherent (dev->udev, dev->bulk_out_size,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
              dev->bulk_out_buffer,
              dev->write_urb->transfer_dma);
3c8961ee6   Mariusz Kozlowski   usb: writing_usb_...
348
      usb_free_urb (dev->write_urb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
      kfree (dev);
  }
    </programlisting>
    <para>
       If a program currently has an open handle to the device, we reset the flag
       <literal>device_present</literal>. For
       every read, write, release and other functions that expect a device to be
       present, the driver first checks this flag to see if the device is
       still present. If not, it releases that the device has disappeared, and a
       -ENODEV error is returned to the user-space program. When the release
       function is eventually called, it determines if there is no device
       and if not, it does the cleanup that the skel_disconnect
       function normally does if there are no open files on the device (see
       Listing 5).
    </para>
    </chapter>
  
    <chapter id="iso">
        <title>Isochronous Data</title>
    <para>
       This usb-skeleton driver does not have any examples of interrupt or
       isochronous data being sent to or from the device. Interrupt data is sent
       almost exactly as bulk data is, with a few minor exceptions.  Isochronous
       data works differently with continuous streams of data being sent to or
       from the device. The audio and video camera drivers are very good examples
       of drivers that handle isochronous data and will be useful if you also
       need to do this.
    </para>
    </chapter>
    
    <chapter id="Conclusion">
        <title>Conclusion</title>
    <para>
       Writing Linux USB device drivers is not a difficult task as the
       usb-skeleton driver shows. This driver, combined with the other current
       USB drivers, should provide enough examples to help a beginning author
       create a working driver in a minimal amount of time. The linux-usb-devel
       mailing list archives also contain a lot of helpful information.
    </para>
    </chapter>
  
    <chapter id="resources">
        <title>Resources</title>
    <para>
       The Linux USB Project: <ulink url="http://www.linux-usb.org">http://www.linux-usb.org/</ulink>
    </para>
    <para>
       Linux Hotplug Project: <ulink url="http://linux-hotplug.sourceforge.net">http://linux-hotplug.sourceforge.net/</ulink>
    </para>
    <para>
       Linux USB Working Devices List: <ulink url="http://www.qbik.ch/usb/devices">http://www.qbik.ch/usb/devices/</ulink>
    </para>
    <para>
       linux-usb-devel Mailing List Archives: <ulink url="http://marc.theaimsgroup.com/?l=linux-usb-devel">http://marc.theaimsgroup.com/?l=linux-usb-devel</ulink>
    </para>
    <para>
       Programming Guide for Linux USB Device Drivers: <ulink url="http://usb.cs.tum.edu/usbdoc">http://usb.cs.tum.edu/usbdoc</ulink>
    </para>
    <para>
       USB Home Page: <ulink url="http://www.usb.org">http://www.usb.org</ulink>
    </para>
    </chapter>
  
  </book>