ReactOS 0.4.17-dev-1281-g065abb3
portxfer.cpp File Reference
#include "usbhub3.h"
#include <debug.h>
Include dependency graph for portxfer.cpp:

Go to the source code of this file.

Classes

struct  PortChangeOrder
 

Macros

#define NDEBUG
 
#define PORT_OVER_CURRENT_LIMIT   5
 
#define PORT_OVER_CURRENT_WINDOW   (3LL * 1000 * 1000 * 10)
 

Functions

static VOID NTAPI PortTrackPendingOperation (_In_ HubPort *Port, _In_ USBD_STATUS UrbStatus)
 
static VOID NTAPI PortCacheSetFeature (_In_ HubPort *Port)
 
static VOID NTAPI PortControlComplete (_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, _In_ WDFCONTEXT Context)
 
static VOID NTAPI PortSendControl (_In_ HubPort *Port, _In_ UCHAR RequestType, _In_ UCHAR Request, _In_ USHORT Value, _In_ USHORT Index, _In_reads_bytes_opt_(Length) PVOID Buffer, _In_ USHORT Length)
 
static USHORT NTAPI PortIndex (_In_ HubPort *Port, _In_ UCHAR High)
 
static VOID NTAPI PortDropInitialConnectReference (_In_ HubPort *Port)
 
static PortEvent NTAPI PortNextChange20 (_In_ HubPort *Port, _In_ USHORT Status, _In_ USHORT Previous, _In_ USHORT Change)
 
static PortEvent NTAPI PortNextChange30 (_In_ HubPort *Port, _In_ USHORT Status, _In_ USHORT Previous, _In_ USHORT Change)
 
static VOID NTAPI PortReportChange (_In_ HubPort *Port, _In_ PortEvent Result, _In_ USHORT Status, _In_ USHORT Previous, _In_ USHORT Change)
 

Variables

static EVT_WDF_REQUEST_COMPLETION_ROUTINE PortControlComplete
 
static const PortChangeOrder PortChanges []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file portxfer.cpp.

◆ PORT_OVER_CURRENT_LIMIT

#define PORT_OVER_CURRENT_LIMIT   5

Definition at line 14 of file portxfer.cpp.

◆ PORT_OVER_CURRENT_WINDOW

#define PORT_OVER_CURRENT_WINDOW   (3LL * 1000 * 1000 * 10)

Definition at line 15 of file portxfer.cpp.

Function Documentation

◆ PortCacheSetFeature()

static VOID NTAPI PortCacheSetFeature ( _In_ HubPort *  Port)
static

Definition at line 52 of file portxfer.cpp.

54{
55 const UCHAR* Setup = Port->m_Control.Urb.SetupPacket;
56 USHORT Feature = Setup[2] | (Setup[3] << 8);
57 USHORT LinkState = Setup[5];
58 USHORT* Current = &Port->m_Current.StatusChange.PortStatus.AsUshort16;
59
61 {
62 Port->m_PreviousStatus |= PS_SUSPENDED;
64 }
65 else if (Feature == PORT_F_LINK_STATE && (LinkState == LINK_U3 || LinkState == LINK_SS_DISABLED))
66 {
67 Port->m_PreviousStatus = (Port->m_PreviousStatus & ~PS_LINK_MASK) | (LinkState << PS_LINK_SHIFT);
68 *Current = (*Current & ~PS_LINK_MASK) | (LinkState << PS_LINK_SHIFT);
69 }
70}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE ACPI_ADR_SPACE_HANDLER ACPI_ADR_SPACE_SETUP Setup
Definition: acpixf.h:834
_In_ ULONG const _In_ FEATURE_NUMBER const Feature
Definition: cdrom.h:1077
CPPORT Port[4]
Definition: headless.c:38
HubUxdSettings Current
#define PS_SUSPENDED
Definition: hubreq.h:128
#define PORT_F_SUSPEND
Definition: hubreq.h:97
#define PS_LINK_SHIFT
Definition: hubreq.h:131
#define LINK_SS_DISABLED
Definition: hubreq.h:117
#define LINK_U3
Definition: hubreq.h:116
#define PORT_F_LINK_STATE
Definition: hubreq.h:99
unsigned short USHORT
Definition: pedump.c:61
unsigned char UCHAR
Definition: typedefs.h:53

Referenced by PortControlComplete().

◆ PortControlComplete()

static VOID NTAPI PortControlComplete ( _In_ WDFREQUEST  Request,
_In_ WDFIOTARGET  Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS  Params,
_In_ WDFCONTEXT  Context 
)
static

