~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to channels/urbdrc/client/data_transfer.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.1.9) (9.1.17 sid)
  • Revision ID: package-import@ubuntu.com-20141111122050-wyr8hrnwco9fcmum
Tags: 1.1.0~git20140921.1.440916e+dfsg1-2ubuntu1
* Merge with Debian unstable, remaining changes
  - Disable ffmpeg support
* Disable gstreamer support, this relies on gstreamer 0.10 and we don't want
  to add any more deps on that.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Implementation
 
3
 * RemoteFX USB Redirection
 
4
 *
 
5
 * Copyright 2012 Atrust corp.
 
6
 * Copyright 2012 Alfred Liu <alfred.liu@atruscorp.com>
 
7
 *
 
8
 * Licensed under the Apache License, Version 2.0 (the "License");
 
9
 * you may not use this file except in compliance with the License.
 
10
 * You may obtain a copy of the License at
 
11
 *
 
12
 *     http://www.apache.org/licenses/LICENSE-2.0
 
13
 *
 
14
 * Unless required by applicable law or agreed to in writing, software
 
15
 * distributed under the License is distributed on an "AS IS" BASIS,
 
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
17
 * See the License for the specific language governing permissions and
 
18
 * limitations under the License.
 
19
 */
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <string.h>
 
24
#include <unistd.h>
 
25
 
 
26
#include <sys/ioctl.h>
 
27
#include <sys/stat.h>
 
28
#include <sys/types.h>
 
29
 
 
30
#include "urbdrc_types.h"
 
31
#include "data_transfer.h"
 
32
 
 
33
static void usb_process_get_port_status(IUDEVICE* pdev, BYTE* OutputBuffer)
 
34
{
 
35
        int bcdUSB = pdev->query_device_descriptor(pdev, BCD_USB);
 
36
 
 
37
        switch (bcdUSB)
 
38
        {
 
39
                case USB_v1_0:
 
40
                        data_write_UINT32(OutputBuffer, 0x303);
 
41
                        break;
 
42
 
 
43
                case USB_v1_1:
 
44
                        data_write_UINT32(OutputBuffer, 0x103);
 
45
                        break;
 
46
 
 
47
                case USB_v2_0:
 
48
                        data_write_UINT32(OutputBuffer, 0x503);
 
49
                        break;
 
50
 
 
51
                default:
 
52
                        data_write_UINT32(OutputBuffer, 0x503);
 
53
                        break;
 
54
        }
 
55
}
 
56
 
 
57
#if ISOCH_FIFO
 
58
 
 
59
static int func_check_isochronous_fds(IUDEVICE* pdev)
 
60
{
 
61
        int ret = 0;
 
62
        BYTE* data_temp;
 
63
        UINT32 size_temp, process_times = 2;
 
64
        ISOCH_CALLBACK_QUEUE* isoch_queue = NULL;
 
65
        ISOCH_CALLBACK_DATA* isoch = NULL;
 
66
        URBDRC_CHANNEL_CALLBACK* callback;
 
67
 
 
68
        isoch_queue = (ISOCH_CALLBACK_QUEUE*) pdev->get_isoch_queue(pdev);
 
69
 
 
70
        while (process_times)
 
71
        {
 
72
                process_times--;
 
73
 
 
74
                if (isoch_queue == NULL || !pdev)
 
75
                        return -1;
 
76
 
 
77
                pthread_mutex_lock(&isoch_queue->isoch_loading);
 
78
 
 
79
                if (isoch_queue->head == NULL)
 
80
                {
 
81
                        pthread_mutex_unlock(&isoch_queue->isoch_loading);
 
82
                        continue;
 
83
                }
 
84
                else
 
85
                {
 
86
                        isoch = isoch_queue->head;
 
87
                }
 
88
 
 
89
                if (!isoch || !isoch->out_data)
 
90
                {
 
91
                        pthread_mutex_unlock(&isoch_queue->isoch_loading);
 
92
                        continue;
 
93
                }
 
94
                else
 
95
                {
 
96
                        callback = (URBDRC_CHANNEL_CALLBACK*) isoch->callback;
 
97
                        size_temp = isoch->out_size;
 
98
                        data_temp = isoch->out_data;
 
99
 
 
100
                        ret = isoch_queue->unregister_data(isoch_queue, isoch);
 
101
 
 
102
                        if (!ret)
 
103
                                LLOGLN(0, ("isoch_queue_unregister_data: Not found isoch data!!\n"));
 
104
 
 
105
                        pthread_mutex_unlock(&isoch_queue->isoch_loading);
 
106
 
 
107
                        if (pdev && !pdev->isSigToEnd(pdev))
 
108
                        {
 
109
                                callback->channel->Write(callback->channel, size_temp, data_temp, NULL);
 
110
                                zfree(data_temp);
 
111
                        }
 
112
                }
 
113
        }
 
114
 
 
115
        return 0;
 
116
}
 
117
 
 
118
#endif
 
119
 
 
120
static int urbdrc_process_register_request_callback(URBDRC_CHANNEL_CALLBACK* callback,
 
121
                BYTE* data, UINT32 data_sizem, IUDEVMAN* udevman, UINT32 UsbDevice)
 
122
{
 
123
        IUDEVICE* pdev;
 
124
        UINT32 NumRequestCompletion = 0;
 
125
        UINT32 RequestCompletion = 0;
 
126
 
 
127
        LLOGLN(urbdrc_debug, ("urbdrc_process_register_request_callback"));
 
128
 
 
129
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
130
 
 
131
        if (pdev == NULL)
 
132
                return 0;
 
133
 
 
134
        if (data_sizem >= 8)
 
135
        {
 
136
                data_read_UINT32(data + 0, NumRequestCompletion); /** must be 1 */
 
137
                /** RequestCompletion:
 
138
                *   unique Request Completion interface for the client to use */
 
139
                data_read_UINT32(data + 4, RequestCompletion);
 
140
                pdev->set_ReqCompletion(pdev, RequestCompletion);
 
141
        }
 
142
        else /** Unregister the device */
 
143
        {
 
144
                data_read_UINT32(data + 0, RequestCompletion);
 
145
 
 
146
                if (1)//(pdev->get_ReqCompletion(pdev) == RequestCompletion)
 
147
                {
 
148
                        /** The wrong driver may also receive this message, So we
 
149
                         *  need some time(default 3s) to check the driver or delete
 
150
                         *  it */
 
151
                        sleep(3);
 
152
                        callback->channel->Write(callback->channel, 0, NULL, NULL);
 
153
                        pdev->SigToEnd(pdev);
 
154
                }
 
155
        }
 
156
 
 
157
        return 0;
 
158
}
 
159
 
 
160
static int urbdrc_process_cancel_request(BYTE* data, UINT32 data_sizem, IUDEVMAN* udevman, UINT32 UsbDevice)
 
161
{
 
162
        IUDEVICE* pdev;
 
163
        UINT32 CancelId;
 
164
        int error = 0;
 
165
 
 
166
        data_read_UINT32(data + 0, CancelId); /** RequestId */
 
167
 
 
168
        LLOGLN(urbdrc_debug, ("urbdrc_process_cancel_request: id 0x%x", CancelId));
 
169
 
 
170
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
171
 
 
172
        if (pdev == NULL)
 
173
                return 0;
 
174
 
 
175
        error = pdev->cancel_transfer_request(pdev, CancelId);
 
176
 
 
177
        return error;
 
178
}
 
179
 
 
180
static int urbdrc_process_retract_device_request(BYTE* data, UINT32 data_sizem, IUDEVMAN* udevman, UINT32 UsbDevice)
 
181
{
 
182
        UINT32 Reason;
 
183
        LLOGLN(urbdrc_debug, ("urbdrc_process_retract_device_request"));
 
184
 
 
185
        data_read_UINT32(data + 0, Reason); /** Reason */
 
186
 
 
187
        switch (Reason)
 
188
        {
 
189
                case UsbRetractReason_BlockedByPolicy:
 
190
                        LLOGLN(urbdrc_debug, ("UsbRetractReason_BlockedByPolicy: now it is not support"));
 
191
                        return -1;
 
192
                        break;
 
193
 
 
194
                default:
 
195
                        LLOGLN(urbdrc_debug, ("urbdrc_process_retract_device_request: Unknown Reason %d", Reason));
 
196
                        return -1;
 
197
                        break;
 
198
        }
 
199
 
 
200
        return 0;
 
201
}
 
202
 
 
203
static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
 
204
                UINT32 data_sizem, UINT32 MessageId, IUDEVMAN * udevman, UINT32 UsbDevice)
 
205
{
 
206
        IUDEVICE* pdev;
 
207
        UINT32 out_size;
 
208
        UINT32 InterfaceId;
 
209
        UINT32 IoControlCode;
 
210
        UINT32 InputBufferSize;
 
211
        UINT32 OutputBufferSize;
 
212
        UINT32 RequestId;
 
213
        UINT32 usbd_status = USBD_STATUS_SUCCESS;
 
214
        BYTE* OutputBuffer;
 
215
        BYTE* out_data;
 
216
        int i, offset, success = 0;
 
217
 
 
218
        LLOGLN(urbdrc_debug, ("urbdrc_process__io_control"));
 
219
 
 
220
        data_read_UINT32(data + 0, IoControlCode);
 
221
        data_read_UINT32(data + 4, InputBufferSize);
 
222
        data_read_UINT32(data + 8 + InputBufferSize, OutputBufferSize);
 
223
        data_read_UINT32(data + 12 + InputBufferSize, RequestId);
 
224
 
 
225
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
226
 
 
227
        if (pdev == NULL)
 
228
                return 0;
 
229
 
 
230
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
231
 
 
232
        /**  process */
 
233
        OutputBuffer = (BYTE *)malloc(OutputBufferSize);
 
234
        memset(OutputBuffer, 0, OutputBufferSize);
 
235
 
 
236
        switch (IoControlCode)
 
237
        {
 
238
                case IOCTL_INTERNAL_USB_SUBMIT_URB:  /** 0x00220003 */
 
239
                        LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_SUBMIT_URB"));
 
240
                        fprintf(stderr, " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked\n");
 
241
                        break;
 
242
 
 
243
                case IOCTL_INTERNAL_USB_RESET_PORT:  /** 0x00220007 */
 
244
                        LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_RESET_PORT"));
 
245
                        break;
 
246
 
 
247
                case IOCTL_INTERNAL_USB_GET_PORT_STATUS: /** 0x00220013 */
 
248
                        LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_GET_PORT_STATUS"));
 
249
 
 
250
                        success = pdev->query_device_port_status(pdev, &usbd_status, &OutputBufferSize, OutputBuffer);
 
251
 
 
252
                        if (success)
 
253
                        {
 
254
                                if (pdev->isExist(pdev) == 0)
 
255
                                {
 
256
                                        data_write_UINT32(OutputBuffer, 0);
 
257
                                }
 
258
                                else
 
259
                                {
 
260
                                        usb_process_get_port_status(pdev, OutputBuffer);
 
261
                                        OutputBufferSize = 4;
 
262
                                }
 
263
 
 
264
                                LLOGLN(urbdrc_debug, ("PORT STATUS(fake!):0x%02x%02x%02x%02x",
 
265
                                        OutputBuffer[3], OutputBuffer[2], OutputBuffer[1], OutputBuffer[0]));
 
266
                        }
 
267
 
 
268
                        break;
 
269
 
 
270
                case IOCTL_INTERNAL_USB_CYCLE_PORT:  /** 0x0022001F */
 
271
                        LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_CYCLE_PORT"));
 
272
                        fprintf(stderr, " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked\n");
 
273
                        break;
 
274
 
 
275
                case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: /** 0x00220027 */
 
276
                        LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION"));
 
277
                        fprintf(stderr, " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked\n");
 
278
                        break;
 
279
 
 
280
                default:
 
281
                        LLOGLN(urbdrc_debug, ("urbdrc_process_io_control: unknown IoControlCode 0x%X", IoControlCode));
 
282
                        return -1;
 
283
                        break;
 
284
        }
 
285
 
 
286
        offset = 28;
 
287
        out_size = offset + OutputBufferSize;
 
288
        out_data = (BYTE *) malloc(out_size);
 
289
        memset(out_data, 0, out_size);
 
290
        data_write_UINT32(out_data + 0, InterfaceId); /** interface */
 
291
        data_write_UINT32(out_data + 4, MessageId); /** message id */
 
292
        data_write_UINT32(out_data + 8, IOCONTROL_COMPLETION); /** function id */
 
293
        data_write_UINT32(out_data + 12, RequestId); /** RequestId */
 
294
        data_write_UINT32(out_data + 16, USBD_STATUS_SUCCESS); /** HResult */
 
295
        data_write_UINT32(out_data + 20, OutputBufferSize); /** Information */
 
296
        data_write_UINT32(out_data + 24, OutputBufferSize); /** OutputBufferSize */
 
297
 
 
298
        for (i=0;i<OutputBufferSize;i++)
 
299
        {
 
300
                data_write_BYTE(out_data + offset, OutputBuffer[i]); /** OutputBuffer */
 
301
                offset += 1;
 
302
        }
 
303
 
 
304
        if (!pdev->isSigToEnd(pdev))
 
305
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
306
 
 
307
        zfree(out_data);
 
308
        zfree(OutputBuffer);
 
309
 
 
310
        return 0;
 
311
}
 
