/* * Reset the printer, then wait until it's selected and not busy. */ int ulptopen(dev_t dev, int flag, int mode, struct proc *p) { u_char flags = ULPTFLAGS(dev); struct ulpt_softc *sc; usbd_status err; int error; if (ULPTUNIT(dev) >= ulpt_cd.cd_ndevs) return (ENXIO); sc = ulpt_cd.cd_devs[ULPTUNIT(dev)]; if (sc == NULL) return (ENXIO); if (sc == NULL || sc->sc_iface == NULL || usbd_is_dying(sc->sc_udev)) return (ENXIO); if (sc->sc_state) return (EBUSY); sc->sc_state = ULPT_INIT; sc->sc_flags = flags; DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags)); error = 0; sc->sc_refcnt++; if ((flags & ULPT_NOPRIME) == 0) { ulpt_reset(sc); if (usbd_is_dying(sc->sc_udev)) { error = ENXIO; sc->sc_state = 0; goto done; } } err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe); if (err) { sc->sc_state = 0; error = EIO; goto done; } if (ulptusein && sc->sc_in != -1) { DPRINTF(("ulpt_open: open input pipe\n")); err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe); if (err) { error = EIO; usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; sc->sc_state = 0; goto done; } sc->sc_in_xfer1 = usbd_alloc_xfer(sc->sc_udev); sc->sc_in_xfer2 = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_in_xfer1 == NULL || sc->sc_in_xfer2 == NULL) { error = ENOMEM; if (sc->sc_in_xfer1 != NULL) { usbd_free_xfer(sc->sc_in_xfer1); sc->sc_in_xfer1 = NULL; } if (sc->sc_in_xfer2 != NULL) { usbd_free_xfer(sc->sc_in_xfer2); sc->sc_in_xfer2 = NULL; } usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; sc->sc_state = 0; goto done; } usbd_setup_xfer(sc->sc_in_xfer1, sc->sc_in_pipe, sc, sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ulpt_input); usbd_setup_xfer(sc->sc_in_xfer2, sc->sc_in_pipe, sc, sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ulpt_input); usbd_transfer(sc->sc_in_xfer1); /* ignore failed start */ } sc->sc_state = ULPT_OPEN; done: if (--sc->sc_refcnt < 0) usb_detach_wakeup(&sc->sc_dev); DPRINTF(("ulptopen: done, error=%d\n", error)); return (error); }
/* * Reset the printer, then wait until it's selected and not busy. */ int ulptopen(dev_t dev, int flag, int mode, struct proc *p) { u_char flags = ULPTFLAGS(dev); struct ulpt_softc *sc; usbd_status err; int spin, error; if (ULPTUNIT(dev) >= ulpt_cd.cd_ndevs) return (ENXIO); sc = ulpt_cd.cd_devs[ULPTUNIT(dev)]; if (sc == NULL) return (ENXIO); if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying) return (ENXIO); if (sc->sc_state) return (EBUSY); sc->sc_state = ULPT_INIT; sc->sc_flags = flags; DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags)); error = 0; sc->sc_refcnt++; if ((flags & ULPT_NOPRIME) == 0) ulpt_reset(sc); for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) { DPRINTF(("ulpt_open: waiting a while\n")); if (spin >= TIMEOUT) { error = EBUSY; sc->sc_state = 0; goto done; } /* wait 1/4 second, give up if we get a signal */ error = tsleep((caddr_t)sc, LPTPRI | PCATCH, "ulptop", STEP); if (error != EWOULDBLOCK) { sc->sc_state = 0; goto done; } if (sc->sc_dying) { error = ENXIO; sc->sc_state = 0; goto done; } } err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe); if (err) { sc->sc_state = 0; error = EIO; goto done; } if (ulptusein && sc->sc_in != -1) { DPRINTF(("ulpt_open: open input pipe\n")); err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe); if (err) { error = EIO; usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; sc->sc_state = 0; goto done; } sc->sc_in_xfer1 = usbd_alloc_xfer(sc->sc_udev); sc->sc_in_xfer2 = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_in_xfer1 == NULL || sc->sc_in_xfer2 == NULL) { error = ENOMEM; if (sc->sc_in_xfer1 != NULL) { usbd_free_xfer(sc->sc_in_xfer1); sc->sc_in_xfer1 = NULL; } if (sc->sc_in_xfer2 != NULL) { usbd_free_xfer(sc->sc_in_xfer2); sc->sc_in_xfer2 = NULL; } usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; sc->sc_state = 0; goto done; } usbd_setup_xfer(sc->sc_in_xfer1, sc->sc_in_pipe, sc, sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ulpt_input); usbd_setup_xfer(sc->sc_in_xfer2, sc->sc_in_pipe, sc, sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ulpt_input); usbd_transfer(sc->sc_in_xfer1); /* ignore failed start */ } sc->sc_state = ULPT_OPEN; done: if (--sc->sc_refcnt < 0) usb_detach_wakeup(&sc->sc_dev); DPRINTF(("ulptopen: done, error=%d\n", error)); return (error); }