Skip to content

Commit

Permalink
linux: stop driver from submitting URBs once device has been disconne…
Browse files Browse the repository at this point in the history
…cted

This fixes and issues where the drive would continue to submit URBs even after
the device was unplugged, and the usb_device was freed from the usb core causing
kernel panics.
  • Loading branch information
robertghilduta committed Jul 10, 2013
1 parent 15215df commit 55c3879
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion linux/kernel/bladeRF.c
Expand Up @@ -22,6 +22,7 @@ typedef struct {
struct usb_interface *interface;

int intnum;
int disconnecting;

int rx_en;
spinlock_t data_in_lock;
Expand Down Expand Up @@ -255,6 +256,9 @@ static int enable_rx(bladerf_device_t *dev) {
if (dev->intnum != 1)
return -1;

if (dev->disconnecting)
return -ENODEV;

ret = __bladerf_snd_cmd(dev, BLADE_USB_CMD_RF_RX, &val, sizeof(val));
if (ret < 0)
goto err_out;
Expand Down Expand Up @@ -285,6 +289,9 @@ static ssize_t bladerf_read(struct file *file, char __user *buf, size_t count, l
return -1;
}

if (dev->disconnecting)
return -ENODEV;

if (!dev->rx_en) {
if (enable_rx(dev)) {
return -EINVAL;
Expand Down Expand Up @@ -365,7 +372,8 @@ static void __bladeRF_write_cb(struct urb *urb)
usb_unanchor_urb(urb);

atomic_dec(&dev->data_out_inflight);
__submit_tx_urb(dev);
if (dev->tx_en)
__submit_tx_urb(dev);
dev->bytes += DATA_BUF_SZ;
wake_up_interruptible(&dev->data_out_wait);
}
Expand Down Expand Up @@ -1040,6 +1048,7 @@ static int bladerf_probe(struct usb_interface *interface,
dev->intnum = 0;
dev->bytes = 0;
dev->debug = 0;
dev->disconnecting = 0;

atomic_set(&dev->data_in_inflight, 0);
atomic_set(&dev->data_out_inflight, 0);
Expand Down Expand Up @@ -1076,6 +1085,13 @@ static void bladerf_disconnect(struct usb_interface *interface)

dev = usb_get_intfdata(interface);

dev->disconnecting = 1;
dev->tx_en = 0;
dev->rx_en = 0;

usb_kill_anchored_urbs(&dev->data_out_anchor);
usb_kill_anchored_urbs(&dev->data_in_anchor);

bladerf_stop(dev);

usb_deregister_dev(interface, &bladerf_class);
Expand Down

0 comments on commit 55c3879

Please sign in to comment.