usbd_status uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len) { char *buf; usbd_status retstat; if (scd->sc_report_id == 0) return usbd_set_report_async(scd->sc_parent->sc_iface, type, scd->sc_report_id, data, len); buf = malloc(len + 1, M_TEMP, M_NOWAIT); if (buf == NULL) return (USBD_NOMEM); buf[0] = scd->sc_report_id; memcpy(buf+1, data, len); retstat = usbd_set_report_async(scd->sc_parent->sc_iface, type, scd->sc_report_id, buf, len + 1); /* * Since report requests are write-only it is safe to free * the buffer right after submitting the transfer because * it won't be used afterward. */ free(buf, M_TEMP); return retstat; }
static void set_leds(ukbd_state_t *state, int leds) { u_int8_t res = leds; DPRINTF(("ukbd:set_leds: state=%p leds=%d\n", state, leds)); usbd_set_report_async(state->ks_iface, UHID_OUTPUT_REPORT, 0, &res, 1); }
void uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len) { /* XXX */ char buf[100]; if (scd->sc_report_id) { buf[0] = scd->sc_report_id; memcpy(buf+1, data, len); len++; data = buf; } usbd_set_report_async(scd->sc_parent->sc_iface, type, scd->sc_report_id, data, len); }
void uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len) { /* XXX */ char buf[100]; if (scd->sc_report_id) { buf[0] = scd->sc_report_id; if ((uint)len > sizeof(buf) - 1) { #ifdef DIAGNOSTIC printf("%s: report length too large (%d)\n", scd->sc_dev.dv_xname, len); #endif return; } memcpy(buf+1, data, len); len++; data = buf; } usbd_set_report_async(scd->sc_parent->sc_iface, type, scd->sc_report_id, data, len); }
static usbd_status upwr_send_cmd(struct upwr_softc *sc, uint8_t cmd) { #if USE_RAW_DO_REQUEST usb_device_request_t req; usbd_status err; //req.bmRequestType = UT_READ_CLASS_INTERFACE;//UT_WRITE_VENDOR_DEVICE; req.bmRequestType = cmd; req.bRequest = 0xff; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, 64); err = usbd_do_request(sc->sc_udev, &req, &sc->sc_buf); if (err) { printf("%s : could not issue command %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); return (EIO); } return 0; #endif #ifdef USE_SET_REPORT uint8_t req[64]; usbd_status err; int i = 0; int size =0; int s; printf("send_cmd xfer=%p ipipe=%p\n", sc->sc_xfer, sc->sc_ipipe); memset(req, CMD_PADDING, sizeof(req)); req[0] = cmd; for (i = 0; i < 64; i++) { printf("%x ", req[i]); } printf("\n"); /* need something ? */ s = splusb(); size = sizeof(req); /* // won't work? err = usbd_intr_transfer(sc->sc_xfer, sc->sc_ipipe, 0, hz, req, &size, "upwr"); */ // this does send setup transaction, and then DATA1 output report. // In windows, only DATA0 output report goes. // Something nasty? err = usbd_set_report_async(sc->sc_iface, UHID_OUTPUT_REPORT, 0, req, 144); if (err) { printf("send_cmd : %s\n", usbd_errstr(err)); dlog("usbd_set_report_error : EIO %d\n",err); return err; } printf("done transfer"); splx(s);; /* wait ack? : do we need this? */ tsleep(sc, 0, "upwr", hz/10); return 0; #endif }