312
 
 
313
static int urbdrc_process_internal_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
 
314
                UINT32 data_sizem, UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice)
 
315
{
 
316
        IUDEVICE* pdev;
 
317
        BYTE* out_data;
 
318
        UINT32 out_size, IoControlCode, InterfaceId, InputBufferSize;
 
319
        UINT32 OutputBufferSize, RequestId, frames;
 
320
 
 
321
        data_read_UINT32(data + 0, IoControlCode);
 
322
 
 
323
        LLOGLN(urbdrc_debug, ("urbdrc_process_internal_io_control:0x%x", IoControlCode));
 
324
 
 
325
        data_read_UINT32(data + 4, InputBufferSize);
 
326
        data_read_UINT32(data + 8, OutputBufferSize);
 
327
        data_read_UINT32(data + 12, RequestId);
 
328
 
 
329
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
330
 
 
331
        if (pdev == NULL)
 
332
                return 0;
 
333
 
 
334
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
335
 
 
336
        /** Fixme: Currently this is a FALSE bustime... */
 
337
        urbdrc_get_mstime(frames);
 
338
 
 
339
        out_size = 32;
 
340
        out_data = (BYTE *) malloc(out_size);
 
341
        memset(out_data, 0, out_size);
 
342
        data_write_UINT32(out_data + 0, InterfaceId); /** interface */
 
343
        data_write_UINT32(out_data + 4, MessageId); /** message id */
 
344
        data_write_UINT32(out_data + 8, IOCONTROL_COMPLETION); /** function id */
 
345
        data_write_UINT32(out_data + 12, RequestId); /** RequestId */
 
346
        data_write_UINT32(out_data + 16, 0); /** HResult */
 
347
        data_write_UINT32(out_data + 20, 4); /** Information */
 
348
        data_write_UINT32(out_data + 24, 4); /** OutputBufferSize */
 
349
        data_write_UINT32(out_data + 28, frames); /** OutputBuffer */
 
350
 
 
351
        if (!pdev->isSigToEnd(pdev))
 
352
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
353
 
 
354
        zfree(out_data);
 
355
 
 
356
        return 0;
 
357
}
 
358
 
 
359
static int urbdrc_process_query_device_text(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
 
360
                UINT32 data_sizem, UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice)
 
361
{
 
362
        IUDEVICE* pdev;
 
363
        UINT32 out_size;
 
364
        UINT32 InterfaceId;
 
365
        UINT32 TextType;
 
366
        UINT32 LocaleId;
 
367
        UINT32 bufferSize = 1024;
 
368
        BYTE* out_data;
 
369
        BYTE DeviceDescription[bufferSize];
 
370
        int out_offset;
 
371
 
 
372
        LLOGLN(urbdrc_debug, ("urbdrc_process_query_device_text"));
 
373
 
 
374
        data_read_UINT32(data + 0, TextType);
 
375
        data_read_UINT32(data + 4, LocaleId);
 
376
 
 
377
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
378
 
 
379
        if (pdev == NULL)
 
380
                return 0;
 
381
 
 
382
        pdev->control_query_device_text(pdev, TextType, LocaleId, &bufferSize, DeviceDescription);
 
383
 
 
384
        InterfaceId = ((STREAM_ID_STUB << 30) | UsbDevice);
 
385
 
 
386
        out_offset = 16;
 
387
        out_size = out_offset + bufferSize;
 
388
 
 
389
        if (bufferSize != 0)
 
390
                out_size += 2;
 
391
 
 
392
        out_data = (BYTE*) malloc(out_size);
 
393
        memset(out_data, 0, out_size);
 
394
 
 
395
        data_write_UINT32(out_data + 0, InterfaceId); /** interface */
 
396
        data_write_UINT32(out_data + 4, MessageId); /** message id */
 
397
 
 
398
        if (bufferSize != 0)
 
399
        {
 
400
                data_write_UINT32(out_data + 8, (bufferSize/2)+1); /** cchDeviceDescription */
 
401
                out_offset = 12;
 
402
                memcpy(out_data + out_offset, DeviceDescription, bufferSize);
 
403
                out_offset += bufferSize;
 
404
                data_write_UINT16(out_data + out_offset, 0x0000);
 
405
                out_offset += 2;
 
406
        }
 
407
        else
 
408
        {
 
409
                data_write_UINT32(out_data + 8, 0); /** cchDeviceDescription */
 
410
                out_offset = 12;
 
411
        }
 
412
 
 
413
        data_write_UINT32(out_data + out_offset, 0); /** HResult */
 
414
 
 
415
        if (!pdev->isSigToEnd(pdev))
 
416
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
417
 
 
418
        zfree(out_data);
 
419
 
 
420
        return 0;
 
421
}
 
422
 
 
423
static void func_select_all_interface_for_msconfig(IUDEVICE* pdev, MSUSB_CONFIG_DESCRIPTOR* MsConfig)
 
424
{
 
425
        int inum;
 
426
        MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
 
427
        BYTE  InterfaceNumber, AlternateSetting;
 
428
        UINT32 NumInterfaces = MsConfig->NumInterfaces;
 
429
 
 
430
        for (inum = 0; inum < NumInterfaces; inum++)
 
431
        {
 
432
                InterfaceNumber = MsInterfaces[inum]->InterfaceNumber;
 
433
                AlternateSetting = MsInterfaces[inum]->AlternateSetting;
 
434
                pdev->select_interface(pdev, InterfaceNumber, AlternateSetting);
 
435
        }
 
436
}
 
437
 
 
438
static int urb_select_configuration(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
 
439
        UINT32 data_sizem, UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice, int transferDir)
 
440
{
 
441
        MSUSB_CONFIG_DESCRIPTOR * MsConfig = NULL;
 
442
        IUDEVICE* pdev = NULL;
 
443
        UINT32 out_size, InterfaceId, RequestId, NumInterfaces, usbd_status = 0;
 
444
        BYTE ConfigurationDescriptorIsValid;
 
445
        BYTE* out_data;
 
446
        int MsOutSize = 0, offset = 0;
 
447
 
 
448
        if (transferDir == 0)
 
449
        {
 
450
                fprintf(stderr, "urb_select_configuration: not support transfer out\n");
 
451
                return -1;
 
452
        }
 
453
 
 
454
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
455
 
 
456
        if (pdev == NULL)
 
457
                return 0;
 
458
 
 
459
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
460
        data_read_UINT32(data + 0, RequestId);
 
461
        data_read_BYTE(data + 4, ConfigurationDescriptorIsValid);
 
462
        data_read_UINT32(data + 8, NumInterfaces);
 
463
        offset = 12;
 
464
 
 
465
        /** if ConfigurationDescriptorIsValid is zero, then just do nothing.*/
 
466
        if (ConfigurationDescriptorIsValid)
 
467
        {
 
468
                /* parser data for struct config */
 
469
                MsConfig = msusb_msconfig_read(data + offset, data_sizem - offset, NumInterfaces);
 
470
                /* select config */
 
471
                pdev->select_configuration(pdev, MsConfig->bConfigurationValue);
 
472
                /* select all interface */
 
473
                func_select_all_interface_for_msconfig(pdev, MsConfig);
 
474
                /* complete configuration setup */
 
475
                MsConfig = pdev->complete_msconfig_setup(pdev, MsConfig);
 
476
        }
 
477
 
 
478
        if (MsConfig)
 
479
                MsOutSize = MsConfig->MsOutSize;
 
480
 
 
481
        if (MsOutSize > 0)
 
482
                out_size = 36 + MsOutSize;
 
483
        else
 
484
                out_size = 44;
 
485
        out_data = (BYTE *) malloc(out_size);
 
486
        memset(out_data, 0, out_size);
 
487
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
488
        data_write_UINT32(out_data + 4, MessageId);             /** message id */
 
489
        data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);        /** function id */
 
490
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
491
        if (MsOutSize > 0)
 
492
        {
 
493
                /** CbTsUrbResult */
 
494
                data_write_UINT32(out_data + 16, 8 + MsOutSize);
 
495
                /** TS_URB_RESULT_HEADER Size*/
 
496
                data_write_UINT16(out_data + 20, 8 + MsOutSize);
 
497
        }
 
498
        else
 
499
        {
 
500
                data_write_UINT32(out_data + 16, 16);
 
501
                data_write_UINT16(out_data + 20, 16);
 
502
        }
 
503
 
 
504
        /** Padding, MUST be ignored upon receipt */
 
505
        data_write_UINT16(out_data + 22, URB_FUNCTION_SELECT_CONFIGURATION);
 
506
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
507
        offset = 28;
 
508
        /** TS_URB_SELECT_CONFIGURATION_RESULT */
 
509
        if (MsOutSize > 0)
 
510
        {
 
511
                msusb_msconfig_write(MsConfig, out_data, &offset);
 
512
        }
 
513
        else
 
514
        {
 
515
                data_write_UINT32(out_data + offset, 0);        /** ConfigurationHandle */
 
516
                data_write_UINT32(out_data + offset + 4, NumInterfaces);        /** NumInterfaces */
 
517
                offset += 8;
 
518
        }
 
519
        data_write_UINT32(out_data + offset, 0);        /** HResult */
 
520
        data_write_UINT32(out_data + offset + 4, 0);    /** OutputBufferSize */
 
521
 
 
522
        if (!pdev->isSigToEnd(pdev))
 
523
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
524
        zfree(out_data);
 
525
        return 0;
 
526
}
 
527
 
 
528
static int urb_select_interface(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data, UINT32 data_sizem,
 
529
        UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice, int transferDir)
 
530
{
 
531
        MSUSB_CONFIG_DESCRIPTOR* MsConfig;
 
532
        MSUSB_INTERFACE_DESCRIPTOR* MsInterface;
 
533
        IUDEVICE* pdev;
 
534
        UINT32 out_size, InterfaceId, RequestId, ConfigurationHandle;
 
535
        UINT32 OutputBufferSize;
 
536
        BYTE InterfaceNumber;
 
537
        BYTE* out_data;
 
538
        int out_offset, interface_size;
 
539
 
 
540
        if (transferDir == 0)
 
541
        {
 
542
                fprintf(stderr, "urb_select_interface: not support transfer out\n");
 
543
                return -1;
 
544
        }
 
545
 
 
546
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
547
 
 
548
        if (pdev == NULL)
 
549
                return 0;
 
550
 
 
551
        InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
552
 
 
553
        data_read_UINT32(data + 0, RequestId);
 
554
        data_read_UINT32(data + 4, ConfigurationHandle);
 
555
        out_offset = 8;
 
556
 
 
557
        MsInterface = msusb_msinterface_read(data + out_offset, data_sizem - out_offset, &out_offset);
 
558
 
 
559
        data_read_UINT32(data + out_offset, OutputBufferSize);
 
560
 
 
561
        pdev->select_interface(pdev, MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
 
562
 
 
563
        /* replace device's MsInterface */
 
564
        MsConfig = pdev->get_MsConfig(pdev);
 
565
        InterfaceNumber = MsInterface->InterfaceNumber;
 
566
        msusb_msinterface_replace(MsConfig, InterfaceNumber, MsInterface);
 
567
 
 
568
        /* complete configuration setup */
 
569
        MsConfig = pdev->complete_msconfig_setup(pdev, MsConfig);
 
570
        MsInterface = MsConfig->MsInterfaces[InterfaceNumber];
 
571
        interface_size = 16 + (MsInterface->NumberOfPipes * 20);
 
572
 
 
573
        out_size = 36 + interface_size ;
 
574
        out_data = (BYTE*) malloc(out_size);
 
575
        memset(out_data, 0, out_size);
 
576
 
 
577
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
578
        data_write_UINT32(out_data + 4, MessageId);             /** message id */
 
579
        data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);        /** function id */
 
580
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
581
        data_write_UINT32(out_data + 16, 8 + interface_size);   /** CbTsUrbResult */
 
582
        /** TS_URB_RESULT_HEADER */
 
583
        data_write_UINT16(out_data + 20, 8 + interface_size);   /** Size */
 
584
        /** Padding, MUST be ignored upon receipt */
 
585
        data_write_UINT16(out_data + 22, URB_FUNCTION_SELECT_INTERFACE);
 
586
        data_write_UINT32(out_data + 24, USBD_STATUS_SUCCESS);  /** UsbdStatus */
 
587
        out_offset = 28;
 
588
 
 
589
        /** TS_URB_SELECT_INTERFACE_RESULT */
 
590
        msusb_msinterface_write(MsInterface, out_data + out_offset, &out_offset);
 
591
 
 
592
        data_write_UINT32(out_data + out_offset, 0);    /** HResult */
 
593
        data_write_UINT32(out_data + out_offset + 4, OutputBufferSize); /** OutputBufferSize */
 
594
 
 
595
        if (!pdev->isSigToEnd(pdev))
 
596
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
597
 
 
598
        zfree(out_data);
 
599
 
 
600
        return 0;
 
601
}
 
