Merge pull request #185 from dominicgs/remove-kernel-driver
Fix GitHub issue #163 - Detach the kernel driver automatically
This commit is contained in:
@ -69,6 +69,11 @@ typedef enum {
|
||||
HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT = 24,
|
||||
} hackrf_vendor_request;
|
||||
|
||||
typedef enum {
|
||||
USB_CONFIG_STANDARD = 0x1,
|
||||
USB_CONFIG_CPLD_UPDATE = 0x2,
|
||||
} hackrf_usb_configurations;
|
||||
|
||||
typedef enum {
|
||||
HACKRF_TRANSCEIVER_MODE_OFF = 0,
|
||||
HACKRF_TRANSCEIVER_MODE_RECEIVE = 1,
|
||||
@ -233,6 +238,72 @@ static int prepare_transfers(
|
||||
}
|
||||
}
|
||||
|
||||
static int detach_kernel_drivers(libusb_device_handle* usb_device_handle)
|
||||
{
|
||||
int i, num_interfaces, result;
|
||||
libusb_device* dev;
|
||||
struct libusb_config_descriptor* config;
|
||||
|
||||
dev = libusb_get_device(usb_device_handle);
|
||||
result = libusb_get_active_config_descriptor(dev, &config);
|
||||
if( result < 0 )
|
||||
{
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
num_interfaces = config->bNumInterfaces;
|
||||
libusb_free_config_descriptor(config);
|
||||
for(i=0; i<num_interfaces; i++)
|
||||
{
|
||||
result = libusb_kernel_driver_active(usb_device_handle, i);
|
||||
if( result < 0 )
|
||||
{
|
||||
if( result == LIBUSB_ERROR_NOT_SUPPORTED ) {
|
||||
return 0;
|
||||
}
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
} else if( result == 1 ) {
|
||||
result = libusb_detach_kernel_driver(usb_device_handle, i);
|
||||
if( result != 0 )
|
||||
{
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
static int set_hackrf_configuration(libusb_device_handle* usb_device, int config)
|
||||
{
|
||||
int result, curr_config;
|
||||
result = libusb_get_configuration(usb_device, &curr_config);
|
||||
if( result != 0 )
|
||||
{
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
if(curr_config != config)
|
||||
{
|
||||
result = detach_kernel_drivers(usb_device);
|
||||
if( result != 0 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = libusb_set_configuration(usb_device, config);
|
||||
if( result != 0 )
|
||||
{
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
}
|
||||
|
||||
result = detach_kernel_drivers(usb_device);
|
||||
if( result != 0 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@ -410,16 +481,16 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d
|
||||
|
||||
//int speed = libusb_get_device_speed(usb_device);
|
||||
// TODO: Error or warning if not high speed USB?
|
||||
|
||||
result = libusb_set_configuration(usb_device, 1);
|
||||
if( result != 0 )
|
||||
|
||||
result = set_hackrf_configuration(usb_device, USB_CONFIG_STANDARD);
|
||||
if( result != LIBUSB_SUCCESS )
|
||||
{
|
||||
libusb_close(usb_device);
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
return result;
|
||||
}
|
||||
|
||||
result = libusb_claim_interface(usb_device, 0);
|
||||
if( result != 0 )
|
||||
if( result != LIBUSB_SUCCESS )
|
||||
{
|
||||
libusb_close(usb_device);
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
@ -842,9 +913,10 @@ int ADDCALL hackrf_cpld_write(hackrf_device* device,
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
result = libusb_set_configuration(device->usb_device, 2);
|
||||
if (result != LIBUSB_SUCCESS) {
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
result = set_hackrf_configuration(device->usb_device, USB_CONFIG_CPLD_UPDATE);
|
||||
if( result != LIBUSB_SUCCESS )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = libusb_claim_interface(device->usb_device, 0);
|
||||
|
Reference in New Issue
Block a user