No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / usb / uscanner.c
bloba66143e329e86a0b07ee3e9d4abd5271bc895dea
1 /* $NetBSD: uscanner.c,v 1.66 2009/09/23 19:07:19 plunky Exp $ */
3 /*
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
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).
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.
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: uscanner.c,v 1.66 2009/09/23 19:07:19 plunky Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #if defined(__NetBSD__) || defined(__OpenBSD__)
42 #include <sys/device.h>
43 #elif defined(__FreeBSD__)
44 #include <sys/module.h>
45 #include <sys/bus.h>
46 #include <sys/conf.h>
47 #include <sys/fcntl.h>
48 #include <sys/filio.h>
49 #endif
50 #include <sys/file.h>
51 #if defined(__FreeBSD__) && __FreeBSD_version >= 500014
52 #include <sys/selinfo.h>
53 #else
54 #include <sys/select.h>
55 #endif
56 #include <sys/proc.h>
57 #include <sys/vnode.h>
58 #include <sys/poll.h>
59 #include <sys/conf.h>
61 #include <dev/usb/usb.h>
62 #include <dev/usb/usbdi.h>
63 #include <dev/usb/usbdi_util.h>
65 #include <dev/usb/usbdevs.h>
67 #ifdef USCANNER_DEBUG
68 #define DPRINTF(x) if (uscannerdebug) logprintf x
69 #define DPRINTFN(n,x) if (uscannerdebug>(n)) logprintf x
70 int uscannerdebug = 0;
71 #else
72 #define DPRINTF(x)
73 #define DPRINTFN(n,x)
74 #endif
76 struct uscan_info {
77 struct usb_devno devno;
78 u_int flags;
79 #define USC_KEEP_OPEN 1
82 /* Table of scanners that may work with this driver. */
83 static const struct uscan_info uscanner_devs[] = {
84 /* Acer Peripherals */
85 {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U }, 0 },
86 {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U }, 0 },
87 {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U }, 0 },
88 {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U }, 0 },
90 /* AGFA */
91 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U }, 0 },
92 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U }, 0 },
93 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2 }, 0 },
94 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH }, 0 },
95 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40 }, 0 },
96 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50 }, 0 },
97 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20 }, 0 },
98 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25 }, 0 },
99 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26 }, 0 },
100 {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52 }, 0 },
102 /* Avision */
103 {{ USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U }, 0 },
105 /* Canon */
106 {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U }, 0 },
107 {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N670U }, 0 },
108 {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U }, 0 },
109 {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U }, 0 },
111 /* Kye */
112 {{ USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO }, 0 },
114 /* HP */
115 {{ USB_VENDOR_HP, USB_PRODUCT_HP_2200C }, 0 },
116 {{ USB_VENDOR_HP, USB_PRODUCT_HP_3300C }, 0 },
117 {{ USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE }, 0 },
118 {{ USB_VENDOR_HP, USB_PRODUCT_HP_4100C }, 0 },
119 {{ USB_VENDOR_HP, USB_PRODUCT_HP_4200C }, 0 },
120 {{ USB_VENDOR_HP, USB_PRODUCT_HP_4300C }, 0 },
121 {{ USB_VENDOR_HP, USB_PRODUCT_HP_S20 }, 0 },
122 {{ USB_VENDOR_HP, USB_PRODUCT_HP_5200C }, 0 },
123 #if 0
124 /* Handled by usscanner */
125 {{ USB_VENDOR_HP, USB_PRODUCT_HP_5300C }, 0 },
126 #endif
127 {{ USB_VENDOR_HP, USB_PRODUCT_HP_6200C }, 0 },
128 {{ USB_VENDOR_HP, USB_PRODUCT_HP_6300C }, 0 },
130 #if 0
131 /* XXX Should be handled by usscanner */
132 /* Microtek */
133 {{ USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX }, 0 },
134 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U }, 0 },
135 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX }, 0 },
136 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2 }, 0 },
137 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6 }, 0 },
138 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL }, 0 },
139 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2 }, 0 },
140 {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL }, 0 },
141 #endif
143 /* Minolta */
144 {{ USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400 }, 0 },
146 /* Mustek */
147 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU }, 0 },
148 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F }, 0 },
149 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA }, 0 },
150 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB }, 0 },
151 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU }, 0 },
152 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB }, 0 },
153 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB }, 0 },
154 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS }, 0 },
155 {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS }, 0 },
157 /* National */
158 {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200 }, 0 },
159 {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400 }, 0 },
161 /* Primax */
162 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300 }, 0 },
163 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300 }, 0 },
164 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300 }, 0 },
165 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002 }, 0 },
166 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600 }, 0 },
167 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U }, 0 },
168 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200 }, 0 },
169 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200 }, 0 },
170 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U }, 0 },
171 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600 }, 0 },
172 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I }, 0 },
173 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600 }, 0 },
174 {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600 }, 0 },
176 /* Epson */
177 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636 }, 0 },
178 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610 }, 0 },
179 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200 }, 0 },
180 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240 }, 0 },
181 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250 }, 0 },
182 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260 }, 0 },
183 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600 }, 0 },
184 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640 }, 0 },
185 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660 }, 0 },
186 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670 }, 0 },
187 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U }, 0 },
188 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650 }, 0 },
189 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2400 }, 0 },
190 {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F }, USC_KEEP_OPEN },
192 /* UMAX */
193 {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
194 {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U }, 0 },
195 {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U }, 0 },
196 {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U }, 0 },
197 {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U }, 0 },
198 {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400 }, 0 },
200 /* Visioneer */
201 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000 }, 0 },
202 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300 }, 0 },
203 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600 }, 0 },
204 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100 }, 0 },
205 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200 }, 0 },
206 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100 }, 0 },
207 {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600 }, 0 },
209 /* Ultima */
210 {{ USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS }, 0 },
213 #define uscanner_lookup(v, p) ((const struct uscan_info *)usb_lookup(uscanner_devs, v, p))
215 #define USCANNER_BUFFERSIZE 1024
217 struct uscanner_softc {
218 USBBASEDEVICE sc_dev; /* base device */
219 usbd_device_handle sc_udev;
220 usbd_interface_handle sc_iface;
222 u_int sc_dev_flags;
224 usbd_pipe_handle sc_bulkin_pipe;
225 int sc_bulkin;
226 usbd_xfer_handle sc_bulkin_xfer;
227 void *sc_bulkin_buffer;
228 int sc_bulkin_bufferlen;
229 int sc_bulkin_datalen;
231 usbd_pipe_handle sc_bulkout_pipe;
232 int sc_bulkout;
233 usbd_xfer_handle sc_bulkout_xfer;
234 void *sc_bulkout_buffer;
235 int sc_bulkout_bufferlen;
236 int sc_bulkout_datalen;
238 struct selinfo sc_selq;
240 u_char sc_state;
241 #define USCANNER_OPEN 0x01 /* opened */
243 int sc_refcnt;
244 u_char sc_dying;
247 #if defined(__NetBSD__)
248 dev_type_open(uscanneropen);
249 dev_type_close(uscannerclose);
250 dev_type_read(uscannerread);
251 dev_type_write(uscannerwrite);
252 dev_type_ioctl(uscannerioctl);
253 dev_type_poll(uscannerpoll);
254 dev_type_kqfilter(uscannerkqfilter);
256 const struct cdevsw uscanner_cdevsw = {
257 uscanneropen, uscannerclose, uscannerread, uscannerwrite,
258 uscannerioctl, nostop, notty, uscannerpoll, nommap, uscannerkqfilter,
259 D_OTHER,
261 #elif defined(__OpenBSD__)
262 cdev_decl(uscanner);
263 #elif defined(__FreeBSD__)
264 d_open_t uscanneropen;
265 d_close_t uscannerclose;
266 d_read_t uscannerread;
267 d_write_t uscannerwrite;
268 d_poll_t uscannerpoll;
270 #define USCANNER_CDEV_MAJOR 156
272 Static struct cdevsw uscanner_cdevsw = {
273 /* open */ uscanneropen,
274 /* close */ uscannerclose,
275 /* read */ uscannerread,
276 /* write */ uscannerwrite,
277 /* ioctl */ noioctl,
278 /* poll */ uscannerpoll,
279 /* mmap */ nommap,
280 /* strategy */ nostrategy,
281 /* name */ "uscanner",
282 /* maj */ USCANNER_CDEV_MAJOR,
283 /* dump */ nodump,
284 /* psize */ nopsize,
285 /* flags */ 0,
286 #if !defined(__FreeBSD__) || (__FreeBSD__ < 5)
287 /* bmaj */ -1
288 #endif
290 #endif
292 Static int uscanner_do_read(struct uscanner_softc *, struct uio *, int);
293 Static int uscanner_do_write(struct uscanner_softc *, struct uio *, int);
294 Static void uscanner_do_close(struct uscanner_softc *);
296 #define USCANNERUNIT(n) (minor(n))
298 USB_DECLARE_DRIVER(uscanner);
300 USB_MATCH(uscanner)
302 USB_MATCH_START(uscanner, uaa);
304 return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ?
305 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
308 USB_ATTACH(uscanner)
310 USB_ATTACH_START(uscanner, sc, uaa);
311 usb_interface_descriptor_t *id = 0;
312 usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
313 char *devinfop;
314 int i;
315 usbd_status err;
317 sc->sc_dev = self;
319 aprint_naive("\n");
320 aprint_normal("\n");
322 devinfop = usbd_devinfo_alloc(uaa->device, 0);
323 aprint_normal_dev(self, "%s\n", devinfop);
324 usbd_devinfo_free(devinfop);
326 sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
328 sc->sc_udev = uaa->device;
330 err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
331 if (err) {
332 aprint_error_dev(self, "setting config no failed\n");
333 sc->sc_dying = 1;
334 USB_ATTACH_ERROR_RETURN;
337 /* XXX We only check the first interface */
338 err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
339 if (!err && sc->sc_iface)
340 id = usbd_get_interface_descriptor(sc->sc_iface);
341 if (err || id == 0) {
342 aprint_error_dev(self,
343 "could not get interface descriptor, err=%d,id=%p\n",
344 err, id);
345 sc->sc_dying = 1;
346 USB_ATTACH_ERROR_RETURN;
349 /* Find the two first bulk endpoints */
350 for (i = 0 ; i < id->bNumEndpoints; i++) {
351 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
352 if (ed == 0) {
353 aprint_error_dev(self,
354 "could not read endpoint descriptor\n");
355 sc->sc_dying = 1;
356 USB_ATTACH_ERROR_RETURN;
359 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
360 && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
361 ed_bulkin = ed;
362 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
363 && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
364 ed_bulkout = ed;
367 if (ed_bulkin && ed_bulkout) /* found all we need */
368 break;
371 /* Verify that we got something sensible */
372 if (ed_bulkin == NULL || ed_bulkout == NULL) {
373 aprint_error_dev(self,
374 "bulk-in and/or bulk-out endpoint not found\n");
375 sc->sc_dying = 1;
376 USB_ATTACH_ERROR_RETURN;
379 sc->sc_bulkin = ed_bulkin->bEndpointAddress;
380 sc->sc_bulkout = ed_bulkout->bEndpointAddress;
382 #ifdef __FreeBSD__
383 /* the main device, ctrl endpoint */
384 make_dev(&uscanner_cdevsw, USBDEVUNIT(sc->sc_dev),
385 UID_ROOT, GID_OPERATOR, 0644, "%s", USBDEVNAME(sc->sc_dev));
386 #endif
387 selinit(&sc->sc_selq);
388 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
389 USBDEV(sc->sc_dev));
391 USB_ATTACH_SUCCESS_RETURN;
395 uscanneropen(dev_t dev, int flag, int mode,
396 struct lwp *l)
398 struct uscanner_softc *sc;
399 int unit = USCANNERUNIT(dev);
400 usbd_status err;
402 USB_GET_SC_OPEN(uscanner, unit, sc);
404 DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n",
405 flag, mode, unit));
407 if (sc->sc_dying)
408 return (ENXIO);
410 if (sc->sc_state & USCANNER_OPEN)
411 return (EBUSY);
413 sc->sc_state |= USCANNER_OPEN;
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 */
419 sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE;
420 sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE;
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);
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);
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);
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);
455 return (0); /* success */
459 uscannerclose(dev_t dev, int flag, int mode,
460 struct lwp *l)
462 struct uscanner_softc *sc;
464 USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
466 DPRINTFN(5, ("uscannerclose: flag=%d, mode=%d, unit=%"PRId32"\n",
467 flag, mode, USCANNERUNIT(dev)));
469 #ifdef DIAGNOSTIC
470 if (!(sc->sc_state & USCANNER_OPEN)) {
471 printf("uscannerclose: not open\n");
472 return (EINVAL);
474 #endif
476 uscanner_do_close(sc);
478 return (0);
481 void
482 uscanner_do_close(struct uscanner_softc *sc)
484 if (sc->sc_bulkin_xfer) {
485 usbd_free_xfer(sc->sc_bulkin_xfer);
486 sc->sc_bulkin_xfer = NULL;
488 if (sc->sc_bulkout_xfer) {
489 usbd_free_xfer(sc->sc_bulkout_xfer);
490 sc->sc_bulkout_xfer = NULL;
493 if (!(sc->sc_dev_flags & USC_KEEP_OPEN)) {
494 if (sc->sc_bulkin_pipe != NULL) {
495 usbd_abort_pipe(sc->sc_bulkin_pipe);
496 usbd_close_pipe(sc->sc_bulkin_pipe);
497 sc->sc_bulkin_pipe = NULL;
499 if (sc->sc_bulkout_pipe != NULL) {
500 usbd_abort_pipe(sc->sc_bulkout_pipe);
501 usbd_close_pipe(sc->sc_bulkout_pipe);
502 sc->sc_bulkout_pipe = NULL;
506 if (sc->sc_bulkin_buffer) {
507 free(sc->sc_bulkin_buffer, M_USBDEV);
508 sc->sc_bulkin_buffer = NULL;
510 if (sc->sc_bulkout_buffer) {
511 free(sc->sc_bulkout_buffer, M_USBDEV);
512 sc->sc_bulkout_buffer = NULL;
515 sc->sc_state &= ~USCANNER_OPEN;
518 Static int
519 uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
521 u_int32_t n, tn;
522 usbd_status err;
523 int error = 0;
525 DPRINTFN(5, ("%s: uscannerread\n", USBDEVNAME(sc->sc_dev)));
527 if (sc->sc_dying)
528 return (EIO);
530 while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) {
531 DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n));
532 tn = n;
534 err = usbd_bulk_transfer(
535 sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
536 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
537 sc->sc_bulkin_buffer, &tn,
538 "uscnrb");
539 if (err) {
540 if (err == USBD_INTERRUPTED)
541 error = EINTR;
542 else if (err == USBD_TIMEOUT)
543 error = ETIMEDOUT;
544 else
545 error = EIO;
546 break;
548 DPRINTFN(1, ("uscannerread: got %d bytes\n", tn));
549 error = uiomove(sc->sc_bulkin_buffer, tn, uio);
550 if (error || tn < n)
551 break;
554 return (error);
558 uscannerread(dev_t dev, struct uio *uio, int flag)
560 struct uscanner_softc *sc;
561 int error;
563 USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
565 sc->sc_refcnt++;
566 error = uscanner_do_read(sc, uio, flag);
567 if (--sc->sc_refcnt < 0)
568 usb_detach_wakeup(USBDEV(sc->sc_dev));
570 return (error);
573 Static int
574 uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
576 u_int32_t n;
577 int error = 0;
578 usbd_status err;
580 DPRINTFN(5, ("%s: uscanner_do_write\n", USBDEVNAME(sc->sc_dev)));
582 if (sc->sc_dying)
583 return (EIO);
585 while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) {
586 error = uiomove(sc->sc_bulkout_buffer, n, uio);
587 if (error)
588 break;
589 DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n));
590 err = usbd_bulk_transfer(
591 sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
592 0, USBD_NO_TIMEOUT,
593 sc->sc_bulkout_buffer, &n,
594 "uscnwb");
595 if (err) {
596 if (err == USBD_INTERRUPTED)
597 error = EINTR;
598 else
599 error = EIO;
600 break;
604 return (error);
608 uscannerwrite(dev_t dev, struct uio *uio, int flag)
610 struct uscanner_softc *sc;
611 int error;
613 USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
615 sc->sc_refcnt++;
616 error = uscanner_do_write(sc, uio, flag);
617 if (--sc->sc_refcnt < 0)
618 usb_detach_wakeup(USBDEV(sc->sc_dev));
619 return (error);
622 #if defined(__NetBSD__) || defined(__OpenBSD__)
624 uscanner_activate(device_ptr_t self, enum devact act)
626 struct uscanner_softc *sc = device_private(self);
628 switch (act) {
629 case DVACT_DEACTIVATE:
630 sc->sc_dying = 1;
631 return 0;
632 default:
633 return EOPNOTSUPP;
636 #endif
638 USB_DETACH(uscanner)
640 USB_DETACH_START(uscanner, sc);
641 int s;
642 #if defined(__NetBSD__) || defined(__OpenBSD__)
643 int maj, mn;
644 #elif defined(__FreeBSD__)
645 dev_t dev;
646 struct vnode *vp;
647 #endif
649 #if defined(__NetBSD__) || defined(__OpenBSD__)
650 DPRINTF(("uscanner_detach: sc=%p flags=%d\n", sc, flags));
651 #elif defined(__FreeBSD__)
652 DPRINTF(("uscanner_detach: sc=%p\n", sc));
653 #endif
655 sc->sc_dying = 1;
656 sc->sc_dev_flags = 0; /* make close really close device */
658 /* Abort all pipes. Causes processes waiting for transfer to wake. */
659 if (sc->sc_bulkin_pipe != NULL)
660 usbd_abort_pipe(sc->sc_bulkin_pipe);
661 if (sc->sc_bulkout_pipe != NULL)
662 usbd_abort_pipe(sc->sc_bulkout_pipe);
664 s = splusb();
665 if (--sc->sc_refcnt >= 0) {
666 /* Wait for processes to go away. */
667 usb_detach_wait(USBDEV(sc->sc_dev));
669 splx(s);
671 #if defined(__NetBSD__) || defined(__OpenBSD__)
672 /* locate the major number */
673 #if defined(__NetBSD__)
674 maj = cdevsw_lookup_major(&uscanner_cdevsw);
675 #elif defined(__OpenBSD__)
676 for (maj = 0; maj < nchrdev; maj++)
677 if (cdevsw[maj].d_open == uscanneropen)
678 break;
679 #endif
681 /* Nuke the vnodes for any open instances (calls close). */
682 mn = device_unit(self) * USB_MAX_ENDPOINTS;
683 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
684 #elif defined(__FreeBSD__)
685 /* destroy the device for the control endpoint */
686 dev = makedev(USCANNER_CDEV_MAJOR, USBDEVUNIT(sc->sc_dev));
687 vp = SLIST_FIRST(&dev->si_hlist);
688 if (vp)
689 VOP_REVOKE(vp, REVOKEALL);
690 destroy_dev(dev);
691 #endif
693 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
694 USBDEV(sc->sc_dev));
695 seldestroy(&sc->sc_selq);
697 return (0);
701 uscannerpoll(dev_t dev, int events, struct lwp *l)
703 struct uscanner_softc *sc;
704 int revents = 0;
706 USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
708 if (sc->sc_dying)
709 return (POLLHUP);
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.
716 revents |= events &
717 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
719 return (revents);
722 static void
723 filt_uscannerdetach(struct knote *kn)
725 struct uscanner_softc *sc = kn->kn_hook;
727 SLIST_REMOVE(&sc->sc_selq.sel_klist, kn, knote, kn_selnext);
730 static const struct filterops uscanner_seltrue_filtops =
731 { 1, NULL, filt_uscannerdetach, filt_seltrue };
734 uscannerkqfilter(dev_t dev, struct knote *kn)
736 struct uscanner_softc *sc;
737 struct klist *klist;
739 USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);
741 if (sc->sc_dying)
742 return (ENXIO);
744 switch (kn->kn_filter) {
745 case EVFILT_READ:
746 case EVFILT_WRITE:
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.
752 klist = &sc->sc_selq.sel_klist;
753 kn->kn_fop = &uscanner_seltrue_filtops;
754 break;
756 default:
757 return (EINVAL);
760 kn->kn_hook = sc;
762 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
764 return (0);
768 uscannerioctl(dev_t dev, u_long cmd, void *addr,
769 int flag, struct lwp *l)
771 return (EINVAL);
774 #if defined(__FreeBSD__)
775 DRIVER_MODULE(uscanner, uhub, uscanner_driver, uscanner_devclass, usbd_driver_load, 0);
776 #endif