602
 
 
603
static int urb_control_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
 
604
        UINT32 data_sizem, UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice, int transferDir, int External)
 
605
{
 
606
        IUDEVICE* pdev;
 
607
        UINT32 out_size, RequestId, InterfaceId, EndpointAddress, PipeHandle;
 
608
        UINT32 TransferFlags, OutputBufferSize, usbd_status, Timeout;
 
609
        BYTE bmRequestType, Request;
 
610
        UINT16 Value, Index, length;
 
611
        BYTE* buffer;
 
612
        BYTE* out_data;
 
613
        int offset, ret;
 
614
 
 
615
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
616
 
 
617
        if (pdev == NULL)
 
618
                return 0;
 
619
 
 
620
        InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
621
        data_read_UINT32(data + 0, RequestId);
 
622
        data_read_UINT32(data + 4, PipeHandle);
 
623
        data_read_UINT32(data + 8, TransferFlags); /** TransferFlags */
 
624
 
 
625
        EndpointAddress = (PipeHandle & 0x000000ff);
 
626
        offset  = 12;
 
627
        Timeout = 2000;
 
628
 
 
629
        switch (External)
 
630
        {
 
631
                case URB_CONTROL_TRANSFER_EXTERNAL:
 
632
                        data_read_UINT32(data + offset, Timeout); /** TransferFlags */
 
633
                        offset += 4;
 
634
                        break;
 
635
                case URB_CONTROL_TRANSFER_NONEXTERNAL:
 
636
                        break;
 
637
        }
 
638
 
 
639
        /** SetupPacket 8 bytes */
 
640
        data_read_BYTE(data + offset, bmRequestType);
 
641
        data_read_BYTE(data + offset + 1, Request);
 
642
        data_read_UINT16(data + offset + 2, Value);
 
643
        data_read_UINT16(data + offset + 4, Index);
 
644
        data_read_UINT16(data + offset + 6, length);
 
645
        data_read_UINT32(data + offset + 8, OutputBufferSize);
 
646
        offset +=  12;
 
647
 
 
648
        if (length != OutputBufferSize)
 
649
        {
 
650
                LLOGLN(urbdrc_debug, ("urb_control_transfer ERROR: buf != length"));
 
651
                return -1;
 
652
        }
 
653
 
 
654
        out_size = 36 + OutputBufferSize;
 
655
        out_data = (BYTE *) malloc(out_size);
 
656
        memset(out_data, 0, out_size);
 
657
 
 
658
        buffer = out_data + 36;
 
659
 
 
660
        /** Get Buffer Data */
 
661
        if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
662
                memcpy(buffer, data + offset, OutputBufferSize);
 
663
 
 
664
        /**  process URB_FUNCTION_CONTROL_TRANSFER */
 
665
        ret = pdev->control_transfer(
 
666
                pdev, RequestId, EndpointAddress, TransferFlags,
 
667
                bmRequestType,
 
668
                Request,
 
669
                Value,
 
670
                Index,
 
671
                &usbd_status,
 
672
                &OutputBufferSize,
 
673
                buffer,
 
674
                Timeout);
 
675
 
 
676
        if (ret < 0){
 
677
                LLOGLN(urbdrc_debug, ("control_transfer: error num %d!!\n", ret));
 
678
                OutputBufferSize = 0;
 
679
        }
 
680
 
 
681
        /** send data */
 
682
        offset = 36;
 
683
        if (transferDir == USBD_TRANSFER_DIRECTION_IN)
 
684
                out_size = offset + OutputBufferSize;
 
685
        else
 
686
                out_size = offset;
 
687
 
 
688
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
689
        data_write_UINT32(out_data + 4, MessageId);             /** message id */
 
690
 
 
691
        if(transferDir == USBD_TRANSFER_DIRECTION_IN && OutputBufferSize != 0)
 
692
                data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
693
        else
 
694
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
695
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
696
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
697
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
698
        data_write_UINT16(out_data + 20, 0x0008);       /** Size */
 
699
 
 
700
        /** Padding, MUST be ignored upon receipt */
 
701
        data_write_UINT16(out_data + 22, URB_FUNCTION_CONTROL_TRANSFER);
 
702
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
703
 
 
704
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
705
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
706
 
 
707
        if (!pdev->isSigToEnd(pdev))
 
708
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
709
 
 
710
        zfree(out_data);
 
711
 
 
712
        return 0;
 
713
}
 
714
 
 
715
static int urb_bulk_or_interrupt_transfer(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data,
 
716
        UINT32 data_sizem, UINT32 MessageId, IUDEVMAN* udevman, UINT32 UsbDevice, int transferDir)
 
717
{
 
718
        int offset;
 
719
        BYTE* Buffer;
 
720
        IUDEVICE* pdev;
 
721
        BYTE* out_data;
 
722
        UINT32 out_size, RequestId, InterfaceId, EndpointAddress, PipeHandle;
 
723
        UINT32 TransferFlags, OutputBufferSize, usbd_status = 0;
 
724
 
 
725
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
726
 
 
727
        if (pdev == NULL)
 
728
                return 0;
 
729
 
 
730
        InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
731
 
 
732
        data_read_UINT32(data + 0, RequestId);
 
733
        data_read_UINT32(data + 4, PipeHandle);
 
734
        data_read_UINT32(data + 8, TransferFlags);      /** TransferFlags */
 
735
        data_read_UINT32(data + 12, OutputBufferSize);
 
736
        offset = 16;
 
737
        EndpointAddress = (PipeHandle & 0x000000ff);
 
738
 
 
739
        if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
740
                out_size = 36;
 
741
        else
 
742
                out_size = 36 + OutputBufferSize;
 
743
 
 
744
        Buffer = NULL;
 
745
        out_data = (BYTE*) malloc(out_size);
 
746
        memset(out_data, 0, out_size);
 
747
 
 
748
        switch (transferDir)
 
749
        {
 
750
                case USBD_TRANSFER_DIRECTION_OUT:
 
751
                        Buffer = data + offset;
 
752
                        break;
 
753
 
 
754
                case USBD_TRANSFER_DIRECTION_IN:
 
755
                        Buffer = out_data + 36;
 
756
                        break;
 
757
        }
 
758
 
 
759
        /**  process URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER */
 
760
        pdev->bulk_or_interrupt_transfer(
 
761
                pdev, RequestId, EndpointAddress,
 
762
                TransferFlags,
 
763
                &usbd_status,
 
764
                &OutputBufferSize,
 
765
                Buffer,
 
766
                10000);
 
767
 
 
768
        offset = 36;
 
769
        if (transferDir == USBD_TRANSFER_DIRECTION_IN)
 
770
                out_size = offset + OutputBufferSize;
 
771
        else
 
772
                out_size = offset;
 
773
        /** send data */
 
774
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
775
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
776
        if(transferDir == USBD_TRANSFER_DIRECTION_IN && OutputBufferSize != 0)
 
777
                data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
778
        else
 
779
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
780
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
781
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
782
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
783
        data_write_UINT16(out_data + 20, 0x0008);       /** Size */
 
784
 
 
785
        /** Padding, MUST be ignored upon receipt */
 
786
        data_write_UINT16(out_data + 22, URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER);
 
787
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
788
 
 
789
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
790
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
791
 
 
792
        if (pdev && !pdev->isSigToEnd(pdev))
 
793
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
794
 
 
795
        zfree(out_data);
 
796
 
 
797
        return 0;
 
798
}
 
799
 
 
800
 
 
801
static int urb_isoch_transfer(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
 
802
        UINT32 data_sizem,
 
803
        UINT32 MessageId,
 
804
        IUDEVMAN * udevman,
 
805
        UINT32 UsbDevice,
 
806
        int transferDir)
 
807
{
 
808
        IUDEVICE * pdev;
 
809
        UINT32  RequestId, InterfaceId, EndpointAddress;
 
810
        UINT32  PipeHandle, TransferFlags, StartFrame, NumberOfPackets;
 
811
        UINT32  ErrorCount, OutputBufferSize, usbd_status = 0;
 
812
        UINT32  RequestField, noAck = 0;
 
813
        UINT32  out_size = 0;
 
814
        BYTE *  iso_buffer      = NULL;
 
815
        BYTE *  iso_packets     = NULL;
 
816
        BYTE *  out_data        = NULL;
 
817
        int     offset, nullBuffer = 0, iso_status;
 
818
 
 
819
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
820
        if (pdev == NULL)
 
821
                return 0;
 
822
        if (pdev->isSigToEnd(pdev))
 
823
                return 0;
 
824
 
 
825
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
826
        data_read_UINT32(data + 0, RequestField);
 
827
        RequestId                       = RequestField & 0x7fffffff;
 
828
        noAck                           = (RequestField & 0x80000000)>>31;
 
829
        data_read_UINT32(data + 4, PipeHandle);
 
830
        EndpointAddress         = (PipeHandle & 0x000000ff);
 
831
        data_read_UINT32(data + 8, TransferFlags); /** TransferFlags */
 
832
        data_read_UINT32(data + 12, StartFrame); /** StartFrame */
 
833
        data_read_UINT32(data + 16, NumberOfPackets); /** NumberOfPackets */
 
834
        data_read_UINT32(data + 20, ErrorCount); /** ErrorCount */
 
835
        offset = 24 + (NumberOfPackets * 12);
 
836
        data_read_UINT32(data + offset, OutputBufferSize);
 
837
        offset += 4;
 
838
 
 
839
        /** send data memory alloc */
 
840
        if (transferDir == USBD_TRANSFER_DIRECTION_OUT) {
 
841
                if (!noAck) {
 
842
                        out_size = 48 + (NumberOfPackets * 12);
 
843
                        out_data = (BYTE *) malloc(out_size);
 
844
                        iso_packets = out_data + 40;
 
845
                }
 
846
        }
 
847
        else {
 
848
                out_size = 48 + OutputBufferSize + (NumberOfPackets * 12);
 
849
                out_data = (BYTE *) malloc(out_size);
 
850
                iso_packets = out_data + 40;
 
851
        }
 
852
 
 
853
        if (out_size)
 
854
                memset(out_data, 0, out_size);
 
855
 
 
856
        switch (transferDir)
 
857
        {
 
858
                case USBD_TRANSFER_DIRECTION_OUT:
 
859
                        /** Get Buffer Data */
 
860
                        //memcpy(iso_buffer, data + offset, OutputBufferSize);
 
861
                        iso_buffer = data + offset;
 
862
                        break;
 
863
                case USBD_TRANSFER_DIRECTION_IN:
 
864
                        iso_buffer = out_data + 48 + (NumberOfPackets * 12);
 
865
                        break;
 
866
        }
 
867
 
 
868
        LLOGLN(urbdrc_debug, ("urb_isoch_transfer: EndpointAddress: 0x%x, "
 
869
                "TransferFlags: 0x%x, " "StartFrame: 0x%x, "
 
870
                "NumberOfPackets: 0x%x, " "OutputBufferSize: 0x%x "
 
871
                "RequestId: 0x%x",
 
872
                EndpointAddress, TransferFlags, StartFrame,
 
873
                NumberOfPackets, OutputBufferSize, RequestId));
 
874
 
 
875
#if ISOCH_FIFO
 
876
        ISOCH_CALLBACK_QUEUE * isoch_queue = NULL;
 
877
        ISOCH_CALLBACK_DATA * isoch = NULL;
 
878
        if(!noAck)
 
879
        {
 
880
                isoch_queue = (ISOCH_CALLBACK_QUEUE *)pdev->get_isoch_queue(pdev);
 
881
                isoch = isoch_queue->register_data(isoch_queue, callback, pdev);
 
882
        }
 
883
#endif
 
884
 
 
885
        iso_status = pdev->isoch_transfer(
 
886
                pdev, RequestId, EndpointAddress,
 
887
                TransferFlags,
 
888
                noAck,
 
889
                &ErrorCount,
 
890
                &usbd_status,
 
891
                &StartFrame,
 
892
                NumberOfPackets,
 
893
                iso_packets,
 
894
                &OutputBufferSize,
 
895
                iso_buffer,
 
896
                2000);
 
897
 
 
898
        if(noAck)
 
899
        {
 
900
                zfree(out_data);
 
901
                return 0;
 
902
        }
 
903
 
 
904
        if (iso_status < 0)
 
905
                nullBuffer = 1;
 
906
 
 
907
 
 
908
        out_size = 48;
 
909
        if (nullBuffer)
 
910
                OutputBufferSize = 0;
 
911
        else
 
912
                out_size += OutputBufferSize + (NumberOfPackets * 12);
 
913
        /* fill the send data */
 
914
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
915
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
916
        if(OutputBufferSize != 0 && !nullBuffer)
 
917
                data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
918
        else
 
919
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
920
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
921
        data_write_UINT32(out_data + 16, 20 + (NumberOfPackets * 12));  /** CbTsUrbResult */
 
922
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
923
        data_write_UINT16(out_data + 20, 20 + (NumberOfPackets * 12));  /** Size */
 
924
        /** Padding, MUST be ignored upon receipt */
 
925
        data_write_UINT16(out_data + 22, URB_FUNCTION_ISOCH_TRANSFER);
 
926
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
927
 
 
928
        data_write_UINT32(out_data + 28, StartFrame);   /** StartFrame */
 
929
        if (!nullBuffer)
 
930
        {
 
931
                /** NumberOfPackets */
 
932
                data_write_UINT32(out_data + 32, NumberOfPackets);
 
933
                data_write_UINT32(out_data + 36, ErrorCount);   /** ErrorCount */
 
934
                offset = 40 + (NumberOfPackets * 12);
 
935
        }
 
936
        else
 
937
        {
 
938
                data_write_UINT32(out_data + 32, 0);    /** NumberOfPackets */
 
939
                data_write_UINT32(out_data + 36, NumberOfPackets);      /** ErrorCount */
 
940
                offset = 40;
 
941
        }
 
942
 
 
943
        data_write_UINT32(out_data + offset, 0);        /** HResult */
 
944
        data_write_UINT32(out_data + offset + 4, OutputBufferSize);     /** OutputBufferSize */
 
945
 
 
946
#if ISOCH_FIFO
 
947
        if(!noAck){
 
948
                pthread_mutex_lock(&isoch_queue->isoch_loading);
 
949
                isoch->out_data = out_data;
 
950
                isoch->out_size = out_size;
 
951
                pthread_mutex_unlock(&isoch_queue->isoch_loading);
 
952
        }
 
953
#else
 
954
        if (!pdev->isSigToEnd(pdev))
 
955
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
956
        zfree(out_data);
 
957
#endif
 
958
 
 
959
        if (nullBuffer)
 
960
                return -1;
 
961
 
 
962
        return 0;
 
963
}
 
