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