The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/usbdi_util.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: usbdi_util.c,v 1.42 2004/12/03 08:53:40 augustss Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Lennart Augustsson (lennart@augustsson.net) at
    9  * Carlstedt Research & Technology.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD: releng/7.3/sys/dev/usb/usbdi_util.c 170960 2007-06-20 05:11:37Z imp $");
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/kernel.h>
   46 #include <sys/module.h>
   47 #include <sys/malloc.h>
   48 #include <sys/bus.h>
   49 
   50 #include <dev/usb/usb.h>
   51 #include <dev/usb/usbhid.h>
   52 
   53 #include <dev/usb/usbdi.h>
   54 #include <dev/usb/usbdi_util.h>
   55 
   56 #ifdef USB_DEBUG
   57 #define DPRINTF(x)      if (usbdebug) printf x
   58 #define DPRINTFN(n,x)   if (usbdebug>(n)) printf x
   59 extern int usbdebug;
   60 #else
   61 #define DPRINTF(x)
   62 #define DPRINTFN(n,x)
   63 #endif
   64 
   65 usbd_status
   66 usbd_get_desc(usbd_device_handle dev, int type, int index, int len, void *desc)
   67 {
   68         usb_device_request_t req;
   69 
   70         DPRINTFN(3,("usbd_get_desc: type=%d, index=%d, len=%d\n",
   71                     type, index, len));
   72 
   73         req.bmRequestType = UT_READ_DEVICE;
   74         req.bRequest = UR_GET_DESCRIPTOR;
   75         USETW2(req.wValue, type, index);
   76         USETW(req.wIndex, 0);
   77         USETW(req.wLength, len);
   78         return (usbd_do_request(dev, &req, desc));
   79 }
   80 
   81 usbd_status
   82 usbd_get_config_desc(usbd_device_handle dev, int confidx,
   83                      usb_config_descriptor_t *d)
   84 {
   85         usbd_status err;
   86 
   87         DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", confidx));
   88         err = usbd_get_desc(dev, UDESC_CONFIG, confidx,
   89                             USB_CONFIG_DESCRIPTOR_SIZE, d);
   90         if (err)
   91                 return (err);
   92         if (d->bDescriptorType != UDESC_CONFIG) {
   93                 DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc "
   94                              "len=%d type=%d\n",
   95                              confidx, d->bLength, d->bDescriptorType));
   96                 return (USBD_INVAL);
   97         }
   98         return (USBD_NORMAL_COMPLETION);
   99 }
  100 
  101 usbd_status
  102 usbd_get_config_desc_full(usbd_device_handle dev, int conf, void *d, int size)
  103 {
  104         DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf));
  105         return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d));
  106 }
  107 
  108 usbd_status
  109 usbd_get_device_desc(usbd_device_handle dev, usb_device_descriptor_t *d)
  110 {
  111         DPRINTFN(3,("usbd_get_device_desc:\n"));
  112         return (usbd_get_desc(dev, UDESC_DEVICE,
  113                              0, USB_DEVICE_DESCRIPTOR_SIZE, d));
  114 }
  115 
  116 usbd_status
  117 usbd_get_device_status(usbd_device_handle dev, usb_status_t *st)
  118 {
  119         usb_device_request_t req;
  120 
  121         req.bmRequestType = UT_READ_DEVICE;
  122         req.bRequest = UR_GET_STATUS;
  123         USETW(req.wValue, 0);
  124         USETW(req.wIndex, 0);
  125         USETW(req.wLength, sizeof(usb_status_t));
  126         return (usbd_do_request(dev, &req, st));
  127 }
  128 
  129 usbd_status
  130 usbd_get_hub_status(usbd_device_handle dev, usb_hub_status_t *st)
  131 {
  132         usb_device_request_t req;
  133 
  134         req.bmRequestType = UT_READ_CLASS_DEVICE;
  135         req.bRequest = UR_GET_STATUS;
  136         USETW(req.wValue, 0);
  137         USETW(req.wIndex, 0);
  138         USETW(req.wLength, sizeof(usb_hub_status_t));
  139         return (usbd_do_request(dev, &req, st));
  140 }
  141 
  142 usbd_status
  143 usbd_set_address(usbd_device_handle dev, int addr)
  144 {
  145         usb_device_request_t req;
  146 
  147         req.bmRequestType = UT_WRITE_DEVICE;
  148         req.bRequest = UR_SET_ADDRESS;
  149         USETW(req.wValue, addr);
  150         USETW(req.wIndex, 0);
  151         USETW(req.wLength, 0);
  152         return usbd_do_request(dev, &req, 0);
  153 }
  154 
  155 usbd_status
  156 usbd_get_port_status(usbd_device_handle dev, int port, usb_port_status_t *ps)
  157 {
  158         usb_device_request_t req;
  159 
  160         req.bmRequestType = UT_READ_CLASS_OTHER;
  161         req.bRequest = UR_GET_STATUS;
  162         USETW(req.wValue, 0);
  163         USETW(req.wIndex, port);
  164         USETW(req.wLength, sizeof *ps);
  165         return (usbd_do_request(dev, &req, ps));
  166 }
  167 
  168 usbd_status
  169 usbd_clear_hub_feature(usbd_device_handle dev, int sel)
  170 {
  171         usb_device_request_t req;
  172 
  173         req.bmRequestType = UT_WRITE_CLASS_DEVICE;
  174         req.bRequest = UR_CLEAR_FEATURE;
  175         USETW(req.wValue, sel);
  176         USETW(req.wIndex, 0);
  177         USETW(req.wLength, 0);
  178         return (usbd_do_request(dev, &req, 0));
  179 }
  180 
  181 usbd_status
  182 usbd_set_hub_feature(usbd_device_handle dev, int sel)
  183 {
  184         usb_device_request_t req;
  185 
  186         req.bmRequestType = UT_WRITE_CLASS_DEVICE;
  187         req.bRequest = UR_SET_FEATURE;
  188         USETW(req.wValue, sel);
  189         USETW(req.wIndex, 0);
  190         USETW(req.wLength, 0);
  191         return (usbd_do_request(dev, &req, 0));
  192 }
  193 
  194 usbd_status
  195 usbd_clear_port_feature(usbd_device_handle dev, int port, int sel)
  196 {
  197         usb_device_request_t req;
  198 
  199         req.bmRequestType = UT_WRITE_CLASS_OTHER;
  200         req.bRequest = UR_CLEAR_FEATURE;
  201         USETW(req.wValue, sel);
  202         USETW(req.wIndex, port);
  203         USETW(req.wLength, 0);
  204         return (usbd_do_request(dev, &req, 0));
  205 }
  206 
  207 usbd_status
  208 usbd_set_port_feature(usbd_device_handle dev, int port, int sel)
  209 {
  210         usb_device_request_t req;
  211 
  212         req.bmRequestType = UT_WRITE_CLASS_OTHER;
  213         req.bRequest = UR_SET_FEATURE;
  214         USETW(req.wValue, sel);
  215         USETW(req.wIndex, port);
  216         USETW(req.wLength, 0);
  217         return (usbd_do_request(dev, &req, 0));
  218 }
  219 
  220 usbd_status
  221 usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report)
  222 {
  223         usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
  224         usbd_device_handle dev;
  225         usb_device_request_t req;
  226 
  227         DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n",
  228                      iface, id->bInterfaceNumber));
  229         if (id == NULL)
  230                 return (USBD_IOERROR);
  231         usbd_interface2device_handle(iface, &dev);
  232         req.bmRequestType = UT_READ_CLASS_INTERFACE;
  233         req.bRequest = UR_GET_PROTOCOL;
  234         USETW(req.wValue, 0);
  235         USETW(req.wIndex, id->bInterfaceNumber);
  236         USETW(req.wLength, 1);
  237         return (usbd_do_request(dev, &req, report));
  238 }
  239 
  240 usbd_status
  241 usbd_set_protocol(usbd_interface_handle iface, int report)
  242 {
  243         usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
  244         usbd_device_handle dev;
  245         usb_device_request_t req;
  246 
  247         DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
  248                      iface, report, id->bInterfaceNumber));
  249         if (id == NULL)
  250                 return (USBD_IOERROR);
  251         usbd_interface2device_handle(iface, &dev);
  252         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
  253         req.bRequest = UR_SET_PROTOCOL;
  254         USETW(req.wValue, report);
  255         USETW(req.wIndex, id->bInterfaceNumber);
  256         USETW(req.wLength, 0);
  257         return (usbd_do_request(dev, &req, 0));
  258 }
  259 
  260 usbd_status
  261 usbd_set_report(usbd_interface_handle iface, int type, int id, void *data,
  262                 int len)
  263 {
  264         usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
  265         usbd_device_handle dev;
  266         usb_device_request_t req;
  267 
  268         DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
  269         if (ifd == NULL)
  270                 return (USBD_IOERROR);
  271         usbd_interface2device_handle(iface, &dev);
  272         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
  273         req.bRequest = UR_SET_REPORT;
  274         USETW2(req.wValue, type, id);
  275         USETW(req.wIndex, ifd->bInterfaceNumber);
  276         USETW(req.wLength, len);
  277         return (usbd_do_request(dev, &req, data));
  278 }
  279 
  280 usbd_status
  281 usbd_set_report_async(usbd_interface_handle iface, int type, int id, void *data,
  282                       int len)
  283 {
  284         usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
  285         usbd_device_handle dev;
  286         usb_device_request_t req;
  287 
  288         DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
  289         if (ifd == NULL)
  290                 return (USBD_IOERROR);
  291         usbd_interface2device_handle(iface, &dev);
  292         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
  293         req.bRequest = UR_SET_REPORT;
  294         USETW2(req.wValue, type, id);
  295         USETW(req.wIndex, ifd->bInterfaceNumber);
  296         USETW(req.wLength, len);
  297         return (usbd_do_request_async(dev, &req, data));
  298 }
  299 
  300 usbd_status
  301 usbd_get_report(usbd_interface_handle iface, int type, int id, void *data,
  302                 int len)
  303 {
  304         usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
  305         usbd_device_handle dev;
  306         usb_device_request_t req;
  307 
  308         DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
  309         if (ifd == NULL)
  310                 return (USBD_IOERROR);
  311         usbd_interface2device_handle(iface, &dev);
  312         req.bmRequestType = UT_READ_CLASS_INTERFACE;
  313         req.bRequest = UR_GET_REPORT;
  314         USETW2(req.wValue, type, id);
  315         USETW(req.wIndex, ifd->bInterfaceNumber);
  316         USETW(req.wLength, len);
  317         return (usbd_do_request(dev, &req, data));
  318 }
  319 
  320 usbd_status
  321 usbd_set_idle(usbd_interface_handle iface, int duration, int id)
  322 {
  323         usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
  324         usbd_device_handle dev;
  325         usb_device_request_t req;
  326 
  327         DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
  328         if (ifd == NULL)
  329                 return (USBD_IOERROR);
  330         usbd_interface2device_handle(iface, &dev);
  331         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
  332         req.bRequest = UR_SET_IDLE;
  333         USETW2(req.wValue, duration, id);
  334         USETW(req.wIndex, ifd->bInterfaceNumber);
  335         USETW(req.wLength, 0);
  336         return (usbd_do_request(dev, &req, 0));
  337 }
  338 
  339 usbd_status
  340 usbd_get_report_descriptor(usbd_device_handle dev, int ifcno,
  341                            int size, void *d)
  342 {
  343         usb_device_request_t req;
  344 
  345         req.bmRequestType = UT_READ_INTERFACE;
  346         req.bRequest = UR_GET_DESCRIPTOR;
  347         USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */
  348         USETW(req.wIndex, ifcno);
  349         USETW(req.wLength, size);
  350         return (usbd_do_request(dev, &req, d));
  351 }
  352 
  353 usb_hid_descriptor_t *
  354 usbd_get_hid_descriptor(usbd_interface_handle ifc)
  355 {
  356         usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc);
  357         usbd_device_handle dev;
  358         usb_config_descriptor_t *cdesc;
  359         usb_hid_descriptor_t *hd;
  360         char *p, *end;
  361 
  362         if (idesc == NULL)
  363                 return (NULL);
  364         usbd_interface2device_handle(ifc, &dev);
  365         cdesc = usbd_get_config_descriptor(dev);
  366 
  367         p = (char *)idesc + idesc->bLength;
  368         end = (char *)cdesc + UGETW(cdesc->wTotalLength);
  369 
  370         for (; p < end; p += hd->bLength) {
  371                 hd = (usb_hid_descriptor_t *)p;
  372                 if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
  373                         return (hd);
  374                 if (hd->bDescriptorType == UDESC_INTERFACE)
  375                         break;
  376         }
  377         return (NULL);
  378 }
  379 
  380 usbd_status
  381 usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep,
  382                       struct malloc_type *mem)
  383 {
  384         usb_interface_descriptor_t *id;
  385         usb_hid_descriptor_t *hid;
  386         usbd_device_handle dev;
  387         usbd_status err;
  388 
  389         usbd_interface2device_handle(ifc, &dev);
  390         id = usbd_get_interface_descriptor(ifc);
  391         if (id == NULL)
  392                 return (USBD_INVAL);
  393         hid = usbd_get_hid_descriptor(ifc);
  394         if (hid == NULL)
  395                 return (USBD_IOERROR);
  396         *sizep = UGETW(hid->descrs[0].wDescriptorLength);
  397         *descp = malloc(*sizep, mem, M_NOWAIT);
  398         if (*descp == NULL)
  399                 return (USBD_NOMEM);
  400         err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
  401                                          *sizep, *descp);
  402         if (err) {
  403                 free(*descp, mem);
  404                 *descp = NULL;
  405                 return (err);
  406         }
  407         return (USBD_NORMAL_COMPLETION);
  408 }
  409 
  410 usbd_status
  411 usbd_get_config(usbd_device_handle dev, u_int8_t *conf)
  412 {
  413         usb_device_request_t req;
  414 
  415         req.bmRequestType = UT_READ_DEVICE;
  416         req.bRequest = UR_GET_CONFIG;
  417         USETW(req.wValue, 0);
  418         USETW(req.wIndex, 0);
  419         USETW(req.wLength, 1);
  420         return (usbd_do_request(dev, &req, conf));
  421 }
  422 
  423 static void usbd_bulk_transfer_cb(usbd_xfer_handle xfer,
  424                                   usbd_private_handle priv, usbd_status status);
  425 static void
  426 usbd_bulk_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
  427                       usbd_status status)
  428 {
  429         wakeup(xfer);
  430 }
  431 
  432 usbd_status
  433 usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
  434                    u_int16_t flags, u_int32_t timeout, void *buf,
  435                    u_int32_t *size, char *lbl)
  436 {
  437         usbd_status err;
  438         int s, error;
  439 
  440         usbd_setup_xfer(xfer, pipe, 0, buf, *size,
  441                         flags, timeout, usbd_bulk_transfer_cb);
  442         DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
  443         s = splusb();           /* don't want callback until tsleep() */
  444         err = usbd_transfer(xfer);
  445         if (err != USBD_IN_PROGRESS) {
  446                 splx(s);
  447                 return (err);
  448         }
  449         error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
  450         splx(s);
  451         if (error) {
  452                 DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
  453                 usbd_abort_pipe(pipe);
  454                 return (USBD_INTERRUPTED);
  455         }
  456         usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
  457         DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
  458         if (err) {
  459                 DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
  460                 usbd_clear_endpoint_stall(pipe);
  461         }
  462         return (err);
  463 }
  464 
  465 static void usbd_intr_transfer_cb(usbd_xfer_handle xfer,
  466                                   usbd_private_handle priv, usbd_status status);
  467 static void
  468 usbd_intr_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
  469                       usbd_status status)
  470 {
  471         wakeup(xfer);
  472 }
  473 
  474 usbd_status
  475 usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
  476                    u_int16_t flags, u_int32_t timeout, void *buf,
  477                    u_int32_t *size, char *lbl)
  478 {
  479         usbd_status err;
  480         int s, error;
  481 
  482         usbd_setup_xfer(xfer, pipe, 0, buf, *size,
  483                         flags, timeout, usbd_intr_transfer_cb);
  484         DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
  485         s = splusb();           /* don't want callback until tsleep() */
  486         err = usbd_transfer(xfer);
  487         if (err != USBD_IN_PROGRESS) {
  488                 splx(s);
  489                 return (err);
  490         }
  491         error = tsleep(xfer, PZERO | PCATCH, lbl, 0);
  492         splx(s);
  493         if (error) {
  494                 DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error));
  495                 usbd_abort_pipe(pipe);
  496                 return (USBD_INTERRUPTED);
  497         }
  498         usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
  499         DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
  500         if (err) {
  501                 DPRINTF(("usbd_intr_transfer: error=%d\n", err));
  502                 usbd_clear_endpoint_stall(pipe);
  503         }
  504         return (err);
  505 }
  506 
  507 void
  508 usb_detach_wait(device_t dv)
  509 {
  510         DPRINTF(("usb_detach_wait: waiting for %s\n", device_get_nameunit(dv)));
  511         if (tsleep(dv, PZERO, "usbdet", hz * 60))
  512                 printf("usb_detach_wait: %s didn't detach\n",
  513                         device_get_nameunit(dv));
  514         DPRINTF(("usb_detach_wait: %s done\n", device_get_nameunit(dv)));
  515 }
  516 
  517 void
  518 usb_detach_wakeup(device_t dv)
  519 {
  520         DPRINTF(("usb_detach_wakeup: for %s\n", device_get_nameunit(dv)));
  521         wakeup(dv);
  522 }
  523 
  524 const usb_descriptor_t *
  525 usb_find_desc(usbd_device_handle dev, int type, int subtype)
  526 {
  527         usbd_desc_iter_t iter;
  528         const usb_descriptor_t *desc;
  529 
  530         usb_desc_iter_init(dev, &iter);
  531         for (;;) {
  532                 desc = usb_desc_iter_next(&iter);
  533                 if (!desc || (desc->bDescriptorType == type &&
  534                               (subtype == USBD_SUBTYPE_ANY ||
  535                                subtype == desc->bDescriptorSubtype)))
  536                         break;
  537         }
  538         return desc;
  539 }

Cache object: 619f4c6d5ce6a0ccaa798647df64a991


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.