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