int test_device(uint16_t vid, uint16_t pid) { libusb_device_handle *handle; libusb_device *dev; uint8_t bus, port_path[8]; struct libusb_config_descriptor *conf_desc; const struct libusb_endpoint_descriptor *endpoint; int i, j, k, r; int iface, nb_ifaces; #if defined(__linux) // Attaching/detaching the kernel driver is only relevant for Linux int iface_detached = -1; #endif struct libusb_device_descriptor dev_desc; char string[128]; uint8_t string_index[3]; // indexes of the string descriptors uint8_t endpoint_in = 0, endpoint_out = 0; // default IN and OUT endpoints printf("Opening device...\n"); handle = libusb_open_device_with_vid_pid(NULL, vid, pid); if (handle == NULL) { perr(" Failed.\n"); return -1; } dev = libusb_get_device(handle); bus = libusb_get_bus_number(dev); r = libusb_get_port_path(NULL, dev, port_path, sizeof(port_path)); if (r > 0) { printf("bus: %d, port path from HCD: %d", bus, port_path[0]); for (i=1; i<r; i++) { printf("->%d", port_path[i]); } printf("\n"); } printf("\nReading device descriptor:\n"); CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc)); printf(" length: %d\n", dev_desc.bLength); printf(" device class: %d\n", dev_desc.bDeviceClass); printf(" S/N: %d\n", dev_desc.iSerialNumber); printf(" VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct); printf(" bcdDevice: %04X\n", dev_desc.bcdDevice); printf(" iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber); printf(" nb confs: %d\n", dev_desc.bNumConfigurations); // Copy the string descriptors for easier parsing string_index[0] = dev_desc.iManufacturer; string_index[1] = dev_desc.iProduct; string_index[2] = dev_desc.iSerialNumber; printf("\nReading configuration descriptors:\n"); CALL_CHECK(libusb_get_config_descriptor(dev, 0, &conf_desc)); nb_ifaces = conf_desc->bNumInterfaces; printf(" nb interfaces: %d\n", nb_ifaces); for (i=0; i<conf_desc->bNumInterfaces; i++) { for (j=0; j<conf_desc->usb_interface[i].num_altsetting; j++) { printf("interface[%d].altsetting[%d]: num endpoints = %d\n", i, j, conf_desc->usb_interface[i].altsetting[j].bNumEndpoints); printf(" Class.SubClass.Protocol: %02X.%02X.%02X\n", conf_desc->usb_interface[i].altsetting[j].bInterfaceClass, conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass, conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol); if ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE) && ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x01) || (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) ) && (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) { // Mass storage devices that can use basic SCSI commands test_mode = USE_SCSI; } for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) { endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k]; printf(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress); // Use the first bulk IN/OUT endpoints found as default for testing if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) { if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) { if (!endpoint_in) endpoint_in = endpoint->bEndpointAddress; } else { if (!endpoint_out) endpoint_out = endpoint->bEndpointAddress; } } printf(" max packet size: %04X\n", endpoint->wMaxPacketSize); printf(" polling interval: %02X\n", endpoint->bInterval); } } } libusb_free_config_descriptor(conf_desc); for (iface = 0; iface < nb_ifaces; iface++) { printf("\nClaiming interface %d...\n", iface); r = libusb_claim_interface(handle, iface); #if defined(__linux) if ((r != LIBUSB_SUCCESS) && (iface == 0)) { // Maybe we need to detach the driver perr(" Failed. Trying to detach driver...\n"); libusb_detach_kernel_driver(handle, iface); iface_detached = iface; printf(" Claiming interface again...\n"); r = libusb_claim_interface(handle, iface); } #endif if (r != LIBUSB_SUCCESS) { perr(" Failed.\n"); } } printf("\nReading string descriptors:\n"); for (i=0; i<3; i++) { if (string_index[i] == 0) { continue; } if (libusb_get_string_descriptor_ascii(handle, string_index[i], string, 128) >= 0) { printf(" String (0x%02X): \"%s\"\n", string_index[i], string); } } switch(test_mode) { case USE_PS3: CALL_CHECK(display_ps3_status(handle)); break; case USE_XBOX: CALL_CHECK(display_xbox_status(handle)); CALL_CHECK(set_xbox_actuators(handle, 128, 222)); msleep(2000); CALL_CHECK(set_xbox_actuators(handle, 0, 0)); break; case USE_SCSI: CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out)); default: break; } printf("\n"); for (iface = 0; iface<nb_ifaces; iface++) { printf("Releasing interface %d...\n", iface); libusb_release_interface(handle, iface); } #if defined(__linux) if (iface_detached >= 0) { printf("Re-attaching kernel driver...\n"); libusb_attach_kernel_driver(handle, iface_detached); } #endif printf("Closing device...\n"); libusb_close(handle); return 0; }
static int test_device(uint16_t vid, uint16_t pid) { libusb_device_handle *handle; libusb_device *dev; uint8_t bus, port_path[8]; struct libusb_bos_descriptor *bos_desc; struct libusb_config_descriptor *conf_desc; const struct libusb_endpoint_descriptor *endpoint; int i, j, k, r; int iface, nb_ifaces, first_iface = -1; struct libusb_device_descriptor dev_desc; const char* speed_name[5] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)", "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)"}; char string[128]; uint8_t string_index[3]; // indexes of the string descriptors uint8_t endpoint_in = 0, endpoint_out = 0; // default IN and OUT endpoints printf("Opening device %04X:%04X...\n", vid, pid); handle = libusb_open_device_with_vid_pid(NULL, vid, pid); if (handle == NULL) { perr(" Failed.\n"); return -1; } dev = libusb_get_device(handle); bus = libusb_get_bus_number(dev); if (extra_info) { r = libusb_get_port_numbers(dev, port_path, sizeof(port_path)); if (r > 0) { printf("\nDevice properties:\n"); printf(" bus number: %d\n", bus); printf(" port path: %d", port_path[0]); for (i=1; i<r; i++) { printf("->%d", port_path[i]); } printf(" (from root hub)\n"); } r = libusb_get_device_speed(dev); if ((r<0) || (r>4)) r=0; printf(" speed: %s\n", speed_name[r]); } printf("\nReading device descriptor:\n"); CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc)); printf(" length: %d\n", dev_desc.bLength); printf(" device class: %d\n", dev_desc.bDeviceClass); printf(" S/N: %d\n", dev_desc.iSerialNumber); printf(" VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct); printf(" bcdDevice: %04X\n", dev_desc.bcdDevice); printf(" iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber); printf(" nb confs: %d\n", dev_desc.bNumConfigurations); // Copy the string descriptors for easier parsing string_index[0] = dev_desc.iManufacturer; string_index[1] = dev_desc.iProduct; string_index[2] = dev_desc.iSerialNumber; printf("\nReading BOS descriptor: "); if (libusb_get_bos_descriptor(handle, &bos_desc) == LIBUSB_SUCCESS) { printf("%d caps\n", bos_desc->bNumDeviceCaps); for (i = 0; i < bos_desc->bNumDeviceCaps; i++) print_device_cap(bos_desc->dev_capability[i]); libusb_free_bos_descriptor(bos_desc); } else { printf("no descriptor\n"); } printf("\nReading first configuration descriptor:\n"); CALL_CHECK(libusb_get_config_descriptor(dev, 0, &conf_desc)); nb_ifaces = conf_desc->bNumInterfaces; printf(" nb interfaces: %d\n", nb_ifaces); if (nb_ifaces > 0) first_iface = conf_desc->usb_interface[0].altsetting[0].bInterfaceNumber; for (i=0; i<nb_ifaces; i++) { printf(" interface[%d]: id = %d\n", i, conf_desc->usb_interface[i].altsetting[0].bInterfaceNumber); for (j=0; j<conf_desc->usb_interface[i].num_altsetting; j++) { printf("interface[%d].altsetting[%d]: num endpoints = %d\n", i, j, conf_desc->usb_interface[i].altsetting[j].bNumEndpoints); printf(" Class.SubClass.Protocol: %02X.%02X.%02X\n", conf_desc->usb_interface[i].altsetting[j].bInterfaceClass, conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass, conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol); if ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE) && ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x01) || (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) ) && (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) { // Mass storage devices that can use basic SCSI commands test_mode = USE_SCSI; } for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) { struct libusb_ss_endpoint_companion_descriptor *ep_comp = NULL; endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k]; printf(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress); // Use the first interrupt or bulk IN/OUT endpoints as default for testing if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) & (LIBUSB_TRANSFER_TYPE_BULK | LIBUSB_TRANSFER_TYPE_INTERRUPT)) { if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) { if (!endpoint_in) endpoint_in = endpoint->bEndpointAddress; } else { if (!endpoint_out) endpoint_out = endpoint->bEndpointAddress; } } printf(" max packet size: %04X\n", endpoint->wMaxPacketSize); printf(" polling interval: %02X\n", endpoint->bInterval); libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp); if (ep_comp) { printf(" max burst: %02X (USB 3.0)\n", ep_comp->bMaxBurst); printf(" bytes per interval: %04X (USB 3.0)\n", ep_comp->wBytesPerInterval); libusb_free_ss_endpoint_companion_descriptor(ep_comp); } } } } libusb_free_config_descriptor(conf_desc); libusb_set_auto_detach_kernel_driver(handle, 1); for (iface = 0; iface < nb_ifaces; iface++) { printf("\nClaiming interface %d...\n", iface); r = libusb_claim_interface(handle, iface); if (r != LIBUSB_SUCCESS) { perr(" Failed.\n"); } } printf("\nReading string descriptors:\n"); for (i=0; i<3; i++) { if (string_index[i] == 0) { continue; } if (libusb_get_string_descriptor_ascii(handle, string_index[i], (unsigned char*)string, 128) >= 0) { printf(" String (0x%02X): \"%s\"\n", string_index[i], string); } } // Read the OS String Descriptor if (libusb_get_string_descriptor_ascii(handle, 0xEE, (unsigned char*)string, 128) >= 0) { printf(" String (0x%02X): \"%s\"\n", 0xEE, string); // If this is a Microsoft OS String Descriptor, // attempt to read the WinUSB extended Feature Descriptors if (strncmp(string, "MSFT100", 7) == 0) read_ms_winsub_feature_descriptors(handle, string[7], first_iface); } switch(test_mode) { case USE_PS3: CALL_CHECK(display_ps3_status(handle)); break; case USE_XBOX: CALL_CHECK(display_xbox_status(handle)); CALL_CHECK(set_xbox_actuators(handle, 128, 222)); msleep(2000); CALL_CHECK(set_xbox_actuators(handle, 0, 0)); break; case USE_HID: test_hid(handle, endpoint_in); break; case USE_SCSI: CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out)); case USE_GENERIC: break; } printf("\n"); for (iface = 0; iface<nb_ifaces; iface++) { printf("Releasing interface %d...\n", iface); libusb_release_interface(handle, iface); } printf("Closing device...\n"); libusb_close(handle); return 0; }
void ps4loadROM(void) { uint8_t endpoint_in = 0, endpoint_out = 0; int usb_storage_found = 0; unsigned short usb_stor_vid; unsigned short usb_stor_pid; // Read all USBs libusb_device **list; libusb_device_descriptor desc; struct libusb_config_descriptor *config; const struct libusb_interface *inter; const struct libusb_interface_descriptor *interdesc; const struct libusb_endpoint_descriptor *epdesc; int ret = sceUsbdInit(); debug("sceUsbdInit %d\n", ret); int count = sceUsbdGetDeviceList(&list); debug("Device list count %d\n", count); int i; for(i = 0; i < count; i++) { debug("Device %i\n", i); ret = sceUsbdGetDeviceDescriptor(list[i], &desc); debug(" Get device descriptor: %d\n", ret); debug(" Device Class: 0x%02X\n", desc.bDeviceClass); debug(" Vendor ID: 0x%04X\n", desc.idVendor); debug(" Product ID: 0x%04X\n", desc.idProduct); debug(" Number of possible configurations: %i\n", desc.bNumConfigurations); ret = sceUsbdGetConfigDescriptor(list[i], 0, &config); debug("\n Get config descriptor: %d\n", ret); debug(" Number of interfaces: %i\n\n", config->bNumInterfaces); int j; for (j = 0; j < config->bNumInterfaces; j++) { debug(" Interface %i\n", j); inter = &config->interface[j]; debug(" Number of alternate settings: %i\n", inter->num_altsetting); int k; for (k = 0; k < inter->num_altsetting; k++) { debug(" Interface %i\n", j); interdesc = &inter->altsetting[j]; debug(" Interface Number: %i\n", interdesc->bInterfaceNumber); debug(" Number of endpoints: %i\n", interdesc->bNumEndpoints); if ( (interdesc->bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE) && ( (interdesc->bInterfaceSubClass == 0x01) || (interdesc->bInterfaceSubClass == 0x06) ) && (interdesc->bInterfaceProtocol == 0x50) ) { usb_storage_found = 1; usb_stor_vid = desc.idVendor; usb_stor_pid = desc.idProduct; } int l; for(l = 0; l < interdesc->bNumEndpoints; l++) { debug(" Endpoint %i\n", l); epdesc = &interdesc->endpoint[l]; debug(" Descriptor Type: 0x%02X\n", epdesc->bDescriptorType); debug(" EP Address: 0x%02X\n", epdesc->bEndpointAddress); debug(" EP Attributes: 0x%02X\n", epdesc->bmAttributes); if ((epdesc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) & (LIBUSB_TRANSFER_TYPE_BULK | LIBUSB_TRANSFER_TYPE_INTERRUPT)) { if (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_IN) { if (!endpoint_in) endpoint_in = epdesc->bEndpointAddress; } else { if (!endpoint_out) endpoint_out = epdesc->bEndpointAddress; } } } } } sceUsbdFreeConfigDescriptor(config); } sceUsbdFreeDeviceList(list, 1); if (usb_storage_found) { libusb_device_handle *handle; handle = sceUsbdOpenDeviceWithVidPid(usb_stor_vid, usb_stor_pid); test_mass_storage(handle, endpoint_in, endpoint_out); } else { debug("USB storage not found.\n"); } sceUsbdExit(); }