Definition at line 75 of file portxfer.cpp.

80{
82 NTSTATUS Status = Params->IoStatus.Status;
83 UCHAR RequestCode = Port->m_Control.Urb.SetupPacket[1];
84
87
88 if (!NT_SUCCESS(Status))
89 {
90 DPRINT1("Hub %p port %u control request 0x%x failed 0x%lx, URB status 0x%lx\n",
91 Port->m_Hub, Port->Number(), RequestCode, Status, Port->m_Control.Urb.Hdr.Status);
92 Port->m_Hub->m_FailureMessageId = HUB_MSG_CONTROL_TRANSFER_FAILED;
93 }
94 else if (RequestCode == HUB_REQUEST_GET_STATUS)
95 {
96 DPRINT("Hub %p port %u status 0x%x change 0x%x\n",
97 Port->m_Hub, Port->Number(),
98 Port->m_Current.StatusChange.PortStatus.AsUshort16, Port->m_Current.StatusChange.PortChange.AsUshort16);
99 PortTrackPendingOperation(Port, Port->m_Control.Urb.Hdr.Status);
100 }
101 else if (RequestCode == HUB_REQUEST_SET_FEATURE)
102 {
104 }
105
106 Port->m_Control.Reuse();
108}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
#define HUB_MSG_CONTROL_TRANSFER_FAILED
Definition: hubreq.h:151
#define HUB_REQUEST_GET_STATUS
Definition: hubreq.h:85
#define HUB_REQUEST_SET_FEATURE
Definition: hubreq.h:87
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
static VOID NTAPI PortTrackPendingOperation(_In_ HubPort *Port, _In_ USBD_STATUS UrbStatus)
Definition: portxfer.cpp:26
static VOID NTAPI PortCacheSetFeature(_In_ HubPort *Port)
Definition: portxfer.cpp:52
#define DPRINT
Definition: sndvol32.h:73
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

◆ PortDropInitialConnectReference()

static VOID NTAPI PortDropInitialConnectReference ( _In_ HubPort *  Port)
static

Definition at line 337 of file portxfer.cpp.

339{
340 if (!Port->m_InitialConnectPowerReference)
341 return;
342
343 WdfDeviceResumeIdle(Port->m_Hub->m_Device);
344 Port->m_InitialConnectPowerReference = FALSE;
345}
#define FALSE
Definition: types.h:117
#define WdfDeviceResumeIdle(Device)
Definition: wdfdevice.h:1983

Referenced by PortMachine::NextChange().

◆ PortIndex()

◆ PortNextChange20()

static PortEvent NTAPI PortNextChange20 ( _In_ HubPort *  Port,
_In_ USHORT  Status,
_In_ USHORT  Previous,
_In_ USHORT  Change 
)
static

Definition at line 351 of file portxfer.cpp.

356{
358
360 {
361 Port->m_ConnectionStatus = DeviceCausedOvercurrent;
363 }
364
366 {
369
370 Port->m_ConnectionStatus = DeviceCausedOvercurrent;
372 }
373
374 if (!(Status & PS_POWER_20))
376
377 if ((Change & PC_CONNECT) || ((Status ^ Previous) & PS_CONNECTED))
379
380 if ((Status & PS_RESET) || !(Status & PS_CONNECTED))
382
383 if (Change & PC_RESET)
385
386 if (Change & PC_SUSPEND)
388
390}
unsigned char BOOLEAN
Definition: actypes.h:127
USHORT Change
Definition: bootdev.cpp:133
_In_ ULONG const Usable
Definition: cdrom.h:1084
Previous
#define PC_RESET
Definition: hubreq.h:140
#define PC_OVER_CURRENT
Definition: hubreq.h:139
#define PC_SUSPEND
Definition: hubreq.h:138
#define PC_CONNECT
Definition: hubreq.h:136
#define PS_OVER_CURRENT
Definition: hubreq.h:129
#define PS_CONNECTED
Definition: hubreq.h:126
#define PS_RESET
Definition: hubreq.h:130
#define PS_POWER_20
Definition: hubreq.h:133
#define PS_ENABLED
Definition: hubreq.h:127
@ ChangeOverCurrent
@ DeviceCausedOvercurrent
Definition: usbioctl.h:282

Referenced by PortMachine::NextChange().

◆ PortNextChange30()

