usbsample.c
上传用户:wudi5211
上传日期:2010-01-21
资源大小:607k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
  3.  * Copyright (C) 2001 O'Reilly & Associates
  4.  *
  5.  * The source code in this file can be freely used, adapted,
  6.  * and redistributed in source or binary form, so long as an
  7.  * acknowledgment appears in derived source files.  The citation
  8.  * should list that the code comes from the book "Linux Device
  9.  * Drivers" by Alessandro Rubini and Jonathan Corbet, published
  10.  * by O'Reilly & Associates.   No warranty is attached;
  11.  * we cannot take responsibility for errors or fitness for use.
  12.  *
  13.  *
  14.  * This sample driver implements USB protocol decoding for both an USB
  15.  * keyboard and an USB mouse. You can test it using either device, provided
  16.  * they are not already managed by the official drivers. If you want
  17.  * to only experiment with one device, pass the nokbd=1 or the
  18.  * no_mouse=1 option to the command line of insmod
  19.  */
  20. #ifndef __KERNEL__
  21. #  define __KERNEL__
  22. #endif
  23. #ifndef MODULE
  24. #  define MODULE
  25. #endif
  26. #include <linux/config.h>
  27. #include <linux/module.h>
  28. /* No USB with 2.0, make an explicit error and avoid strange ones */
  29. #if LINUX_VERSION_CODE < 0x020200
  30. #  error "This module needs kmod, so it won't run with 2.0"
  31. #else
  32. #include <linux/kernel.h>
  33. #include <linux/malloc.h>
  34. #include <linux/init.h>
  35. #include <linux/usb.h>
  36. /*
  37.  * Note: <linux/usb.h> in 2.2 includes <linux/kcomp.h> that breaks
  38.  * our sysdep.h . You can't disable kcomp.h from entering the game,
  39.  * so "sysdep.h" can't be included here. If you write a backward-portable
  40.  * driver with both USB and something-else support, you need to separate
  41.  * the USB stuff in order not to rely on sysdep.h in USB-related  files
  42.  */
  43. #if 0
  44.   #include "sysdep.h"
  45. #else
  46.   #include "usb-sysdep.h"
  47. #endif
  48. /*
  49.  * We need a local data structure, as it must be allocated for each new
  50.  * mouse device plugged in the USB bus
  51.  */
  52. struct sample_device {
  53.     unsigned char data[8];   /* enough for keyboard and mouse protocols */
  54.     char *name;              /* either "kdb" or "mouse" */
  55.     struct urb urb;          /* USB Request block, to get USB data*/
  56.     int maxp;                /* packet len */
  57.     char output[80];         /* used for printk at irq time */
  58. };
  59. /*
  60.  * Handler for data sent in by the device. The function is called by
  61.  * the USB kernel subsystem whenever a device spits out new data
  62.  */
  63. static void sample_irq(struct urb *urb)
  64. {
  65.     struct sample_device *sample = urb->context;
  66.     char *pos = sample->output;
  67.     int i;
  68.     if (urb->status != USB_ST_NOERROR) return;
  69.     pos += sprintf(pos, "usbsample: data from %-8s =",
  70.    sample->name);
  71.     for (i=0; i<sample->maxp; i++) {
  72. pos += sprintf(pos, " %02x", sample->data[i]);
  73.     }
  74.     printk(KERN_INFO "%sn", sample->output);
  75. }
  76. /*
  77.  * These two callbacks are invoked when an USB device is detached or attached
  78.  * to the bus
  79.  */
  80. static void sample_disconnect(struct usb_device *udev, void *clientdata)
  81. {
  82.     /* the clientdata is the sample_device we passed originally */
  83.     struct sample_device *sample = clientdata;
  84.     /* remove the URB, remove the input device, free memory */
  85.     usb_unlink_urb(&sample->urb);
  86.     kfree(sample);
  87.     printk(KERN_INFO "sample: USB %s disconnectedn", sample->name);
  88.     /*
  89.      * here you might MOD_DEC_USE_COUNT, but only if you increment
  90.      * the count in sample_probe() below
  91.      */
  92.     return;
  93. }
  94. static void *sample_probe(struct usb_device *udev, unsigned int ifnum,
  95.   const struct usb_device_id *id)
  96. {
  97.     /*
  98.      * The probe procedure is pretty standard. Device matching has already
  99.      * been performed based on the id_table structure (defined later)
  100.      */
  101.     struct usb_interface *iface;
  102.     struct usb_interface_descriptor *interface;
  103.     struct usb_endpoint_descriptor *endpoint;
  104.     struct sample_device *sample;
  105.     printk(KERN_INFO "usbsample: probe called for %s devicen",
  106.    (char *)id->driver_info /* "mouse" or "keyboard" */ );
  107.     iface = &udev->actconfig->interface[ifnum];
  108.     interface = &iface->altsetting[iface->act_altsetting];
  109.     if (interface->bNumEndpoints != 1) return NULL;
  110.     endpoint = interface->endpoint + 0;
  111.     if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
  112.     if ((endpoint->bmAttributes & 3) != 3) return NULL;
  113.     usb_set_protocol(udev, interface->bInterfaceNumber, 0);
  114.     usb_set_idle(udev, interface->bInterfaceNumber, 0, 0);
  115.     /* allocate and zero a new data structure for the new device */
  116.     sample = kmalloc(sizeof(struct sample_device), GFP_KERNEL);
  117.     if (!sample) return NULL; /* failure */
  118.     memset(sample, 0, sizeof(*sample));
  119.     sample->name = (char *)id->driver_info;
  120.     /* fill the URB data structure using the FILL_INT_URB macro */
  121.     {
  122. int pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
  123. int maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
  124. if (maxp > 8) maxp = 8; sample->maxp = maxp; /* remember for later */
  125. FILL_INT_URB(&sample->urb, udev, pipe, sample->data, maxp,
  126.       sample_irq, sample, endpoint->bInterval);
  127.     }
  128.     /* register the URB within the USB subsystem */
  129.     if (usb_submit_urb(&sample->urb)) {
  130. kfree(sample);
  131. return NULL;
  132.     }
  133.     /* announce yourself */
  134.     printk(KERN_INFO "usbsample: probe successful for %s (maxp is %i)n",
  135.    sample->name, sample->maxp);
  136.     /*
  137.      * here you might MOD_INC_USE_COUNT; if you do, you'll need to unplug
  138.      * the device or the devices before being able to unload the module
  139.      */
  140.     /* and return the new structure */
  141.     return sample;
  142. }
  143. /*
  144.  * The id_table, lists all devices that can be handled by this driver.
  145.  * The three numbers are class, subclass, protocol. <linux/usb.h> has
  146.  * more details about interface mathces and vendor/device matches.
  147.  * This feature is not there in version 2.2, see below, sample_probe_22()
  148.  * for details. Here we use a fake usb_device_id structure defined in 
  149.  * ./usb-sysdep.h
  150.  */
  151. static struct usb_device_id sample_id_table [] = {
  152.     {
  153. USB_INTERFACE_INFO(3, 1, 1),
  154. driver_info: (unsigned long)"keyboard"
  155.     },
  156.     {
  157. USB_INTERFACE_INFO(3, 1, 2),
  158. driver_info: (unsigned long)"mouse"
  159.     },
  160.     {
  161. 0, /* no more matches */
  162.     }
  163. };
  164. /*
  165.  * The callbacks are registered within the USB subsystem using the
  166.  * usb_driver data structure
  167.  */
  168. #ifdef LINUX_24
  169. static struct usb_driver sample_usb_driver = {
  170.         name:        "sample",
  171.         probe:       sample_probe,
  172.         disconnect:  sample_disconnect,
  173.         id_table:    sample_id_table,
  174. };
  175. #else /* 2.2 */
  176. /*
  177.  * With version 2.2, there is no device_id support: the probe function
  178.  * is called for every device being plugged, and it must select whether
  179.  * the device is going to be handled or not. Here we extract the identification
  180.  * phase (based on class/subclass/protocol in this case) and rely on
  181.  * sample_probe() above for the interesting part of the game. Note
  182.  * that a 2.4 driver can use this approach as well, by not defining an
  183.  * id table (and achieving a 2.2 and 2.4 source with less ifdef). We think
  184.  * the id_table way is much cleaner, so we chose to exploit it where available
  185.  */
  186. static void *sample_probe_22(struct usb_device *udev, unsigned int ifnum)
  187. {
  188.     struct usb_device_id *id;
  189.     struct usb_interface_descriptor *interface;
  190.     printk(KERN_INFO "sample_probe_22 calledn");
  191.     if (udev->descriptor.bNumConfigurations != 1) return NULL;
  192.     interface = udev->config[0].interface[ifnum].altsetting;
  193.     for (id = sample_id_table; id->driver_info; id++) {
  194.         if (interface->bInterfaceClass !=    id->class)    continue;
  195.         if (interface->bInterfaceSubClass != id->subclass) continue;
  196.         if (interface->bInterfaceProtocol != id->protocol) continue;
  197. break; /* found */
  198.     }
  199.     if (!id->driver_info)
  200. return NULL; /* not ours */
  201.     return sample_probe(udev, ifnum, id);
  202. }
  203. static struct usb_driver sample_usb_driver = {
  204.         name:        "sample",
  205.         probe:       sample_probe_22,
  206.         disconnect:  sample_disconnect,
  207. /* no id_table field here */
  208. };
  209. #endif /* 2.2 */
  210. /*
  211.  * Functions called at module load and unload time: only register and
  212.  * unregister the USB callbacks
  213.  */
  214. int sample_init(void)
  215. {
  216.     /* just register it, returns 0 or error code */
  217.     return usb_register(&sample_usb_driver);
  218. }
  219. void sample_exit(void)
  220. {
  221.     usb_deregister(&sample_usb_driver);
  222. }
  223. module_init(sample_init);
  224. module_exit(sample_exit);
  225. #endif /* no 2.0 */