static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { uint8_t cdb[16]; // SCSI Command Descriptor Block uint8_t sense[18]; uint32_t expected_tag; int size; int rc; // Request Sense printf("Request Sense:\n"); memset(sense, 0, sizeof(sense)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x03; // Request Sense cdb[4] = REQUEST_SENSE_LENGTH; send_mass_storage_command(handle, endpoint_out, 0, cdb, LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH, &expected_tag); rc = libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&sense, REQUEST_SENSE_LENGTH, &size, 1000); if (rc < 0) { printf("libusb_bulk_transfer failed: %s\n", libusb_error_name(rc)); return; } printf(" received %d bytes\n", size); if ((sense[0] != 0x70) && (sense[0] != 0x71)) { perr(" ERROR No sense data\n"); } else { perr(" ERROR Sense: %02X %02X %02X\n", sense[2]&0x0F, sense[12], sense[13]); } // Strictly speaking, the get_mass_storage_status() call should come // before these perr() lines. If the status is nonzero then we must // assume there's no data in the buffer. For xusb it doesn't matter. get_mass_storage_status(handle, endpoint_in, expected_tag); }
// Mass Storage device to test bulk transfers (non destructive test) static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { int r, size; uint8_t lun; uint32_t expected_tag; uint32_t i, max_lba, block_size; double device_size; uint8_t cdb[16]; // SCSI Command Descriptor Block uint8_t buffer[64]; char vid[9], pid[9], rev[5]; unsigned char *data; FILE *fd; printf("Reading Max LUN:\n"); r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, BOMS_GET_MAX_LUN, 0, 0, &lun, 1, 1000); // Some devices send a STALL instead of the actual value. // In such cases we should set lun to 0. if (r == 0) { lun = 0; } else if (r < 0) { perr(" Failed: %s", libusb_strerror((enum libusb_error)r)); } printf(" Max LUN = %d\n", lun); // Send Inquiry printf("Sending Inquiry:\n"); memset(buffer, 0, sizeof(buffer)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x12; // Inquiry cdb[4] = INQUIRY_LENGTH; send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, &expected_tag); CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, INQUIRY_LENGTH, &size, 1000)); printf(" received %d bytes\n", size); // The following strings are not zero terminated for (i=0; i<8; i++) { vid[i] = buffer[8+i]; pid[i] = buffer[16+i]; rev[i/2] = buffer[32+i/2]; // instead of another loop } vid[8] = 0; pid[8] = 0; rev[4] = 0; printf(" VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid, pid, rev); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } // Read capacity printf("Reading Capacity:\n"); memset(buffer, 0, sizeof(buffer)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x25; // Read Capacity send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, &expected_tag); CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, READ_CAPACITY_LENGTH, &size, 1000)); printf(" received %d bytes\n", size); max_lba = be_to_int32(&buffer[0]); block_size = be_to_int32(&buffer[4]); device_size = ((double)(max_lba+1))*block_size/(1024*1024*1024); printf(" Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba, block_size, device_size); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } // coverity[tainted_data] data = (unsigned char*) calloc(1, block_size); if (data == NULL) { perr(" unable to allocate data buffer\n"); return -1; } // Send Read printf("Attempting to read %d bytes:\n", block_size); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x28; // Read(10) cdb[8] = 0x01; // 1 block send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, block_size, &expected_tag); libusb_bulk_transfer(handle, endpoint_in, data, block_size, &size, 5000); printf(" READ: received %d bytes\n", size); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } else { display_buffer_hex(data, size); if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) { if (fwrite(data, 1, (size_t)size, fd) != (unsigned int)size) { perr(" unable to write binary data\n"); } fclose(fd); } } free(data); return 0; }
// Mass Storage device to test bulk transfers (non destructive test) static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { int r, size; uint8_t lun; uint32_t expected_tag; uint32_t i, max_lba, block_size; double device_size; uint8_t cdb[16]; // SCSI Command Descriptor Block uint8_t buffer[64]; char vid[9], pid[9], rev[5]; debug("Reading Max LUN:\n"); r = sceUsbdControlTransfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, BOMS_GET_MAX_LUN, 0, 0, &lun, 1, 1000); // Some devices send a STALL instead of the actual value. // In such cases we should set lun to 0. if (r == 0) { lun = 0; } else if (r < 0) { debug(" Failed\n"); } debug(" Max LUN = %d\n", lun); // Send Inquiry debug("Sending Inquiry:\n"); memset(buffer, 0, sizeof(buffer)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x12; // Inquiry cdb[4] = INQUIRY_LENGTH; send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, &expected_tag); CALL_CHECK(sceUsbdBulkTransfer(handle, endpoint_in, (unsigned char*)&buffer, INQUIRY_LENGTH, &size, 1000)); debug(" received %d bytes\n", size); // The following strings are not zero terminated for (i=0; i<8; i++) { vid[i] = buffer[8+i]; pid[i] = buffer[16+i]; rev[i/2] = buffer[32+i/2]; // instead of another loop } vid[8] = 0; pid[8] = 0; rev[4] = 0; debug(" VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid, pid, rev); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } // Read capacity debug("Reading Capacity:\n"); memset(buffer, 0, sizeof(buffer)); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x25; // Read Capacity send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, &expected_tag); CALL_CHECK(sceUsbdBulkTransfer(handle, endpoint_in, (unsigned char*)&buffer, READ_CAPACITY_LENGTH, &size, 1000)); debug(" received %d bytes\n", size); max_lba = be_to_int32(&buffer[0]); block_size = be_to_int32(&buffer[4]); device_size = ((double)(max_lba+1))*block_size/(1024*1024*1024); debug(" Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba, block_size, device_size); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); } // coverity[tainted_data] //data = (unsigned char*) calloc(1, block_size); //if (data == NULL) { // debug(" unable to allocate data buffer\n"); // return -1; //} // Send Read debug("Attempting to read %d bytes:\n", block_size); memset(cdb, 0, sizeof(cdb)); cdb[0] = 0x28; // Read(10) //cdb[8] = 0x01; // 1 block cdb[8] = sizeof(cart) / block_size; // blocks //send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, block_size, &expected_tag); send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, sizeof(cart), &expected_tag); //sceUsbdBulkTransfer(handle, endpoint_in, cart, block_size, &size, 5000); sceUsbdBulkTransfer(handle, endpoint_in, cart, sizeof(cart), &size, 5000); debug(" READ: received %d bytes\n", size); if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) { get_sense(handle, endpoint_in, endpoint_out); }// else { //display_buffer_hex(data, size); //} //free(data); return 0; }