Static int uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag) { u_int32_t n; int error = 0; usbd_status err; DPRINTFN(5, ("%s: uscanner_do_write\n", device_xname(sc->sc_dev))); if (sc->sc_dying) return (EIO); while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) { error = uiomove(sc->sc_bulkout_buffer, n, uio); if (error) break; DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n)); err = usbd_bulk_transfer( sc->sc_bulkout_xfer, sc->sc_bulkout_pipe, 0, USBD_NO_TIMEOUT, sc->sc_bulkout_buffer, &n, "uscnwb"); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else error = EIO; break; } } return (error); }
int stuirda_write(void *h, struct uio *uio, int flag) { struct uirda_softc *sc = h; usbd_status err; u_int32_t n; int error = 0; DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) return (EIO); #ifdef DIAGNOSTIC if (sc->sc_wr_buf == NULL) return (EINVAL); #endif n = uio->uio_resid; if (n > sc->sc_params.maxsize) return (EINVAL); sc->sc_refcnt++; mutex_enter(&sc->sc_wr_buf_lk); sc->sc_wr_buf[0] = UIRDA_EB_NO_CHANGE | UIRDA_NO_SPEED; sc->sc_wr_buf[1] = 0; sc->sc_wr_buf[2] = 7; /* XXX turnaround - maximum for now */ if ((n > 0 && (n % 128) == 0 && (n % 512) != 0)) { sc->sc_wr_buf[1] = 1; } error = uiomove(sc->sc_wr_buf + STUIRDA_HEADER_SIZE, n, uio); if (!error) { DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); n += STUIRDA_HEADER_SIZE + sc->sc_wr_buf[1]; err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, USBD_FORCE_SHORT_XFER|USBD_NO_COPY, UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n, "uirdawr"); DPRINTFN(2, ("uirdawrite: err=%d\n", err)); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; } } mutex_exit(&sc->sc_wr_buf_lk); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); return (error); }
int uriowrite(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; usbd_xfer_handle xfer; usbd_status err; void *bufp; u_int32_t n; int error = 0; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); DPRINTFN(5, ("uriowrite: unit=%d, len=%ld\n", URIOUNIT(dev), (long)uio->uio_resid)); if (sc->sc_dying) return (EIO); xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) return (ENOMEM); bufp = usbd_alloc_buffer(xfer, URIO_BSIZE); if (bufp == NULL) { usbd_free_xfer(xfer); return (ENOMEM); } sc->sc_refcnt++; while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) { error = uiomove(bufp, n, uio); if (error) break; DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n)); err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY, URIO_RW_TIMEOUT, bufp, &n, "uriowr"); DPRINTFN(2, ("uriowrite: err=%d\n", err)); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } } usbd_free_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev), error)); return (error); }
int urioread(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; usbd_xfer_handle xfer; usbd_status err; void *bufp; u_int32_t n, tn; int error = 0; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); DPRINTFN(5, ("urioread: %d\n", URIOUNIT(dev))); if (sc->sc_dying) return (EIO); xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) return (ENOMEM); bufp = usbd_alloc_buffer(xfer, URIO_BSIZE); if (bufp == NULL) { usbd_free_xfer(xfer); return (ENOMEM); } sc->sc_refcnt++; while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) { DPRINTFN(1, ("urioread: start transfer %d bytes\n", n)); tn = n; err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, USBD_NO_COPY, URIO_RW_TIMEOUT, bufp, &tn, "uriors"); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } DPRINTFN(1, ("urioread: got %d bytes\n", tn)); error = uiomove(bufp, tn, uio); if (error || tn < n) break; } usbd_free_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (error); }
int uirda_write(void *h, struct uio *uio, int flag) { struct uirda_softc *sc = h; usbd_status err; u_int32_t n; int error = 0; DPRINTFN(1,("%s: sc=%p\n", __FUNCTION__, sc)); if (sc->sc_dying) return (EIO); #ifdef DIAGNOSTIC if (sc->sc_wr_buf == NULL) return (EINVAL); #endif n = uio->uio_resid; if (n > sc->sc_params.maxsize) return (EINVAL); sc->sc_refcnt++; lockmgr(&sc->sc_wr_buf_lk, LK_EXCLUSIVE, NULL); sc->sc_wr_buf[0] = UIRDA_EB_NO_CHANGE | UIRDA_NO_SPEED; error = uiomove(sc->sc_wr_buf + UIRDA_OUTPUT_HEADER_SIZE, n, uio); if (!error) { DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); n++; err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n, "uirdawr"); DPRINTFN(2, ("uirdawrite: err=%d\n", err)); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; } } lockmgr(&sc->sc_wr_buf_lk, LK_RELEASE, NULL); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); DPRINTFN(1,("%s: sc=%p done\n", __FUNCTION__, sc)); return (error); }
Static int uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag) { u_int32_t n, tn; usbd_status err; int error = 0; DPRINTFN(5, ("%s: uscannerread\n", device_xname(sc->sc_dev))); if (sc->sc_dying) return (EIO); while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) { DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n)); tn = n; err = usbd_bulk_transfer( sc->sc_bulkin_xfer, sc->sc_bulkin_pipe, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, sc->sc_bulkin_buffer, &tn, "uscnrb"); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } DPRINTFN(1, ("uscannerread: got %d bytes\n", tn)); error = uiomove(sc->sc_bulkin_buffer, tn, uio); if (error || tn < n) break; } return (error); }
int stuirda_fwload(struct uirda_softc *sc) { int rc; firmware_handle_t fh; off_t fwsize; usb_device_descriptor_t usbddsc; usbd_xfer_handle fwxfer; usbd_pipe_handle fwpipe; usbd_status status; usb_device_request_t req; char *buffer; char *p; char fwname[12]; int n; u_int8_t *usbbuf; /* size_t bsize; */ printf("%s: needing to download firmware\n", device_xname(sc->sc_dev)); status = usbd_get_device_desc(sc->sc_udev, &usbddsc); if (status) { printf("%s: can't get device descriptor, status %d\n", device_xname(sc->sc_dev), status); return status; } rc = usbd_get_class_desc(sc->sc_udev, UDESC_IRDA, 0, USB_IRDA_DESCRIPTOR_SIZE, &sc->sc_irdadesc); printf("error %d reading class desc\n", rc); snprintf(fwname, sizeof(fwname), "4210%02x%02x.sb", usbddsc.bcdDevice[1], usbddsc.bcdDevice[0]); printf("%s: Attempting to load firmware %s\n", device_xname(sc->sc_dev), fwname); rc = firmware_open("stuirda", fwname, &fh); if (rc) { printf("%s: Cannot load firmware\n", device_xname(sc->sc_dev)); return rc; } fwsize = firmware_get_size(fh); printf("%s: Firmware size %lld\n", device_xname(sc->sc_dev), (long long)fwsize); buffer = firmware_malloc(fwsize); if (buffer == NULL) { printf("%s: Cannot load firmware: out of memory\n", device_xname(sc->sc_dev)); goto giveup2; } rc = firmware_read(fh, 0, buffer, (size_t)fwsize); if (rc) { printf("%s: Cannot read firmware\n", device_xname(sc->sc_dev)); goto giveup3; } for (p = buffer + sizeof("Product Version:"); p < buffer + fwsize - 5; p++) { if (0x1A == *p) break; } if (0x1a != *p || memcmp(p+1, "STMP", 4) != 0) { /* firmware bad */ printf("%s: Bad firmware\n", device_xname(sc->sc_dev)); goto giveup3; } p += 5; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = 2 /* XXX magic */; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, 0); rc = usbd_do_request(sc->sc_udev, &req, 0); if (rc) { printf("%s: Cannot switch to f/w d/l mode, error %d\n", device_xname(sc->sc_dev), rc); goto giveup3; } delay(100000); rc = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &fwpipe); if (rc) { printf("%s: Cannot open pipe, rc=%d\n", device_xname(sc->sc_dev), rc); goto giveup3; } fwxfer = usbd_alloc_xfer(sc->sc_udev); if (fwxfer == NULL) { printf("%s: Cannot alloc xfer\n", device_xname(sc->sc_dev)); goto giveup4; } usbbuf = usbd_alloc_buffer(fwxfer, 1024); if (usbbuf == NULL) { printf("%s: Cannot alloc usb buf\n", device_xname(sc->sc_dev)); goto giveup5; } n = (buffer + fwsize - p); while (n > 0) { if (n > 1023) n = 1023; memcpy(usbbuf, p, n); rc = usbd_bulk_transfer(fwxfer, fwpipe, USBD_SYNCHRONOUS|USBD_FORCE_SHORT_XFER, 5000, usbbuf, &n, "uirda-fw-wr"); printf("%s: write: rc=%d, %d left\n", device_xname(sc->sc_dev), rc, n); if (rc) { printf("%s: write: rc=%d, %d bytes written\n", device_xname(sc->sc_dev), rc, n); goto giveup4; } printf("%s: written %d\n", device_xname(sc->sc_dev), n); p += n; n = (buffer + fwsize - p); } delay(100000); /* TODO: more code here */ rc = 0; usbd_free_buffer(fwxfer); giveup5: usbd_free_xfer(fwxfer); giveup4: usbd_close_pipe(fwpipe); giveup3: firmware_free(buffer, fwsize); giveup2: firmware_close(fh); return rc; }
int uirda_set_params(void *h, struct irda_params *p) { struct uirda_softc *sc = h; usbd_status err; int i; u_int8_t hdr; u_int32_t n; u_int mask; DPRINTF(("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__, sc, p->speed, p->ebofs, p->maxsize)); if (sc->sc_dying) return (EIO); hdr = 0; if (p->ebofs != sc->sc_params.ebofs) { /* round up ebofs */ mask = 1 /* sc->sc_irdadesc.bmAdditionalBOFs*/; DPRINTF(("u.s.p.: mask=0x%x, sc->ebofs=%d, p->ebofs=%d\n", mask, sc->sc_params.ebofs, p->ebofs)); for (i = 0; i < UIRDA_NEBOFS; i++) { DPRINTF(("u.s.p.: u_e[%d].mask=0x%x, count=%d\n", i, uirda_ebofs[i].mask, uirda_ebofs[i].count)); if ((mask & uirda_ebofs[i].mask) && uirda_ebofs[i].count >= p->ebofs) { hdr = uirda_ebofs[i].header; goto found1; } } for (i = 0; i < UIRDA_NEBOFS; i++) { DPRINTF(("u.s.p.: u_e[%d].mask=0x%x, count=%d\n", i, uirda_ebofs[i].mask, uirda_ebofs[i].count)); if ((mask & uirda_ebofs[i].mask)) { hdr = uirda_ebofs[i].header; goto found1; } } /* no good value found */ return (EINVAL); found1: DPRINTF(("uirda_set_params: ebofs hdr=0x%02x\n", hdr)); ; } if (hdr != 0 || p->speed != sc->sc_params.speed) { /* find speed */ mask = UGETW(sc->sc_irdadesc.wBaudRate); for (i = 0; i < UIRDA_NSPEEDS; i++) { if ((mask & uirda_speeds[i].mask) && uirda_speeds[i].speed == p->speed) { hdr |= uirda_speeds[i].header; goto found2; } } /* no good value found */ return (EINVAL); found2: DPRINTF(("uirda_set_params: speed hdr=0x%02x\n", hdr)); ; } if (p->maxsize != sc->sc_params.maxsize) { if (p->maxsize > IRDA_MAX_FRAME_SIZE) return (EINVAL); sc->sc_params.maxsize = p->maxsize; #if 0 DPRINTF(("%s: new buffers, old size=%d\n", __func__, sc->sc_params.maxsize)); if (p->maxsize > 10000 || p < 0) /* XXX */ return (EINVAL); /* Change the write buffer */ mutex_enter(&sc->sc_wr_buf_lk); if (sc->sc_wr_buf != NULL) usbd_free_buffer(sc->sc_wr_xfer); sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, p->maxsize+1); mutex_exit(&sc->sc_wr_buf_lk); if (sc->sc_wr_buf == NULL) return (ENOMEM); /* Change the read buffer */ mutex_enter(&sc->sc_rd_buf_lk); usbd_abort_pipe(sc->sc_rd_pipe); if (sc->sc_rd_buf != NULL) usbd_free_buffer(sc->sc_rd_xfer); sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, p->maxsize+1); sc->sc_rd_count = 0; if (sc->sc_rd_buf == NULL) { mutex_exit(&sc->sc_rd_buf_lk); return (ENOMEM); } sc->sc_params.maxsize = p->maxsize; err = uirda_start_read(sc); /* XXX check */ mutex_exit(&sc->sc_rd_buf_lk); #endif } if (hdr != 0 && hdr != sc->sc_wr_hdr) { /* * A change has occurred, transmit a 0 length frame with * the new settings. The 0 length frame is not sent to the * device. */ DPRINTF(("%s: sc=%p setting header 0x%02x\n", __func__, sc, hdr)); sc->sc_wr_hdr = hdr; mutex_enter(&sc->sc_wr_buf_lk); sc->sc_wr_buf[0] = hdr; n = UIRDA_OUTPUT_HEADER_SIZE; err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n, "uirdast"); if (err) { aprint_error_dev(sc->sc_dev, "set failed, err=%d\n", err); usbd_clear_endpoint_stall(sc->sc_wr_pipe); } mutex_exit(&sc->sc_wr_buf_lk); } sc->sc_params = *p; return (0); }