static void do_msc_shorter_cmd(uint8_t lun) { uint8_t buffer[sizeof(umass_bbb_cbw_t)]; int actlen; int error; int x; memset(buffer, 0, sizeof(buffer)); for (x = 0; x != (sizeof(buffer) - 1); x++) { error = libusb20_tr_bulk_intr_sync(xfer_out, buffer, x, &actlen, 250); printf("Sent short %d of %d bytes wrapper block, " "status = %d\n", x, (int)(sizeof(buffer) - 1), error); do_msc_reset(lun); if (error != 0) { printf("ERROR: Too short command wrapper " "was not accepted\n"); stats.xfer_error++; break; } } }
static void doit(struct libusb20_device *dev) { int rv; if (do_request) printf("doit(): bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\n", setup.bmRequestType, setup.bRequest, setup.wValue, setup.wIndex, setup.wLength); /* * Open the device, allocating memory for two possible (bulk or * interrupt) transfers. * * If only control transfers are intended (via * libusb20_dev_request_sync()), transfer_max can be given as 0. */ if ((rv = libusb20_dev_open(dev, 1)) != 0) { fprintf(stderr, "libusb20_dev_open: %s\n", libusb20_strerror(rv)); return; } /* * If the device has more than one configuration, select the desired * one here. */ if ((rv = libusb20_dev_set_config_index(dev, 0)) != 0) { fprintf(stderr, "libusb20_dev_set_config_index: %s\n", libusb20_strerror(rv)); return; } uint8_t *data = 0; uint16_t actlen; if ((setup.bmRequestType & 0x80) != 0) { /* this is an IN request, allocate a buffer */ data = malloc(setup.wLength); if (data == 0) { fprintf(stderr, "Out of memory allocating %u bytes of reply buffer\n", setup.wLength); return; } } else data = out_buf; if (do_request) { if ((rv = libusb20_dev_request_sync(dev, &setup, data, &actlen, TIMEOUT, 0 /* flags */)) != 0) { fprintf(stderr, "libusb20_dev_request_sync: %s\n", libusb20_strerror(rv)); } printf("sent %d bytes\n", actlen); if ((setup.bmRequestType & 0x80) != 0) { print_formatted(data, (uint32_t)setup.wLength); free(data); } } if (intr_ep != 0) { /* * One transfer has been requested in libusb20_dev_open() above; * obtain the corresponding transfer struct pointer. */ struct libusb20_transfer *xfr_intr = libusb20_tr_get_pointer(dev, 0); if (xfr_intr == NULL) { fprintf(stderr, "libusb20_tr_get_pointer: %s\n", libusb20_strerror(rv)); return; } /* * Open the interrupt transfer. */ if ((rv = libusb20_tr_open(xfr_intr, 0, 1, intr_ep)) != 0) { fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv)); return; } uint8_t in_buf[BUFLEN]; uint32_t rlen; if ((rv = libusb20_tr_bulk_intr_sync(xfr_intr, in_buf, BUFLEN, &rlen, TIMEOUT)) != 0) { fprintf(stderr, "libusb20_tr_bulk_intr_sync: %s\n", libusb20_strerror(rv)); } printf("received %d bytes\n", rlen); if (rlen > 0) print_formatted(in_buf, rlen); libusb20_tr_close(xfr_intr); } libusb20_dev_close(dev); }
static void doit(struct libusb20_device *dev) { int rv; /* * Open the device, allocating memory for two possible (bulk or * interrupt) transfers. * * If only control transfers are intended (via * libusb20_dev_request_sync()), transfer_max can be given as 0. */ if ((rv = libusb20_dev_open(dev, 2)) != 0) { fprintf(stderr, "libusb20_dev_open: %s\n", libusb20_strerror(rv)); return; } /* * If the device has more than one configuration, select the desired * one here. */ if ((rv = libusb20_dev_set_config_index(dev, 0)) != 0) { fprintf(stderr, "libusb20_dev_set_config_index: %s\n", libusb20_strerror(rv)); return; } /* * Two transfers have been requested in libusb20_dev_open() above; * obtain the corresponding transfer struct pointers. */ struct libusb20_transfer *xfr_out = libusb20_tr_get_pointer(dev, 0); struct libusb20_transfer *xfr_in = libusb20_tr_get_pointer(dev, 1); if (xfr_in == NULL || xfr_out == NULL) { fprintf(stderr, "libusb20_tr_get_pointer: %s\n", libusb20_strerror(rv)); return; } /* * Open both transfers, the "out" one for the write endpoint, the * "in" one for the read endpoint (ep | 0x80). */ if ((rv = libusb20_tr_open(xfr_out, 0, 1, out_ep)) != 0) { fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv)); return; } if ((rv = libusb20_tr_open(xfr_in, 0, 1, in_ep)) != 0) { fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv)); return; } uint8_t in_buf[BUFLEN]; uint32_t rlen; if (out_len > 0) { if ((rv = libusb20_tr_bulk_intr_sync(xfr_out, out_buf, out_len, &rlen, TIMEOUT)) != 0) { fprintf(stderr, "libusb20_tr_bulk_intr_sync (OUT): %s\n", libusb20_strerror(rv)); } printf("sent %d bytes\n", rlen); } if ((rv = libusb20_tr_bulk_intr_sync(xfr_in, in_buf, BUFLEN, &rlen, TIMEOUT)) != 0) { fprintf(stderr, "libusb20_tr_bulk_intr_sync: %s\n", libusb20_strerror(rv)); } printf("received %d bytes\n", rlen); if (rlen > 0) print_formatted(in_buf, rlen); libusb20_tr_close(xfr_out); libusb20_tr_close(xfr_in); libusb20_dev_close(dev); }
void usb_set_and_clear_stall_test(uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; struct libusb20_transfer *pxfer; int iter; int error; int errcnt; int ep; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 1); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } printf("Starting set and clear stall test " "for VID=0x%04x PID=0x%04x\n", vid, pid); iter = 0; errcnt = 0; for (ep = 2; ep != 32; ep++) { struct LIBUSB20_CONTROL_SETUP_DECODED setup_set_stall; struct LIBUSB20_CONTROL_SETUP_DECODED setup_get_status; uint8_t epno = ((ep / 2) | ((ep & 1) << 7)); uint8_t buf[1]; LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup_set_stall); setup_set_stall.bmRequestType = 0x02; /* write endpoint */ setup_set_stall.bRequest = 0x03; /* set feature */ setup_set_stall.wValue = 0x00; /* UF_ENDPOINT_HALT */ setup_set_stall.wIndex = epno; setup_set_stall.wLength = 0; LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup_get_status); setup_get_status.bmRequestType = 0x82; /* read endpoint */ setup_get_status.bRequest = 0x00; /* get status */ setup_get_status.wValue = 0x00; setup_get_status.wIndex = epno; setup_get_status.wLength = 1; if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } pxfer = libusb20_tr_get_pointer(pdev, 0); error = libusb20_tr_open(pxfer, 1, 1, epno); if (error != 0) { printf("Endpoint 0x%02x does not exist " "in current setting. (%s, ignored)\n", epno, libusb20_strerror(error)); continue; } printf("Stalling endpoint 0x%02x\n", epno); /* set stall */ error = libusb20_dev_request_sync(pdev, &setup_set_stall, NULL, NULL, 250, 0); if (error != 0) { printf("Endpoint 0x%02x does not allow " "setting of stall. (%s)\n", epno, libusb20_strerror(error)); errcnt++; } /* get EP status */ buf[0] = 0; error = libusb20_dev_request_sync(pdev, &setup_get_status, buf, NULL, 250, 0); if (error != 0) { printf("Endpoint 0x%02x does not allow " "reading status. (%s)\n", epno, libusb20_strerror(error)); errcnt++; } else { if (!(buf[0] & 1)) { printf("Endpoint 0x%02x status is " "not set to stalled\n", epno); errcnt++; } } buf[0] = 0; error = libusb20_tr_bulk_intr_sync(pxfer, buf, 1, NULL, 250); if (error != LIBUSB20_TRANSFER_STALL) { printf("Endpoint 0x%02x does not appear to " "have stalled. Missing stall PID!\n", epno); errcnt++; } printf("Unstalling endpoint 0x%02x\n", epno); libusb20_tr_clear_stall_sync(pxfer); /* get EP status */ buf[0] = 0; error = libusb20_dev_request_sync(pdev, &setup_get_status, buf, NULL, 250, 0); if (error != 0) { printf("Endpoint 0x%02x does not allow " "reading status. (%s)\n", epno, libusb20_strerror(error)); errcnt++; } else { if (buf[0] & 1) { printf("Endpoint 0x%02x status is " "still stalled\n", epno); errcnt++; } } libusb20_tr_close(pxfer); iter++; } libusb20_dev_free(pdev); printf("\n" "Test summary\n" "============\n" "Endpoints tested: %d\n" "Errors: %d\n", iter, errcnt); }
static uint8_t do_msc_cmd(uint8_t *pcmd, uint8_t cmdlen, void *pdata, uint32_t datalen, uint8_t isread, uint8_t isshort, uint8_t lun, uint8_t flags) { umass_bbb_cbw_t cbw; umass_bbb_csw_t csw; struct libusb20_transfer *xfer_io; uint32_t actlen; uint32_t timeout; int error; memset(&cbw, 0, sizeof(cbw)); USETDW(cbw.dCBWSignature, xfer_wrapper_sig); USETDW(cbw.dCBWTag, xfer_current_id); xfer_current_id++; USETDW(cbw.dCBWDataTransferLength, datalen); cbw.bCBWFlags = (isread ? CBWFLAGS_IN : CBWFLAGS_OUT); cbw.bCBWLUN = lun; cbw.bCDBLength = cmdlen; bcopy(pcmd, cbw.CBWCDB, cmdlen); actlen = 0; timeout = ((datalen + 299999) / 300000) * 1000; timeout += 5000; if ((error = libusb20_tr_bulk_intr_sync(xfer_out, &cbw, sizeof(cbw), &actlen, TIMEOUT_FILTER(1000)))) { printf("ERROR: CBW reception: %d\n", error); do_msc_reset(lun); return (1); } if (actlen != sizeof(cbw)) { printf("ERROR: CBW length: %d != %d\n", actlen, (int)sizeof(cbw)); do_msc_reset(lun); return (1); } if (flags & 1) datalen /= 2; if (datalen != 0) { xfer_io = isread ? xfer_in : xfer_out; if ((error = libusb20_tr_bulk_intr_sync(xfer_io, pdata, datalen, &actlen, TIMEOUT_FILTER(timeout)))) { printf("ERROR: Data transfer: %d\n", error); do_msc_reset(lun); return (1); } if ((actlen != datalen) && (!isshort)) { printf("ERROR: Short data: %d of %d bytes\n", actlen, datalen); do_msc_reset(lun); return (1); } } actlen = 0; timeout = 8; do { error = libusb20_tr_bulk_intr_sync(xfer_in, &csw, sizeof(csw), &actlen, TIMEOUT_FILTER(1000)); if (error) { if (error == LIBUSB20_TRANSFER_TIMED_OUT) { printf("TIMEOUT: Trying to get CSW again. " "%d tries left.\n", timeout); } else { break; } } else { break; } } while (--timeout); if (error) { libusb20_tr_clear_stall_sync(xfer_in); error = libusb20_tr_bulk_intr_sync(xfer_in, &csw, sizeof(csw), &actlen, TIMEOUT_FILTER(1000)); if (error) { libusb20_tr_clear_stall_sync(xfer_in); printf("ERROR: Could not read CSW: Stalled or " "timeout (%d).\n", error); do_msc_reset(lun); return (1); } } if (UGETDW(csw.dCSWSignature) != CSWSIGNATURE) { printf("ERROR: Wrong CSW signature\n"); do_msc_reset(lun); return (1); } if (actlen != sizeof(csw)) { printf("ERROR: Wrong CSW length: %d != %d\n", actlen, (int)sizeof(csw)); do_msc_reset(lun); return (1); } if (csw.bCSWStatus != 0) { printf("ERROR: CSW status: %d\n", (int)csw.bCSWStatus); return (1); } else { stats.xfer_success++; return (0); } }