static PortEvent NTAPI PortNextChange30 ( _In_ HubPort *  Port,
_In_ USHORT  Status,
_In_ USHORT  Previous,
_In_ USHORT  Change 
)
static

Definition at line 395 of file portxfer.cpp.

400{
401 HubFdo* Hub = Port->m_Hub;
403 USHORT PreviousLink = HubLinkState(Previous);
404 BOOLEAN Connected = (Status & PS_CONNECTED) != 0;
405 BOOLEAN ConnectChanged = (Change & PC_CONNECT) || ((Status ^ Previous) & PS_CONNECTED);
406
408 {
409 Port->m_ConnectionStatus = DeviceCausedOvercurrent;
411 }
412
414 {
417
418 Port->m_ConnectionStatus = DeviceCausedOvercurrent;
420 }
421
422 if (!(Status & PS_POWER_30))
424
425 /* Caught in the middle of a reset */
426 if (Status & PS_RESET)
427 {
430 if (Connected)
432 return ConnectChanged ? PortEvent::ChangeConnect : PortEvent::ChangeNone;
433 }
434
435 /* A disconnect can pass through Rx.Detect, or park in Polling on re-driver systems */
436 if (!Connected && (Previous & PS_POWER_30))
437 {
438 if (Link == LINK_RX_DETECT && PreviousLink != LINK_RX_DETECT)
440 if (Link == LINK_POLLING && PreviousLink != LINK_POLLING)
442 }
443
444 if (Link == LINK_LOOPBACK)
446
447 if (Link == LINK_SS_DISABLED && PreviousLink != LINK_SS_DISABLED)
449
450 if (Link == LINK_COMPLIANCE)
452
453 /* The same SS.Inactive error is reported once until a reset */
454 if (Link == LINK_SS_INACTIVE)
455 {
458 if (Port->m_LastChange == PortEvent::ChangeLinkError)
459 {
460 DPRINT1("Hub %p port %u still in SS.Inactive, already reported\n", Hub, Port->Number());
462 }
466 }
467
468 if (ConnectChanged)
470
471 if (!Connected)
472 {
473 if (Status & PS_ENABLED)
475 if (Link <= LINK_U3)
478 }
479
480 if (Link == LINK_RX_DETECT)
482
483 if (!(Status & PS_ENABLED))
485
486 if (Link > LINK_U3 && Link != LINK_RECOVERY)
488
489 if (Change & PC_RESET)
491
492 if (PreviousLink == LINK_U3 && Link != LINK_U3)
494
496}
HubFdo * Hub
Definition: bootdev.cpp:261
Definition: fdo.h:132
BOOLEAN HasFlag(_In_ HubFlag Flag) const
Definition: fdo.h:153
#define LINK_LOOPBACK
Definition: hubreq.h:123
#define LINK_RX_DETECT
Definition: hubreq.h:118
#define LINK_RECOVERY
Definition: hubreq.h:121
#define LINK_SS_INACTIVE
Definition: hubreq.h:119
#define PC_CONFIG_ERROR
Definition: hubreq.h:143
#define LINK_POLLING
Definition: hubreq.h:120
#define PS_POWER_30
Definition: hubreq.h:134
FORCEINLINE USHORT NTAPI HubLinkState(_In_ USHORT Status)
Definition: hubreq.h:159
#define LINK_COMPLIANCE
Definition: hubreq.h:122
@ ChangeNeedsHubReset
@ ToleratesU0WhileDetached
@ IgnoreEnabledInSsInactive
@ DiscardEnableDuringReset

Referenced by PortMachine::NextChange().

◆ PortReportChange()

static VOID NTAPI PortReportChange ( _In_ HubPort *  Port,
_In_ PortEvent  Result,
_In_ USHORT  Status,
_In_ USHORT  Previous,
_In_ USHORT  Change 
)
static

Definition at line 502 of file portxfer.cpp.

508{
509 const char* What;
510
511 switch (Result)
512 {
514 What = "over current";
515 break;
516
518 /* An empty 2.0 port with no change also answers ChangeError */
519 if (!(Status & PS_CONNECTED) && Change == 0)
520 {
521 DPRINT("Hub %p port %u empty, no change\n", Port->m_Hub, Port->Number());
522 return;
523 }
524
525 What = "invalid status";
526 break;
527
529 What = "invalid status, hub reset";
530 break;
531
533 What = "link error, port reset";
534 break;
535
537 if (Status & PS_CONNECTED)
538 {
539 DPRINT("Hub %p port %u connect change\n", Port->m_Hub, Port->Number());
540 return;
541 }
542
543 What = "disconnect";
544 break;
545
546 default:
547 return;
548 }
549
550 DPRINT1("Hub %p port %u %s: status 0x%x previous 0x%x change 0x%x\n",
551 Port->m_Hub, Port->Number(), What, Status, Previous, Change);
552}
_In_ DsmEvent _In_ PCSTR What
Definition: childpdo.cpp:261
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by PortMachine::LostChange(), and PortMachine::NextChange().

