static int open_via_info(void **driver, backend_probe_target probe_target, struct bladerf_devinfo *info_in, struct bladerf_devinfo *info_out) { int status; int instance = -1; struct bladerf_devinfo_list info_list; CCyUSBDevice *dev; struct bladerf_cyapi *cyapi_data; dev = new CCyUSBDevice(NULL, driver_guid); if (dev == NULL) { return BLADERF_ERR_MEM; } cyapi_data = (struct bladerf_cyapi *) calloc(1, sizeof(cyapi_data[0])); if (cyapi_data == NULL) { delete dev; return BLADERF_ERR_MEM; } bladerf_devinfo_list_init(&info_list); status = cyapi_probe(probe_target, &info_list); for (unsigned int i = 0; i < info_list.num_elt && status == 0; i++) { if (bladerf_devinfo_matches(&info_list.elt[i], info_in)) { instance = info_list.elt[i].instance; status = open_device(dev, instance, &cyapi_data->mutex); if (status == 0) { cyapi_data->dev = dev; *driver = cyapi_data; if (info_out != NULL) { memcpy(info_out, &info_list.elt[instance], sizeof(info_out[0])); } status = 0; break; } } } if (status == 0 && instance < 0) { status = BLADERF_ERR_NODEV; } if (status != 0) { delete dev; CloseHandle(cyapi_data->mutex); } free(info_list.elt); return status; }
int backend_probe(backend_probe_target probe_target, struct bladerf_devinfo **devinfo_items, size_t *num_items) { int status; int first_backend_error = 0; struct bladerf_devinfo_list list; size_t i; const size_t n_backends = ARRAY_SIZE(backend_list); *devinfo_items = NULL; *num_items = 0; status = bladerf_devinfo_list_init(&list); if (status != 0) { log_debug("Failed to initialize devinfo list: %s\n", bladerf_strerror(status)); return status; } for (i = 0; i < n_backends; i++) { status = backend_list[i]->probe(probe_target, &list); if (status < 0 && status != BLADERF_ERR_NODEV) { log_debug("Probe failed on backend %d: %s\n", i, bladerf_strerror(status)); if (!first_backend_error) { first_backend_error = status; } } } *num_items = list.num_elt; if (*num_items != 0) { *devinfo_items = list.elt; } else { /* For no items, we end up passing back a NULL list to the * API caller, so we'll just free this up now */ free(list.elt); /* Report the first error that occurred if we couldn't find anything */ status = first_backend_error == 0 ? BLADERF_ERR_NODEV : first_backend_error; } return status; }
int backend_probe(struct bladerf_devinfo **devinfo_items, size_t *num_items) { int probe_status, backend_status; struct bladerf_devinfo_list list; size_t i; const size_t n_backends = ARRAY_SIZE(backend_list); *devinfo_items = NULL; *num_items = 0; probe_status = bladerf_devinfo_list_init(&list); if (probe_status == 0) { for (i = 0; i < n_backends && probe_status == 0; i++) { backend_status = backend_list[i].fns->probe(&list); /* Error out if a backend hit any concerning error */ if (backend_status < 0 && backend_status != BLADERF_ERR_NODEV) { probe_status = backend_status; } } } if (probe_status == 0) { *num_items = list.num_elt; if (*num_items != 0) { *devinfo_items = list.elt; } else { /* For no items, we end up passing back a NULL list to the * API caller, so we'll just free this up now */ free(list.elt); probe_status = BLADERF_ERR_NODEV; } } else { free(list.elt); } return probe_status; }
static int linux_open( struct bladerf **device, struct bladerf_devinfo *info) { char dev_name[32]; struct bladerf_linux *backend; struct bladerf *ret = NULL; int status = BLADERF_ERR_IO; int fd; /* Everything here starts with a driver file descriptor, * so no need to allocate backend and ret until we know we * have said fd */ assert(info->backend == BLADERF_BACKEND_LINUX || info->backend == BLADERF_BACKEND_ANY); /* If an instance is specified, we start with that */ if (info->instance != DEVINFO_INST_ANY) { snprintf(dev_name, sizeof(dev_name), "/dev/bladerf%d", info->instance); fd = open(dev_name, O_RDWR); if (fd >= 0) { backend = calloc(1, sizeof(*backend)); if (backend == NULL) { return BLADERF_ERR_MEM; } ret = calloc(1, sizeof(*ret)); if (ret == NULL) { free(backend); return BLADERF_ERR_MEM; } ret->fpga_version.describe = calloc(1, BLADERF_VERSION_STR_MAX); if (ret->fpga_version.describe == NULL) { free(ret); free(backend); return BLADERF_ERR_MEM; } ret->fw_version.describe = calloc(1, BLADERF_VERSION_STR_MAX); if (ret->fw_version.describe == NULL) { free((void*)ret->fpga_version.describe); free(ret); free(backend); return BLADERF_ERR_MEM; } backend->fd = fd; ret->fn = &bladerf_linux_fn; ret->backend = backend; *device = ret; /* Ensure all dev-info fields are written */ status = linux_populate_devinfo(ret, &ret->ident, info->instance); if (status < 0) { goto linux_open_err; } /* Populate version fields */ status = linux_populate_fpga_version(ret); if (status < 0) { goto linux_open_err; } status = linux_populate_fw_version(ret); linux_open_err: if (status < 0) { free((void*)ret->fw_version.describe); free((void*)ret->fpga_version.describe); free(ret); free(backend); } } else { log_error("Failed to open %s: %s\n", dev_name, strerror(errno)); } } else { /* Otherwise, we user our probe routine to get a device info list, * and then search it */ struct bladerf_devinfo_list list; size_t i; status = bladerf_devinfo_list_init(&list); if (status < 0) { log_error("Failed to initialized devinfo list!\n"); } else { status = linux_probe(&list); if (status < 0) { if (status == BLADERF_ERR_NODEV) { log_debug("No devices available on the Linux driver backend.\n"); } else { log_error("Probe failed: %s\n", bladerf_strerror(status)); } } else { for (i = 0; i < list.num_elt && !ret; i++) { if (bladerf_devinfo_matches(&list.elt[i], info)) { status = linux_open(device, &list.elt[i]); if (status) { log_error("Failed to open instance %d - " "trying next\n", list.elt[i].instance); } else { backend =(*device)->backend; } } } free(list.elt); } } } return status; }