1 /*
2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort device functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6 */
7
8 #include "usbport.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13 NTSTATUS
14 NTAPI
USBPORT_SendSetupPacket(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PDEVICE_OBJECT FdoDevice,IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,IN PVOID Buffer,IN ULONG Length,IN OUT PULONG TransferedLen,IN OUT PUSBD_STATUS pUSBDStatus)15 USBPORT_SendSetupPacket(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
16 IN PDEVICE_OBJECT FdoDevice,
17 IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
18 IN PVOID Buffer,
19 IN ULONG Length,
20 IN OUT PULONG TransferedLen,
21 IN OUT PUSBD_STATUS pUSBDStatus)
22 {
23 PURB Urb;
24 PMDL Mdl;
25 USBD_STATUS USBDStatus;
26 KEVENT Event;
27 NTSTATUS Status;
28
29 DPRINT("USBPORT_SendSetupPacket: DeviceHandle - %p, FdoDevice - %p, SetupPacket - %p, Buffer - %p, Length - %x, TransferedLen - %x, pUSBDStatus - %x\n",
30 DeviceHandle,
31 FdoDevice,
32 SetupPacket,
33 Buffer,
34 Length,
35 TransferedLen,
36 pUSBDStatus);
37
38 KeInitializeEvent(&Event, NotificationEvent, FALSE);
39
40 Urb = ExAllocatePoolWithTag(NonPagedPool,
41 sizeof(struct _URB_CONTROL_TRANSFER),
42 USB_PORT_TAG);
43
44 if (Urb)
45 {
46 InterlockedIncrement(&DeviceHandle->DeviceHandleLock);
47
48 RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_TRANSFER));
49
50 RtlCopyMemory(Urb->UrbControlTransfer.SetupPacket,
51 SetupPacket,
52 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
53
54 Urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_TRANSFER);
55 Urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
56 Urb->UrbHeader.UsbdDeviceHandle = DeviceHandle;
57 Urb->UrbHeader.UsbdFlags = 0;
58
59 Urb->UrbControlTransfer.PipeHandle = &DeviceHandle->PipeHandle;
60 Urb->UrbControlTransfer.TransferBufferLength = Length;
61 Urb->UrbControlTransfer.TransferBuffer = Buffer;
62 Urb->UrbControlTransfer.TransferBufferMDL = NULL;
63
64 Urb->UrbControlTransfer.TransferFlags = USBD_SHORT_TRANSFER_OK |
65 USBD_TRANSFER_DIRECTION;
66
67 if (SetupPacket->bmRequestType.Dir != BMREQUEST_DEVICE_TO_HOST)
68 {
69 Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN;
70 }
71
72 Status = STATUS_SUCCESS;
73
74 if (Length)
75 {
76 Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
77
78 Urb->UrbControlTransfer.TransferBufferMDL = Mdl;
79
80 if (Mdl)
81 {
82 Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_MDL;
83 MmBuildMdlForNonPagedPool(Mdl);
84 }
85 else
86 {
87 Status = USBPORT_USBDStatusToNtStatus(NULL,
88 USBD_STATUS_INSUFFICIENT_RESOURCES);
89 }
90 }
91
92 if (NT_SUCCESS(Status))
93 {
94 USBDStatus = USBPORT_AllocateTransfer(FdoDevice,
95 Urb,
96 NULL,
97 NULL,
98 &Event);
99
100 if (USBD_SUCCESS(USBDStatus))
101 {
102 InterlockedIncrement(&DeviceHandle->DeviceHandleLock);
103
104 USBPORT_QueueTransferUrb(Urb);
105
106 KeWaitForSingleObject(&Event,
107 Suspended,
108 KernelMode,
109 FALSE,
110 NULL);
111
112 USBDStatus = Urb->UrbHeader.Status;
113 }
114
115 Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
116
117 if (TransferedLen)
118 *TransferedLen = Urb->UrbControlTransfer.TransferBufferLength;
119
120 if (pUSBDStatus)
121 *pUSBDStatus = USBDStatus;
122 }
123
124 InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
125 ExFreePoolWithTag(Urb, USB_PORT_TAG);
126 }
127 else
128 {
129 if (pUSBDStatus)
130 *pUSBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES;
131
132 Status = USBPORT_USBDStatusToNtStatus(NULL,
133 USBD_STATUS_INSUFFICIENT_RESOURCES);
134 }
135
136 DPRINT("USBPORT_SendSetupPacket: Status - %x\n", Status);
137 return Status;
138 }
139
140 ULONG
141 NTAPI
USBPORT_GetInterfaceLength(IN PUSB_INTERFACE_DESCRIPTOR iDescriptor,IN ULONG_PTR EndDescriptors)142 USBPORT_GetInterfaceLength(IN PUSB_INTERFACE_DESCRIPTOR iDescriptor,
143 IN ULONG_PTR EndDescriptors)
144 {
145 SIZE_T Length;
146 PUSB_ENDPOINT_DESCRIPTOR Descriptor;
147 ULONG ix;
148
149 DPRINT("USBPORT_GetInterfaceLength ... \n");
150
151 Length = iDescriptor->bLength;
152 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)iDescriptor + Length);
153
154 if (iDescriptor->bNumEndpoints)
155 {
156 for (ix = 0; ix < iDescriptor->bNumEndpoints; ix++)
157 {
158 while ((Descriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE) &&
159 (Descriptor->bLength > 0))
160 {
161 Length += Descriptor->bLength;
162 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor +
163 Descriptor->bLength);
164 }
165
166 Length += Descriptor->bLength;
167 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor +
168 Descriptor->bLength);
169 }
170 }
171
172 while (((ULONG_PTR)Descriptor < EndDescriptors) &&
173 (Descriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE) &&
174 (Descriptor->bLength > 0))
175 {
176 Length += Descriptor->bLength;
177 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor +
178 Descriptor->bLength);
179 }
180
181 return Length;
182 }
183
184 PUSB_INTERFACE_DESCRIPTOR
185 NTAPI
USBPORT_ParseConfigurationDescriptor(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor,IN UCHAR InterfaceNumber,IN UCHAR Alternate,OUT PBOOLEAN HasAlternates)186 USBPORT_ParseConfigurationDescriptor(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor,
187 IN UCHAR InterfaceNumber,
188 IN UCHAR Alternate,
189 OUT PBOOLEAN HasAlternates)
190 {
191 PUSB_CONFIGURATION_DESCRIPTOR TmpDescriptor;
192 PUSB_INTERFACE_DESCRIPTOR iDescriptor;
193 PUSB_INTERFACE_DESCRIPTOR OutDescriptor = NULL;
194 ULONG_PTR Descriptor = (ULONG_PTR)ConfigDescriptor;
195 ULONG_PTR EndDescriptors;
196 ULONG ix;
197
198 DPRINT("USBPORT_ParseConfigurationDescriptor ... \n");
199
200 if (HasAlternates)
201 *HasAlternates = FALSE;
202
203 for (TmpDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)ConfigDescriptor + ConfigDescriptor->bLength);
204 TmpDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE && TmpDescriptor->bLength > 0;
205 TmpDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)TmpDescriptor + TmpDescriptor->bLength))
206 ;
207
208 iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)TmpDescriptor;
209
210 EndDescriptors = (ULONG_PTR)ConfigDescriptor +
211 ConfigDescriptor->wTotalLength;
212
213 while ((Descriptor < EndDescriptors) &&
214 (iDescriptor->bInterfaceNumber != InterfaceNumber))
215 {
216 Descriptor = (ULONG_PTR)iDescriptor +
217 USBPORT_GetInterfaceLength(iDescriptor, EndDescriptors);
218
219 iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Descriptor;
220 }
221
222 ix = 0;
223
224 while (Descriptor < EndDescriptors &&
225 iDescriptor->bInterfaceNumber == InterfaceNumber)
226 {
227 if (iDescriptor->bAlternateSetting == Alternate)
228 OutDescriptor = iDescriptor;
229
230 Descriptor = (ULONG_PTR)iDescriptor +
231 USBPORT_GetInterfaceLength(iDescriptor, EndDescriptors);
232
233 iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Descriptor;
234
235 ++ix;
236 }
237
238 if ((ix > 1) && HasAlternates)
239 *HasAlternates = TRUE;
240
241 return OutDescriptor;
242 }
243
244 USBD_STATUS
245 NTAPI
USBPORT_OpenInterface(IN PURB Urb,IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle,IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,IN OUT PUSBPORT_INTERFACE_HANDLE * iHandle,IN BOOLEAN SendSetInterface)246 USBPORT_OpenInterface(IN PURB Urb,
247 IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
248 IN PDEVICE_OBJECT FdoDevice,
249 IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle,
250 IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,
251 IN OUT PUSBPORT_INTERFACE_HANDLE *iHandle,
252 IN BOOLEAN SendSetInterface)
253 {
254 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
255 PUSBPORT_INTERFACE_HANDLE InterfaceHandle = NULL;
256 PUSBPORT_PIPE_HANDLE PipeHandle;
257 PUSB_ENDPOINT_DESCRIPTOR Descriptor;
258 PUSBD_PIPE_INFORMATION PipeInfo;
259 BOOLEAN HasAlternates;
260 ULONG NumEndpoints;
261 SIZE_T Length;
262 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
263 SIZE_T HandleLength;
264 BOOLEAN IsAllocated = FALSE;
265 USHORT MaxPacketSize;
266 USHORT wMaxPacketSize;
267 ULONG ix;
268 USBD_STATUS USBDStatus = USBD_STATUS_SUCCESS;
269 NTSTATUS Status;
270
271 DPRINT("USBPORT_OpenInterface: ...\n");
272
273 InterfaceDescriptor = USBPORT_ParseConfigurationDescriptor(ConfigHandle->ConfigurationDescriptor,
274 InterfaceInfo->InterfaceNumber,
275 InterfaceInfo->AlternateSetting,
276 &HasAlternates);
277
278 NumEndpoints = InterfaceDescriptor->bNumEndpoints;
279
280 Length = FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes) +
281 NumEndpoints * sizeof(USBD_PIPE_INFORMATION);
282
283 if (HasAlternates && SendSetInterface)
284 {
285 RtlZeroMemory(&SetupPacket, sizeof(SetupPacket));
286
287 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
288 SetupPacket.bmRequestType.Type = BMREQUEST_STANDARD;
289 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
290 SetupPacket.bRequest = USB_REQUEST_SET_INTERFACE;
291 SetupPacket.wValue.W = InterfaceInfo->AlternateSetting;
292 SetupPacket.wIndex.W = InterfaceInfo->InterfaceNumber;
293 SetupPacket.wLength = 0;
294
295 USBPORT_SendSetupPacket(DeviceHandle,
296 FdoDevice,
297 &SetupPacket,
298 NULL,
299 0,
300 NULL,
301 &USBDStatus);
302 if (!USBD_SUCCESS(USBDStatus))
303 {
304 goto Exit;
305 }
306 }
307
308 if (*iHandle)
309 {
310 InterfaceHandle = *iHandle;
311 }
312 else
313 {
314 HandleLength = FIELD_OFFSET(USBPORT_INTERFACE_HANDLE, PipeHandle) +
315 NumEndpoints * sizeof(USBPORT_PIPE_HANDLE);
316
317 InterfaceHandle = ExAllocatePoolWithTag(NonPagedPool,
318 HandleLength,
319 USB_PORT_TAG);
320
321 if (!InterfaceHandle)
322 {
323 USBDStatus = USBD_STATUS_INSUFFICIENT_RESOURCES;
324 goto Exit;
325 }
326
327 RtlZeroMemory(InterfaceHandle, HandleLength);
328
329 for (ix = 0; ix < NumEndpoints; ++ix)
330 {
331 PipeHandle = &InterfaceHandle->PipeHandle[ix];
332
333 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED;
334 PipeHandle->Endpoint = NULL;
335 }
336
337 IsAllocated = TRUE;
338 }
339
340 InterfaceHandle->AlternateSetting = InterfaceInfo->AlternateSetting;
341
342 RtlCopyMemory(&InterfaceHandle->InterfaceDescriptor,
343 InterfaceDescriptor,
344 sizeof(USB_INTERFACE_DESCRIPTOR));
345
346 InterfaceInfo->Class = InterfaceDescriptor->bInterfaceClass;
347 InterfaceInfo->SubClass = InterfaceDescriptor->bInterfaceSubClass;
348 InterfaceInfo->Protocol = InterfaceDescriptor->bInterfaceProtocol;
349 InterfaceInfo->Reserved = 0;
350 InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints;
351
352 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor +
353 InterfaceDescriptor->bLength);
354
355 for (ix = 0; ix < NumEndpoints; ++ix)
356 {
357 PipeHandle = &InterfaceHandle->PipeHandle[ix];
358
359 while (Descriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE)
360 {
361 if (Descriptor->bLength == 0)
362 {
363 break;
364 }
365 else
366 {
367 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor +
368 Descriptor->bLength);
369 }
370 }
371
372 if (InterfaceInfo->Pipes[ix].PipeFlags & USBD_PF_CHANGE_MAX_PACKET)
373 {
374 Descriptor->wMaxPacketSize = InterfaceInfo->Pipes[ix].MaximumPacketSize;
375 }
376
377 RtlCopyMemory(&PipeHandle->EndpointDescriptor,
378 Descriptor,
379 sizeof(USB_ENDPOINT_DESCRIPTOR));
380
381 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED;
382 PipeHandle->PipeFlags = InterfaceInfo->Pipes[ix].PipeFlags;
383 PipeHandle->Endpoint = NULL;
384
385 wMaxPacketSize = Descriptor->wMaxPacketSize;
386
387 /* USB 2.0 Specification, 5.9 High-Speed, High Bandwidth Endpoints */
388 MaxPacketSize = (wMaxPacketSize & 0x7FF) * (((wMaxPacketSize >> 11) & 3) + 1);
389
390 InterfaceInfo->Pipes[ix].EndpointAddress = Descriptor->bEndpointAddress;
391 InterfaceInfo->Pipes[ix].PipeType = Descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK;
392 InterfaceInfo->Pipes[ix].MaximumPacketSize = MaxPacketSize;
393 InterfaceInfo->Pipes[ix].PipeHandle = (USBD_PIPE_HANDLE)-1;
394 InterfaceInfo->Pipes[ix].Interval = Descriptor->bInterval;
395
396 Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)Descriptor +
397 Descriptor->bLength);
398 }
399
400 if (USBD_SUCCESS(USBDStatus))
401 {
402 for (ix = 0; ix < NumEndpoints; ++ix)
403 {
404 PipeInfo = &InterfaceInfo->Pipes[ix];
405 PipeHandle = &InterfaceHandle->PipeHandle[ix];
406
407 Status = USBPORT_OpenPipe(FdoDevice,
408 DeviceHandle,
409 PipeHandle,
410 &USBDStatus);
411
412 if (!NT_SUCCESS(Status))
413 break;
414
415 PipeInfo->PipeHandle = PipeHandle;
416 }
417
418 if (NumEndpoints)
419 {
420 USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
421 }
422 }
423
424 Exit:
425
426 if (USBD_SUCCESS(USBDStatus))
427 {
428 InterfaceInfo->InterfaceHandle = InterfaceHandle;
429 *iHandle = InterfaceHandle;
430 InterfaceInfo->Length = Length;
431 }
432 else
433 {
434 if (InterfaceHandle)
435 {
436 if (NumEndpoints)
437 {
438 DPRINT1("USBPORT_OpenInterface: USBDStatus - %lx\n", USBDStatus);
439 }
440
441 if (IsAllocated)
442 ExFreePoolWithTag(InterfaceHandle, USB_PORT_TAG);
443 }
444 }
445
446 return USBDStatus;
447 }
448
449 VOID
450 NTAPI
USBPORT_CloseConfiguration(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PDEVICE_OBJECT FdoDevice)451 USBPORT_CloseConfiguration(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
452 IN PDEVICE_OBJECT FdoDevice)
453 {
454 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle;
455 PLIST_ENTRY iHandleList;
456 PUSBPORT_INTERFACE_HANDLE iHandle;
457 ULONG NumEndpoints;
458 PUSBPORT_PIPE_HANDLE PipeHandle;
459
460 DPRINT("USBPORT_CloseConfiguration: ... \n");
461
462 ConfigHandle = DeviceHandle->ConfigHandle;
463
464 if (ConfigHandle)
465 {
466 iHandleList = &ConfigHandle->InterfaceHandleList;
467
468 while (!IsListEmpty(iHandleList))
469 {
470 iHandle = CONTAINING_RECORD(iHandleList->Flink,
471 USBPORT_INTERFACE_HANDLE,
472 InterfaceLink);
473
474 DPRINT("USBPORT_CloseConfiguration: iHandle - %p\n", iHandle);
475
476 RemoveHeadList(iHandleList);
477
478 NumEndpoints = iHandle->InterfaceDescriptor.bNumEndpoints;
479
480 PipeHandle = &iHandle->PipeHandle[0];
481
482 while (NumEndpoints > 0)
483 {
484 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle);
485 PipeHandle += 1;
486 --NumEndpoints;
487 }
488
489 ExFreePoolWithTag(iHandle, USB_PORT_TAG);
490 }
491
492 ExFreePoolWithTag(ConfigHandle, USB_PORT_TAG);
493 DeviceHandle->ConfigHandle = NULL;
494 }
495 }
496
497 NTSTATUS
498 NTAPI
USBPORT_InitInterfaceInfo(IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle)499 USBPORT_InitInterfaceInfo(IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,
500 IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle)
501 {
502 PUSB_INTERFACE_DESCRIPTOR Descriptor;
503 PUSBD_PIPE_INFORMATION Pipe;
504 SIZE_T Length;
505 ULONG PipeFlags;
506 ULONG NumberOfPipes;
507 USBD_STATUS USBDStatus = USBD_STATUS_SUCCESS;
508
509 DPRINT("USBPORT_InitInterfaceInfo: InterfaceInfo - %p, ConfigHandle - %p\n",
510 InterfaceInfo,
511 ConfigHandle);
512
513 Descriptor = USBPORT_ParseConfigurationDescriptor(ConfigHandle->ConfigurationDescriptor,
514 InterfaceInfo->InterfaceNumber,
515 InterfaceInfo->AlternateSetting,
516 NULL);
517
518 Length = sizeof(USBD_INTERFACE_INFORMATION) +
519 sizeof(USBD_PIPE_INFORMATION);
520
521 if (Descriptor)
522 {
523 NumberOfPipes = Descriptor->bNumEndpoints;
524
525 Length = FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes) +
526 NumberOfPipes * sizeof(USBD_PIPE_INFORMATION);
527
528 if (InterfaceInfo->Length >= Length)
529 {
530 InterfaceInfo->Class = 0;
531 InterfaceInfo->SubClass = 0;
532 InterfaceInfo->Protocol = 0;
533 InterfaceInfo->Reserved = 0;
534 InterfaceInfo->InterfaceHandle = 0;
535 InterfaceInfo->NumberOfPipes = NumberOfPipes;
536
537 Pipe = InterfaceInfo->Pipes;
538
539 while (NumberOfPipes > 0)
540 {
541 Pipe->EndpointAddress = 0;
542 Pipe->Interval = 0;
543 Pipe->PipeType = 0;
544 Pipe->PipeHandle = 0;
545
546 PipeFlags = Pipe->PipeFlags;
547
548 if (PipeFlags & ~USBD_PF_VALID_MASK)
549 USBDStatus = USBD_STATUS_INVALID_PIPE_FLAGS;
550
551 if (!(PipeFlags & USBD_PF_CHANGE_MAX_PACKET))
552 Pipe->MaximumPacketSize = 0;
553
554 Pipe += 1;
555 --NumberOfPipes;
556 }
557 }
558 else
559 {
560 USBDStatus = USBD_STATUS_BUFFER_TOO_SMALL;
561 }
562 }
563 else
564 {
565 USBDStatus = USBD_STATUS_INTERFACE_NOT_FOUND;
566 }
567
568 InterfaceInfo->Length = Length;
569 return USBDStatus;
570 }
571
572 NTSTATUS
573 NTAPI
USBPORT_HandleSelectConfiguration(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)574 USBPORT_HandleSelectConfiguration(IN PDEVICE_OBJECT FdoDevice,
575 IN PIRP Irp,
576 IN PURB Urb)
577 {
578 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor;
579 PUSBPORT_DEVICE_HANDLE DeviceHandle;
580 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle = NULL;
581 PUSBD_INTERFACE_INFORMATION InterfaceInfo;
582 PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
583 ULONG iNumber;
584 ULONG ix;
585 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
586 NTSTATUS Status;
587 USBD_STATUS USBDStatus;
588 PUSBPORT_DEVICE_EXTENSION FdoExtension;
589
590 DPRINT("USBPORT_HandleSelectConfiguration: ConfigDescriptor %p\n",
591 Urb->UrbSelectConfiguration.ConfigurationDescriptor);
592
593 FdoExtension = FdoDevice->DeviceExtension;
594
595 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
596 Executive,
597 KernelMode,
598 FALSE,
599 NULL);
600
601 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
602 ConfigDescriptor = Urb->UrbSelectConfiguration.ConfigurationDescriptor;
603
604 if (!ConfigDescriptor)
605 {
606 DPRINT("USBPORT_HandleSelectConfiguration: ConfigDescriptor == NULL\n");
607
608 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
609
610 SetupPacket.bmRequestType.B = 0;
611 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION;
612 SetupPacket.wValue.W = 0;
613 SetupPacket.wIndex.W = 0;
614 SetupPacket.wLength = 0;
615
616 USBPORT_SendSetupPacket(DeviceHandle,
617 FdoDevice,
618 &SetupPacket,
619 NULL,
620 0,
621 NULL,
622 NULL);
623
624 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
625 goto Exit;
626 }
627
628 USBPORT_DumpingConfiguration(ConfigDescriptor);
629
630 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
631
632 iNumber = 0;
633
634 do
635 {
636 ++iNumber;
637 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)
638 ((ULONG_PTR)InterfaceInfo +
639 InterfaceInfo->Length);
640 }
641 while ((ULONG_PTR)InterfaceInfo < (ULONG_PTR)Urb + Urb->UrbHeader.Length);
642
643 if ((iNumber <= 0) || (iNumber != ConfigDescriptor->bNumInterfaces))
644 {
645 Status = USBPORT_USBDStatusToNtStatus(Urb,
646 USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR);
647 goto Exit;
648 }
649
650 ConfigHandle = ExAllocatePoolWithTag(NonPagedPool,
651 ConfigDescriptor->wTotalLength + sizeof(USBPORT_CONFIGURATION_HANDLE),
652 USB_PORT_TAG);
653
654 if (!ConfigHandle)
655 {
656 Status = USBPORT_USBDStatusToNtStatus(Urb,
657 USBD_STATUS_INSUFFICIENT_RESOURCES);
658 goto Exit;
659 }
660
661 RtlZeroMemory(ConfigHandle,
662 ConfigDescriptor->wTotalLength + sizeof(USBPORT_CONFIGURATION_HANDLE));
663
664 InitializeListHead(&ConfigHandle->InterfaceHandleList);
665
666 ConfigHandle->ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)(ConfigHandle + 1);
667
668 RtlCopyMemory(ConfigHandle->ConfigurationDescriptor,
669 ConfigDescriptor,
670 ConfigDescriptor->wTotalLength);
671
672 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
673
674 SetupPacket.bmRequestType.B = 0;
675 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION;
676 SetupPacket.wValue.W = ConfigDescriptor->bConfigurationValue;
677 SetupPacket.wIndex.W = 0;
678 SetupPacket.wLength = 0;
679
680 USBPORT_SendSetupPacket(DeviceHandle,
681 FdoDevice,
682 &SetupPacket,
683 NULL,
684 0,
685 NULL,
686 &USBDStatus);
687
688 if (USBD_ERROR(USBDStatus))
689 {
690 Status = USBPORT_USBDStatusToNtStatus(Urb,
691 USBD_STATUS_SET_CONFIG_FAILED);
692 goto Exit;
693 }
694
695 if (iNumber <= 0)
696 {
697 Status = USBPORT_USBDStatusToNtStatus(Urb,
698 USBD_STATUS_SUCCESS);
699
700 goto Exit;
701 }
702
703 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
704
705 for (ix = 0; ix < iNumber; ++ix)
706 {
707 USBDStatus = USBPORT_InitInterfaceInfo(InterfaceInfo,
708 ConfigHandle);
709
710 InterfaceHandle = NULL;
711
712 if (USBD_SUCCESS(USBDStatus))
713 {
714 USBDStatus = USBPORT_OpenInterface(Urb,
715 DeviceHandle,
716 FdoDevice,
717 ConfigHandle,
718 InterfaceInfo,
719 &InterfaceHandle,
720 TRUE);
721 }
722
723 if (InterfaceHandle)
724 {
725 InsertTailList(&ConfigHandle->InterfaceHandleList,
726 &InterfaceHandle->InterfaceLink);
727 }
728
729 if (USBD_ERROR(USBDStatus))
730 break;
731
732 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)
733 ((ULONG_PTR)InterfaceInfo +
734 InterfaceInfo->Length);
735 }
736
737 if (ix >= iNumber)
738 {
739 Status = USBPORT_USBDStatusToNtStatus(Urb,
740 USBD_STATUS_SUCCESS);
741 }
742 else
743 {
744 Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
745 }
746
747 Exit:
748
749 if (NT_SUCCESS(Status))
750 {
751 Urb->UrbSelectConfiguration.ConfigurationHandle = ConfigHandle;
752 DeviceHandle->ConfigHandle = ConfigHandle;
753 }
754 else
755 {
756 DPRINT1("USBPORT_HandleSelectConfiguration: Status %x\n", Status);
757 }
758
759 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
760 LOW_REALTIME_PRIORITY,
761 1,
762 FALSE);
763
764 return Status;
765 }
766
767 VOID
768 NTAPI
USBPORT_AddDeviceHandle(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE DeviceHandle)769 USBPORT_AddDeviceHandle(IN PDEVICE_OBJECT FdoDevice,
770 IN PUSBPORT_DEVICE_HANDLE DeviceHandle)
771 {
772 PUSBPORT_DEVICE_EXTENSION FdoExtension;
773
774 DPRINT("USBPORT_AddDeviceHandle: ... \n");
775
776 FdoExtension = FdoDevice->DeviceExtension;
777
778 InsertTailList(&FdoExtension->DeviceHandleList,
779 &DeviceHandle->DeviceHandleLink);
780 }
781
782 VOID
783 NTAPI
USBPORT_RemoveDeviceHandle(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE DeviceHandle)784 USBPORT_RemoveDeviceHandle(IN PDEVICE_OBJECT FdoDevice,
785 IN PUSBPORT_DEVICE_HANDLE DeviceHandle)
786 {
787 PUSBPORT_DEVICE_EXTENSION FdoExtension;
788 KIRQL OldIrql;
789
790 DPRINT("USBPORT_RemoveDeviceHandle \n");
791
792 FdoExtension = FdoDevice->DeviceExtension;
793
794 KeAcquireSpinLock(&FdoExtension->DeviceHandleSpinLock, &OldIrql);
795 RemoveEntryList(&DeviceHandle->DeviceHandleLink);
796 KeReleaseSpinLock(&FdoExtension->DeviceHandleSpinLock, OldIrql);
797 }
798
799 BOOLEAN
800 NTAPI
USBPORT_ValidateDeviceHandle(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE DeviceHandle)801 USBPORT_ValidateDeviceHandle(IN PDEVICE_OBJECT FdoDevice,
802 IN PUSBPORT_DEVICE_HANDLE DeviceHandle)
803 {
804 PUSBPORT_DEVICE_EXTENSION FdoExtension;
805 KIRQL OldIrql;
806 PLIST_ENTRY HandleList;
807 PUSBPORT_DEVICE_HANDLE CurrentHandle;
808 BOOLEAN Result = FALSE;
809
810 //DPRINT("USBPORT_ValidateDeviceHandle: DeviceHandle - %p\n", DeviceHandle \n");
811
812 FdoExtension = FdoDevice->DeviceExtension;
813
814 KeAcquireSpinLock(&FdoExtension->DeviceHandleSpinLock, &OldIrql);
815 if (DeviceHandle)
816 {
817 HandleList = FdoExtension->DeviceHandleList.Flink;
818
819 while (HandleList != &FdoExtension->DeviceHandleList)
820 {
821 CurrentHandle = CONTAINING_RECORD(HandleList,
822 USBPORT_DEVICE_HANDLE,
823 DeviceHandleLink);
824
825 if (CurrentHandle == DeviceHandle)
826 {
827 Result = TRUE;
828 break;
829 }
830
831 HandleList = HandleList->Flink;
832 }
833 }
834 KeReleaseSpinLock(&FdoExtension->DeviceHandleSpinLock, OldIrql);
835
836 return Result;
837 }
838
839 BOOLEAN
840 NTAPI
USBPORT_DeviceHasTransfers(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE DeviceHandle)841 USBPORT_DeviceHasTransfers(IN PDEVICE_OBJECT FdoDevice,
842 IN PUSBPORT_DEVICE_HANDLE DeviceHandle)
843 {
844 PLIST_ENTRY PipeHandleList;
845 PUSBPORT_PIPE_HANDLE PipeHandle;
846
847 DPRINT("USBPORT_DeviceHasTransfers: ... \n");
848
849 PipeHandleList = DeviceHandle->PipeHandleList.Flink;
850
851 while (PipeHandleList != &DeviceHandle->PipeHandleList)
852 {
853 PipeHandle = CONTAINING_RECORD(PipeHandleList,
854 USBPORT_PIPE_HANDLE,
855 PipeLink);
856
857 PipeHandleList = PipeHandleList->Flink;
858
859 if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE) &&
860 USBPORT_EndpointHasQueuedTransfers(FdoDevice, PipeHandle->Endpoint, NULL))
861 {
862 return TRUE;
863 }
864 }
865
866 return FALSE;
867 }
868
869 VOID
870 NTAPI
USBPORT_AbortTransfers(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE DeviceHandle)871 USBPORT_AbortTransfers(IN PDEVICE_OBJECT FdoDevice,
872 IN PUSBPORT_DEVICE_HANDLE DeviceHandle)
873 {
874 PLIST_ENTRY HandleList;
875 PUSBPORT_PIPE_HANDLE PipeHandle;
876 BOOLEAN Result;
877
878 DPRINT("USBPORT_AbortAllTransfers: ... \n");
879
880 HandleList = DeviceHandle->PipeHandleList.Flink;
881
882 while (HandleList != &DeviceHandle->PipeHandleList)
883 {
884 PipeHandle = CONTAINING_RECORD(HandleList,
885 USBPORT_PIPE_HANDLE,
886 PipeLink);
887
888 HandleList = HandleList->Flink;
889
890 if (!(PipeHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB))
891 {
892 PipeHandle->Endpoint->Flags |= ENDPOINT_FLAG_ABORTING;
893
894 USBPORT_AbortEndpoint(FdoDevice, PipeHandle->Endpoint, NULL);
895 USBPORT_FlushMapTransfers(FdoDevice);
896 }
897 }
898
899 while (TRUE)
900 {
901 Result = USBPORT_DeviceHasTransfers(FdoDevice, DeviceHandle);
902
903 if (!Result)
904 break;
905
906 USBPORT_Wait(FdoDevice, 100);
907 }
908 }
909
910 PUSB2_TT_EXTENSION
911 NTAPI
USBPORT_GetTt(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,OUT PUSHORT OutPort,OUT PUSBPORT_DEVICE_HANDLE * OutHubDeviceHandle)912 USBPORT_GetTt(IN PDEVICE_OBJECT FdoDevice,
913 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,
914 OUT PUSHORT OutPort,
915 OUT PUSBPORT_DEVICE_HANDLE * OutHubDeviceHandle)
916 {
917 PUSBPORT_DEVICE_HANDLE DeviceHandle = HubDeviceHandle;
918 ULONG TtCount;
919 PLIST_ENTRY Entry;
920 PUSB2_TT_EXTENSION TtExtension = NULL;
921
922 DPRINT("USBPORT_GetTt: HubDeviceHandle - %p\n", HubDeviceHandle);
923
924 *OutHubDeviceHandle = NULL;
925
926 while (DeviceHandle->DeviceSpeed != UsbHighSpeed)
927 {
928 DPRINT("USBPORT_GetTt: DeviceHandle - %p, DeviceHandle->PortNumber - %X\n",
929 DeviceHandle,
930 DeviceHandle->PortNumber);
931
932 *OutPort = DeviceHandle->PortNumber;
933
934 DeviceHandle = DeviceHandle->HubDeviceHandle;
935
936 if (!DeviceHandle)
937 return NULL;
938 }
939
940 TtCount = DeviceHandle->TtCount;
941
942 if (!TtCount)
943 return NULL;
944
945 if (IsListEmpty(&DeviceHandle->TtList))
946 return NULL;
947
948 Entry = DeviceHandle->TtList.Flink;
949
950 if (TtCount > 1)
951 {
952 while (Entry != &DeviceHandle->TtList)
953 {
954 ASSERT(Entry != NULL);
955
956 TtExtension = CONTAINING_RECORD(Entry,
957 USB2_TT_EXTENSION,
958 Link);
959
960 if (TtExtension->TtNumber == *OutPort)
961 break;
962
963 Entry = Entry->Flink;
964
965 TtExtension = NULL;
966 }
967 }
968 else
969 {
970 TtExtension = CONTAINING_RECORD(Entry,
971 USB2_TT_EXTENSION,
972 Link);
973 }
974
975 *OutHubDeviceHandle = DeviceHandle;
976
977 return TtExtension;
978 }
979
980 NTSTATUS
981 NTAPI
USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE * pUsbdDeviceHandle,IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,IN USHORT PortStatus,IN USHORT Port)982 USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle,
983 IN PDEVICE_OBJECT FdoDevice,
984 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,
985 IN USHORT PortStatus,
986 IN USHORT Port)
987 {
988 PUSBPORT_DEVICE_HANDLE TtDeviceHandle = NULL;
989 PUSB2_TT_EXTENSION TtExtension = NULL;
990 USHORT port;
991 PUSBPORT_DEVICE_HANDLE DeviceHandle;
992 PUSBPORT_PIPE_HANDLE PipeHandle;
993 BOOL IsOpenedPipe;
994 PVOID DeviceDescriptor;
995 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
996 ULONG TransferedLen;
997 ULONG DescriptorMinSize;
998 UCHAR MaxPacketSize;
999 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1000 PUSBPORT_REGISTRATION_PACKET Packet;
1001 NTSTATUS Status;
1002
1003 DPRINT("USBPORT_CreateDevice: PortStatus - %p, Port - %x\n",
1004 PortStatus,
1005 Port);
1006
1007 FdoExtension = FdoDevice->DeviceExtension;
1008 Packet = &FdoExtension->MiniPortInterface->Packet;
1009
1010 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
1011 Executive,
1012 KernelMode,
1013 FALSE,
1014 NULL);
1015
1016 if (!USBPORT_ValidateDeviceHandle(FdoDevice, HubDeviceHandle))
1017 {
1018 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1019 LOW_REALTIME_PRIORITY,
1020 1,
1021 FALSE);
1022
1023 DPRINT1("USBPORT_CreateDevice: Not valid hub DeviceHandle\n");
1024 return STATUS_DEVICE_NOT_CONNECTED;
1025 }
1026
1027 port = Port;
1028
1029 if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2 &&
1030 !(PortStatus & USB_PORT_STATUS_HIGH_SPEED))
1031 {
1032 DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port\n");
1033
1034 TtExtension = USBPORT_GetTt(FdoDevice,
1035 HubDeviceHandle,
1036 &port,
1037 &TtDeviceHandle);
1038
1039 DPRINT("USBPORT_CreateDevice: TtDeviceHandle - %p, port - %x\n",
1040 TtDeviceHandle,
1041 port);
1042 }
1043
1044 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1045 LOW_REALTIME_PRIORITY,
1046 1,
1047 FALSE);
1048
1049 DeviceHandle = ExAllocatePoolWithTag(NonPagedPool,
1050 sizeof(USBPORT_DEVICE_HANDLE),
1051 USB_PORT_TAG);
1052
1053 if (!DeviceHandle)
1054 {
1055 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceHandle\n");
1056 return STATUS_INSUFFICIENT_RESOURCES;
1057 }
1058
1059 RtlZeroMemory(DeviceHandle, sizeof(USBPORT_DEVICE_HANDLE));
1060
1061 *pUsbdDeviceHandle = NULL;
1062
1063 DeviceHandle->TtExtension = TtExtension;
1064 DeviceHandle->PortNumber = Port;
1065 DeviceHandle->HubDeviceHandle = HubDeviceHandle;
1066
1067 if (PortStatus & USB_PORT_STATUS_LOW_SPEED)
1068 {
1069 DeviceHandle->DeviceSpeed = UsbLowSpeed;
1070 }
1071 else if (PortStatus & USB_PORT_STATUS_HIGH_SPEED)
1072 {
1073 DeviceHandle->DeviceSpeed = UsbHighSpeed;
1074 }
1075 else
1076 {
1077 DeviceHandle->DeviceSpeed = UsbFullSpeed;
1078 }
1079
1080 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
1081 Executive,
1082 KernelMode,
1083 FALSE,
1084 NULL);
1085
1086 PipeHandle = &DeviceHandle->PipeHandle;
1087
1088 PipeHandle->Flags = PIPE_HANDLE_FLAG_CLOSED;
1089
1090 PipeHandle->EndpointDescriptor.bLength = sizeof(PipeHandle->EndpointDescriptor);
1091 PipeHandle->EndpointDescriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
1092
1093 if (DeviceHandle->DeviceSpeed == UsbLowSpeed)
1094 {
1095 PipeHandle->EndpointDescriptor.wMaxPacketSize = 8;
1096 }
1097 else
1098 {
1099 PipeHandle->EndpointDescriptor.wMaxPacketSize = USB_DEFAULT_MAX_PACKET;
1100 }
1101
1102 InitializeListHead(&DeviceHandle->PipeHandleList);
1103 InitializeListHead(&DeviceHandle->TtList);
1104
1105 Status = USBPORT_OpenPipe(FdoDevice,
1106 DeviceHandle,
1107 PipeHandle,
1108 NULL);
1109
1110 IsOpenedPipe = NT_SUCCESS(Status);
1111
1112 if (NT_ERROR(Status))
1113 {
1114 DPRINT1("USBPORT_CreateDevice: USBPORT_OpenPipe return - %lx\n", Status);
1115
1116 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1117 LOW_REALTIME_PRIORITY,
1118 1,
1119 FALSE);
1120
1121 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG);
1122
1123 return Status;
1124 }
1125
1126 DeviceDescriptor = ExAllocatePoolWithTag(NonPagedPool,
1127 USB_DEFAULT_MAX_PACKET,
1128 USB_PORT_TAG);
1129
1130 if (!DeviceDescriptor)
1131 {
1132 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceDescriptor\n");
1133 goto ErrorExit;
1134 }
1135
1136 RtlZeroMemory(DeviceDescriptor, USB_DEFAULT_MAX_PACKET);
1137 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1138
1139 SetupPacket.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1140 SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1141 SetupPacket.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE;
1142 SetupPacket.wLength = USB_DEFAULT_MAX_PACKET;
1143
1144 TransferedLen = 0;
1145
1146 Status = USBPORT_SendSetupPacket(DeviceHandle,
1147 FdoDevice,
1148 &SetupPacket,
1149 DeviceDescriptor,
1150 USB_DEFAULT_MAX_PACKET,
1151 &TransferedLen,
1152 NULL);
1153
1154 RtlCopyMemory(&DeviceHandle->DeviceDescriptor,
1155 DeviceDescriptor,
1156 sizeof(USB_DEVICE_DESCRIPTOR));
1157
1158 ExFreePoolWithTag(DeviceDescriptor, USB_PORT_TAG);
1159
1160 DescriptorMinSize = RTL_SIZEOF_THROUGH_FIELD(USB_DEVICE_DESCRIPTOR,
1161 bMaxPacketSize0);
1162
1163 if ((TransferedLen == DescriptorMinSize) && !NT_SUCCESS(Status))
1164 {
1165 Status = STATUS_SUCCESS;
1166 }
1167
1168 if (NT_SUCCESS(Status) && (TransferedLen >= DescriptorMinSize))
1169 {
1170 if ((DeviceHandle->DeviceDescriptor.bLength >= sizeof(USB_DEVICE_DESCRIPTOR)) &&
1171 (DeviceHandle->DeviceDescriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE))
1172 {
1173 MaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0;
1174
1175 if (MaxPacketSize == 8 ||
1176 MaxPacketSize == 16 ||
1177 MaxPacketSize == 32 ||
1178 MaxPacketSize == 64)
1179 {
1180 USBPORT_AddDeviceHandle(FdoDevice, DeviceHandle);
1181
1182 *pUsbdDeviceHandle = DeviceHandle;
1183
1184 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1185 LOW_REALTIME_PRIORITY,
1186 1,
1187 FALSE);
1188
1189 return Status;
1190 }
1191 }
1192 }
1193
1194 DPRINT1("USBPORT_CreateDevice: ERROR!!! TransferedLen - %x, Status - %lx\n",
1195 TransferedLen,
1196 Status);
1197
1198 ErrorExit:
1199
1200 if (TtExtension && TtDeviceHandle)
1201 {
1202 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_OTHER;
1203 SetupPacket.bmRequestType.Reserved = 0;
1204 SetupPacket.bmRequestType.Type = BMREQUEST_CLASS;
1205 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1206
1207 /* Table 11-15. Hub Class Requests */
1208 if (TtDeviceHandle == HubDeviceHandle)
1209 {
1210 SetupPacket.bRequest = USB_REQUEST_RESET_TT;
1211 }
1212 else
1213 {
1214 SetupPacket.bRequest = USB_REQUEST_CLEAR_TT_BUFFER;
1215 }
1216
1217 SetupPacket.wValue.LowByte = 0;
1218 SetupPacket.wValue.HiByte = 0;
1219 SetupPacket.wIndex.W = port;
1220 SetupPacket.wLength = 0;
1221
1222 USBPORT_SendSetupPacket(TtDeviceHandle,
1223 FdoDevice,
1224 &SetupPacket,
1225 NULL,
1226 0,
1227 NULL,
1228 NULL);
1229 }
1230
1231 Status = STATUS_DEVICE_DATA_ERROR;
1232
1233 if (IsOpenedPipe)
1234 {
1235 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle);
1236 }
1237
1238 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1239 LOW_REALTIME_PRIORITY,
1240 1,
1241 FALSE);
1242
1243 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG);
1244
1245 return Status;
1246 }
1247
1248 ULONG
1249 NTAPI
USBPORT_AllocateUsbAddress(IN PDEVICE_OBJECT FdoDevice)1250 USBPORT_AllocateUsbAddress(IN PDEVICE_OBJECT FdoDevice)
1251 {
1252 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1253 ULONG BitMapIdx;
1254 ULONG BitNumber;
1255 ULONG ix;
1256
1257 DPRINT("USBPORT_AllocateUsbAddress \n");
1258
1259 FdoExtension = FdoDevice->DeviceExtension;
1260
1261 for (ix = 0; ix < 4; ++ix)
1262 {
1263 BitMapIdx = 1;
1264
1265 for (BitNumber = 0; BitNumber < 32; ++BitNumber)
1266 {
1267 if (!(FdoExtension->UsbAddressBitMap[ix] & BitMapIdx))
1268 {
1269 FdoExtension->UsbAddressBitMap[ix] |= BitMapIdx;
1270 return 32 * ix + BitNumber;
1271 }
1272
1273 BitMapIdx <<= 2;
1274 }
1275 }
1276
1277 return 0;
1278 }
1279
1280 VOID
1281 NTAPI
USBPORT_FreeUsbAddress(IN PDEVICE_OBJECT FdoDevice,IN USHORT DeviceAddress)1282 USBPORT_FreeUsbAddress(IN PDEVICE_OBJECT FdoDevice,
1283 IN USHORT DeviceAddress)
1284 {
1285 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1286 ULONG ix;
1287 ULONG BitMapIdx;
1288 ULONG BitNumber;
1289 USHORT CurrentAddress;
1290
1291 DPRINT("USBPORT_FreeUsbAddress: DeviceAddress - %x\n", DeviceAddress);
1292
1293 FdoExtension = FdoDevice->DeviceExtension;
1294
1295 for (ix = 0; ix < 4; ++ix)
1296 {
1297 BitMapIdx = 1;
1298 CurrentAddress = 32 * ix;
1299
1300 for (BitNumber = 0; BitNumber < 32; ++BitNumber)
1301 {
1302 if (CurrentAddress == DeviceAddress)
1303 {
1304 FdoExtension->UsbAddressBitMap[ix] &= ~BitMapIdx;
1305 return;
1306 }
1307
1308 BitMapIdx <<= 2;
1309 CurrentAddress++;
1310 }
1311 }
1312 }
1313
1314 NTSTATUS
1315 NTAPI
USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PDEVICE_OBJECT FdoDevice)1316 USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
1317 IN PDEVICE_OBJECT FdoDevice)
1318 {
1319 PUSBPORT_ENDPOINT Endpoint;
1320 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
1321 ULONG TransferedLen;
1322 USHORT DeviceAddress = 0;
1323 UCHAR MaxPacketSize;
1324 NTSTATUS Status;
1325 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1326
1327 DPRINT("USBPORT_InitializeDevice: ... \n");
1328
1329 ASSERT(DeviceHandle != NULL);
1330
1331 FdoExtension = FdoDevice->DeviceExtension;
1332
1333 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
1334 Executive,
1335 KernelMode,
1336 FALSE,
1337 NULL);
1338
1339 DeviceAddress = USBPORT_AllocateUsbAddress(FdoDevice);
1340 ASSERT(DeviceHandle->DeviceAddress == USB_DEFAULT_DEVICE_ADDRESS);
1341
1342 RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1343
1344 CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
1345 CtrlSetup.wValue.W = DeviceAddress;
1346
1347 Status = USBPORT_SendSetupPacket(DeviceHandle,
1348 FdoDevice,
1349 &CtrlSetup,
1350 NULL,
1351 0,
1352 NULL,
1353 NULL);
1354
1355 DPRINT("USBPORT_InitializeDevice: DeviceAddress - %x. SendSetupPacket Status - %x\n",
1356 DeviceAddress,
1357 Status);
1358
1359 if (!NT_SUCCESS(Status))
1360 goto ExitError;
1361
1362 DeviceHandle->DeviceAddress = DeviceAddress;
1363 Endpoint = DeviceHandle->PipeHandle.Endpoint;
1364
1365 Endpoint->EndpointProperties.TotalMaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0;
1366 Endpoint->EndpointProperties.DeviceAddress = DeviceAddress;
1367
1368 Status = USBPORT_ReopenPipe(FdoDevice, Endpoint);
1369
1370 if (!NT_SUCCESS(Status))
1371 goto ExitError;
1372
1373 USBPORT_Wait(FdoDevice, 10);
1374
1375 RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1376
1377 CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1378 CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE;
1379 CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
1380 CtrlSetup.bmRequestType.B = 0x80;
1381
1382 Status = USBPORT_SendSetupPacket(DeviceHandle,
1383 FdoDevice,
1384 &CtrlSetup,
1385 &DeviceHandle->DeviceDescriptor,
1386 sizeof(USB_DEVICE_DESCRIPTOR),
1387 &TransferedLen,
1388 NULL);
1389
1390 if (NT_SUCCESS(Status))
1391 {
1392 ASSERT(TransferedLen == sizeof(USB_DEVICE_DESCRIPTOR));
1393 ASSERT(DeviceHandle->DeviceDescriptor.bLength >= sizeof(USB_DEVICE_DESCRIPTOR));
1394 ASSERT(DeviceHandle->DeviceDescriptor.bDescriptorType == USB_DEVICE_DESCRIPTOR_TYPE);
1395
1396 MaxPacketSize = DeviceHandle->DeviceDescriptor.bMaxPacketSize0;
1397
1398 ASSERT((MaxPacketSize == 8) ||
1399 (MaxPacketSize == 16) ||
1400 (MaxPacketSize == 32) ||
1401 (MaxPacketSize == 64));
1402
1403 if (DeviceHandle->DeviceSpeed == UsbHighSpeed &&
1404 DeviceHandle->DeviceDescriptor.bDeviceClass == USB_DEVICE_CLASS_HUB)
1405 {
1406 DeviceHandle->Flags |= DEVICE_HANDLE_FLAG_USB2HUB;
1407 }
1408 }
1409 else
1410 {
1411 ExitError:
1412 DPRINT1("USBPORT_InitializeDevice: ExitError. Status - %x\n", Status);
1413 }
1414
1415 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1416 LOW_REALTIME_PRIORITY,
1417 1,
1418 FALSE);
1419
1420 return Status;
1421 }
1422
1423 NTSTATUS
1424 NTAPI
USBPORT_GetUsbDescriptor(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,IN PDEVICE_OBJECT FdoDevice,IN UCHAR Type,IN PUCHAR ConfigDesc,IN PULONG ConfigDescSize)1425 USBPORT_GetUsbDescriptor(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
1426 IN PDEVICE_OBJECT FdoDevice,
1427 IN UCHAR Type,
1428 IN PUCHAR ConfigDesc,
1429 IN PULONG ConfigDescSize)
1430 {
1431 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
1432
1433 DPRINT("USBPORT_GetUsbDescriptor: Type - %x\n");
1434
1435 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1436
1437 SetupPacket.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1438 SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR;
1439 SetupPacket.wValue.HiByte = Type;
1440 SetupPacket.wLength = (USHORT)*ConfigDescSize;
1441
1442 return USBPORT_SendSetupPacket(DeviceHandle,
1443 FdoDevice,
1444 &SetupPacket,
1445 ConfigDesc,
1446 *ConfigDescSize,
1447 ConfigDescSize,
1448 NULL);
1449 }
1450
1451 PUSBPORT_INTERFACE_HANDLE
1452 NTAPI
USBPORT_GetInterfaceHandle(IN PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle,IN UCHAR InterfaceNumber)1453 USBPORT_GetInterfaceHandle(IN PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle,
1454 IN UCHAR InterfaceNumber)
1455 {
1456 PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
1457 PLIST_ENTRY iHandleList;
1458 UCHAR InterfaceNum;
1459
1460 DPRINT("USBPORT_GetInterfaceHandle: ConfigurationHandle - %p, InterfaceNumber - %p\n",
1461 ConfigurationHandle,
1462 InterfaceNumber);
1463
1464 iHandleList = ConfigurationHandle->InterfaceHandleList.Flink;
1465
1466 while (iHandleList &&
1467 (iHandleList != &ConfigurationHandle->InterfaceHandleList))
1468 {
1469 InterfaceHandle = CONTAINING_RECORD(iHandleList,
1470 USBPORT_INTERFACE_HANDLE,
1471 InterfaceLink);
1472
1473 InterfaceNum = InterfaceHandle->InterfaceDescriptor.bInterfaceNumber;
1474
1475 if (InterfaceNum == InterfaceNumber)
1476 return InterfaceHandle;
1477
1478 iHandleList = InterfaceHandle->InterfaceLink.Flink;
1479 }
1480
1481 return NULL;
1482 }
1483
1484 NTSTATUS
1485 NTAPI
USBPORT_HandleSelectInterface(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)1486 USBPORT_HandleSelectInterface(IN PDEVICE_OBJECT FdoDevice,
1487 IN PIRP Irp,
1488 IN PURB Urb)
1489 {
1490 PUSBPORT_DEVICE_HANDLE DeviceHandle;
1491 PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle;
1492 PUSBD_INTERFACE_INFORMATION Interface;
1493 PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
1494 PUSBPORT_INTERFACE_HANDLE iHandle;
1495 PUSBPORT_PIPE_HANDLE PipeHandle;
1496 USBD_STATUS USBDStatus;
1497 USHORT Length;
1498 ULONG ix;
1499 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1500
1501 DPRINT("USBPORT_HandleSelectInterface: ... \n");
1502
1503 FdoExtension = FdoDevice->DeviceExtension;
1504
1505 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
1506 Executive,
1507 KernelMode,
1508 FALSE,
1509 NULL);
1510
1511 ConfigurationHandle = Urb->UrbSelectInterface.ConfigurationHandle;
1512
1513 Interface = &Urb->UrbSelectInterface.Interface;
1514
1515 Length = Interface->Length + sizeof(USBD_PIPE_INFORMATION);
1516 Urb->UrbHeader.Length = Length;
1517
1518 USBDStatus = USBPORT_InitInterfaceInfo(Interface, ConfigurationHandle);
1519
1520 if (USBDStatus)
1521 {
1522 Interface->InterfaceHandle = (USBD_INTERFACE_HANDLE)-1;
1523 return USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
1524 }
1525
1526 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
1527
1528 InterfaceHandle = USBPORT_GetInterfaceHandle(ConfigurationHandle,
1529 Interface->InterfaceNumber);
1530
1531 if (InterfaceHandle)
1532 {
1533 RemoveEntryList(&InterfaceHandle->InterfaceLink);
1534
1535 if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints)
1536 {
1537 PipeHandle = &InterfaceHandle->PipeHandle[0];
1538
1539 for (ix = 0;
1540 ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
1541 ix++)
1542 {
1543 USBPORT_ClosePipe(DeviceHandle, FdoDevice, PipeHandle);
1544 PipeHandle += 1;
1545 }
1546 }
1547 }
1548
1549 iHandle = 0;
1550
1551 USBDStatus = USBPORT_OpenInterface(Urb,
1552 DeviceHandle,
1553 FdoDevice,
1554 ConfigurationHandle,
1555 Interface,
1556 &iHandle,
1557 TRUE);
1558
1559 if (USBDStatus)
1560 {
1561 Interface->InterfaceHandle = (USBD_INTERFACE_HANDLE)-1;
1562 }
1563 else
1564 {
1565 if (InterfaceHandle)
1566 ExFreePoolWithTag(InterfaceHandle, USB_PORT_TAG);
1567
1568 Interface->InterfaceHandle = iHandle;
1569
1570 InsertTailList(&ConfigurationHandle->InterfaceHandleList,
1571 &iHandle->InterfaceLink);
1572 }
1573
1574 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1575 LOW_REALTIME_PRIORITY,
1576 1,
1577 FALSE);
1578
1579 return USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
1580 }
1581
1582 NTSTATUS
1583 NTAPI
USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice,IN OUT PUSBPORT_DEVICE_HANDLE DeviceHandle,IN ULONG Flags)1584 USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice,
1585 IN OUT PUSBPORT_DEVICE_HANDLE DeviceHandle,
1586 IN ULONG Flags)
1587 {
1588 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1589 PUSB2_TT_EXTENSION TtExtension;
1590 ULONG ix;
1591 KIRQL OldIrql;
1592
1593 DPRINT("USBPORT_RemoveDevice: DeviceHandle - %p, Flags - %x\n",
1594 DeviceHandle,
1595 Flags);
1596
1597 FdoExtension = FdoDevice->DeviceExtension;
1598
1599 if ((Flags & USBD_KEEP_DEVICE_DATA) ||
1600 (Flags & USBD_MARK_DEVICE_BUSY))
1601 {
1602 return STATUS_SUCCESS;
1603 }
1604
1605 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
1606 Executive,
1607 KernelMode,
1608 FALSE,
1609 NULL);
1610
1611 if (!USBPORT_ValidateDeviceHandle(FdoDevice, DeviceHandle))
1612 {
1613 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1614 LOW_REALTIME_PRIORITY,
1615 1,
1616 FALSE);
1617
1618 DPRINT1("USBPORT_RemoveDevice: Not valid device handle\n");
1619 return STATUS_DEVICE_NOT_CONNECTED;
1620 }
1621
1622 USBPORT_RemoveDeviceHandle(FdoDevice, DeviceHandle);
1623
1624 DeviceHandle->Flags |= DEVICE_HANDLE_FLAG_REMOVED;
1625
1626 USBPORT_AbortTransfers(FdoDevice, DeviceHandle);
1627
1628 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock - %x\n",
1629 DeviceHandle->DeviceHandleLock);
1630
1631 while (InterlockedDecrement(&DeviceHandle->DeviceHandleLock) >= 0)
1632 {
1633 InterlockedIncrement(&DeviceHandle->DeviceHandleLock);
1634 USBPORT_Wait(FdoDevice, 100);
1635 }
1636
1637 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock ok\n");
1638
1639 if (DeviceHandle->ConfigHandle)
1640 {
1641 USBPORT_CloseConfiguration(DeviceHandle, FdoDevice);
1642 }
1643
1644 USBPORT_ClosePipe(DeviceHandle, FdoDevice, &DeviceHandle->PipeHandle);
1645
1646 if (DeviceHandle->DeviceAddress)
1647 {
1648 USBPORT_FreeUsbAddress(FdoDevice, DeviceHandle->DeviceAddress);
1649 }
1650
1651 if (!IsListEmpty(&DeviceHandle->TtList))
1652 {
1653 DPRINT1("USBPORT_RemoveDevice: DeviceHandle->TtList not empty\n");
1654 }
1655
1656 while (!IsListEmpty(&DeviceHandle->TtList))
1657 {
1658 TtExtension = CONTAINING_RECORD(DeviceHandle->TtList.Flink,
1659 USB2_TT_EXTENSION,
1660 Link);
1661
1662 RemoveHeadList(&DeviceHandle->TtList);
1663
1664 DPRINT("USBPORT_RemoveDevice: TtExtension - %p\n", TtExtension);
1665
1666 KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql);
1667
1668 TtExtension->Flags |= USB2_TT_EXTENSION_FLAG_DELETED;
1669
1670 if (IsListEmpty(&TtExtension->EndpointList))
1671 {
1672 USBPORT_UpdateAllocatedBwTt(TtExtension);
1673
1674 for (ix = 0; ix < USB2_FRAMES; ix++)
1675 {
1676 FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth;
1677 }
1678
1679 DPRINT("USBPORT_RemoveDevice: ExFreePoolWithTag TtExtension - %p\n", TtExtension);
1680 ExFreePoolWithTag(TtExtension, USB_PORT_TAG);
1681 }
1682
1683 KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql);
1684 }
1685
1686 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1687 LOW_REALTIME_PRIORITY,
1688 1,
1689 FALSE);
1690
1691 if (!(DeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB))
1692 {
1693 ExFreePoolWithTag(DeviceHandle, USB_PORT_TAG);
1694 }
1695
1696 return STATUS_SUCCESS;
1697 }
1698
1699 NTSTATUS
1700 NTAPI
USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice,IN OUT PUSBPORT_DEVICE_HANDLE OldDeviceHandle,IN OUT PUSBPORT_DEVICE_HANDLE NewDeviceHandle)1701 USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice,
1702 IN OUT PUSBPORT_DEVICE_HANDLE OldDeviceHandle,
1703 IN OUT PUSBPORT_DEVICE_HANDLE NewDeviceHandle)
1704 {
1705 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1706 PLIST_ENTRY iHandleList;
1707 PUSBPORT_ENDPOINT Endpoint;
1708 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements = {0};
1709 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
1710 NTSTATUS Status = STATUS_SUCCESS;
1711 USBD_STATUS USBDStatus;
1712 KIRQL OldIrql;
1713 PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
1714 PUSBPORT_PIPE_HANDLE PipeHandle;
1715 PUSBPORT_REGISTRATION_PACKET Packet;
1716
1717 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle - %p, NewDeviceHandle - %p\n",
1718 OldDeviceHandle,
1719 NewDeviceHandle);
1720
1721 FdoExtension = FdoDevice->DeviceExtension;
1722
1723 KeWaitForSingleObject(&FdoExtension->DeviceSemaphore,
1724 Executive,
1725 KernelMode,
1726 FALSE,
1727 NULL);
1728
1729 if (!USBPORT_ValidateDeviceHandle(FdoDevice, OldDeviceHandle))
1730 {
1731 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1732 LOW_REALTIME_PRIORITY,
1733 1,
1734 FALSE);
1735
1736 #ifndef NDEBUG
1737 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle not valid\n");
1738 DbgBreakPoint();
1739 #endif
1740 return STATUS_DEVICE_NOT_CONNECTED;
1741 }
1742
1743 if (!USBPORT_ValidateDeviceHandle(FdoDevice, NewDeviceHandle))
1744 {
1745 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1746 LOW_REALTIME_PRIORITY,
1747 1,
1748 FALSE);
1749 #ifndef NDEBUG
1750 DPRINT("USBPORT_RestoreDevice: NewDeviceHandle not valid\n");
1751 DbgBreakPoint();
1752 #endif
1753 return STATUS_DEVICE_NOT_CONNECTED;
1754 }
1755
1756 USBPORT_RemoveDeviceHandle(FdoDevice, OldDeviceHandle);
1757 USBPORT_AbortTransfers(FdoDevice, OldDeviceHandle);
1758
1759 while (InterlockedDecrement(&OldDeviceHandle->DeviceHandleLock) >= 0)
1760 {
1761 InterlockedIncrement(&OldDeviceHandle->DeviceHandleLock);
1762 USBPORT_Wait(FdoDevice, 100);
1763 }
1764
1765 if (sizeof(USB_DEVICE_DESCRIPTOR) == RtlCompareMemory(&NewDeviceHandle->DeviceDescriptor,
1766 &OldDeviceHandle->DeviceDescriptor,
1767 sizeof(USB_DEVICE_DESCRIPTOR)))
1768 {
1769 NewDeviceHandle->ConfigHandle = OldDeviceHandle->ConfigHandle;
1770
1771 if (OldDeviceHandle->ConfigHandle)
1772 {
1773 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1774
1775 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1776 SetupPacket.bRequest = USB_REQUEST_SET_CONFIGURATION;
1777 SetupPacket.wValue.W = OldDeviceHandle->ConfigHandle->ConfigurationDescriptor->bConfigurationValue;
1778 SetupPacket.wIndex.W = 0;
1779 SetupPacket.wLength = 0;
1780
1781 USBPORT_SendSetupPacket(NewDeviceHandle,
1782 FdoDevice,
1783 &SetupPacket,
1784 NULL,
1785 0,
1786 NULL,
1787 &USBDStatus);
1788
1789 if (USBD_ERROR(USBDStatus))
1790 Status = USBPORT_USBDStatusToNtStatus(NULL, USBDStatus);
1791
1792 if (NT_SUCCESS(Status))
1793 {
1794 iHandleList = NewDeviceHandle->ConfigHandle->InterfaceHandleList.Flink;
1795
1796 while (iHandleList &&
1797 iHandleList != &NewDeviceHandle->ConfigHandle->InterfaceHandleList)
1798 {
1799 InterfaceHandle = CONTAINING_RECORD(iHandleList,
1800 USBPORT_INTERFACE_HANDLE,
1801 InterfaceLink);
1802
1803 if (InterfaceHandle->AlternateSetting)
1804 {
1805 RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1806
1807 SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1808 SetupPacket.bmRequestType.Type = BMREQUEST_STANDARD;
1809 SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
1810
1811 SetupPacket.bRequest = USB_REQUEST_SET_INTERFACE;
1812 SetupPacket.wValue.W = InterfaceHandle->InterfaceDescriptor.bAlternateSetting;
1813 SetupPacket.wIndex.W = InterfaceHandle->InterfaceDescriptor.bInterfaceNumber;
1814 SetupPacket.wLength = 0;
1815
1816 USBPORT_SendSetupPacket(NewDeviceHandle,
1817 FdoDevice,
1818 &SetupPacket,
1819 NULL,
1820 0,
1821 NULL,
1822 &USBDStatus);
1823 }
1824
1825 iHandleList = iHandleList->Flink;
1826 }
1827 }
1828 }
1829
1830 if (NewDeviceHandle->Flags & DEVICE_HANDLE_FLAG_USB2HUB)
1831 {
1832 DPRINT1("USBPORT_RestoreDevice: FIXME Transaction Translator\n");
1833 NewDeviceHandle->TtCount = OldDeviceHandle->TtCount;
1834
1835 #ifndef NDEBUG
1836 DbgBreakPoint();
1837 #endif
1838 }
1839
1840 while (!IsListEmpty(&OldDeviceHandle->PipeHandleList))
1841 {
1842 PipeHandle = CONTAINING_RECORD(OldDeviceHandle->PipeHandleList.Flink,
1843 USBPORT_PIPE_HANDLE,
1844 PipeLink);
1845
1846 DPRINT("USBPORT_RestoreDevice: PipeHandle - %p\n", PipeHandle);
1847
1848 USBPORT_RemovePipeHandle(OldDeviceHandle, PipeHandle);
1849
1850 if (PipeHandle != &OldDeviceHandle->PipeHandle)
1851 {
1852 USBPORT_AddPipeHandle(NewDeviceHandle, PipeHandle);
1853
1854 if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE))
1855 {
1856 Endpoint = PipeHandle->Endpoint;
1857 Endpoint->DeviceHandle = NewDeviceHandle;
1858 Endpoint->EndpointProperties.DeviceAddress = NewDeviceHandle->DeviceAddress;
1859
1860 Packet = &FdoExtension->MiniPortInterface->Packet;
1861
1862 if (!(Endpoint->Flags & ENDPOINT_FLAG_NUKE))
1863 {
1864 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock,
1865 &OldIrql);
1866
1867 Packet->ReopenEndpoint(FdoExtension->MiniPortExt,
1868 &Endpoint->EndpointProperties,
1869 Endpoint + 1);
1870
1871 Packet->SetEndpointDataToggle(FdoExtension->MiniPortExt,
1872 Endpoint + 1,
1873 0);
1874
1875 Packet->SetEndpointStatus(FdoExtension->MiniPortExt,
1876 Endpoint + 1,
1877 USBPORT_ENDPOINT_RUN);
1878
1879 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock,
1880 OldIrql);
1881 }
1882 else
1883 {
1884 MiniportCloseEndpoint(FdoDevice, Endpoint);
1885
1886 RtlZeroMemory(Endpoint + 1, Packet->MiniPortEndpointSize);
1887
1888 RtlZeroMemory((PVOID)Endpoint->EndpointProperties.BufferVA,
1889 Endpoint->EndpointProperties.BufferLength);
1890
1891 KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
1892
1893 Packet->QueryEndpointRequirements(FdoExtension->MiniPortExt,
1894 &Endpoint->EndpointProperties,
1895 &EndpointRequirements);
1896
1897 KeReleaseSpinLock(&FdoExtension->MiniportSpinLock,
1898 OldIrql);
1899
1900 MiniportOpenEndpoint(FdoDevice, Endpoint);
1901
1902 Endpoint->Flags &= ~(ENDPOINT_FLAG_NUKE |
1903 ENDPOINT_FLAG_ABORTING);
1904
1905 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
1906 &Endpoint->EndpointOldIrql);
1907
1908 if (Endpoint->StateLast == USBPORT_ENDPOINT_ACTIVE)
1909 {
1910 KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
1911
1912 Packet->SetEndpointState(FdoExtension->MiniPortExt,
1913 Endpoint + 1,
1914 USBPORT_ENDPOINT_ACTIVE);
1915
1916 KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
1917 }
1918
1919 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
1920 Endpoint->EndpointOldIrql);
1921 }
1922 }
1923 }
1924 }
1925
1926 USBPORT_AddPipeHandle(OldDeviceHandle, &OldDeviceHandle->PipeHandle);
1927 }
1928 else
1929 {
1930 #ifndef NDEBUG
1931 DPRINT("USBPORT_RestoreDevice: New DeviceDescriptor != Old DeviceDescriptor\n");
1932 DbgBreakPoint();
1933 #endif
1934 Status = STATUS_UNSUCCESSFUL;
1935 }
1936
1937 USBPORT_ClosePipe(OldDeviceHandle, FdoDevice, &OldDeviceHandle->PipeHandle);
1938
1939 if (OldDeviceHandle->DeviceAddress != 0)
1940 USBPORT_FreeUsbAddress(FdoDevice, OldDeviceHandle->DeviceAddress);
1941
1942 KeReleaseSemaphore(&FdoExtension->DeviceSemaphore,
1943 LOW_REALTIME_PRIORITY,
1944 1,
1945 FALSE);
1946
1947 ExFreePoolWithTag(OldDeviceHandle, USB_PORT_TAG);
1948
1949 return Status;
1950 }
1951
1952 NTSTATUS
1953 NTAPI
USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,IN ULONG TtNumber)1954 USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice,
1955 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,
1956 IN ULONG TtNumber)
1957 {
1958 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1959 PUSB2_TT_EXTENSION TtExtension;
1960 ULONG ix;
1961
1962 DPRINT("USBPORT_InitializeTT: HubDeviceHandle - %p, TtNumber - %X\n",
1963 HubDeviceHandle,
1964 TtNumber);
1965
1966 FdoExtension = FdoDevice->DeviceExtension;
1967
1968 TtExtension = ExAllocatePoolWithTag(NonPagedPool,
1969 sizeof(USB2_TT_EXTENSION),
1970 USB_PORT_TAG);
1971
1972 if (!TtExtension)
1973 {
1974 DPRINT1("USBPORT_InitializeTT: ExAllocatePoolWithTag return NULL\n");
1975 return STATUS_INSUFFICIENT_RESOURCES;
1976 }
1977
1978 DPRINT("USBPORT_InitializeTT: TtExtension - %p\n", TtExtension);
1979
1980 RtlZeroMemory(TtExtension, sizeof(USB2_TT_EXTENSION));
1981
1982 TtExtension->DeviceAddress = HubDeviceHandle->DeviceAddress;
1983 TtExtension->TtNumber = TtNumber;
1984 TtExtension->RootHubPdo = FdoExtension->RootHubPdo;
1985 TtExtension->BusBandwidth = TOTAL_USB11_BUS_BANDWIDTH;
1986
1987 InitializeListHead(&TtExtension->EndpointList);
1988
1989 /* 90% maximum allowed for periodic endpoints */
1990 for (ix = 0; ix < USB2_FRAMES; ix++)
1991 {
1992 TtExtension->Bandwidth[ix] = TtExtension->BusBandwidth -
1993 TtExtension->BusBandwidth / 10;
1994 }
1995
1996 USBPORT_UpdateAllocatedBwTt(TtExtension);
1997
1998 for (ix = 0; ix < USB2_FRAMES; ix++)
1999 {
2000 FdoExtension->Bandwidth[ix] -= TtExtension->MaxBandwidth;
2001 }
2002
2003 USB2_InitTT(FdoExtension->Usb2Extension, &TtExtension->Tt);
2004
2005 InsertTailList(&HubDeviceHandle->TtList, &TtExtension->Link);
2006
2007 return STATUS_SUCCESS;
2008 }
2009
2010 NTSTATUS
2011 NTAPI
USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,IN ULONG TtCount)2012 USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice,
2013 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle,
2014 IN ULONG TtCount)
2015 {
2016 NTSTATUS Status;
2017 ULONG ix;
2018
2019 DPRINT("USBPORT_Initialize20Hub: TtCount - %X\n", TtCount);
2020
2021 if (!HubDeviceHandle)
2022 {
2023 return STATUS_INVALID_PARAMETER;
2024 }
2025
2026 if (HubDeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB)
2027 {
2028 return STATUS_SUCCESS;
2029 }
2030
2031 if (TtCount == 0)
2032 {
2033 HubDeviceHandle->TtCount = 0;
2034 return STATUS_SUCCESS;
2035 }
2036
2037 for (ix = 0; ix < TtCount; ++ix)
2038 {
2039 Status = USBPORT_InitializeTT(FdoDevice, HubDeviceHandle, ix + 1);
2040
2041 if (!NT_SUCCESS(Status))
2042 break;
2043 }
2044
2045 HubDeviceHandle->TtCount = TtCount;
2046
2047 return Status;
2048 }
2049