ulpt.c revision 1.62 1 /* $NetBSD: ulpt.c,v 1.62 2004/04/23 17:25:25 itojun Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/ulpt.c,v 1.24 1999/11/17 22:33:44 n_hibma Exp $ */
3
4 /*
5 * Copyright (c) 1998, 2003 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 (at) augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
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.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 /*
42 * Printer Class spec: http://www.usb.org/developers/data/devclass/usbprint109.PDF
43 */
44
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: ulpt.c,v 1.62 2004/04/23 17:25:25 itojun Exp $");
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/proc.h>
51 #include <sys/kernel.h>
52 #include <sys/fcntl.h>
53 #if defined(__NetBSD__) || defined(__OpenBSD__)
54 #include <sys/device.h>
55 #include <sys/ioctl.h>
56 #elif defined(__FreeBSD__)
57 #include <sys/ioccom.h>
58 #include <sys/module.h>
59 #include <sys/bus.h>
60 #endif
61 #include <sys/uio.h>
62 #include <sys/conf.h>
63 #include <sys/vnode.h>
64 #include <sys/syslog.h>
65
66 #include <machine/vmparam.h> /* PAGE_SIZE */
67
68 #include <dev/usb/usb.h>
69 #include <dev/usb/usbdi.h>
70 #include <dev/usb/usbdi_util.h>
71 #include <dev/usb/usbdevs.h>
72 #include <dev/usb/usb_quirks.h>
73
74 #define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
75 #define STEP hz/4
76
77 #define LPTPRI (PZERO+8)
78 #define ULPT_BSIZE PAGE_SIZE
79
80 #define ULPT_READS_PER_SEC 5
81 #define ULPT_READ_TIMO 10
82
83 #ifdef ULPT_DEBUG
84 #define DPRINTF(x) if (ulptdebug) logprintf x
85 #define DPRINTFN(n,x) if (ulptdebug>(n)) logprintf x
86 int ulptdebug = 0;
87 #else
88 #define DPRINTF(x)
89 #define DPRINTFN(n,x)
90 #endif
91
92 #define UR_GET_DEVICE_ID 0
93 #define UR_GET_PORT_STATUS 1
94 #define UR_SOFT_RESET 2
95
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)
101
102 struct ulpt_softc {
103 USBBASEDEVICE sc_dev;
104 usbd_device_handle sc_udev; /* device */
105 usbd_interface_handle sc_iface; /* interface */
106 int sc_ifaceno;
107
108 int sc_out;
109 usbd_pipe_handle sc_out_pipe; /* bulk out pipe */
110 usbd_xfer_handle sc_out_xfer;
111 void *sc_out_buf;
112
113 int sc_in;
114 usbd_pipe_handle sc_in_pipe; /* bulk in pipe */
115 usbd_xfer_handle sc_in_xfer;
116 void *sc_in_buf;
117
118 usb_callout_t sc_read_callout;
119 int sc_has_callout;
120
121 u_char sc_state;
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 */
125 u_char sc_flags;
126 #define ULPT_NOPRIME 0x40 /* don't prime on open */
127 u_char sc_laststatus;
128
129 int sc_refcnt;
130 u_char sc_dying;
131
132 #if defined(__FreeBSD__)
133 dev_t dev;
134 dev_t dev_noprime;
135 #endif
136 };
137
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);
144
145 const struct cdevsw ulpt_cdevsw = {
146 ulptopen, ulptclose, ulptread, ulptwrite, ulptioctl,
147 nostop, notty, nopoll, nommap, nokqfilter,
148 };
149 #elif defined(__OpenBSD__)
150 cdev_decl(ulpt);
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;
156
157 #define ULPT_CDEV_MAJOR 113
158
159 Static struct cdevsw ulpt_cdevsw = {
160 /* open */ ulptopen,
161 /* close */ ulptclose,
162 /* read */ noread,
163 /* write */ ulptwrite,
164 /* ioctl */ ulptioctl,
165 /* poll */ nopoll,
166 /* mmap */ nommap,
167 /* strategy */ nostrategy,
168 /* name */ "ulpt",
169 /* maj */ ULPT_CDEV_MAJOR,
170 /* dump */ nodump,
171 /* psize */ nopsize,
172 /* flags */ 0,
173 #if !defined(__FreeBSD__) || (__FreeBSD__ < 5)
174 /* bmaj */ -1
175 #endif
176 };
177 #endif
178
179 void ulpt_disco(void *);
180
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,
187 usbd_status status);
188 void ulpt_tick(void *xsc);
189
190 #if 0
191 void ieee1284_print_id(char *);
192 #endif
193
194 #define ULPTUNIT(s) (minor(s) & 0x1f)
195 #define ULPTFLAGS(s) (minor(s) & 0xe0)
196
197
198 USB_DECLARE_DRIVER(ulpt);
199
200 USB_MATCH(ulpt)
201 {
202 USB_MATCH_START(ulpt, uaa);
203 usb_interface_descriptor_t *id;
204
205 DPRINTFN(10,("ulpt_match\n"));
206 if (uaa->iface == NULL)
207 return (UMATCH_NONE);
208 id = usbd_get_interface_descriptor(uaa->iface);
209 if (id != NULL &&
210 id->bInterfaceClass == UICLASS_PRINTER &&
211 id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
212 (id->bInterfaceProtocol == UIPROTO_PRINTER_UNI ||
213 id->bInterfaceProtocol == UIPROTO_PRINTER_BI ||
214 id->bInterfaceProtocol == UIPROTO_PRINTER_1284))
215 return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
216 return (UMATCH_NONE);
217 }
218
219 USB_ATTACH(ulpt)
220 {
221 USB_ATTACH_START(ulpt, sc, uaa);
222 usbd_device_handle dev = uaa->device;
223 usbd_interface_handle iface = uaa->iface;
224 usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface);
225 usb_interface_descriptor_t *id, *iend;
226 usb_config_descriptor_t *cdesc;
227 usbd_status err;
228 char devinfo[1024];
229 usb_endpoint_descriptor_t *ed;
230 u_int8_t epcount;
231 int i, altno;
232
233 DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
234 usbd_devinfo(dev, 0, devinfo, sizeof(devinfo));
235 USB_ATTACH_SETUP;
236 printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
237 devinfo, ifcd->bInterfaceClass, ifcd->bInterfaceSubClass);
238
239 /* XXX
240 * Stepping through the alternate settings needs to be abstracted out.
241 */
242 cdesc = usbd_get_config_descriptor(dev);
243 if (cdesc == NULL) {
244 printf("%s: failed to get configuration descriptor\n",
245 USBDEVNAME(sc->sc_dev));
246 USB_ATTACH_ERROR_RETURN;
247 }
248 iend = (usb_interface_descriptor_t *)
249 ((char *)cdesc + UGETW(cdesc->wTotalLength));
250 #ifdef DIAGNOSTIC
251 if (ifcd < (usb_interface_descriptor_t *)cdesc ||
252 ifcd >= iend)
253 panic("ulpt: iface desc out of range");
254 #endif
255 #if 0
256 /* Step through all the descriptors looking for bidir mode */
257 for (id = ifcd, altno = 0;
258 id < iend;
259 id = (void *)((char *)id + id->bLength)) {
260 if (id->bDescriptorType == UDESC_INTERFACE &&
261 id->bInterfaceNumber == ifcd->bInterfaceNumber) {
262 if (id->bInterfaceClass == UICLASS_PRINTER &&
263 id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
264 (id->bInterfaceProtocol == UIPROTO_PRINTER_BI /*||
265 id->bInterfaceProtocol == UIPROTO_PRINTER_1284*/))
266 goto found;
267 altno++;
268 }
269 }
270 id = ifcd; /* not found, use original */
271 found:
272 if (id != ifcd) {
273 /* Found a new bidir setting */
274 DPRINTF(("ulpt_attach: set altno = %d\n", altno));
275 err = usbd_set_interface(iface, altno);
276 if (err) {
277 printf("%s: setting alternate interface failed\n",
278 USBDEVNAME(sc->sc_dev));
279 sc->sc_dying = 1;
280 USB_ATTACH_ERROR_RETURN;
281 }
282 }
283 #else
284 id = ifcd;
285 err = 0;
286 altno = 0;
287 #endif
288
289 epcount = 0;
290 (void)usbd_endpoint_count(iface, &epcount);
291
292 sc->sc_in = -1;
293 sc->sc_out = -1;
294 for (i = 0; i < epcount; i++) {
295 ed = usbd_interface2endpoint_descriptor(iface, i);
296 if (ed == NULL) {
297 printf("%s: couldn't get ep %d\n",
298 USBDEVNAME(sc->sc_dev), i);
299 USB_ATTACH_ERROR_RETURN;
300 }
301 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
302 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
303 sc->sc_in = ed->bEndpointAddress;
304 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
305 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
306 sc->sc_out = ed->bEndpointAddress;
307 }
308 }
309 if (sc->sc_out == -1) {
310 printf("%s: could not find bulk out endpoint\n",
311 USBDEVNAME(sc->sc_dev));
312 sc->sc_dying = 1;
313 USB_ATTACH_ERROR_RETURN;
314 }
315
316 if (usbd_get_quirks(dev)->uq_flags & UQ_BROKEN_BIDIR) {
317 /* This device doesn't handle reading properly. */
318 sc->sc_in = -1;
319 }
320
321 printf("%s: using %s-directional mode\n", USBDEVNAME(sc->sc_dev),
322 sc->sc_in >= 0 ? "bi" : "uni");
323
324 DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_out));
325
326 sc->sc_iface = iface;
327 sc->sc_ifaceno = id->bInterfaceNumber;
328 sc->sc_udev = dev;
329
330 #if 0
331 /*
332 * This code is disabled because for some mysterious reason it causes
333 * printing not to work. But only sometimes, and mostly with
334 * UHCI and less often with OHCI. *sigh*
335 */
336 {
337 usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
338 usb_device_request_t req;
339 int len, alen;
340
341 req.bmRequestType = UT_READ_CLASS_INTERFACE;
342 req.bRequest = UR_GET_DEVICE_ID;
343 USETW(req.wValue, cd->bConfigurationValue);
344 USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting);
345 USETW(req.wLength, sizeof devinfo - 1);
346 err = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
347 &alen, USBD_DEFAULT_TIMEOUT);
348 if (err) {
349 printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev));
350 } else if (alen <= 2) {
351 printf("%s: empty device id, no printer connected?\n",
352 USBDEVNAME(sc->sc_dev));
353 } else {
354 /* devinfo now contains an IEEE-1284 device ID */
355 len = ((devinfo[0] & 0xff) << 8) | (devinfo[1] & 0xff);
356 if (len > sizeof devinfo - 3)
357 len = sizeof devinfo - 3;
358 devinfo[len] = 0;
359 printf("%s: device id <", USBDEVNAME(sc->sc_dev));
360 ieee1284_print_id(devinfo+2);
361 printf(">\n");
362 }
363 }
364 #endif
365
366 #if defined(__FreeBSD__)
367 sc->dev = make_dev(&ulpt_cdevsw, device_get_unit(self),
368 UID_ROOT, GID_OPERATOR, 0644, "ulpt%d", device_get_unit(self));
369 sc->dev_noprime = make_dev(&ulpt_cdevsw,
370 device_get_unit(self)|ULPT_NOPRIME,
371 UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self));
372 #endif
373
374 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
375 USBDEV(sc->sc_dev));
376
377 USB_ATTACH_SUCCESS_RETURN;
378 }
379
380 #if defined(__NetBSD__) || defined(__OpenBSD__)
381 int
382 ulpt_activate(device_ptr_t self, enum devact act)
383 {
384 struct ulpt_softc *sc = (struct ulpt_softc *)self;
385
386 switch (act) {
387 case DVACT_ACTIVATE:
388 return (EOPNOTSUPP);
389
390 case DVACT_DEACTIVATE:
391 sc->sc_dying = 1;
392 break;
393 }
394 return (0);
395 }
396 #endif
397
398 USB_DETACH(ulpt)
399 {
400 USB_DETACH_START(ulpt, sc);
401 int s;
402 #if defined(__NetBSD__) || defined(__OpenBSD__)
403 int maj, mn;
404 #elif defined(__FreeBSD__)
405 struct vnode *vp;
406 #endif
407
408 DPRINTF(("ulpt_detach: sc=%p\n", sc));
409
410 sc->sc_dying = 1;
411 if (sc->sc_out_pipe != NULL)
412 usbd_abort_pipe(sc->sc_out_pipe);
413 if (sc->sc_in_pipe != NULL)
414 usbd_abort_pipe(sc->sc_in_pipe);
415
416 s = splusb();
417 if (--sc->sc_refcnt >= 0) {
418 /* There is noone to wake, aborting the pipe is enough */
419 /* Wait for processes to go away. */
420 usb_detach_wait(USBDEV(sc->sc_dev));
421 }
422 splx(s);
423
424 #if defined(__NetBSD__) || defined(__OpenBSD__)
425 /* locate the major number */
426 #if defined(__NetBSD__)
427 maj = cdevsw_lookup_major(&ulpt_cdevsw);
428 #elif defined(__OpenBSD__)
429 for (maj = 0; maj < nchrdev; maj++)
430 if (cdevsw[maj].d_open == ulptopen)
431 break;
432 #endif
433
434 /* Nuke the vnodes for any open instances (calls close). */
435 mn = self->dv_unit;
436 vdevgone(maj, mn, mn, VCHR);
437 vdevgone(maj, mn | ULPT_NOPRIME , mn | ULPT_NOPRIME, VCHR);
438 #elif defined(__FreeBSD__)
439 vp = SLIST_FIRST(&sc->dev->si_hlist);
440 if (vp)
441 VOP_REVOKE(vp, REVOKEALL);
442 vp = SLIST_FIRST(&sc->dev_noprime->si_hlist);
443 if (vp)
444 VOP_REVOKE(vp, REVOKEALL);
445
446 destroy_dev(sc->dev);
447 destroy_dev(sc->dev_noprime);
448 #endif
449
450 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
451 USBDEV(sc->sc_dev));
452
453 return (0);
454 }
455
456 int
457 ulpt_status(struct ulpt_softc *sc)
458 {
459 usb_device_request_t req;
460 usbd_status err;
461 u_char status;
462
463 req.bmRequestType = UT_READ_CLASS_INTERFACE;
464 req.bRequest = UR_GET_PORT_STATUS;
465 USETW(req.wValue, 0);
466 USETW(req.wIndex, sc->sc_ifaceno);
467 USETW(req.wLength, 1);
468 err = usbd_do_request(sc->sc_udev, &req, &status);
469 DPRINTFN(1, ("ulpt_status: status=0x%02x err=%d\n", status, err));
470 if (!err)
471 return (status);
472 else
473 return (0);
474 }
475
476 void
477 ulpt_reset(struct ulpt_softc *sc)
478 {
479 usb_device_request_t req;
480
481 DPRINTFN(1, ("ulpt_reset\n"));
482 req.bRequest = UR_SOFT_RESET;
483 USETW(req.wValue, 0);
484 USETW(req.wIndex, sc->sc_ifaceno);
485 USETW(req.wLength, 0);
486
487 /*
488 * There was a mistake in the USB printer 1.0 spec that gave the
489 * request type as UT_WRITE_CLASS_OTHER; it should have been
490 * UT_WRITE_CLASS_INTERFACE. Many printers use the old one,
491 * so we try both.
492 */
493 req.bmRequestType = UT_WRITE_CLASS_OTHER;
494 if (usbd_do_request(sc->sc_udev, &req, 0)) { /* 1.0 */
495 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
496 (void)usbd_do_request(sc->sc_udev, &req, 0); /* 1.1 */
497 }
498 }
499
500 #if 0
501 static void
502 ulpt_input(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
503 {
504 struct ulpt_softc *sc = priv;
505
506 DPRINTFN(2,("ulpt_input: got some data\n"));
507 /* Do it again. */
508 if (xfer == sc->sc_in_xfer1)
509 usbd_transfer(sc->sc_in_xfer2);
510 else
511 usbd_transfer(sc->sc_in_xfer1);
512 }
513 #endif
514
515 int ulptusein = 1;
516
517 /*
518 * Reset the printer, then wait until it's selected and not busy.
519 */
520 int
521 ulptopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
522 {
523 u_char flags = ULPTFLAGS(dev);
524 struct ulpt_softc *sc;
525 usbd_status err;
526 int spin, error;
527
528 USB_GET_SC_OPEN(ulpt, ULPTUNIT(dev), sc);
529
530 if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying)
531 return (ENXIO);
532
533 if (sc->sc_state)
534 return (EBUSY);
535
536 sc->sc_state = ULPT_INIT;
537 sc->sc_flags = flags;
538 DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags));
539
540 #if defined(ULPT_DEBUG) && defined(__FreeBSD__)
541 /* Ignoring these flags might not be a good idea */
542 if ((flags & ~ULPT_NOPRIME) != 0)
543 printf("ulptopen: flags ignored: %b\n", flags,
544 "\20\3POS_INIT\4POS_ACK\6PRIME_OPEN\7AUTOLF\10BYPASS");
545 #endif
546
547
548 error = 0;
549 sc->sc_refcnt++;
550
551 if ((flags & ULPT_NOPRIME) == 0)
552 ulpt_reset(sc);
553
554 for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) {
555 DPRINTF(("ulpt_open: waiting a while\n"));
556 if (spin >= TIMEOUT) {
557 error = EBUSY;
558 sc->sc_state = 0;
559 goto done;
560 }
561
562 /* wait 1/4 second, give up if we get a signal */
563 error = tsleep((caddr_t)sc, LPTPRI | PCATCH, "ulptop", STEP);
564 if (error != EWOULDBLOCK) {
565 sc->sc_state = 0;
566 goto done;
567 }
568
569 if (sc->sc_dying) {
570 error = ENXIO;
571 sc->sc_state = 0;
572 goto done;
573 }
574 }
575
576 err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe);
577 if (err) {
578 error = EIO;
579 goto err0;
580 }
581 sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev);
582 if (sc->sc_out_xfer == NULL) {
583 error = ENOMEM;
584 goto err1;
585 }
586 sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, ULPT_BSIZE);
587 if (sc->sc_out_buf == NULL) {
588 error = ENOMEM;
589 goto err2;
590 }
591
592 if (ulptusein && sc->sc_in != -1) {
593 DPRINTF(("ulpt_open: open input pipe\n"));
594 err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe);
595 if (err) {
596 error = EIO;
597 goto err2;
598 }
599 sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev);
600 if (sc->sc_in_xfer == NULL) {
601 error = ENOMEM;
602 goto err3;
603 }
604 sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, ULPT_BSIZE);
605 if (sc->sc_in_buf == NULL) {
606 error = ENOMEM;
607 goto err4;
608 }
609
610 /* If it's not opened for read the set up a reader. */
611 if (!(flags & FREAD)) {
612 DPRINTF(("ulpt_open: start read callout\n"));
613 usb_callout_init(sc->sc_read_callout);
614 usb_callout(sc->sc_read_callout, hz/5, ulpt_tick, sc);
615 sc->sc_has_callout = 1;
616 }
617 }
618
619 sc->sc_state = ULPT_OPEN;
620 goto done;
621
622 err4:
623 usbd_free_xfer(sc->sc_in_xfer);
624 sc->sc_in_xfer = NULL;
625 err3:
626 usbd_close_pipe(sc->sc_in_pipe);
627 sc->sc_in_pipe = NULL;
628 err2:
629 usbd_free_xfer(sc->sc_out_xfer);
630 sc->sc_out_xfer = NULL;
631 err1:
632 usbd_close_pipe(sc->sc_out_pipe);
633 sc->sc_out_pipe = NULL;
634 err0:
635 sc->sc_state = 0;
636
637 done:
638 if (--sc->sc_refcnt < 0)
639 usb_detach_wakeup(USBDEV(sc->sc_dev));
640
641 DPRINTF(("ulptopen: done, error=%d\n", error));
642 return (error);
643 }
644
645 int
646 ulpt_statusmsg(u_char status, struct ulpt_softc *sc)
647 {
648 u_char new;
649
650 status = (status ^ LPS_INVERT) & LPS_MASK;
651 new = status & ~sc->sc_laststatus;
652 sc->sc_laststatus = status;
653
654 if (new & LPS_SELECT)
655 log(LOG_NOTICE, "%s: offline\n", USBDEVNAME(sc->sc_dev));
656 else if (new & LPS_NOPAPER)
657 log(LOG_NOTICE, "%s: out of paper\n", USBDEVNAME(sc->sc_dev));
658 else if (new & LPS_NERR)
659 log(LOG_NOTICE, "%s: output error\n", USBDEVNAME(sc->sc_dev));
660
661 return (status);
662 }
663
664 int
665 ulptclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
666 {
667 struct ulpt_softc *sc;
668
669 USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
670
671 if (sc->sc_state != ULPT_OPEN)
672 /* We are being forced to close before the open completed. */
673 return (0);
674
675 if (sc->sc_has_callout) {
676 usb_uncallout(sc->sc_read_callout, ulpt_tick, sc);
677 sc->sc_has_callout = 0;
678 }
679
680 if (sc->sc_out_pipe != NULL) {
681 usbd_abort_pipe(sc->sc_out_pipe);
682 usbd_close_pipe(sc->sc_out_pipe);
683 sc->sc_out_pipe = NULL;
684 }
685 if (sc->sc_out_xfer != NULL) {
686 usbd_free_xfer(sc->sc_out_xfer);
687 sc->sc_out_xfer = NULL;
688 }
689
690 if (sc->sc_in_pipe != NULL) {
691 usbd_abort_pipe(sc->sc_in_pipe);
692 usbd_close_pipe(sc->sc_in_pipe);
693 sc->sc_in_pipe = NULL;
694 }
695 if (sc->sc_in_xfer != NULL) {
696 usbd_free_xfer(sc->sc_in_xfer);
697 sc->sc_in_xfer = NULL;
698 }
699
700 sc->sc_state = 0;
701
702 DPRINTF(("ulptclose: closed\n"));
703 return (0);
704 }
705
706 int
707 ulpt_do_write(struct ulpt_softc *sc, struct uio *uio, int flags)
708 {
709 u_int32_t n;
710 int error = 0;
711 void *bufp;
712 usbd_xfer_handle xfer;
713 usbd_status err;
714
715 DPRINTF(("ulptwrite\n"));
716 xfer = sc->sc_out_xfer;
717 bufp = sc->sc_out_buf;
718 while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
719 ulpt_statusmsg(ulpt_status(sc), sc);
720 error = uiomove(bufp, n, uio);
721 if (error)
722 break;
723 DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n));
724 err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
725 USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
726 if (err) {
727 DPRINTF(("ulptwrite: error=%d\n", err));
728 error = EIO;
729 break;
730 }
731 }
732
733 return (error);
734 }
735
736 int
737 ulptwrite(dev_t dev, struct uio *uio, int flags)
738 {
739 struct ulpt_softc *sc;
740 int error;
741
742 USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
743
744 if (sc->sc_dying)
745 return (EIO);
746
747 sc->sc_refcnt++;
748 error = ulpt_do_write(sc, uio, flags);
749 if (--sc->sc_refcnt < 0)
750 usb_detach_wakeup(USBDEV(sc->sc_dev));
751 return (error);
752 }
753
754 int
755 ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags)
756 {
757 u_int32_t n, on;
758 int error = 0;
759 void *bufp;
760 usbd_xfer_handle xfer;
761 usbd_status err;
762
763 DPRINTF(("ulptread\n"));
764
765 if (sc->sc_in_pipe == NULL)
766 return 0;
767
768 xfer = sc->sc_in_xfer;
769 bufp = sc->sc_in_buf;
770 while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
771 DPRINTFN(1, ("ulptread: transfer %d bytes\n", n));
772 on = n;
773 err = usbd_bulk_transfer(xfer, sc->sc_in_pipe,
774 USBD_NO_COPY | USBD_SHORT_XFER_OK,
775 USBD_NO_TIMEOUT, bufp, &n, "ulptrd");
776 if (err) {
777 DPRINTF(("ulptread: error=%d\n", err));
778 error = EIO;
779 break;
780 }
781 error = uiomove(bufp, n, uio);
782 if (error)
783 break;
784 if (on != n)
785 break;
786 }
787
788 return (error);
789 }
790
791 int
792 ulptread(dev_t dev, struct uio *uio, int flags)
793 {
794 struct ulpt_softc *sc;
795 int error;
796
797 USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
798
799 if (sc->sc_dying)
800 return (EIO);
801
802 sc->sc_refcnt++;
803 error = ulpt_do_read(sc, uio, flags);
804 if (--sc->sc_refcnt < 0)
805 usb_detach_wakeup(USBDEV(sc->sc_dev));
806 return (error);
807 }
808
809 void
810 ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
811 usbd_status status)
812 {
813 usbd_status err;
814 u_int32_t n;
815 usbd_private_handle xsc;
816 struct ulpt_softc *sc;
817
818 usbd_get_xfer_status(xfer, &xsc, NULL, &n, &err);
819 sc = xsc;
820
821 DPRINTFN(1,("ulpt_read_cb: start sc=%p, err=%d n=%d\n", sc, err, n));
822
823 #ifdef ULPT_DEBUG
824 if (!err && n > 0)
825 DPRINTF(("ulpt_tick: discarding %d bytes\n", n));
826 #endif
827 if (!err || err == USBD_TIMEOUT)
828 usb_callout(sc->sc_read_callout, hz / ULPT_READS_PER_SEC,
829 ulpt_tick, sc);
830 }
831
832 void
833 ulpt_tick(void *xsc)
834 {
835 struct ulpt_softc *sc = xsc;
836 usbd_status err;
837
838 if (sc == NULL || sc->sc_dying)
839 return;
840
841 DPRINTFN(1,("ulpt_tick: start sc=%p\n", sc));
842
843 usbd_setup_xfer(sc->sc_in_xfer, sc->sc_in_pipe, sc, sc->sc_in_buf,
844 ULPT_BSIZE, USBD_NO_COPY | USBD_SHORT_XFER_OK,
845 ULPT_READ_TIMO, ulpt_read_cb);
846 err = usbd_transfer(sc->sc_in_xfer);
847 DPRINTFN(1,("ulpt_tick: err=%d\n", err));
848 }
849
850 int
851 ulptioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
852 {
853 int error = 0;
854
855 switch (cmd) {
856 default:
857 error = ENODEV;
858 }
859
860 return (error);
861 }
862
863 #if 0
864 /* XXX This does not belong here. */
865 /*
866 * Print select parts of a IEEE 1284 device ID.
867 */
868 void
869 ieee1284_print_id(char *str)
870 {
871 char *p, *q;
872
873 for (p = str-1; p; p = strchr(p, ';')) {
874 p++; /* skip ';' */
875 if (strncmp(p, "MFG:", 4) == 0 ||
876 strncmp(p, "MANUFACTURER:", 14) == 0 ||
877 strncmp(p, "MDL:", 4) == 0 ||
878 strncmp(p, "MODEL:", 6) == 0) {
879 q = strchr(p, ';');
880 if (q)
881 printf("%.*s", (int)(q - p + 1), p);
882 }
883 }
884 }
885 #endif
886
887 #if defined(__FreeBSD__)
888 DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, usbd_driver_load, 0);
889 #endif
890
891
892
893
894
895 #if 0
896 usbd_setup_xfer(sc->sc_in_xfer1, sc->sc_in_pipe, sc,
897 sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK,
898 USBD_NO_TIMEOUT, ulpt_input);
899 usbd_setup_xfer(sc->sc_in_xfer2, sc->sc_in_pipe, sc,
900 sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK,
901 USBD_NO_TIMEOUT, ulpt_input);
902 usbd_transfer(sc->sc_in_xfer1); /* ignore failed start */
903 #endif
904