devices.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:18k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * devices.c
  3.  * (C) Copyright 1999 Randy Dunlap.
  4.  * (C) Copyright 1999,2000 Thomas Sailer <sailer@ife.ee.ethz.ch>. (proc file per device)
  5.  * (C) Copyright 1999 Deti Fliegl (new USB architecture)
  6.  *
  7.  * $id$
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22.  *
  23.  *************************************************************
  24.  *
  25.  * <mountpoint>/devices contains USB topology, device, config, class,
  26.  * interface, & endpoint data.
  27.  *
  28.  * I considered using /proc/bus/usb/devices/device# for each device
  29.  * as it is attached or detached, but I didn't like this for some
  30.  * reason -- maybe it's just too deep of a directory structure.
  31.  * I also don't like looking in multiple places to gather and view
  32.  * the data.  Having only one file for ./devices also prevents race
  33.  * conditions that could arise if a program was reading device info
  34.  * for devices that are being removed (unplugged).  (That is, the
  35.  * program may find a directory for devnum_12 then try to open it,
  36.  * but it was just unplugged, so the directory is now deleted.
  37.  * But programs would just have to be prepared for situations like
  38.  * this in any plug-and-play environment.)
  39.  *
  40.  * 1999-12-16: Thomas Sailer <sailer@ife.ee.ethz.ch>
  41.  *   Converted the whole proc stuff to real
  42.  *   read methods. Now not the whole device list needs to fit
  43.  *   into one page, only the device list for one bus.
  44.  *   Added a poll method to /proc/bus/usb/devices, to wake
  45.  *   up an eventual usbd
  46.  * 2000-01-04: Thomas Sailer <sailer@ife.ee.ethz.ch>
  47.  *   Turned into its own filesystem
  48.  * 2000-07-05: Ashley Montanaro <ashley@compsoc.man.ac.uk>
  49.  *   Converted file reading routine to dump to buffer once
  50.  *   per device, not per bus
  51.  *
  52.  * $Id: devices.c,v 1.5 2000/01/11 13:58:21 tom Exp $
  53.  */
  54. #include <linux/fs.h>
  55. #include <linux/mm.h>
  56. #include <linux/slab.h>
  57. #include <linux/poll.h>
  58. #include <linux/usb.h>
  59. #include <linux/smp_lock.h>
  60. #include <linux/usbdevice_fs.h>
  61. #include <asm/uaccess.h>
  62. #include "hcd.h"
  63. #define MAX_TOPO_LEVEL 6
  64. /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
  65. #define ALLOW_SERIAL_NUMBER
  66. static char *format_topo =
  67. /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
  68.   "T:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2dn";
  69. static char *format_string_manufacturer =
  70. /* S:  Manufacturer=xxxx */
  71.   "S:  Manufacturer=%.100sn";
  72. static char *format_string_product =
  73. /* S:  Product=xxxx */
  74.   "S:  Product=%.100sn";
  75. #ifdef ALLOW_SERIAL_NUMBER
  76. static char *format_string_serialnumber =
  77. /* S:  SerialNumber=xxxx */
  78.   "S:  SerialNumber=%.100sn";
  79. #endif
  80. static char *format_bandwidth =
  81. /* B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
  82.   "B:  Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3dn";
  83.   
  84. static char *format_device1 =
  85. /* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
  86.   "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3dn";
  87. static char *format_device2 =
  88. /* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */
  89.   "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02xn";
  90. static char *format_config =
  91. /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
  92.   "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmAn";
  93.   
  94. static char *format_iface =
  95. /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
  96.   "I:  If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%sn";
  97. static char *format_endpt =
  98. /* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */
  99.   "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%csn";
  100. /*
  101.  * Need access to the driver and USB bus lists.
  102.  * extern struct list_head usb_driver_list;
  103.  * extern struct list_head usb_bus_list;
  104.  * However, these will come from functions that return ptrs to each of them.
  105.  */
  106. static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq);
  107. static unsigned int conndiscevcnt = 0;
  108. /* this struct stores the poll state for <mountpoint>/devices pollers */
  109. struct usb_device_status {
  110. unsigned int lastev;
  111. };
  112. struct class_info {
  113. int class;
  114. char *class_name;
  115. };
  116. static const struct class_info clas_info[] =
  117. { /* max. 5 chars. per name string */
  118. {USB_CLASS_PER_INTERFACE, ">ifc"},
  119. {USB_CLASS_AUDIO, "audio"},
  120. {USB_CLASS_COMM, "comm."},
  121. {USB_CLASS_HID, "HID"},
  122. {USB_CLASS_HUB, "hub"},
  123. {USB_CLASS_PHYSICAL, "PID"},
  124. {USB_CLASS_PRINTER, "print"},
  125. {USB_CLASS_MASS_STORAGE, "stor."},
  126. {USB_CLASS_CDC_DATA, "data"},
  127. {USB_CLASS_APP_SPEC, "app."},
  128. {USB_CLASS_VENDOR_SPEC, "vend."},
  129. {USB_CLASS_STILL_IMAGE, "still"},
  130. {USB_CLASS_CSCID, "scard"},
  131. {USB_CLASS_CONTENT_SEC, "c-sec"},
  132. {-1, "unk."} /* leave as last */
  133. };
  134. /*****************************************************************/
  135. void usbdevfs_conn_disc_event(void)
  136. {
  137. wake_up(&deviceconndiscwq);
  138. conndiscevcnt++;
  139. }
  140. static const char *class_decode(const int class)
  141. {
  142. int ix;
  143. for (ix = 0; clas_info[ix].class != -1; ix++)
  144. if (clas_info[ix].class == class)
  145. break;
  146. return (clas_info[ix].class_name);
  147. }
  148. static char *usb_dump_endpoint_descriptor (
  149. int speed,
  150. char *start,
  151. char *end,
  152. const struct usb_endpoint_descriptor *desc
  153. )
  154. {
  155. char dir, unit, *type;
  156. unsigned interval, in, bandwidth = 1;
  157. if (start > end)
  158. return start;
  159. in = (desc->bEndpointAddress & USB_DIR_IN);
  160. dir = in ? 'I' : 'O';
  161. if (speed == USB_SPEED_HIGH) {
  162. switch (desc->wMaxPacketSize & (0x03 << 11)) {
  163. case 1 << 11: bandwidth = 2; break;
  164. case 2 << 11: bandwidth = 3; break;
  165. }
  166. }
  167. /* this isn't checking for illegal values */
  168. switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
  169. case USB_ENDPOINT_XFER_CONTROL:
  170. type = "Ctrl";
  171. if (speed == USB_SPEED_HIGH)  /* uframes per NAK */
  172. interval = desc->bInterval;
  173. else
  174. interval = 0;
  175. dir = 'B'; /* ctrl is bidirectional */
  176. break;
  177. case USB_ENDPOINT_XFER_ISOC:
  178. type = "Isoc";
  179. interval = 1 << (desc->bInterval - 1);
  180. break;
  181. case USB_ENDPOINT_XFER_BULK:
  182. type = "Bulk";
  183. if (speed == USB_SPEED_HIGH && !in) /* uframes per NAK */
  184. interval = desc->bInterval;
  185. else
  186. interval = 0;
  187. break;
  188. case USB_ENDPOINT_XFER_INT:
  189. type = "Int.";
  190. if (speed == USB_SPEED_HIGH) {
  191. interval = 1 << (desc->bInterval - 1);
  192. } else
  193. interval = desc->bInterval;
  194. break;
  195. default: /* "can't happen" */
  196. return start;
  197. }
  198. interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000;
  199. if (interval % 1000)
  200. unit = 'u';
  201. else {
  202. unit = 'm';
  203. interval /= 1000;
  204. }
  205. start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
  206.  desc->bmAttributes, type,
  207.  (desc->wMaxPacketSize & 0x07ff) * bandwidth,
  208.  interval, unit);
  209. return start;
  210. }
  211. static char *usb_dump_interface_descriptor(char *start, char *end, const struct usb_interface *iface, int setno)
  212. {
  213. struct usb_interface_descriptor *desc = &iface->altsetting[setno];
  214. if (start > end)
  215. return start;
  216. start += sprintf(start, format_iface,
  217.  desc->bInterfaceNumber,
  218.  desc->bAlternateSetting,
  219.  desc->bNumEndpoints,
  220.  desc->bInterfaceClass,
  221.  class_decode(desc->bInterfaceClass),
  222.  desc->bInterfaceSubClass,
  223.  desc->bInterfaceProtocol,
  224.  iface->driver ? iface->driver->name : "(none)");
  225. return start;
  226. }
  227. static char *usb_dump_interface(
  228. int speed,
  229. char *start,
  230. char *end,
  231. const struct usb_interface *iface,
  232. int setno
  233. ) {
  234. struct usb_interface_descriptor *desc = &iface->altsetting[setno];
  235. int i;
  236. start = usb_dump_interface_descriptor(start, end, iface, setno);
  237. for (i = 0; i < desc->bNumEndpoints; i++) {
  238. if (start > end)
  239. return start;
  240. start = usb_dump_endpoint_descriptor(speed,
  241. start, end, desc->endpoint + i);
  242. }
  243. return start;
  244. }
  245. /* TBD:
  246.  * 0. TBDs
  247.  * 1. marking active config and ifaces (code lists all, but should mark
  248.  *    which ones are active, if any)
  249.  * 2. add <halted> status to each endpoint line
  250.  */
  251. static char *usb_dump_config_descriptor(char *start, char *end, const struct usb_config_descriptor *desc, int active)
  252. {
  253. if (start > end)
  254. return start;
  255. start += sprintf(start, format_config,
  256.  active ? '*' : ' ', /* mark active/actual/current cfg. */
  257.  desc->bNumInterfaces,
  258.  desc->bConfigurationValue,
  259.  desc->bmAttributes,
  260.  desc->MaxPower * 2);
  261. return start;
  262. }
  263. static char *usb_dump_config (
  264. int speed,
  265. char *start,
  266. char *end,
  267. const struct usb_config_descriptor *config,
  268. int active
  269. )
  270. {
  271. int i, j;
  272. struct usb_interface *interface;
  273. if (start > end)
  274. return start;
  275. if (!config) /* getting these some in 2.3.7; none in 2.3.6 */
  276. return start + sprintf(start, "(null Cfg. desc.)n");
  277. start = usb_dump_config_descriptor(start, end, config, active);
  278. for (i = 0; i < config->bNumInterfaces; i++) {
  279. interface = config->interface + i;
  280. if (!interface)
  281. break;
  282. for (j = 0; j < interface->num_altsetting; j++) {
  283. if (start > end)
  284. return start;
  285. start = usb_dump_interface(speed,
  286. start, end, interface, j);
  287. }
  288. }
  289. return start;
  290. }
  291. /*
  292.  * Dump the different USB descriptors.
  293.  */
  294. static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc)
  295. {
  296. if (start > end)
  297. return start;
  298. start += sprintf (start, format_device1,
  299.   desc->bcdUSB >> 8, desc->bcdUSB & 0xff,
  300.   desc->bDeviceClass,
  301.   class_decode (desc->bDeviceClass),
  302.   desc->bDeviceSubClass,
  303.   desc->bDeviceProtocol,
  304.   desc->bMaxPacketSize0,
  305.   desc->bNumConfigurations);
  306. if (start > end)
  307. return start;
  308. start += sprintf(start, format_device2,
  309.  desc->idVendor, desc->idProduct,
  310.  desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
  311. return start;
  312. }
  313. /*
  314.  * Dump the different strings that this device holds.
  315.  */
  316. static char *usb_dump_device_strings (char *start, char *end, struct usb_device *dev)
  317. {
  318. char *buf;
  319. if (start > end)
  320. return start;
  321. buf = kmalloc(128, GFP_KERNEL);
  322. if (!buf)
  323. return start;
  324. if (dev->descriptor.iManufacturer) {
  325. if (usb_string(dev, dev->descriptor.iManufacturer, buf, 128) > 0)
  326. start += sprintf(start, format_string_manufacturer, buf);
  327. }
  328. if (start > end)
  329. goto out;
  330. if (dev->descriptor.iProduct) {
  331. if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0)
  332. start += sprintf(start, format_string_product, buf);
  333. }
  334. if (start > end)
  335. goto out;
  336. #ifdef ALLOW_SERIAL_NUMBER
  337. if (dev->descriptor.iSerialNumber) {
  338. if (usb_string(dev, dev->descriptor.iSerialNumber, buf, 128) > 0)
  339. start += sprintf(start, format_string_serialnumber, buf);
  340. }
  341. #endif
  342.  out:
  343. kfree(buf);
  344. return start;
  345. }
  346. static char *usb_dump_desc(char *start, char *end, struct usb_device *dev)
  347. {
  348. int i;
  349. if (start > end)
  350. return start;
  351. start = usb_dump_device_descriptor(start, end, &dev->descriptor);
  352. if (start > end)
  353. return start;
  354. start = usb_dump_device_strings (start, end, dev);
  355. for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
  356. if (start > end)
  357. return start;
  358. start = usb_dump_config(dev->speed,
  359. start, end, dev->config + i,
  360. /* active ? */
  361. (dev->config + i) == dev->actconfig);
  362. }
  363. return start;
  364. }
  365. #ifdef PROC_EXTRA /* TBD: may want to add this code later */
  366. static char *usb_dump_hub_descriptor(char *start, char *end, const struct usb_hub_descriptor * desc)
  367. {
  368. int leng = USB_DT_HUB_NONVAR_SIZE;
  369. unsigned char *ptr = (unsigned char *)desc;
  370. if (start > end)
  371. return start;
  372. start += sprintf(start, "Interface:");
  373. while (leng && start <= end) {
  374. start += sprintf(start, " %02x", *ptr);
  375. ptr++; leng--;
  376. }
  377. *start++ = 'n';
  378. return start;
  379. }
  380. static char *usb_dump_string(char *start, char *end, const struct usb_device *dev, char *id, int index)
  381. {
  382. if (start > end)
  383. return start;
  384. start += sprintf(start, "Interface:");
  385. if (index <= dev->maxstring && dev->stringindex && dev->stringindex[index])
  386. start += sprintf(start, "%s: %.100s ", id, dev->stringindex[index]);
  387. return start;
  388. }
  389. #endif /* PROC_EXTRA */
  390. /*****************************************************************/
  391. /* This is a recursive function. Parameters:
  392.  * buffer - the user-space buffer to write data into
  393.  * nbytes - the maximum number of bytes to write
  394.  * skip_bytes - the number of bytes to skip before writing anything
  395.  * file_offset - the offset into the devices file on completion
  396.  */
  397. static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
  398. struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
  399. {
  400. int chix;
  401. int ret, cnt = 0;
  402. int parent_devnum = 0;
  403. char *pages_start, *data_end, *speed;
  404. unsigned int length;
  405. ssize_t total_written = 0;
  406. /* don't bother with anything else if we're not writing any data */
  407. if (*nbytes <= 0)
  408. return 0;
  409. if (level > MAX_TOPO_LEVEL)
  410. return total_written;
  411. /* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */
  412.         if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1)))
  413.                 return -ENOMEM;
  414. if (usbdev->parent && usbdev->parent->devnum != -1)
  415. parent_devnum = usbdev->parent->devnum;
  416. /*
  417.  * So the root hub's parent is 0 and any device that is
  418.  * plugged into the root hub has a parent of 0.
  419.  */
  420. switch (usbdev->speed) {
  421. case USB_SPEED_LOW:
  422. speed = "1.5"; break;
  423. case USB_SPEED_UNKNOWN: /* usb 1.1 root hub code */
  424. case USB_SPEED_FULL:
  425. speed = "12 "; break;
  426. case USB_SPEED_HIGH:
  427. speed = "480"; break;
  428. default:
  429. speed = "?? ";
  430. }
  431. data_end = pages_start + sprintf(pages_start, format_topo,
  432. bus->busnum, level, parent_devnum,
  433. index, count, usbdev->devnum,
  434. speed, usbdev->maxchild);
  435. /*
  436.  * level = topology-tier level;
  437.  * parent_devnum = parent device number;
  438.  * index = parent's connector number;
  439.  * count = device count at this level
  440.  */
  441. /* If this is the root hub, display the bandwidth information */
  442.   if (level == 0) {
  443.   int max;
  444.  
  445.   /* high speed reserves 80%, full/low reserves 90% */
  446.   if (usbdev->speed == USB_SPEED_HIGH)
  447.   max = 800;
  448.   else
  449.   max = FRAME_TIME_MAX_USECS_ALLOC;
  450.  
  451.   /* report "average" periodic allocation over a microsecond.
  452.    * the schedules are actually bursty, HCDs need to deal with
  453.    * that and just compute/report this average.
  454.    */
  455.   data_end += sprintf(data_end, format_bandwidth,
  456.   bus->bandwidth_allocated, max,
  457.   (100 * bus->bandwidth_allocated + max / 2)
  458.   / max,
  459.            bus->bandwidth_int_reqs,
  460.    bus->bandwidth_isoc_reqs);
  461.   }
  462. data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev);
  463. if (data_end > (pages_start + (2 * PAGE_SIZE) - 256))
  464. data_end += sprintf(data_end, "(truncated)n");
  465. length = data_end - pages_start;
  466. /* if we can start copying some data to the user */
  467. if (length > *skip_bytes) {
  468. length -= *skip_bytes;
  469. if (length > *nbytes)
  470. length = *nbytes;
  471. if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) {
  472. free_pages((unsigned long)pages_start, 1);
  473. if (total_written == 0)
  474. return -EFAULT;
  475. return total_written;
  476. }
  477. *nbytes -= length;
  478. *file_offset += length;
  479. total_written += length;
  480. *buffer += length;
  481. *skip_bytes = 0;
  482. } else
  483. *skip_bytes -= length;
  484. free_pages((unsigned long)pages_start, 1);
  485. /* Now look at all of this device's children. */
  486. for (chix = 0; chix < usbdev->maxchild; chix++) {
  487. if (usbdev->children[chix]) {
  488. ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, usbdev->children[chix],
  489. bus, level + 1, chix, ++cnt);
  490. if (ret == -EFAULT)
  491. return total_written;
  492. total_written += ret;
  493. }
  494. }
  495. return total_written;
  496. }
  497. static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
  498. {
  499. struct list_head *buslist;
  500. struct usb_bus *bus;
  501. ssize_t ret, total_written = 0;
  502. loff_t skip_bytes = *ppos;
  503. if (*ppos < 0)
  504. return -EINVAL;
  505. if (nbytes <= 0)
  506. return 0;
  507. if (!access_ok(VERIFY_WRITE, buf, nbytes))
  508. return -EFAULT;
  509. /* enumerate busses */
  510. down (&usb_bus_list_lock);
  511. for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) {
  512. /* print devices for this bus */
  513. bus = list_entry(buslist, struct usb_bus, bus_list);
  514. /* recurse through all children of the root hub */
  515. ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
  516. if (ret < 0) {
  517. up(&usb_bus_list_lock);
  518. return ret;
  519. }
  520. total_written += ret;
  521. }
  522. up (&usb_bus_list_lock);
  523. return total_written;
  524. }
  525. /* Kernel lock for "lastev" protection */
  526. static unsigned int usb_device_poll(struct file *file, struct poll_table_struct *wait)
  527. {
  528. struct usb_device_status *st = (struct usb_device_status *)file->private_data;
  529. unsigned int mask = 0;
  530. lock_kernel();
  531. if (!st) {
  532. st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
  533. if (!st) {
  534. unlock_kernel();
  535. return POLLIN;
  536. }
  537. /*
  538.  * need to prevent the module from being unloaded, since
  539.  * proc_unregister does not call the release method and
  540.  * we would have a memory leak
  541.  */
  542. st->lastev = conndiscevcnt;
  543. file->private_data = st;
  544. mask = POLLIN;
  545. }
  546. if (file->f_mode & FMODE_READ)
  547.                 poll_wait(file, &deviceconndiscwq, wait);
  548. if (st->lastev != conndiscevcnt)
  549. mask |= POLLIN;
  550. st->lastev = conndiscevcnt;
  551. unlock_kernel();
  552. return mask;
  553. }
  554. static int usb_device_open(struct inode *inode, struct file *file)
  555. {
  556.         file->private_data = NULL;
  557.         return 0;
  558. }
  559. static int usb_device_release(struct inode *inode, struct file *file)
  560. {
  561. if (file->private_data) {
  562. kfree(file->private_data);
  563. file->private_data = NULL;
  564. }
  565.         return 0;
  566. }
  567. static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig)
  568. {
  569. switch (orig) {
  570. case 0:
  571. file->f_pos = offset;
  572. return file->f_pos;
  573. case 1:
  574. file->f_pos += offset;
  575. return file->f_pos;
  576. case 2:
  577. return -EINVAL;
  578. default:
  579. return -EINVAL;
  580. }
  581. }
  582. struct file_operations usbdevfs_devices_fops = {
  583. llseek: usb_device_lseek,
  584. read: usb_device_read,
  585. poll: usb_device_poll,
  586. open: usb_device_open,
  587. release: usb_device_release,
  588. };