xref: /aosp_15_r20/external/libusb/libusb/os/windows_usbdk.c (revision 86b64dcb59b3a0b37502ecd56e119234366a6f7e)
1*86b64dcbSAndroid Build Coastguard Worker /*
2*86b64dcbSAndroid Build Coastguard Worker  * windows UsbDk backend for libusb 1.0
3*86b64dcbSAndroid Build Coastguard Worker  * Copyright © 2014 Red Hat, Inc.
4*86b64dcbSAndroid Build Coastguard Worker 
5*86b64dcbSAndroid Build Coastguard Worker  * Authors:
6*86b64dcbSAndroid Build Coastguard Worker  * Dmitry Fleytman <[email protected]>
7*86b64dcbSAndroid Build Coastguard Worker  * Pavel Gurvich <[email protected]>
8*86b64dcbSAndroid Build Coastguard Worker  *
9*86b64dcbSAndroid Build Coastguard Worker  * This library is free software; you can redistribute it and/or
10*86b64dcbSAndroid Build Coastguard Worker  * modify it under the terms of the GNU Lesser General Public
11*86b64dcbSAndroid Build Coastguard Worker  * License as published by the Free Software Foundation; either
12*86b64dcbSAndroid Build Coastguard Worker  * version 2.1 of the License, or (at your option) any later version.
13*86b64dcbSAndroid Build Coastguard Worker  *
14*86b64dcbSAndroid Build Coastguard Worker  * This library is distributed in the hope that it will be useful,
15*86b64dcbSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16*86b64dcbSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17*86b64dcbSAndroid Build Coastguard Worker  * Lesser General Public License for more details.
18*86b64dcbSAndroid Build Coastguard Worker  *
19*86b64dcbSAndroid Build Coastguard Worker  * You should have received a copy of the GNU Lesser General Public
20*86b64dcbSAndroid Build Coastguard Worker  * License along with this library; if not, write to the Free Software
21*86b64dcbSAndroid Build Coastguard Worker  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22*86b64dcbSAndroid Build Coastguard Worker  */
23*86b64dcbSAndroid Build Coastguard Worker 
24*86b64dcbSAndroid Build Coastguard Worker #include <config.h>
25*86b64dcbSAndroid Build Coastguard Worker 
26*86b64dcbSAndroid Build Coastguard Worker #include <windows.h>
27*86b64dcbSAndroid Build Coastguard Worker #include <stdio.h>
28*86b64dcbSAndroid Build Coastguard Worker 
29*86b64dcbSAndroid Build Coastguard Worker #include "libusbi.h"
30*86b64dcbSAndroid Build Coastguard Worker #include "windows_usbdk.h"
31*86b64dcbSAndroid Build Coastguard Worker 
32*86b64dcbSAndroid Build Coastguard Worker #if !defined(STATUS_SUCCESS)
33*86b64dcbSAndroid Build Coastguard Worker typedef LONG NTSTATUS;
34*86b64dcbSAndroid Build Coastguard Worker #define STATUS_SUCCESS			((NTSTATUS)0x00000000L)
35*86b64dcbSAndroid Build Coastguard Worker #endif
36*86b64dcbSAndroid Build Coastguard Worker 
37*86b64dcbSAndroid Build Coastguard Worker #if !defined(STATUS_CANCELLED)
38*86b64dcbSAndroid Build Coastguard Worker #define STATUS_CANCELLED		((NTSTATUS)0xC0000120L)
39*86b64dcbSAndroid Build Coastguard Worker #endif
40*86b64dcbSAndroid Build Coastguard Worker 
41*86b64dcbSAndroid Build Coastguard Worker #if !defined(STATUS_REQUEST_CANCELED)
42*86b64dcbSAndroid Build Coastguard Worker #define STATUS_REQUEST_CANCELED		((NTSTATUS)0xC0000703L)
43*86b64dcbSAndroid Build Coastguard Worker #endif
44*86b64dcbSAndroid Build Coastguard Worker 
45*86b64dcbSAndroid Build Coastguard Worker static struct {
46*86b64dcbSAndroid Build Coastguard Worker 	HMODULE module;
47*86b64dcbSAndroid Build Coastguard Worker 
48*86b64dcbSAndroid Build Coastguard Worker 	USBDK_GET_DEVICES_LIST			GetDevicesList;
49*86b64dcbSAndroid Build Coastguard Worker 	USBDK_RELEASE_DEVICES_LIST		ReleaseDevicesList;
50*86b64dcbSAndroid Build Coastguard Worker 	USBDK_START_REDIRECT			StartRedirect;
51*86b64dcbSAndroid Build Coastguard Worker 	USBDK_STOP_REDIRECT			StopRedirect;
52*86b64dcbSAndroid Build Coastguard Worker 	USBDK_GET_CONFIGURATION_DESCRIPTOR	GetConfigurationDescriptor;
53*86b64dcbSAndroid Build Coastguard Worker 	USBDK_RELEASE_CONFIGURATION_DESCRIPTOR	ReleaseConfigurationDescriptor;
54*86b64dcbSAndroid Build Coastguard Worker 	USBDK_READ_PIPE				ReadPipe;
55*86b64dcbSAndroid Build Coastguard Worker 	USBDK_WRITE_PIPE			WritePipe;
56*86b64dcbSAndroid Build Coastguard Worker 	USBDK_ABORT_PIPE			AbortPipe;
57*86b64dcbSAndroid Build Coastguard Worker 	USBDK_RESET_PIPE			ResetPipe;
58*86b64dcbSAndroid Build Coastguard Worker 	USBDK_SET_ALTSETTING			SetAltsetting;
59*86b64dcbSAndroid Build Coastguard Worker 	USBDK_RESET_DEVICE			ResetDevice;
60*86b64dcbSAndroid Build Coastguard Worker 	USBDK_GET_REDIRECTOR_SYSTEM_HANDLE	GetRedirectorSystemHandle;
61*86b64dcbSAndroid Build Coastguard Worker } usbdk_helper;
62*86b64dcbSAndroid Build Coastguard Worker 
get_usbdk_proc_addr(struct libusb_context * ctx,LPCSTR api_name)63*86b64dcbSAndroid Build Coastguard Worker static FARPROC get_usbdk_proc_addr(struct libusb_context *ctx, LPCSTR api_name)
64*86b64dcbSAndroid Build Coastguard Worker {
65*86b64dcbSAndroid Build Coastguard Worker 	FARPROC api_ptr = GetProcAddress(usbdk_helper.module, api_name);
66*86b64dcbSAndroid Build Coastguard Worker 
67*86b64dcbSAndroid Build Coastguard Worker 	if (api_ptr == NULL)
68*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(ctx, "UsbDkHelper API %s not found: %s", api_name, windows_error_str(0));
69*86b64dcbSAndroid Build Coastguard Worker 
70*86b64dcbSAndroid Build Coastguard Worker 	return api_ptr;
71*86b64dcbSAndroid Build Coastguard Worker }
72*86b64dcbSAndroid Build Coastguard Worker 
unload_usbdk_helper_dll(void)73*86b64dcbSAndroid Build Coastguard Worker static void unload_usbdk_helper_dll(void)
74*86b64dcbSAndroid Build Coastguard Worker {
75*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.module != NULL) {
76*86b64dcbSAndroid Build Coastguard Worker 		FreeLibrary(usbdk_helper.module);
77*86b64dcbSAndroid Build Coastguard Worker 		usbdk_helper.module = NULL;
78*86b64dcbSAndroid Build Coastguard Worker 	}
79*86b64dcbSAndroid Build Coastguard Worker }
80*86b64dcbSAndroid Build Coastguard Worker 
load_usbdk_helper_dll(struct libusb_context * ctx)81*86b64dcbSAndroid Build Coastguard Worker static int load_usbdk_helper_dll(struct libusb_context *ctx)
82*86b64dcbSAndroid Build Coastguard Worker {
83*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.module = load_system_library(ctx, "UsbDkHelper");
84*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.module == NULL) {
85*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(ctx, "Failed to load UsbDkHelper.dll: %s", windows_error_str(0));
86*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NOT_FOUND;
87*86b64dcbSAndroid Build Coastguard Worker 	}
88*86b64dcbSAndroid Build Coastguard Worker 
89*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.GetDevicesList = (USBDK_GET_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_GetDevicesList");
90*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.GetDevicesList == NULL)
91*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
92*86b64dcbSAndroid Build Coastguard Worker 
93*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.ReleaseDevicesList = (USBDK_RELEASE_DEVICES_LIST)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseDevicesList");
94*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.ReleaseDevicesList == NULL)
95*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
96*86b64dcbSAndroid Build Coastguard Worker 
97*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.StartRedirect = (USBDK_START_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StartRedirect");
98*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.StartRedirect == NULL)
99*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
100*86b64dcbSAndroid Build Coastguard Worker 
101*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.StopRedirect = (USBDK_STOP_REDIRECT)get_usbdk_proc_addr(ctx, "UsbDk_StopRedirect");
102*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.StopRedirect == NULL)
103*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
104*86b64dcbSAndroid Build Coastguard Worker 
105*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.GetConfigurationDescriptor = (USBDK_GET_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_GetConfigurationDescriptor");
106*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.GetConfigurationDescriptor == NULL)
107*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
108*86b64dcbSAndroid Build Coastguard Worker 
109*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.ReleaseConfigurationDescriptor = (USBDK_RELEASE_CONFIGURATION_DESCRIPTOR)get_usbdk_proc_addr(ctx, "UsbDk_ReleaseConfigurationDescriptor");
110*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.ReleaseConfigurationDescriptor == NULL)
111*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
112*86b64dcbSAndroid Build Coastguard Worker 
113*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.ReadPipe = (USBDK_READ_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ReadPipe");
114*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.ReadPipe == NULL)
115*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
116*86b64dcbSAndroid Build Coastguard Worker 
117*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.WritePipe = (USBDK_WRITE_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_WritePipe");
118*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.WritePipe == NULL)
119*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
120*86b64dcbSAndroid Build Coastguard Worker 
121*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.AbortPipe = (USBDK_ABORT_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_AbortPipe");
122*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.AbortPipe == NULL)
123*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
124*86b64dcbSAndroid Build Coastguard Worker 
125*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.ResetPipe = (USBDK_RESET_PIPE)get_usbdk_proc_addr(ctx, "UsbDk_ResetPipe");
126*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.ResetPipe == NULL)
127*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
128*86b64dcbSAndroid Build Coastguard Worker 
129*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.SetAltsetting = (USBDK_SET_ALTSETTING)get_usbdk_proc_addr(ctx, "UsbDk_SetAltsetting");
130*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.SetAltsetting == NULL)
131*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
132*86b64dcbSAndroid Build Coastguard Worker 
133*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.ResetDevice = (USBDK_RESET_DEVICE)get_usbdk_proc_addr(ctx, "UsbDk_ResetDevice");
134*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.ResetDevice == NULL)
135*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
136*86b64dcbSAndroid Build Coastguard Worker 
137*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.GetRedirectorSystemHandle = (USBDK_GET_REDIRECTOR_SYSTEM_HANDLE)get_usbdk_proc_addr(ctx, "UsbDk_GetRedirectorSystemHandle");
138*86b64dcbSAndroid Build Coastguard Worker 	if (usbdk_helper.GetRedirectorSystemHandle == NULL)
139*86b64dcbSAndroid Build Coastguard Worker 		goto error_unload;
140*86b64dcbSAndroid Build Coastguard Worker 
141*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
142*86b64dcbSAndroid Build Coastguard Worker 
143*86b64dcbSAndroid Build Coastguard Worker error_unload:
144*86b64dcbSAndroid Build Coastguard Worker 	FreeLibrary(usbdk_helper.module);
145*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.module = NULL;
146*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_ERROR_NOT_FOUND;
147*86b64dcbSAndroid Build Coastguard Worker }
148*86b64dcbSAndroid Build Coastguard Worker 
149*86b64dcbSAndroid Build Coastguard Worker typedef SC_HANDLE (WINAPI *POPENSCMANAGERA)(LPCSTR, LPCSTR, DWORD);
150*86b64dcbSAndroid Build Coastguard Worker typedef SC_HANDLE (WINAPI *POPENSERVICEA)(SC_HANDLE, LPCSTR, DWORD);
151*86b64dcbSAndroid Build Coastguard Worker typedef BOOL (WINAPI *PCLOSESERVICEHANDLE)(SC_HANDLE);
152*86b64dcbSAndroid Build Coastguard Worker 
usbdk_init(struct libusb_context * ctx)153*86b64dcbSAndroid Build Coastguard Worker static int usbdk_init(struct libusb_context *ctx)
154*86b64dcbSAndroid Build Coastguard Worker {
155*86b64dcbSAndroid Build Coastguard Worker 	POPENSCMANAGERA pOpenSCManagerA;
156*86b64dcbSAndroid Build Coastguard Worker 	POPENSERVICEA pOpenServiceA;
157*86b64dcbSAndroid Build Coastguard Worker 	PCLOSESERVICEHANDLE pCloseServiceHandle;
158*86b64dcbSAndroid Build Coastguard Worker 	SC_HANDLE managerHandle;
159*86b64dcbSAndroid Build Coastguard Worker 	SC_HANDLE serviceHandle;
160*86b64dcbSAndroid Build Coastguard Worker 	HMODULE h;
161*86b64dcbSAndroid Build Coastguard Worker 
162*86b64dcbSAndroid Build Coastguard Worker 	h = load_system_library(ctx, "Advapi32");
163*86b64dcbSAndroid Build Coastguard Worker 	if (h == NULL) {
164*86b64dcbSAndroid Build Coastguard Worker 		usbi_warn(ctx, "failed to open Advapi32\n");
165*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_OTHER;
166*86b64dcbSAndroid Build Coastguard Worker 	}
167*86b64dcbSAndroid Build Coastguard Worker 
168*86b64dcbSAndroid Build Coastguard Worker 	pOpenSCManagerA = (POPENSCMANAGERA)GetProcAddress(h, "OpenSCManagerA");
169*86b64dcbSAndroid Build Coastguard Worker 	if (pOpenSCManagerA == NULL) {
170*86b64dcbSAndroid Build Coastguard Worker 		usbi_warn(ctx, "failed to find %s in Advapi32\n", "OpenSCManagerA");
171*86b64dcbSAndroid Build Coastguard Worker 		goto error_free_library;
172*86b64dcbSAndroid Build Coastguard Worker 	}
173*86b64dcbSAndroid Build Coastguard Worker 	pOpenServiceA = (POPENSERVICEA)GetProcAddress(h, "OpenServiceA");
174*86b64dcbSAndroid Build Coastguard Worker 	if (pOpenServiceA == NULL) {
175*86b64dcbSAndroid Build Coastguard Worker 		usbi_warn(ctx, "failed to find %s in Advapi32\n", "OpenServiceA");
176*86b64dcbSAndroid Build Coastguard Worker 		goto error_free_library;
177*86b64dcbSAndroid Build Coastguard Worker 	}
178*86b64dcbSAndroid Build Coastguard Worker 	pCloseServiceHandle = (PCLOSESERVICEHANDLE)GetProcAddress(h, "CloseServiceHandle");
179*86b64dcbSAndroid Build Coastguard Worker 	if (pCloseServiceHandle == NULL) {
180*86b64dcbSAndroid Build Coastguard Worker 		usbi_warn(ctx, "failed to find %s in Advapi32\n", "CloseServiceHandle");
181*86b64dcbSAndroid Build Coastguard Worker 		goto error_free_library;
182*86b64dcbSAndroid Build Coastguard Worker 	}
183*86b64dcbSAndroid Build Coastguard Worker 
184*86b64dcbSAndroid Build Coastguard Worker 	managerHandle = pOpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
185*86b64dcbSAndroid Build Coastguard Worker 	if (managerHandle == NULL) {
186*86b64dcbSAndroid Build Coastguard Worker 		usbi_warn(ctx, "failed to open service control manager: %s", windows_error_str(0));
187*86b64dcbSAndroid Build Coastguard Worker 		goto error_free_library;
188*86b64dcbSAndroid Build Coastguard Worker 	}
189*86b64dcbSAndroid Build Coastguard Worker 
190*86b64dcbSAndroid Build Coastguard Worker 	serviceHandle = pOpenServiceA(managerHandle, "UsbDk", GENERIC_READ);
191*86b64dcbSAndroid Build Coastguard Worker 	pCloseServiceHandle(managerHandle);
192*86b64dcbSAndroid Build Coastguard Worker 
193*86b64dcbSAndroid Build Coastguard Worker 	if (serviceHandle == NULL) {
194*86b64dcbSAndroid Build Coastguard Worker 		if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
195*86b64dcbSAndroid Build Coastguard Worker 			usbi_warn(ctx, "failed to open UsbDk service: %s", windows_error_str(0));
196*86b64dcbSAndroid Build Coastguard Worker 		FreeLibrary(h);
197*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NOT_FOUND;
198*86b64dcbSAndroid Build Coastguard Worker 	}
199*86b64dcbSAndroid Build Coastguard Worker 
200*86b64dcbSAndroid Build Coastguard Worker 	pCloseServiceHandle(serviceHandle);
201*86b64dcbSAndroid Build Coastguard Worker 	FreeLibrary(h);
202*86b64dcbSAndroid Build Coastguard Worker 
203*86b64dcbSAndroid Build Coastguard Worker 	return load_usbdk_helper_dll(ctx);
204*86b64dcbSAndroid Build Coastguard Worker 
205*86b64dcbSAndroid Build Coastguard Worker error_free_library:
206*86b64dcbSAndroid Build Coastguard Worker 	FreeLibrary(h);
207*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_ERROR_OTHER;
208*86b64dcbSAndroid Build Coastguard Worker }
209*86b64dcbSAndroid Build Coastguard Worker 
usbdk_exit(struct libusb_context * ctx)210*86b64dcbSAndroid Build Coastguard Worker static void usbdk_exit(struct libusb_context *ctx)
211*86b64dcbSAndroid Build Coastguard Worker {
212*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(ctx);
213*86b64dcbSAndroid Build Coastguard Worker 	unload_usbdk_helper_dll();
214*86b64dcbSAndroid Build Coastguard Worker }
215*86b64dcbSAndroid Build Coastguard Worker 
usbdk_get_session_id_for_device(struct libusb_context * ctx,PUSB_DK_DEVICE_ID id,unsigned long * session_id)216*86b64dcbSAndroid Build Coastguard Worker static int usbdk_get_session_id_for_device(struct libusb_context *ctx,
217*86b64dcbSAndroid Build Coastguard Worker 	PUSB_DK_DEVICE_ID id, unsigned long *session_id)
218*86b64dcbSAndroid Build Coastguard Worker {
219*86b64dcbSAndroid Build Coastguard Worker 	char dev_identity[ARRAYSIZE(id->DeviceID) + ARRAYSIZE(id->InstanceID) + 1];
220*86b64dcbSAndroid Build Coastguard Worker 
221*86b64dcbSAndroid Build Coastguard Worker 	if (snprintf(dev_identity, sizeof(dev_identity), "%S%S", id->DeviceID, id->InstanceID) == -1) {
222*86b64dcbSAndroid Build Coastguard Worker 		usbi_warn(ctx, "cannot form device identity");
223*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NOT_SUPPORTED;
224*86b64dcbSAndroid Build Coastguard Worker 	}
225*86b64dcbSAndroid Build Coastguard Worker 
226*86b64dcbSAndroid Build Coastguard Worker 	*session_id = htab_hash(dev_identity);
227*86b64dcbSAndroid Build Coastguard Worker 
228*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
229*86b64dcbSAndroid Build Coastguard Worker }
230*86b64dcbSAndroid Build Coastguard Worker 
usbdk_release_config_descriptors(struct usbdk_device_priv * priv,uint8_t count)231*86b64dcbSAndroid Build Coastguard Worker static void usbdk_release_config_descriptors(struct usbdk_device_priv *priv, uint8_t count)
232*86b64dcbSAndroid Build Coastguard Worker {
233*86b64dcbSAndroid Build Coastguard Worker 	uint8_t i;
234*86b64dcbSAndroid Build Coastguard Worker 
235*86b64dcbSAndroid Build Coastguard Worker 	for (i = 0; i < count; i++)
236*86b64dcbSAndroid Build Coastguard Worker 		usbdk_helper.ReleaseConfigurationDescriptor(priv->config_descriptors[i]);
237*86b64dcbSAndroid Build Coastguard Worker 
238*86b64dcbSAndroid Build Coastguard Worker 	free(priv->config_descriptors);
239*86b64dcbSAndroid Build Coastguard Worker 	priv->config_descriptors = NULL;
240*86b64dcbSAndroid Build Coastguard Worker }
241*86b64dcbSAndroid Build Coastguard Worker 
usbdk_cache_config_descriptors(struct libusb_context * ctx,struct usbdk_device_priv * priv,PUSB_DK_DEVICE_INFO info)242*86b64dcbSAndroid Build Coastguard Worker static int usbdk_cache_config_descriptors(struct libusb_context *ctx,
243*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv, PUSB_DK_DEVICE_INFO info)
244*86b64dcbSAndroid Build Coastguard Worker {
245*86b64dcbSAndroid Build Coastguard Worker 	uint8_t i;
246*86b64dcbSAndroid Build Coastguard Worker 	USB_DK_CONFIG_DESCRIPTOR_REQUEST Request;
247*86b64dcbSAndroid Build Coastguard Worker 	Request.ID = info->ID;
248*86b64dcbSAndroid Build Coastguard Worker 
249*86b64dcbSAndroid Build Coastguard Worker 	priv->config_descriptors = calloc(info->DeviceDescriptor.bNumConfigurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR));
250*86b64dcbSAndroid Build Coastguard Worker 	if (priv->config_descriptors == NULL) {
251*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(ctx, "failed to allocate configuration descriptors holder");
252*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NO_MEM;
253*86b64dcbSAndroid Build Coastguard Worker 	}
254*86b64dcbSAndroid Build Coastguard Worker 
255*86b64dcbSAndroid Build Coastguard Worker 	for (i = 0; i < info->DeviceDescriptor.bNumConfigurations; i++) {
256*86b64dcbSAndroid Build Coastguard Worker 		ULONG Length;
257*86b64dcbSAndroid Build Coastguard Worker 
258*86b64dcbSAndroid Build Coastguard Worker 		Request.Index = i;
259*86b64dcbSAndroid Build Coastguard Worker 		if (!usbdk_helper.GetConfigurationDescriptor(&Request, &priv->config_descriptors[i], &Length)) {
260*86b64dcbSAndroid Build Coastguard Worker 			usbi_err(ctx, "failed to retrieve configuration descriptors");
261*86b64dcbSAndroid Build Coastguard Worker 			usbdk_release_config_descriptors(priv, i);
262*86b64dcbSAndroid Build Coastguard Worker 			return LIBUSB_ERROR_OTHER;
263*86b64dcbSAndroid Build Coastguard Worker 		}
264*86b64dcbSAndroid Build Coastguard Worker 	}
265*86b64dcbSAndroid Build Coastguard Worker 
266*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
267*86b64dcbSAndroid Build Coastguard Worker }
268*86b64dcbSAndroid Build Coastguard Worker 
usbdk_device_priv_init(struct libusb_context * ctx,struct libusb_device * dev,PUSB_DK_DEVICE_INFO info)269*86b64dcbSAndroid Build Coastguard Worker static inline int usbdk_device_priv_init(struct libusb_context *ctx, struct libusb_device *dev, PUSB_DK_DEVICE_INFO info)
270*86b64dcbSAndroid Build Coastguard Worker {
271*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev);
272*86b64dcbSAndroid Build Coastguard Worker 
273*86b64dcbSAndroid Build Coastguard Worker 	priv->ID = info->ID;
274*86b64dcbSAndroid Build Coastguard Worker 	priv->active_configuration = 0;
275*86b64dcbSAndroid Build Coastguard Worker 
276*86b64dcbSAndroid Build Coastguard Worker 	return usbdk_cache_config_descriptors(ctx, priv, info);
277*86b64dcbSAndroid Build Coastguard Worker }
278*86b64dcbSAndroid Build Coastguard Worker 
usbdk_device_init(struct libusb_device * dev,PUSB_DK_DEVICE_INFO info)279*86b64dcbSAndroid Build Coastguard Worker static void usbdk_device_init(struct libusb_device *dev, PUSB_DK_DEVICE_INFO info)
280*86b64dcbSAndroid Build Coastguard Worker {
281*86b64dcbSAndroid Build Coastguard Worker 	dev->bus_number = (uint8_t)info->FilterID;
282*86b64dcbSAndroid Build Coastguard Worker 	dev->port_number = (uint8_t)info->Port;
283*86b64dcbSAndroid Build Coastguard Worker 	dev->parent_dev = NULL;
284*86b64dcbSAndroid Build Coastguard Worker 
285*86b64dcbSAndroid Build Coastguard Worker 	// Addresses in libusb are 1-based
286*86b64dcbSAndroid Build Coastguard Worker 	dev->device_address = (uint8_t)(info->Port + 1);
287*86b64dcbSAndroid Build Coastguard Worker 
288*86b64dcbSAndroid Build Coastguard Worker 	static_assert(sizeof(dev->device_descriptor) == sizeof(info->DeviceDescriptor),
289*86b64dcbSAndroid Build Coastguard Worker 		      "mismatch between libusb and OS device descriptor sizes");
290*86b64dcbSAndroid Build Coastguard Worker 	memcpy(&dev->device_descriptor, &info->DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE);
291*86b64dcbSAndroid Build Coastguard Worker 	usbi_localize_device_descriptor(&dev->device_descriptor);
292*86b64dcbSAndroid Build Coastguard Worker 
293*86b64dcbSAndroid Build Coastguard Worker 	switch (info->Speed) {
294*86b64dcbSAndroid Build Coastguard Worker 	case LowSpeed:
295*86b64dcbSAndroid Build Coastguard Worker 		dev->speed = LIBUSB_SPEED_LOW;
296*86b64dcbSAndroid Build Coastguard Worker 		break;
297*86b64dcbSAndroid Build Coastguard Worker 	case FullSpeed:
298*86b64dcbSAndroid Build Coastguard Worker 		dev->speed = LIBUSB_SPEED_FULL;
299*86b64dcbSAndroid Build Coastguard Worker 		break;
300*86b64dcbSAndroid Build Coastguard Worker 	case HighSpeed:
301*86b64dcbSAndroid Build Coastguard Worker 		dev->speed = LIBUSB_SPEED_HIGH;
302*86b64dcbSAndroid Build Coastguard Worker 		break;
303*86b64dcbSAndroid Build Coastguard Worker 	case SuperSpeed:
304*86b64dcbSAndroid Build Coastguard Worker 		dev->speed = LIBUSB_SPEED_SUPER;
305*86b64dcbSAndroid Build Coastguard Worker 		break;
306*86b64dcbSAndroid Build Coastguard Worker 	case NoSpeed:
307*86b64dcbSAndroid Build Coastguard Worker 	default:
308*86b64dcbSAndroid Build Coastguard Worker 		dev->speed = LIBUSB_SPEED_UNKNOWN;
309*86b64dcbSAndroid Build Coastguard Worker 		break;
310*86b64dcbSAndroid Build Coastguard Worker 	}
311*86b64dcbSAndroid Build Coastguard Worker }
312*86b64dcbSAndroid Build Coastguard Worker 
usbdk_get_device_list(struct libusb_context * ctx,struct discovered_devs ** _discdevs)313*86b64dcbSAndroid Build Coastguard Worker static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_devs **_discdevs)
314*86b64dcbSAndroid Build Coastguard Worker {
315*86b64dcbSAndroid Build Coastguard Worker 	int r = LIBUSB_SUCCESS;
316*86b64dcbSAndroid Build Coastguard Worker 	ULONG i;
317*86b64dcbSAndroid Build Coastguard Worker 	struct discovered_devs *discdevs = NULL;
318*86b64dcbSAndroid Build Coastguard Worker 	ULONG dev_number;
319*86b64dcbSAndroid Build Coastguard Worker 	PUSB_DK_DEVICE_INFO devices;
320*86b64dcbSAndroid Build Coastguard Worker 
321*86b64dcbSAndroid Build Coastguard Worker 	if (!usbdk_helper.GetDevicesList(&devices, &dev_number))
322*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_OTHER;
323*86b64dcbSAndroid Build Coastguard Worker 
324*86b64dcbSAndroid Build Coastguard Worker 	for (i = 0; i < dev_number; i++) {
325*86b64dcbSAndroid Build Coastguard Worker 		unsigned long session_id;
326*86b64dcbSAndroid Build Coastguard Worker 		struct libusb_device *dev = NULL;
327*86b64dcbSAndroid Build Coastguard Worker 
328*86b64dcbSAndroid Build Coastguard Worker 		if (usbdk_get_session_id_for_device(ctx, &devices[i].ID, &session_id))
329*86b64dcbSAndroid Build Coastguard Worker 			continue;
330*86b64dcbSAndroid Build Coastguard Worker 
331*86b64dcbSAndroid Build Coastguard Worker 		dev = usbi_get_device_by_session_id(ctx, session_id);
332*86b64dcbSAndroid Build Coastguard Worker 		if (dev == NULL) {
333*86b64dcbSAndroid Build Coastguard Worker 			dev = usbi_alloc_device(ctx, session_id);
334*86b64dcbSAndroid Build Coastguard Worker 			if (dev == NULL) {
335*86b64dcbSAndroid Build Coastguard Worker 				usbi_err(ctx, "failed to allocate a new device structure");
336*86b64dcbSAndroid Build Coastguard Worker 				continue;
337*86b64dcbSAndroid Build Coastguard Worker 			}
338*86b64dcbSAndroid Build Coastguard Worker 
339*86b64dcbSAndroid Build Coastguard Worker 			usbdk_device_init(dev, &devices[i]);
340*86b64dcbSAndroid Build Coastguard Worker 			if (usbdk_device_priv_init(ctx, dev, &devices[i]) != LIBUSB_SUCCESS) {
341*86b64dcbSAndroid Build Coastguard Worker 				libusb_unref_device(dev);
342*86b64dcbSAndroid Build Coastguard Worker 				continue;
343*86b64dcbSAndroid Build Coastguard Worker 			}
344*86b64dcbSAndroid Build Coastguard Worker 		}
345*86b64dcbSAndroid Build Coastguard Worker 
346*86b64dcbSAndroid Build Coastguard Worker 		discdevs = discovered_devs_append(*_discdevs, dev);
347*86b64dcbSAndroid Build Coastguard Worker 		libusb_unref_device(dev);
348*86b64dcbSAndroid Build Coastguard Worker 		if (!discdevs) {
349*86b64dcbSAndroid Build Coastguard Worker 			usbi_err(ctx, "cannot append new device to list");
350*86b64dcbSAndroid Build Coastguard Worker 			r = LIBUSB_ERROR_NO_MEM;
351*86b64dcbSAndroid Build Coastguard Worker 			goto func_exit;
352*86b64dcbSAndroid Build Coastguard Worker 		}
353*86b64dcbSAndroid Build Coastguard Worker 
354*86b64dcbSAndroid Build Coastguard Worker 		*_discdevs = discdevs;
355*86b64dcbSAndroid Build Coastguard Worker 	}
356*86b64dcbSAndroid Build Coastguard Worker 
357*86b64dcbSAndroid Build Coastguard Worker func_exit:
358*86b64dcbSAndroid Build Coastguard Worker 	usbdk_helper.ReleaseDevicesList(devices);
359*86b64dcbSAndroid Build Coastguard Worker 	return r;
360*86b64dcbSAndroid Build Coastguard Worker }
361*86b64dcbSAndroid Build Coastguard Worker 
usbdk_get_config_descriptor(struct libusb_device * dev,uint8_t config_index,void * buffer,size_t len)362*86b64dcbSAndroid Build Coastguard Worker static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len)
363*86b64dcbSAndroid Build Coastguard Worker {
364*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev);
365*86b64dcbSAndroid Build Coastguard Worker 	PUSB_CONFIGURATION_DESCRIPTOR config_header;
366*86b64dcbSAndroid Build Coastguard Worker 	size_t size;
367*86b64dcbSAndroid Build Coastguard Worker 
368*86b64dcbSAndroid Build Coastguard Worker 	config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptors[config_index];
369*86b64dcbSAndroid Build Coastguard Worker 
370*86b64dcbSAndroid Build Coastguard Worker 	size = min(config_header->wTotalLength, len);
371*86b64dcbSAndroid Build Coastguard Worker 	memcpy(buffer, config_header, size);
372*86b64dcbSAndroid Build Coastguard Worker 	return (int)size;
373*86b64dcbSAndroid Build Coastguard Worker }
374*86b64dcbSAndroid Build Coastguard Worker 
usbdk_get_config_descriptor_by_value(struct libusb_device * dev,uint8_t bConfigurationValue,void ** buffer)375*86b64dcbSAndroid Build Coastguard Worker static int usbdk_get_config_descriptor_by_value(struct libusb_device *dev, uint8_t bConfigurationValue,
376*86b64dcbSAndroid Build Coastguard Worker 	void **buffer)
377*86b64dcbSAndroid Build Coastguard Worker {
378*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev);
379*86b64dcbSAndroid Build Coastguard Worker 	PUSB_CONFIGURATION_DESCRIPTOR config_header;
380*86b64dcbSAndroid Build Coastguard Worker 	uint8_t index;
381*86b64dcbSAndroid Build Coastguard Worker 
382*86b64dcbSAndroid Build Coastguard Worker 	for (index = 0; index < dev->device_descriptor.bNumConfigurations; index++) {
383*86b64dcbSAndroid Build Coastguard Worker 		config_header = priv->config_descriptors[index];
384*86b64dcbSAndroid Build Coastguard Worker 		if (config_header->bConfigurationValue == bConfigurationValue) {
385*86b64dcbSAndroid Build Coastguard Worker 			*buffer = priv->config_descriptors[index];
386*86b64dcbSAndroid Build Coastguard Worker 			return (int)config_header->wTotalLength;
387*86b64dcbSAndroid Build Coastguard Worker 		}
388*86b64dcbSAndroid Build Coastguard Worker 	}
389*86b64dcbSAndroid Build Coastguard Worker 
390*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_ERROR_NOT_FOUND;
391*86b64dcbSAndroid Build Coastguard Worker }
392*86b64dcbSAndroid Build Coastguard Worker 
usbdk_get_active_config_descriptor(struct libusb_device * dev,void * buffer,size_t len)393*86b64dcbSAndroid Build Coastguard Worker static int usbdk_get_active_config_descriptor(struct libusb_device *dev, void *buffer, size_t len)
394*86b64dcbSAndroid Build Coastguard Worker {
395*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev);
396*86b64dcbSAndroid Build Coastguard Worker 
397*86b64dcbSAndroid Build Coastguard Worker 	return usbdk_get_config_descriptor(dev, priv->active_configuration, buffer, len);
398*86b64dcbSAndroid Build Coastguard Worker }
399*86b64dcbSAndroid Build Coastguard Worker 
usbdk_open(struct libusb_device_handle * dev_handle)400*86b64dcbSAndroid Build Coastguard Worker static int usbdk_open(struct libusb_device_handle *dev_handle)
401*86b64dcbSAndroid Build Coastguard Worker {
402*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_device *dev = dev_handle->dev;
403*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_context *ctx = DEVICE_CTX(dev);
404*86b64dcbSAndroid Build Coastguard Worker 	struct windows_context_priv *priv = usbi_get_context_priv(ctx);
405*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *device_priv = usbi_get_device_priv(dev);
406*86b64dcbSAndroid Build Coastguard Worker 
407*86b64dcbSAndroid Build Coastguard Worker 	device_priv->redirector_handle = usbdk_helper.StartRedirect(&device_priv->ID);
408*86b64dcbSAndroid Build Coastguard Worker 	if (device_priv->redirector_handle == INVALID_HANDLE_VALUE) {
409*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(ctx, "Redirector startup failed");
410*86b64dcbSAndroid Build Coastguard Worker 		device_priv->redirector_handle = NULL;
411*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_OTHER;
412*86b64dcbSAndroid Build Coastguard Worker 	}
413*86b64dcbSAndroid Build Coastguard Worker 
414*86b64dcbSAndroid Build Coastguard Worker 	device_priv->system_handle = usbdk_helper.GetRedirectorSystemHandle(device_priv->redirector_handle);
415*86b64dcbSAndroid Build Coastguard Worker 
416*86b64dcbSAndroid Build Coastguard Worker 	if (CreateIoCompletionPort(device_priv->system_handle, priv->completion_port, (ULONG_PTR)dev_handle, 0) == NULL) {
417*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(ctx, "failed to associate handle to I/O completion port: %s", windows_error_str(0));
418*86b64dcbSAndroid Build Coastguard Worker 		usbdk_helper.StopRedirect(device_priv->redirector_handle);
419*86b64dcbSAndroid Build Coastguard Worker 		device_priv->system_handle = NULL;
420*86b64dcbSAndroid Build Coastguard Worker 		device_priv->redirector_handle = NULL;
421*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_OTHER;
422*86b64dcbSAndroid Build Coastguard Worker 	}
423*86b64dcbSAndroid Build Coastguard Worker 
424*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
425*86b64dcbSAndroid Build Coastguard Worker }
426*86b64dcbSAndroid Build Coastguard Worker 
usbdk_close(struct libusb_device_handle * dev_handle)427*86b64dcbSAndroid Build Coastguard Worker static void usbdk_close(struct libusb_device_handle *dev_handle)
428*86b64dcbSAndroid Build Coastguard Worker {
429*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
430*86b64dcbSAndroid Build Coastguard Worker 
431*86b64dcbSAndroid Build Coastguard Worker 	if (!usbdk_helper.StopRedirect(priv->redirector_handle))
432*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(HANDLE_CTX(dev_handle), "Redirector shutdown failed");
433*86b64dcbSAndroid Build Coastguard Worker 
434*86b64dcbSAndroid Build Coastguard Worker 	priv->system_handle = NULL;
435*86b64dcbSAndroid Build Coastguard Worker 	priv->redirector_handle = NULL;
436*86b64dcbSAndroid Build Coastguard Worker }
437*86b64dcbSAndroid Build Coastguard Worker 
usbdk_get_configuration(struct libusb_device_handle * dev_handle,uint8_t * config)438*86b64dcbSAndroid Build Coastguard Worker static int usbdk_get_configuration(struct libusb_device_handle *dev_handle, uint8_t *config)
439*86b64dcbSAndroid Build Coastguard Worker {
440*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
441*86b64dcbSAndroid Build Coastguard Worker 
442*86b64dcbSAndroid Build Coastguard Worker 	*config = priv->active_configuration;
443*86b64dcbSAndroid Build Coastguard Worker 
444*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
445*86b64dcbSAndroid Build Coastguard Worker }
446*86b64dcbSAndroid Build Coastguard Worker 
usbdk_set_configuration(struct libusb_device_handle * dev_handle,uint8_t config)447*86b64dcbSAndroid Build Coastguard Worker static int usbdk_set_configuration(struct libusb_device_handle *dev_handle, uint8_t config)
448*86b64dcbSAndroid Build Coastguard Worker {
449*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(dev_handle);
450*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(config);
451*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
452*86b64dcbSAndroid Build Coastguard Worker }
453*86b64dcbSAndroid Build Coastguard Worker 
usbdk_claim_interface(struct libusb_device_handle * dev_handle,uint8_t iface)454*86b64dcbSAndroid Build Coastguard Worker static int usbdk_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface)
455*86b64dcbSAndroid Build Coastguard Worker {
456*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(dev_handle);
457*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(iface);
458*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
459*86b64dcbSAndroid Build Coastguard Worker }
460*86b64dcbSAndroid Build Coastguard Worker 
usbdk_set_interface_altsetting(struct libusb_device_handle * dev_handle,uint8_t iface,uint8_t altsetting)461*86b64dcbSAndroid Build Coastguard Worker static int usbdk_set_interface_altsetting(struct libusb_device_handle *dev_handle, uint8_t iface, uint8_t altsetting)
462*86b64dcbSAndroid Build Coastguard Worker {
463*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
464*86b64dcbSAndroid Build Coastguard Worker 
465*86b64dcbSAndroid Build Coastguard Worker 	if (!usbdk_helper.SetAltsetting(priv->redirector_handle, iface, altsetting)) {
466*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(HANDLE_CTX(dev_handle), "SetAltsetting failed: %s", windows_error_str(0));
467*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NO_DEVICE;
468*86b64dcbSAndroid Build Coastguard Worker 	}
469*86b64dcbSAndroid Build Coastguard Worker 
470*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
471*86b64dcbSAndroid Build Coastguard Worker }
472*86b64dcbSAndroid Build Coastguard Worker 
usbdk_release_interface(struct libusb_device_handle * dev_handle,uint8_t iface)473*86b64dcbSAndroid Build Coastguard Worker static int usbdk_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface)
474*86b64dcbSAndroid Build Coastguard Worker {
475*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(dev_handle);
476*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(iface);
477*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
478*86b64dcbSAndroid Build Coastguard Worker }
479*86b64dcbSAndroid Build Coastguard Worker 
usbdk_clear_halt(struct libusb_device_handle * dev_handle,unsigned char endpoint)480*86b64dcbSAndroid Build Coastguard Worker static int usbdk_clear_halt(struct libusb_device_handle *dev_handle, unsigned char endpoint)
481*86b64dcbSAndroid Build Coastguard Worker {
482*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
483*86b64dcbSAndroid Build Coastguard Worker 
484*86b64dcbSAndroid Build Coastguard Worker 	if (!usbdk_helper.ResetPipe(priv->redirector_handle, endpoint)) {
485*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(HANDLE_CTX(dev_handle), "ResetPipe failed: %s", windows_error_str(0));
486*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NO_DEVICE;
487*86b64dcbSAndroid Build Coastguard Worker 	}
488*86b64dcbSAndroid Build Coastguard Worker 
489*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
490*86b64dcbSAndroid Build Coastguard Worker }
491*86b64dcbSAndroid Build Coastguard Worker 
usbdk_reset_device(struct libusb_device_handle * dev_handle)492*86b64dcbSAndroid Build Coastguard Worker static int usbdk_reset_device(struct libusb_device_handle *dev_handle)
493*86b64dcbSAndroid Build Coastguard Worker {
494*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev_handle->dev);
495*86b64dcbSAndroid Build Coastguard Worker 
496*86b64dcbSAndroid Build Coastguard Worker 	if (!usbdk_helper.ResetDevice(priv->redirector_handle)) {
497*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(HANDLE_CTX(dev_handle), "ResetDevice failed: %s", windows_error_str(0));
498*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NO_DEVICE;
499*86b64dcbSAndroid Build Coastguard Worker 	}
500*86b64dcbSAndroid Build Coastguard Worker 
501*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
502*86b64dcbSAndroid Build Coastguard Worker }
503*86b64dcbSAndroid Build Coastguard Worker 
usbdk_destroy_device(struct libusb_device * dev)504*86b64dcbSAndroid Build Coastguard Worker static void usbdk_destroy_device(struct libusb_device *dev)
505*86b64dcbSAndroid Build Coastguard Worker {
506*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(dev);
507*86b64dcbSAndroid Build Coastguard Worker 
508*86b64dcbSAndroid Build Coastguard Worker 	if (priv->config_descriptors != NULL)
509*86b64dcbSAndroid Build Coastguard Worker 		usbdk_release_config_descriptors(priv, dev->device_descriptor.bNumConfigurations);
510*86b64dcbSAndroid Build Coastguard Worker }
511*86b64dcbSAndroid Build Coastguard Worker 
usbdk_clear_transfer_priv(struct usbi_transfer * itransfer)512*86b64dcbSAndroid Build Coastguard Worker static void usbdk_clear_transfer_priv(struct usbi_transfer *itransfer)
513*86b64dcbSAndroid Build Coastguard Worker {
514*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_transfer_priv *transfer_priv = get_usbdk_transfer_priv(itransfer);
515*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
516*86b64dcbSAndroid Build Coastguard Worker 
517*86b64dcbSAndroid Build Coastguard Worker 	if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
518*86b64dcbSAndroid Build Coastguard Worker 		safe_free(transfer_priv->IsochronousPacketsArray);
519*86b64dcbSAndroid Build Coastguard Worker 		safe_free(transfer_priv->IsochronousResultsArray);
520*86b64dcbSAndroid Build Coastguard Worker 	}
521*86b64dcbSAndroid Build Coastguard Worker }
522*86b64dcbSAndroid Build Coastguard Worker 
usbdk_do_control_transfer(struct usbi_transfer * itransfer)523*86b64dcbSAndroid Build Coastguard Worker static int usbdk_do_control_transfer(struct usbi_transfer *itransfer)
524*86b64dcbSAndroid Build Coastguard Worker {
525*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
526*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
527*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_transfer_priv *transfer_priv = get_usbdk_transfer_priv(itransfer);
528*86b64dcbSAndroid Build Coastguard Worker 	OVERLAPPED *overlapped = get_transfer_priv_overlapped(itransfer);
529*86b64dcbSAndroid Build Coastguard Worker 	TransferResult transResult;
530*86b64dcbSAndroid Build Coastguard Worker 
531*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.Buffer = (PVOID64)transfer->buffer;
532*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.BufferLength = transfer->length;
533*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.TransferType = ControlTransferType;
534*86b64dcbSAndroid Build Coastguard Worker 
535*86b64dcbSAndroid Build Coastguard Worker 	set_transfer_priv_handle(itransfer, priv->system_handle);
536*86b64dcbSAndroid Build Coastguard Worker 
537*86b64dcbSAndroid Build Coastguard Worker 	if (transfer->buffer[0] & LIBUSB_ENDPOINT_IN)
538*86b64dcbSAndroid Build Coastguard Worker 		transResult = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, overlapped);
539*86b64dcbSAndroid Build Coastguard Worker 	else
540*86b64dcbSAndroid Build Coastguard Worker 		transResult = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, overlapped);
541*86b64dcbSAndroid Build Coastguard Worker 
542*86b64dcbSAndroid Build Coastguard Worker 	switch (transResult) {
543*86b64dcbSAndroid Build Coastguard Worker 	case TransferSuccess:
544*86b64dcbSAndroid Build Coastguard Worker 		windows_force_sync_completion(itransfer, (ULONG)transfer_priv->request.Result.GenResult.BytesTransferred);
545*86b64dcbSAndroid Build Coastguard Worker 		break;
546*86b64dcbSAndroid Build Coastguard Worker 	case TransferSuccessAsync:
547*86b64dcbSAndroid Build Coastguard Worker 		break;
548*86b64dcbSAndroid Build Coastguard Worker 	case TransferFailure:
549*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(TRANSFER_CTX(transfer), "ControlTransfer failed: %s", windows_error_str(0));
550*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_IO;
551*86b64dcbSAndroid Build Coastguard Worker 	}
552*86b64dcbSAndroid Build Coastguard Worker 
553*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
554*86b64dcbSAndroid Build Coastguard Worker }
555*86b64dcbSAndroid Build Coastguard Worker 
usbdk_do_bulk_transfer(struct usbi_transfer * itransfer)556*86b64dcbSAndroid Build Coastguard Worker static int usbdk_do_bulk_transfer(struct usbi_transfer *itransfer)
557*86b64dcbSAndroid Build Coastguard Worker {
558*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
559*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
560*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_transfer_priv *transfer_priv = get_usbdk_transfer_priv(itransfer);
561*86b64dcbSAndroid Build Coastguard Worker 	OVERLAPPED *overlapped = get_transfer_priv_overlapped(itransfer);
562*86b64dcbSAndroid Build Coastguard Worker 	TransferResult transferRes;
563*86b64dcbSAndroid Build Coastguard Worker 
564*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.Buffer = (PVOID64)transfer->buffer;
565*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.BufferLength = transfer->length;
566*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.EndpointAddress = transfer->endpoint;
567*86b64dcbSAndroid Build Coastguard Worker 
568*86b64dcbSAndroid Build Coastguard Worker 	switch (transfer->type) {
569*86b64dcbSAndroid Build Coastguard Worker 	case LIBUSB_TRANSFER_TYPE_BULK:
570*86b64dcbSAndroid Build Coastguard Worker 		transfer_priv->request.TransferType = BulkTransferType;
571*86b64dcbSAndroid Build Coastguard Worker 		break;
572*86b64dcbSAndroid Build Coastguard Worker 	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
573*86b64dcbSAndroid Build Coastguard Worker 		transfer_priv->request.TransferType = InterruptTransferType;
574*86b64dcbSAndroid Build Coastguard Worker 		break;
575*86b64dcbSAndroid Build Coastguard Worker 	}
576*86b64dcbSAndroid Build Coastguard Worker 
577*86b64dcbSAndroid Build Coastguard Worker 	set_transfer_priv_handle(itransfer, priv->system_handle);
578*86b64dcbSAndroid Build Coastguard Worker 
579*86b64dcbSAndroid Build Coastguard Worker 	if (IS_XFERIN(transfer))
580*86b64dcbSAndroid Build Coastguard Worker 		transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, overlapped);
581*86b64dcbSAndroid Build Coastguard Worker 	else
582*86b64dcbSAndroid Build Coastguard Worker 		transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, overlapped);
583*86b64dcbSAndroid Build Coastguard Worker 
584*86b64dcbSAndroid Build Coastguard Worker 	switch (transferRes) {
585*86b64dcbSAndroid Build Coastguard Worker 	case TransferSuccess:
586*86b64dcbSAndroid Build Coastguard Worker 		windows_force_sync_completion(itransfer, (ULONG)transfer_priv->request.Result.GenResult.BytesTransferred);
587*86b64dcbSAndroid Build Coastguard Worker 		break;
588*86b64dcbSAndroid Build Coastguard Worker 	case TransferSuccessAsync:
589*86b64dcbSAndroid Build Coastguard Worker 		break;
590*86b64dcbSAndroid Build Coastguard Worker 	case TransferFailure:
591*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(TRANSFER_CTX(transfer), "ReadPipe/WritePipe failed: %s", windows_error_str(0));
592*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_IO;
593*86b64dcbSAndroid Build Coastguard Worker 	}
594*86b64dcbSAndroid Build Coastguard Worker 
595*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
596*86b64dcbSAndroid Build Coastguard Worker }
597*86b64dcbSAndroid Build Coastguard Worker 
usbdk_do_iso_transfer(struct usbi_transfer * itransfer)598*86b64dcbSAndroid Build Coastguard Worker static int usbdk_do_iso_transfer(struct usbi_transfer *itransfer)
599*86b64dcbSAndroid Build Coastguard Worker {
600*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
601*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_device_priv *priv = usbi_get_device_priv(transfer->dev_handle->dev);
602*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_transfer_priv *transfer_priv = get_usbdk_transfer_priv(itransfer);
603*86b64dcbSAndroid Build Coastguard Worker 	OVERLAPPED *overlapped = get_transfer_priv_overlapped(itransfer);
604*86b64dcbSAndroid Build Coastguard Worker 	TransferResult transferRes;
605*86b64dcbSAndroid Build Coastguard Worker 	int i;
606*86b64dcbSAndroid Build Coastguard Worker 
607*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.Buffer = (PVOID64)transfer->buffer;
608*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.BufferLength = transfer->length;
609*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.EndpointAddress = transfer->endpoint;
610*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.TransferType = IsochronousTransferType;
611*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.IsochronousPacketsArraySize = transfer->num_iso_packets;
612*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->IsochronousPacketsArray = malloc(transfer->num_iso_packets * sizeof(ULONG64));
613*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.IsochronousPacketsArray = (PVOID64)transfer_priv->IsochronousPacketsArray;
614*86b64dcbSAndroid Build Coastguard Worker 	if (!transfer_priv->IsochronousPacketsArray) {
615*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(TRANSFER_CTX(transfer), "Allocation of IsochronousPacketsArray failed");
616*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NO_MEM;
617*86b64dcbSAndroid Build Coastguard Worker 	}
618*86b64dcbSAndroid Build Coastguard Worker 
619*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->IsochronousResultsArray = malloc(transfer->num_iso_packets * sizeof(USB_DK_ISO_TRANSFER_RESULT));
620*86b64dcbSAndroid Build Coastguard Worker 	transfer_priv->request.Result.IsochronousResultsArray = (PVOID64)transfer_priv->IsochronousResultsArray;
621*86b64dcbSAndroid Build Coastguard Worker 	if (!transfer_priv->IsochronousResultsArray) {
622*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(TRANSFER_CTX(transfer), "Allocation of isochronousResultsArray failed");
623*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NO_MEM;
624*86b64dcbSAndroid Build Coastguard Worker 	}
625*86b64dcbSAndroid Build Coastguard Worker 
626*86b64dcbSAndroid Build Coastguard Worker 	for (i = 0; i < transfer->num_iso_packets; i++)
627*86b64dcbSAndroid Build Coastguard Worker 		transfer_priv->IsochronousPacketsArray[i] = transfer->iso_packet_desc[i].length;
628*86b64dcbSAndroid Build Coastguard Worker 
629*86b64dcbSAndroid Build Coastguard Worker 	set_transfer_priv_handle(itransfer, priv->system_handle);
630*86b64dcbSAndroid Build Coastguard Worker 
631*86b64dcbSAndroid Build Coastguard Worker 	if (IS_XFERIN(transfer))
632*86b64dcbSAndroid Build Coastguard Worker 		transferRes = usbdk_helper.ReadPipe(priv->redirector_handle, &transfer_priv->request, overlapped);
633*86b64dcbSAndroid Build Coastguard Worker 	else
634*86b64dcbSAndroid Build Coastguard Worker 		transferRes = usbdk_helper.WritePipe(priv->redirector_handle, &transfer_priv->request, overlapped);
635*86b64dcbSAndroid Build Coastguard Worker 
636*86b64dcbSAndroid Build Coastguard Worker 	switch (transferRes) {
637*86b64dcbSAndroid Build Coastguard Worker 	case TransferSuccess:
638*86b64dcbSAndroid Build Coastguard Worker 		windows_force_sync_completion(itransfer, (ULONG)transfer_priv->request.Result.GenResult.BytesTransferred);
639*86b64dcbSAndroid Build Coastguard Worker 		break;
640*86b64dcbSAndroid Build Coastguard Worker 	case TransferSuccessAsync:
641*86b64dcbSAndroid Build Coastguard Worker 		break;
642*86b64dcbSAndroid Build Coastguard Worker 	case TransferFailure:
643*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_IO;
644*86b64dcbSAndroid Build Coastguard Worker 	}
645*86b64dcbSAndroid Build Coastguard Worker 
646*86b64dcbSAndroid Build Coastguard Worker 	return LIBUSB_SUCCESS;
647*86b64dcbSAndroid Build Coastguard Worker }
648*86b64dcbSAndroid Build Coastguard Worker 
usbdk_submit_transfer(struct usbi_transfer * itransfer)649*86b64dcbSAndroid Build Coastguard Worker static int usbdk_submit_transfer(struct usbi_transfer *itransfer)
650*86b64dcbSAndroid Build Coastguard Worker {
651*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
652*86b64dcbSAndroid Build Coastguard Worker 
653*86b64dcbSAndroid Build Coastguard Worker 	switch (transfer->type) {
654*86b64dcbSAndroid Build Coastguard Worker 	case LIBUSB_TRANSFER_TYPE_CONTROL:
655*86b64dcbSAndroid Build Coastguard Worker 		return usbdk_do_control_transfer(itransfer);
656*86b64dcbSAndroid Build Coastguard Worker 	case LIBUSB_TRANSFER_TYPE_BULK:
657*86b64dcbSAndroid Build Coastguard Worker 	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
658*86b64dcbSAndroid Build Coastguard Worker 		if (IS_XFEROUT(transfer) && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET))
659*86b64dcbSAndroid Build Coastguard Worker 			return LIBUSB_ERROR_NOT_SUPPORTED; //TODO: Check whether we can support this in UsbDk
660*86b64dcbSAndroid Build Coastguard Worker 		return usbdk_do_bulk_transfer(itransfer);
661*86b64dcbSAndroid Build Coastguard Worker 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
662*86b64dcbSAndroid Build Coastguard Worker 		return usbdk_do_iso_transfer(itransfer);
663*86b64dcbSAndroid Build Coastguard Worker 	default:
664*86b64dcbSAndroid Build Coastguard Worker 		// Should not get here since windows_submit_transfer() validates
665*86b64dcbSAndroid Build Coastguard Worker 		// the transfer->type field
666*86b64dcbSAndroid Build Coastguard Worker 		usbi_err(TRANSFER_CTX(transfer), "unsupported endpoint type %d", transfer->type);
667*86b64dcbSAndroid Build Coastguard Worker 		return LIBUSB_ERROR_NOT_SUPPORTED;
668*86b64dcbSAndroid Build Coastguard Worker 	}
669*86b64dcbSAndroid Build Coastguard Worker }
670*86b64dcbSAndroid Build Coastguard Worker 
usbdk_copy_transfer_data(struct usbi_transfer * itransfer,DWORD length)671*86b64dcbSAndroid Build Coastguard Worker static enum libusb_transfer_status usbdk_copy_transfer_data(struct usbi_transfer *itransfer, DWORD length)
672*86b64dcbSAndroid Build Coastguard Worker {
673*86b64dcbSAndroid Build Coastguard Worker 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
674*86b64dcbSAndroid Build Coastguard Worker 	struct usbdk_transfer_priv *transfer_priv = get_usbdk_transfer_priv(itransfer);
675*86b64dcbSAndroid Build Coastguard Worker 
676*86b64dcbSAndroid Build Coastguard Worker 	UNUSED(length);
677*86b64dcbSAndroid Build Coastguard Worker 
678*86b64dcbSAndroid Build Coastguard Worker 	if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) {
679*86b64dcbSAndroid Build Coastguard Worker 		ULONG64 i;
680*86b64dcbSAndroid Build Coastguard Worker 
681*86b64dcbSAndroid Build Coastguard Worker 		for (i = 0; i < transfer_priv->request.IsochronousPacketsArraySize; i++) {
682*86b64dcbSAndroid Build Coastguard Worker 			struct libusb_iso_packet_descriptor *lib_desc = &transfer->iso_packet_desc[i];
683*86b64dcbSAndroid Build Coastguard Worker 
684*86b64dcbSAndroid Build Coastguard Worker 			switch (transfer_priv->IsochronousResultsArray[i].TransferResult) {
685*86b64dcbSAndroid Build Coastguard Worker 			case STATUS_SUCCESS:
686*86b64dcbSAndroid Build Coastguard Worker 			case STATUS_CANCELLED:
687*86b64dcbSAndroid Build Coastguard Worker 			case STATUS_REQUEST_CANCELED:
688*86b64dcbSAndroid Build Coastguard Worker 				lib_desc->status = LIBUSB_TRANSFER_COMPLETED; // == ERROR_SUCCESS
689*86b64dcbSAndroid Build Coastguard Worker 				break;
690*86b64dcbSAndroid Build Coastguard Worker 			default:
691*86b64dcbSAndroid Build Coastguard Worker 				lib_desc->status = LIBUSB_TRANSFER_ERROR; // ERROR_UNKNOWN_EXCEPTION;
692*86b64dcbSAndroid Build Coastguard Worker 				break;
693*86b64dcbSAndroid Build Coastguard Worker 			}
694*86b64dcbSAndroid Build Coastguard Worker 
695*86b64dcbSAndroid Build Coastguard Worker 			lib_desc->actual_length = (unsigned int)transfer_priv->IsochronousResultsArray[i].ActualLength;
696*86b64dcbSAndroid Build Coastguard Worker 		}
697*86b64dcbSAndroid Build Coastguard Worker 	}
698*86b64dcbSAndroid Build Coastguard Worker 
699*86b64dcbSAndroid Build Coastguard Worker 	itransfer->transferred += (int)transfer_priv->request.Result.GenResult.BytesTransferred;
700*86b64dcbSAndroid Build Coastguard Worker 	return usbd_status_to_libusb_transfer_status((USBD_STATUS)transfer_priv->request.Result.GenResult.UsbdStatus);
701*86b64dcbSAndroid Build Coastguard Worker }
702*86b64dcbSAndroid Build Coastguard Worker 
703*86b64dcbSAndroid Build Coastguard Worker const struct windows_backend usbdk_backend = {
704*86b64dcbSAndroid Build Coastguard Worker 	usbdk_init,
705*86b64dcbSAndroid Build Coastguard Worker 	usbdk_exit,
706*86b64dcbSAndroid Build Coastguard Worker 	usbdk_get_device_list,
707*86b64dcbSAndroid Build Coastguard Worker 	usbdk_open,
708*86b64dcbSAndroid Build Coastguard Worker 	usbdk_close,
709*86b64dcbSAndroid Build Coastguard Worker 	usbdk_get_active_config_descriptor,
710*86b64dcbSAndroid Build Coastguard Worker 	usbdk_get_config_descriptor,
711*86b64dcbSAndroid Build Coastguard Worker 	usbdk_get_config_descriptor_by_value,
712*86b64dcbSAndroid Build Coastguard Worker 	usbdk_get_configuration,
713*86b64dcbSAndroid Build Coastguard Worker 	usbdk_set_configuration,
714*86b64dcbSAndroid Build Coastguard Worker 	usbdk_claim_interface,
715*86b64dcbSAndroid Build Coastguard Worker 	usbdk_release_interface,
716*86b64dcbSAndroid Build Coastguard Worker 	usbdk_set_interface_altsetting,
717*86b64dcbSAndroid Build Coastguard Worker 	usbdk_clear_halt,
718*86b64dcbSAndroid Build Coastguard Worker 	usbdk_reset_device,
719*86b64dcbSAndroid Build Coastguard Worker 	usbdk_destroy_device,
720*86b64dcbSAndroid Build Coastguard Worker 	usbdk_submit_transfer,
721*86b64dcbSAndroid Build Coastguard Worker 	NULL,	/* cancel_transfer */
722*86b64dcbSAndroid Build Coastguard Worker 	usbdk_clear_transfer_priv,
723*86b64dcbSAndroid Build Coastguard Worker 	usbdk_copy_transfer_data,
724*86b64dcbSAndroid Build Coastguard Worker };
725