964
 
 
965
static int urb_control_descriptor_request(URBDRC_CHANNEL_CALLBACK* callback,
 
966
        BYTE * data,
 
967
        UINT32 data_sizem,
 
968
        UINT32 MessageId,
 
969
        IUDEVMAN * udevman,
 
970
        UINT32 UsbDevice,
 
971
        BYTE func_recipient,
 
972
        int transferDir)
 
973
{
 
974
        IUDEVICE* pdev;
 
975
        UINT32 out_size, InterfaceId, RequestId, OutputBufferSize, usbd_status;
 
976
        BYTE bmRequestType, desc_index, desc_type;
 
977
        UINT16 langId;
 
978
        BYTE* buffer;
 
979
        BYTE* out_data;
 
980
        int ret, offset;
 
981
 
 
982
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
983
 
 
984
        if (pdev == NULL)
 
985
                return 0;
 
986
 
 
987
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
988
        data_read_UINT32(data + 0, RequestId);
 
989
        data_read_BYTE(data + 4, desc_index);
 
990
        data_read_BYTE(data + 5, desc_type);
 
991
        data_read_UINT16(data + 6, langId);
 
992
        data_read_UINT32(data + 8, OutputBufferSize);
 
993
 
 
994
        out_size = 36 + OutputBufferSize;
 
995
        out_data = (BYTE *) malloc(out_size);
 
996
        memset(out_data, 0, out_size);
 
997
 
 
998
        buffer = out_data + 36;
 
999
 
 
1000
        bmRequestType = func_recipient;
 
1001
        switch (transferDir)
 
1002
        {
 
1003
                case USBD_TRANSFER_DIRECTION_IN:
 
1004
                        bmRequestType |= 0x80;
 
1005
                        break;
 
1006
                case USBD_TRANSFER_DIRECTION_OUT:
 
1007
                        bmRequestType |= 0x00;
 
1008
                        offset = 12;
 
1009
                        memcpy(buffer, data + offset, OutputBufferSize);
 
1010
                        break;
 
1011
                default:
 
1012
                        LLOGLN(urbdrc_debug, ("%s: get error transferDir", __func__));
 
1013
                        OutputBufferSize = 0;
 
1014
                        usbd_status = USBD_STATUS_STALL_PID;
 
1015
                        break;
 
1016
        }
 
1017
 
 
1018
        /** process get usb device descriptor */
 
1019
 
 
1020
        ret = pdev->control_transfer(
 
1021
                pdev, RequestId, 0, 0, bmRequestType,
 
1022
                0x06, /* REQUEST_GET_DESCRIPTOR */
 
1023
                (desc_type << 8) | desc_index,
 
1024
                langId,
 
1025
                &usbd_status,
 
1026
                &OutputBufferSize,
 
1027
                buffer,
 
1028
                1000);
 
1029
 
 
1030
 
 
1031
        if (ret < 0) {
 
1032
                LLOGLN(urbdrc_debug, ("%s:get_descriptor: error num %d", __func__, ret));
 
1033
                OutputBufferSize = 0;
 
1034
        }
 
1035
 
 
1036
        offset = 36;
 
1037
        out_size = offset + OutputBufferSize;
 
1038
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1039
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
1040
        data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
1041
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1042
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
1043
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1044
        data_write_UINT16(out_data + 20, 0x0008);       /** Size */
 
1045
        /** Padding, MUST be ignored upon receipt */
 
1046
        data_write_UINT16(out_data + 22, URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE);
 
1047
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1048
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1049
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1050
 
 
1051
        if (!pdev->isSigToEnd(pdev))
 
1052
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1053
 
 
1054
        zfree(out_data);
 
1055
        return 0;
 
1056
}
 
1057
 
 
1058
static int urb_control_get_status_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
 
1059
        UINT32 data_sizem,
 
1060
        UINT32 MessageId,
 
1061
        IUDEVMAN * udevman,
 
1062
        UINT32 UsbDevice,
 
1063
        BYTE func_recipient,
 
1064
        int transferDir)
 
1065
{
 
1066
        IUDEVICE* pdev;
 
1067
        UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
 
1068
        UINT16 Index;
 
1069
        BYTE bmRequestType;
 
1070
        BYTE* buffer;
 
1071
        BYTE* out_data;
 
1072
        int offset, ret;
 
1073
 
 
1074
        if (transferDir == 0){
 
1075
                LLOGLN(urbdrc_debug, ("urb_control_get_status_request: not support transfer out\n"));
 
1076
                return -1;
 
1077
        }
 
1078
 
 
1079
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1080
        if (pdev == NULL)
 
1081
                return 0;
 
1082
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1083
 
 
1084
        data_read_UINT32(data + 0, RequestId);
 
1085
        data_read_UINT16(data + 4, Index); /** Index */
 
1086
        data_read_UINT32(data + 8, OutputBufferSize);
 
1087
 
 
1088
        out_size = 36 + OutputBufferSize;
 
1089
        out_data = (BYTE *) malloc(out_size);
 
1090
        memset(out_data, 0, out_size);
 
1091
 
 
1092
        buffer = out_data + 36;
 
1093
 
 
1094
        bmRequestType = func_recipient | 0x80;
 
1095
 
 
1096
        ret = pdev->control_transfer(
 
1097
                pdev, RequestId, 0, 0, bmRequestType,
 
1098
                0x00, /* REQUEST_GET_STATUS */
 
1099
                0,
 
1100
                Index,
 
1101
                &usbd_status,
 
1102
                &OutputBufferSize,
 
1103
                buffer,
 
1104
                1000);
 
1105
 
 
1106
        if (ret < 0){
 
1107
                LLOGLN(urbdrc_debug, ("%s:control_transfer: error num %d!!\n", __func__, ret));
 
1108
                OutputBufferSize = 0;
 
1109
                usbd_status = USBD_STATUS_STALL_PID;
 
1110
        }
 
1111
        else{
 
1112
                usbd_status = USBD_STATUS_SUCCESS;
 
1113
        }
 
1114
 
 
1115
        /** send data */
 
1116
        offset = 36;
 
1117
        if (transferDir == USBD_TRANSFER_DIRECTION_IN)
 
1118
                out_size = offset + OutputBufferSize;
 
1119
        else
 
1120
                out_size = offset;
 
1121
 
 
1122
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1123
        data_write_UINT32(out_data + 4, MessageId);             /** message id */
 
1124
 
 
1125
        if(transferDir == USBD_TRANSFER_DIRECTION_IN && OutputBufferSize != 0)
 
1126
                data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
1127
        else
 
1128
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1129
 
 
1130
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId, include NoAck*/
 
1131
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
1132
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1133
        data_write_UINT16(out_data + 20, 0x0008);               /** Size */
 
1134
        /** Padding, MUST be ignored upon receipt */
 
1135
        data_write_UINT16(out_data + 22, URB_FUNCTION_VENDOR_DEVICE);
 
1136
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1137
 
 
1138
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1139
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1140
 
 
1141
        if (!pdev->isSigToEnd(pdev))
 
1142
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1143
 
 
1144
        zfree(out_data);
 
1145
 
 
1146
        return 0;
 
1147
}
 
1148
 
 
1149
static int urb_control_vendor_or_class_request(URBDRC_CHANNEL_CALLBACK * callback,
 
1150
        BYTE * data,
 
1151
        UINT32 data_sizem,
 
1152
        UINT32 MessageId,
 
1153
        IUDEVMAN * udevman,
 
1154
        UINT32 UsbDevice,
 
1155
        BYTE func_type,
 
1156
        BYTE func_recipient,
 
1157
        int transferDir)
 
1158
{
 
1159
        IUDEVICE* pdev;
 
1160
        UINT32 out_size, RequestId, InterfaceId, TransferFlags, usbd_status;
 
1161
        UINT32 OutputBufferSize;
 
1162
        BYTE ReqTypeReservedBits, Request, bmRequestType;
 
1163
        UINT16 Value, Index, Padding;
 
1164
        BYTE* buffer;
 
1165
        BYTE* out_data;
 
1166
        int offset, ret;
 
1167
        /** control by vendor command */
 
1168
 
 
1169
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1170
        if (pdev == NULL)
 
1171
                return 0;
 
1172
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1173
 
 
1174
        data_read_UINT32(data + 0, RequestId);
 
1175
        data_read_UINT32(data + 4, TransferFlags); /** TransferFlags */
 
1176
        data_read_BYTE(data + 8, ReqTypeReservedBits); /** ReqTypeReservedBids */
 
1177
        data_read_BYTE(data + 9, Request); /** Request */
 
1178
        data_read_UINT16(data + 10, Value); /** value */
 
1179
        data_read_UINT16(data + 12, Index); /** index */
 
1180
        data_read_UINT16(data + 14, Padding); /** Padding */
 
1181
        data_read_UINT32(data + 16, OutputBufferSize);
 
1182
        offset = 20;
 
1183
 
 
1184
        out_size = 36 + OutputBufferSize;
 
1185
        out_data = (BYTE *) malloc(out_size);
 
1186
        memset(out_data, 0, out_size);
 
1187
 
 
1188
        buffer = out_data + 36;
 
1189
 
 
1190
        /** Get Buffer */
 
1191
        if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
1192
                memcpy(buffer, data + offset, OutputBufferSize);
 
1193
 
 
1194
        /** vendor or class command */
 
1195
        bmRequestType = func_type | func_recipient;
 
1196
 
 
1197
        if (TransferFlags & USBD_TRANSFER_DIRECTION)
 
1198
                bmRequestType |= 0x80;
 
1199
 
 
1200
        LLOGLN(urbdrc_debug, ("urb_control_vendor_or_class_request: "
 
1201
                "RequestId 0x%x TransferFlags: 0x%x ReqTypeReservedBits: 0x%x "
 
1202
                "Request:0x%x Value: 0x%x Index: 0x%x OutputBufferSize: 0x%x bmRequestType: 0x%x!!",
 
1203
                RequestId, TransferFlags, ReqTypeReservedBits, Request, Value,
 
1204
                Index, OutputBufferSize, bmRequestType));
 
1205
 
 
1206
        ret = pdev->control_transfer(
 
1207
                pdev, RequestId, 0, 0, bmRequestType,
 
1208
                Request,
 
1209
                Value,
 
1210
                Index,
 
1211
                &usbd_status,
 
1212
                &OutputBufferSize,
 
1213
                buffer,
 
1214
                2000);
 
1215
 
 
1216
        if (ret < 0){
 
1217
                LLOGLN(urbdrc_debug, ("%s:control_transfer: error num %d!!", __func__, ret));
 
1218
                OutputBufferSize = 0;
 
1219
                usbd_status = USBD_STATUS_STALL_PID;
 
1220
        }
 
1221
        else{
 
1222
                usbd_status = USBD_STATUS_SUCCESS;
 
1223
        }
 
1224
 
 
1225
        offset = 36;
 
1226
        if (transferDir == USBD_TRANSFER_DIRECTION_IN)
 
1227
                out_size = offset + OutputBufferSize;
 
1228
        else
 
1229
                out_size = offset;
 
1230
        /** send data */
 
1231
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1232
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
1233
 
 
1234
        if(transferDir == USBD_TRANSFER_DIRECTION_IN && OutputBufferSize != 0)
 
1235
                data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
1236
        else
 
1237
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1238
 
 
1239
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId, include NoAck*/
 
1240
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
1241
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1242
        data_write_UINT16(out_data + 20, 0x0008);       /** Size */
 
1243
        data_write_UINT16(out_data + 22, URB_FUNCTION_VENDOR_DEVICE);   /** Padding, MUST be ignored upon receipt */
 
1244
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1245
 
 
1246
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1247
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1248
 
 
1249
        if (!pdev->isSigToEnd(pdev))
 
1250
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1251
 
 
1252
        zfree(out_data);
 
1253
        return 0;
 
1254
}
 
