1 /* $NetBSD: uscanner.c,v 1.66 2009/09/23 19:07:19 plunky Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
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
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>
47 #include <sys/fcntl.h>
48 #include <sys/filio.h>
51 #if defined(__FreeBSD__) && __FreeBSD_version >= 500014
52 #include <sys/selinfo.h>
54 #include <sys/select.h>
57 #include <sys/vnode.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>
68 #define DPRINTF(x) if (uscannerdebug) logprintf x
69 #define DPRINTFN(n,x) if (uscannerdebug>(n)) logprintf x
70 int uscannerdebug
= 0;
77 struct usb_devno devno
;
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 },
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 },
103 {{ USB_VENDOR_AVISION
, USB_PRODUCT_AVISION_1200U
}, 0 },
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 },
112 {{ USB_VENDOR_KYE
, USB_PRODUCT_KYE_VIVIDPRO
}, 0 },
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 },
124 /* Handled by usscanner */
125 {{ USB_VENDOR_HP
, USB_PRODUCT_HP_5300C
}, 0 },
127 {{ USB_VENDOR_HP
, USB_PRODUCT_HP_6200C
}, 0 },
128 {{ USB_VENDOR_HP
, USB_PRODUCT_HP_6300C
}, 0 },
131 /* XXX Should be handled by usscanner */
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 },
144 {{ USB_VENDOR_MINOLTA
, USB_PRODUCT_MINOLTA_5400
}, 0 },
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 },
158 {{ USB_VENDOR_NATIONAL
, USB_PRODUCT_NATIONAL_BEARPAW1200
}, 0 },
159 {{ USB_VENDOR_NATIONAL
, USB_PRODUCT_NATIONAL_BEARPAW2400
}, 0 },
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 },
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
},
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 },
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 },
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
;
224 usbd_pipe_handle sc_bulkin_pipe
;
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
;
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
;
241 #define USCANNER_OPEN 0x01 /* opened */
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
,
261 #elif defined(__OpenBSD__)
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
,
278 /* poll */ uscannerpoll
,
280 /* strategy */ nostrategy
,
281 /* name */ "uscanner",
282 /* maj */ USCANNER_CDEV_MAJOR
,
286 #if !defined(__FreeBSD__) || (__FreeBSD__ < 5)
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
);
302 USB_MATCH_START(uscanner
, uaa
);
304 return (uscanner_lookup(uaa
->vendor
, uaa
->product
) != NULL
?
305 UMATCH_VENDOR_PRODUCT
: UMATCH_NONE
);
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
;
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 */
332 aprint_error_dev(self
, "setting config no failed\n");
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",
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
);
353 aprint_error_dev(self
,
354 "could not read endpoint descriptor\n");
356 USB_ATTACH_ERROR_RETURN
;
359 if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
360 && (ed
->bmAttributes
& UE_XFERTYPE
) == UE_BULK
) {
362 } else if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_OUT
363 && (ed
->bmAttributes
& UE_XFERTYPE
) == UE_BULK
) {
367 if (ed_bulkin
&& ed_bulkout
) /* found all we need */
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");
376 USB_ATTACH_ERROR_RETURN
;
379 sc
->sc_bulkin
= ed_bulkin
->bEndpointAddress
;
380 sc
->sc_bulkout
= ed_bulkout
->bEndpointAddress
;
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
));
387 selinit(&sc
->sc_selq
);
388 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->sc_udev
,
391 USB_ATTACH_SUCCESS_RETURN
;
395 uscanneropen(dev_t dev
, int flag
, int mode
,
398 struct uscanner_softc
*sc
;
399 int unit
= USCANNERUNIT(dev
);
402 USB_GET_SC_OPEN(uscanner
, unit
, sc
);
404 DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n",
410 if (sc
->sc_state
& USCANNER_OPEN
)
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
);
427 printf("%s: cannot open bulk-in pipe (addr %d)\n",
428 USBDEVNAME(sc
->sc_dev
), sc
->sc_bulkin
);
429 uscanner_do_close(sc
);
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
);
437 printf("%s: cannot open bulk-out pipe (addr %d)\n",
438 USBDEVNAME(sc
->sc_dev
), sc
->sc_bulkout
);
439 uscanner_do_close(sc
);
444 sc
->sc_bulkin_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
445 if (sc
->sc_bulkin_xfer
== NULL
) {
446 uscanner_do_close(sc
);
449 sc
->sc_bulkout_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
450 if (sc
->sc_bulkout_xfer
== NULL
) {
451 uscanner_do_close(sc
);
455 return (0); /* success */
459 uscannerclose(dev_t dev
, int flag
, int mode
,
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
)));
470 if (!(sc
->sc_state
& USCANNER_OPEN
)) {
471 printf("uscannerclose: not open\n");
476 uscanner_do_close(sc
);
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
;
519 uscanner_do_read(struct uscanner_softc
*sc
, struct uio
*uio
, int flag
)
525 DPRINTFN(5, ("%s: uscannerread\n", USBDEVNAME(sc
->sc_dev
)));
530 while ((n
= min(sc
->sc_bulkin_bufferlen
, uio
->uio_resid
)) != 0) {
531 DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",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
,
540 if (err
== USBD_INTERRUPTED
)
542 else if (err
== USBD_TIMEOUT
)
548 DPRINTFN(1, ("uscannerread: got %d bytes\n", tn
));
549 error
= uiomove(sc
->sc_bulkin_buffer
, tn
, uio
);
558 uscannerread(dev_t dev
, struct uio
*uio
, int flag
)
560 struct uscanner_softc
*sc
;
563 USB_GET_SC(uscanner
, USCANNERUNIT(dev
), sc
);
566 error
= uscanner_do_read(sc
, uio
, flag
);
567 if (--sc
->sc_refcnt
< 0)
568 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
574 uscanner_do_write(struct uscanner_softc
*sc
, struct uio
*uio
, int flag
)
580 DPRINTFN(5, ("%s: uscanner_do_write\n", USBDEVNAME(sc
->sc_dev
)));
585 while ((n
= min(sc
->sc_bulkout_bufferlen
, uio
->uio_resid
)) != 0) {
586 error
= uiomove(sc
->sc_bulkout_buffer
, n
, uio
);
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
,
593 sc
->sc_bulkout_buffer
, &n
,
596 if (err
== USBD_INTERRUPTED
)
608 uscannerwrite(dev_t dev
, struct uio
*uio
, int flag
)
610 struct uscanner_softc
*sc
;
613 USB_GET_SC(uscanner
, USCANNERUNIT(dev
), sc
);
616 error
= uscanner_do_write(sc
, uio
, flag
);
617 if (--sc
->sc_refcnt
< 0)
618 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
622 #if defined(__NetBSD__) || defined(__OpenBSD__)
624 uscanner_activate(device_ptr_t self
, enum devact act
)
626 struct uscanner_softc
*sc
= device_private(self
);
629 case DVACT_DEACTIVATE
:
640 USB_DETACH_START(uscanner
, sc
);
642 #if defined(__NetBSD__) || defined(__OpenBSD__)
644 #elif defined(__FreeBSD__)
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
));
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
);
665 if (--sc
->sc_refcnt
>= 0) {
666 /* Wait for processes to go away. */
667 usb_detach_wait(USBDEV(sc
->sc_dev
));
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
)
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
);
689 VOP_REVOKE(vp
, REVOKEALL
);
693 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
695 seldestroy(&sc
->sc_selq
);
701 uscannerpoll(dev_t dev
, int events
, struct lwp
*l
)
703 struct uscanner_softc
*sc
;
706 USB_GET_SC(uscanner
, USCANNERUNIT(dev
), sc
);
712 * We have no easy way of determining if a read will
713 * yield any data or a write will happen.
717 (POLLIN
| POLLRDNORM
| POLLOUT
| POLLWRNORM
);
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
;
739 USB_GET_SC(uscanner
, USCANNERUNIT(dev
), sc
);
744 switch (kn
->kn_filter
) {
748 * We have no easy way of determining if a read will
749 * yield any data or a write will happen.
752 klist
= &sc
->sc_selq
.sel_klist
;
753 kn
->kn_fop
= &uscanner_seltrue_filtops
;
762 SLIST_INSERT_HEAD(klist
, kn
, kn_selnext
);
768 uscannerioctl(dev_t dev
, u_long cmd
, void *addr
,
769 int flag
, struct lwp
*l
)
774 #if defined(__FreeBSD__)
775 DRIVER_MODULE(uscanner
, uhub
, uscanner_driver
, uscanner_devclass
, usbd_driver_load
, 0);