aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Karatarakis <alex@karatarakis.com>2017-11-21 01:14:18 -0800
committerGitHub <noreply@github.com>2017-11-21 01:14:18 -0800
commitec4eb5bc06f8516b649ca390cce13cf989ce34fd (patch)
treed2066b97d8608fc29f95ea57d3487b988a45e0e2
parent23932a841e4eb7f82e0587020b6ece8da2c8237e (diff)
parentcd9d32721d4a200cf04520175eaafd84ee1c8f31 (diff)
downloadvcpkg-ec4eb5bc06f8516b649ca390cce13cf989ce34fd.tar.gz
vcpkg-ec4eb5bc06f8516b649ca390cce13cf989ce34fd.zip
Merge pull request #2224 from jasjuang/libusb
[libusb] apply patch to make it libfreenect2 compatible
-rw-r--r--ports/libusb/libfreenect2.patch268
-rw-r--r--ports/libusb/portfile.cmake5
2 files changed, 273 insertions, 0 deletions
diff --git a/ports/libusb/libfreenect2.patch b/ports/libusb/libfreenect2.patch
new file mode 100644
index 000000000..2c2b859b0
--- /dev/null
+++ b/ports/libusb/libfreenect2.patch
@@ -0,0 +1,268 @@
+diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c
+index 93668f3..7fdafd6 100644
+--- a/libusb/os/windows_winusb.c
++++ b/libusb/os/windows_winusb.c
+@@ -66,6 +66,7 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev
+ static int winusbx_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface);
+ static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer);
+ static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
++static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer);
+ static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer);
+ static int winusbx_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
+ static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer);
+@@ -1901,6 +1902,10 @@ void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
+
+ usbi_free_fd(&transfer_priv->pollable_fd);
+ safe_free(transfer_priv->hid_buffer);
++
++ //TODO this should occur during windows_free_transfer instead
++ safe_free(transfer_priv->iso_context);
++
+ // When auto claim is in use, attempt to release the auto-claimed interface
+ auto_release(itransfer);
+ }
+@@ -2274,7 +2279,7 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
+ winusbx_clear_halt,
+ winusbx_reset_device,
+ winusbx_submit_bulk_transfer,
+- unsupported_submit_iso_transfer,
++ winusbx_submit_iso_transfer,
+ winusbx_submit_control_transfer,
+ winusbx_abort_control,
+ winusbx_abort_transfers,
+@@ -2374,6 +2379,8 @@ static int winusbx_init(int sub_api, struct libusb_context *ctx)
+ WinUSBX_Set(SetPipePolicy);
+ WinUSBX_Set(SetPowerPolicy);
+ WinUSBX_Set(WritePipe);
++ WinUSBX_Set(IsoReadPipe);
++ WinUSBX_Set(IsoWritePipe);
+ if (!native_winusb)
+ WinUSBX_Set(ResetDevice);
+
+@@ -2803,6 +2810,100 @@ static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_ha
+ return LIBUSB_SUCCESS;
+ }
+
++static int winusbx_submit_iso_transfer(int sub_api, struct usbi_transfer *itransfer)
++{
++ struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
++ struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
++ struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
++ struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle);
++ struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
++ HANDLE winusb_handle;
++ bool ret;
++ int current_interface;
++ struct winfd wfd;
++ int i;
++ uint16_t maxPacketSize;
++ uint32_t offset;
++ size_t ctx_size;
++
++ CHECK_WINUSBX_AVAILABLE(sub_api);
++
++ if (sub_api != SUB_API_LIBUSBK && sub_api != SUB_API_LIBUSB0)
++ {
++ //iso only supported on libusbk-based backends
++ return unsupported_submit_iso_transfer(sub_api, itransfer);
++ };
++
++ transfer_priv->pollable_fd = INVALID_WINFD;
++
++ current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint);
++ if (current_interface < 0) {
++ usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer");
++ return LIBUSB_ERROR_NOT_FOUND;
++ }
++
++ usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
++
++ winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
++
++ wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
++ // Always use the handle returned from usbi_create_fd (wfd.handle)
++ if (wfd.fd < 0) {
++ return LIBUSB_ERROR_NO_MEM;
++ }
++
++ ctx_size = sizeof(KISO_CONTEXT)+sizeof(KISO_PACKET)* transfer->num_iso_packets;
++ //Init the libusbk iso_context
++ if (!transfer_priv->iso_context)
++ {
++ transfer_priv->iso_context = (PKISO_CONTEXT)malloc(ctx_size);
++ if (!transfer_priv->iso_context)
++ {
++ //TODO does this return leak mem, or does the transfer get cleaned up?
++ return LIBUSB_ERROR_NO_MEM;
++ }
++ }
++ memset(transfer_priv->iso_context, 0, ctx_size);
++
++ //start ASAP
++ transfer_priv->iso_context->StartFrame = 0;
++ transfer_priv->iso_context->NumberOfPackets = transfer->num_iso_packets;
++
++ /* convert the transfer packet lengths to iso_packet offsets */
++ offset = 0;
++ for (i = 0; i < transfer->num_iso_packets; i++)
++ {
++ transfer_priv->iso_context->IsoPackets[i].offset = offset;
++ offset += transfer->iso_packet_desc[i].length;
++ }
++
++ if (IS_XFERIN(transfer)) {
++ usbi_dbg("reading %d iso packets", transfer->num_iso_packets);
++ ret = WinUSBX[sub_api].IsoReadPipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, wfd.overlapped, transfer_priv->iso_context);
++ }
++ else {
++ usbi_dbg("writing %d iso packets", transfer->num_iso_packets);
++ ret = WinUSBX[sub_api].IsoWritePipe(wfd.handle, transfer->endpoint, transfer->buffer, transfer->length, wfd.overlapped, transfer_priv->iso_context);
++ }
++
++ if (!ret) {
++ if (GetLastError() != ERROR_IO_PENDING) {
++ usbi_err(ctx, "IsoReadPipe/IsoWritePipe failed: %s", windows_error_str(0));
++ usbi_free_fd(&wfd);
++ return LIBUSB_ERROR_IO;
++ }
++ }
++ else {
++ wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
++ wfd.overlapped->InternalHigh = (DWORD)transfer->length;
++ }
++
++ transfer_priv->pollable_fd = wfd;
++ transfer_priv->interface_number = (uint8_t)current_interface;
++
++ return LIBUSB_SUCCESS;
++}
++
+ static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer)
+ {
+ struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+@@ -2989,7 +3090,36 @@ static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_ha
+
+ static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size)
+ {
++ struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
++ struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
++ struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
++ int i;
++
++ CHECK_WINUSBX_AVAILABLE(sub_api);
++
++ if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
++ {
++ //for isochronous, need to copy the individual iso packet actual_lengths and statuses
++ if (sub_api == SUB_API_LIBUSBK || sub_api == SUB_API_LIBUSB0)
++ {
++ //iso only supported on libusbk-based backends for now
++
++ for (i = 0; i < transfer->num_iso_packets; i++)
++ {
++ transfer->iso_packet_desc[i].actual_length = transfer_priv->iso_context->IsoPackets[i].actual_length;
++ //TODO translate USDB_STATUS codes http://msdn.microsoft.com/en-us/library/ff539136(VS.85).aspx to libusb_transfer_status
++ //transfer->iso_packet_desc[i].status = transfer_priv->iso_context->IsoPackets[i].status;
++ }
++ }
++ else
++ {
++ //This should only occur if backend is not set correctly or other backend isoc is partially implemented
++ return unsupported_copy_transfer_data(sub_api, itransfer, io_size);
++ }
++ }
++
+ itransfer->transferred += io_size;
++
+ return LIBUSB_TRANSFER_COMPLETED;
+ }
+
+diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h
+index 89ebc24..28a7e4f 100644
+--- a/libusb/os/windows_winusb.h
++++ b/libusb/os/windows_winusb.h
+@@ -154,6 +154,42 @@ struct libusb_hid_descriptor {
+ #define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
+ #define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
+
++
++/* start libusbk_shared.h definitions, must match libusbk_shared.h for isochronous support */
++
++//KISO_PACKET is equivalent of libusb_iso_packet_descriptor except uses absolute "offset" field instead of sequential Lengths
++typedef struct _KISO_PACKET
++{
++ UINT offset;
++ USHORT actual_length; //changed from libusbk_shared.h "Length" for clarity
++ USHORT status;
++
++} KISO_PACKET;
++
++typedef KISO_PACKET* PKISO_PACKET;
++
++typedef enum _KISO_FLAG
++{
++ KISO_FLAG_NONE = 0,
++ KISO_FLAG_SET_START_FRAME = 0x00000001,
++} KISO_FLAG;
++
++//KISO_CONTEXT is the conceptual equivalent of libusb_transfer except is isochronous-specific and must match libusbk's version
++typedef struct _KISO_CONTEXT
++{
++ KISO_FLAG Flags;
++ UINT StartFrame;
++ SHORT ErrorCount;
++ SHORT NumberOfPackets;
++ UINT UrbHdrStatus;
++ KISO_PACKET IsoPackets[0];
++
++} KISO_CONTEXT;
++
++typedef KISO_CONTEXT* PKISO_CONTEXT;
++
++/* end libusbk_shared.h definitions */
++
+ // The following are used for HID reports IOCTLs
+ #define HID_CTL_CODE(id) \
+ CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS)
+@@ -280,6 +316,8 @@ struct windows_transfer_priv {
+ uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
+ uint8_t *hid_dest; // transfer buffer destination, required for HID
+ size_t hid_expected_size;
++ /* Isoc */
++ PKISO_CONTEXT iso_context;
+ };
+
+ // used to match a device driver (including filter drivers) against a supported API
+@@ -623,6 +661,23 @@ typedef BOOL (WINAPI *WinUsb_ResetDevice_t)(
+ WINUSB_INTERFACE_HANDLE InterfaceHandle
+ );
+
++typedef BOOL(WINAPI *WinUsb_IsoReadPipe_t)(
++ WINUSB_INTERFACE_HANDLE InterfaceHandle,
++ UCHAR PipeID,
++ PUCHAR Buffer,
++ ULONG BufferLength,
++ LPOVERLAPPED Overlapped,
++ PKISO_CONTEXT IsoContext
++ );
++typedef BOOL(WINAPI *WinUsb_IsoWritePipe_t)(
++ WINUSB_INTERFACE_HANDLE InterfaceHandle,
++ UCHAR PipeID,
++ PUCHAR Buffer,
++ ULONG BufferLength,
++ LPOVERLAPPED Overlapped,
++ PKISO_CONTEXT IsoContext
++ );
++
+ /* /!\ These must match the ones from the official libusbk.h */
+ typedef enum _KUSB_FNID {
+ KUSB_FNID_Init,
+@@ -703,6 +758,8 @@ struct winusb_interface {
+ WinUsb_SetPowerPolicy_t SetPowerPolicy;
+ WinUsb_WritePipe_t WritePipe;
+ WinUsb_ResetDevice_t ResetDevice;
++ WinUsb_IsoReadPipe_t IsoReadPipe;
++ WinUsb_IsoWritePipe_t IsoWritePipe;
+ };
+
+ /* hid.dll interface */
diff --git a/ports/libusb/portfile.cmake b/ports/libusb/portfile.cmake
index 398fdcfd1..cd99405e6 100644
--- a/ports/libusb/portfile.cmake
+++ b/ports/libusb/portfile.cmake
@@ -16,6 +16,11 @@ vcpkg_from_github(
HEAD_REF master
)
+vcpkg_apply_patches(
+ SOURCE_PATH ${SOURCE_PATH}
+ PATCHES "${CMAKE_CURRENT_LIST_DIR}/libfreenect2.patch"
+)
+
if (TRIPLET_SYSTEM_ARCH MATCHES "x86")
set(MSBUILD_PLATFORM "Win32")
else ()