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/uscanner.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: uscanner.c,v 1.45 2004/03/15 11:09:23 augustss Exp $   */
    2 
    3 /*
    4  * Copyright (c) 2000 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  * and Nick Hibma (n_hibma@qubesoft.com).
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *        This product includes software developed by the NetBSD
   23  *        Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 #include <sys/cdefs.h>
   42 __KERNEL_RCSID(0, "$NetBSD: uscanner.c,v 1.45 2004/03/15 11:09:23 augustss Exp $");
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/malloc.h>
   48 #if defined(__NetBSD__) || defined(__OpenBSD__)
   49 #include <sys/device.h>
   50 #elif defined(__FreeBSD__)
   51 #include <sys/module.h>
   52 #include <sys/bus.h>
   53 #include <sys/conf.h>
   54 #include <sys/fcntl.h>
   55 #include <sys/filio.h>
   56 #endif
   57 #include <sys/tty.h>
   58 #include <sys/file.h>
   59 #if defined(__FreeBSD__) && __FreeBSD_version >= 500014
   60 #include <sys/selinfo.h>
   61 #else
   62 #include <sys/select.h>
   63 #endif
   64 #include <sys/proc.h>
   65 #include <sys/vnode.h>
   66 #include <sys/poll.h>
   67 #include <sys/conf.h>
   68 
   69 #include <dev/usb/usb.h>
   70 #include <dev/usb/usbdi.h>
   71 #include <dev/usb/usbdi_util.h>
   72 
   73 #include <dev/usb/usbdevs.h>
   74 
   75 #ifdef USCANNER_DEBUG
   76 #define DPRINTF(x)      if (uscannerdebug) logprintf x
   77 #define DPRINTFN(n,x)   if (uscannerdebug>(n)) logprintf x
   78 int     uscannerdebug = 0;
   79 #else
   80 #define DPRINTF(x)
   81 #define DPRINTFN(n,x)
   82 #endif
   83 
   84 struct uscan_info {
   85         struct usb_devno devno;
   86         u_int flags;
   87 #define USC_KEEP_OPEN 1
   88 };
   89 
   90 /* Table of scanners that may work with this driver. */
   91 static const struct uscan_info uscanner_devs[] = {
   92   /* Acer Peripherals */
   93  {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U }, 0 },
   94  {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U }, 0 },
   95  {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U }, 0 },
   96  {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U }, 0 },
   97 
   98   /* AGFA */
   99  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U }, 0 },
  100  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U }, 0 },
  101  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2 }, 0 },
  102  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH }, 0 },
  103  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40 }, 0 },
  104  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50 }, 0 },
  105  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20 }, 0 },
  106  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25 }, 0 },
  107  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26 }, 0 },
  108  {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52 }, 0 },
  109 
  110   /* Avision */
  111  {{ USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U }, 0 },
  112 
  113   /* Canon */
  114  {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U }, 0 },
  115  {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N670U }, 0 },
  116  {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U }, 0 },
  117  {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U }, 0 },
  118 
  119   /* Kye */
  120  {{ USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO }, 0 },
  121 
  122   /* HP */
  123  {{ USB_VENDOR_HP, USB_PRODUCT_HP_2200C }, 0 },
  124  {{ USB_VENDOR_HP, USB_PRODUCT_HP_3300C }, 0 },
  125  {{ USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE }, 0 },
  126  {{ USB_VENDOR_HP, USB_PRODUCT_HP_4100C }, 0 },
  127  {{ USB_VENDOR_HP, USB_PRODUCT_HP_4200C }, 0 },
  128  {{ USB_VENDOR_HP, USB_PRODUCT_HP_4300C }, 0 },
  129  {{ USB_VENDOR_HP, USB_PRODUCT_HP_S20 }, 0 },
  130  {{ USB_VENDOR_HP, USB_PRODUCT_HP_5200C }, 0 },
  131 #if 0
  132   /* Handled by usscanner */
  133  {{ USB_VENDOR_HP, USB_PRODUCT_HP_5300C }, 0 },
  134 #endif
  135  {{ USB_VENDOR_HP, USB_PRODUCT_HP_6200C }, 0 },
  136  {{ USB_VENDOR_HP, USB_PRODUCT_HP_6300C }, 0 },
  137 
  138 #if 0
  139   /* XXX Should be handled by usscanner */
  140   /* Microtek */
  141  {{ USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX }, 0 },
  142  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U }, 0 },
  143  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX }, 0 },
  144  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2 }, 0 },
  145  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6 }, 0 },
  146  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL }, 0 },
  147  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2 }, 0 },
  148  {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL }, 0 },
  149 #endif
  150 
  151   /* Minolta */
  152  {{ USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400 }, 0 },
  153 
  154   /* Mustek */
  155  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU }, 0 },
  156  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F }, 0 },
  157  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA }, 0 },
  158  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB }, 0 },
  159  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU }, 0 },
  160  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB }, 0 },
  161  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB }, 0 },
  162  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS }, 0 },
  163  {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS }, 0 },
  164 
  165   /* National */
  166  {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200 }, 0 },
  167  {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400 }, 0 },
  168 
  169   /* Primax */
  170  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300 }, 0 },
  171  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300 }, 0 },
  172  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300 }, 0 },
  173  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002 }, 0 },
  174  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600 }, 0 },
  175  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U }, 0 },
  176  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200 }, 0 },
  177  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200 }, 0 },
  178  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U }, 0 },
  179  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600 }, 0 },
  180  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I }, 0 },
  181  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600 }, 0 },
  182  {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600 }, 0 },
  183 
  184   /* Epson */
  185  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636 }, 0 },
  186  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610 }, 0 },
  187  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200 }, 0 },
  188  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240 }, 0 },
  189  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250 }, 0 },
  190  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260 }, 0 },
  191  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600 }, 0 },
  192  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640 }, 0 },
  193  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660 }, 0 },
  194  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670 }, 0 },
  195  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U }, 0 },
  196  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650 }, 0 },
  197  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2400 }, 0 },
  198  {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F }, USC_KEEP_OPEN },
  199 
  200   /* UMAX */
  201  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
  202  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U }, 0 },
  203  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U }, 0 },
  204  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U }, 0 },
  205  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U }, 0 },
  206  {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400 }, 0 },
  207 
  208   /* Visioneer */
  209  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000 }, 0 },
  210  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300 }, 0 },
  211  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600 }, 0 },
  212  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100 }, 0 },
  213  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200 }, 0 },
  214  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100 }, 0 },
  215  {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600 }, 0 },
  216 
  217   /* Ultima */
  218  {{ USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS }, 0 },
  219 
  220 };
  221 #define uscanner_lookup(v, p) ((const struct uscan_info *)usb_lookup(uscanner_devs, v, p))
  222 
  223 #define USCANNER_BUFFERSIZE     1024
  224 
  225 struct uscanner_softc {
  226         USBBASEDEVICE           sc_dev;         /* base device */
  227         usbd_device_handle      sc_udev;
  228         usbd_interface_handle   sc_iface;
  229 
  230         u_int                   sc_dev_flags;
  231 
  232         usbd_pipe_handle        sc_bulkin_pipe;
  233         int                     sc_bulkin;
  234         usbd_xfer_handle        sc_bulkin_xfer;
  235         void                    *sc_bulkin_buffer;
  236         int                     sc_bulkin_bufferlen;
  237         int                     sc_bulkin_datalen;
  238 
  239         usbd_pipe_handle        sc_bulkout_pipe;
  240         int                     sc_bulkout;
  241         usbd_xfer_handle        sc_bulkout_xfer;
  242         void                    *sc_bulkout_buffer;
  243         int                     sc_bulkout_bufferlen;
  244         int                     sc_bulkout_datalen;
  245 
  246         struct selinfo          sc_selq;
  247 
  248         u_char                  sc_state;
  249 #define USCANNER_OPEN           0x01    /* opened */
  250 
  251         int                     sc_refcnt;
  252         u_char                  sc_dying;
  253 };
  254 
  255 #if defined(__NetBSD__)
  256 dev_type_open(uscanneropen);
  257 dev_type_close(uscannerclose);
  258 dev_type_read(uscannerread);
  259 dev_type_write(uscannerwrite);
  260 dev_type_ioctl(uscannerioctl);
  261 dev_type_poll(uscannerpoll);
  262 dev_type_kqfilter(uscannerkqfilter);
  263 
  264 const struct cdevsw uscanner_cdevsw = {
  265         uscanneropen, uscannerclose, uscannerread, uscannerwrite,
  266         uscannerioctl, nostop, notty, uscannerpoll, nommap, uscannerkqfilter,
  267 };
  268 #elif defined(__OpenBSD__)
  269 cdev_decl(uscanner);
  270 #elif defined(__FreeBSD__)
  271 d_open_t  uscanneropen;
  272 d_close_t uscannerclose;
  273 d_read_t  uscannerread;
  274 d_write_t uscannerwrite;
  275 d_poll_t  uscannerpoll;
  276 
  277 #define USCANNER_CDEV_MAJOR     156
  278 
  279 Static struct cdevsw uscanner_cdevsw = {
  280         /* open */      uscanneropen,
  281         /* close */     uscannerclose,
  282         /* read */      uscannerread,
  283         /* write */     uscannerwrite,
  284         /* ioctl */     noioctl,
  285         /* poll */      uscannerpoll,
  286         /* mmap */      nommap,
  287         /* strategy */  nostrategy,
  288         /* name */      "uscanner",
  289         /* maj */       USCANNER_CDEV_MAJOR,
  290         /* dump */      nodump,
  291         /* psize */     nopsize,
  292         /* flags */     0,
  293 #if !defined(__FreeBSD__) || (__FreeBSD__ < 5)
  294         /* bmaj */      -1
  295 #endif
  296 };
  297 #endif
  298 
  299 Static int uscanner_do_read(struct uscanner_softc *, struct uio *, int);
  300 Static int uscanner_do_write(struct uscanner_softc *, struct uio *, int);
  301 Static void uscanner_do_close(struct uscanner_softc *);
  302 
  303 #define USCANNERUNIT(n) (minor(n))
  304 
  305 USB_DECLARE_DRIVER(uscanner);
  306 
  307 USB_MATCH(uscanner)
  308 {
  309         USB_MATCH_START(uscanner, uaa);
  310 
  311         if (uaa->iface != NULL)
  312                 return UMATCH_NONE;
  313 
  314         return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ?
  315                 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
  316 }
  317 
  318 USB_ATTACH(uscanner)
  319 {
  320         USB_ATTACH_START(uscanner, sc, uaa);
  321         usb_interface_descriptor_t *id = 0;
  322         usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
  323         char devinfo[1024];
  324         int i;
  325         usbd_status err;
  326 
  327         usbd_devinfo(uaa->device, 0, devinfo);
  328         USB_ATTACH_SETUP;
  329         printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
  330 
  331         sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
  332 
  333         sc->sc_udev = uaa->device;
  334 
  335         err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
  336         if (err) {
  337                 printf("%s: setting config no failed\n",
  338                     USBDEVNAME(sc->sc_dev));
  339                 USB_ATTACH_ERROR_RETURN;
  340         }
  341 
  342         /* XXX We only check the first interface */
  343         err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
  344         if (!err && sc->sc_iface)
  345             id = usbd_get_interface_descriptor(sc->sc_iface);
  346         if (err || id == 0) {
  347                 printf("%s: could not get interface descriptor, err=%d,id=%p\n",
  348                        USBDEVNAME(sc->sc_dev), err, id);
  349                 USB_ATTACH_ERROR_RETURN;
  350         }
  351 
  352         /* Find the two first bulk endpoints */
  353         for (i = 0 ; i < id->bNumEndpoints; i++) {
  354                 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
  355                 if (ed == 0) {
  356                         printf("%s: could not read endpoint descriptor\n",
  357                                USBDEVNAME(sc->sc_dev));
  358                         USB_ATTACH_ERROR_RETURN;
  359                 }
  360 
  361                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
  362                     && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
  363                         ed_bulkin = ed;
  364                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
  365                     && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
  366                         ed_bulkout = ed;
  367                 }
  368 
  369                 if (ed_bulkin && ed_bulkout)    /* found all we need */
  370                         break;
  371         }
  372 
  373         /* Verify that we goething sensible */
  374         if (ed_bulkin == NULL || ed_bulkout == NULL) {
  375                 printf("%s: bulk-in and/or bulk-out endpoint not found\n",
  376                         USBDEVNAME(sc->sc_dev));
  377                 USB_ATTACH_ERROR_RETURN;
  378         }
  379 
  380         sc->sc_bulkin = ed_bulkin->bEndpointAddress;
  381         sc->sc_bulkout = ed_bulkout->bEndpointAddress;
  382 
  383 #ifdef __FreeBSD__
  384         /* the main device, ctrl endpoint */
  385         make_dev(&uscanner_cdevsw, USBDEVUNIT(sc->sc_dev),
  386                 UID_ROOT, GID_OPERATOR, 0644, "%s", USBDEVNAME(sc->sc_dev));
  387 #endif
  388 
  389         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
  390                            USBDEV(sc->sc_dev));
  391 
  392         USB_ATTACH_SUCCESS_RETURN;
  393 }
  394 
  395 int
  396 uscanneropen(dev_t dev, int flag, int mode, usb_proc_ptr p)
  397 {
  398         struct uscanner_softc *sc;
  399         int unit = USCANNERUNIT(dev);
  400         usbd_status err;
  401 
  402         USB_GET_SC_OPEN(uscanner, unit, sc);
  403 
  404         DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n",
  405                      flag, mode, unit));
  406 
  407         if (sc->sc_dying)
  408                 return (ENXIO);
  409 
  410         if (sc->sc_state & USCANNER_OPEN)
  411                 return (EBUSY);
  412 
  413         sc->sc_state |= USCANNER_OPEN;
  414 
  415         sc->sc_bulkin_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
  416         sc->sc_bulkout_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
  417         /* No need to check buffers for NULL since we have WAITOK */
  418 
  419         sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE;
  420         sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE;
  421 
  422         /* We have decided on which endpoints to use, now open the pipes */
  423         if (sc->sc_bulkin_pipe == NULL) {
  424                 err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin,
  425                                      USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
  426                 if (err) {
  427                         printf("%s: cannot open bulk-in pipe (addr %d)\n",
  428                                USBDEVNAME(sc->sc_dev), sc->sc_bulkin);
  429                         uscanner_do_close(sc);
  430                         return (EIO);
  431                 }
  432         }
  433         if (sc->sc_bulkout_pipe == NULL) {
  434                 err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout,
  435                                      USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
  436                 if (err) {
  437                         printf("%s: cannot open bulk-out pipe (addr %d)\n",
  438                                USBDEVNAME(sc->sc_dev), sc->sc_bulkout);
  439                         uscanner_do_close(sc);
  440                         return (EIO);
  441                 }
  442         }
  443 
  444         sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev);
  445         if (sc->sc_bulkin_xfer == NULL) {
  446                 uscanner_do_close(sc);
  447                 return (ENOMEM);
  448         }
  449         sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev);
  450         if (sc->sc_bulkout_xfer == NULL) {
  451                 uscanner_do_close(sc);
  452                 return (ENOMEM);
  453         }
  454 
  455         return (0);     /* success */
  456 }
  457 
  458 int
  459 uscannerclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
  460 {
  461         struct uscanner_softc *sc;
  462 
  463         USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
  464 
  465         DPRINTFN(5, ("uscannerclose: flag=%d, mode=%d, unit=%d\n",
  466                      flag, mode, USCANNERUNIT(dev)));
  467 
  468 #ifdef DIAGNOSTIC
  469         if (!(sc->sc_state & USCANNER_OPEN)) {
  470                 printf("uscannerclose: not open\n");
  471                 return (EINVAL);
  472         }
  473 #endif
  474 
  475         uscanner_do_close(sc);
  476 
  477         return (0);
  478 }
  479 
  480 void
  481 uscanner_do_close(struct uscanner_softc *sc)
  482 {
  483         if (sc->sc_bulkin_xfer) {
  484                 usbd_free_xfer(sc->sc_bulkin_xfer);
  485                 sc->sc_bulkin_xfer = NULL;
  486         }
  487         if (sc->sc_bulkout_xfer) {
  488                 usbd_free_xfer(sc->sc_bulkout_xfer);
  489                 sc->sc_bulkout_xfer = NULL;
  490         }
  491 
  492         if (!(sc->sc_dev_flags & USC_KEEP_OPEN)) {
  493                 if (sc->sc_bulkin_pipe != NULL) {
  494                         usbd_abort_pipe(sc->sc_bulkin_pipe);
  495                         usbd_close_pipe(sc->sc_bulkin_pipe);
  496                         sc->sc_bulkin_pipe = NULL;
  497                 }
  498                 if (sc->sc_bulkout_pipe != NULL) {
  499                         usbd_abort_pipe(sc->sc_bulkout_pipe);
  500                         usbd_close_pipe(sc->sc_bulkout_pipe);
  501                         sc->sc_bulkout_pipe = NULL;
  502                 }
  503         }
  504 
  505         if (sc->sc_bulkin_buffer) {
  506                 free(sc->sc_bulkin_buffer, M_USBDEV);
  507                 sc->sc_bulkin_buffer = NULL;
  508         }
  509         if (sc->sc_bulkout_buffer) {
  510                 free(sc->sc_bulkout_buffer, M_USBDEV);
  511                 sc->sc_bulkout_buffer = NULL;
  512         }
  513 
  514         sc->sc_state &= ~USCANNER_OPEN;
  515 }
  516 
  517 Static int
  518 uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
  519 {
  520         u_int32_t n, tn;
  521         usbd_status err;
  522         int error = 0;
  523 
  524         DPRINTFN(5, ("%s: uscannerread\n", USBDEVNAME(sc->sc_dev)));
  525 
  526         if (sc->sc_dying)
  527                 return (EIO);
  528 
  529         while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) {
  530                 DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n));
  531                 tn = n;
  532 
  533                 err = usbd_bulk_transfer(
  534                         sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
  535                         USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
  536                         sc->sc_bulkin_buffer, &tn,
  537                         "uscnrb");
  538                 if (err) {
  539                         if (err == USBD_INTERRUPTED)
  540                                 error = EINTR;
  541                         else if (err == USBD_TIMEOUT)
  542                                 error = ETIMEDOUT;
  543                         else
  544                                 error = EIO;
  545                         break;
  546                 }
  547                 DPRINTFN(1, ("uscannerread: got %d bytes\n", tn));
  548                 error = uiomove(sc->sc_bulkin_buffer, tn, uio);
  549                 if (error || tn < n)
  550                         break;
  551         }
  552 
  553         return (error);
  554 }
  555 
  556 int
  557 uscannerread(dev_t dev, struct uio *uio, int flag)
  558 {
  559         struct uscanner_softc *sc;
  560         int error;
  561 
  562         USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
  563 
  564         sc->sc_refcnt++;
  565         error = uscanner_do_read(sc, uio, flag);
  566         if (--sc->sc_refcnt < 0)
  567                 usb_detach_wakeup(USBDEV(sc->sc_dev));
  568 
  569         return (error);
  570 }
  571 
  572 Static int
  573 uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
  574 {
  575         u_int32_t n;
  576         int error = 0;
  577         usbd_status err;
  578 
  579         DPRINTFN(5, ("%s: uscanner_do_write\n", USBDEVNAME(sc->sc_dev)));
  580 
  581         if (sc->sc_dying)
  582                 return (EIO);
  583 
  584         while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) {
  585                 error = uiomove(sc->sc_bulkout_buffer, n, uio);
  586                 if (error)
  587                         break;
  588                 DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n));
  589                 err = usbd_bulk_transfer(
  590                         sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
  591                         0, USBD_NO_TIMEOUT,
  592                         sc->sc_bulkout_buffer, &n,
  593                         "uscnwb");
  594                 if (err) {
  595                         if (err == USBD_INTERRUPTED)
  596                                 error = EINTR;
  597                         else
  598                                 error = EIO;
  599                         break;
  600                 }
  601         }
  602 
  603         return (error);
  604 }
  605 
  606 int
  607 uscannerwrite(dev_t dev, struct uio *uio, int flag)
  608 {
  609         struct uscanner_softc *sc;
  610         int error;
  611 
  612         USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
  613 
  614         sc->sc_refcnt++;
  615         error = uscanner_do_write(sc, uio, flag);
  616         if (--sc->sc_refcnt < 0)
  617                 usb_detach_wakeup(USBDEV(sc->sc_dev));
  618         return (error);
  619 }
  620 
  621 #if defined(__NetBSD__) || defined(__OpenBSD__)
  622 int
  623 uscanner_activate(device_ptr_t self, enum devact act)
  624 {
  625         struct uscanner_softc *sc = (struct uscanner_softc *)self;
  626 
  627         switch (act) {
  628         case DVACT_ACTIVATE:
  629                 return (EOPNOTSUPP);
  630 
  631         case DVACT_DEACTIVATE:
  632                 sc->sc_dying = 1;
  633                 break;
  634         }
  635         return (0);
  636 }
  637 #endif
  638 
  639 USB_DETACH(uscanner)
  640 {
  641         USB_DETACH_START(uscanner, sc);
  642         int s;
  643 #if defined(__NetBSD__) || defined(__OpenBSD__)
  644         int maj, mn;
  645 #elif defined(__FreeBSD__)
  646         dev_t dev;
  647         struct vnode *vp;
  648 #endif
  649 
  650 #if defined(__NetBSD__) || defined(__OpenBSD__)
  651         DPRINTF(("uscanner_detach: sc=%p flags=%d\n", sc, flags));
  652 #elif defined(__FreeBSD__)
  653         DPRINTF(("uscanner_detach: sc=%p\n", sc));
  654 #endif
  655 
  656         sc->sc_dying = 1;
  657         sc->sc_dev_flags = 0;   /* make close really close device */
  658 
  659         /* Abort all pipes.  Causes processes waiting for transfer to wake. */
  660         if (sc->sc_bulkin_pipe != NULL)
  661                 usbd_abort_pipe(sc->sc_bulkin_pipe);
  662         if (sc->sc_bulkout_pipe != NULL)
  663                 usbd_abort_pipe(sc->sc_bulkout_pipe);
  664 
  665         s = splusb();
  666         if (--sc->sc_refcnt >= 0) {
  667                 /* Wait for processes to go away. */
  668                 usb_detach_wait(USBDEV(sc->sc_dev));
  669         }
  670         splx(s);
  671 
  672 #if defined(__NetBSD__) || defined(__OpenBSD__)
  673         /* locate the major number */
  674 #if defined(__NetBSD__)
  675         maj = cdevsw_lookup_major(&uscanner_cdevsw);
  676 #elif defined(__OpenBSD__)
  677         for (maj = 0; maj < nchrdev; maj++)
  678                 if (cdevsw[maj].d_open == uscanneropen)
  679                         break;
  680 #endif
  681 
  682         /* Nuke the vnodes for any open instances (calls close). */
  683         mn = self->dv_unit * USB_MAX_ENDPOINTS;
  684         vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
  685 #elif defined(__FreeBSD__)
  686         /* destroy the device for the control endpoint */
  687         dev = makedev(USCANNER_CDEV_MAJOR, USBDEVUNIT(sc->sc_dev));
  688         vp = SLIST_FIRST(&dev->si_hlist);
  689         if (vp)
  690                 VOP_REVOKE(vp, REVOKEALL);
  691         destroy_dev(dev);
  692 #endif
  693 
  694         usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
  695                            USBDEV(sc->sc_dev));
  696 
  697         return (0);
  698 }
  699 
  700 int
  701 uscannerpoll(dev_t dev, int events, usb_proc_ptr p)
  702 {
  703         struct uscanner_softc *sc;
  704         int revents = 0;
  705 
  706         USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
  707 
  708         if (sc->sc_dying)
  709                 return (EIO);
  710 
  711         /*
  712          * We have no easy way of determining if a read will
  713          * yield any data or a write will happen.
  714          * Pretend they will.
  715          */
  716         revents |= events &
  717                    (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
  718 
  719         return (revents);
  720 }
  721 
  722 static void
  723 filt_uscannerdetach(struct knote *kn)
  724 {
  725         struct uscanner_softc *sc = kn->kn_hook;
  726 
  727         SLIST_REMOVE(&sc->sc_selq.sel_klist, kn, knote, kn_selnext);
  728 }
  729 
  730 static const struct filterops uscanner_seltrue_filtops =
  731         { 1, NULL, filt_uscannerdetach, filt_seltrue };
  732 
  733 int
  734 uscannerkqfilter(dev_t dev, struct knote *kn)
  735 {
  736         struct uscanner_softc *sc;
  737         struct klist *klist;
  738 
  739         USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
  740 
  741         if (sc->sc_dying)
  742                 return (1);
  743 
  744         switch (kn->kn_filter) {
  745         case EVFILT_READ:
  746         case EVFILT_WRITE:
  747                 /* 
  748                  * We have no easy way of determining if a read will
  749                  * yield any data or a write will happen.
  750                  * Pretend they will.
  751                  */
  752                 klist = &sc->sc_selq.sel_klist;
  753                 kn->kn_fop = &uscanner_seltrue_filtops;
  754                 break;
  755 
  756         default:
  757                 return (1);
  758         }
  759 
  760         kn->kn_hook = sc;
  761 
  762         SLIST_INSERT_HEAD(klist, kn, kn_selnext);
  763 
  764         return (0);
  765 }
  766 
  767 int
  768 uscannerioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
  769 {
  770         return (EINVAL);
  771 }
  772 
  773 #if defined(__FreeBSD__)
  774 DRIVER_MODULE(uscanner, uhub, uscanner_driver, uscanner_devclass, usbd_driver_load, 0);
  775 #endif

Cache object: f3f66ad9aa99993bf08ade5879f6c630


[ 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.