Urbrdc fix (#7417)
* fix libusb libusb_device usage (manually unref required usb devices, versus freeing all when we still hold references to the ones we want) * disabled detach_kernel_driver & attach_kernel_driver on win32 since libusb does not support them * fixed libusb async event handling * add log for transfer request error * Update libusb_udevice.c * refactor code
This commit is contained in:
parent
68eb6e4afc
commit
21ca4a009d
@ -1752,6 +1752,13 @@ static UINT urbdrc_process_transfer_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLB
|
||||
break;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_WARN,
|
||||
"USB transfer request URB Function %08" PRIx32 " failed with %08" PRIx32,
|
||||
URB_Function, error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -501,17 +501,19 @@ static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_n
|
||||
|
||||
for (i = 0; i < total_device; i++)
|
||||
{
|
||||
uint8_t cbus = libusb_get_bus_number(libusb_list[i]);
|
||||
uint8_t caddr = libusb_get_device_address(libusb_list[i]);
|
||||
|
||||
if ((bus_number == cbus) && (dev_number == caddr))
|
||||
LIBUSB_DEVICE* dev = libusb_list[i];
|
||||
if ((bus_number == libusb_get_bus_number(dev)) &&
|
||||
(dev_number == libusb_get_device_address(dev)))
|
||||
{
|
||||
device = libusb_list[i];
|
||||
break;
|
||||
device = dev;
|
||||
}
|
||||
else
|
||||
{
|
||||
libusb_unref_device(dev);
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(libusb_list, 1);
|
||||
libusb_free_device_list(libusb_list, 0);
|
||||
return device;
|
||||
}
|
||||
|
||||
@ -533,7 +535,6 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(URBDRC_PLUGIN* urbdrc, LIBUSB
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting)
|
||||
{
|
||||
int error = 0, diff = 0;
|
||||
@ -1023,6 +1024,9 @@ static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
|
||||
if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _WIN32
|
||||
return TRUE;
|
||||
#else
|
||||
urbdrc = pdev->urbdrc;
|
||||
|
||||
if ((pdev->status & URBDRC_DEVICE_DETACH_KERNEL) == 0)
|
||||
@ -1043,6 +1047,7 @@ static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev)
|
||||
@ -1059,12 +1064,14 @@ static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev)
|
||||
|
||||
log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_release_interface", err);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (err != LIBUSB_ERROR_NO_DEVICE)
|
||||
{
|
||||
err = libusb_attach_kernel_driver(pdev->libusb_handle, i);
|
||||
log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_attach_kernel_driver if=%d",
|
||||
err, i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1485,6 +1492,7 @@ static void udev_free(IUDEVICE* idev)
|
||||
ArrayList_Free(udev->request_queue);
|
||||
/* free the config descriptor that send from windows */
|
||||
msusb_msconfig_free(udev->MsConfig);
|
||||
libusb_unref_device(udev->libusb_dev);
|
||||
libusb_close(udev->libusb_handle);
|
||||
libusb_close(udev->hub_handle);
|
||||
free(udev->devDescriptor);
|
||||
@ -1533,8 +1541,8 @@ static void udev_load_interface(UDEVICE* pdev)
|
||||
pdev->iface.free = udev_free;
|
||||
}
|
||||
|
||||
static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev,
|
||||
UINT16 bus_number, UINT16 dev_number)
|
||||
static int udev_get_device_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev,
|
||||
UINT16 bus_number, UINT16 dev_number)
|
||||
{
|
||||
int error;
|
||||
ssize_t i, total_device;
|
||||
@ -1546,21 +1554,19 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI
|
||||
|
||||
for (i = 0; i < total_device; i++)
|
||||
{
|
||||
LIBUSB_DEVICE_HANDLE* handle;
|
||||
uint8_t cbus = libusb_get_bus_number(libusb_list[i]);
|
||||
uint8_t caddr = libusb_get_device_address(libusb_list[i]);
|
||||
LIBUSB_DEVICE* dev = libusb_list[i];
|
||||
|
||||
if ((bus_number != cbus) || (dev_number != caddr))
|
||||
if ((bus_number != libusb_get_bus_number(dev)) ||
|
||||
(dev_number != libusb_get_device_address(dev)))
|
||||
continue;
|
||||
|
||||
error = libusb_open(libusb_list[i], &handle);
|
||||
error = libusb_open(dev, &pdev->libusb_handle);
|
||||
|
||||
if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
|
||||
break;
|
||||
|
||||
/* get port number */
|
||||
error = libusb_get_port_numbers(libusb_list[i], port_numbers, sizeof(port_numbers));
|
||||
libusb_close(handle);
|
||||
error = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers));
|
||||
|
||||
if (error < 1)
|
||||
{
|
||||
@ -1578,29 +1584,40 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, " DevPath: %s", pdev->path);
|
||||
break;
|
||||
}
|
||||
libusb_free_device_list(libusb_list, 1);
|
||||
|
||||
if (error < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev,
|
||||
UINT16 bus_number, UINT16 dev_number)
|
||||
{
|
||||
int error;
|
||||
ssize_t i, total_device;
|
||||
LIBUSB_DEVICE** libusb_list;
|
||||
LIBUSB_DEVICE_HANDLE* handle;
|
||||
total_device = libusb_get_device_list(ctx, &libusb_list);
|
||||
|
||||
/* Look for device hub. */
|
||||
if (error == 0)
|
||||
error = -1;
|
||||
|
||||
for (i = 0; i < total_device; i++)
|
||||
{
|
||||
error = -1;
|
||||
LIBUSB_DEVICE* dev = libusb_list[i];
|
||||
|
||||
for (i = 0; i < total_device; i++)
|
||||
{
|
||||
LIBUSB_DEVICE_HANDLE* handle;
|
||||
uint8_t cbus = libusb_get_bus_number(libusb_list[i]);
|
||||
uint8_t caddr = libusb_get_device_address(libusb_list[i]);
|
||||
if ((bus_number != libusb_get_bus_number(dev)) ||
|
||||
(1 != libusb_get_device_address(dev))) /* Root hub allways first on bus. */
|
||||
continue;
|
||||
|
||||
if ((bus_number != cbus) || (1 != caddr)) /* Root hub allways first on bus. */
|
||||
continue;
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number);
|
||||
error = libusb_open(dev, &handle);
|
||||
|
||||
WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number);
|
||||
error = libusb_open(libusb_list[i], &handle);
|
||||
if (!log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
|
||||
pdev->hub_handle = handle;
|
||||
|
||||
if (!log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
|
||||
pdev->hub_handle = handle;
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
libusb_free_device_list(libusb_list, 1);
|
||||
@ -1651,30 +1668,26 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUS
|
||||
if (urbdrc->listener_callback)
|
||||
udev_set_channelManager(&pdev->iface, urbdrc->listener_callback->channel_mgr);
|
||||
|
||||
/* Get DEVICE handle */
|
||||
status = udev_get_device_handle(urbdrc, context, pdev, bus_number, dev_number);
|
||||
if (status != LIBUSB_SUCCESS)
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
const uint8_t port = libusb_get_port_number(pdev->libusb_dev);
|
||||
libusb_get_device_descriptor(pdev->libusb_dev, &desc);
|
||||
|
||||
log_libusb_result(urbdrc->log, WLOG_ERROR,
|
||||
"libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]", status,
|
||||
bus_number, port, dev_number, desc.idVendor, desc.idProduct);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get HUB handle */
|
||||
status = udev_get_hub_handle(urbdrc, context, pdev, bus_number, dev_number);
|
||||
|
||||
if (status < 0)
|
||||
pdev->hub_handle = NULL;
|
||||
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
const uint8_t bus = libusb_get_bus_number(pdev->libusb_dev);
|
||||
const uint8_t port = libusb_get_port_number(pdev->libusb_dev);
|
||||
const uint8_t addr = libusb_get_device_address(pdev->libusb_dev);
|
||||
libusb_get_device_descriptor(pdev->libusb_dev, &desc);
|
||||
|
||||
status = libusb_open(pdev->libusb_dev, &pdev->libusb_handle);
|
||||
|
||||
if (status != LIBUSB_SUCCESS)
|
||||
{
|
||||
log_libusb_result(urbdrc->log, WLOG_ERROR,
|
||||
"libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]",
|
||||
status, bus, port, addr, desc.idVendor, desc.idProduct);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
pdev->devDescriptor = udev_new_descript(urbdrc, pdev->libusb_dev);
|
||||
|
||||
if (!pdev->devDescriptor)
|
||||
@ -1745,8 +1758,6 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendo
|
||||
{
|
||||
LIBUSB_DEVICE** libusb_list;
|
||||
UDEVICE** array;
|
||||
UINT16 bus_number;
|
||||
UINT16 dev_number;
|
||||
ssize_t i, total_device;
|
||||
size_t num = 0;
|
||||
|
||||
@ -1763,23 +1774,27 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendo
|
||||
|
||||
for (i = 0; i < total_device; i++)
|
||||
{
|
||||
LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, libusb_list[i]);
|
||||
LIBUSB_DEVICE* dev = libusb_list[i];
|
||||
LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, dev);
|
||||
|
||||
if ((descriptor->idVendor == idVendor) && (descriptor->idProduct == idProduct))
|
||||
{
|
||||
bus_number = libusb_get_bus_number(libusb_list[i]);
|
||||
dev_number = libusb_get_device_address(libusb_list[i]);
|
||||
array[num] = (PUDEVICE)udev_init(urbdrc, ctx, libusb_list[i], bus_number, dev_number);
|
||||
array[num] = (PUDEVICE)udev_init(urbdrc, ctx, dev, libusb_get_bus_number(dev),
|
||||
libusb_get_device_address(dev));
|
||||
|
||||
if (array[num] != NULL)
|
||||
num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
libusb_unref_device(dev);
|
||||
}
|
||||
|
||||
free(descriptor);
|
||||
}
|
||||
|
||||
fail:
|
||||
libusb_free_device_list(libusb_list, 1);
|
||||
libusb_free_device_list(libusb_list, 0);
|
||||
*devArray = (IUDEVICE**)array;
|
||||
return num;
|
||||
}
|
||||
|
@ -195,6 +195,12 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
|
||||
/* register all device that match pid vid */
|
||||
num = udev_new_by_id(urbdrc, udevman->context, idVendor, idProduct, &devArray);
|
||||
|
||||
if (num == 0)
|
||||
{
|
||||
WLog_Print(urbdrc->log, WLOG_WARN,
|
||||
"Could not find or redirect any usb devices by id %04x:%04x", idVendor, idProduct);
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
UINT32 id;
|
||||
@ -835,7 +841,7 @@ static BOOL poll_libusb_events(UDEVMAN* udevman)
|
||||
{
|
||||
int rc = LIBUSB_SUCCESS;
|
||||
struct timeval tv = { 0, 500 };
|
||||
if (libusb_try_lock_events(udevman->context))
|
||||
if (libusb_try_lock_events(udevman->context) == 0)
|
||||
{
|
||||
if (libusb_event_handling_ok(udevman->context))
|
||||
{
|
||||
@ -924,7 +930,7 @@ UINT freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS
|
||||
udevman->next_device_id = BASE_USBDEVICE_NUM;
|
||||
udevman->iface.plugin = pEntryPoints->plugin;
|
||||
rc = libusb_init(&udevman->context);
|
||||
|
||||
|
||||
if (rc != LIBUSB_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user