1255
 
 
1256
 
 
1257
 
 
1258
static int urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback,
 
1259
        BYTE * data,
 
1260
        UINT32 data_sizem,
 
1261
        UINT32 MessageId,
 
1262
        IUDEVMAN * udevman,
 
1263
        UINT32 UsbDevice,
 
1264
        int transferDir)
 
1265
{
 
1266
        IUDEVICE* pdev;
 
1267
        UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
 
1268
        BYTE Recipient, InterfaceNumber, Ms_PageIndex;
 
1269
        UINT16 Ms_featureDescIndex;
 
1270
        BYTE* out_data;
 
1271
        BYTE* buffer;
 
1272
        int offset, ret;
 
1273
 
 
1274
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1275
 
 
1276
        if (pdev == NULL)
 
1277
                return 0;
 
1278
 
 
1279
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1280
 
 
1281
        data_read_UINT32(data + 0, RequestId);
 
1282
        data_read_BYTE(data + 4, Recipient); /** Recipient */
 
1283
        Recipient = Recipient && 0x1f;
 
1284
        data_read_BYTE(data + 5, InterfaceNumber); /** InterfaceNumber */
 
1285
        data_read_BYTE(data + 6, Ms_PageIndex); /** Ms_PageIndex */
 
1286
        data_read_UINT16(data + 7, Ms_featureDescIndex); /** Ms_featureDescIndex */
 
1287
        data_read_UINT32(data + 12, OutputBufferSize);
 
1288
        offset = 16;
 
1289
 
 
1290
        out_size = 36 + OutputBufferSize;
 
1291
        out_data = (BYTE *) malloc(out_size);
 
1292
        memset(out_data, 0, out_size);
 
1293
 
 
1294
        buffer = out_data + 36;
 
1295
 
 
1296
        switch (transferDir)
 
1297
        {
 
1298
                case USBD_TRANSFER_DIRECTION_OUT:
 
1299
                        fprintf(stderr, "Function urb_os_feature_descriptor_request: OUT Unchecked\n");
 
1300
                        memcpy(buffer, data + offset, OutputBufferSize);
 
1301
                        break;
 
1302
                case USBD_TRANSFER_DIRECTION_IN:
 
1303
                        break;
 
1304
        }
 
1305
 
 
1306
        LLOGLN(urbdrc_debug, ("Ms descriptor arg: Recipient:0x%x, "
 
1307
                "InterfaceNumber:0x%x, Ms_PageIndex:0x%x, "
 
1308
                "Ms_featureDescIndex:0x%x, OutputBufferSize:0x%x",
 
1309
                Recipient, InterfaceNumber, Ms_PageIndex,
 
1310
                Ms_featureDescIndex, OutputBufferSize));
 
1311
        /** get ms string */
 
1312
        ret = pdev->os_feature_descriptor_request(
 
1313
                pdev, RequestId, Recipient,
 
1314
                InterfaceNumber,
 
1315
                Ms_PageIndex,
 
1316
                Ms_featureDescIndex,
 
1317
                &usbd_status,
 
1318
                &OutputBufferSize,
 
1319
                buffer,
 
1320
                1000);
 
1321
 
 
1322
        if (ret < 0)
 
1323
                LLOGLN(urbdrc_debug, ("os_feature_descriptor_request: error num %d", ret));
 
1324
 
 
1325
        offset = 36;
 
1326
        out_size = offset + OutputBufferSize;
 
1327
        /** send data */
 
1328
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1329
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
1330
        if(OutputBufferSize!=0)
 
1331
                data_write_UINT32(out_data + 8, URB_COMPLETION);        /** function id */
 
1332
        else
 
1333
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1334
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1335
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
1336
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1337
        data_write_UINT16(out_data + 20, 0x0008);       /** Size */
 
1338
 
 
1339
        /** Padding, MUST be ignored upon receipt */
 
1340
        data_write_UINT16(out_data + 22, URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR);
 
1341
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1342
 
 
1343
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1344
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1345
 
 
1346
        if (!pdev->isSigToEnd(pdev))
 
1347
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1348
 
 
1349
        zfree(out_data);
 
1350
 
 
1351
        return 0;
 
1352
}
 
1353
 
 
1354
static int urb_pipe_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
 
1355
        UINT32 data_sizem,
 
1356
        UINT32 MessageId,
 
1357
        IUDEVMAN * udevman,
 
1358
        UINT32 UsbDevice,
 
1359
        int transferDir,
 
1360
        int action)
 
1361
{
 
1362
        IUDEVICE* pdev;
 
1363
        UINT32 out_size, RequestId, InterfaceId, PipeHandle, EndpointAddress;
 
1364
        UINT32 OutputBufferSize, usbd_status = 0;
 
1365
        BYTE* out_data;
 
1366
        int out_offset, ret;
 
1367
 
 
1368
        if (transferDir == 0){
 
1369
                LLOGLN(urbdrc_debug, ("urb_pipe_request: not support transfer out\n"));
 
1370
                return -1;
 
1371
        }
 
1372
 
 
1373
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1374
 
 
1375
        if (pdev == NULL)
 
1376
                return 0;
 
1377
 
 
1378
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1379
 
 
1380
        data_read_UINT32(data + 0, RequestId);
 
1381
        data_read_UINT32(data + 4, PipeHandle); /** PipeHandle */
 
1382
        data_read_UINT32(data + 8, OutputBufferSize);
 
1383
        EndpointAddress = (PipeHandle & 0x000000ff);
 
1384
 
 
1385
 
 
1386
        switch (action){
 
1387
                case PIPE_CANCEL:
 
1388
                        LLOGLN(urbdrc_debug, ("urb_pipe_request: PIPE_CANCEL 0x%x ", EndpointAddress));
 
1389
 
 
1390
                        ret = pdev->control_pipe_request(
 
1391
                                pdev, RequestId, EndpointAddress,
 
1392
                                &usbd_status,
 
1393
                                PIPE_CANCEL);
 
1394
 
 
1395
                        if (ret < 0) {
 
1396
                                LLOGLN(urbdrc_debug, ("PIPE SET HALT: error num %d", ret));
 
1397
                        }
 
1398
 
 
1399
 
 
1400
                        break;
 
1401
                case PIPE_RESET:
 
1402
                        LLOGLN(urbdrc_debug, ("urb_pipe_request: PIPE_RESET ep 0x%x ", EndpointAddress));
 
1403
 
 
1404
                        ret = pdev->control_pipe_request(
 
1405
                                pdev, RequestId, EndpointAddress,
 
1406
                                &usbd_status,
 
1407
                                PIPE_RESET);
 
1408
 
 
1409
                        if (ret < 0)
 
1410
                                LLOGLN(urbdrc_debug, ("PIPE RESET: error num %d!!\n", ret));
 
1411
 
 
1412
                        break;
 
1413
                default:
 
1414
                        LLOGLN(urbdrc_debug, ("urb_pipe_request action: %d is not support!\n", action));
 
1415
                        break;
 
1416
        }
 
1417
 
 
1418
 
 
1419
        /** send data */
 
1420
        out_offset = 36;
 
1421
        out_size = out_offset + OutputBufferSize;
 
1422
        out_data = (BYTE *) malloc(out_size);
 
1423
        memset(out_data, 0, out_size);
 
1424
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1425
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
1426
 
 
1427
        data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1428
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1429
        data_write_UINT32(out_data + 16, 0x00000008);   /** CbTsUrbResult */
 
1430
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1431
        data_write_UINT16(out_data + 20, 0x0008);       /** Size */
 
1432
 
 
1433
        /** Padding, MUST be ignored upon receipt */
 
1434
        data_write_UINT16(out_data + 22, URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL);
 
1435
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1436
 
 
1437
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1438
        data_write_UINT32(out_data + 32, 0);    /** OutputBufferSize */
 
1439
 
 
1440
        if (!pdev->isSigToEnd(pdev))
 
1441
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1442
        zfree(out_data);
 
1443
 
 
1444
        return 0;
 
1445
}
 
1446
 
 
1447
static int urb_get_current_frame_number(URBDRC_CHANNEL_CALLBACK* callback,
 
1448
        BYTE * data,
 
1449
        UINT32 data_sizem,
 
1450
        UINT32 MessageId,
 
1451
        IUDEVMAN * udevman,
 
1452
        UINT32 UsbDevice,
 
1453
        int transferDir)
 
1454
{
 
1455
        IUDEVICE* pdev;
 
1456
        UINT32 out_size, RequestId, InterfaceId, OutputBufferSize;
 
1457
        UINT32 dummy_frames;
 
1458
        BYTE* out_data;
 
1459
 
 
1460
        if (transferDir == 0){
 
1461
                LLOGLN(urbdrc_debug, ("urb_get_current_frame_number: not support transfer out\n"));
 
1462
                //exit(1);
 
1463
                return -1;
 
1464
        }
 
1465
 
 
1466
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1467
        if (pdev == NULL)
 
1468
                return 0;
 
1469
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1470
 
 
1471
        data_read_UINT32(data + 0, RequestId);
 
1472
        data_read_UINT32(data + 4, OutputBufferSize);
 
1473
 
 
1474
         /** Fixme: Need to fill actual frame number!!*/
 
1475
        urbdrc_get_mstime(dummy_frames);
 
1476
 
 
1477
        out_size = 40;
 
1478
        out_data = (BYTE *) malloc(out_size);
 
1479
        memset(out_data, 0, out_size);
 
1480
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1481
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
1482
 
 
1483
        data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1484
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1485
        data_write_UINT32(out_data + 16, 12);   /** CbTsUrbResult */
 
1486
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1487
        data_write_UINT16(out_data + 20, 12);   /** Size */
 
1488
 
 
1489
        /** Padding, MUST be ignored upon receipt */
 
1490
        data_write_UINT16(out_data + 22, URB_FUNCTION_GET_CURRENT_FRAME_NUMBER);
 
1491
        data_write_UINT32(out_data + 24, USBD_STATUS_SUCCESS);  /** UsbdStatus */
 
1492
        data_write_UINT32(out_data + 28, dummy_frames); /** FrameNumber */
 
1493
 
 
1494
        data_write_UINT32(out_data + 32, 0);    /** HResult */
 
1495
        data_write_UINT32(out_data + 36, 0);    /** OutputBufferSize */
 
1496
 
 
1497
        if (!pdev->isSigToEnd(pdev))
 
1498
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1499
        zfree(out_data);
 
1500
        return 0;
 
1501
}
 
1502
 
 
1503
 
 
1504
/* Unused function for current server */
 
1505
static int urb_control_get_configuration_request(URBDRC_CHANNEL_CALLBACK* callback,
 
1506
        BYTE * data,
 
1507
        UINT32 data_sizem,
 
1508
        UINT32 MessageId,
 
1509
        IUDEVMAN * udevman,
 
1510
        UINT32 UsbDevice,
 
1511
        int transferDir)
 
