1 /* $NetBSD: ulpt.c,v 1.83 2009/09/23 19:07:19 plunky Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/ulpt.c,v 1.24 1999/11/17 22:33:44 n_hibma Exp $ */
5 * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
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.
35 * Printer Class spec: http://www.usb.org/developers/data/devclass/usbprint109.PDF
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: ulpt.c,v 1.83 2009/09/23 19:07:19 plunky Exp $");
41 #include <sys/param.h>
42 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/fcntl.h>
46 #if defined(__NetBSD__) || defined(__OpenBSD__)
47 #include <sys/device.h>
48 #include <sys/ioctl.h>
49 #elif defined(__FreeBSD__)
50 #include <sys/ioccom.h>
51 #include <sys/module.h>
56 #include <sys/vnode.h>
57 #include <sys/syslog.h>
59 #include <machine/vmparam.h> /* PAGE_SIZE */
61 #include <dev/usb/usb.h>
62 #include <dev/usb/usbdi.h>
63 #include <dev/usb/usbdi_util.h>
64 #include <dev/usb/usbdevs.h>
65 #include <dev/usb/usb_quirks.h>
67 #define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
70 #define LPTPRI (PZERO+8)
71 #define ULPT_BSIZE PAGE_SIZE
73 #define ULPT_READS_PER_SEC 5
74 /* XXX Why is 10 us a reasonable value? */
75 #define ULPT_READ_TIMO 10
78 #define DPRINTFN(n,x) if (ulptdebug>=(n)) logprintf x
81 * The strategy for debug levels is:
82 * 1: attach-time operations
83 * 2: open/close/status/reset
85 * 4: read/write details
86 * 10: left over from previous debug code
92 #define UR_GET_DEVICE_ID 0
93 #define UR_GET_PORT_STATUS 1
94 #define UR_SOFT_RESET 2
96 #define LPS_NERR 0x08 /* printer no error */
97 #define LPS_SELECT 0x10 /* printer selected */
98 #define LPS_NOPAPER 0x20 /* printer out of paper */
99 #define LPS_INVERT (LPS_SELECT|LPS_NERR)
100 #define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER)
103 USBBASEDEVICE sc_dev
;
104 usbd_device_handle sc_udev
; /* device */
105 usbd_interface_handle sc_iface
; /* interface */
109 usbd_pipe_handle sc_out_pipe
; /* bulk out pipe */
110 usbd_xfer_handle sc_out_xfer
;
114 usbd_pipe_handle sc_in_pipe
; /* bulk in pipe */
115 usbd_xfer_handle sc_in_xfer
;
118 usb_callout_t sc_read_callout
; /* to drain input on write-only opens */
122 #define ULPT_OPEN 0x01 /* device is open */
123 #define ULPT_OBUSY 0x02 /* printer is busy doing output */
124 #define ULPT_INIT 0x04 /* waiting to initialize for open */
126 #define ULPT_NOPRIME 0x40 /* don't prime on open */
127 u_char sc_laststatus
;
132 #if defined(__FreeBSD__)
138 #if defined(__NetBSD__)
139 dev_type_open(ulptopen
);
140 dev_type_close(ulptclose
);
141 dev_type_write(ulptwrite
);
142 dev_type_read(ulptread
);
143 dev_type_ioctl(ulptioctl
);
145 const struct cdevsw ulpt_cdevsw
= {
146 ulptopen
, ulptclose
, ulptread
, ulptwrite
, ulptioctl
,
147 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
,
149 #elif defined(__OpenBSD__)
151 #elif defined(__FreeBSD__)
152 Static d_open_t ulptopen
;
153 Static d_close_t ulptclose
;
154 Static d_write_t ulptwrite
;
155 Static d_ioctl_t ulptioctl
;
157 #define ULPT_CDEV_MAJOR 113
159 Static
struct cdevsw ulpt_cdevsw
= {
161 /* close */ ulptclose
,
163 /* write */ ulptwrite
,
164 /* ioctl */ ulptioctl
,
167 /* strategy */ nostrategy
,
169 /* maj */ ULPT_CDEV_MAJOR
,
173 #if !defined(__FreeBSD__) || (__FreeBSD__ < 5)
179 void ulpt_disco(void *);
181 int ulpt_do_write(struct ulpt_softc
*, struct uio
*uio
, int);
182 int ulpt_do_read(struct ulpt_softc
*, struct uio
*uio
, int);
183 int ulpt_status(struct ulpt_softc
*);
184 void ulpt_reset(struct ulpt_softc
*);
185 int ulpt_statusmsg(u_char
, struct ulpt_softc
*);
186 void ulpt_read_cb(usbd_xfer_handle xfer
, usbd_private_handle priv
,
188 void ulpt_tick(void *xsc
);
191 void ieee1284_print_id(char *);
194 #define ULPTUNIT(s) (minor(s) & 0x1f)
195 #define ULPTFLAGS(s) (minor(s) & 0xe0)
198 USB_DECLARE_DRIVER(ulpt
);
202 USB_IFMATCH_START(ulpt
, uaa
);
204 /* XXX Print something useful, or don't. */
205 DPRINTFN(10,("ulpt_match\n"));
207 if (uaa
->class == UICLASS_PRINTER
&&
208 uaa
->subclass
== UISUBCLASS_PRINTER
&&
209 (uaa
->proto
== UIPROTO_PRINTER_UNI
||
210 uaa
->proto
== UIPROTO_PRINTER_BI
||
211 uaa
->proto
== UIPROTO_PRINTER_1284
))
212 return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO
);
213 return (UMATCH_NONE
);
218 USB_IFATTACH_START(ulpt
, sc
, uaa
);
219 usbd_device_handle dev
= uaa
->device
;
220 usbd_interface_handle iface
= uaa
->iface
;
221 usb_interface_descriptor_t
*ifcd
= usbd_get_interface_descriptor(iface
);
222 const usb_interface_descriptor_t
*id
;
225 usb_endpoint_descriptor_t
*ed
;
228 usbd_desc_iter_t iter
;
235 devinfop
= usbd_devinfo_alloc(dev
, 0);
236 aprint_normal_dev(self
, "%s, iclass %d/%d\n",
237 devinfop
, ifcd
->bInterfaceClass
, ifcd
->bInterfaceSubClass
);
238 usbd_devinfo_free(devinfop
);
240 /* Loop through descriptors looking for a bidir mode. */
241 usb_desc_iter_init(dev
, &iter
);
243 id
= (const usb_interface_descriptor_t
*)usb_desc_iter_next(&iter
);
246 if (id
->bDescriptorType
== UDESC_INTERFACE
&&
247 id
->bInterfaceNumber
== ifcd
->bInterfaceNumber
) {
248 if (id
->bInterfaceClass
== UICLASS_PRINTER
&&
249 id
->bInterfaceSubClass
== UISUBCLASS_PRINTER
&&
250 (id
->bInterfaceProtocol
== UIPROTO_PRINTER_BI
/*||
251 id->bInterfaceProtocol == UIPROTO_PRINTER_1284*/))
256 id
= ifcd
; /* not found, use original */
259 /* Found a new bidir setting */
260 DPRINTFN(1, ("ulpt_attach: set altno = %d\n", altno
));
261 err
= usbd_set_interface(iface
, altno
);
263 aprint_error_dev(self
,
264 "setting alternate interface failed\n");
266 USB_ATTACH_ERROR_RETURN
;
271 (void)usbd_endpoint_count(iface
, &epcount
);
275 for (i
= 0; i
< epcount
; i
++) {
276 ed
= usbd_interface2endpoint_descriptor(iface
, i
);
278 aprint_error_dev(self
, "couldn't get ep %d\n", i
);
279 USB_ATTACH_ERROR_RETURN
;
281 if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
&&
282 UE_GET_XFERTYPE(ed
->bmAttributes
) == UE_BULK
) {
283 sc
->sc_in
= ed
->bEndpointAddress
;
284 } else if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_OUT
&&
285 UE_GET_XFERTYPE(ed
->bmAttributes
) == UE_BULK
) {
286 sc
->sc_out
= ed
->bEndpointAddress
;
289 if (sc
->sc_out
== -1) {
290 aprint_error_dev(self
, "could not find bulk out endpoint\n");
292 USB_ATTACH_ERROR_RETURN
;
295 if (usbd_get_quirks(dev
)->uq_flags
& UQ_BROKEN_BIDIR
) {
296 /* This device doesn't handle reading properly. */
300 aprint_normal_dev(self
, "using %s-directional mode\n",
301 sc
->sc_in
>= 0 ? "bi" : "uni");
303 sc
->sc_iface
= iface
;
304 sc
->sc_ifaceno
= id
->bInterfaceNumber
;
309 * This code is disabled because for some mysterious reason it causes
310 * printing not to work. But only sometimes, and mostly with
311 * UHCI and less often with OHCI. *sigh*
314 usb_config_descriptor_t
*cd
= usbd_get_config_descriptor(dev
);
315 usb_device_request_t req
;
318 req
.bmRequestType
= UT_READ_CLASS_INTERFACE
;
319 req
.bRequest
= UR_GET_DEVICE_ID
;
320 USETW(req
.wValue
, cd
->bConfigurationValue
);
321 USETW2(req
.wIndex
, id
->bInterfaceNumber
, id
->bAlternateSetting
);
322 USETW(req
.wLength
, DEVINFOSIZE
- 1);
323 err
= usbd_do_request_flags(dev
, &req
, devinfop
, USBD_SHORT_XFER_OK
,
324 &alen
, USBD_DEFAULT_TIMEOUT
);
326 printf("%s: cannot get device id\n", USBDEVNAME(sc
->sc_dev
));
327 } else if (alen
<= 2) {
328 printf("%s: empty device id, no printer connected?\n",
329 USBDEVNAME(sc
->sc_dev
));
331 /* devinfop now contains an IEEE-1284 device ID */
332 len
= ((devinfop
[0] & 0xff) << 8) | (devinfop
[1] & 0xff);
333 if (len
> DEVINFOSIZE
- 3)
334 len
= DEVINFOSIZE
- 3;
336 printf("%s: device id <", USBDEVNAME(sc
->sc_dev
));
337 ieee1284_print_id(devinfop
+2);
343 #if defined(__FreeBSD__)
344 sc
->dev
= make_dev(&ulpt_cdevsw
, device_get_unit(self
),
345 UID_ROOT
, GID_OPERATOR
, 0644, "ulpt%d", device_get_unit(self
));
346 sc
->dev_noprime
= make_dev(&ulpt_cdevsw
,
347 device_get_unit(self
)|ULPT_NOPRIME
,
348 UID_ROOT
, GID_OPERATOR
, 0644, "unlpt%d", device_get_unit(self
));
351 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->sc_udev
,
354 DPRINTFN(1, ("ulpt_attach: sc=%p in=%d out=%d\n",
355 sc
, sc
->sc_out
, sc
->sc_in
));
357 USB_ATTACH_SUCCESS_RETURN
;
360 #if defined(__NetBSD__) || defined(__OpenBSD__)
362 ulpt_activate(device_ptr_t self
, enum devact act
)
364 struct ulpt_softc
*sc
= device_private(self
);
367 case DVACT_DEACTIVATE
:
378 USB_DETACH_START(ulpt
, sc
);
380 #if defined(__NetBSD__) || defined(__OpenBSD__)
382 #elif defined(__FreeBSD__)
386 DPRINTFN(1, ("ulpt_detach: sc=%p\n", sc
));
389 if (sc
->sc_out_pipe
!= NULL
)
390 usbd_abort_pipe(sc
->sc_out_pipe
);
391 if (sc
->sc_in_pipe
!= NULL
)
392 usbd_abort_pipe(sc
->sc_in_pipe
);
395 if (--sc
->sc_refcnt
>= 0) {
396 /* There is noone to wake, aborting the pipe is enough */
397 /* Wait for processes to go away. */
398 usb_detach_wait(USBDEV(sc
->sc_dev
));
402 #if defined(__NetBSD__) || defined(__OpenBSD__)
403 /* locate the major number */
404 #if defined(__NetBSD__)
405 maj
= cdevsw_lookup_major(&ulpt_cdevsw
);
406 #elif defined(__OpenBSD__)
407 for (maj
= 0; maj
< nchrdev
; maj
++)
408 if (cdevsw
[maj
].d_open
== ulptopen
)
412 /* Nuke the vnodes for any open instances (calls close). */
413 mn
= device_unit(self
);
414 vdevgone(maj
, mn
, mn
, VCHR
);
415 vdevgone(maj
, mn
| ULPT_NOPRIME
, mn
| ULPT_NOPRIME
, VCHR
);
416 #elif defined(__FreeBSD__)
417 vp
= SLIST_FIRST(&sc
->dev
->si_hlist
);
419 VOP_REVOKE(vp
, REVOKEALL
);
420 vp
= SLIST_FIRST(&sc
->dev_noprime
->si_hlist
);
422 VOP_REVOKE(vp
, REVOKEALL
);
424 destroy_dev(sc
->dev
);
425 destroy_dev(sc
->dev_noprime
);
428 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
435 ulpt_status(struct ulpt_softc
*sc
)
437 usb_device_request_t req
;
441 req
.bmRequestType
= UT_READ_CLASS_INTERFACE
;
442 req
.bRequest
= UR_GET_PORT_STATUS
;
443 USETW(req
.wValue
, 0);
444 USETW(req
.wIndex
, sc
->sc_ifaceno
);
445 USETW(req
.wLength
, 1);
446 err
= usbd_do_request(sc
->sc_udev
, &req
, &status
);
447 DPRINTFN(2, ("ulpt_status: status=0x%02x err=%d\n", status
, err
));
455 ulpt_reset(struct ulpt_softc
*sc
)
457 usb_device_request_t req
;
459 DPRINTFN(2, ("ulpt_reset\n"));
460 req
.bRequest
= UR_SOFT_RESET
;
461 USETW(req
.wValue
, 0);
462 USETW(req
.wIndex
, sc
->sc_ifaceno
);
463 USETW(req
.wLength
, 0);
466 * There was a mistake in the USB printer 1.0 spec that gave the
467 * request type as UT_WRITE_CLASS_OTHER; it should have been
468 * UT_WRITE_CLASS_INTERFACE. Many printers use the old one,
471 req
.bmRequestType
= UT_WRITE_CLASS_OTHER
;
472 if (usbd_do_request(sc
->sc_udev
, &req
, 0)) { /* 1.0 */
473 req
.bmRequestType
= UT_WRITE_CLASS_INTERFACE
;
474 (void)usbd_do_request(sc
->sc_udev
, &req
, 0); /* 1.1 */
481 * Reset the printer, then wait until it's selected and not busy.
484 ulptopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
486 u_char flags
= ULPTFLAGS(dev
);
487 struct ulpt_softc
*sc
;
491 USB_GET_SC_OPEN(ulpt
, ULPTUNIT(dev
), sc
);
493 if (sc
== NULL
|| sc
->sc_iface
== NULL
|| sc
->sc_dying
)
499 sc
->sc_state
= ULPT_INIT
;
500 sc
->sc_flags
= flags
;
501 DPRINTFN(2, ("ulptopen: flags=0x%x\n", (unsigned)flags
));
503 #if defined(ULPT_DEBUG) && defined(__FreeBSD__)
504 /* Ignoring these flags might not be a good idea */
505 if ((flags
& ~ULPT_NOPRIME
) != 0)
506 printf("ulptopen: flags ignored: %b\n", flags
,
507 "\20\3POS_INIT\4POS_ACK\6PRIME_OPEN\7AUTOLF\10BYPASS");
514 #if 0 /* XXX causes some printers to disconnect */
515 if ((flags
& ULPT_NOPRIME
) == 0)
519 for (spin
= 0; (ulpt_status(sc
) & LPS_SELECT
) == 0; spin
+= STEP
) {
520 DPRINTFN(2, ("ulpt_open: waiting a while\n"));
521 if (spin
>= TIMEOUT
) {
527 /* wait 1/4 second, give up if we get a signal */
528 error
= tsleep((void *)sc
, LPTPRI
| PCATCH
, "ulptop", STEP
);
529 if (error
!= EWOULDBLOCK
) {
541 err
= usbd_open_pipe(sc
->sc_iface
, sc
->sc_out
, 0, &sc
->sc_out_pipe
);
546 sc
->sc_out_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
547 if (sc
->sc_out_xfer
== NULL
) {
551 sc
->sc_out_buf
= usbd_alloc_buffer(sc
->sc_out_xfer
, ULPT_BSIZE
);
552 if (sc
->sc_out_buf
== NULL
) {
557 if (ulptusein
&& sc
->sc_in
!= -1) {
558 DPRINTFN(2, ("ulpt_open: opening input pipe %d\n", sc
->sc_in
));
559 err
= usbd_open_pipe(sc
->sc_iface
, sc
->sc_in
,0,&sc
->sc_in_pipe
);
564 sc
->sc_in_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
565 if (sc
->sc_in_xfer
== NULL
) {
569 sc
->sc_in_buf
= usbd_alloc_buffer(sc
->sc_in_xfer
, ULPT_BSIZE
);
570 if (sc
->sc_in_buf
== NULL
) {
575 /* If it's not opened for read then set up a reader. */
576 if (!(flag
& FREAD
)) {
577 DPRINTFN(2, ("ulpt_open: start read callout\n"));
578 usb_callout_init(sc
->sc_read_callout
);
579 usb_callout(sc
->sc_read_callout
, hz
/5, ulpt_tick
, sc
);
580 sc
->sc_has_callout
= 1;
584 sc
->sc_state
= ULPT_OPEN
;
588 usbd_free_xfer(sc
->sc_in_xfer
);
589 sc
->sc_in_xfer
= NULL
;
591 usbd_close_pipe(sc
->sc_in_pipe
);
592 sc
->sc_in_pipe
= NULL
;
594 usbd_free_xfer(sc
->sc_out_xfer
);
595 sc
->sc_out_xfer
= NULL
;
597 usbd_close_pipe(sc
->sc_out_pipe
);
598 sc
->sc_out_pipe
= NULL
;
603 if (--sc
->sc_refcnt
< 0)
604 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
606 DPRINTFN(2, ("ulptopen: done, error=%d\n", error
));
611 * XXX Document return value semantics.
614 ulpt_statusmsg(u_char status
, struct ulpt_softc
*sc
)
618 status
= (status
^ LPS_INVERT
) & LPS_MASK
;
619 new = status
& ~sc
->sc_laststatus
;
620 sc
->sc_laststatus
= status
;
622 if (new & LPS_SELECT
)
623 log(LOG_NOTICE
, "%s: offline\n", USBDEVNAME(sc
->sc_dev
));
624 if (new & LPS_NOPAPER
)
625 log(LOG_NOTICE
, "%s: out of paper\n", USBDEVNAME(sc
->sc_dev
));
627 log(LOG_NOTICE
, "%s: output error\n", USBDEVNAME(sc
->sc_dev
));
633 ulptclose(dev_t dev
, int flag
, int mode
,
636 struct ulpt_softc
*sc
;
638 USB_GET_SC(ulpt
, ULPTUNIT(dev
), sc
);
640 if (sc
->sc_state
!= ULPT_OPEN
)
641 /* We are being forced to close before the open completed. */
644 if (sc
->sc_has_callout
) {
645 DPRINTFN(2, ("ulptclose: stopping read callout\n"));
646 usb_uncallout(sc
->sc_read_callout
, ulpt_tick
, sc
);
647 sc
->sc_has_callout
= 0;
650 if (sc
->sc_out_pipe
!= NULL
) {
651 usbd_abort_pipe(sc
->sc_out_pipe
);
652 usbd_close_pipe(sc
->sc_out_pipe
);
653 sc
->sc_out_pipe
= NULL
;
655 if (sc
->sc_out_xfer
!= NULL
) {
656 usbd_free_xfer(sc
->sc_out_xfer
);
657 sc
->sc_out_xfer
= NULL
;
660 if (sc
->sc_in_pipe
!= NULL
) {
661 usbd_abort_pipe(sc
->sc_in_pipe
);
662 usbd_close_pipe(sc
->sc_in_pipe
);
663 sc
->sc_in_pipe
= NULL
;
665 if (sc
->sc_in_xfer
!= NULL
) {
666 usbd_free_xfer(sc
->sc_in_xfer
);
667 sc
->sc_in_xfer
= NULL
;
672 DPRINTFN(2, ("ulptclose: closed\n"));
677 ulpt_do_write(struct ulpt_softc
*sc
, struct uio
*uio
, int flags
)
682 usbd_xfer_handle xfer
;
685 DPRINTFN(3, ("ulptwrite\n"));
686 xfer
= sc
->sc_out_xfer
;
687 bufp
= sc
->sc_out_buf
;
688 while ((n
= min(ULPT_BSIZE
, uio
->uio_resid
)) != 0) {
689 ulpt_statusmsg(ulpt_status(sc
), sc
);
690 error
= uiomove(bufp
, n
, uio
);
693 DPRINTFN(4, ("ulptwrite: transfer %d bytes\n", n
));
694 err
= usbd_bulk_transfer(xfer
, sc
->sc_out_pipe
, USBD_NO_COPY
,
695 USBD_NO_TIMEOUT
, bufp
, &n
, "ulptwr");
697 DPRINTFN(3, ("ulptwrite: error=%d\n", err
));
707 ulptwrite(dev_t dev
, struct uio
*uio
, int flags
)
709 struct ulpt_softc
*sc
;
712 USB_GET_SC(ulpt
, ULPTUNIT(dev
), sc
);
718 error
= ulpt_do_write(sc
, uio
, flags
);
719 if (--sc
->sc_refcnt
< 0)
720 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
725 * Perform a read operation according to the given uio.
726 * This should respect nonblocking I/O status.
728 * XXX Doing a short read when more data is available seems to be
730 * http://www.freebsd.org/cgi/query-pr.cgi?pr=91538&cat= for a fix.
731 * However, this will be unnecessary given a proper fix for the next
732 * problem, and most actual callers read a lot.
734 * XXX This code should interact properly with select/poll, and that
735 * requires the USB transactions to be queued and function before the
736 * user does a read. Read will then consume data from a buffer, and
737 * not interact with the device. See ucom.c for an example of how to
741 ulpt_do_read(struct ulpt_softc
*sc
, struct uio
*uio
, int flags
)
743 u_int32_t n
, nread
, nreq
;
744 int error
= 0, nonblocking
, timeout
;
746 usbd_xfer_handle xfer
;
747 usbd_status err
= USBD_NORMAL_COMPLETION
;
749 /* XXX Resolve with background reader process. KASSERT? */
750 if (sc
->sc_in_pipe
== NULL
)
753 if (flags
& IO_NDELAY
)
759 timeout
= USBD_DEFAULT_TIMEOUT
; /* 5 ms */
761 timeout
= USBD_NO_TIMEOUT
;
763 DPRINTFN(3, ("ulptread nonblocking=%d uio_reside=%ld timeout=%d\n",
764 nonblocking
, (u_long
)uio
->uio_resid
, timeout
));
766 xfer
= sc
->sc_in_xfer
;
767 bufp
= sc
->sc_in_buf
;
769 while ((nreq
= min(ULPT_BSIZE
, uio
->uio_resid
)) != 0) {
772 printf("ulptread: pre-switch error %d != 0", error
);
777 * XXX Even with the short timeout, this will tsleep,
778 * but it should be adequately prompt in practice.
781 DPRINTFN(4, ("ulptread: transfer %d bytes, nonblocking=%d timeout=%d\n",
782 n
, nonblocking
, timeout
));
783 err
= usbd_bulk_transfer(xfer
, sc
->sc_in_pipe
,
784 USBD_NO_COPY
| USBD_SHORT_XFER_OK
,
785 timeout
, bufp
, &n
, "ulptrd");
787 DPRINTFN(4, ("ulptread: transfer complete nreq %d n %d nread %d err %d\n",
788 nreq
, n
, nread
, err
));
790 * Process "err" return, jumping to done if we set "error".
793 case USBD_NORMAL_COMPLETION
:
795 DPRINTFN(3, ("ulptread: NORMAL n==0\n"));
799 case USBD_SHORT_XFER
:
800 /* We said SHORT_XFER_OK, so shouldn't happen. */
801 DPRINTFN(3, ("ulptread: SHORT n=%d\n", n
));
805 if (nonblocking
== 0) {
806 /* XXX Cannot happen; perhaps KASSERT. */
807 printf("ulptread: timeout in blocking mode\n");
812 DPRINTFN(3, ("ulptread: TIMEOUT n %d nread %d error %d\n",
815 * Don't set error until we understand why
820 case USBD_INTERRUPTED
:
822 * The tsleep in usbd_bulk_transfer was
823 * interrupted. Reflect it to the caller so
824 * that reading can be interrupted.
827 DPRINTFN(3, ("ulptread: EINTR error %d\n", error
));
832 /* Assume all other return codes are really errors. */
834 DPRINTFN(3, ("ulptread: n %d err %d error %d\n",
841 printf("ulptread: post-switch error %d != 0", error
);
847 * Record progress to enable later choosing
848 * between short reads and EWOULDBLOCK.
852 /* Copy to userspace, giving up on any error. */
853 error
= uiomove(bufp
, n
, uio
);
858 * We read 0 bytes, and therefore are done,
859 * even if we aren't in nonblocking mode.
861 if (error
== 0 && nread
== 0)
863 DPRINTFN(3, ("ulptread: read 0=>done error %d\n",
869 * A short transfer indicates no more data will be
870 * forthcoming. Terminate this read regardless of
871 * whether we are in nonblocking mode. XXX Reconsider
872 * for blocking mode; maybe we should continue to
873 * block, but maybe it just doesn't make senes to do
874 * blocking reads from devices like this.
876 if (err
== USBD_SHORT_XFER
) {
877 DPRINTFN(3, ("ulptread: SHORT=>done n %d nread %d err %d error %d\n",
878 n
, nread
, err
, error
));
884 DPRINTFN(3, ("ulptread: finished n %d nread %d err %d error %d\n",
885 n
, nread
, err
, error
));
890 ulptread(dev_t dev
, struct uio
*uio
, int flags
)
892 struct ulpt_softc
*sc
;
895 USB_GET_SC(ulpt
, ULPTUNIT(dev
), sc
);
901 error
= ulpt_do_read(sc
, uio
, flags
);
902 if (--sc
->sc_refcnt
< 0)
903 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
908 ulpt_read_cb(usbd_xfer_handle xfer
, usbd_private_handle priv
,
913 usbd_private_handle xsc
;
914 struct ulpt_softc
*sc
;
916 usbd_get_xfer_status(xfer
, &xsc
, NULL
, &n
, &err
);
919 DPRINTFN(4, ("ulpt_read_cb: start sc=%p, err=%d n=%d\n", sc
, err
, n
));
923 DPRINTFN(3, ("ulpt_tick: discarding %d bytes\n", n
));
925 if (!err
|| err
== USBD_TIMEOUT
)
926 usb_callout(sc
->sc_read_callout
, hz
/ ULPT_READS_PER_SEC
,
931 * For devices which are not opened for reading, this function is
932 * called continuously to start read bulk transfers to avoid the
933 * printer overflowing its output buffer.
935 * XXX This should be adapted for continuous reads to allow select to
936 * work; see do_ulpt_read().
941 struct ulpt_softc
*sc
= xsc
;
944 if (sc
== NULL
|| sc
->sc_dying
)
947 usbd_setup_xfer(sc
->sc_in_xfer
, sc
->sc_in_pipe
, sc
, sc
->sc_in_buf
,
948 ULPT_BSIZE
, USBD_NO_COPY
| USBD_SHORT_XFER_OK
,
949 ULPT_READ_TIMO
, ulpt_read_cb
);
950 err
= usbd_transfer(sc
->sc_in_xfer
);
951 DPRINTFN(3, ("ulpt_tick: sc=%p err=%d\n", sc
, err
));
955 ulptioctl(dev_t dev
, u_long cmd
, void *data
,
956 int flag
, struct lwp
*l
)
958 struct ulpt_softc
*sc
;
960 USB_GET_SC(ulpt
, ULPTUNIT(dev
), sc
);
971 /* XXX This does not belong here. */
973 * Print select parts of a IEEE 1284 device ID.
976 ieee1284_print_id(char *str
)
980 for (p
= str
-1; p
; p
= strchr(p
, ';')) {
982 if (strncmp(p
, "MFG:", 4) == 0 ||
983 strncmp(p
, "MANUFACTURER:", 14) == 0 ||
984 strncmp(p
, "MDL:", 4) == 0 ||
985 strncmp(p
, "MODEL:", 6) == 0) {
988 printf("%.*s", (int)(q
- p
+ 1), p
);
994 #if defined(__FreeBSD__)
995 DRIVER_MODULE(ulpt
, uhub
, ulpt_driver
, ulpt_devclass
, usbd_driver_load
, 0);