cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

writing_usb_driver.rst (13503B)


      1.. _writing-usb-driver:
      2
      3==========================
      4Writing USB Device Drivers
      5==========================
      6
      7:Author: Greg Kroah-Hartman
      8
      9Introduction
     10============
     11
     12The Linux USB subsystem has grown from supporting only two different
     13types of devices in the 2.2.7 kernel (mice and keyboards), to over 20
     14different types of devices in the 2.4 kernel. Linux currently supports
     15almost all USB class devices (standard types of devices like keyboards,
     16mice, modems, printers and speakers) and an ever-growing number of
     17vendor-specific devices (such as USB to serial converters, digital
     18cameras, Ethernet devices and MP3 players). For a full list of the
     19different USB devices currently supported, see Resources.
     20
     21The remaining kinds of USB devices that do not have support on Linux are
     22almost all vendor-specific devices. Each vendor decides to implement a
     23custom protocol to talk to their device, so a custom driver usually
     24needs to be created. Some vendors are open with their USB protocols and
     25help with the creation of Linux drivers, while others do not publish
     26them, and developers are forced to reverse-engineer. See Resources for
     27some links to handy reverse-engineering tools.
     28
     29Because each different protocol causes a new driver to be created, I
     30have written a generic USB driver skeleton, modelled after the
     31pci-skeleton.c file in the kernel source tree upon which many PCI
     32network drivers have been based. This USB skeleton can be found at
     33drivers/usb/usb-skeleton.c in the kernel source tree. In this article I
     34will walk through the basics of the skeleton driver, explaining the
     35different pieces and what needs to be done to customize it to your
     36specific device.
     37
     38Linux USB Basics
     39================
     40
     41If you are going to write a Linux USB driver, please become familiar
     42with the USB protocol specification. It can be found, along with many
     43other useful documents, at the USB home page (see Resources). An
     44excellent introduction to the Linux USB subsystem can be found at the
     45USB Working Devices List (see Resources). It explains how the Linux USB
     46subsystem is structured and introduces the reader to the concept of USB
     47urbs (USB Request Blocks), which are essential to USB drivers.
     48
     49The first thing a Linux USB driver needs to do is register itself with
     50the Linux USB subsystem, giving it some information about which devices
     51the driver supports and which functions to call when a device supported
     52by the driver is inserted or removed from the system. All of this
     53information is passed to the USB subsystem in the :c:type:`usb_driver`
     54structure. The skeleton driver declares a :c:type:`usb_driver` as::
     55
     56    static struct usb_driver skel_driver = {
     57	    .name        = "skeleton",
     58	    .probe       = skel_probe,
     59	    .disconnect  = skel_disconnect,
     60	    .suspend     = skel_suspend,
     61	    .resume      = skel_resume,
     62	    .pre_reset   = skel_pre_reset,
     63	    .post_reset  = skel_post_reset,
     64	    .id_table    = skel_table,
     65	    .supports_autosuspend = 1,
     66    };
     67
     68
     69The variable name is a string that describes the driver. It is used in
     70informational messages printed to the system log. The probe and
     71disconnect function pointers are called when a device that matches the
     72information provided in the ``id_table`` variable is either seen or
     73removed.
     74
     75The fops and minor variables are optional. Most USB drivers hook into
     76another kernel subsystem, such as the SCSI, network or TTY subsystem.
     77These types of drivers register themselves with the other kernel
     78subsystem, and any user-space interactions are provided through that
     79interface. But for drivers that do not have a matching kernel subsystem,
     80such as MP3 players or scanners, a method of interacting with user space
     81is needed. The USB subsystem provides a way to register a minor device
     82number and a set of :c:type:`file_operations` function pointers that enable
     83this user-space interaction. The skeleton driver needs this kind of
     84interface, so it provides a minor starting number and a pointer to its
     85:c:type:`file_operations` functions.
     86
     87The USB driver is then registered with a call to usb_register(),
     88usually in the driver's init function, as shown here::
     89
     90    static int __init usb_skel_init(void)
     91    {
     92	    int result;
     93
     94	    /* register this driver with the USB subsystem */
     95	    result = usb_register(&skel_driver);
     96	    if (result < 0) {
     97		    pr_err("usb_register failed for the %s driver. Error number %d\n",
     98		           skel_driver.name, result);
     99		    return -1;
    100	    }
    101
    102	    return 0;
    103    }
    104    module_init(usb_skel_init);
    105
    106
    107When the driver is unloaded from the system, it needs to deregister
    108itself with the USB subsystem. This is done with usb_deregister()
    109function::
    110
    111    static void __exit usb_skel_exit(void)
    112    {
    113	    /* deregister this driver with the USB subsystem */
    114	    usb_deregister(&skel_driver);
    115    }
    116    module_exit(usb_skel_exit);
    117
    118
    119To enable the linux-hotplug system to load the driver automatically when
    120the device is plugged in, you need to create a ``MODULE_DEVICE_TABLE``.
    121The following code tells the hotplug scripts that this module supports a
    122single device with a specific vendor and product ID::
    123
    124    /* table of devices that work with this driver */
    125    static struct usb_device_id skel_table [] = {
    126	    { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
    127	    { }                      /* Terminating entry */
    128    };
    129    MODULE_DEVICE_TABLE (usb, skel_table);
    130
    131
    132There are other macros that can be used in describing a struct
    133:c:type:`usb_device_id` for drivers that support a whole class of USB
    134drivers. See :ref:`usb.h <usb_header>` for more information on this.
    135
    136Device operation
    137================
    138
    139When a device is plugged into the USB bus that matches the device ID
    140pattern that your driver registered with the USB core, the probe
    141function is called. The :c:type:`usb_device` structure, interface number and
    142the interface ID are passed to the function::
    143
    144    static int skel_probe(struct usb_interface *interface,
    145	const struct usb_device_id *id)
    146
    147
    148The driver now needs to verify that this device is actually one that it
    149can accept. If so, it returns 0. If not, or if any error occurs during
    150initialization, an errorcode (such as ``-ENOMEM`` or ``-ENODEV``) is
    151returned from the probe function.
    152
    153In the skeleton driver, we determine what end points are marked as
    154bulk-in and bulk-out. We create buffers to hold the data that will be
    155sent and received from the device, and a USB urb to write data to the
    156device is initialized.
    157
    158Conversely, when the device is removed from the USB bus, the disconnect
    159function is called with the device pointer. The driver needs to clean
    160any private data that has been allocated at this time and to shut down
    161any pending urbs that are in the USB system.
    162
    163Now that the device is plugged into the system and the driver is bound
    164to the device, any of the functions in the :c:type:`file_operations` structure
    165that were passed to the USB subsystem will be called from a user program
    166trying to talk to the device. The first function called will be open, as
    167the program tries to open the device for I/O. We increment our private
    168usage count and save a pointer to our internal structure in the file
    169structure. This is done so that future calls to file operations will
    170enable the driver to determine which device the user is addressing. All
    171of this is done with the following code::
    172
    173    /* increment our usage count for the device */
    174    kref_get(&dev->kref);
    175
    176    /* save our object in the file's private structure */
    177    file->private_data = dev;
    178
    179
    180After the open function is called, the read and write functions are
    181called to receive and send data to the device. In the ``skel_write``
    182function, we receive a pointer to some data that the user wants to send
    183to the device and the size of the data. The function determines how much
    184data it can send to the device based on the size of the write urb it has
    185created (this size depends on the size of the bulk out end point that
    186the device has). Then it copies the data from user space to kernel
    187space, points the urb to the data and submits the urb to the USB
    188subsystem. This can be seen in the following code::
    189
    190    /* we can only write as much as 1 urb will hold */
    191    size_t writesize = min_t(size_t, count, MAX_TRANSFER);
    192
    193    /* copy the data from user space into our urb */
    194    copy_from_user(buf, user_buffer, writesize);
    195
    196    /* set up our urb */
    197    usb_fill_bulk_urb(urb,
    198		      dev->udev,
    199		      usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
    200		      buf,
    201		      writesize,
    202		      skel_write_bulk_callback,
    203		      dev);
    204
    205    /* send the data out the bulk port */
    206    retval = usb_submit_urb(urb, GFP_KERNEL);
    207    if (retval) {
    208	    dev_err(&dev->interface->dev,
    209                "%s - failed submitting write urb, error %d\n",
    210                __func__, retval);
    211    }
    212
    213
    214When the write urb is filled up with the proper information using the
    215:c:func:`usb_fill_bulk_urb` function, we point the urb's completion callback
    216to call our own ``skel_write_bulk_callback`` function. This function is
    217called when the urb is finished by the USB subsystem. The callback
    218function is called in interrupt context, so caution must be taken not to
    219do very much processing at that time. Our implementation of
    220``skel_write_bulk_callback`` merely reports if the urb was completed
    221successfully or not and then returns.
    222
    223The read function works a bit differently from the write function in
    224that we do not use an urb to transfer data from the device to the
    225driver. Instead we call the :c:func:`usb_bulk_msg` function, which can be used
    226to send or receive data from a device without having to create urbs and
    227handle urb completion callback functions. We call the :c:func:`usb_bulk_msg`
    228function, giving it a buffer into which to place any data received from
    229the device and a timeout value. If the timeout period expires without
    230receiving any data from the device, the function will fail and return an
    231error message. This can be shown with the following code::
    232
    233    /* do an immediate bulk read to get data from the device */
    234    retval = usb_bulk_msg (skel->dev,
    235			   usb_rcvbulkpipe (skel->dev,
    236			   skel->bulk_in_endpointAddr),
    237			   skel->bulk_in_buffer,
    238			   skel->bulk_in_size,
    239			   &count, 5000);
    240    /* if the read was successful, copy the data to user space */
    241    if (!retval) {
    242	    if (copy_to_user (buffer, skel->bulk_in_buffer, count))
    243		    retval = -EFAULT;
    244	    else
    245		    retval = count;
    246    }
    247
    248
    249The :c:func:`usb_bulk_msg` function can be very useful for doing single reads
    250or writes to a device; however, if you need to read or write constantly to
    251a device, it is recommended to set up your own urbs and submit them to
    252the USB subsystem.
    253
    254When the user program releases the file handle that it has been using to
    255talk to the device, the release function in the driver is called. In
    256this function we decrement our private usage count and wait for possible
    257pending writes::
    258
    259    /* decrement our usage count for the device */
    260    --skel->open_count;
    261
    262
    263One of the more difficult problems that USB drivers must be able to
    264handle smoothly is the fact that the USB device may be removed from the
    265system at any point in time, even if a program is currently talking to
    266it. It needs to be able to shut down any current reads and writes and
    267notify the user-space programs that the device is no longer there. The
    268following code (function ``skel_delete``) is an example of how to do
    269this::
    270
    271    static inline void skel_delete (struct usb_skel *dev)
    272    {
    273	kfree (dev->bulk_in_buffer);
    274	if (dev->bulk_out_buffer != NULL)
    275	    usb_free_coherent (dev->udev, dev->bulk_out_size,
    276		dev->bulk_out_buffer,
    277		dev->write_urb->transfer_dma);
    278	usb_free_urb (dev->write_urb);
    279	kfree (dev);
    280    }
    281
    282
    283If a program currently has an open handle to the device, we reset the
    284flag ``device_present``. For every read, write, release and other
    285functions that expect a device to be present, the driver first checks
    286this flag to see if the device is still present. If not, it releases
    287that the device has disappeared, and a ``-ENODEV`` error is returned to the
    288user-space program. When the release function is eventually called, it
    289determines if there is no device and if not, it does the cleanup that
    290the ``skel_disconnect`` function normally does if there are no open files
    291on the device (see Listing 5).
    292
    293Isochronous Data
    294================
    295
    296This usb-skeleton driver does not have any examples of interrupt or
    297isochronous data being sent to or from the device. Interrupt data is
    298sent almost exactly as bulk data is, with a few minor exceptions.
    299Isochronous data works differently with continuous streams of data being
    300sent to or from the device. The audio and video camera drivers are very
    301good examples of drivers that handle isochronous data and will be useful
    302if you also need to do this.
    303
    304Conclusion
    305==========
    306
    307Writing Linux USB device drivers is not a difficult task as the
    308usb-skeleton driver shows. This driver, combined with the other current
    309USB drivers, should provide enough examples to help a beginning author
    310create a working driver in a minimal amount of time. The linux-usb-devel
    311mailing list archives also contain a lot of helpful information.
    312
    313Resources
    314=========
    315
    316The Linux USB Project:
    317http://www.linux-usb.org/
    318
    319Linux Hotplug Project:
    320http://linux-hotplug.sourceforge.net/
    321
    322linux-usb Mailing List Archives:
    323https://lore.kernel.org/linux-usb/
    324
    325Programming Guide for Linux USB Device Drivers:
    326https://lmu.web.psi.ch/docu/manuals/software_manuals/linux_sl/usb_linux_programming_guide.pdf
    327
    328USB Home Page: https://www.usb.org