◆ PortSendControl()

static VOID NTAPI PortSendControl ( _In_ HubPort *  Port,
_In_ UCHAR  RequestType,
_In_ UCHAR  Request,
_In_ USHORT  Value,
_In_ USHORT  Index,
_In_reads_bytes_opt_(Length) PVOID  Buffer,
_In_ USHORT  Length 
)
static

Definition at line 113 of file portxfer.cpp.

121{
122 HubFdo* Hub = Port->m_Hub;
124
125 Port->m_Control.SetSetup(RequestType, Request, Value, Index, Length);
126 DPRINT("Hub %p port %u request 0x%x value %u index 0x%x\n", Hub, Port->Number(), Request, Value, Index);
127
128 Status = Port->m_Control.Send(Hub->m_RootHubTarget,
129 Hub->UsbDevice(),
131 Port,
132 Buffer,
133 Length,
134 FALSE,
136 if (!NT_SUCCESS(Status))
138}
Definition: bufpool.h:45
WDFIOTARGET m_RootHubTarget
Definition: fdo.h:368
UCXUSBDEVICE UsbDevice() const
Definition: fdo.h:180
BOOLEAN NeedsForwardProgress() const
Definition: fdo.h:208
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static EVT_WDF_REQUEST_COMPLETION_ROUTINE PortControlComplete
Definition: portxfer.cpp:17
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFQUEUE _In_ _Strict_type_match_ WDF_REQUEST_TYPE RequestType
Definition: wdfdevice.h:4239
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by PortMachine::SendAckChange(), PortMachine::SendDisable(), PortMachine::SendGetStatus(), PortMachine::SendLinkDisable(), PortMachine::SendLinkRxDetect(), PortMachine::SendPortPower(), PortMachine::SendRemoteWake(), PortMachine::SendReset(), PortMachine::SendResume(), PortMachine::SendSuspend(), PortMachine::SendU1Timeout(), PortMachine::SendU2Timeout(), and PortMachine::SendWarmReset().

◆ PortTrackPendingOperation()

static VOID NTAPI PortTrackPendingOperation ( _In_ HubPort *  Port,
_In_ USBD_STATUS  UrbStatus 
)
static

Definition at line 26 of file portxfer.cpp.

29{
30 HubFdo* Hub = Port->m_Hub;
31
33 {
36 {
37 DPRINT("Hub %p port %u resume pending, hub kept awake\n", Hub, Port->Number());
39 }
40 }
42 {
45 }
46}
WDFDEVICE m_Device
Definition: fdo.h:349
@ PendingHubPowerReference
#define USBD_STATUS_PORT_OPERATION_PENDING
Definition: usb.h:178
#define WdfDeviceStopIdle(Device, WaitForD0)
Definition: wdfdevice.h:1977

Referenced by PortControlComplete().

Variable Documentation

◆ PortChanges

const PortChangeOrder PortChanges[]
static
Initial value:
=
{
}
#define PORT_C_LINK_STATE
Definition: hubreq.h:108
#define PC_BH_RESET
Definition: hubreq.h:141
#define PC_LINK_STATE
Definition: hubreq.h:142
#define PORT_C_CONNECTION
Definition: hubreq.h:101
#define PORT_C_RESET
Definition: hubreq.h:105
#define PC_ENABLE
Definition: hubreq.h:137
#define PORT_C_OVER_CURRENT
Definition: hubreq.h:104
#define PORT_C_BH_RESET
Definition: hubreq.h:112
#define PORT_C_ENABLE
Definition: hubreq.h:102
#define PORT_C_SUSPEND
Definition: hubreq.h:103
#define PORT_C_CONFIG_ERROR
Definition: hubreq.h:109

Definition at line 286 of file portxfer.cpp.

Referenced by PortMachine::PendingChange().

◆ PortControlComplete

EVT_WDF_REQUEST_COMPLETION_ROUTINE PortControlComplete
static

Definition at line 17 of file portxfer.cpp.

Referenced by PortSendControl().