/** * @brief Check if this platform supports hotplug. * @returns true if hotplug is supported and enabled on this platform, false * otherwise. */ bool AsyncPluginImpl::HotplugSupported() { #ifdef HAVE_LIBUSB_HOTPLUG_API return libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) != 0; #else return false; #endif }
struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, unsigned long session_id) { size_t priv_size = usbi_backend->device_priv_size; struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size); int r; if (!dev) return NULL; r = usbi_mutex_init(&dev->lock, NULL); if (r) { free(dev); return NULL; } dev->ctx = ctx; dev->refcnt = 1; dev->session_data = session_id; dev->speed = LIBUSB_SPEED_UNKNOWN; if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { usbi_connect_device (dev); } return dev; }
void LibUsbDevice::initializeDevice() { int status; status = libusb_init(&context); //initialize the library for the session we just declared if(status != 0) { cstatus = tr("Initialization Error!"); qDebug()<<"Initialization Error! "<<status<<endl; //there was an error isInitialiazed = false; return; } isInitialiazed = true; if(libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)&&0) { hasHotPlugSupport = true; //status = libusb_hotplug_register_callback (context, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE , VENDOR_ID, // PRODUCT_ID, CLASS_ID, hotplugAttachCallback, this, &hotplugHandle[0]); if (LIBUSB_SUCCESS != status) { hasHotPlugSupport = false; } //status = libusb_hotplug_register_callback (context, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE , VENDOR_ID, // PRODUCT_ID, CLASS_ID, hotplugDetachCallback, this, &hotplugHandle[1]); if (LIBUSB_SUCCESS != status) { hasHotPlugSupport = false; } future = QtConcurrent::run (this,&LibUsbDevice::eventThread); } libusb_set_debug(context, LIBUSB_LOG_LEVEL_INFO); //set verbosity level to 3 }
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx, libusb_hotplug_callback_handle handle) { struct libusb_hotplug_callback *hotplug_cb; libusb_hotplug_message message; ssize_t ret; /* check for hotplug support */ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { return; } USBI_GET_CONTEXT(ctx); usbi_mutex_lock(&ctx->hotplug_cbs_lock); list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { if (handle == hotplug_cb->handle) { /* Mark this callback for deregistration */ hotplug_cb->needs_free = 1; } } usbi_mutex_unlock(&ctx->hotplug_cbs_lock); /* wakeup handle_events to do the actual free */ memset(&message, 0, sizeof(message)); ret = usbi_write(ctx->hotplug_pipe[1], &message, sizeof(message)); if (sizeof(message) != ret) { usbi_err(ctx, "error writing hotplug message"); } }
int main(int argc, char *argv[]) { libusb_hotplug_callback_handle hp[2]; int product_id, vendor_id, class_id; int rc; vendor_id = (argc > 1) ? strtol (argv[1], NULL, 0) : 0x045a; product_id = (argc > 2) ? strtol (argv[2], NULL, 0) : 0x5005; class_id = (argc > 3) ? strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY; rc = libusb_init (NULL); if (rc < 0) { printf("failed to initialise libusb: %s\n", libusb_error_name(rc)); return EXIT_FAILURE; } if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { printf ("Hotplug capabilites are not supported on this platform\n"); libusb_exit (NULL); return EXIT_FAILURE; } rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id, product_id, class_id, hotplug_callback, NULL, &hp[0]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 0\n"); libusb_exit (NULL); return EXIT_FAILURE; } rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id, product_id,class_id, hotplug_callback_detach, NULL, &hp[1]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 1\n"); libusb_exit (NULL); return EXIT_FAILURE; } while (done < 2) { rc = libusb_handle_events (NULL); if (rc < 0) printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc)); } if (handle) { libusb_close (handle); } libusb_exit (NULL); return EXIT_SUCCESS; }
UsbNotifier::UsbNotifier(int vendor, int product, QObject *parent) : QThread(parent) , d(new UsbNotifierPrivate) { // register to the QMetaSystem so Qt knows how to pass arount the object qRegisterMetaType<UsbDevice>("UsbDevice"); if (!s_me) { s_me = this; } d->vendor = vendor; d->product = product; libusb_hotplug_callback_handle attachHandle; libusb_hotplug_callback_handle detachHandle; libusb_init(NULL); libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING); if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { // TODO setup hotplug callbacks qDebug("This device correctly supports callback"); } else { // TODO use thread with manual update } int result = libusb_hotplug_register_callback(NULL , LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED , LIBUSB_HOTPLUG_ENUMERATE , d->vendor == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->vendor , d->product == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->product , LIBUSB_HOTPLUG_MATCH_ANY , &deviceInsertCallback , NULL , &attachHandle); // TODO handle callback registration fail qDebug() << "CALLBACK BIND RESULT: " << result; result = libusb_hotplug_register_callback(NULL , LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT , LIBUSB_HOTPLUG_ENUMERATE , d->vendor == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->vendor , d->product == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->product , LIBUSB_HOTPLUG_MATCH_ANY , &deviceDetachCallback , NULL , &detachHandle); // TODO handle callback registration fail qDebug() << "CALLBACK BIND RESULT: " << result; }
static gboolean g_usb_context_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { GUsbContext *context = G_USB_CONTEXT (initable); GUsbContextPrivate *priv; gint rc; libusb_context *ctx; priv = context->priv; rc = libusb_init (&ctx); if (rc < 0) { g_set_error (error, G_USB_CONTEXT_ERROR, G_USB_CONTEXT_ERROR_INTERNAL, "failed to init libusb: %s [%i]", g_usb_strerror (rc), rc); return FALSE; } priv->main_ctx = g_main_context_ref (g_main_context_default ()); priv->ctx = ctx; priv->thread_event_run = 1; priv->thread_event = g_thread_new ("GUsbEventThread", g_usb_context_event_thread_cb, context); /* watch for add/remove */ if (libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { rc = libusb_hotplug_register_callback (priv->ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, g_usb_context_hotplug_cb, context, &context->priv->hotplug_id); if (rc != LIBUSB_SUCCESS) { g_warning ("Error creating a hotplug callback: %s", g_usb_strerror (rc)); } } return TRUE; }
int usb_can_callback(struct usb_sock_t *usb) { IGNORE(usb); if (!g_options.vendor_id || !g_options.product_id) { NOTE("Exit-on-unplug requires vid & pid"); return 0; } int works = !!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG); if (!works) WARN("Libusb cannot tell us when to disconnect"); return works; }
/** * HWStubBackendHelper */ HWStubBackendHelper::HWStubBackendHelper() { libusb_init(NULL); #ifdef LIBUSB_NO_HOTPLUG m_hotplug = false; #else m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG); if(m_hotplug) { m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback( NULL, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), LIBUSB_HOTPLUG_ENUMERATE, HWSTUB_USB_VID, HWSTUB_USB_PID, HWSTUB_CLASS, &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), &m_hotplug_handle); } #endif }
/** * HWStubBackendHelper */ HWStubBackendHelper::HWStubBackendHelper() { #ifdef LIBUSB_NO_HOTPLUG m_hotplug = false; #else m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG); if(m_hotplug) { int evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT; m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback( NULL, (libusb_hotplug_event)evt, LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), &m_hotplug_handle); } #endif /* LIBUSB_NO_HOTPLUG */ }
/** * g_usb_context_enumerate: * @context: a #GUsbContext * * Enumerates all the USB devices and adds them to the context. * * You only need to call this function once, and any subsequent calls * are silently ignored. * * Since: 0.2.2 **/ void g_usb_context_enumerate (GUsbContext *context) { GUsbContextPrivate *priv = context->priv; /* only ever initially scan once, then rely on hotplug / poll */ if (priv->done_enumerate) return; g_usb_context_rescan (context); if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { g_debug ("platform does not do hotplug, using polling"); priv->hotplug_poll_id = g_timeout_add_seconds (1, g_usb_context_rescan_cb, context); } priv->done_enumerate = TRUE; }
int main(int argc, const char *argv[]) { int rc; libusb_context *ctx = NULL; libusb_hotplug_callback_handle handles[3]; _init(ctx); if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { printf("Hotplug not supported by this build of libusb\n"); libusb_exit (NULL); return EXIT_FAILURE; } rc = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, ROMVID, ROMPID, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handles[0]); rc = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, SPLVID, SPLPID, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handles[1]); rc = libusb_hotplug_register_callback(ctx, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, UBOOTVID, UBOOTPID, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handles[2]); if (LIBUSB_SUCCESS != rc) { fprintf(stderr, "Error registering callback 0\n"); libusb_exit(NULL); return EXIT_FAILURE; } while (!finished) { rc = libusb_handle_events(ctx); if (rc) { printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc)); } } _destroy(ctx); return 0; }
bool FCServer::startUSB(libusb_context *usb) { mUSB = usb; // Enumerate all attached devices, and get notified of hotplug events libusb_hotplug_register_callback(mUSB, libusb_hotplug_event(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, cbHotplug, this, 0); // On platforms without real USB hotplug, emulate it with a polling thread if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { mUSBHotplugThread = new tthread::thread(usbHotplugThreadFunc, this); } return true; }
void usbi_connect_device(struct libusb_device *dev) { libusb_hotplug_message message; ssize_t ret; memset(&message, 0, sizeof(message)); message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED; message.device = dev; dev->attached = 1; usbi_mutex_lock(&dev->ctx->usb_devs_lock); list_add(&dev->list, &dev->ctx->usb_devs); usbi_mutex_unlock(&dev->ctx->usb_devs_lock); if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) { ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message)); if (sizeof (message) != ret) { usbi_err(DEVICE_CTX(dev), "error writing hotplug message"); } } }
int main (int argc, char *argv[]) { libusb_hotplug_callback_handle hp[2]; int product_id, vendor_id, class_id; int rc; vendor_id = (argc > 1) ? strtol (argv[1], NULL, 0) : 0x045a; product_id = (argc > 2) ? strtol (argv[2], NULL, 0) : 0x5005; class_id = (argc > 3) ? strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY; libusb_init (NULL); if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { printf ("Hotplug not supported by this build of libusb\n"); libusb_exit (NULL); return EXIT_FAILURE; } rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id, product_id, class_id, hotplug_callback, NULL, &hp[0]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 0\n"); libusb_exit (NULL); return EXIT_FAILURE; } rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id, product_id,class_id, hotplug_callback_detach, NULL, &hp[1]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 1\n"); libusb_exit (NULL); return EXIT_FAILURE; } while (done < 2) { libusb_handle_events (NULL); } libusb_exit (NULL); }
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx, libusb_hotplug_callback_handle handle) { struct libusb_hotplug_callback *hotplug_cb; /* check for hotplug support */ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { return; } USBI_GET_CONTEXT(ctx); usbi_mutex_lock(&ctx->hotplug_cbs_lock); list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { if (handle == hotplug_cb->handle) { /* Mark this callback for deregistration */ hotplug_cb->needs_free = 1; } } usbi_mutex_unlock(&ctx->hotplug_cbs_lock); }
static void *libusb_hid_init(void) { unsigned i, count; int ret; struct libusb_device **devices; libusb_hid_t *hid = (libusb_hid_t*)calloc(1, sizeof(*hid)); if (!hid) goto error; ret = libusb_init(&hid->ctx); if (ret < 0) goto error; if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) goto error; hid->slots = pad_connection_init(MAX_USERS); if (!hid->slots) goto error; count = libusb_get_device_list(hid->ctx, &devices); for (i = 0; i < count; i++) { struct libusb_device_descriptor desc; libusb_get_device_descriptor(devices[i], &desc); if (desc.idVendor > 0 && desc.idProduct > 0) add_adapter(hid, devices[i]); } if (count > 0) libusb_free_device_list(devices, 1); ret = libusb_hotplug_register_callback( hid->ctx, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, libusb_hid_hotplug_callback, hid, &hid->hp); if (ret != LIBUSB_SUCCESS) { RARCH_ERR("Error creating a hotplug callback.\n"); goto error; } hid->poll_thread = sthread_create(poll_thread, hid); if (!hid->poll_thread) { RARCH_ERR("Error creating polling thread"); goto error; } return hid; error: if (hid) libusb_hid_free(hid); return NULL; }
int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *handle) { libusb_hotplug_callback *new_callback; static int handle_id = 1; /* check for hotplug support */ if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { return LIBUSB_ERROR_NOT_SUPPORTED; } /* check for sane values */ if ((LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) || (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) || (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) || !cb_fn) { return LIBUSB_ERROR_INVALID_PARAM; } USBI_GET_CONTEXT(ctx); new_callback = (libusb_hotplug_callback *)calloc(1, sizeof (*new_callback)); if (!new_callback) { return LIBUSB_ERROR_NO_MEM; } new_callback->ctx = ctx; new_callback->vendor_id = vendor_id; new_callback->product_id = product_id; new_callback->dev_class = dev_class; new_callback->flags = flags; new_callback->events = events; new_callback->cb = cb_fn; new_callback->user_data = user_data; new_callback->needs_free = 0; usbi_mutex_lock(&ctx->hotplug_cbs_lock); /* protect the handle by the context hotplug lock. it doesn't matter if the same handle * is used for different contexts only that the handle is unique for this context */ new_callback->handle = handle_id++; list_add(&new_callback->list, &ctx->hotplug_cbs); usbi_mutex_unlock(&ctx->hotplug_cbs_lock); if (flags & LIBUSB_HOTPLUG_ENUMERATE) { int i, len; struct libusb_device **devs; len = (int) libusb_get_device_list(ctx, &devs); if (len < 0) { libusb_hotplug_deregister_callback(ctx, new_callback->handle); return len; } for (i = 0; i < len; i++) { usbi_hotplug_match_cb(ctx, devs[i], LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, new_callback); } libusb_free_device_list(devs, 1); } if (handle) { *handle = new_callback->handle; } return LIBUSB_SUCCESS; }
int main(int argc, char *argv[]) { libusb_hotplug_callback_handle hp[2]; int product_id, vendor_id, class_id = LIBUSB_HOTPLUG_MATCH_ANY; g_Command_Attach = ""; g_Command_Detach = ""; int rc; char flag_initial_search = 0; /* getopt */ while ((rc = getopt(argc, argv, "c:a:d:ih")) != -1) { switch (rc) { case 'c': class_id = strtol(optarg, NULL, 0); break; case 'a': g_Command_Attach = optarg; break; case 'd': g_Command_Detach = optarg; break; case 'i': flag_initial_search = 1; break; case 'h': default: /* '?' */ print_usage(argv[0]); exit(EXIT_FAILURE); } } if (optind + 2 > argc) { print_usage(argv[0]); exit(EXIT_FAILURE); } vendor_id = strtol(argv[optind++], NULL, 0); product_id = strtol(argv[optind++], NULL, 0); /* 初期化 */ rc = libusb_init (NULL); if (rc < 0) { fprintf(stderr, "failed to initialise libusb: %s\n", libusb_error_name(rc)); return EXIT_FAILURE; } /* シグナルハンドリング */ signal(SIGINT, finish); signal(SIGTERM, finish); /* ホットプラグ対応のプラットフォームか調べる */ if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) { fprintf (stderr, "Hotplug capabilites are not supported on this platform\n"); libusb_exit (NULL); return EXIT_FAILURE; } /* (オプションi)起動した時点での状態から目的のUSBデバイスを探す。 */ if (flag_initial_search) { if (find_device(vendor_id, product_id)) { func_attached(); } else { func_detached(); } } /* デバイスが接続されたら実行される関数を登録 */ rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id, product_id, class_id, hotplug_callback, NULL, &hp[0]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 0\n"); libusb_exit (NULL); return EXIT_FAILURE; } /* デバイスが切断されたら実行される関数を登録 */ rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id, product_id,class_id, hotplug_callback_detach, NULL, &hp[1]); if (LIBUSB_SUCCESS != rc) { fprintf (stderr, "Error registering callback 1\n"); libusb_exit (NULL); return EXIT_FAILURE; } /* メインループ。イベントを回し続ける */ while (1) { rc = libusb_handle_events (NULL); if (rc < 0) fprintf(stderr, "libusb_handle_events() failed: %s\n", libusb_error_name(rc)); } /* 到達不能コード。終了処理はシグナルにより呼び出される。 */ /* libusb_exit (NULL); */ }
SR_PRIV int fx2lafw_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) { libusb_device **devlist; struct sr_usb_dev_inst *usb; struct libusb_device_descriptor des; struct dev_context *devc; struct drv_context *drvc; struct version_info vi; int ret, i, device_count; uint8_t revid; char connection_id[64]; drvc = di->context; devc = sdi->priv; usb = sdi->conn; if (sdi->status == SR_ST_ACTIVE) /* Device is already in use. */ return SR_ERR; device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); if (device_count < 0) { sr_err("Failed to get device list: %s.", libusb_error_name(device_count)); return SR_ERR; } for (i = 0; i < device_count; i++) { libusb_get_device_descriptor(devlist[i], &des); if (des.idVendor != devc->profile->vid || des.idProduct != devc->profile->pid) continue; if ((sdi->status == SR_ST_INITIALIZING) || (sdi->status == SR_ST_INACTIVE)) { /* * Check device by its physical USB bus/port address. */ usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); if (strcmp(sdi->connection_id, connection_id)) /* This is not the one. */ continue; } if (!(ret = libusb_open(devlist[i], &usb->devhdl))) { if (usb->address == 0xff) /* * First time we touch this device after FW * upload, so we don't know the address yet. */ usb->address = libusb_get_device_address(devlist[i]); } else { sr_err("Failed to open device: %s.", libusb_error_name(ret)); break; } if (libusb_has_capability(LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) { if (libusb_kernel_driver_active(usb->devhdl, USB_INTERFACE) == 1) { if ((ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE)) < 0) { sr_err("Failed to detach kernel driver: %s.", libusb_error_name(ret)); return SR_ERR; } } } ret = command_get_fw_version(usb->devhdl, &vi); if (ret != SR_OK) { sr_err("Failed to get firmware version."); break; } ret = command_get_revid_version(sdi, &revid); if (ret != SR_OK) { sr_err("Failed to get REVID."); break; } /* * Changes in major version mean incompatible/API changes, so * bail out if we encounter an incompatible version. * Different minor versions are OK, they should be compatible. */ if (vi.major != FX2LAFW_REQUIRED_VERSION_MAJOR) { sr_err("Expected firmware version %d.x, " "got %d.%d.", FX2LAFW_REQUIRED_VERSION_MAJOR, vi.major, vi.minor); break; } sdi->status = SR_ST_ACTIVE; sr_info("Opened device on %d.%d (logical) / %s (physical), " "interface %d, firmware %d.%d.", usb->bus, usb->address, connection_id, USB_INTERFACE, vi.major, vi.minor); sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.", revid, (revid != 1) ? " (FX2)" : "A (FX2LP)"); break; } libusb_free_device_list(devlist, 1); if (sdi->status != SR_ST_ACTIVE) return SR_ERR; return SR_OK; }
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_config_descriptor *conf_desc; const struct libusb_endpoint_descriptor *endpoint; int i, j, k, r; int iface, nb_ifaces, first_iface = -1; // For attaching/detaching the kernel driver, if needed int iface_detached = -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_path(NULL, 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 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); 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++) { 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_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 ((r != LIBUSB_SUCCESS) && libusb_has_capability(LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER) && (libusb_kernel_driver_active(handle, iface) > 0)) { // Try to detach the kernel driver perr(" A kernel driver is active, trying to detach it...\n"); r = libusb_detach_kernel_driver(handle, iface); if (r == LIBUSB_SUCCESS) { iface_detached = iface; printf(" Claiming interface again...\n"); 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); } if (iface_detached >= 0) { printf("Re-attaching kernel driver...\n"); libusb_attach_kernel_driver(handle, iface_detached); } printf("Closing device...\n"); libusb_close(handle); return 0; }