1512
{
 
1513
        IUDEVICE* pdev;
 
1514
        UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
 
1515
        BYTE* buffer;
 
1516
        BYTE* out_data;
 
1517
        int ret, offset;
 
1518
 
 
1519
        if (transferDir == 0)
 
1520
        {
 
1521
                LLOGLN(urbdrc_debug, ("urb_control_get_configuration_request:"
 
1522
                        " not support transfer out\n"));
 
1523
                return -1;
 
1524
        }
 
1525
 
 
1526
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1527
 
 
1528
        if (pdev == NULL)
 
1529
                return 0;
 
1530
 
 
1531
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1532
 
 
1533
        data_read_UINT32(data + 0, RequestId);
 
1534
        data_read_UINT32(data + 4, OutputBufferSize);
 
1535
 
 
1536
        out_size = 36 + OutputBufferSize;
 
1537
        out_data = (BYTE *) malloc(out_size);
 
1538
        memset(out_data, 0, out_size);
 
1539
 
 
1540
        buffer = out_data + 36;
 
1541
 
 
1542
        ret = pdev->control_transfer(
 
1543
                pdev, RequestId, 0, 0, 0x80 | 0x00,
 
1544
                0x08, /* REQUEST_GET_CONFIGURATION */
 
1545
                0,
 
1546
                0,
 
1547
                &usbd_status,
 
1548
                &OutputBufferSize,
 
1549
                buffer,
 
1550
                1000);
 
1551
 
 
1552
        if (ret < 0){
 
1553
                LLOGLN(urbdrc_debug, ("%s:control_transfer: error num %d\n", __func__, ret));
 
1554
                OutputBufferSize = 0;
 
1555
        }
 
1556
 
 
1557
 
 
1558
        offset = 36;
 
1559
        out_size = offset + OutputBufferSize;
 
1560
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1561
        data_write_UINT32(out_data + 4, MessageId);     /** message id */
 
1562
 
 
1563
        if (OutputBufferSize != 0)
 
1564
                data_write_UINT32(out_data + 8, URB_COMPLETION);
 
1565
        else
 
1566
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1567
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1568
        data_write_UINT32(out_data + 16, 8);    /** CbTsUrbResult */
 
1569
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1570
        data_write_UINT16(out_data + 20, 8);    /** Size */
 
1571
 
 
1572
        /** Padding, MUST be ignored upon receipt */
 
1573
        data_write_UINT16(out_data + 22, URB_FUNCTION_GET_CONFIGURATION);
 
1574
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1575
 
 
1576
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1577
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1578
 
 
1579
        if (!pdev->isSigToEnd(pdev))
 
1580
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1581
        zfree(out_data);
 
1582
        return 0;
 
1583
}
 
1584
 
 
1585
/* Unused function for current server */
 
1586
static int urb_control_get_interface_request(URBDRC_CHANNEL_CALLBACK* callback,
 
1587
        BYTE * data,
 
1588
        UINT32 data_sizem,
 
1589
        UINT32 MessageId,
 
1590
        IUDEVMAN * udevman,
 
1591
        UINT32 UsbDevice,
 
1592
        int transferDir)
 
1593
{
 
1594
        IUDEVICE* pdev;
 
1595
        UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
 
1596
        UINT16 interface;
 
1597
        BYTE* buffer;
 
1598
        BYTE* out_data;
 
1599
        int ret, offset;
 
1600
 
 
1601
        if (transferDir == 0){
 
1602
                LLOGLN(urbdrc_debug, ("urb_control_get_interface_request: not support transfer out\n"));
 
1603
                return -1;
 
1604
        }
 
1605
 
 
1606
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1607
        if (pdev == NULL)
 
1608
                return 0;
 
1609
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1610
 
 
1611
        data_read_UINT32(data + 0, RequestId);
 
1612
        data_read_UINT16(data + 4, interface);
 
1613
        data_read_UINT32(data + 8, OutputBufferSize);
 
1614
 
 
1615
        out_size = 36 + OutputBufferSize;
 
1616
        out_data = (BYTE *) malloc(out_size);
 
1617
        memset(out_data, 0, out_size);
 
1618
 
 
1619
        buffer = out_data + 36;
 
1620
 
 
1621
        ret = pdev->control_transfer(pdev, RequestId, 0, 0, 0x80 | 0x01,
 
1622
                0x0A, /* REQUEST_GET_INTERFACE */
 
1623
                0,
 
1624
                interface,
 
1625
                &usbd_status,
 
1626
                &OutputBufferSize,
 
1627
                buffer,
 
1628
                1000);
 
1629
 
 
1630
        if (ret < 0){
 
1631
                LLOGLN(urbdrc_debug, ("%s:control_transfer: error num %d\n", __func__, ret));
 
1632
                OutputBufferSize = 0;
 
1633
        }
 
1634
 
 
1635
        offset = 36;
 
1636
        out_size = offset + OutputBufferSize;
 
1637
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1638
        data_write_UINT32(out_data + 4, MessageId);             /** message id */
 
1639
 
 
1640
        if (OutputBufferSize != 0)
 
1641
                data_write_UINT32(out_data + 8, URB_COMPLETION);
 
1642
        else
 
1643
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1644
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1645
        data_write_UINT32(out_data + 16, 8);    /** CbTsUrbResult */
 
1646
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1647
        data_write_UINT16(out_data + 20, 8);    /** Size */
 
1648
 
 
1649
        /** Padding, MUST be ignored upon receipt */
 
1650
        data_write_UINT16(out_data + 22, URB_FUNCTION_GET_INTERFACE);
 
1651
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1652
 
 
1653
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1654
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1655
 
 
1656
        if (!pdev->isSigToEnd(pdev))
 
1657
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1658
        zfree(out_data);
 
1659
        return 0;
 
1660
}
 
1661
 
 
1662
static int urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
 
1663
        UINT32 data_sizem,
 
1664
        UINT32 MessageId,
 
1665
        IUDEVMAN * udevman,
 
1666
        UINT32 UsbDevice,
 
1667
        BYTE func_recipient,
 
1668
        BYTE command,
 
1669
        int transferDir)
 
1670
{
 
1671
        IUDEVICE* pdev;
 
1672
        UINT32 out_size, RequestId, InterfaceId, OutputBufferSize, usbd_status;
 
1673
        UINT16 FeatureSelector, Index;
 
1674
        BYTE bmRequestType, bmRequest;
 
1675
        BYTE* buffer;
 
1676
        BYTE* out_data;
 
1677
        int ret, offset;
 
1678
 
 
1679
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1680
 
 
1681
        if (pdev == NULL)
 
1682
                return 0;
 
1683
 
 
1684
        InterfaceId = ((STREAM_ID_PROXY<<30) | pdev->get_ReqCompletion(pdev));
 
1685
 
 
1686
        data_read_UINT32(data + 0, RequestId);
 
1687
        data_read_UINT16(data + 4, FeatureSelector);
 
1688
        data_read_UINT16(data + 6, Index);
 
1689
        data_read_UINT32(data + 8, OutputBufferSize);
 
1690
        offset = 12;
 
1691
 
 
1692
        out_size = 36 + OutputBufferSize;
 
1693
        out_data = (BYTE *) malloc(out_size);
 
1694
        memset(out_data, 0, out_size);
 
1695
 
 
1696
        buffer = out_data + 36;
 
1697
 
 
1698
        bmRequestType = func_recipient;
 
1699
        switch (transferDir)
 
1700
        {
 
1701
                case USBD_TRANSFER_DIRECTION_OUT:
 
1702
                        fprintf(stderr, "Function urb_control_feature_request: OUT Unchecked\n");
 
1703
                        memcpy(buffer, data + offset, OutputBufferSize);
 
1704
                        bmRequestType |= 0x00;
 
1705
                        break;
 
1706
                case USBD_TRANSFER_DIRECTION_IN:
 
1707
                        bmRequestType |= 0x80;
 
1708
                        break;
 
1709
        }
 
1710
 
 
1711
        switch (command)
 
1712
        {
 
1713
                case URB_SET_FEATURE:
 
1714
                        bmRequest = 0x03; /* REQUEST_SET_FEATURE */
 
1715
                        break;
 
1716
                case URB_CLEAR_FEATURE:
 
1717
                        bmRequest = 0x01; /* REQUEST_CLEAR_FEATURE */
 
1718
                        break;
 
1719
                default:
 
1720
                        fprintf(stderr, "urb_control_feature_request: Error Command %x\n", command);
 
1721
                        return -1;
 
1722
        }
 
1723
 
 
1724
        ret = pdev->control_transfer(
 
1725
                pdev, RequestId, 0, 0, bmRequestType, bmRequest,
 
1726
                FeatureSelector,
 
1727
                Index,
 
1728
                &usbd_status,
 
1729
                &OutputBufferSize,
 
1730
                buffer,
 
1731
                1000);
 
1732
 
 
1733
        if (ret < 0){
 
1734
                LLOGLN(urbdrc_debug, ("feature control transfer: error num %d", ret));
 
1735
                OutputBufferSize = 0;
 
1736
        }
 
1737
 
 
1738
        offset = 36;
 
1739
        out_size = offset + OutputBufferSize;
 
1740
        data_write_UINT32(out_data + 0, InterfaceId);   /** interface */
 
1741
        data_write_UINT32(out_data + 4, MessageId);             /** message id */
 
1742
 
 
1743
        if (OutputBufferSize != 0)
 
1744
                data_write_UINT32(out_data + 8, URB_COMPLETION);
 
1745
        else
 
1746
                data_write_UINT32(out_data + 8, URB_COMPLETION_NO_DATA);
 
1747
        data_write_UINT32(out_data + 12, RequestId);    /** RequestId */
 
1748
        data_write_UINT32(out_data + 16, 8);    /** CbTsUrbResult */
 
1749
        /** TsUrbResult TS_URB_RESULT_HEADER */
 
1750
        data_write_UINT16(out_data + 20, 8);    /** Size */
 
1751
 
 
1752
        /** Padding, MUST be ignored upon receipt */
 
1753
        data_write_UINT16(out_data + 22, URB_FUNCTION_GET_INTERFACE);
 
1754
        data_write_UINT32(out_data + 24, usbd_status);  /** UsbdStatus */
 
1755
 
 
1756
        data_write_UINT32(out_data + 28, 0);    /** HResult */
 
1757
        data_write_UINT32(out_data + 32, OutputBufferSize);     /** OutputBufferSize */
 
1758
 
 
1759
 
 
1760
        if (!pdev->isSigToEnd(pdev))
 
1761
                callback->channel->Write(callback->channel, out_size, out_data, NULL);
 
1762
        zfree(out_data);
 
1763
        return 0;
 
1764
}
 
1765
 
 
1766
static int urbdrc_process_transfer_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE * data,
 
1767
        UINT32 data_sizem,
 
1768
        UINT32 MessageId,
 
1769
        IUDEVMAN * udevman,
 
1770
        UINT32 UsbDevice,
 
1771
        int transferDir)
 
