コード例 #1
0
ファイル: bladeRF.c プロジェクト: adamgreig/bladeRF
static int enable_rx(bladerf_device_t *dev) {
    int ret;
    int i;
    unsigned int val;
    val = 1;

    if (dev->intnum != 1)
        return -1;

    if (dev->disconnecting)
        return -ENODEV;

    for (i = 0; i < NUM_DATA_URB; i++)
        dev->data_in_bufs[i].valid = 1;

    ret = __bladerf_snd_cmd(dev, BLADE_USB_CMD_RF_RX, &val, sizeof(val));
    if (ret < 0)
        goto err_out;

    ret = 0;
    dev->rx_en = 1;

    for (i = 0; i < NUM_CONCURRENT; i++) {
        if ((ret = __submit_rx_urb(dev, 0)) < 0) {
            dev_err(&dev->interface->dev, "Error submitting initial RX URBs (%d/%d), error=%d\n", i, NUM_CONCURRENT, ret);
            break;
        }
    }

err_out:
    return ret;
}
コード例 #2
0
ファイル: bladeRF.c プロジェクト: bpadalino/bladeRF
static void __bladeRF_read_cb(struct urb *urb) {
    bladerf_device_t *dev;
    unsigned char *buf;

    buf = (unsigned char *)urb->transfer_buffer;
    dev = (bladerf_device_t *)urb->context;

    if (dev->rx_en)
        __submit_rx_urb(dev, GFP_ATOMIC);
    wake_up_interruptible(&dev->data_in_wait);
}
コード例 #3
0
ファイル: bladeRF.c プロジェクト: adamgreig/bladeRF
static void __bladeRF_read_cb(struct urb *urb) {
    bladerf_device_t *dev;
    unsigned char *buf;

    buf = (unsigned char *)urb->transfer_buffer;
    dev = (bladerf_device_t *)urb->context;
    usb_unanchor_urb(urb);
    atomic_dec(&dev->data_in_inflight);
    dev->bytes += DATA_BUF_SZ;
    atomic_inc(&dev->data_in_cnt);

    if (dev->rx_en)
        __submit_rx_urb(dev, GFP_ATOMIC);
    wake_up_interruptible(&dev->data_in_wait);
}
コード例 #4
0
ファイル: bladeRF.c プロジェクト: adamgreig/bladeRF
static ssize_t bladerf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
    ssize_t ret = 0;
    bladerf_device_t *dev;
    unsigned long flags;
    int read;

    dev = (bladerf_device_t *)file->private_data;
    if (dev->intnum != 1) {
        return -1;
    }

    if (dev->reader) {
        if (file != dev->reader) {
            return -EPERM;
        }
    } else
        dev->reader = file;

    if (dev->disconnecting)
        return -ENODEV;

    if (!dev->rx_en) {
        if (enable_rx(dev)) {
            return -EINVAL;
        }
    }
    read = 0;

    while (!read) {
        int reread;
        reread = atomic_read(&dev->data_in_cnt);

        if (reread) {
            unsigned int idx;

            spin_lock_irqsave(&dev->data_in_lock, flags);
            atomic_dec(&dev->data_in_cnt);
            atomic_dec(&dev->data_in_used);
            idx = dev->data_in_consumer_idx++;
            dev->data_in_consumer_idx &= (NUM_DATA_URB - 1);

            spin_unlock_irqrestore(&dev->data_in_lock, flags);

            if (copy_to_user(buf, dev->data_in_bufs[idx].addr, DATA_BUF_SZ)) {
                ret = -EFAULT;
            } else {
                ret = 0;
            }


            dev->data_in_bufs[idx].valid = 1; // mark this RX packet as free

            // in case all of the buffers were full, rx needs to be restarted
            // samples may have also been dropped if this happens because the user-mode
            // application is not reading samples fast enough
            if (atomic_read(&dev->data_in_inflight) == 0)
                __submit_rx_urb(dev, 0);


            if (!ret)
                ret = DATA_BUF_SZ;

            break;

        } else {
            ret = wait_event_interruptible_timeout(dev->data_in_wait, atomic_read(&dev->data_in_cnt), 2 * HZ);
            if (ret < 0) {
                break;
            } else if (ret == 0) {
                ret = -ETIMEDOUT;
                break;
            } else {
                ret = 0;
            }
        }
    }

    return ret;
}