⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 writing_usb_driver.tmpl

📁 linux 内核源代码
💻 TMPL
📖 第 1 页 / 共 2 页
字号:
<?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      structured and introduces the reader to the concept of USB urbs, which      are essential to USB drivers.  </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>      When the driver is unloaded from the system, it needs to unregister      itself with the USB subsystem. This is done with the usb_unregister      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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -