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; }
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); }
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); }
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; }