/** * Find USB devices supporting the USBTMC class * * @param usb_ctx libusb context to use while scanning. * * @return A GSList of struct sr_usb_dev_inst, with bus and address fields * indicating devices with USBTMC support. */ SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx) { struct sr_usb_dev_inst *usb; struct libusb_device **devlist; struct libusb_device_descriptor des; struct libusb_config_descriptor *confdes; const struct libusb_interface_descriptor *intfdes; GSList *devices; int confidx, intfidx, ret, i; devices = NULL; libusb_get_device_list(usb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } for (confidx = 0; confidx < des.bNumConfigurations; confidx++) { if (libusb_get_config_descriptor(devlist[i], confidx, &confdes) != 0) { sr_err("Failed to get configuration descriptor."); break; } for (intfidx = 0; intfidx < confdes->bNumInterfaces; intfidx++) { intfdes = confdes->interface[intfidx].altsetting; if (intfdes->bInterfaceClass != LIBUSB_CLASS_APPLICATION || intfdes->bInterfaceSubClass != SUBCLASS_USBTMC || intfdes->bInterfaceProtocol != USBTMC_USB488) continue; sr_dbg("Found USBTMC device (VID:PID = %04x:%04x, bus.address = " "%d.%d).", des.idVendor, des.idProduct, libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i])); usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); devices = g_slist_append(devices, usb); } libusb_free_config_descriptor(confdes); } } libusb_free_device_list(devlist, 1); sr_dbg("Found %d device(s).", g_slist_length(devices)); return devices; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_usb_dev_inst *usb; struct sr_config *src; const struct hantek_6xxx_profile *prof; GSList *l, *devices, *conn_devices; struct libusb_device_descriptor des; libusb_device **devlist; int i, j; const char *conn; char connection_id[64]; drvc = di->context; devices = 0; conn = NULL; for (l = options; l; l = l->next) { src = l->data; if (src->key == SR_CONF_CONN) { conn = g_variant_get_string(src->data, NULL); break; } } if (conn) conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn); else conn_devices = NULL; /* Find all Hantek 60xx devices and upload firmware to all of them. */ libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if (conn) { usb = NULL; for (l = conn_devices; l; l = l->next) { usb = l->data; if (usb->bus == libusb_get_bus_number(devlist[i]) && usb->address == libusb_get_device_address(devlist[i])) break; } if (!l) /* This device matched none of the ones that * matched the conn specification. */ continue; } libusb_get_device_descriptor(devlist[i], &des); usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); prof = NULL; for (j = 0; j < (int)ARRAY_SIZE(dev_profiles); j++) { if (des.idVendor == dev_profiles[j].orig_vid && des.idProduct == dev_profiles[j].orig_pid) { /* Device matches the pre-firmware profile. */ prof = &dev_profiles[j]; sr_dbg("Found a %s %s.", prof->vendor, prof->model); sdi = hantek_6xxx_dev_new(prof); sdi->connection_id = g_strdup(connection_id); devices = g_slist_append(devices, sdi); devc = sdi->priv; if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i], USB_CONFIGURATION, prof->firmware) == SR_OK) /* Remember when the firmware on this device was updated. */ devc->fw_updated = g_get_monotonic_time(); else sr_err("Firmware upload failed."); /* Dummy USB address of 0xff will get overwritten later. */ sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), 0xff, NULL); break; } else if (des.idVendor == dev_profiles[j].fw_vid && des.idProduct == dev_profiles[j].fw_pid) { /* Device matches the post-firmware profile. */ prof = &dev_profiles[j]; sr_dbg("Found a %s %s.", prof->vendor, prof->model); sdi = hantek_6xxx_dev_new(prof); sdi->connection_id = g_strdup(connection_id); sdi->status = SR_ST_INACTIVE; devices = g_slist_append(devices, sdi); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); break; } } if (!prof) /* Not a supported VID/PID. */ continue; } libusb_free_device_list(devlist, 1); return devices; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct sr_channel *ch; struct drv_context *drvc; struct dev_context *devc; const struct zp_model *prof; struct libusb_device_descriptor des; libusb_device **devlist; GSList *devices; int ret, devcnt, i, j; (void)options; drvc = di->priv; devices = NULL; /* Find all ZEROPLUS analyzers and add them to device list. */ devcnt = 0; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */ for (i = 0; devlist[i]; i++) { ret = libusb_get_device_descriptor(devlist[i], &des); if (ret != 0) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } prof = NULL; for (j = 0; j < zeroplus_models[j].vid; j++) { if (des.idVendor == zeroplus_models[j].vid && des.idProduct == zeroplus_models[j].pid) { prof = &zeroplus_models[j]; } } /* Skip if the device was not found. */ if (!prof) continue; sr_info("Found ZEROPLUS %s.", prof->model_name); /* Register the device with libsigrok. */ if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_INACTIVE, VENDOR_NAME, prof->model_name, NULL))) { sr_err("%s: sr_dev_inst_new failed", __func__); return NULL; } sdi->driver = di; /* Allocate memory for our private driver context. */ if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } sdi->priv = devc; devc->prof = prof; devc->num_channels = prof->channels; #ifdef ZP_EXPERIMENTAL devc->max_sample_depth = 128 * 1024; devc->max_samplerate = 200; #else devc->max_sample_depth = prof->sample_depth * 1024; devc->max_samplerate = prof->max_sampling_freq; #endif devc->max_samplerate *= SR_MHZ(1); devc->memory_size = MEMORY_SIZE_8K; // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES); /* Fill in channellist according to this device's profile. */ for (j = 0; j < devc->num_channels; j++) { if (!(ch = sr_channel_new(j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); } devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); devcnt++; } libusb_free_device_list(devlist, 1); return devices; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct dev_context *devc; const struct zp_model *prof; struct libusb_device_descriptor des; struct libusb_device_handle *hdl; libusb_device **devlist; GSList *devices; int ret, i, j; char serial_num[64], connection_id[64]; (void)options; drvc = di->priv; devices = NULL; /* Find all ZEROPLUS analyzers and add them to device list. */ libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */ for (i = 0; devlist[i]; i++) { ret = libusb_get_device_descriptor(devlist[i], &des); if (ret != 0) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } if ((ret = libusb_open(devlist[i], &hdl)) < 0) continue; if (des.iSerialNumber == 0) { serial_num[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iSerialNumber, (unsigned char *) serial_num, sizeof(serial_num))) < 0) { sr_warn("Failed to get serial number string descriptor: %s.", libusb_error_name(ret)); continue; } libusb_close(hdl); usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); prof = NULL; for (j = 0; j < zeroplus_models[j].vid; j++) { if (des.idVendor == zeroplus_models[j].vid && des.idProduct == zeroplus_models[j].pid) { prof = &zeroplus_models[j]; } } /* Skip if the device was not found. */ if (!prof) continue; sr_info("Found ZEROPLUS %s.", prof->model_name); /* Register the device with libsigrok. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->vendor = g_strdup(VENDOR_NAME); sdi->model = g_strdup(prof->model_name); sdi->driver = di; sdi->serial_num = g_strdup(serial_num); sdi->connection_id = g_strdup(connection_id); /* Allocate memory for our private driver context. */ devc = g_malloc0(sizeof(struct dev_context)); sdi->priv = devc; devc->prof = prof; devc->num_channels = prof->channels; #ifdef ZP_EXPERIMENTAL devc->max_sample_depth = 128 * 1024; devc->max_samplerate = 200; #else devc->max_sample_depth = prof->sample_depth * 1024; devc->max_samplerate = prof->max_sampling_freq; #endif devc->max_samplerate *= SR_MHZ(1); devc->memory_size = MEMORY_SIZE_8K; // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES); /* Fill in channellist according to this device's profile. */ for (j = 0; j < devc->num_channels; j++) sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]); devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } libusb_free_device_list(devlist, 1); return devices; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct sr_dev_inst *sdi; struct drv_context *drvc; struct sr_usb_dev_inst *usb; struct libusb_device_descriptor des; libusb_device **devlist; GSList *devices; char connection_id[64]; size_t i; int r; (void)options; drvc = di->context; devices = NULL; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); for (i = 0; devlist[i]; i++) { libusb_get_device_descriptor(devlist[i], &des); if (des.idVendor != LOGICSTUDIO16_VID) continue; usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); usb = NULL; switch (des.idProduct) { case LOGICSTUDIO16_PID_HAVE_FIRMWARE: usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); sdi = create_device(usb, SR_ST_INACTIVE, 0); break; case LOGICSTUDIO16_PID_LACK_FIRMWARE: r = ezusb_upload_firmware(drvc->sr_ctx, devlist[i], USB_CONFIGURATION, FX2_FIRMWARE); if (r != SR_OK) { /* * An error message has already been logged by * ezusb_upload_firmware(). */ continue; } /* * Put unknown as the address so that we know we still * need to get the proper address after the device * renumerates. */ usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), UNKNOWN_ADDRESS, NULL); sdi = create_device(usb, SR_ST_INITIALIZING, g_get_monotonic_time()); break; default: break; } /* Cannot handle this device? */ if (!usb) continue; sdi->connection_id = g_strdup(connection_id); devices = g_slist_append(devices, sdi); } libusb_free_device_list(devlist, 1); return std_scan_complete(di, devices); }
/** * Find USB devices according to a connection string. * * @param usb_ctx libusb context to use while scanning. * @param conn Connection string specifying the device(s) to match. This * can be of the form "<bus>.<address>", or "<vendorid>.<productid>". * * @return A GSList of struct sr_usb_dev_inst, with bus and address fields * matching the device that matched the connection string. The GSList and * its contents must be freed by the caller. */ SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn) { struct sr_usb_dev_inst *usb; struct libusb_device **devlist; struct libusb_device_descriptor des; GSList *devices; GRegex *reg; GMatchInfo *match; int vid, pid, bus, addr, b, a, ret, i; char *mstr; vid = pid = bus = addr = 0; reg = g_regex_new(CONN_USB_VIDPID, 0, 0, NULL); if (g_regex_match(reg, conn, 0, &match)) { if ((mstr = g_match_info_fetch(match, 1))) vid = strtoul(mstr, NULL, 16); g_free(mstr); if ((mstr = g_match_info_fetch(match, 2))) pid = strtoul(mstr, NULL, 16); g_free(mstr); sr_dbg("Trying to find USB device with VID:PID = %04x:%04x.", vid, pid); } else { g_match_info_unref(match); g_regex_unref(reg); reg = g_regex_new(CONN_USB_BUSADDR, 0, 0, NULL); if (g_regex_match(reg, conn, 0, &match)) { if ((mstr = g_match_info_fetch(match, 1))) bus = strtoul(mstr, NULL, 10); g_free(mstr); if ((mstr = g_match_info_fetch(match, 2))) addr = strtoul(mstr, NULL, 10); g_free(mstr); sr_dbg("Trying to find USB device with bus.address = " "%d.%d.", bus, addr); } } g_match_info_unref(match); g_regex_unref(reg); if (vid + pid + bus + addr == 0) { sr_err("Neither VID:PID nor bus.address was specified."); return NULL; } if (bus > 64) { sr_err("Invalid bus specified: %d.", bus); return NULL; } if (addr > 127) { sr_err("Invalid address specified: %d.", addr); return NULL; } /* Looks like a valid USB device specification, but is it connected? */ devices = NULL; libusb_get_device_list(usb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } if (vid + pid && (des.idVendor != vid || des.idProduct != pid)) continue; b = libusb_get_bus_number(devlist[i]); a = libusb_get_device_address(devlist[i]); if (bus + addr && (b != bus || a != addr)) continue; sr_dbg("Found USB device (VID:PID = %04x:%04x, bus.address = " "%d.%d).", des.idVendor, des.idProduct, b, a); usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); devices = g_slist_append(devices, usb); } libusb_free_device_list(devlist, 1); sr_dbg("Found %d device(s).", g_slist_length(devices)); return devices; }
static int hw_init(const char *devinfo) { struct sr_dev_inst *sdi; struct libusb_device_descriptor des; libusb_device **devlist; int ret, devcnt, i; struct context *ctx; /* Avoid compiler warnings. */ (void)devinfo; /* Allocate memory for our private driver context. */ if (!(ctx = g_try_malloc(sizeof(struct context)))) { sr_err("zp: %s: ctx malloc failed", __func__); return 0; } /* Set some sane defaults. */ ctx->cur_samplerate = 0; ctx->limit_samples = 0; ctx->num_channels = 32; /* TODO: This isn't initialized before it's needed :( */ ctx->memory_size = 0; ctx->probe_mask = 0; memset(ctx->trigger_mask, 0, NUM_TRIGGER_STAGES); memset(ctx->trigger_value, 0, NUM_TRIGGER_STAGES); // memset(ctx->trigger_buffer, 0, NUM_TRIGGER_STAGES); if (libusb_init(&usb_context) != 0) { sr_err("zp: Failed to initialize USB."); return 0; } /* Find all ZeroPlus analyzers and add them to device list. */ devcnt = 0; libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */ for (i = 0; devlist[i]; i++) { ret = libusb_get_device_descriptor(devlist[i], &des); if (ret != 0) { sr_err("zp: failed to get device descriptor: %d", ret); continue; } if (des.idVendor == USB_VENDOR) { /* * Definitely a Zeroplus. * TODO: Any way to detect specific model/version in * the zeroplus range? */ /* Register the device with libsigrok. */ if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_INACTIVE, USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION))) { sr_err("zp: %s: sr_dev_inst_new failed", __func__); return 0; } sdi->priv = ctx; dev_insts = g_slist_append(dev_insts, sdi); ctx->usb = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); devcnt++; } } libusb_free_device_list(devlist, 1); return devcnt; }
static GSList *hw_scan(GSList *options) { struct sr_dev_inst *sdi; const struct dso_profile *prof; struct drv_context *drvc; struct dev_context *devc; GSList *devices; struct libusb_device_descriptor des; libusb_device **devlist; int devcnt, ret, i, j; (void)options; drvc = di->priv; drvc->instances = NULL; devcnt = 0; devices = 0; clear_instances(); /* Find all Hantek DSO devices and upload firmware to all of them. */ libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { sr_err("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } prof = NULL; for (j = 0; dev_profiles[j].orig_vid; j++) { if (des.idVendor == dev_profiles[j].orig_vid && des.idProduct == dev_profiles[j].orig_pid) { /* Device matches the pre-firmware profile. */ prof = &dev_profiles[j]; sr_dbg("Found a %s %s.", prof->vendor, prof->model); sdi = dso_dev_new(devcnt, prof); devices = g_slist_append(devices, sdi); devc = sdi->priv; if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, prof->firmware) == SR_OK) /* Remember when the firmware on this device was updated */ devc->fw_updated = g_get_monotonic_time(); else sr_err("Firmware upload failed for " "device %d.", devcnt); /* Dummy USB address of 0xff will get overwritten later. */ devc->usb = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), 0xff, NULL); devcnt++; break; } else if (des.idVendor == dev_profiles[j].fw_vid && des.idProduct == dev_profiles[j].fw_pid) { /* Device matches the post-firmware profile. */ prof = &dev_profiles[j]; sr_dbg("Found a %s %s.", prof->vendor, prof->model); sdi = dso_dev_new(devcnt, prof); sdi->status = SR_ST_INACTIVE; devices = g_slist_append(devices, sdi); devc = sdi->priv; devc->usb = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); devcnt++; break; } } if (!prof) /* not a supported VID/PID */ continue; } libusb_free_device_list(devlist, 1); return devices; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_usb_dev_inst *usb; struct sr_channel *ch; struct sr_channel_group *cg; struct sr_config *src; const struct fx2lafw_profile *prof; GSList *l, *devices, *conn_devices; gboolean has_firmware; struct libusb_device_descriptor des; libusb_device **devlist; struct libusb_device_handle *hdl; int ret, i, j; int num_logic_channels = 0, num_analog_channels = 0; const char *conn; char manufacturer[64], product[64], serial_num[64], connection_id[64]; char channel_name[16]; drvc = di->context; conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; } } if (conn) conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn); else conn_devices = NULL; /* Find all fx2lafw compatible devices and upload firmware to them. */ devices = NULL; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if (conn) { usb = NULL; for (l = conn_devices; l; l = l->next) { usb = l->data; if (usb->bus == libusb_get_bus_number(devlist[i]) && usb->address == libusb_get_device_address(devlist[i])) break; } if (!l) /* This device matched none of the ones that * matched the conn specification. */ continue; } libusb_get_device_descriptor( devlist[i], &des); if (!is_plausible(&des)) continue; if ((ret = libusb_open(devlist[i], &hdl)) < 0) { sr_warn("Failed to open potential device with " "VID:PID %04x:%04x: %s.", des.idVendor, des.idProduct, libusb_error_name(ret)); continue; } if (des.iManufacturer == 0) { manufacturer[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iManufacturer, (unsigned char *) manufacturer, sizeof(manufacturer))) < 0) { sr_warn("Failed to get manufacturer string descriptor: %s.", libusb_error_name(ret)); continue; } if (des.iProduct == 0) { product[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iProduct, (unsigned char *) product, sizeof(product))) < 0) { sr_warn("Failed to get product string descriptor: %s.", libusb_error_name(ret)); continue; } if (des.iSerialNumber == 0) { serial_num[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iSerialNumber, (unsigned char *) serial_num, sizeof(serial_num))) < 0) { sr_warn("Failed to get serial number string descriptor: %s.", libusb_error_name(ret)); continue; } libusb_close(hdl); if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0) continue; prof = NULL; for (j = 0; supported_fx2[j].vid; j++) { if (des.idVendor == supported_fx2[j].vid && des.idProduct == supported_fx2[j].pid && (!supported_fx2[j].usb_manufacturer || !strcmp(manufacturer, supported_fx2[j].usb_manufacturer)) && (!supported_fx2[j].usb_product || !strcmp(product, supported_fx2[j].usb_product))) { prof = &supported_fx2[j]; break; } } if (!prof) continue; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INITIALIZING; sdi->vendor = g_strdup(prof->vendor); sdi->model = g_strdup(prof->model); sdi->version = g_strdup(prof->model_version); sdi->serial_num = g_strdup(serial_num); sdi->connection_id = g_strdup(connection_id); /* Fill in channellist according to this device's profile. */ num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8; num_analog_channels = prof->dev_caps & DEV_CAPS_AX_ANALOG ? 1 : 0; /* Logic channels, all in one channel group. */ cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup("Logic"); for (j = 0; j < num_logic_channels; j++) { sprintf(channel_name, "D%d", j); ch = sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_name); cg->channels = g_slist_append(cg->channels, ch); } sdi->channel_groups = g_slist_append(NULL, cg); for (j = 0; j < num_analog_channels; j++) { snprintf(channel_name, 16, "A%d", j); ch = sr_channel_new(sdi, j + num_logic_channels, SR_CHANNEL_ANALOG, TRUE, channel_name); /* Every analog channel gets its own channel group. */ cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup(channel_name); cg->channels = g_slist_append(NULL, ch); sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); } devc = fx2lafw_dev_new(); devc->profile = prof; sdi->priv = devc; devices = g_slist_append(devices, sdi); devc->samplerates = samplerates; devc->num_samplerates = ARRAY_SIZE(samplerates); has_firmware = usb_match_manuf_prod(devlist[i], "sigrok", "fx2lafw"); if (has_firmware) { /* Already has the firmware, so fix the new address. */ sr_dbg("Found an fx2lafw device."); sdi->status = SR_ST_INACTIVE; sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i], USB_CONFIGURATION, prof->firmware) == SR_OK) { /* Store when this device's FW was updated. */ devc->fw_updated = g_get_monotonic_time(); } else { sr_err("Firmware upload failed for " "device %d.%d (logical), name %s.", libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), prof->firmware); } sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), 0xff, NULL); } } libusb_free_device_list(devlist, 1); g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); return std_scan_complete(di, devices); }
static int parse_conn_busaddr(struct sr_dev_inst *sdi, const char *conn) { struct context *ctx; libusb_device **devlist; struct libusb_device_descriptor des; GRegex *reg; GMatchInfo *match; int bus, addr, found, err, i; char *busstr, *addrstr; found = FALSE; reg = g_regex_new(DMM_CONN_USB_BUSADDR, 0, 0, NULL); if (g_regex_match(reg, conn, 0, &match)) { /* Extract bus. */ if (!(busstr = g_match_info_fetch(match, 0))) { sr_err("failed to fetch bus from regex"); goto err; } bus = strtoul(busstr, NULL, 16); g_free(busstr); if (bus > 64) { sr_err("invalid bus"); goto err; } /* Extract address. */ if (!(addrstr = g_match_info_fetch(match, 0))) { sr_err("failed to fetch address from regex"); goto err; } addr = strtoul(addrstr, NULL, 16); g_free(addrstr); if (addr > 127) { sr_err("invalid address"); goto err; } /* Looks like a valid bus/address, but is it connected? */ libusb_get_device_list(genericdmm_usb_context, &devlist); for (i = 0; devlist[i]; i++) { if ((err = libusb_get_device_descriptor(devlist[i], &des))) { sr_err("genericdmm: failed to get device descriptor: %d", err); goto err; } if (libusb_get_bus_number(devlist[i]) == bus && libusb_get_device_address(devlist[i]) == addr) { ctx = sdi->priv; ctx->usb = sr_usb_dev_inst_new(bus, addr, NULL); found = TRUE; break; } } libusb_free_device_list(devlist, 1); } err: if (match) g_match_info_unref(match); g_regex_unref(reg); return found; }
static int parse_conn_vidpid(struct sr_dev_inst *sdi, const char *conn) { struct context *ctx; libusb_device **devlist; struct libusb_device_descriptor des; GRegex *reg; GMatchInfo *match; int vid, pid, found, err, i; char *vidstr, *pidstr; found = FALSE; reg = g_regex_new(DMM_CONN_USB_VIDPID, 0, 0, NULL); if (g_regex_match(reg, conn, 0, &match)) { /* Extract VID. */ if (!(vidstr = g_match_info_fetch(match, 0))) { sr_err("failed to fetch VID from regex"); goto err; } vid = strtoul(vidstr, NULL, 16); g_free(vidstr); if (vid > 0xffff) { sr_err("invalid VID"); goto err; } /* Extract PID. */ if (!(pidstr = g_match_info_fetch(match, 0))) { sr_err("failed to fetch PID from regex"); goto err; } pid = strtoul(pidstr, NULL, 16); g_free(pidstr); if (pid > 0xffff) { sr_err("invalid PID"); goto err; } /* Looks like a valid VID:PID, but is it connected? */ libusb_get_device_list(genericdmm_usb_context, &devlist); for (i = 0; devlist[i]; i++) { if ((err = libusb_get_device_descriptor(devlist[i], &des))) { sr_err("genericdmm: failed to get device descriptor: %d", err); goto err; } if (des.idVendor == vid && des.idProduct == pid) { ctx = sdi->priv; ctx->usb = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); found = TRUE; break; } } libusb_free_device_list(devlist, 1); } err: if (match) g_match_info_unref(match); g_regex_unref(reg); return found; }
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_usb_dev_inst *usb; struct sr_config *src; GSList *l, *devices, *conn_devices; struct libusb_device_descriptor des; libusb_device **devlist; int ret; unsigned int i, j; const char *conn; char connection_id[64]; drvc = di->priv; conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; } } if (conn) conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn); else conn_devices = NULL; /* Find all Logic16 devices and upload firmware to them. */ devices = NULL; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if (conn) { usb = NULL; for (l = conn_devices; l; l = l->next) { usb = l->data; if (usb->bus == libusb_get_bus_number(devlist[i]) && usb->address == libusb_get_device_address(devlist[i])) break; } if (!l) /* This device matched none of the ones that * matched the conn specification. */ continue; } if ((ret = libusb_get_device_descriptor(devlist[i], &des)) != 0) { sr_warn("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); if (des.idVendor != LOGIC16_VID || des.idProduct != LOGIC16_PID) continue; sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INITIALIZING; sdi->vendor = g_strdup("Saleae"); sdi->model = g_strdup("Logic16"); sdi->driver = di; sdi->connection_id = g_strdup(connection_id); for (j = 0; j < ARRAY_SIZE(channel_names); j++) sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]); devc = g_malloc0(sizeof(struct dev_context)); devc->selected_voltage_range = VOLTAGE_RANGE_18_33_V; sdi->priv = devc; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); if (check_conf_profile(devlist[i])) { /* Already has the firmware, so fix the new address. */ sr_dbg("Found a Logic16 device."); sdi->status = SR_ST_INACTIVE; sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, FX2_FIRMWARE) == SR_OK) /* Store when this device's FW was updated. */ devc->fw_updated = g_get_monotonic_time(); else sr_err("Firmware upload failed."); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), 0xff, NULL); } } libusb_free_device_list(devlist, 1); g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); return devices; }
static GSList *scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_usb_dev_inst *usb; struct sr_channel *ch; struct sr_config *src; const struct fx2lafw_profile *prof; GSList *l, *devices, *conn_devices; struct libusb_device_descriptor des; libusb_device **devlist; struct libusb_device_handle *hdl; int devcnt, num_logic_channels, ret, i, j; const char *conn; char manufacturer[64], product[64]; drvc = di->priv; conn = NULL; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = g_variant_get_string(src->data, NULL); break; } } if (conn) conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn); else conn_devices = NULL; /* Find all fx2lafw compatible devices and upload firmware to them. */ devices = NULL; libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); for (i = 0; devlist[i]; i++) { if (conn) { usb = NULL; for (l = conn_devices; l; l = l->next) { usb = l->data; if (usb->bus == libusb_get_bus_number(devlist[i]) && usb->address == libusb_get_device_address(devlist[i])) break; } if (!l) /* This device matched none of the ones that * matched the conn specification. */ continue; } if ((ret = libusb_get_device_descriptor( devlist[i], &des)) != 0) { sr_warn("Failed to get device descriptor: %s.", libusb_error_name(ret)); continue; } if ((ret = libusb_open(devlist[i], &hdl)) < 0) continue; if (des.iManufacturer == 0) { manufacturer[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iManufacturer, (unsigned char *) manufacturer, sizeof(manufacturer))) < 0) { sr_warn("Failed to get manufacturer string descriptor: %s.", libusb_error_name(ret)); continue; } if (des.iProduct == 0) { product[0] = '\0'; } else if ((ret = libusb_get_string_descriptor_ascii(hdl, des.iProduct, (unsigned char *) product, sizeof(product))) < 0) { sr_warn("Failed to get product string descriptor: %s.", libusb_error_name(ret)); continue; } libusb_close(hdl); prof = NULL; for (j = 0; supported_fx2[j].vid; j++) { if (des.idVendor == supported_fx2[j].vid && des.idProduct == supported_fx2[j].pid && (!supported_fx2[j].usb_manufacturer || !strcmp(manufacturer, supported_fx2[j].usb_manufacturer)) && (!supported_fx2[j].usb_manufacturer || !strcmp(product, supported_fx2[j].usb_product))) { prof = &supported_fx2[j]; break; } } /* Skip if the device was not found. */ if (!prof) continue; devcnt = g_slist_length(drvc->instances); sdi = sr_dev_inst_new(devcnt, SR_ST_INITIALIZING, prof->vendor, prof->model, prof->model_version); if (!sdi) return NULL; sdi->driver = di; /* Fill in channellist according to this device's profile. */ num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8; for (j = 0; j < num_logic_channels; j++) { if (!(ch = sr_channel_new(j, SR_CHANNEL_LOGIC, TRUE, channel_names[j]))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); } devc = fx2lafw_dev_new(); devc->profile = prof; sdi->priv = devc; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); if (fx2lafw_check_conf_profile(devlist[i])) { /* Already has the firmware, so fix the new address. */ sr_dbg("Found an fx2lafw device."); sdi->status = SR_ST_INACTIVE; sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, prof->firmware) == SR_OK) /* Store when this device's FW was updated. */ devc->fw_updated = g_get_monotonic_time(); else sr_err("Firmware upload failed for " "device %d.", devcnt); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), 0xff, NULL); } } libusb_free_device_list(devlist, 1); g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); return devices; }