1772
{
 
1773
        IUDEVICE *      pdev;
 
1774
        UINT32          CbTsUrb;
 
1775
        UINT16          Size;
 
1776
        UINT16          URB_Function;
 
1777
        UINT32          OutputBufferSize;
 
1778
        int                     error = 0;
 
1779
 
 
1780
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
1781
        if (pdev == NULL)
 
1782
                return 0;
 
1783
        data_read_UINT32(data + 0, CbTsUrb);    /** CbTsUrb */
 
1784
        data_read_UINT16(data + 4, Size);       /** size */
 
1785
        data_read_UINT16(data + 6, URB_Function);
 
1786
        data_read_UINT32(data + 4 + CbTsUrb, OutputBufferSize);
 
1787
 
 
1788
        switch (URB_Function)
 
1789
        {
 
1790
                case URB_FUNCTION_SELECT_CONFIGURATION:                 /** 0x0000 */
 
1791
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SELECT_CONFIGURATION"));
 
1792
                        error = urb_select_configuration(
 
1793
                                callback, data + 8,
 
1794
                                data_sizem - 8,
 
1795
                                MessageId,
 
1796
                                udevman,
 
1797
                                UsbDevice,
 
1798
                                transferDir);
 
1799
                        break;
 
1800
                case URB_FUNCTION_SELECT_INTERFACE:                             /** 0x0001 */
 
1801
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SELECT_INTERFACE"));
 
1802
                        error = urb_select_interface(
 
1803
                                callback, data + 8,
 
1804
                                data_sizem - 8,
 
1805
                                MessageId,
 
1806
                                udevman,
 
1807
                                UsbDevice,
 
1808
                                transferDir);
 
1809
                        break;
 
1810
                case URB_FUNCTION_ABORT_PIPE:                                   /** 0x0002  */
 
1811
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_ABORT_PIPE"));
 
1812
                        error = urb_pipe_request(
 
1813
                                callback, data + 8, data_sizem - 8,
 
1814
                                MessageId,
 
1815
                                udevman,
 
1816
                                UsbDevice,
 
1817
                                transferDir,
 
1818
                                PIPE_CANCEL);
 
1819
                        break;
 
1820
                case URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL:    /** 0x0003  */
 
1821
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL"));
 
1822
                        error = -1;  /** This URB function is obsolete in Windows 2000
 
1823
                                                         * and later operating systems
 
1824
                                                         * and is not supported by Microsoft. */
 
1825
                        break;
 
1826
                case URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL: /** 0x0004 */
 
1827
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL"));
 
1828
                        error = -1;  /** This URB function is obsolete in Windows 2000
 
1829
                                                         * and later operating systems
 
1830
                                                         * and is not supported by Microsoft. */
 
1831
                        break;
 
1832
                case URB_FUNCTION_GET_FRAME_LENGTH:                             /** 0x0005 */
 
1833
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_FRAME_LENGTH"));
 
1834
                        error = -1;  /** This URB function is obsolete in Windows 2000
 
1835
                                                         * and later operating systems
 
1836
                                                         * and is not supported by Microsoft. */
 
1837
                        break;
 
1838
                case URB_FUNCTION_SET_FRAME_LENGTH:                             /** 0x0006 */
 
1839
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_FRAME_LENGTH"));
 
1840
                        error = -1;  /** This URB function is obsolete in Windows 2000
 
1841
                                                         * and later operating systems
 
1842
                                                         * and is not supported by Microsoft. */
 
1843
                        break;
 
1844
                case URB_FUNCTION_GET_CURRENT_FRAME_NUMBER:             /** 0x0007 */
 
1845
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER"));
 
1846
                        error = urb_get_current_frame_number(
 
1847
                                callback, data + 8,
 
1848
                                data_sizem - 8,
 
1849
                                MessageId,
 
1850
                                udevman,
 
1851
                                UsbDevice,
 
1852
                                transferDir);
 
1853
                        break;
 
1854
                case URB_FUNCTION_CONTROL_TRANSFER:                             /** 0x0008 */
 
1855
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CONTROL_TRANSFER"));
 
1856
                        error = urb_control_transfer(
 
1857
                                callback, data + 8,
 
1858
                                data_sizem - 8,
 
1859
                                MessageId,
 
1860
                                udevman,
 
1861
                                UsbDevice,
 
1862
                                transferDir,
 
1863
                                URB_CONTROL_TRANSFER_NONEXTERNAL);
 
1864
                        break;
 
1865
                case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:   /** 0x0009 */
 
1866
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER"));
 
1867
                        error = urb_bulk_or_interrupt_transfer(
 
1868
                                callback, data + 8,
 
1869
                                data_sizem - 8,
 
1870
                                MessageId,
 
1871
                                udevman,
 
1872
                                UsbDevice,
 
1873
                                transferDir);
 
1874
                        break;
 
1875
                case URB_FUNCTION_ISOCH_TRANSFER:                               /** 0x000A */
 
1876
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_ISOCH_TRANSFER"));
 
1877
                        error = urb_isoch_transfer(
 
1878
                                callback, data + 8, data_sizem - 8,
 
1879
                                MessageId,
 
1880
                                udevman,
 
1881
                                UsbDevice,
 
1882
                                transferDir);
 
1883
                        break;
 
1884
                case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:   /** 0x000B */
 
1885
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE"));
 
1886
                        error = urb_control_descriptor_request(
 
1887
                                callback, data + 8,
 
1888
                                data_sizem - 8,
 
1889
                                MessageId,
 
1890
                                udevman,
 
1891
                                UsbDevice,
 
1892
                                0x00,
 
1893
                                transferDir);
 
1894
                        break;
 
1895
                case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:             /** 0x000C */
 
1896
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE"));
 
1897
                        error = urb_control_descriptor_request(
 
1898
                                callback, data + 8,
 
1899
                                data_sizem - 8,
 
1900
                                MessageId,
 
1901
                                udevman,
 
1902
                                UsbDevice,
 
1903
                                0x00,
 
1904
                                transferDir);
 
1905
                        break;
 
1906
                case URB_FUNCTION_SET_FEATURE_TO_DEVICE:                /** 0x000D */
 
1907
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_FEATURE_TO_DEVICE"));
 
1908
                        error = urb_control_feature_request(callback, 
 
1909
                                data + 8,
 
1910
                                data_sizem - 8,
 
1911
                                MessageId,
 
1912
                                udevman,
 
1913
                                UsbDevice,
 
1914
                                0x00,
 
1915
                                URB_SET_FEATURE,
 
1916
                                transferDir);
 
1917
                        break;
 
1918
                case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:             /** 0x000E */
 
1919
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_FEATURE_TO_INTERFACE"));
 
1920
                        error = urb_control_feature_request(
 
1921
                                callback, data + 8,
 
1922
                                data_sizem - 8,
 
1923
                                MessageId,
 
1924
                                udevman,
 
1925
                                UsbDevice,
 
1926
                                0x01,
 
1927
                                URB_SET_FEATURE,
 
1928
                                transferDir);
 
1929
                        break;
 
1930
                case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:              /** 0x000F */
 
1931
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_FEATURE_TO_ENDPOINT"));
 
1932
                        error = urb_control_feature_request(
 
1933
                                callback, data + 8,
 
1934
                                data_sizem - 8,
 
1935
                                MessageId,
 
1936
                                udevman,
 
1937
                                UsbDevice,
 
1938
                                0x02,
 
1939
                                URB_SET_FEATURE,
 
1940
                                transferDir);
 
1941
                        break;
 
1942
                case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:              /** 0x0010 */
 
1943
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE"));
 
1944
                        error = urb_control_feature_request(
 
1945
                                callback, data + 8,
 
1946
                                data_sizem - 8,
 
1947
                                MessageId,
 
1948
                                udevman,
 
1949
                                UsbDevice,
 
1950
                                0x00,
 
1951
                                URB_CLEAR_FEATURE,
 
1952
                                transferDir);
 
1953
                        break;
 
1954
                case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:   /** 0x0011 */
 
1955
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE"));
 
1956
                        error = urb_control_feature_request(
 
1957
                                callback, data + 8,
 
1958
                                data_sizem - 8,
 
1959
                                MessageId,
 
1960
                                udevman,
 
1961
                                UsbDevice,
 
1962
                                0x01,
 
1963
                                URB_CLEAR_FEATURE,
 
1964
                                transferDir);
 
1965
                        break;
 
1966
                case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:    /** 0x0012 */
 
1967
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT"));
 
1968
                        error = urb_control_feature_request(
 
1969
                                callback, data + 8,
 
1970
                                data_sizem - 8,
 
1971
                                MessageId,
 
1972
                                udevman,
 
1973
                                UsbDevice,
 
1974
                                0x02,
 
1975
                                URB_CLEAR_FEATURE,
 
1976
                                transferDir);
 
1977
                        break;
 
1978
                case URB_FUNCTION_GET_STATUS_FROM_DEVICE:               /** 0x0013 */
 
1979
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_STATUS_FROM_DEVICE"));
 
1980
                        error = urb_control_get_status_request(
 
1981
                                callback, data + 8,
 
1982
                                data_sizem - 8,
 
1983
                                MessageId,
 
1984
                                udevman,
 
1985
                                UsbDevice,
 
1986
                                0x00,
 
1987
                                transferDir);
 
1988
                        break;
 
1989
                case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:    /** 0x0014 */
 
1990
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_STATUS_FROM_INTERFACE"));
 
1991
                        error = urb_control_get_status_request(
 
1992
                                callback, data + 8,
 
1993
                                data_sizem - 8,
 
1994
                                MessageId,
 
1995
                                udevman,
 
1996
                                UsbDevice,
 
1997
                                0x01,
 
1998
                                transferDir);
 
1999
                        break;
 
2000
                case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:             /** 0x0015 */
 
2001
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_STATUS_FROM_ENDPOINT"));
 
2002
                        error = urb_control_get_status_request(
 
2003
                                callback, data + 8,
 
2004
                                data_sizem - 8,
 
2005
                                MessageId,
 
2006
                                udevman,
 
2007
                                UsbDevice,
 
2008
                                0x02,
 
2009
                                transferDir);
 
2010
                        break;
 
2011
                case URB_FUNCTION_RESERVED_0X0016:                              /** 0x0016 */
 
2012
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVED_0X0016"));
 
2013
                        error = -1;
 
2014
                        break;
 
2015
                case URB_FUNCTION_VENDOR_DEVICE:                                /** 0x0017 */
 
2016
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_VENDOR_DEVICE"));
 
2017
                        error = urb_control_vendor_or_class_request(
 
2018
                                callback, data + 8,
 
2019
                                data_sizem - 8,
 
2020
                                MessageId,
 
2021
                                udevman,
 
2022
                                UsbDevice,
 
2023
                                (0x02 << 5), /* vendor type */
 
2024
                                0x00,
 
2025
                                transferDir);
 
2026
                        break;
 
2027
                case URB_FUNCTION_VENDOR_INTERFACE:                             /** 0x0018 */
 
2028
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_VENDOR_INTERFACE"));
 
2029
                        error = urb_control_vendor_or_class_request(
 
2030
                                callback, data + 8,
 
2031
                                data_sizem - 8,
 
2032
                                MessageId,
 
2033
                                udevman,
 
2034
                                UsbDevice,
 
2035
                                (0x02 << 5), /* vendor type */
 
2036
                                0x01,
 
2037
                                transferDir);
 
2038
                        break;
 
2039
                case URB_FUNCTION_VENDOR_ENDPOINT:                              /** 0x0019 */
 
2040
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_VENDOR_ENDPOINT"));
 
2041
                        error = urb_control_vendor_or_class_request(
 
2042
                                callback, data + 8,
 
2043
                                data_sizem - 8,
 
2044
                                MessageId,
 
2045
                                udevman,
 
2046
                                UsbDevice,
 
2047
                                (0x02 << 5), /* vendor type */
 
2048
                                0x02,
 
2049
                                transferDir);
 
2050
                        break;
 
2051
                case URB_FUNCTION_CLASS_DEVICE:                                 /** 0x001A */
 
2052
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLASS_DEVICE"));
 
2053
                        error = urb_control_vendor_or_class_request(
 
2054
                                callback, data + 8,
 
2055
                                data_sizem - 8,
 
2056
                                MessageId,
 
2057
                                udevman,
 
2058
                                UsbDevice,
 
2059
                                (0x01 << 5), /* class type */
 
2060
                                0x00,
 
2061
                                transferDir);
 
2062
                        break;
 
2063
                case URB_FUNCTION_CLASS_INTERFACE:                              /** 0x001B */
 
2064
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLASS_INTERFACE"));
 
2065
                        error = urb_control_vendor_or_class_request(
 
2066
                                callback, data + 8,
 
2067
                                data_sizem - 8,
 
2068
                                MessageId,
 
2069
                                udevman,
 
2070
                                UsbDevice,
 
2071
                                (0x01 << 5), /* class type */
 
2072
                                0x01,
 
2073
                                transferDir);
 
2074
                        break;
 
2075
                case URB_FUNCTION_CLASS_ENDPOINT:                               /** 0x001C */
 
2076
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLASS_ENDPOINT"));
 
2077
                        error = urb_control_vendor_or_class_request(
 
2078
                                callback, data + 8,
 
2079
                                data_sizem - 8,
 
2080
                                MessageId,
 
2081
                                udevman,
 
2082
                                UsbDevice,
 
2083
                                (0x01 << 5), /* class type */
 
2084
                                0x02,
 
2085
                                transferDir);
 
2086
                        break;
 
2087
                case URB_FUNCTION_RESERVE_0X001D:                               /** 0x001D */
 
2088
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVE_0X001D"));
 
2089
                        error = -1;
 
2090
                        break;
 
2091
                case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: /** 0x001E */
 
2092
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL"));
 
2093
                        error = urb_pipe_request(
 
2094
                                callback, data + 8, data_sizem - 8,
 
2095
                                MessageId,
 
2096
                                udevman,
 
2097
                                UsbDevice,
 
2098
                                transferDir,
 
2099
                                PIPE_RESET);
 
2100
                        break;
 
2101
                case URB_FUNCTION_CLASS_OTHER:                                  /** 0x001F */
 
2102
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLASS_OTHER"));
 
2103
                        error = urb_control_vendor_or_class_request(
 
2104
                                callback, data + 8,
 
2105
                                data_sizem - 8,
 
2106
                                MessageId,
 
2107
                                udevman,
 
2108
                                UsbDevice,
 
2109
                                (0x01 << 5), /* class type */
 
2110
                                0x03,
 
2111
                                transferDir);
 
2112
                        break;
 
2113
                case URB_FUNCTION_VENDOR_OTHER:                                 /** 0x0020 */
 
2114
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_VENDOR_OTHER"));
 
2115
                        error = urb_control_vendor_or_class_request(
 
2116
                                callback, data + 8,
 
2117
                                data_sizem - 8,
 
2118
                                MessageId,
 
2119
                                udevman,
 
2120
                                UsbDevice,
 
2121
                                (0x02 << 5), /* vendor type */
 
2122
                                0x03,
 
2123
                                transferDir);
 
2124
                        break;
 
2125
                case URB_FUNCTION_GET_STATUS_FROM_OTHER:                /** 0x0021 */
 
2126
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_STATUS_FROM_OTHER"));
 
2127
                        error = urb_control_get_status_request(
 
2128
                                callback, data + 8,
 
2129
                                data_sizem - 8,
 
2130
                                MessageId,
 
2131
                                udevman,
 
2132
                                UsbDevice,
 
2133
                                0x03,
 
2134
                                transferDir);
 
2135
                        break;
 
2136
                case URB_FUNCTION_CLEAR_FEATURE_TO_OTHER:               /** 0x0022 */
 
2137
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CLEAR_FEATURE_TO_OTHER"));
 
2138
                        error = urb_control_feature_request(
 
2139
                                callback, data + 8,
 
2140
                                data_sizem - 8,
 
2141
                                MessageId,
 
2142
                                udevman,
 
2143
                                UsbDevice,
 
2144
                                0x03,
 
2145
                                URB_CLEAR_FEATURE,
 
2146
                                transferDir);
 
2147
                        break;
 
2148
                case URB_FUNCTION_SET_FEATURE_TO_OTHER:                 /** 0x0023 */
 
2149
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_FEATURE_TO_OTHER"));
 
2150
                        error = urb_control_feature_request(
 
2151
                                callback, data + 8,
 
2152
                                data_sizem - 8,
 
2153
                                MessageId,
 
2154
                                udevman,
 
2155
                                UsbDevice,
 
2156
                                0x03,
 
2157
                                URB_SET_FEATURE,
 
2158
                                transferDir);
 
2159
                        break;
 
2160
                case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT: /** 0x0024 */
 
2161
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT"));
 
2162
                        error = urb_control_descriptor_request(
 
2163
                                callback, data + 8,
 
2164
                                data_sizem - 8,
 
2165
                                MessageId,
 
2166
                                udevman,
 
2167
                                UsbDevice,
 
2168
                                0x02,
 
2169
                                transferDir);
 
2170
                        break;
 
2171
                case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:   /** 0x0025 */
 
2172
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT"));
 
2173
                        error = urb_control_descriptor_request(
 
2174
                                callback, data + 8,
 
2175
                                data_sizem - 8,
 
2176
                                MessageId,
 
2177
                                udevman,
 
2178
                                UsbDevice,
 
2179
                                0x02,
 
2180
                                transferDir);
 
2181
                        break;
 
2182
                case URB_FUNCTION_GET_CONFIGURATION:                    /** 0x0026 */
 
2183
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_CONFIGURATION"));
 
2184
                        error =  urb_control_get_configuration_request(
 
2185
                                callback, data + 8,
 
2186
                                data_sizem - 8,
 
2187
                                MessageId,
 
2188
                                udevman,
 
2189
                                UsbDevice,
 
2190
                                transferDir);
 
2191
                        break;
 
2192
                case URB_FUNCTION_GET_INTERFACE:                                /** 0x0027 */
 
2193
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_INTERFACE"));
 
2194
                        error =  urb_control_get_interface_request(
 
2195
                                callback, data + 8,
 
2196
                                data_sizem - 8,
 
2197
                                MessageId,
 
2198
                                udevman,
 
2199
                                UsbDevice,
 
2200
                                transferDir);
 
2201
                        break;
 
2202
                case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:        /** 0x0028 */
 
2203
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE"));
 
2204
                        error = urb_control_descriptor_request(
 
2205
                                callback, data + 8,
 
2206
                                data_sizem - 8,
 
2207
                                MessageId,
 
2208
                                udevman,
 
2209
                                UsbDevice,
 
2210
                                0x01,
 
2211
                                transferDir);
 
2212
                        break;
 
2213
                case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:  /** 0x0029 */
 
2214
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE"));
 
2215
                        error = urb_control_descriptor_request(
 
2216
                                callback, data + 8,
 
2217
                                data_sizem - 8,
 
2218
                                MessageId,
 
2219
                                udevman,
 
2220
                                UsbDevice,
 
2221
                                0x01,
 
2222
                                transferDir);
 
2223
                        break;
 
2224
                case URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR:    /** 0x002A */
 
2225
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR"));
 
2226
                        error = urb_os_feature_descriptor_request(
 
2227
                                callback, data + 8,
 
2228
                                data_sizem - 8,
 
2229
                                MessageId,
 
2230
                                udevman,
 
2231
                                UsbDevice,
 
2232
                                transferDir);
 
2233
                        break;
 
2234
                case URB_FUNCTION_RESERVE_0X002B:                               /** 0x002B */
 
2235
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVE_0X002B"));
 
2236
                        error = -1;
 
2237
                        break;
 
2238
                case URB_FUNCTION_RESERVE_0X002C:                               /** 0x002C */
 
2239
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVE_0X002C"));
 
2240
                        error = -1;
 
2241
                        break;
 
2242
                case URB_FUNCTION_RESERVE_0X002D:                               /** 0x002D */
 
2243
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVE_0X002D"));
 
2244
                        error = -1;
 
2245
                        break;
 
2246
                case URB_FUNCTION_RESERVE_0X002E:                               /** 0x002E */
 
2247
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVE_0X002E"));
 
2248
                        error = -1;
 
2249
                        break;
 
2250
                case URB_FUNCTION_RESERVE_0X002F:                               /** 0x002F */
 
2251
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_RESERVE_0X002F"));
 
2252
                        error = -1;
 
2253
                        break;
 
2254
                /** USB 2.0 calls start at 0x0030 */
 
2255
                case URB_FUNCTION_SYNC_RESET_PIPE:                              /** 0x0030 */
 
2256
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SYNC_RESET_PIPE"));
 
2257
                        error = urb_pipe_request(
 
2258
                                callback, data + 8,
 
2259
                                data_sizem - 8,
 
2260
                                MessageId,
 
2261
                                udevman,
 
2262
                                UsbDevice,
 
2263
                                transferDir,
 
2264
                                PIPE_RESET);
 
2265
                        error = -9;  /** function not support */
 
2266
                        break;
 
2267
                case URB_FUNCTION_SYNC_CLEAR_STALL:                             /** 0x0031 */
 
2268
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_SYNC_CLEAR_STALL"));
 
2269
                        error = urb_pipe_request(
 
2270
                                callback, data + 8,
 
2271
                                data_sizem - 8,
 
2272
                                MessageId,
 
2273
                                udevman,
 
2274
                                UsbDevice,
 
2275
                                transferDir,
 
2276
                                PIPE_RESET);
 
2277
                        error = -9;
 
2278
                        break;
 
2279
                case URB_FUNCTION_CONTROL_TRANSFER_EX:                  /** 0x0032 */
 
2280
                        LLOGLN(urbdrc_debug, ("URB_Func: URB_FUNCTION_CONTROL_TRANSFER_EX"));
 
2281
                        error = urb_control_transfer(
 
2282
                                callback, data + 8,
 
2283
                                data_sizem - 8,
 
2284
                                MessageId,
 
2285
                                udevman,
 
2286
                                UsbDevice,
 
2287
                                transferDir,
 
2288
                                URB_CONTROL_TRANSFER_EXTERNAL);
 
2289
                        break;
 
2290
                default:
 
2291
                        LLOGLN(urbdrc_debug, ("URB_Func: %x is not found!", URB_Function));
 
2292
                        break;
 
2293
        }
 
2294
 
 
2295
        return error;
 
2296
}
 
