@@ -1674,15 +1674,276 @@ UsbSerCleanup(IN PDEVICE_OBJECT DeviceObject,
16741674 return STATUS_SUCCESS ;
16751675}
16761676
1677+ VOID
1678+ NTAPI
1679+ UsbSerPoRequestCompletion (IN PDEVICE_OBJECT DeviceObject ,
1680+ IN UCHAR MinorFunction ,
1681+ IN POWER_STATE PowerState ,
1682+ IN PVOID Context ,
1683+ IN PIO_STATUS_BLOCK IoStatus )
1684+ {
1685+ PDEVICE_OBJECT PhysicalDevice = Context ;
1686+ PUSBSER_DEVICE_EXTENSION Extension ;
1687+ PIRP Irp ;
1688+
1689+ DPRINT1 ("UsbSerPoRequestCompletion: %p, %X\n" , DeviceObject , MinorFunction );
1690+
1691+ Extension = PhysicalDevice -> DeviceExtension ;
1692+ Irp = Extension -> SetPwrIrp ;
1693+
1694+ IoCopyCurrentIrpStackLocationToNext (Irp );
1695+ PoStartNextPowerIrp (Irp );
1696+ PoCallDriver (Extension -> LowerDevice , Irp );
1697+
1698+ Extension -> SetPwrIrp = NULL ;
1699+ }
1700+
1701+ VOID
1702+ NTAPI
1703+ UsbSerSendWaitWake (IN PUSBSER_DEVICE_EXTENSION Extension )
1704+ {
1705+ UNIMPLEMENTED_DBGBREAK ();
1706+ }
1707+
1708+ BOOLEAN
1709+ NTAPI
1710+ UsbSerSetDevicePowerState (IN PDEVICE_OBJECT DeviceObject ,
1711+ IN POWER_STATE State )
1712+ {
1713+ PUSBSER_DEVICE_EXTENSION Extension ;
1714+ KIRQL Irql ;
1715+ BOOLEAN Result ;
1716+
1717+ DPRINT1 ("UsbSerSetDevicePowerState: %p\n" , DeviceObject );
1718+
1719+ Extension = DeviceObject -> DeviceExtension ;
1720+
1721+ if (State .DeviceState == PowerDeviceD0 )
1722+ {
1723+ DPRINT1 ("PowerDeviceD0\n" );
1724+ Result = TRUE;
1725+ }
1726+ else if (State .DeviceState == PowerDeviceD1 )
1727+ {
1728+ DPRINT1 ("PowerDeviceD1\n" );
1729+
1730+ KeAcquireSpinLock (& Extension -> SpinLock , & Irql );
1731+ Extension -> DevicePowerState = State .DeviceState ;
1732+ KeReleaseSpinLock (& Extension -> SpinLock , Irql );
1733+
1734+ UsbSerAbortPipes (DeviceObject );
1735+
1736+ if (Extension -> IsWaitWake && State .DeviceState <= Extension -> DeviceWake )
1737+ UsbSerSendWaitWake (Extension );
1738+
1739+ Result = FALSE;
1740+ }
1741+ else if (State .DeviceState == PowerDeviceD2 )
1742+ {
1743+ DPRINT1 ("PowerDeviceD2\n" );
1744+
1745+ KeAcquireSpinLock (& Extension -> SpinLock , & Irql );
1746+ Extension -> DevicePowerState = State .DeviceState ;
1747+ KeReleaseSpinLock (& Extension -> SpinLock , Irql );
1748+
1749+ UsbSerAbortPipes (DeviceObject );
1750+
1751+ if (Extension -> IsWaitWake && State .DeviceState <= Extension -> DeviceWake )
1752+ UsbSerSendWaitWake (Extension );
1753+
1754+ Result = FALSE;
1755+ }
1756+ else if (State .DeviceState == PowerDeviceD3 )
1757+ {
1758+ DPRINT1 ("PowerDeviceD3\n" );
1759+
1760+ KeAcquireSpinLock (& Extension -> SpinLock , & Irql );
1761+ Extension -> DevicePowerState = State .DeviceState ;
1762+ KeReleaseSpinLock (& Extension -> SpinLock , Irql );
1763+
1764+ UsbSerAbortPipes (DeviceObject );
1765+
1766+ Result = FALSE;
1767+ }
1768+ else
1769+ {
1770+ DPRINT1 ("UsbSerSetDevicePowerState: DeviceState %X\n" , State .DeviceState );
1771+ Result = FALSE;
1772+ }
1773+
1774+ PoSetPowerState (DeviceObject , DevicePowerState , State );
1775+
1776+ return Result ;
1777+ }
1778+
1779+ NTSTATUS
1780+ NTAPI
1781+ UsbSerWaitWakeIrpCompletionRoutine (IN PDEVICE_OBJECT DeviceObject ,
1782+ IN PIRP Irp ,
1783+ IN PVOID Context )
1784+ {
1785+ UNIMPLEMENTED_DBGBREAK ();
1786+ return STATUS_MORE_PROCESSING_REQUIRED ;
1787+ }
1788+
1789+ NTSTATUS
1790+ NTAPI
1791+ UsbSerPowerIrpComplete (IN PDEVICE_OBJECT DeviceObject ,
1792+ IN PIRP Irp ,
1793+ IN PVOID Context )
1794+ {
1795+ UNIMPLEMENTED_DBGBREAK ();
1796+ return STATUS_MORE_PROCESSING_REQUIRED ;
1797+ }
1798+
16771799NTSTATUS
16781800NTAPI
16791801UsbSerProcessPowerIrp (IN PDEVICE_OBJECT DeviceObject ,
16801802 IN PIRP Irp )
16811803{
1682- DPRINT ("UsbSerProcessPowerIrp: DeviceObject %p, Irp %p\n" , DeviceObject , Irp );
1683- PAGED_CODE ();
1684- UNIMPLEMENTED ;
1685- return STATUS_NOT_IMPLEMENTED ;
1804+ PUSBSER_DEVICE_EXTENSION Extension ;
1805+ PIO_STACK_LOCATION IoStack ;
1806+ SYSTEM_POWER_STATE SystemState ;
1807+ POWER_STATE DesiredDevicePowerState ;
1808+ ULONG ix ;
1809+ BOOLEAN Result ;
1810+ NTSTATUS Status = STATUS_SUCCESS ;
1811+
1812+ DPRINT1 ("UsbSerProcessPowerIrp: %p, %p\n" , DeviceObject , Irp );
1813+
1814+ Extension = DeviceObject -> DeviceExtension ;
1815+ IoStack = IoGetCurrentIrpStackLocation (Irp );
1816+
1817+ if (IoStack -> MinorFunction == IRP_MN_WAIT_WAKE )
1818+ {
1819+ Extension -> MinDeviceState = Extension -> DeviceWake ;
1820+
1821+ DPRINT1 ("UsbSerProcessPowerIrp: IRP_MN_WAIT_WAKE (%X, %X)\n" , Extension -> DevicePowerState , Extension -> DeviceWake );
1822+
1823+ if (Extension -> DevicePowerState != PowerDeviceD0 && Extension -> DeviceWake <= Extension -> DevicePowerState )
1824+ {
1825+ IoCopyCurrentIrpStackLocationToNext (Irp );
1826+ IoSetCompletionRoutine (Irp , UsbSerWaitWakeIrpCompletionRoutine , DeviceObject , TRUE, TRUE, TRUE);
1827+
1828+ DPRINT1 ("UsbSerProcessPowerIrp: Send down wait wake\n" );
1829+
1830+ PoStartNextPowerIrp (Irp );
1831+ PoCallDriver (Extension -> LowerDevice , Irp );
1832+ Status = STATUS_PENDING ;
1833+ }
1834+ else
1835+ {
1836+ Irp -> IoStatus .Status = STATUS_INVALID_DEVICE_STATE ;
1837+ PoStartNextPowerIrp (Irp );
1838+ IoCompleteRequest (Irp , 0 );
1839+ Status = STATUS_INVALID_DEVICE_STATE ;
1840+ }
1841+ }
1842+ else if (IoStack -> MinorFunction == IRP_MN_POWER_SEQUENCE )
1843+ {
1844+ DPRINT1 ("UsbSerProcessPowerIrp: IRP_MN_POWER_SEQUENCE\n" );
1845+
1846+ IoCopyCurrentIrpStackLocationToNext (Irp );
1847+ PoStartNextPowerIrp (Irp );
1848+ Status = PoCallDriver (Extension -> LowerDevice , Irp );
1849+ }
1850+ else if (IoStack -> MinorFunction == IRP_MN_SET_POWER )
1851+ {
1852+ DPRINT1 ("UsbSerProcessPowerIrp: IRP_MN_SET_POWER\n" );
1853+
1854+ if (IoStack -> Parameters .Power .Type == SystemPowerState )
1855+ {
1856+ DPRINT1 ("UsbSerProcessPowerIrp: SystemPowerState\n" );
1857+
1858+ SystemState = IoStack -> Parameters .Power .State .SystemState ;
1859+ DPRINT1 ("UsbSerProcessPowerIrp: SystemState %X\n" , SystemState );
1860+
1861+ for (ix = 0 ; ix < 8 ; ix ++ )
1862+ {
1863+ DPRINT1 ("UsbSerProcessPowerIrp: DeviceState[%X] %X\n" , ix , Extension -> Capabilities .DeviceState [ix ]);
1864+ }
1865+
1866+ DPRINT1 ("UsbSerProcessPowerIrp: DeviceWake %X SystemWake %X\n" ,
1867+ Extension -> Capabilities .DeviceWake , Extension -> Capabilities .SystemWake );
1868+
1869+ if (SystemState == PowerSystemWorking )
1870+ {
1871+ DPRINT1 ("UsbSerProcessPowerIrp: Setting to D0\n" );
1872+ DesiredDevicePowerState .DeviceState = PowerDeviceD0 ;
1873+ }
1874+ else if (Extension -> IsWaitWake )
1875+ {
1876+ DPRINT1 ("UsbSerProcessPowerIrp: We want to send a wait wake Irp\n" );
1877+ DesiredDevicePowerState .DeviceState = Extension -> Capabilities .DeviceState [SystemState ];
1878+ }
1879+ else
1880+ {
1881+ DPRINT1 ("UsbSerProcessPowerIrp: No wait wake Irp to send\n" );
1882+ DesiredDevicePowerState .DeviceState = PowerDeviceD3 ;
1883+ }
1884+
1885+ DPRINT1 ("UsbSerProcessPowerIrp: DesiredDevicePowerState %X\n" , DesiredDevicePowerState .SystemState );
1886+
1887+ if (DesiredDevicePowerState .DeviceState != Extension -> DevicePowerState )
1888+ {
1889+ Extension -> SetPwrIrp = Irp ;
1890+ Status = PoRequestPowerIrp (Extension -> PhysicalDevice ,
1891+ IRP_MN_SET_POWER ,
1892+ DesiredDevicePowerState ,
1893+ UsbSerPoRequestCompletion ,
1894+ DeviceObject ,
1895+ NULL );
1896+ }
1897+ else
1898+ {
1899+ IoCopyCurrentIrpStackLocationToNext (Irp );
1900+ PoStartNextPowerIrp (Irp );
1901+ Status = PoCallDriver (Extension -> LowerDevice , Irp );
1902+ }
1903+ }
1904+ else if (IoStack -> Parameters .Power .Type == DevicePowerState )
1905+ {
1906+ DPRINT1 ("UsbSerProcessPowerIrp: DevicePowerState\n" );
1907+
1908+ Result = UsbSerSetDevicePowerState (DeviceObject , IoStack -> Parameters .Power .State );
1909+
1910+ IoCopyCurrentIrpStackLocationToNext (Irp );
1911+
1912+ if (Result )
1913+ IoSetCompletionRoutine (Irp , UsbSerPowerIrpComplete , DeviceObject , TRUE, TRUE, TRUE);
1914+
1915+ PoStartNextPowerIrp (Irp );
1916+ Status = PoCallDriver (Extension -> LowerDevice , Irp );
1917+ }
1918+ }
1919+ else if (IoStack -> MinorFunction == IRP_MN_QUERY_POWER )
1920+ {
1921+ DPRINT1 ("UsbSerProcessPowerIrp: IRP_MN_QUERY_POWER\n" );
1922+
1923+ if (Extension -> IsWaitWake &&
1924+ IoStack -> Parameters .Power .Type == SystemPowerState &&
1925+ Extension -> Capabilities .DeviceState [IoStack -> Parameters .Power .State .DeviceState ] > Extension -> DeviceWake )
1926+ {
1927+ Irp -> IoStatus .Status = STATUS_INVALID_DEVICE_STATE ;
1928+ Status = STATUS_INVALID_DEVICE_STATE ;
1929+ PoStartNextPowerIrp (Irp );
1930+ IoCompleteRequest (Irp , 0 );
1931+ }
1932+ else
1933+ {
1934+ IoCopyCurrentIrpStackLocationToNext (Irp );
1935+ PoStartNextPowerIrp (Irp );
1936+ Status = PoCallDriver (Extension -> LowerDevice , Irp );
1937+ }
1938+ }
1939+ else
1940+ {
1941+ IoCopyCurrentIrpStackLocationToNext (Irp );
1942+ PoStartNextPowerIrp (Irp );
1943+ Status = PoCallDriver (Extension -> LowerDevice , Irp );
1944+ }
1945+
1946+ return Status ;
16861947}
16871948
16881949NTSTATUS
@@ -1747,6 +2008,68 @@ UsbSerUnload(IN PDRIVER_OBJECT DriverObject)
17472008 PAGED_CODE ();
17482009}
17492010
2011+ NTSTATUS
2012+ NTAPI
2013+ UsbSerIrpCompletionRoutine (IN PDEVICE_OBJECT DeviceObject ,
2014+ IN PIRP Irp ,
2015+ IN PVOID Context )
2016+ {
2017+ PRKEVENT Event = Context ;
2018+
2019+ DPRINT ("UsbSerIrpCompletionRoutine: Irp %p\n" , Irp );
2020+
2021+ KeSetEvent (Event , EVENT_INCREMENT , FALSE);
2022+
2023+ return STATUS_MORE_PROCESSING_REQUIRED ;
2024+ }
2025+
2026+ NTSTATUS
2027+ NTAPI
2028+ UsbSerQueryCapabilities (IN PDEVICE_OBJECT DeviceObject ,
2029+ IN PDEVICE_CAPABILITIES Capabilities )
2030+ {
2031+ PIO_STACK_LOCATION IoStack ;
2032+ KEVENT Event ;
2033+ PIRP Irp ;
2034+ NTSTATUS Status ;
2035+
2036+ DPRINT ("UsbSerQueryCapabilities\n" );
2037+
2038+ Irp = IoAllocateIrp (DeviceObject -> StackSize , FALSE);
2039+ if (!Irp )
2040+ {
2041+ DPRINT1 ("UsbSerQueryCapabilities: failed allocate irp\n" );
2042+ return STATUS_INSUFFICIENT_RESOURCES ;
2043+ }
2044+
2045+ IoStack = IoGetNextIrpStackLocation (Irp );
2046+ IoStack -> MajorFunction = IRP_MJ_PNP ;
2047+ IoStack -> MinorFunction = IRP_MN_QUERY_CAPABILITIES ;
2048+
2049+ KeInitializeEvent (& Event , NotificationEvent , FALSE);
2050+
2051+ IoSetCompletionRoutine (Irp , UsbSerIrpCompletionRoutine , & Event , TRUE, TRUE, TRUE);
2052+ Irp -> IoStatus .Status = STATUS_NOT_SUPPORTED ;
2053+
2054+ RtlZeroMemory (Capabilities , sizeof (* Capabilities ));
2055+
2056+ Capabilities -> Size = sizeof (* Capabilities );
2057+ Capabilities -> Version = 1 ;
2058+ Capabilities -> SurpriseRemovalOK = 1 ;
2059+ Capabilities -> Address = 0xFFFFFFFF ;
2060+ Capabilities -> UINumber = 0xFFFFFFFF ;
2061+
2062+ IoStack -> Parameters .DeviceCapabilities .Capabilities = Capabilities ;
2063+
2064+ Status = IoCallDriver (DeviceObject , Irp );
2065+ if (Status == STATUS_PENDING )
2066+ KeWaitForSingleObject (& Event , Suspended , KernelMode , FALSE, NULL );
2067+
2068+ IoFreeIrp (Irp );
2069+
2070+ return Status ;
2071+ }
2072+
17502073NTSTATUS
17512074NTAPI
17522075UsbSerPnPAddDevice (IN PDRIVER_OBJECT DriverObject ,
@@ -1762,6 +2085,7 @@ UsbSerPnPAddDevice(IN PDRIVER_OBJECT DriverObject,
17622085 WCHAR CharSymLink [64 ];
17632086 UNICODE_STRING SymLinkName ;
17642087 ULONG ExtSize ;
2088+ ULONG ix ;
17652089
17662090 PAGED_CODE ();
17672091 DPRINT ("UsbSerPnPAddDevice: DriverObject %p, TargetDevice %p\n" , DriverObject , TargetDevice );
@@ -1872,6 +2196,16 @@ UsbSerPnPAddDevice(IN PDRIVER_OBJECT DriverObject,
18722196 NewDevice -> Flags |= DO_POWER_PAGABLE ;
18732197 NewDevice -> Flags &= ~DO_DEVICE_INITIALIZING ;
18742198
2199+ UsbSerQueryCapabilities (Extension -> LowerDevice , & Extension -> Capabilities );
2200+
2201+ Extension -> MinDeviceState = 0 ;
2202+
2203+ for (ix = 2 ; ix < 5 ; ix ++ )
2204+ {
2205+ if (Extension -> Capabilities .DeviceState [ix ] < PowerDeviceD3 )
2206+ Extension -> MinDeviceState = Extension -> Capabilities .DeviceState [ix ];
2207+ }
2208+
18752209 Extension -> WmiLibInfo .GuidCount = 1 ;
18762210 Extension -> WmiLibInfo .GuidList = SerialWmiGuidList ;
18772211
0 commit comments