Merge from vendor branch GDB:
[dragonfly.git] / sys / dev / usbmisc / uscanner / uscanner.c
1 /* 
2  * $NetBSD: uscanner.c,v 1.30 2002/07/11 21:14:36 augustss Exp $
3  * $FreeBSD: src/sys/dev/usb/uscanner.c,v 1.48 2003/12/22 19:58:27 sanpei Exp $
4  * $DragonFly: src/sys/dev/usbmisc/uscanner/uscanner.c,v 1.26 2007/11/06 07:37:01 hasso Exp $
5  */
6
7 /* Also already merged from NetBSD:
8  *      $NetBSD: uscanner.c,v 1.33 2002/09/23 05:51:24 simonb Exp $
9  */
10
11 /*
12  * Copyright (c) 2000 The NetBSD Foundation, Inc.
13  * All rights reserved.
14  *
15  * This code is derived from software contributed to The NetBSD Foundation
16  * by Lennart Augustsson (lennart@augustsson.net) at
17  * Carlstedt Research & Technology
18  * and Nick Hibma (n_hibma@qubesoft.com).
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions
22  * are met:
23  * 1. Redistributions of source code must retain the above copyright
24  *    notice, this list of conditions and the following disclaimer.
25  * 2. Redistributions in binary form must reproduce the above copyright
26  *    notice, this list of conditions and the following disclaimer in the
27  *    documentation and/or other materials provided with the distribution.
28  * 3. All advertising materials mentioning features or use of this software
29  *    must display the following acknowledgement:
30  *        This product includes software developed by the NetBSD
31  *        Foundation, Inc. and its contributors.
32  * 4. Neither the name of The NetBSD Foundation nor the names of its
33  *    contributors may be used to endorse or promote products derived
34  *    from this software without specific prior written permission.
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
37  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46  * POSSIBILITY OF SUCH DAMAGE.
47  */
48
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/malloc.h>
54 #include <sys/module.h>
55 #include <sys/bus.h>
56 #include <sys/conf.h>
57 #include <sys/fcntl.h>
58 #include <sys/filio.h>
59 #include <sys/tty.h>
60 #include <sys/file.h>
61 #include <sys/select.h>
62 #include <sys/proc.h>
63 #include <sys/poll.h>
64 #include <sys/conf.h>
65 #include <sys/sysctl.h>
66 #include <sys/thread2.h>
67
68 #include <bus/usb/usb.h>
69 #include <bus/usb/usbdi.h>
70 #include <bus/usb/usbdi_util.h>
71
72 #ifdef USB_DEBUG
73 #define DPRINTF(x)      if (uscannerdebug) kprintf x
74 #define DPRINTFN(n,x)   if (uscannerdebug>(n)) kprintf x
75 int     uscannerdebug = 0;
76 SYSCTL_NODE(_hw_usb, OID_AUTO, uscanner, CTLFLAG_RW, 0, "USB uscanner");
77 SYSCTL_INT(_hw_usb_uscanner, OID_AUTO, debug, CTLFLAG_RW,
78            &uscannerdebug, 0, "uscanner debug level");
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_DEVICE(0x04a5, 0x2022) }, 0 }, /* Acerscan 320U */
94  {{ USB_DEVICE(0x04a5, 0x2040) }, 0 }, /* Acerscan 640U */
95  {{ USB_DEVICE(0x04a5, 0x2060) }, 0 }, /* Acerscan 620U */
96  {{ USB_DEVICE(0x04a5, 0x12a6) }, 0 }, /* Acerscan C310U */
97   /* AGFA */
98  {{ USB_DEVICE(0x06bd, 0x0002) }, 0 }, /* SnapScan 1236U */
99  {{ USB_DEVICE(0x06bd, 0x0001) }, 0 }, /* SnapScan 1212U */
100  {{ USB_DEVICE(0x06bd, 0x2061) }, 0 }, /* SnapScan 1212U */
101  {{ USB_DEVICE(0x06bd, 0x0100) }, 0 }, /* SnapScan Touch */
102  {{ USB_DEVICE(0x06bd, 0x208d) }, 0 }, /* SnapScan e40 */
103  {{ USB_DEVICE(0x06bd, 0x208f) }, 0 }, /* SnapScan e50 */
104  {{ USB_DEVICE(0x06bd, 0x2091) }, 0 }, /* SnapScan e20 */
105  {{ USB_DEVICE(0x06bd, 0x2095) }, 0 }, /* SnapScan e25 */
106  {{ USB_DEVICE(0x06bd, 0x2097) }, 0 }, /* SnapScan e26 */
107  {{ USB_DEVICE(0x06bd, 0x20fd) }, 0 }, /* SnapScan e52 */
108   /* Avision */
109  {{ USB_DEVICE(0x0638, 0x0268) }, 0 }, /* Avision 1200U */
110   /* Canon */
111  {{ USB_DEVICE(0x04a9, 0x2206) }, 0 }, /* CanoScan N656U */
112  {{ USB_DEVICE(0x04a9, 0x220d) }, 0 }, /* CanoScan N676U */
113  {{ USB_DEVICE(0x04a9, 0x2208) }, 0 }, /* CanoScan D660U */
114   /* Kye */
115  {{ USB_DEVICE(0x0458, 0x2001) }, 0 }, /* ColorPage Vivid-Pro */
116   /* HP */
117  {{ USB_DEVICE(0x03f0, 0x0605) }, 0 }, /* ScanJet 2200C */
118  {{ USB_DEVICE(0x03f0, 0x0205) }, 0 }, /* ScanJet 3300C */
119  {{ USB_DEVICE(0x03f0, 0x0405) }, 0 }, /* ScanJet 3400cse */
120  {{ USB_DEVICE(0x03f0, 0x0101) }, 0 }, /* Scanjet 4100C */
121  {{ USB_DEVICE(0x03f0, 0x0105) }, 0 }, /* ScanJet 4200C */
122  {{ USB_DEVICE(0x03f0, 0x0305) }, 0 }, /* Scanjet 4300C */
123  {{ USB_DEVICE(0x03f0, 0x0102) }, 0 }, /* Photosmart S20 */
124  {{ USB_DEVICE(0x03f0, 0x0401) }, 0 }, /* Scanjet 5200C */
125  {{ USB_DEVICE(0x03f0, 0x0701) }, 0 }, /* Scanjet 5300C */
126  {{ USB_DEVICE(0x03f0, 0x1005) }, 0 }, /* Scanjet 5400C */
127  {{ USB_DEVICE(0x03f0, 0x0201) }, 0 }, /* ScanJet 6200C */
128  {{ USB_DEVICE(0x03f0, 0x0601) }, 0 }, /* Scanjet 6300C */
129   /* Scanlogic */
130  {{ USB_DEVICE(0x04ce, 0x0300) }, 0 }, /* Phantom 336CX - C3 */
131   /* Microtek */
132  {{ USB_DEVICE(0x05da, 0x0099) }, 0 }, /* Phantom 336CX - C3 */
133  {{ USB_DEVICE(0x05da, 0x0094) }, 0 }, /* ScanMaker X6 - X6U */
134  {{ USB_DEVICE(0x05da, 0x00a0) }, 0 }, /* Phantom 336CX - C3 */
135  {{ USB_DEVICE(0x05da, 0x009a) }, 0 }, /* Phantom C6 */
136  {{ USB_DEVICE(0x05da, 0x00a3) }, 0 }, /* ScanMaker V6USL */
137  {{ USB_DEVICE(0x05da, 0x80a3) }, 0 }, /* ScanMaker V6USL */
138  {{ USB_DEVICE(0x05da, 0x80ac) }, 0 }, /* ScanMaker V6UL */
139   /* Minolta */
140  {{ USB_DEVICE(0x0686, 0x400e) }, 0 }, /* Dimage 5400 */
141   /* Mustek */
142  {{ USB_DEVICE(0x055f, 0x0001) }, 0 }, /* 1200 CU */
143  {{ USB_DEVICE(0x055f, 0x0010) }, 0 }, /* BearPaw 1200F */
144  {{ USB_DEVICE(0x055f, 0x021e) }, 0 }, /* BearPaw 1200TA */
145  {{ USB_DEVICE(0x055f, 0x0873) }, 0 }, /* 600 USB */
146  {{ USB_DEVICE(0x055f, 0x0002) }, 0 }, /* 600 CU */
147  {{ USB_DEVICE(0x055f, 0x0003) }, 0 }, /* 1200 USB */
148  {{ USB_DEVICE(0x055f, 0x0006) }, 0 }, /* 1200 UB */
149  {{ USB_DEVICE(0x055f, 0x0007) }, 0 }, /* 1200 USB */
150  {{ USB_DEVICE(0x055f, 0x0008) }, 0 }, /* 1200 CU */
151   /* National */
152  {{ USB_DEVICE(0x0400, 0x1000) }, 0 }, /* BearPaw 1200 */
153  {{ USB_DEVICE(0x0400, 0x1001) }, 0 }, /* BearPaw 2400 */
154   /* Primax */
155  {{ USB_DEVICE(0x0461, 0x0300) }, 0 }, /* G2-200 */
156  {{ USB_DEVICE(0x0461, 0x0301) }, 0 }, /* G2E-300 */
157  {{ USB_DEVICE(0x0461, 0x0302) }, 0 }, /* G2-300 */
158  {{ USB_DEVICE(0x0461, 0x0303) }, 0 }, /* G2E-300 */
159  {{ USB_DEVICE(0x0461, 0x0340) }, 0 }, /* Colorado USB 9600 */
160  {{ USB_DEVICE(0x0461, 0x0341) }, 0 }, /* Colorado 600u */
161  {{ USB_DEVICE(0x0461, 0x0345) }, 0 }, /* Visioneer 6200 */
162  {{ USB_DEVICE(0x0461, 0x0360) }, 0 }, /* Colorado USB 19200 */
163  {{ USB_DEVICE(0x0461, 0x0361) }, 0 }, /* Colorado 1200u */
164  {{ USB_DEVICE(0x0461, 0x0380) }, 0 }, /* G2-600 */
165  {{ USB_DEVICE(0x0461, 0x0381) }, 0 }, /* ReadyScan 636i */
166  {{ USB_DEVICE(0x0461, 0x0382) }, 0 }, /* G2-600 */
167  {{ USB_DEVICE(0x0461, 0x0383) }, 0 }, /* G2E-600 */
168   /* Epson */
169  {{ USB_DEVICE(0x04b8, 0x0101) }, 0 }, /* Perfection 636U/636Photo */
170  {{ USB_DEVICE(0x04b8, 0x0103) }, 0 }, /* Perfection 610 */
171  {{ USB_DEVICE(0x04b8, 0x0104) }, 0 }, /* Perfection 1200U/1200Photo */
172  {{ USB_DEVICE(0x04b8, 0x010b) }, 0 }, /* Perfection 1240U/1240Photo */
173  {{ USB_DEVICE(0x04b8, 0x010f) }, 0 }, /* Perfection 1250U/1250Photo */
174  {{ USB_DEVICE(0x04b8, 0x0107) }, 0 }, /* Expression 1600 */
175  {{ USB_DEVICE(0x04b8, 0x010a) }, 0 }, /* Perfection 1640SU */
176  {{ USB_DEVICE(0x04b8, 0x010c) }, 0 }, /* Perfection 640U */
177  {{ USB_DEVICE(0x04b8, 0x0110) }, 0 }, /* Perfection 1650 */
178  {{ USB_DEVICE(0x04b8, 0x011e) }, 0 }, /* Perfection 1660 */
179  {{ USB_DEVICE(0x04b8, 0x011d) }, 0 }, /* Perfection 1260 */
180  {{ USB_DEVICE(0x04b8, 0x0112) }, USC_KEEP_OPEN }, /* GT-9700F */
181  {{ USB_DEVICE(0x04b8, 0x011b) }, 0 }, /* GT-9300UF */
182   /* UMAX */
183  {{ USB_DEVICE(0x1606, 0x0010) }, 0 }, /* Astra 1220U */
184  {{ USB_DEVICE(0x1606, 0x0002) }, 0 }, /* Astra 1236U */
185  {{ USB_DEVICE(0x1606, 0x0030) }, 0 }, /* Astra 2000U */
186  {{ USB_DEVICE(0x1606, 0x0130) }, 0 }, /* Astra 2100U */
187  {{ USB_DEVICE(0x1606, 0x0230) }, 0 }, /* Astra 2200U */
188  {{ USB_DEVICE(0x1606, 0x0060) }, 0 }, /* Astra 3400 */
189   /* Visioneer */
190  {{ USB_DEVICE(0x04a7, 0x0224) }, 0 }, /* Scanport 3000 */
191  {{ USB_DEVICE(0x04a7, 0x0221) }, 0 }, /* OneTouch 5300 */
192  {{ USB_DEVICE(0x04a7, 0x0211) }, 0 }, /* OneTouch 7600 */
193  {{ USB_DEVICE(0x04a7, 0x0231) }, 0 }, /* OneTouch 6100 */
194  {{ USB_DEVICE(0x04a7, 0x0311) }, 0 }, /* OneTouch 6200 */
195  {{ USB_DEVICE(0x04a7, 0x0321) }, 0 }, /* OneTouch 8100 */
196  {{ USB_DEVICE(0x04a7, 0x0331) }, 0 }, /* OneTouch 8600 */
197   /* Ultima */
198  {{ USB_DEVICE(0x05d8, 0x4002) }, 0 }, /* 1200 UB Plus */
199 };
200 #define uscanner_lookup(v, p) ((const struct uscan_info *)usb_lookup(uscanner_devs, v, p))
201
202 #define USCANNER_BUFFERSIZE     1024
203
204 struct uscanner_softc {
205         device_t                sc_dev;         /* base device */
206         usbd_device_handle      sc_udev;
207         usbd_interface_handle   sc_iface;
208
209         u_int                   sc_dev_flags;
210
211         usbd_pipe_handle        sc_bulkin_pipe;
212         int                     sc_bulkin;
213         usbd_xfer_handle        sc_bulkin_xfer;
214         void                    *sc_bulkin_buffer;
215         int                     sc_bulkin_bufferlen;
216         int                     sc_bulkin_datalen;
217
218         usbd_pipe_handle        sc_bulkout_pipe;
219         int                     sc_bulkout;
220         usbd_xfer_handle        sc_bulkout_xfer;
221         void                    *sc_bulkout_buffer;
222         int                     sc_bulkout_bufferlen;
223         int                     sc_bulkout_datalen;
224
225         u_char                  sc_state;
226 #define USCANNER_OPEN           0x01    /* opened */
227
228         int                     sc_refcnt;
229         u_char                  sc_dying;
230 };
231
232 d_open_t  uscanneropen;
233 d_close_t uscannerclose;
234 d_read_t  uscannerread;
235 d_write_t uscannerwrite;
236 d_poll_t  uscannerpoll;
237
238 #define USCANNER_CDEV_MAJOR     156
239
240 static struct dev_ops uscanner_ops = {
241         { "uscanner", USCANNER_CDEV_MAJOR, 0 },
242         .d_open =       uscanneropen,
243         .d_close =      uscannerclose,
244         .d_read =       uscannerread,
245         .d_write =      uscannerwrite,
246         .d_poll =       uscannerpoll,
247 };
248
249 static int uscanner_do_read(struct uscanner_softc *, struct uio *, int);
250 static int uscanner_do_write(struct uscanner_softc *, struct uio *, int);
251 static void uscanner_do_close(struct uscanner_softc *);
252
253 #define USCANNERUNIT(n) (minor(n))
254
255 static device_probe_t uscanner_match;
256 static device_attach_t uscanner_attach;
257 static device_detach_t uscanner_detach;
258
259 static devclass_t uscanner_devclass;
260
261 static kobj_method_t uscanner_methods[] = {
262         DEVMETHOD(device_probe, uscanner_match),
263         DEVMETHOD(device_attach, uscanner_attach),
264         DEVMETHOD(device_detach, uscanner_detach),
265         {0,0}
266 };
267
268 static driver_t uscanner_driver = {
269         "uscanner",
270         uscanner_methods,
271         sizeof(struct uscanner_softc)
272 };
273
274 MODULE_DEPEND(uscanner, usb, 1, 1, 1);
275
276 static int
277 uscanner_match(device_t self)
278 {
279         struct usb_attach_arg *uaa = device_get_ivars(self);
280
281         if (uaa->iface != NULL)
282                 return UMATCH_NONE;
283
284         return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ?
285                 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
286 }
287
288 static int
289 uscanner_attach(device_t self)
290 {
291         struct uscanner_softc *sc = device_get_softc(self);
292         struct usb_attach_arg *uaa = device_get_ivars(self);
293         usb_interface_descriptor_t *id = 0;
294         usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
295         int i;
296         usbd_status err;
297
298         sc->sc_dev = self;
299
300         sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
301
302         sc->sc_udev = uaa->device;
303
304         err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
305         if (err) {
306                 kprintf("%s: setting config no failed\n",
307                     device_get_nameunit(sc->sc_dev));
308                 return ENXIO;
309         }
310
311         /* XXX We only check the first interface */
312         err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
313         if (!err && sc->sc_iface)
314             id = usbd_get_interface_descriptor(sc->sc_iface);
315         if (err || id == 0) {
316                 kprintf("%s: could not get interface descriptor, err=%d,id=%p\n",
317                        device_get_nameunit(sc->sc_dev), err, id);
318                 return ENXIO;
319         }
320
321         /* Find the two first bulk endpoints */
322         for (i = 0 ; i < id->bNumEndpoints; i++) {
323                 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
324                 if (ed == 0) {
325                         kprintf("%s: could not read endpoint descriptor\n",
326                                device_get_nameunit(sc->sc_dev));
327                         return ENXIO;
328                 }
329
330                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
331                     && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
332                         ed_bulkin = ed;
333                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
334                     && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
335                         ed_bulkout = ed;
336                 }
337
338                 if (ed_bulkin && ed_bulkout)    /* found all we need */
339                         break;
340         }
341
342         /* Verify that we goething sensible */
343         if (ed_bulkin == NULL || ed_bulkout == NULL) {
344                 kprintf("%s: bulk-in and/or bulk-out endpoint not found\n",
345                         device_get_nameunit(sc->sc_dev));
346                 return ENXIO;
347         }
348
349         sc->sc_bulkin = ed_bulkin->bEndpointAddress;
350         sc->sc_bulkout = ed_bulkout->bEndpointAddress;
351
352         /* the main device, ctrl endpoint */
353         dev_ops_add(&uscanner_ops, -1, device_get_unit(sc->sc_dev));
354         make_dev(&uscanner_ops, device_get_unit(sc->sc_dev),
355                 UID_ROOT, GID_OPERATOR, 0644, "%s", device_get_nameunit(sc->sc_dev));
356
357         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
358                            sc->sc_dev);
359
360         return 0;
361 }
362
363 int
364 uscanneropen(struct dev_open_args *ap)
365 {
366         cdev_t dev = ap->a_head.a_dev;
367         struct uscanner_softc *sc;
368         int unit = USCANNERUNIT(dev);
369         usbd_status err;
370
371         sc = devclass_get_softc(uscanner_devclass, unit);
372         if (sc == NULL)
373                 return (ENXIO);
374
375         DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n",
376                      ap->a_oflags, ap->a_devtype, unit));
377
378         if (sc->sc_dying)
379                 return (ENXIO);
380
381         if (sc->sc_state & USCANNER_OPEN)
382                 return (EBUSY);
383
384         sc->sc_state |= USCANNER_OPEN;
385
386         sc->sc_bulkin_buffer = kmalloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
387         sc->sc_bulkout_buffer = kmalloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
388         /* No need to check buffers for NULL since we have WAITOK */
389
390         sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE;
391         sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE;
392
393         /* We have decided on which endpoints to use, now open the pipes */
394         if (sc->sc_bulkin_pipe == NULL) {
395                 err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin,
396                                      USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
397                 if (err) {
398                         kprintf("%s: cannot open bulk-in pipe (addr %d)\n",
399                                device_get_nameunit(sc->sc_dev), sc->sc_bulkin);
400                         uscanner_do_close(sc);
401                         return (EIO);
402                 }
403         }
404         if (sc->sc_bulkout_pipe == NULL) {
405                 err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout,
406                                      USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
407                 if (err) {
408                         kprintf("%s: cannot open bulk-out pipe (addr %d)\n",
409                                device_get_nameunit(sc->sc_dev), sc->sc_bulkout);
410                         uscanner_do_close(sc);
411                         return (EIO);
412                 }
413         }
414
415         sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev);
416         if (sc->sc_bulkin_xfer == NULL) {
417                 uscanner_do_close(sc);
418                 return (ENOMEM);
419         }
420         sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev);
421         if (sc->sc_bulkout_xfer == NULL) {
422                 uscanner_do_close(sc);
423                 return (ENOMEM);
424         }
425
426         return (0);     /* success */
427 }
428
429 int
430 uscannerclose(struct dev_close_args *ap)
431 {
432         cdev_t dev = ap->a_head.a_dev;
433         struct uscanner_softc *sc;
434
435         sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
436
437         DPRINTFN(5, ("uscannerclose: flag=%d, mode=%d, unit=%d\n",
438                      ap->a_fflag, ap->a_devtype, USCANNERUNIT(dev)));
439
440 #ifdef DIAGNOSTIC
441         if (!(sc->sc_state & USCANNER_OPEN)) {
442                 kprintf("uscannerclose: not open\n");
443                 return (EINVAL);
444         }
445 #endif
446
447         uscanner_do_close(sc);
448
449         return (0);
450 }
451
452 void
453 uscanner_do_close(struct uscanner_softc *sc)
454 {
455         if (sc->sc_bulkin_xfer) {
456                 usbd_free_xfer(sc->sc_bulkin_xfer);
457                 sc->sc_bulkin_xfer = NULL;
458         }
459         if (sc->sc_bulkout_xfer) {
460                 usbd_free_xfer(sc->sc_bulkout_xfer);
461                 sc->sc_bulkout_xfer = NULL;
462         }
463
464         if (!(sc->sc_dev_flags & USC_KEEP_OPEN)) {
465                 if (sc->sc_bulkin_pipe != NULL) {
466                         usbd_abort_pipe(sc->sc_bulkin_pipe);
467                         usbd_close_pipe(sc->sc_bulkin_pipe);
468                         sc->sc_bulkin_pipe = NULL;
469                 }
470                 if (sc->sc_bulkout_pipe != NULL) {
471                         usbd_abort_pipe(sc->sc_bulkout_pipe);
472                         usbd_close_pipe(sc->sc_bulkout_pipe);
473                         sc->sc_bulkout_pipe = NULL;
474                 }
475         }
476
477         if (sc->sc_bulkin_buffer) {
478                 kfree(sc->sc_bulkin_buffer, M_USBDEV);
479                 sc->sc_bulkin_buffer = NULL;
480         }
481         if (sc->sc_bulkout_buffer) {
482                 kfree(sc->sc_bulkout_buffer, M_USBDEV);
483                 sc->sc_bulkout_buffer = NULL;
484         }
485
486         sc->sc_state &= ~USCANNER_OPEN;
487 }
488
489 static int
490 uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
491 {
492         u_int32_t n, tn;
493         usbd_status err;
494         int error = 0;
495
496         DPRINTFN(5, ("%s: uscannerread\n", device_get_nameunit(sc->sc_dev)));
497
498         if (sc->sc_dying)
499                 return (EIO);
500
501         while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) {
502                 DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n));
503                 tn = n;
504
505                 err = usbd_bulk_transfer(
506                         sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
507                         USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
508                         sc->sc_bulkin_buffer, &tn,
509                         "uscnrb");
510                 if (err) {
511                         if (err == USBD_INTERRUPTED)
512                                 error = EINTR;
513                         else if (err == USBD_TIMEOUT)
514                                 error = ETIMEDOUT;
515                         else
516                                 error = EIO;
517                         break;
518                 }
519                 DPRINTFN(1, ("uscannerread: got %d bytes\n", tn));
520                 error = uiomove(sc->sc_bulkin_buffer, tn, uio);
521                 if (error || tn < n)
522                         break;
523         }
524
525         return (error);
526 }
527
528 int
529 uscannerread(struct dev_read_args *ap)
530 {
531         cdev_t dev = ap->a_head.a_dev;
532         struct uscanner_softc *sc;
533         int error;
534
535         sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
536
537         sc->sc_refcnt++;
538         error = uscanner_do_read(sc, ap->a_uio, ap->a_ioflag);
539         if (--sc->sc_refcnt < 0)
540                 usb_detach_wakeup(sc->sc_dev);
541
542         return (error);
543 }
544
545 static int
546 uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
547 {
548         u_int32_t n;
549         int error = 0;
550         usbd_status err;
551
552         DPRINTFN(5, ("%s: uscanner_do_write\n", device_get_nameunit(sc->sc_dev)));
553
554         if (sc->sc_dying)
555                 return (EIO);
556
557         while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) {
558                 error = uiomove(sc->sc_bulkout_buffer, n, uio);
559                 if (error)
560                         break;
561                 DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n));
562                 err = usbd_bulk_transfer(
563                         sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
564                         0, USBD_NO_TIMEOUT,
565                         sc->sc_bulkout_buffer, &n,
566                         "uscnwb");
567                 if (err) {
568                         if (err == USBD_INTERRUPTED)
569                                 error = EINTR;
570                         else
571                                 error = EIO;
572                         break;
573                 }
574         }
575
576         return (error);
577 }
578
579 int
580 uscannerwrite(struct dev_write_args *ap)
581 {
582         cdev_t dev = ap->a_head.a_dev;
583         struct uscanner_softc *sc;
584         int error;
585
586         sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
587
588         sc->sc_refcnt++;
589         error = uscanner_do_write(sc, ap->a_uio, ap->a_ioflag);
590         if (--sc->sc_refcnt < 0)
591                 usb_detach_wakeup(sc->sc_dev);
592         return (error);
593 }
594
595 static int
596 uscanner_detach(device_t self)
597 {
598         struct uscanner_softc *sc = device_get_softc(self);
599
600         DPRINTF(("uscanner_detach: sc=%p\n", sc));
601
602         sc->sc_dying = 1;
603         sc->sc_dev_flags = 0;   /* make close really close device */
604
605         /* Abort all pipes.  Causes processes waiting for transfer to wake. */
606         if (sc->sc_bulkin_pipe != NULL)
607                 usbd_abort_pipe(sc->sc_bulkin_pipe);
608         if (sc->sc_bulkout_pipe != NULL)
609                 usbd_abort_pipe(sc->sc_bulkout_pipe);
610
611         crit_enter();
612         if (--sc->sc_refcnt >= 0) {
613                 /* Wait for processes to go away. */
614                 usb_detach_wait(sc->sc_dev);
615         }
616         crit_exit();
617
618         /* destroy the device for the control endpoint */
619         dev_ops_remove(&uscanner_ops, -1, device_get_unit(sc->sc_dev));
620
621         usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
622                            sc->sc_dev);
623
624         return (0);
625 }
626
627 int
628 uscannerpoll(struct dev_poll_args *ap)
629 {
630         cdev_t dev = ap->a_head.a_dev;
631         struct uscanner_softc *sc;
632         int revents = 0;
633
634         sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
635
636         if (sc->sc_dying)
637                 return (EIO);
638
639         /*
640          * We have no easy way of determining if a read will
641          * yield any data or a write will happen.
642          * Pretend they will.
643          */
644         revents |= ap->a_events &
645                    (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
646
647         ap->a_events = revents;
648         return (0);
649 }
650
651 DRIVER_MODULE(uscanner, uhub, uscanner_driver, uscanner_devclass, usbd_driver_load, 0);
652