2297
 
 
2298
void* urbdrc_process_udev_data_transfer(void* arg)
 
2299
{
 
2300
        TRANSFER_DATA*  transfer_data = (TRANSFER_DATA*) arg;
 
2301
        URBDRC_CHANNEL_CALLBACK * callback = transfer_data->callback;
 
2302
        BYTE *          pBuffer         = transfer_data->pBuffer;
 
2303
        UINT32          cbSize          = transfer_data->cbSize;
 
2304
        UINT32          UsbDevice       = transfer_data->UsbDevice;
 
2305
        IUDEVMAN *      udevman         = transfer_data->udevman;
 
2306
        UINT32          MessageId;
 
2307
        UINT32          FunctionId;
 
2308
        IUDEVICE*   pdev;
 
2309
        int error = 0;
 
2310
        pdev = udevman->get_udevice_by_UsbDevice(udevman, UsbDevice);
 
2311
        if (pdev == NULL || pdev->isSigToEnd(pdev))
 
2312
        {
 
2313
                if (transfer_data)
 
2314
                {
 
2315
                        if (transfer_data->pBuffer)
 
2316
                                zfree(transfer_data->pBuffer);
 
2317
                        zfree(transfer_data);
 
2318
                }
 
2319
                return 0;
 
2320
        }
 
2321
 
 
2322
        pdev->push_action(pdev);
 
2323
 
 
2324
        /* USB kernel driver detach!! */
 
2325
        pdev->detach_kernel_driver(pdev);
 
2326
 
 
2327
        data_read_UINT32(pBuffer + 0, MessageId);
 
2328
        data_read_UINT32(pBuffer + 4, FunctionId);
 
2329
        switch (FunctionId)
 
2330
        {
 
2331
                case CANCEL_REQUEST:
 
2332
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2333
                                " >>CANCEL_REQUEST<<0x%X", FunctionId));
 
2334
                        error = urbdrc_process_cancel_request(
 
2335
                                pBuffer + 8,
 
2336
                                cbSize - 8,
 
2337
                                udevman,
 
2338
                                UsbDevice);
 
2339
                        break;
 
2340
                case REGISTER_REQUEST_CALLBACK:
 
2341
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2342
                                " >>REGISTER_REQUEST_CALLBACK<<0x%X", FunctionId));
 
2343
                        error = urbdrc_process_register_request_callback(
 
2344
                                callback,
 
2345
                                pBuffer + 8, 
 
2346
                                cbSize - 8, 
 
2347
                                udevman,
 
2348
                                UsbDevice);
 
2349
                        break;
 
2350
                case IO_CONTROL:
 
2351
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2352
                                " >>IO_CONTROL<<0x%X", FunctionId));
 
2353
                        error = urbdrc_process_io_control(
 
2354
                                callback,
 
2355
                                pBuffer + 8,
 
2356
                                cbSize - 8,
 
2357
                                MessageId,
 
2358
                                udevman, UsbDevice);
 
2359
                        break;
 
2360
                case INTERNAL_IO_CONTROL:
 
2361
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2362
                                " >>INTERNAL_IO_CONTROL<<0x%X", FunctionId));
 
2363
                        error = urbdrc_process_internal_io_control(
 
2364
                                callback,
 
2365
                                pBuffer + 8,
 
2366
                                cbSize - 8, 
 
2367
                                MessageId,
 
2368
                                udevman, UsbDevice);
 
2369
                        break;
 
2370
                case QUERY_DEVICE_TEXT:
 
2371
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2372
                                " >>QUERY_DEVICE_TEXT<<0x%X", FunctionId));
 
2373
                        error = urbdrc_process_query_device_text(
 
2374
                                callback,
 
2375
                                pBuffer + 8,
 
2376
                                cbSize - 8,
 
2377
                                MessageId,
 
2378
                                udevman,
 
2379
                                UsbDevice);
 
2380
                        break;
 
2381
                case TRANSFER_IN_REQUEST:
 
2382
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2383
                                " >>TRANSFER_IN_REQUEST<<0x%X", FunctionId));
 
2384
                        error = urbdrc_process_transfer_request(
 
2385
                                callback,
 
2386
                                pBuffer + 8,
 
2387
                                cbSize - 8,
 
2388
                                MessageId,
 
2389
                                udevman,
 
2390
                                UsbDevice,
 
2391
                                USBD_TRANSFER_DIRECTION_IN);
 
2392
                        break;
 
2393
                case TRANSFER_OUT_REQUEST:
 
2394
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2395
                                " >>TRANSFER_OUT_REQUEST<<0x%X", FunctionId));
 
2396
                        error = urbdrc_process_transfer_request(
 
2397
                                callback,
 
2398
                                pBuffer + 8,
 
2399
                                cbSize - 8,
 
2400
                                MessageId,
 
2401
                                udevman,
 
2402
                                UsbDevice,
 
2403
                                USBD_TRANSFER_DIRECTION_OUT);
 
2404
                        break;
 
2405
                case RETRACT_DEVICE:
 
2406
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2407
                                " >>RETRACT_DEVICE<<0x%X", FunctionId));
 
2408
                        error = urbdrc_process_retract_device_request(
 
2409
                                pBuffer + 8,
 
2410
                                cbSize - 8, 
 
2411
                                udevman, 
 
2412
                                UsbDevice);
 
2413
                        break;
 
2414
                default:
 
2415
                        LLOGLN(urbdrc_debug, ("urbdrc_process_udev_data_transfer:"
 
2416
                                " unknown FunctionId 0x%X", FunctionId));
 
2417
                        error = -1;
 
2418
                        break;
 
2419
        }
 
2420
 
 
2421
        if (transfer_data)
 
2422
        {
 
2423
                if (transfer_data->pBuffer)
 
2424
                        zfree(transfer_data->pBuffer);
 
2425
                zfree(transfer_data);
 
2426
        }
 
2427
 
 
2428
        if (pdev)
 
2429
        {
 
2430
#if ISOCH_FIFO
 
2431
                /* check isochronous fds */
 
2432
                func_check_isochronous_fds(pdev);
 
2433
#endif
 
2434
                /* close this channel, if device is not found. */
 
2435
                pdev->complete_action(pdev);
 
2436
        }
 
2437
        else
 
2438
        {
 
2439
                udevman->push_urb(udevman);
 
2440
                return 0;
 
2441
        }
 
2442
 
 
2443
        udevman->push_urb(udevman);
 
2444
        return 0;
 
2445
}