diff --git a/CMakeLists.txt b/CMakeLists.txt index 09a9cbb..13a7d6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,14 @@ else (INSTALL_UDEV_RULES) message (STATUS "Udev rules not being installed, install them with -DINSTALL_UDEV_RULES=ON") endif (INSTALL_UDEV_RULES) +option(DETACH_KERNEL_DRIVER "Detach kernel driver if loaded" OFF) +if (DETACH_KERNEL_DRIVER) + message (STATUS "Building with kernel driver detaching enabled") + add_definitions(-DDETACH_KERNEL_DRIVER=1) +else (DETACH_KERNEL_DRIVER) + message (STATUS "Building with kernel driver detaching disabled, use -DDETACH_KERNEL_DRIVER=ON to enable") +endif (DETACH_KERNEL_DRIVER) + ######################################################################## # Add subdirectories ######################################################################## diff --git a/configure.ac b/configure.ac index 954d2ef..ce47d89 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,12 @@ AC_TRY_COMPILE([],[], AC_MSG_RESULT(no) CFLAGS="$old_CFLAGS") +AC_ARG_ENABLE(driver-detach, +[ --enable-driver-detach Enable detaching of kernel driver (disabled by default)], +[if test x$enableval = xyes; then + CFLAGS="$CFLAGS -DDETACH_KERNEL_DRIVER" +fi]) + dnl Generate the output AC_CONFIG_HEADER(config.h) diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 2f5d90a..ddebb48 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -1351,12 +1351,22 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) if (libusb_kernel_driver_active(dev->devh, 0) == 1) { dev->driver_active = 1; + +#ifdef DETACH_KERNEL_DRIVER if (!libusb_detach_kernel_driver(dev->devh, 0)) { fprintf(stderr, "Detached kernel driver\n"); } else { fprintf(stderr, "Detaching kernel driver failed!"); goto err; } +#else + fprintf(stderr, "\nKernel driver is active, or device is " + "claimed by second instance of librtlsdr." + "\nIn the first case, please either detach" + " or blacklist the kernel module\n" + "(dvb_usb_rtl28xxu), or enable automatic" + " detaching at compile time.\n\n"); +#endif } r = libusb_claim_interface(dev->devh, 0); @@ -1484,12 +1494,14 @@ int rtlsdr_close(rtlsdr_dev_t *dev) libusb_release_interface(dev->devh, 0); +#ifdef DETACH_KERNEL_DRIVER if (dev->driver_active) { if (!libusb_attach_kernel_driver(dev->devh, 0)) fprintf(stderr, "Reattached kernel driver\n"); else fprintf(stderr, "Reattaching kernel driver failed!\n"); } +#endif libusb_close(dev->devh);