Merge pull request #185 from dominicgs/remove-kernel-driver

Fix GitHub issue #163 - Detach the kernel driver automatically
This commit is contained in:
Michael Ossmann
2015-06-29 12:00:58 -06:00

View File

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