ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2020
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
21 participants
133 discussions
Start a n
N
ew thread
[reactos] 01/01: [UDFS] Fix uninitialized var use in UDFCommonCreate, return the right error code CORE-16174
by Suraj K Suresh
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=88f7be101a6217e8026ec…
commit 88f7be101a6217e8026ec0a8b23137047db38299 Author: Suraj K Suresh <kssuraj15(a)gmail.com> AuthorDate: Fri Jan 10 15:39:14 2020 +0530 Commit: Victor Perevertkin <victor(a)perevertkin.ru> CommitDate: Sat Jan 11 02:45:45 2020 +0200 [UDFS] Fix uninitialized var use in UDFCommonCreate, return the right error code CORE-16174 --- drivers/filesystems/udfs/create.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/filesystems/udfs/create.cpp b/drivers/filesystems/udfs/create.cpp index 6455389d52b..a00038e3d0b 100644 --- a/drivers/filesystems/udfs/create.cpp +++ b/drivers/filesystems/udfs/create.cpp @@ -1143,6 +1143,7 @@ op_vol_accs_dnd: // Only say ..CK OFF !!!! if(RC == STATUS_OBJECT_NAME_NOT_FOUND) RC = STATUS_OBJECT_PATH_NOT_FOUND; + ReturnedInformation = FILE_DOES_NOT_EXIST; try_return(RC); }
4 years, 11 months
1
0
0
0
[reactos] 01/01: [APISETS] Forwarders don't need parameter specifications (#2225)
by Serge Gautherie
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=10a4ecdc3f4802abcd027…
commit 10a4ecdc3f4802abcd027dbcd496a4b6671e803e Author: Serge Gautherie <32623169+SergeGautherie(a)users.noreply.github.com> AuthorDate: Fri Jan 10 14:20:53 2020 +0100 Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org> CommitDate: Fri Jan 10 14:20:53 2020 +0100 [APISETS] Forwarders don't need parameter specifications (#2225) Addendum to 192926ee. --- dll/apisets/api-ms-win-appmodel-runtime-l1-1-1.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/apisets/api-ms-win-appmodel-runtime-l1-1-1.spec b/dll/apisets/api-ms-win-appmodel-runtime-l1-1-1.spec index 1c4887411eb..0cdb40a7690 100644 --- a/dll/apisets/api-ms-win-appmodel-runtime-l1-1-1.spec +++ b/dll/apisets/api-ms-win-appmodel-runtime-l1-1-1.spec @@ -8,7 +8,7 @@ @ stub GetCurrentApplicationUserModelId @ stub GetCurrentPackageFamilyName @ stub GetCurrentPackageFullName -@ stdcall -version=0x602+ GetCurrentPackageId(ptr ptr) kernel32.GetCurrentPackageId +@ stdcall -version=0x602+ GetCurrentPackageId() kernel32.GetCurrentPackageId @ stub GetCurrentPackageInfo @ stub GetCurrentPackagePath @ stub GetPackageApplicationIds
4 years, 11 months
1
0
0
0
[reactos] 01/01: [KERNEL32_APITEST] Strengthen ConsoleCP for Writing functions (#2235)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bce2d86ae339d39f76a1b…
commit bce2d86ae339d39f76a1b95fa0a415e4d90c1a92 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Wed Jan 8 21:20:24 2020 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Wed Jan 8 21:20:24 2020 +0900 [KERNEL32_APITEST] Strengthen ConsoleCP for Writing functions (#2235) Add some tests for WriteConsoleOutputCharacterW and WriteConsoleOutputAttribute etc. into ConsoleCP testcase. CORE-12451 --- modules/rostests/apitests/kernel32/ConsoleCP.c | 145 ++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) diff --git a/modules/rostests/apitests/kernel32/ConsoleCP.c b/modules/rostests/apitests/kernel32/ConsoleCP.c index 315f182761a..ab5402f053d 100644 --- a/modules/rostests/apitests/kernel32/ConsoleCP.c +++ b/modules/rostests/apitests/kernel32/ConsoleCP.c @@ -22,6 +22,7 @@ static const WCHAR u0414[] = {0x0414, 0}; /* Д */ static const WCHAR u9580[] = {0x9580, 0}; /* 門 */ static const WCHAR space[] = {L' ', 0}; static const WCHAR ideograph_space = (WCHAR)0x3000; /* fullwidth space */ +static const WCHAR s_str[] = {L'A', 0x9580, 'B', 0}; static LCID lcidJapanese = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT), SORT_DEFAULT); static LCID lcidRussian = MAKELCID(MAKELANGID(LANG_RUSSIAN , SUBLANG_DEFAULT), SORT_DEFAULT); static BOOL s_bIs8Plus; @@ -267,7 +268,7 @@ static void test_cp932(HANDLE hConOut) CONSOLE_SCREEN_BUFFER_INFO csbi; int count; WCHAR str[32]; - WORD attr, attrs[4]; + WORD attr, attrs[16]; CHAR_INFO buff[16]; SMALL_RECT sr; @@ -773,7 +774,7 @@ static void test_cp932(HANDLE hConOut) c.Y = 0; ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); ok_int(ret, 1); - ok_long(len, ARRAYSIZE(attrs)); + ok_long(len, 4); ok_int(attrs[0], ATTR); if (s_bIs8Plus) { @@ -1075,7 +1076,7 @@ static void test_cp932(HANDLE hConOut) c.Y = 0; ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); ok_int(ret, 1); - ok_long(len, ARRAYSIZE(attrs)); + ok_long(len, 4); ok_int(attrs[0], ATTR); if (s_bIs8Plus) { @@ -1090,6 +1091,144 @@ static void test_cp932(HANDLE hConOut) ok_int(attrs[3], ATTR); } + /* FillConsoleOutputAttribute and WriteConsoleOutput */ + { + c.X = c.Y = 0; + SetConsoleCursorPosition(hConOut, c); + okCURSOR(hConOut, c); + for (n = 0; n < count; ++n) + { + ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL); + ok_int(ret, 1); + ok_long(len, 1); + } + + /* fill attrs */ + c.X = c.Y = 0; + SetConsoleCursorPosition(hConOut, c); + okCURSOR(hConOut, c); + ret = FillConsoleOutputAttribute(hConOut, 0xFFFF, 2, c, &len); + ok_int(ret, 1); + ok_long(len, 2); + + /* read attrs */ + memset(attrs, 0x7F, sizeof(attrs)); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len); + ok_int(ret, 1); + ok_long(len, 3); + if (s_bIs8Plus) + { + ok_int(attrs[0], 0xDCFF); + ok_int(attrs[1], 0xDCFF); + } + else + { + ok_int(attrs[0], 0xFCFF); + ok_int(attrs[1], 0xFCFF); + } + ok_int(attrs[2], ATTR); + + /* fill attrs */ + c.X = c.Y = 0; + SetConsoleCursorPosition(hConOut, c); + okCURSOR(hConOut, c); + ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len); + ok_int(ret, 1); + ok_long(len, 4); + + /* write */ + c.X = c.Y = 0; + sr.Left = 0; + sr.Top = 0; + sr.Right = 4; + sr.Bottom = 0; + buff[0].Char.UnicodeChar = L' '; + buff[0].Attributes = ATTR; + buff[1].Char.UnicodeChar = 0x9580; + buff[1].Attributes = ATTR | COMMON_LVB_LEADING_BYTE; + buff[2].Char.UnicodeChar = 0x9580; + buff[2].Attributes = ATTR | COMMON_LVB_TRAILING_BYTE; + buff[3].Char.UnicodeChar = L'A'; + buff[3].Attributes = ATTR; + buff[4].Char.UnicodeChar = L' '; + buff[4].Attributes = 0xFFFF; + buffSize.X = 4; + buffSize.Y = 1; + ret = WriteConsoleOutputW(hConOut, buff, buffSize, c, &sr); + ok_int(ret, 1); + ok_int(sr.Left, 0); + ok_int(sr.Top, 0); + ok_int(sr.Right, 3); + ok_int(sr.Bottom, 0); + + /* read attrs */ + memset(attrs, 0x7F, sizeof(attrs)); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); + ok_int(ret, 1); + ok_long(len, 6); + ok_int(attrs[0], ATTR); + ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(attrs[3], ATTR); + ok_int(attrs[4], ATTR); + ok_int(attrs[5], ATTR); + } + + /* WriteConsoleOutputCharacterW and WriteConsoleOutputAttribute */ + { + c.X = c.Y = 0; + SetConsoleCursorPosition(hConOut, c); + okCURSOR(hConOut, c); + for (n = 0; n < count; ++n) + { + ret = WriteConsoleW(hConOut, space, lstrlenW(space), &len, NULL); + ok_int(ret, 1); + ok_long(len, 1); + } + + /* write attrs */ + attrs[0] = ATTR; + attrs[1] = 0xFFFF; + attrs[2] = ATTR; + attrs[3] = 0; + ret = WriteConsoleOutputAttribute(hConOut, attrs, 4, c, &len); + ok_int(ret, 1); + ok_long(len, 4); + + /* read attrs */ + memset(attrs, 0x7F, sizeof(attrs)); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); + ok_int(ret, 1); + ok_long(len, 4); + ok_int(attrs[0], ATTR); + if (s_bIs8Plus) + ok_int(attrs[1], 0xDCFF); + else + ok_int(attrs[1], 0xFCFF); + ok_int(attrs[2], ATTR); + ok_int(attrs[3], 0); + + /* fill attr */ + ret = FillConsoleOutputAttribute(hConOut, ATTR, 4, c, &len); + ok_int(ret, 1); + ok_long(len, 4); + + /* write char */ + ret = WriteConsoleOutputCharacterW(hConOut, s_str, 4, c, &len); + ok_int(ret, 1); + ok_long(len, 4); + + /* read attrs */ + memset(attrs, 0x7F, sizeof(attrs)); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); + ok_int(ret, 1); + ok_long(len, 4); + ok_int(attrs[0], ATTR); + ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(attrs[3], ATTR); + } + /* Restore code page */ SetConsoleOutputCP(oldcp); }
4 years, 11 months
1
0
0
0
[reactos] 01/01: [SERVICES] Use the local system account to run all services on a LiveCD
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=07d48d88086b396cc33db…
commit 07d48d88086b396cc33db540a713e11c289f4196 Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Wed Jan 8 00:14:50 2020 +0100 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Wed Jan 8 00:15:52 2020 +0100 [SERVICES] Use the local system account to run all services on a LiveCD This fixes CORE-16589. --- base/system/services/database.c | 2 +- base/system/services/services.c | 72 +++++++++++++++++++++++++++++++++++++++++ base/system/services/services.h | 1 + 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/base/system/services/database.c b/base/system/services/database.c index fc3d673c347..6b710926205 100644 --- a/base/system/services/database.c +++ b/base/system/services/database.c @@ -370,7 +370,7 @@ ScmLogonService( DPRINT("ScmLogonService(%p %p)\n", pService, pImage); DPRINT("Service %S\n", pService->lpServiceName); - if (ScmIsLocalSystemAccount(pImage->pszAccountName)) + if (ScmIsLocalSystemAccount(pImage->pszAccountName) || ScmLiveSetup) return ERROR_SUCCESS; /* Get the user and domain names */ diff --git a/base/system/services/services.c b/base/system/services/services.c index 81725260253..7721eb95042 100644 --- a/base/system/services/services.c +++ b/base/system/services/services.c @@ -27,6 +27,7 @@ int WINAPI RegisterServicesProcess(DWORD ServicesProcessId); BOOL ScmInitialize = FALSE; BOOL ScmShutdown = FALSE; +BOOL ScmLiveSetup = FALSE; static HANDLE hScmShutdownEvent = NULL; static HANDLE hScmSecurityServicesEvent = NULL; @@ -48,6 +49,70 @@ PrintString(LPCSTR fmt, ...) #endif } +DWORD +CheckForLiveCD(VOID) +{ + WCHAR CommandLine[MAX_PATH]; + HKEY hSetupKey; + DWORD dwSetupType; + DWORD dwType; + DWORD dwSize; + DWORD dwError; + + DPRINT1("CheckSetup()\n"); + + /* Open the Setup key */ + dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SYSTEM\\Setup", + 0, + KEY_QUERY_VALUE, + &hSetupKey); + if (dwError != ERROR_SUCCESS) + return dwError; + + /* Read the SetupType value */ + dwSize = sizeof(DWORD); + dwError = RegQueryValueExW(hSetupKey, + L"SetupType", + NULL, + &dwType, + (LPBYTE)&dwSetupType, + &dwSize); + + if (dwError != ERROR_SUCCESS || + dwType != REG_DWORD || + dwSize != sizeof(DWORD) || + dwSetupType == 0) + goto done; + + /* Read the CmdLine value */ + dwSize = sizeof(CommandLine); + dwError = RegQueryValueExW(hSetupKey, + L"CmdLine", + NULL, + &dwType, + (LPBYTE)CommandLine, + &dwSize); + + if (dwError != ERROR_SUCCESS || + (dwType != REG_SZ && + dwType != REG_EXPAND_SZ && + dwType != REG_MULTI_SZ)) + goto done; + + /* Check for the '-mini' option */ + if (wcsstr(CommandLine, L" -mini") != NULL) + { + DPRINT1("Running on LiveCD!\n"); + ScmLiveSetup = TRUE; + } + +done: + RegCloseKey(hSetupKey); + + return dwError; +} + DWORD SetSecurityServicesEvent(VOID) @@ -169,6 +234,13 @@ wWinMain(HINSTANCE hInstance, DPRINT("SERVICES: Service Control Manager\n"); + dwError = CheckForLiveCD(); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("SERVICES: Failed to check for LiveCD (Error %lu)\n", dwError); + goto done; + } + /* Make us critical */ RtlSetProcessIsCritical(TRUE, NULL, TRUE); diff --git a/base/system/services/services.h b/base/system/services/services.h index 845ea020da1..6a9dd5d3783 100644 --- a/base/system/services/services.h +++ b/base/system/services/services.h @@ -101,6 +101,7 @@ extern LIST_ENTRY GroupListHead; extern LIST_ENTRY ImageListHead; extern BOOL ScmInitialize; extern BOOL ScmShutdown; +extern BOOL ScmLiveSetup; extern PSECURITY_DESCRIPTOR pPipeSD;
4 years, 11 months
1
0
0
0
[reactos] 01/01: [KS] KsQueryInformationFile(): Fix 'FastIoQueryBasicInfo' copypasta (#2236)
by Serge Gautherie
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e2b536bcb120422085766…
commit e2b536bcb120422085766b56af79ffbc883383a7 Author: Serge Gautherie <32623169+SergeGautherie(a)users.noreply.github.com> AuthorDate: Tue Jan 7 15:13:40 2020 +0100 Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org> CommitDate: Tue Jan 7 15:13:40 2020 +0100 [KS] KsQueryInformationFile(): Fix 'FastIoQueryBasicInfo' copypasta (#2236) Addendum to commit 4725a4fd (r42117). --- drivers/ksfilter/ks/irp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ksfilter/ks/irp.c b/drivers/ksfilter/ks/irp.c index 44e529e4ad5..0e67a66bffd 100644 --- a/drivers/ksfilter/ks/irp.c +++ b/drivers/ksfilter/ks/irp.c @@ -375,8 +375,8 @@ KsQueryInformationFile( } else if (FileInformationClass == FileStandardInformation) { - /* use FastIoQueryBasicInfo routine */ - if (FastIoDispatch->FastIoQueryBasicInfo) + /* use FastIoQueryStandardInfo routine */ + if (FastIoDispatch->FastIoQueryStandardInfo) { return FastIoDispatch->FastIoQueryStandardInfo(FileObject, TRUE, (PFILE_STANDARD_INFORMATION)FileInformation, &IoStatus, DeviceObject); }
4 years, 11 months
1
0
0
0
[reactos] 01/01: [WIN32SS][WINSRV] Fullwidth character handling for Asian console (#2231)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fa42794a3a51367823755…
commit fa42794a3a5136782375598b6636b61a95ae7317 Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Tue Jan 7 15:26:58 2020 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Tue Jan 7 15:26:58 2020 +0900 [WIN32SS][WINSRV] Fullwidth character handling for Asian console (#2231) Far-East Asian language (Chinese, Japanese and Korean; CJK) needs special handling in console. Especially a fullwidth character (mk_wcwidth_cjk(ch) == 2) needs a double width space. A fullwidth character on the console window is treated as a pair of a leading byte and a trailing byte (COMMON_LVB_LEADING_BYTE and COMMON_LVB_TRAILING_BYTE). CORE-12451 --- win32ss/user/winsrv/consrv/condrv/console.c | 11 +- win32ss/user/winsrv/consrv/condrv/text.c | 310 +++++++++++++++------ win32ss/user/winsrv/consrv/frontends/gui/conwnd.c | 2 +- win32ss/user/winsrv/consrv/frontends/gui/guiterm.h | 2 +- win32ss/user/winsrv/consrv/frontends/gui/text.c | 2 +- win32ss/user/winsrv/consrv/frontends/terminal.c | 68 ++++- win32ss/user/winsrv/consrv/include/conio.h | 5 +- win32ss/user/winsrv/consrv/settings.c | 3 + 8 files changed, 298 insertions(+), 105 deletions(-) diff --git a/win32ss/user/winsrv/consrv/condrv/console.c b/win32ss/user/winsrv/consrv/condrv/console.c index d088f317eb4..f888b755c2c 100644 --- a/win32ss/user/winsrv/consrv/condrv/console.c +++ b/win32ss/user/winsrv/consrv/condrv/console.c @@ -6,18 +6,18 @@ * PROGRAMMERS: G� van Geldorp * Jeffrey Morlan * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) + * Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com) */ /* INCLUDES *******************************************************************/ #include <consrv.h> - #include <coninput.h> +#include "../../concfg/font.h" #define NDEBUG #include <debug.h> - /* GLOBALS ********************************************************************/ static ULONG CurrentConsoleID = 0; @@ -220,6 +220,8 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole, if (IsValidCodePage(ConsoleInfo->CodePage)) Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage; + Console->IsCJK = IsCJKCodePage(Console->OutputCodePage); + /* Initialize a new text-mode screen buffer with default settings */ ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize; ScreenBufferInfo.ScreenAttrib = ConsoleInfo->ScreenAttrib; @@ -531,9 +533,14 @@ ConDrvSetConsoleCP(IN PCONSOLE Console, return STATUS_INVALID_PARAMETER; if (OutputCP) + { Console->OutputCodePage = CodePage; + Console->IsCJK = IsCJKCodePage(CodePage); + } else + { Console->InputCodePage = CodePage; + } return STATUS_SUCCESS; } diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index 5b4d415b297..de0c740e58f 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -408,13 +408,9 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, Y = (TopLeft.Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Length = NumCodesToWrite; - // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work - // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work - while (Length--) { - // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either - Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; + Ptr = ConioCoordToPointer(Buffer, X, Y); /* * Change the current colors only if they are the old ones. @@ -516,7 +512,8 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console, WideCharToMultiByte(Console->OutputCodePage, 0, &Ptr->Char.UnicodeChar, 1, &CurCharInfo->Char.AsciiChar, 1, NULL, NULL); } - CurCharInfo->Attributes = Ptr->Attributes; + CurCharInfo->Attributes = + (Ptr->Attributes & ~(COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE)); ++Ptr; ++CurCharInfo; } @@ -723,102 +720,147 @@ ConDrvWriteConsole(IN PCONSOLE Console, return Status; } -NTSTATUS NTAPI -ConDrvReadConsoleOutputString(IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN CODE_TYPE CodeType, - OUT PVOID StringBuffer, - IN ULONG NumCodesToRead, - IN PCOORD ReadCoord, - // OUT PCOORD EndCoord, - OUT PULONG NumCodesRead OPTIONAL) +NTSTATUS FASTCALL +IntReadConsoleOutputStringAscii(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) { - SHORT Xpos, Ypos; - PVOID ReadBuffer; + ULONG CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar); + LPBYTE ReadBuffer = StringBuffer; + SHORT Xpos = ReadCoord->X; + SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; ULONG i; - ULONG CodeSize; PCHAR_INFO Ptr; + BOOL bCJK = Console->IsCJK; - if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */) + for (i = 0; i < NumCodesToRead; ++i) { - return STATUS_INVALID_PARAMETER; + Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); + + ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); + ReadBuffer += CodeSize; + + Xpos++; + if (Xpos == Buffer->ScreenBufferSize.X) + { + Xpos = 0; + Ypos++; + if (Ypos == Buffer->ScreenBufferSize.Y) + { + Ypos = 0; + } + } + + /* For Chinese, Japanese and Korean */ + if (bCJK && (Ptr->Attributes & COMMON_LVB_LEADING_BYTE)) + { + Xpos++; + if (Xpos == Buffer->ScreenBufferSize.X) + { + Xpos = 0; + Ypos++; + if (Ypos == Buffer->ScreenBufferSize.Y) + { + Ypos = 0; + } + } + ++i; + } } - /* Validity checks */ - ASSERT(Console == Buffer->Header.Console); - ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0)); + if (NumCodesRead) + *NumCodesRead = i; - // - // FIXME: Make overflow checks on ReadCoord !!!!!! - // + return STATUS_SUCCESS; +} - if (NumCodesRead) *NumCodesRead = 0; +NTSTATUS FASTCALL +IntReadConsoleOutputStringUnicode(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) +{ + ULONG CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar); + LPBYTE ReadBuffer = StringBuffer; + SHORT Xpos = ReadCoord->X; + SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; + ULONG i, nNumChars = 0; + PCHAR_INFO Ptr; + BOOL bCJK = Console->IsCJK; - switch (CodeType) + for (i = 0; i < NumCodesToRead; ++i, ++nNumChars) { - case CODE_ASCII: - CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar); - break; + Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); - case CODE_UNICODE: - CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar); - break; + *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; + ReadBuffer += CodeSize; - case CODE_ATTRIBUTE: - CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute); - break; + Xpos++; + if (Xpos == Buffer->ScreenBufferSize.X) + { + Xpos = 0; + Ypos++; + if (Ypos == Buffer->ScreenBufferSize.Y) + { + Ypos = 0; + } + } - default: - return STATUS_INVALID_PARAMETER; + /* For Chinese, Japanese and Korean */ + if (bCJK && (Ptr->Attributes & COMMON_LVB_LEADING_BYTE)) + { + Xpos++; + if (Xpos == Buffer->ScreenBufferSize.X) + { + Xpos = 0; + Ypos++; + if (Ypos == Buffer->ScreenBufferSize.Y) + { + Ypos = 0; + } + } + ++i; + } } - ReadBuffer = StringBuffer; - Xpos = ReadCoord->X; - Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; + if (NumCodesRead) + *NumCodesRead = nNumChars; - /* - * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : - * - * If the number of attributes (resp. characters) to be read from extends - * beyond the end of the specified screen buffer row, attributes (resp. - * characters) are read from the next row. If the number of attributes - * (resp. characters) to be read from extends beyond the end of the console - * screen buffer, attributes (resp. characters) up to the end of the console - * screen buffer are read. - * - * TODO: Do NOT loop up to NumCodesToRead, but stop before - * if we are going to overflow... - */ - // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work - for (i = 0; i < min(NumCodesToRead, (ULONG)Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); ++i) - { - // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work either - Ptr = &Buffer->Buffer[Xpos + Ypos * Buffer->ScreenBufferSize.X]; + return STATUS_SUCCESS; +} - switch (CodeType) - { - case CODE_ASCII: - ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); - break; +NTSTATUS FASTCALL +IntReadConsoleOutputStringAttributes(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) +{ + ULONG CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute); + LPBYTE ReadBuffer = StringBuffer; + SHORT Xpos = ReadCoord->X; + SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; + ULONG i; + PCHAR_INFO Ptr; - case CODE_UNICODE: - *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; - break; + for (i = 0; i < NumCodesToRead; ++i) + { + Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); - case CODE_ATTRIBUTE: - *(PWORD)ReadBuffer = Ptr->Attributes; - break; - } - ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); - // ++Ptr; + *(PWORD)ReadBuffer = Ptr->Attributes; + ReadBuffer += CodeSize; Xpos++; - if (Xpos == Buffer->ScreenBufferSize.X) { Xpos = 0; Ypos++; - if (Ypos == Buffer->ScreenBufferSize.Y) { Ypos = 0; @@ -826,16 +868,70 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console, } } - // EndCoord->X = Xpos; - // EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y; + if (Xpos > 0 && Console->IsCJK) + { + ReadBuffer -= CodeSize; + *(PWORD)ReadBuffer &= ~COMMON_LVB_LEADING_BYTE; + } if (NumCodesRead) - *NumCodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize; - // <= NumCodesToRead + *NumCodesRead = NumCodesToRead; return STATUS_SUCCESS; } +NTSTATUS NTAPI +ConDrvReadConsoleOutputString(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) +{ + if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity checks */ + ASSERT(Console == Buffer->Header.Console); + ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0)); + + if (NumCodesRead) + *NumCodesRead = 0; + + switch (CodeType) + { + case CODE_ASCII: + return IntReadConsoleOutputStringAscii(Console, + Buffer, + StringBuffer, + NumCodesToRead, + ReadCoord, + NumCodesRead); + + case CODE_UNICODE: + return IntReadConsoleOutputStringUnicode(Console, + Buffer, + StringBuffer, + NumCodesToRead, + ReadCoord, + NumCodesRead); + + case CODE_ATTRIBUTE: + return IntReadConsoleOutputStringAttributes(Console, + Buffer, + StringBuffer, + NumCodesToRead, + ReadCoord, + NumCodesRead); + + default: + return STATUS_INVALID_PARAMETER; + } +} + NTSTATUS NTAPI ConDrvWriteConsoleOutputString(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, @@ -923,13 +1019,10 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console, X = WriteCoord->X; Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Length = NumCodesToWrite; - // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work - // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work while (Length--) { - // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either - Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; + Ptr = ConioCoordToPointer(Buffer, X, Y); switch (CodeType) { @@ -983,8 +1076,9 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, IN PCOORD WriteCoord, OUT PULONG NumCodesWritten OPTIONAL) { - ULONG X, Y, Length; // , Written = 0; + ULONG X, Y, i; PCHAR_INFO Ptr; + BOOL bLead, bFullwidth; if (Console == NULL || Buffer == NULL || WriteCoord == NULL) { @@ -1010,24 +1104,48 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, X = WriteCoord->X; Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - Length = NumCodesToWrite; // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work - while (Length--) + /* For Chinese, Japanese and Korean */ + bLead = TRUE; + bFullwidth = FALSE; + if (Console->IsCJK) { - // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either - Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; + bFullwidth = (mk_wcwidth_cjk(Code.UnicodeChar) == 2); + if (X > 0) + { + Ptr = ConioCoordToPointer(Buffer, X - 1, Y); + if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE) + { + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes &= ~COMMON_LVB_LEADING_BYTE; + } + } + } + + for (i = 0; i < NumCodesToWrite; ++i) + { + Ptr = ConioCoordToPointer(Buffer, X, Y); switch (CodeType) { case CODE_ASCII: case CODE_UNICODE: Ptr->Char.UnicodeChar = Code.UnicodeChar; + Ptr->Attributes &= ~(COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE); + if (bFullwidth) + { + if (bLead) + Ptr->Attributes |= COMMON_LVB_LEADING_BYTE; + else + Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE; + } break; case CODE_ATTRIBUTE: - Ptr->Attributes = Code.Attribute; + Ptr->Attributes &= ~0xFF; + Ptr->Attributes |= (Code.Attribute & 0xFF); break; } // ++Ptr; @@ -1042,6 +1160,18 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, Y = 0; } } + + bLead = !bLead; + } + + if ((NumCodesToWrite & 1) & bFullwidth) + { + if (X + Y * Buffer->ScreenBufferSize.X > 0) + { + Ptr = ConioCoordToPointer(Buffer, X - 1, Y); + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes &= ~(COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE); + } } if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) diff --git a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c index b7859201a3a..eda0e822861 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c @@ -993,7 +993,7 @@ OnPaint(PGUI_CONSOLE_DATA GuiData) { if (IsCJKCodePage(ActiveBuffer->Header.Console->OutputCodePage)) { - /* For Chinese, Japanese and Korean: */ + /* For Chinese, Japanese and Korean */ GuiPaintTextModeBufferCJK((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer, GuiData, &ps.rcPaint, &rcPaint); } diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h index bd28b2b98d1..2e4a6dfd90f 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h @@ -121,7 +121,7 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PRECT rcView, PRECT rcFramebuffer); -/* For Chinese, Japanese and Korean: */ +/* For Chinese, Japanese and Korean */ VOID GuiPaintTextModeBufferCJK(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, diff --git a/win32ss/user/winsrv/consrv/frontends/gui/text.c b/win32ss/user/winsrv/consrv/frontends/gui/text.c index 2b62c3dd377..8b12645df77 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -494,7 +494,7 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, LeaveCriticalSection(&Console->Lock); } -/* For Chinese, Japanese and Korean: */ +/* For Chinese, Japanese and Korean */ VOID GuiPaintTextModeBufferCJK(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, diff --git a/win32ss/user/winsrv/consrv/frontends/terminal.c b/win32ss/user/winsrv/consrv/frontends/terminal.c index c4ca197a6dd..6603d844050 100644 --- a/win32ss/user/winsrv/consrv/frontends/terminal.c +++ b/win32ss/user/winsrv/consrv/frontends/terminal.c @@ -492,8 +492,6 @@ ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT Scroll UpdateRect->Bottom = Buff->CursorPosition.Y; } -int mk_wcwidth_cjk(wchar_t ucs); - static NTSTATUS ConioWriteConsole(PFRONTEND FrontEnd, PTEXTMODE_SCREEN_BUFFER Buff, @@ -508,7 +506,7 @@ ConioWriteConsole(PFRONTEND FrontEnd, SMALL_RECT UpdateRect; SHORT CursorStartX, CursorStartY; UINT ScrolledLines; - BOOL bCJK = IsCJKCodePage(Console->OutputCodePage); + BOOL bCJK = Console->IsCJK; CursorStartX = Buff->CursorPosition.X; CursorStartY = Buff->CursorPosition.Y; @@ -607,16 +605,56 @@ ConioWriteConsole(PFRONTEND FrontEnd, UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - + /* For Chinese, Japanese and Korean */ if (bCJK && Buffer[i] >= 0x80 && mk_wcwidth_cjk(Buffer[i]) == 2) { /* Buffer[i] is a fullwidth character */ - /* FIXME */ - } - Ptr->Char.UnicodeChar = Buffer[i]; - if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib; + if (Buff->CursorPosition.X > 0) + { + /* Kill the previous leading byte */ + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X - 1, Buff->CursorPosition.Y); + if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE) + { + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes &= ~COMMON_LVB_LEADING_BYTE; + } + } + + if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X - 1) + { + /* New line */ + if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) + { + Buff->CursorPosition.X = 0; + ConioNextLine(Buff, &UpdateRect, &ScrolledLines); + } + else + { + Buff->CursorPosition.X = CursorStartX; + } + } + + /* Set leading */ + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + Ptr->Char.UnicodeChar = Buffer[i]; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib | COMMON_LVB_LEADING_BYTE; + + /* Set trailing */ + Buff->CursorPosition.X++; + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib | COMMON_LVB_TRAILING_BYTE; + } + else + { + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + Ptr->Char.UnicodeChar = Buffer[i]; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + } Buff->CursorPosition.X++; if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) @@ -633,6 +671,18 @@ ConioWriteConsole(PFRONTEND FrontEnd, } } + if (bCJK && Buff->CursorPosition.X > 0) + { + /* Delete trailing */ + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) + { + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + } + } + if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) { // TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, diff --git a/win32ss/user/winsrv/consrv/include/conio.h b/win32ss/user/winsrv/consrv/include/conio.h index 3e7f96dd096..ad1b226020d 100644 --- a/win32ss/user/winsrv/consrv/include/conio.h +++ b/win32ss/user/winsrv/consrv/include/conio.h @@ -345,7 +345,7 @@ typedef struct _CONSOLE /****************************** Other properties ******************************/ COORD ConsoleSize; /* The current size of the console, for text-mode only */ BOOLEAN FixedSize; /* TRUE if the console is of fixed size */ - + BOOLEAN IsCJK; /* TRUE if Chinese, Japanese or Korean (CJK) */ } CONSOLE; // , *PCONSOLE; /* console.c */ @@ -369,4 +369,7 @@ NTSTATUS ConioResizeBuffer(PCONSOLE /*PCONSRV_CONSOLE*/ Console, PTEXTMODE_SCREEN_BUFFER ScreenBuffer, COORD Size); +/* wcwidth.c */ +int mk_wcwidth_cjk(wchar_t ucs); + /* EOF */ diff --git a/win32ss/user/winsrv/consrv/settings.c b/win32ss/user/winsrv/consrv/settings.c index 1cfd4d37971..879c152d4d1 100644 --- a/win32ss/user/winsrv/consrv/settings.c +++ b/win32ss/user/winsrv/consrv/settings.c @@ -10,6 +10,7 @@ /* INCLUDES *******************************************************************/ #include "consrv.h" +#include "../concfg/font.h" #define NDEBUG #include <debug.h> @@ -59,6 +60,8 @@ ConSrvApplyUserSettings(IN PCONSOLE Console, Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage; // ConDrvSetConsoleCP(Console, ConsoleInfo->CodePage, TRUE); // Output // ConDrvSetConsoleCP(Console, ConsoleInfo->CodePage, FALSE); // Input + + Console->IsCJK = IsCJKCodePage(Console->OutputCodePage); } // FIXME: Check ConsoleInfo->WindowSize with respect to
4 years, 11 months
1
0
0
0
[reactos] 01/01: [DESK] The DisplayClassInstaller must create a new DeviceX subkey for each new display devices
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b00a1f3e762cf30105ee9…
commit b00a1f3e762cf30105ee999bd63d92a16d5993ef Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Mon Jan 6 22:38:53 2020 +0100 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Mon Jan 6 22:39:41 2020 +0100 [DESK] The DisplayClassInstaller must create a new DeviceX subkey for each new display devices This should fix CORE-16615 --- dll/cpl/desk/classinst.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/dll/cpl/desk/classinst.c b/dll/cpl/desk/classinst.c index 576a6e76835..4356046fb51 100644 --- a/dll/cpl/desk/classinst.c +++ b/dll/cpl/desk/classinst.c @@ -23,6 +23,7 @@ DisplayClassInstaller( HINF hInf = INVALID_HANDLE_VALUE; TCHAR SectionName[MAX_PATH]; TCHAR ServiceName[MAX_SERVICE_NAME_LEN]; + TCHAR DeviceName[12]; SP_DRVINFO_DETAIL_DATA DriverInfoDetailData; HKEY hDriverKey = INVALID_HANDLE_VALUE; /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */ HKEY hSettingsKey = NULL; @@ -30,6 +31,7 @@ DisplayClassInstaller( HKEY hServiceKey = NULL; HKEY hDeviceSubKey = NULL; DWORD disposition, cchMax, cbData; + WORD wIndex; BOOL result; LONG rc; HRESULT hr; @@ -183,21 +185,33 @@ DisplayClassInstaller( goto cleanup; } - /* Create a Device0 subkey (FIXME: do a loop to find a free number?) */ - rc = RegCreateKeyEx( - hServiceKey, _T("Device0"), 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, - &hDeviceSubKey, &disposition); - if (rc != ERROR_SUCCESS) - { - DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc); - goto cleanup; - } - if (disposition != REG_CREATED_NEW_KEY) + /* Create a new DeviceX subkey */ + for (wIndex = 0; wIndex < 9999; wIndex++) { - rc = ERROR_GEN_FAILURE; - DPRINT("RegCreateKeyEx() failed\n"); - goto cleanup; + _stprintf(DeviceName, _T("Device%hu"), wIndex); + + rc = RegCreateKeyEx( + hServiceKey, DeviceName, 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, + &hDeviceSubKey, &disposition); + if (rc != ERROR_SUCCESS) + { + DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc); + goto cleanup; + } + + if (disposition == REG_CREATED_NEW_KEY) + break; + + if (wIndex == 9999) + { + rc = ERROR_GEN_FAILURE; + DPRINT("RegCreateKeyEx() failed\n"); + goto cleanup; + } + + RegCloseKey(hDeviceSubKey); + hDeviceSubKey = NULL; } /* Install SoftwareSettings section */
4 years, 11 months
1
0
0
0
[reactos] 02/02: [USB] Update the names of new USB drivers
by Oleg Dubinskiy
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=611d925d3280a3bc590d7…
commit 611d925d3280a3bc590d7eccc7d4fdefb043153a Author: Oleg Dubinskiy <oleg.dubinskij2013(a)yandex.ua> AuthorDate: Thu Jan 2 15:05:51 2020 +0200 Commit: Victor Perevertkin <victor(a)perevertkin.ru> CommitDate: Mon Jan 6 21:16:08 2020 +0200 [USB] Update the names of new USB drivers --- drivers/usb/CMakeLists.txt | 8 ++++---- drivers/usb/{usbehci_new => usbehci}/CMakeLists.txt | 0 drivers/usb/{usbehci_new => usbehci}/dbg_ehci.h | 0 drivers/usb/{usbehci_new => usbehci}/debug.c | 0 drivers/usb/{usbehci_new => usbehci}/guid.c | 0 drivers/usb/{usbehci_new => usbehci}/hardware.h | 0 drivers/usb/{usbehci_new => usbehci}/roothub.c | 0 drivers/usb/{usbehci_new => usbehci}/usbehci.c | 0 drivers/usb/{usbehci_new => usbehci}/usbehci.h | 0 drivers/usb/{usbehci_new => usbehci}/usbehci.rc | 0 drivers/usb/{usbhub_new => usbhub}/CMakeLists.txt | 0 drivers/usb/{usbhub_new => usbhub}/dbg_uhub.h | 0 drivers/usb/{usbhub_new => usbhub}/debug.c | 0 drivers/usb/{usbhub_new => usbhub}/guid.c | 0 drivers/usb/{usbhub_new => usbhub}/ioctl.c | 0 drivers/usb/{usbhub_new => usbhub}/pnp.c | 0 drivers/usb/{usbhub_new => usbhub}/power.c | 0 drivers/usb/{usbhub_new => usbhub}/usbhub.c | 0 drivers/usb/{usbhub_new => usbhub}/usbhub.h | 0 drivers/usb/{usbhub_new => usbhub}/usbhub.rc | 0 drivers/usb/{usbohci_new => usbohci}/CMakeLists.txt | 0 drivers/usb/{usbohci_new => usbohci}/dbg_ohci.h | 0 drivers/usb/{usbohci_new => usbohci}/guid.c | 0 drivers/usb/{usbohci_new => usbohci}/hardware.h | 0 drivers/usb/{usbohci_new => usbohci}/roothub.c | 0 drivers/usb/{usbohci_new => usbohci}/usbohci.c | 0 drivers/usb/{usbohci_new => usbohci}/usbohci.h | 0 drivers/usb/{usbohci_new => usbohci}/usbohci.rc | 0 drivers/usb/{usbuhci_new => usbuhci}/CMakeLists.txt | 0 drivers/usb/{usbuhci_new => usbuhci}/dbg_uhci.h | 0 drivers/usb/{usbuhci_new => usbuhci}/guid.c | 0 drivers/usb/{usbuhci_new => usbuhci}/hardware.h | 0 drivers/usb/{usbuhci_new => usbuhci}/roothub.c | 0 drivers/usb/{usbuhci_new => usbuhci}/usbuhci.c | 0 drivers/usb/{usbuhci_new => usbuhci}/usbuhci.h | 0 drivers/usb/{usbuhci_new => usbuhci}/usbuhci.rc | 0 36 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index 3f33c2b2c4f..0a24294acdb 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -1,9 +1,9 @@ add_subdirectory(usbccgp) add_subdirectory(usbd) -add_subdirectory(usbehci_new) -add_subdirectory(usbhub_new) -add_subdirectory(usbohci_new) +add_subdirectory(usbehci) +add_subdirectory(usbhub) +add_subdirectory(usbohci) add_subdirectory(usbport) add_subdirectory(usbstor) #add_subdirectory(usbstor_new) -add_subdirectory(usbuhci_new) +add_subdirectory(usbuhci) diff --git a/drivers/usb/usbehci_new/CMakeLists.txt b/drivers/usb/usbehci/CMakeLists.txt similarity index 100% rename from drivers/usb/usbehci_new/CMakeLists.txt rename to drivers/usb/usbehci/CMakeLists.txt diff --git a/drivers/usb/usbehci_new/dbg_ehci.h b/drivers/usb/usbehci/dbg_ehci.h similarity index 100% rename from drivers/usb/usbehci_new/dbg_ehci.h rename to drivers/usb/usbehci/dbg_ehci.h diff --git a/drivers/usb/usbehci_new/debug.c b/drivers/usb/usbehci/debug.c similarity index 100% rename from drivers/usb/usbehci_new/debug.c rename to drivers/usb/usbehci/debug.c diff --git a/drivers/usb/usbehci_new/guid.c b/drivers/usb/usbehci/guid.c similarity index 100% rename from drivers/usb/usbehci_new/guid.c rename to drivers/usb/usbehci/guid.c diff --git a/drivers/usb/usbehci_new/hardware.h b/drivers/usb/usbehci/hardware.h similarity index 100% rename from drivers/usb/usbehci_new/hardware.h rename to drivers/usb/usbehci/hardware.h diff --git a/drivers/usb/usbehci_new/roothub.c b/drivers/usb/usbehci/roothub.c similarity index 100% rename from drivers/usb/usbehci_new/roothub.c rename to drivers/usb/usbehci/roothub.c diff --git a/drivers/usb/usbehci_new/usbehci.c b/drivers/usb/usbehci/usbehci.c similarity index 100% rename from drivers/usb/usbehci_new/usbehci.c rename to drivers/usb/usbehci/usbehci.c diff --git a/drivers/usb/usbehci_new/usbehci.h b/drivers/usb/usbehci/usbehci.h similarity index 100% rename from drivers/usb/usbehci_new/usbehci.h rename to drivers/usb/usbehci/usbehci.h diff --git a/drivers/usb/usbehci_new/usbehci.rc b/drivers/usb/usbehci/usbehci.rc similarity index 100% rename from drivers/usb/usbehci_new/usbehci.rc rename to drivers/usb/usbehci/usbehci.rc diff --git a/drivers/usb/usbhub_new/CMakeLists.txt b/drivers/usb/usbhub/CMakeLists.txt similarity index 100% rename from drivers/usb/usbhub_new/CMakeLists.txt rename to drivers/usb/usbhub/CMakeLists.txt diff --git a/drivers/usb/usbhub_new/dbg_uhub.h b/drivers/usb/usbhub/dbg_uhub.h similarity index 100% rename from drivers/usb/usbhub_new/dbg_uhub.h rename to drivers/usb/usbhub/dbg_uhub.h diff --git a/drivers/usb/usbhub_new/debug.c b/drivers/usb/usbhub/debug.c similarity index 100% rename from drivers/usb/usbhub_new/debug.c rename to drivers/usb/usbhub/debug.c diff --git a/drivers/usb/usbhub_new/guid.c b/drivers/usb/usbhub/guid.c similarity index 100% rename from drivers/usb/usbhub_new/guid.c rename to drivers/usb/usbhub/guid.c diff --git a/drivers/usb/usbhub_new/ioctl.c b/drivers/usb/usbhub/ioctl.c similarity index 100% rename from drivers/usb/usbhub_new/ioctl.c rename to drivers/usb/usbhub/ioctl.c diff --git a/drivers/usb/usbhub_new/pnp.c b/drivers/usb/usbhub/pnp.c similarity index 100% rename from drivers/usb/usbhub_new/pnp.c rename to drivers/usb/usbhub/pnp.c diff --git a/drivers/usb/usbhub_new/power.c b/drivers/usb/usbhub/power.c similarity index 100% rename from drivers/usb/usbhub_new/power.c rename to drivers/usb/usbhub/power.c diff --git a/drivers/usb/usbhub_new/usbhub.c b/drivers/usb/usbhub/usbhub.c similarity index 100% rename from drivers/usb/usbhub_new/usbhub.c rename to drivers/usb/usbhub/usbhub.c diff --git a/drivers/usb/usbhub_new/usbhub.h b/drivers/usb/usbhub/usbhub.h similarity index 100% rename from drivers/usb/usbhub_new/usbhub.h rename to drivers/usb/usbhub/usbhub.h diff --git a/drivers/usb/usbhub_new/usbhub.rc b/drivers/usb/usbhub/usbhub.rc similarity index 100% rename from drivers/usb/usbhub_new/usbhub.rc rename to drivers/usb/usbhub/usbhub.rc diff --git a/drivers/usb/usbohci_new/CMakeLists.txt b/drivers/usb/usbohci/CMakeLists.txt similarity index 100% rename from drivers/usb/usbohci_new/CMakeLists.txt rename to drivers/usb/usbohci/CMakeLists.txt diff --git a/drivers/usb/usbohci_new/dbg_ohci.h b/drivers/usb/usbohci/dbg_ohci.h similarity index 100% rename from drivers/usb/usbohci_new/dbg_ohci.h rename to drivers/usb/usbohci/dbg_ohci.h diff --git a/drivers/usb/usbohci_new/guid.c b/drivers/usb/usbohci/guid.c similarity index 100% rename from drivers/usb/usbohci_new/guid.c rename to drivers/usb/usbohci/guid.c diff --git a/drivers/usb/usbohci_new/hardware.h b/drivers/usb/usbohci/hardware.h similarity index 100% rename from drivers/usb/usbohci_new/hardware.h rename to drivers/usb/usbohci/hardware.h diff --git a/drivers/usb/usbohci_new/roothub.c b/drivers/usb/usbohci/roothub.c similarity index 100% rename from drivers/usb/usbohci_new/roothub.c rename to drivers/usb/usbohci/roothub.c diff --git a/drivers/usb/usbohci_new/usbohci.c b/drivers/usb/usbohci/usbohci.c similarity index 100% rename from drivers/usb/usbohci_new/usbohci.c rename to drivers/usb/usbohci/usbohci.c diff --git a/drivers/usb/usbohci_new/usbohci.h b/drivers/usb/usbohci/usbohci.h similarity index 100% rename from drivers/usb/usbohci_new/usbohci.h rename to drivers/usb/usbohci/usbohci.h diff --git a/drivers/usb/usbohci_new/usbohci.rc b/drivers/usb/usbohci/usbohci.rc similarity index 100% rename from drivers/usb/usbohci_new/usbohci.rc rename to drivers/usb/usbohci/usbohci.rc diff --git a/drivers/usb/usbuhci_new/CMakeLists.txt b/drivers/usb/usbuhci/CMakeLists.txt similarity index 100% rename from drivers/usb/usbuhci_new/CMakeLists.txt rename to drivers/usb/usbuhci/CMakeLists.txt diff --git a/drivers/usb/usbuhci_new/dbg_uhci.h b/drivers/usb/usbuhci/dbg_uhci.h similarity index 100% rename from drivers/usb/usbuhci_new/dbg_uhci.h rename to drivers/usb/usbuhci/dbg_uhci.h diff --git a/drivers/usb/usbuhci_new/guid.c b/drivers/usb/usbuhci/guid.c similarity index 100% rename from drivers/usb/usbuhci_new/guid.c rename to drivers/usb/usbuhci/guid.c diff --git a/drivers/usb/usbuhci_new/hardware.h b/drivers/usb/usbuhci/hardware.h similarity index 100% rename from drivers/usb/usbuhci_new/hardware.h rename to drivers/usb/usbuhci/hardware.h diff --git a/drivers/usb/usbuhci_new/roothub.c b/drivers/usb/usbuhci/roothub.c similarity index 100% rename from drivers/usb/usbuhci_new/roothub.c rename to drivers/usb/usbuhci/roothub.c diff --git a/drivers/usb/usbuhci_new/usbuhci.c b/drivers/usb/usbuhci/usbuhci.c similarity index 100% rename from drivers/usb/usbuhci_new/usbuhci.c rename to drivers/usb/usbuhci/usbuhci.c diff --git a/drivers/usb/usbuhci_new/usbuhci.h b/drivers/usb/usbuhci/usbuhci.h similarity index 100% rename from drivers/usb/usbuhci_new/usbuhci.h rename to drivers/usb/usbuhci/usbuhci.h diff --git a/drivers/usb/usbuhci_new/usbuhci.rc b/drivers/usb/usbuhci/usbuhci.rc similarity index 100% rename from drivers/usb/usbuhci_new/usbuhci.rc rename to drivers/usb/usbuhci/usbuhci.rc
4 years, 11 months
1
0
0
0
[reactos] 01/02: [SDK][USB] Delete old USB drivers and libusb
by Oleg Dubinskiy
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=83c07f4e4c2a74e00c30d…
commit 83c07f4e4c2a74e00c30db18deee7ba092f44408 Author: Oleg Dubinskiy <oleg.dubinskij2013(a)yandex.ua> AuthorDate: Thu Jan 2 15:01:32 2020 +0200 Commit: Victor Perevertkin <victor(a)perevertkin.ru> CommitDate: Mon Jan 6 21:16:08 2020 +0200 [SDK][USB] Delete old USB drivers and libusb --- CODEOWNERS | 1 - drivers/usb/CMakeLists.txt | 4 - drivers/usb/usbehci/CMakeLists.txt | 25 - drivers/usb/usbehci/guid.cpp | 9 - drivers/usb/usbehci/hardware.cpp | 1490 ----------- drivers/usb/usbehci/hardware.h | 325 --- drivers/usb/usbehci/interfaces.h | 151 -- drivers/usb/usbehci/usb_queue.cpp | 1236 --------- drivers/usb/usbehci/usb_request.cpp | 1852 ------------- drivers/usb/usbehci/usbehci.cpp | 57 - drivers/usb/usbehci/usbehci.h | 36 - drivers/usb/usbehci/usbehci.rc | 5 - drivers/usb/usbhub/CMakeLists.txt | 23 - drivers/usb/usbhub/fdo.c | 2487 ----------------- drivers/usb/usbhub/guid.c | 9 - drivers/usb/usbhub/hub_fdo.c | 216 -- drivers/usb/usbhub/misc.c | 213 -- drivers/usb/usbhub/pdo.c | 863 ------ drivers/usb/usbhub/usbhub.c | 297 -- drivers/usb/usbhub/usbhub.h | 225 -- drivers/usb/usbhub/usbhub.rc | 5 - drivers/usb/usbohci/CMakeLists.txt | 25 - drivers/usb/usbohci/guid.cpp | 9 - drivers/usb/usbohci/hardware.cpp | 1584 ----------- drivers/usb/usbohci/hardware.h | 347 --- drivers/usb/usbohci/interfaces.h | 134 - drivers/usb/usbohci/usb_queue.cpp | 1022 ------- drivers/usb/usbohci/usb_request.cpp | 2014 -------------- drivers/usb/usbohci/usbohci.cpp | 45 - drivers/usb/usbohci/usbohci.h | 54 - drivers/usb/usbohci/usbohci.rc | 5 - drivers/usb/usbuhci/CMakeLists.txt | 25 - drivers/usb/usbuhci/guid.cpp | 9 - drivers/usb/usbuhci/hardware.cpp | 1516 ----------- drivers/usb/usbuhci/hardware.h | 191 -- drivers/usb/usbuhci/interfaces.h | 138 - drivers/usb/usbuhci/usb_queue.cpp | 548 ---- drivers/usb/usbuhci/usb_request.cpp | 1446 ---------- drivers/usb/usbuhci/usbuhci.cpp | 44 - drivers/usb/usbuhci/usbuhci.h | 50 - drivers/usb/usbuhci/usbuhci.rc | 5 - sdk/lib/drivers/CMakeLists.txt | 1 - sdk/lib/drivers/libusb/CMakeLists.txt | 21 - sdk/lib/drivers/libusb/common_interfaces.h | 691 ----- sdk/lib/drivers/libusb/hcd_controller.cpp | 791 ------ sdk/lib/drivers/libusb/hub_controller.cpp | 4014 ---------------------------- sdk/lib/drivers/libusb/libusb.cpp | 170 -- sdk/lib/drivers/libusb/libusb.h | 105 - sdk/lib/drivers/libusb/memory_manager.cpp | 372 --- sdk/lib/drivers/libusb/misc.cpp | 137 - sdk/lib/drivers/libusb/purecall.cpp | 25 - sdk/lib/drivers/libusb/usb_device.cpp | 1329 --------- 52 files changed, 26396 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 571825b6a90..04a24a76bc2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -275,7 +275,6 @@ # R: Extravert-ir, extravert34, Victor Perevertkin # S: Maintained /drivers/usb/ @ThFabba @Extravert-ir -/sdk/lib/drivers/libusb/ @ThFabba @Extravert-ir /sdk/include/reactos/drivers/usbport/ @ThFabba @Extravert-ir # Virtual CD-ROM diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index 1315f1a571e..3f33c2b2c4f 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -1,13 +1,9 @@ add_subdirectory(usbccgp) add_subdirectory(usbd) -#add_subdirectory(usbehci) add_subdirectory(usbehci_new) -#add_subdirectory(usbhub) add_subdirectory(usbhub_new) -#add_subdirectory(usbohci) add_subdirectory(usbohci_new) add_subdirectory(usbport) add_subdirectory(usbstor) #add_subdirectory(usbstor_new) -#add_subdirectory(usbuhci) add_subdirectory(usbuhci_new) diff --git a/drivers/usb/usbehci/CMakeLists.txt b/drivers/usb/usbehci/CMakeLists.txt deleted file mode 100644 index f515915899e..00000000000 --- a/drivers/usb/usbehci/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ - -set_cpp() - -remove_definitions(-D_WIN32_WINNT=0x502) -add_definitions(-D_WIN32_WINNT=0x600) - -include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/drivers/libusb) - -list(APPEND SOURCE - usbehci.cpp - usb_request.cpp - usb_queue.cpp - hardware.cpp - usbehci.h) - -add_library(usbehci MODULE - ${SOURCE} - guid.cpp - usbehci.rc) - -target_link_libraries(usbehci uuid libusb libcntpr ${PSEH_LIB}) -set_module_type(usbehci kernelmodedriver) -add_importlibs(usbehci ntoskrnl hal usbd) -add_pch(usbehci usbehci.h SOURCE) -add_cd_file(TARGET usbehci DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/drivers/usb/usbehci/guid.cpp b/drivers/usb/usbehci/guid.cpp deleted file mode 100644 index 50a60369ff3..00000000000 --- a/drivers/usb/usbehci/guid.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */ - -#include <wdm.h> -#include <initguid.h> -#include <wdmguid.h> -#include <hubbusif.h> -#include <usbbusif.h> - -/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */ diff --git a/drivers/usb/usbehci/hardware.cpp b/drivers/usb/usbehci/hardware.cpp deleted file mode 100644 index 8562eaa4b3c..00000000000 --- a/drivers/usb/usbehci/hardware.cpp +++ /dev/null @@ -1,1490 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbehci/hcd_controller.cpp - * PURPOSE: USB EHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin(a)reactos.org) - * Johannes Anderwald (johannes.anderwald(a)reactos.org) - */ - -#include "usbehci.h" - -#define NDEBUG -#include <debug.h> - -typedef VOID __stdcall HD_INIT_CALLBACK(IN PVOID CallBackContext); - -BOOLEAN -NTAPI -InterruptServiceRoutine( - IN PKINTERRUPT Interrupt, - IN PVOID ServiceContext); - -VOID -NTAPI -EhciDeferredRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2); - -VOID -NTAPI -StatusChangeWorkItemRoutine(PVOID Context); - -class CUSBHardwareDevice : public IEHCIHardwareDevice -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - // com - IMP_IUSBHARDWAREDEVICE - IMP_IUSBEHCIHARDWARE - - // local - BOOLEAN InterruptService(); - VOID PrintCapabilities(); - NTSTATUS StartController(); - NTSTATUS StopController(); - NTSTATUS ResetController(); - - // friend function - friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext); - friend VOID NTAPI EhciDeferredRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2); - friend VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context); - // constructor / destructor - CUSBHardwareDevice(IUnknown *OuterUnknown){} - virtual ~CUSBHardwareDevice(){} - -protected: - LONG m_Ref; // reference count - PDRIVER_OBJECT m_DriverObject; // driver object - PDEVICE_OBJECT m_PhysicalDeviceObject; // pdo - PDEVICE_OBJECT m_FunctionalDeviceObject; // fdo (hcd controller) - PDEVICE_OBJECT m_NextDeviceObject; // lower device object - KSPIN_LOCK m_Lock; // hardware lock - PKINTERRUPT m_Interrupt; // interrupt object - KDPC m_IntDpcObject; // dpc object for deferred isr processing - PVOID VirtualBase; // virtual base for memory manager - PHYSICAL_ADDRESS PhysicalAddress; // physical base for memory manager - PULONG m_Base; // EHCI operational port base registers - PDMA_ADAPTER m_Adapter; // dma adapter object - ULONG m_MapRegisters; // map registers count - EHCI_CAPS m_Capabilities; // EHCI caps - USHORT m_VendorID; // vendor id - USHORT m_DeviceID; // device id - PQUEUE_HEAD AsyncQueueHead; // async queue head terminator - PEHCIQUEUE m_UsbQueue; // usb request queue - PDMAMEMORYMANAGER m_MemoryManager; // memory manager - HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine - PVOID m_SCEContext; // status change callback routine context - BOOLEAN m_DoorBellRingInProgress; // door bell ring in progress - WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback - volatile LONG m_StatusChangeWorkItemStatus; // work item status - ULONG m_SyncFramePhysAddr; // periodic frame list physical address - BUS_INTERFACE_STANDARD m_BusInterface; // pci bus interface - BOOLEAN m_PortResetInProgress[0xF]; // stores reset in progress (vbox hack) - - // read register - ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset); - - // write register - VOID EHCI_WRITE_REGISTER_ULONG(ULONG Offset, ULONG Value); -}; - -//================================================================================================= -// COM -// -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - if (IsEqualGUIDAligned(refiid, IID_IUnknown)) - { - *Output = PVOID(PUNKNOWN(this)); - PUNKNOWN(*Output)->AddRef(); - return STATUS_SUCCESS; - } - - return STATUS_UNSUCCESSFUL; -} - -LPCSTR -STDMETHODCALLTYPE -CUSBHardwareDevice::GetUSBType() -{ - return "USBEHCI"; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::Initialize( - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT FunctionalDeviceObject, - PDEVICE_OBJECT PhysicalDeviceObject, - PDEVICE_OBJECT LowerDeviceObject) -{ - PCI_COMMON_CONFIG PciConfig; - NTSTATUS Status; - ULONG BytesRead; - - DPRINT("CUSBHardwareDevice::Initialize\n"); - - // - // Create DMAMemoryManager for use with QueueHeads and Transfer Descriptors. - // - Status = CreateDMAMemoryManager(&m_MemoryManager); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create DMAMemoryManager Object\n"); - return Status; - } - - // - // Create the UsbQueue class that will handle the Asynchronous and Periodic Schedules - // - Status = CreateUSBQueue((PUSBQUEUE*)&m_UsbQueue); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create UsbQueue!\n"); - return Status; - } - - // - // store device objects - // - m_DriverObject = DriverObject; - m_FunctionalDeviceObject = FunctionalDeviceObject; - m_PhysicalDeviceObject = PhysicalDeviceObject; - m_NextDeviceObject = LowerDeviceObject; - - // - // initialize device lock - // - KeInitializeSpinLock(&m_Lock); - - // - // initialize status change work item - // - ExInitializeWorkItem(&m_StatusChangeWorkItem, StatusChangeWorkItemRoutine, PVOID(this)); - - m_VendorID = 0; - m_DeviceID = 0; - - Status = GetBusInterface(PhysicalDeviceObject, &m_BusInterface); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get BusInterface!\n"); - return Status; - } - - BytesRead = (*m_BusInterface.GetBusData)(m_BusInterface.Context, - PCI_WHICHSPACE_CONFIG, - &PciConfig, - 0, - PCI_COMMON_HDR_LENGTH); - - if (BytesRead != PCI_COMMON_HDR_LENGTH) - { - DPRINT1("Failed to get pci config information!\n"); - return STATUS_SUCCESS; - } - - m_VendorID = PciConfig.VendorID; - m_DeviceID = PciConfig.DeviceID; - - return STATUS_SUCCESS; -} - -VOID -STDMETHODCALLTYPE -CUSBHardwareDevice::SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd) -{ - PULONG Register; - Register = (PULONG)UsbCmd; - WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + EHCI_USBCMD), *Register); -} - -VOID -STDMETHODCALLTYPE -CUSBHardwareDevice::GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd) -{ - PULONG Register; - Register = (PULONG)UsbCmd; - *Register = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + EHCI_USBCMD)); -} - -ULONG -CUSBHardwareDevice::EHCI_READ_REGISTER_ULONG(ULONG Offset) -{ - return READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + Offset)); -} - -VOID -CUSBHardwareDevice::EHCI_WRITE_REGISTER_ULONG(ULONG Offset, ULONG Value) -{ - WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + Offset), Value); -} - -VOID -CUSBHardwareDevice::PrintCapabilities() -{ - if (m_Capabilities.HCSParams.PortPowerControl) - { - DPRINT1("Controller EHCI has Port Power Control\n"); - } - - DPRINT1("Controller Port Routing Rules %lu\n", m_Capabilities.HCSParams.PortRouteRules); - DPRINT1("Number of Ports per Companion Controller %lu\n", m_Capabilities.HCSParams.PortPerCHC); - DPRINT1("Number of Companion Controller %lu\n", m_Capabilities.HCSParams.CHCCount); - - if (m_Capabilities.HCSParams.PortIndicator) - { - DPRINT1("Controller has Port Indicators Support\n"); - } - - if (m_Capabilities.HCSParams.DbgPortNum) - { - DPRINT1("Controller has Debug Port Support At Port %x\n", m_Capabilities.HCSParams.DbgPortNum); - } - - if (m_Capabilities.HCCParams.EECPCapable) - { - DPRINT1("Controller has Extended Capabilities Support\n"); - } - - if (m_Capabilities.HCCParams.ParkMode) - { - DPRINT1("Controller supports Asynchronous Schedule Park\n"); - } - - if (m_Capabilities.HCCParams.VarFrameList) - { - DPRINT1("Controller supports Programmable Frame List Size\n"); - } - - if (m_Capabilities.HCCParams.CurAddrBits) - { - DPRINT1("Controller uses 64-Bit Addressing\n"); - } -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::PnpStart( - PCM_RESOURCE_LIST RawResources, - PCM_RESOURCE_LIST TranslatedResources) -{ - ULONG Index, Count; - PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; - DEVICE_DESCRIPTION DeviceDescription; - PHYSICAL_ADDRESS AsyncPhysicalAddress; - PVOID ResourceBase; - NTSTATUS Status; - UCHAR Value; - UCHAR PortCount; - - DPRINT("CUSBHardwareDevice::PnpStart\n"); - for(Index = 0; Index < TranslatedResources->List[0].PartialResourceList.Count; Index++) - { - // - // get resource descriptor - // - ResourceDescriptor = &TranslatedResources->List[0].PartialResourceList.PartialDescriptors[Index]; - - switch(ResourceDescriptor->Type) - { - case CmResourceTypeInterrupt: - { - KeInitializeDpc(&m_IntDpcObject, - EhciDeferredRoutine, - this); - - Status = IoConnectInterrupt(&m_Interrupt, - InterruptServiceRoutine, - (PVOID)this, - NULL, - ResourceDescriptor->u.Interrupt.Vector, - (KIRQL)ResourceDescriptor->u.Interrupt.Level, - (KIRQL)ResourceDescriptor->u.Interrupt.Level, - (KINTERRUPT_MODE)(ResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED), - (ResourceDescriptor->ShareDisposition != CmResourceShareDeviceExclusive), - ResourceDescriptor->u.Interrupt.Affinity, - FALSE); - - if (!NT_SUCCESS(Status)) - { - // - // failed to register interrupt - // - DPRINT1("IoConnect Interrupt failed with %x\n", Status); - return Status; - } - break; - } - case CmResourceTypeMemory: - { - // - // get resource base - // - ResourceBase = MmMapIoSpace(ResourceDescriptor->u.Memory.Start, ResourceDescriptor->u.Memory.Length, MmNonCached); - if (!ResourceBase) - { - // - // failed to map registers - // - DPRINT1("MmMapIoSpace failed\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // Get controllers capabilities - // - m_Capabilities.Length = READ_REGISTER_UCHAR((PUCHAR)ResourceBase + EHCI_CAPLENGTH); - m_Capabilities.HCIVersion = READ_REGISTER_USHORT((PUSHORT)((ULONG_PTR)ResourceBase + EHCI_HCIVERSION)); - m_Capabilities.HCSParamsLong = READ_REGISTER_ULONG((PULONG)((ULONG_PTR)ResourceBase + EHCI_HCSPARAMS)); - m_Capabilities.HCCParamsLong = READ_REGISTER_ULONG((PULONG)((ULONG_PTR)ResourceBase + EHCI_HCCPARAMS)); - - DPRINT1("Controller Capabilities Length 0x%x\n", m_Capabilities.Length); - DPRINT1("Controller EHCI Version 0x%x\n", m_Capabilities.HCIVersion); - DPRINT1("Controller EHCI Caps HCSParamsLong 0x%lx\n", m_Capabilities.HCSParamsLong); - DPRINT1("Controller EHCI Caps HCCParamsLong 0x%lx\n", m_Capabilities.HCCParamsLong); - DPRINT1("Controller has %lu Ports\n", m_Capabilities.HCSParams.PortCount); - - // - // print capabilities - // - PrintCapabilities(); - - if (m_Capabilities.HCSParams.PortRouteRules) - { - Count = 0; - PortCount = max(m_Capabilities.HCSParams.PortCount/2, (m_Capabilities.HCSParams.PortCount+1)/2); - do - { - // - // each entry is a 4 bit field EHCI 2.2.5 - // - Value = READ_REGISTER_UCHAR((PUCHAR)(ULONG_PTR)ResourceBase + EHCI_HCSP_PORTROUTE + Count); - m_Capabilities.PortRoute[Count*2] = (Value & 0xF0); - - if ((Count*2) + 1 < m_Capabilities.HCSParams.PortCount) - m_Capabilities.PortRoute[(Count*2)+1] = (Value & 0x0F); - - Count++; - } while(Count < PortCount); - } - - // - // Set m_Base to the address of Operational Register Space - // - m_Base = (PULONG)((ULONG_PTR)ResourceBase + m_Capabilities.Length); - break; - } - } - } - - - // - // zero device description - // - RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); - - // - // initialize device description - // - DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; - DeviceDescription.Master = TRUE; - DeviceDescription.ScatterGather = TRUE; - DeviceDescription.Dma32BitAddresses = TRUE; - DeviceDescription.DmaWidth = Width32Bits; - DeviceDescription.InterfaceType = PCIBus; - DeviceDescription.MaximumLength = MAXULONG; - - // - // get dma adapter - // - m_Adapter = IoGetDmaAdapter(m_PhysicalDeviceObject, &DeviceDescription, &m_MapRegisters); - if (!m_Adapter) - { - // - // failed to get dma adapter - // - DPRINT1("Failed to acquire dma adapter\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // Create Common Buffer - // - VirtualBase = m_Adapter->DmaOperations->AllocateCommonBuffer(m_Adapter, - PAGE_SIZE * 4, - &PhysicalAddress, - FALSE); - if (!VirtualBase) - { - DPRINT1("Failed to allocate a common buffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // Initialize the DMAMemoryManager - // - Status = m_MemoryManager->Initialize(this, &m_Lock, PAGE_SIZE * 4, VirtualBase, PhysicalAddress, 32); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to initialize the DMAMemoryManager\n"); - return Status; - } - - // - // Create a queuehead for the Async Register - // - m_MemoryManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&AsyncQueueHead, &AsyncPhysicalAddress); - - AsyncQueueHead->PhysicalAddr = AsyncPhysicalAddress.LowPart; - AsyncQueueHead->HorizontalLinkPointer = AsyncQueueHead->PhysicalAddr | QH_TYPE_QH; - AsyncQueueHead->EndPointCharacteristics.HeadOfReclamation = TRUE; - AsyncQueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED; - AsyncQueueHead->Token.Bits.Halted = TRUE; - - AsyncQueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01; - AsyncQueueHead->NextPointer = TERMINATE_POINTER; - AsyncQueueHead->CurrentLinkPointer = TERMINATE_POINTER; - - InitializeListHead(&AsyncQueueHead->LinkedQueueHeads); - - // - // Initialize the UsbQueue now that we have an AdapterObject. - // - Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, m_MemoryManager, &m_Lock); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to Initialize the UsbQueue\n"); - return Status; - } - - // - // Start the controller - // - DPRINT1("Starting Controller\n"); - Status = StartController(); - - // - // done - // - return Status; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::PnpStop(void) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::GetDeviceDetails( - OUT OPTIONAL PUSHORT VendorId, - OUT OPTIONAL PUSHORT DeviceId, - OUT OPTIONAL PULONG NumberOfPorts, - OUT OPTIONAL PULONG Speed) -{ - if (VendorId) - *VendorId = m_VendorID; - if (DeviceId) - *DeviceId = m_DeviceID; - if (NumberOfPorts) - *NumberOfPorts = m_Capabilities.HCSParams.PortCount; - //FIXME: What to returned here? - if (Speed) - *Speed = 0x200; - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::GetDMA( - OUT struct IDMAMemoryManager **OutDMAMemoryManager) -{ - if (!m_MemoryManager) - return STATUS_UNSUCCESSFUL; - *OutDMAMemoryManager = m_MemoryManager; - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::GetUSBQueue( - OUT struct IUSBQueue **OutUsbQueue) -{ - if (!m_UsbQueue) - return STATUS_UNSUCCESSFUL; - *OutUsbQueue = m_UsbQueue; - return STATUS_SUCCESS; -} - - -NTSTATUS -CUSBHardwareDevice::StartController(void) -{ - EHCI_USBCMD_CONTENT UsbCmd; - ULONG UsbSts, FailSafe, ExtendedCapsSupport, Caps, Index; - UCHAR Value; - LARGE_INTEGER Timeout; - - // - // are extended caps supported - // - ExtendedCapsSupport = (m_Capabilities.HCCParamsLong >> EHCI_ECP_SHIFT) & EHCI_ECP_MASK; - if (ExtendedCapsSupport) - { - DPRINT1("[EHCI] Extended Caps Support detected!\n"); - - // - // sanity check - // - ASSERT(ExtendedCapsSupport >= PCI_COMMON_HDR_LENGTH); - m_BusInterface.GetBusData(m_BusInterface.Context, PCI_WHICHSPACE_CONFIG, &Caps, ExtendedCapsSupport, sizeof(ULONG)); - - // - // OS Handoff Synchronization support capability. EHCI 5.1 - // - if ((Caps & EHCI_LEGSUP_CAPID_MASK) == EHCI_LEGSUP_CAPID) - { - // - // is it bios owned - // - if ((Caps & EHCI_LEGSUP_BIOSOWNED)) - { - DPRINT1("[EHCI] Controller is BIOS owned, acquiring control\n"); - - // - // acquire ownership - // - Value = 1; - m_BusInterface.SetBusData(m_BusInterface.Context, PCI_WHICHSPACE_CONFIG, &Value, ExtendedCapsSupport+3, sizeof(UCHAR)); - - for(Index = 0; Index < 20; Index++) - { - // - // get status - // - m_BusInterface.GetBusData(m_BusInterface.Context, PCI_WHICHSPACE_CONFIG, &Caps, ExtendedCapsSupport, sizeof(ULONG)); - if ((Caps & EHCI_LEGSUP_BIOSOWNED)) - { - // - // lets wait a bit - // - Timeout.QuadPart = 50; - DPRINT1("Waiting %lu milliseconds for port reset\n", Timeout.LowPart); - - // - // convert to 100 ns units (absolute) - // - Timeout.QuadPart *= -10000; - - // - // perform the wait - // - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - } - } - if ((Caps & EHCI_LEGSUP_BIOSOWNED)) - { - // - // failed to acquire ownership - // - DPRINT1("[EHCI] failed to acquire ownership\n"); - } - else if ((Caps & EHCI_LEGSUP_OSOWNED)) - { - // - // HC OS Owned Semaphore EHCI 2.1.7 - // - DPRINT1("[EHCI] acquired ownership\n"); - } -#if 0 - // - // explicitly clear the bios owned flag 2.1.7 - // - Value = 0; - m_BusInterface.SetBusData(m_BusInterface.Context, PCI_WHICHSPACE_CONFIG, &Value, ExtendedCapsSupport+2, sizeof(UCHAR)); - - // - // clear SMI interrupt EHCI 2.1.8 - // - Caps = 4; - m_BusInterface.SetBusData(m_BusInterface.Context, PCI_WHICHSPACE_CONFIG, &Caps, ExtendedCapsSupport+4, sizeof(ULONG)); -#endif - } - } - } - - // - // get command register - // - GetCommandRegister(&UsbCmd); - - // - // disable running schedules - // - UsbCmd.PeriodicEnable = FALSE; - UsbCmd.AsyncEnable = FALSE; - SetCommandRegister(&UsbCmd); - - // - // Wait for execution to start - // - for (FailSafe = 100; FailSafe > 1; FailSafe--) - { - KeStallExecutionProcessor(100); - UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); - - if (!(UsbSts & EHCI_STS_PSS) && (UsbSts & EHCI_STS_ASS)) - { - break; - } - } - - if ((UsbSts & (EHCI_STS_PSS | EHCI_STS_ASS))) - { - DPRINT1("Failed to stop running schedules %x\n", UsbSts); - //ASSERT(FALSE); - } - - - // - // Stop the controller if its running - // - UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); - if (!(UsbSts & EHCI_STS_HALT)) - { - DPRINT1("Stopping Controller %x\n", UsbSts); - StopController(); - } - - // - // Reset the controller - // - ResetController(); - - // - // check caps - // - if (m_Capabilities.HCCParams.CurAddrBits) - { - // - // disable 64-bit addressing - // - EHCI_WRITE_REGISTER_ULONG(EHCI_CTRLDSSEGMENT, 0x0); - } - - // - // Enable Interrupts and start execution - // - ULONG Mask = EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR | EHCI_USBINTR_PC; - EHCI_WRITE_REGISTER_ULONG(EHCI_USBINTR, Mask); - - KeStallExecutionProcessor(10); - - ULONG Status = EHCI_READ_REGISTER_ULONG(EHCI_USBINTR); - - DPRINT1("Interrupt Mask %x\n", Status); - ASSERT((Status & Mask) == Mask); - - // - // Assign the SyncList Register - // - EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, m_SyncFramePhysAddr); - - // - // Set Schedules to Enable and Interrupt Threshold to 1ms. - // - RtlZeroMemory(&UsbCmd, sizeof(EHCI_USBCMD_CONTENT)); - - UsbCmd.PeriodicEnable = TRUE; - UsbCmd.IntThreshold = 0x8; //1ms - UsbCmd.Run = TRUE; - UsbCmd.FrameListSize = 0x0; //1024 - - if (m_Capabilities.HCCParams.ParkMode) - { - // - // enable async park mode - // - UsbCmd.AsyncParkEnable = TRUE; - UsbCmd.AsyncParkCount = 3; - } - - SetCommandRegister(&UsbCmd); - - - // - // Wait for execution to start - // - for (FailSafe = 100; FailSafe > 1; FailSafe--) - { - KeStallExecutionProcessor(100); - UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); - - if (!(UsbSts & EHCI_STS_HALT) && (UsbSts & EHCI_STS_PSS)) - { - break; - } - } - - if (UsbSts & EHCI_STS_HALT) - { - DPRINT1("Could not start execution on the controller\n"); - //ASSERT(FALSE); - return STATUS_UNSUCCESSFUL; - } - - if (!(UsbSts & EHCI_STS_PSS)) - { - DPRINT1("Could not enable periodic scheduling\n"); - //ASSERT(FALSE); - return STATUS_UNSUCCESSFUL; - } - - // - // Assign the AsyncList Register - // - EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, AsyncQueueHead->PhysicalAddr); - - // - // get command register - // - GetCommandRegister(&UsbCmd); - - // - // preserve bits - // - UsbCmd.AsyncEnable = TRUE; - - // - // enable async - // - SetCommandRegister(&UsbCmd); - - // - // Wait for execution to start - // - for (FailSafe = 100; FailSafe > 1; FailSafe--) - { - KeStallExecutionProcessor(100); - UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); - - if ((UsbSts & EHCI_STS_ASS)) - { - break; - } - } - - if (!(UsbSts & EHCI_STS_ASS)) - { - DPRINT1("Failed to enable async schedule UsbSts %x\n", UsbSts); - //ASSERT(FALSE); - return STATUS_UNSUCCESSFUL; - } - - DPRINT1("UsbSts %x\n", UsbSts); - GetCommandRegister(&UsbCmd); - - DPRINT1("UsbCmd.PeriodicEnable %x\n", UsbCmd.PeriodicEnable); - DPRINT1("UsbCmd.AsyncEnable %x\n", UsbCmd.AsyncEnable); - DPRINT1("UsbCmd.IntThreshold %x\n", UsbCmd.IntThreshold); - DPRINT1("UsbCmd.Run %x\n", UsbCmd.Run); - DPRINT1("UsbCmd.FrameListSize %x\n", UsbCmd.FrameListSize); - - // - // Set port routing to EHCI controller - // - EHCI_WRITE_REGISTER_ULONG(EHCI_CONFIGFLAG, 1); - - DPRINT1("EHCI Started!\n"); - return STATUS_SUCCESS; -} - -NTSTATUS -CUSBHardwareDevice::StopController(void) -{ - EHCI_USBCMD_CONTENT UsbCmd; - ULONG UsbSts, FailSafe; - - // - // Disable Interrupts and stop execution - // - EHCI_WRITE_REGISTER_ULONG (EHCI_USBINTR, 0); - - GetCommandRegister(&UsbCmd); - UsbCmd.Run = FALSE; - SetCommandRegister(&UsbCmd); - - for (FailSafe = 100; FailSafe > 1; FailSafe--) - { - KeStallExecutionProcessor(10); - UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); - if (UsbSts & EHCI_STS_HALT) - { - break; - } - } - - if (!(UsbSts & EHCI_STS_HALT)) - { - DPRINT1("EHCI ERROR: Controller is not responding to Stop request!\n"); - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; -} - -NTSTATUS -CUSBHardwareDevice::ResetController(void) -{ - EHCI_USBCMD_CONTENT UsbCmd; - ULONG FailSafe; - - GetCommandRegister(&UsbCmd); - UsbCmd.HCReset = TRUE; - SetCommandRegister(&UsbCmd); - - for (FailSafe = 100; FailSafe > 1; FailSafe--) - { - KeStallExecutionProcessor(100); - GetCommandRegister(&UsbCmd); - if (!UsbCmd.HCReset) - break; - } - - if (UsbCmd.HCReset) - { - DPRINT1("EHCI ERROR: Controller is not responding to reset request!\n"); - return STATUS_UNSUCCESSFUL; - } - - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::ResetPort( - IN ULONG PortIndex) -{ - ULONG PortStatus; - LARGE_INTEGER Timeout; - - if (PortIndex > m_Capabilities.HCSParams.PortCount) - return STATUS_UNSUCCESSFUL; - - PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex)); - - ASSERT(!EHCI_IS_LOW_SPEED(PortStatus)); - ASSERT(PortStatus & EHCI_PRT_CONNECTED); - - // - // Reset and clean enable - // - PortStatus |= EHCI_PRT_RESET; - PortStatus &= EHCI_PORTSC_DATAMASK; - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus); - - // - // delay is 50 ms for port reset as per USB 2.0 spec - // - Timeout.QuadPart = 50; - DPRINT1("Waiting %lu milliseconds for port reset\n", Timeout.LowPart); - - // - // convert to 100 ns units (absolute) - // - Timeout.QuadPart *= -10000; - - // - // perform the wait - // - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::GetPortStatus( - ULONG PortId, - OUT USHORT *PortStatus, - OUT USHORT *PortChange) -{ - ULONG Value; - USHORT Status = 0, Change = 0; - - if (PortId > m_Capabilities.HCSParams.PortCount) - return STATUS_UNSUCCESSFUL; - - // - // Get the value of the Port Status and Control Register - // - Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)); - - // - // If the PowerPortControl is 0 then host controller does not have power control switches - if (!m_Capabilities.HCSParams.PortPowerControl) - { - Status |= USB_PORT_STATUS_POWER; - } - else - { - // Check the value of PortPower - if (Value & EHCI_PRT_POWER) - { - Status |= USB_PORT_STATUS_POWER; - } - } - - // Get Connected Status - if (Value & EHCI_PRT_CONNECTED) - { - Status |= USB_PORT_STATUS_CONNECT; - - // EHCI only supports high speed - Status |= USB_PORT_STATUS_HIGH_SPEED; - } - - // Get Enabled Status - if (Value & EHCI_PRT_ENABLED) - Status |= USB_PORT_STATUS_ENABLE; - - // Is it suspended? - if (Value & EHCI_PRT_SUSPEND) - Status |= USB_PORT_STATUS_SUSPEND; - - // a overcurrent is active? - if (Value & EHCI_PRT_OVERCURRENTACTIVE) - Status |= USB_PORT_STATUS_OVER_CURRENT; - - // In a reset state? - if ((Value & EHCI_PRT_RESET) || m_PortResetInProgress[PortId]) - { - Status |= USB_PORT_STATUS_RESET; - Change |= USB_PORT_STATUS_RESET; - } - - // This indicates a connect or disconnect - if (Value & EHCI_PRT_CONNECTSTATUSCHANGE) - Change |= USB_PORT_STATUS_CONNECT; - - // This is set to indicate a critical port error - if (Value & EHCI_PRT_ENABLEDSTATUSCHANGE) - Change |= USB_PORT_STATUS_ENABLE; - - *PortStatus = Status; - *PortChange = Change; - - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::ClearPortStatus( - ULONG PortId, - ULONG Status) -{ - ULONG Value; - LARGE_INTEGER Timeout; - - DPRINT("CUSBHardwareDevice::ClearPortStatus PortId %x Feature %x\n", PortId, Status); - - if (PortId > m_Capabilities.HCSParams.PortCount) - return STATUS_UNSUCCESSFUL; - - if (Status == C_PORT_RESET) - { - // reset done - m_PortResetInProgress[PortId] = FALSE; - - // Clear reset - Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)); - Value &= (EHCI_PORTSC_DATAMASK | EHCI_PRT_ENABLED); - Value &= ~EHCI_PRT_RESET; - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value); - - // - // wait for reset bit to clear - // - do - { - Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)); - - if (!(Value & EHCI_PRT_RESET)) - break; - - KeStallExecutionProcessor(20); - } while (TRUE); - - // - // delay is 50 ms - // - Timeout.QuadPart = 50; - DPRINT1("Waiting %lu milliseconds for port to recover after reset\n", Timeout.LowPart); - - // - // convert to 100 ns units (absolute) - // - Timeout.QuadPart *= -10000; - - // - // perform the wait - // - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - - // - // check the port status after reset - // - Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)); - if (!(Value & EHCI_PRT_CONNECTED)) - { - DPRINT1("No device is here after reset. Bad controller/device?\n"); - return STATUS_UNSUCCESSFUL; - } - else if (EHCI_IS_LOW_SPEED(Value)) - { - DPRINT1("Low speed device connected. Releasing ownership\n"); - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value | EHCI_PRT_RELEASEOWNERSHIP); - return STATUS_DEVICE_NOT_CONNECTED; - } - else if (!(Value & EHCI_PRT_ENABLED)) - { - DPRINT1("Full speed device connected. Releasing ownership\n"); - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value | EHCI_PRT_RELEASEOWNERSHIP); - return STATUS_DEVICE_NOT_CONNECTED; - } - else - { - DPRINT1("High speed device connected\n"); - return STATUS_SUCCESS; - } - } - else if (Status == C_PORT_CONNECTION) - { - // - // reset status change bits - // - Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)); - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value); - - if (Value & EHCI_PRT_CONNECTED) - { - // - // delay is 100 ms - // - Timeout.QuadPart = 100; - DPRINT1("Waiting %lu milliseconds for port to stabilize after connection\n", Timeout.LowPart); - - // - // convert to 100 ns units (absolute) - // - Timeout.QuadPart *= -10000; - - // - // perform the wait - // - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - } - } - - return STATUS_SUCCESS; -} - - -NTSTATUS -STDMETHODCALLTYPE -CUSBHardwareDevice::SetPortFeature( - ULONG PortId, - ULONG Feature) -{ - DPRINT("CUSBHardwareDevice::SetPortFeature\n"); - - if (PortId > m_Capabilities.HCSParams.PortCount) - return STATUS_UNSUCCESSFUL; - - if (Feature == PORT_ENABLE) - { - // - // FIXME: EHCI Ports can only be disabled via reset - // - DPRINT1("PORT_ENABLE not supported for EHCI\n"); - } - - if (Feature == PORT_RESET) - { - // - // call the helper - // - ResetPort(PortId); - - // reset in progress - m_PortResetInProgress[PortId] = TRUE; - - // - // is there a status change callback - // - if (m_SCECallBack != NULL) - { - // - // issue callback - // - m_SCECallBack(m_SCEContext); - } - } - - if (Feature == PORT_POWER) - { - if (m_Capabilities.HCSParams.PortPowerControl) - { - ULONG Value; - LARGE_INTEGER Timeout; - - // - // enable port power - // - Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)) | EHCI_PRT_POWER; - EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value); - - // - // delay is 20 ms - // - Timeout.QuadPart = 20; - DPRINT1("Waiting %lu milliseconds for port power up\n", Timeout.LowPart); - - // - // convert to 100 ns units (absolute) - // - Timeout.QuadPart *= -10000; - - // - // perform the wait - // - KeDelayExecutionThread(KernelMode, FALSE, &Timeout); - } - } - return STATUS_SUCCESS; -} - -VOID -STDMETHODCALLTYPE -CUSBHardwareDevice::SetAsyncListRegister( - ULONG PhysicalAddress) -{ - EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, PhysicalAddress); -} - -VOID -STDMETHODCALLTYPE -CUSBHardwareDevice::SetPeriodicListRegister( - ULONG PhysicalAddress) -{ - // - // store physical address - // - m_SyncFramePhysAddr = PhysicalAddress; -} - -struct _QUEUE_HEAD * -STDMETHODCALLTYPE -CUSBHardwareDevice::GetAsyncListQueueHead() -{ - return AsyncQueueHead; -} - -ULONG -STDMETHODCALLTYPE -CUSBHardwareDevice::GetPeriodicListRegister() -{ - UNIMPLEMENTED; - return NULL; -} - -VOID -STDMETHODCALLTYPE -CUSBHardwareDevice::SetStatusChangeEndpointCallBack( - PVOID CallBack, - PVOID Context) -{ - m_SCECallBack = (HD_INIT_CALLBACK*)CallBack; - m_SCEContext = Context; -} - -BOOLEAN -NTAPI -InterruptServiceRoutine( - IN PKINTERRUPT Interrupt, - IN PVOID ServiceContext) -{ - CUSBHardwareDevice *This; - ULONG CStatus; - - This = (CUSBHardwareDevice*) ServiceContext; - CStatus = This->EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); - - CStatus &= (EHCI_ERROR_INT | EHCI_STS_INT | EHCI_STS_IAA | EHCI_STS_PCD | EHCI_STS_FLR); - DPRINT("InterruptServiceRoutine CStatus %lx\n", CStatus); - - // - // Check that it belongs to EHCI - // - if (!CStatus) - return FALSE; - - // - // Clear the Status - // - This->EHCI_WRITE_REGISTER_ULONG(EHCI_USBSTS, CStatus); - - if (CStatus & EHCI_STS_FATAL) - { - This->StopController(); - DPRINT1("EHCI: Host System Error!\n"); - return TRUE; - } - - if (CStatus & EHCI_ERROR_INT) - { - DPRINT1("EHCI Status = 0x%x\n", CStatus); - } - - if (CStatus & EHCI_STS_HALT) - { - DPRINT1("Host Error Unexpected Halt\n"); - // FIXME: Reset controller\n"); - return TRUE; - } - - KeInsertQueueDpc(&This->m_IntDpcObject, This, UlongToPtr(CStatus)); - return TRUE; -} - -VOID NTAPI -EhciDeferredRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - CUSBHardwareDevice *This; - ULONG CStatus, PortStatus, PortCount, i, ShouldRingDoorBell, QueueSCEWorkItem; - NTSTATUS Status = STATUS_SUCCESS; - EHCI_USBCMD_CONTENT UsbCmd; - - This = (CUSBHardwareDevice*) SystemArgument1; - CStatus = PtrToUlong(SystemArgument2); - - DPRINT("EhciDeferredRoutine CStatus %lx\n", CStatus); - - // - // check for completion of async schedule - // - if (CStatus & (EHCI_STS_RECL| EHCI_STS_INT | EHCI_ERROR_INT)) - { - // - // check if there is a door bell ring in progress - // - if (This->m_DoorBellRingInProgress == FALSE) - { - if (CStatus & EHCI_ERROR_INT) - { - // - // controller reported error - // - DPRINT1("CStatus %lx\n", CStatus); - //ASSERT(FALSE); - } - - // - // inform IUSBQueue of a completed queue head - // - This->m_UsbQueue->InterruptCallback(Status, &ShouldRingDoorBell); - - // - // was a queue head completed? - // - if (ShouldRingDoorBell) - { - // - // set door ring bell in progress status flag - // - This->m_DoorBellRingInProgress = TRUE; - - // - // get command register - // - This->GetCommandRegister(&UsbCmd); - - // - // set door rang bell bit - // - UsbCmd.DoorBell = TRUE; - - // - // update command status - // - This->SetCommandRegister(&UsbCmd); - } - } - } - - // - // check if the controller has acknowledged the door bell - // - if (CStatus & EHCI_STS_IAA) - { - // - // controller has acknowledged, assert we rang the bell - // - PC_ASSERT(This->m_DoorBellRingInProgress == TRUE); - - // - // now notify IUSBQueue that it can free completed requests - // - This->m_UsbQueue->CompleteAsyncRequests(); - - // - // door ring bell completed - // - This->m_DoorBellRingInProgress = FALSE; - } - - This->GetDeviceDetails(NULL, NULL, &PortCount, NULL); - if (CStatus & EHCI_STS_PCD) - { - QueueSCEWorkItem = FALSE; - for (i = 0; i < PortCount; i++) - { - PortStatus = This->EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * i)); - - // - // Device connected or removed - // - if (PortStatus & EHCI_PRT_CONNECTSTATUSCHANGE) - { - if (PortStatus & EHCI_PRT_CONNECTED) - { - DPRINT1("Device connected on port %lu\n", i); - - if (This->m_Capabilities.HCSParams.CHCCount) - { - if (PortStatus & EHCI_PRT_ENABLED) - { - DPRINT1("Misbehaving controller. Port should be disabled at this point\n"); - } - - if (EHCI_IS_LOW_SPEED(PortStatus)) - { - DPRINT1("Low speed device connected. Releasing ownership\n"); - This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus | EHCI_PRT_RELEASEOWNERSHIP); - continue; - } - } - - // - // work to do - // - QueueSCEWorkItem = TRUE; - } - else - { - DPRINT1("Device disconnected on port %lu\n", i); - - // - // work to do - // - QueueSCEWorkItem = TRUE; - } - } - } - - // - // is there a status change callback and a high speed device connected / disconnected - // - if (QueueSCEWorkItem && This->m_SCECallBack != NULL) - { - if (InterlockedCompareExchange(&This->m_StatusChangeWorkItemStatus, 1, 0) == 0) - { - // - // queue work item for processing - // - ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue); - } - } - } - return; -} - -VOID -NTAPI -StatusChangeWorkItemRoutine( - PVOID Context) -{ - // - // cast to hardware object - // - CUSBHardwareDevice * This = (CUSBHardwareDevice*)Context; - - // - // is there a callback - // - if (This->m_SCECallBack) - { - // - // issue callback - // - This->m_SCECallBack(This->m_SCEContext); - } - - // - // reset active status - // - InterlockedDecrement(&This->m_StatusChangeWorkItemStatus); -} - -NTSTATUS -NTAPI -CreateUSBHardware( - PUSBHARDWAREDEVICE *OutHardware) -{ - PUSBHARDWAREDEVICE This; - - This = new(NonPagedPool, TAG_USBEHCI) CUSBHardwareDevice(0); - - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; - - This->AddRef(); - - // return result - *OutHardware = (PUSBHARDWAREDEVICE)This; - - return STATUS_SUCCESS; -} diff --git a/drivers/usb/usbehci/hardware.h b/drivers/usb/usbehci/hardware.h deleted file mode 100644 index b0ea4811be5..00000000000 --- a/drivers/usb/usbehci/hardware.h +++ /dev/null @@ -1,325 +0,0 @@ -#pragma once - -// -// Host Controller Capability Registers -// -#define EHCI_CAPLENGTH 0x00 -#define EHCI_HCIVERSION 0x02 -#define EHCI_HCSPARAMS 0x04 -#define EHCI_HCCPARAMS 0x08 -#define EHCI_HCSP_PORTROUTE 0x0c - - -// -// Extended Capabilities -// -#define EHCI_ECP_SHIFT 8 -#define EHCI_ECP_MASK 0xff -#define EHCI_LEGSUP_CAPID_MASK 0xff -#define EHCI_LEGSUP_CAPID 0x01 -#define EHCI_LEGSUP_OSOWNED (1 << 24) -#define EHCI_LEGSUP_BIOSOWNED (1 << 16) - - -// -// EHCI Operational Registers -// -#define EHCI_USBCMD 0x00 -#define EHCI_USBSTS 0x04 -#define EHCI_USBINTR 0x08 -#define EHCI_FRINDEX 0x0C -#define EHCI_CTRLDSSEGMENT 0x10 -#define EHCI_PERIODICLISTBASE 0x14 -#define EHCI_ASYNCLISTBASE 0x18 -#define EHCI_CONFIGFLAG 0x40 -#define EHCI_PORTSC 0x44 - -// -// Interrupt Register Flags -// -#define EHCI_USBINTR_INTE 0x01 -#define EHCI_USBINTR_ERR 0x02 -#define EHCI_USBINTR_PC 0x04 -#define EHCI_USBINTR_FLROVR 0x08 -#define EHCI_USBINTR_HSERR 0x10 -#define EHCI_USBINTR_ASYNC 0x20 -// Bits 6:31 Reserved - -// -// Status Register Flags -// -#define EHCI_STS_INT 0x01 -#define EHCI_STS_ERR 0x02 -#define EHCI_STS_PCD 0x04 -#define EHCI_STS_FLR 0x08 -#define EHCI_STS_FATAL 0x10 -#define EHCI_STS_IAA 0x20 -// Bits 11:6 Reserved -#define EHCI_STS_HALT 0x1000 -#define EHCI_STS_RECL 0x2000 -#define EHCI_STS_PSS 0x4000 -#define EHCI_STS_ASS 0x8000 -#define EHCI_ERROR_INT (EHCI_STS_FATAL | EHCI_STS_ERR) - -// -// Port Register Flags -// -#define EHCI_PRT_CONNECTED 0x01 -#define EHCI_PRT_CONNECTSTATUSCHANGE 0x02 -#define EHCI_PRT_ENABLED 0x04 -#define EHCI_PRT_ENABLEDSTATUSCHANGE 0x08 -#define EHCI_PRT_OVERCURRENTACTIVE 0x10 -#define EHCI_PRT_OVERCURRENTCHANGE 0x20 -#define EHCI_PRT_FORCERESUME 0x40 -#define EHCI_PRT_SUSPEND 0x80 -#define EHCI_PRT_RESET 0x100 -#define EHCI_PRT_LINESTATUSA 0x400 -#define EHCI_PRT_LINESTATUSB 0x800 -#define EHCI_PRT_POWER 0x1000 -#define EHCI_PRT_RELEASEOWNERSHIP 0x2000 - -#define EHCI_PORTSC_DATAMASK 0xffffffd1 - -#define EHCI_IS_LOW_SPEED(x) (((x) & EHCI_PRT_LINESTATUSA) && !((x) & EHCI_PRT_LINESTATUSB)) -// -// Terminate Pointer used for QueueHeads and Element Transfer Descriptors to mark Pointers as the end -// -#define TERMINATE_POINTER 0x01 - -// -// QUEUE ELEMENT TRANSFER DESCRIPTOR, defines and structs -// - -// -// Token Flags -// -#define PID_CODE_OUT_TOKEN 0x00 -#define PID_CODE_IN_TOKEN 0x01 -#define PID_CODE_SETUP_TOKEN 0x02 - -#define DO_START_SPLIT 0x00 -#define DO_COMPLETE_SPLIT 0x01 - -#define PING_STATE_DO_OUT 0x00 -#define PING_STATE_DO_PING 0x01 - -typedef struct _PERIODICFRAMELIST -{ - PULONG VirtualAddr; - PHYSICAL_ADDRESS PhysicalAddr; - ULONG Size; -} PERIODICFRAMELIST, *PPERIODICFRAMELIST; - -// -// QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN -// -typedef struct _QETD_TOKEN_BITS -{ - ULONG PingState:1; - ULONG SplitTransactionState:1; - ULONG MissedMicroFrame:1; - ULONG TransactionError:1; - ULONG BabbleDetected:1; - ULONG DataBufferError:1; - ULONG Halted:1; - ULONG Active:1; - ULONG PIDCode:2; - ULONG ErrorCounter:2; - ULONG CurrentPage:3; - ULONG InterruptOnComplete:1; - ULONG TotalBytesToTransfer:15; - ULONG DataToggle:1; -} QETD_TOKEN_BITS, *PQETD_TOKEN_BITS; - -// -// QUEUE ELEMENT TRANSFER DESCRIPTOR -// -typedef struct _QUEUE_TRANSFER_DESCRIPTOR -{ - //Hardware - ULONG NextPointer; - ULONG AlternateNextPointer; - union - { - QETD_TOKEN_BITS Bits; - ULONG DWord; - } Token; - ULONG BufferPointer[5]; - ULONG ExtendedBufferPointer[5]; - - //Software - ULONG PhysicalAddr; - LIST_ENTRY DescriptorEntry; - ULONG TotalBytesToTransfer; -} QUEUE_TRANSFER_DESCRIPTOR, *PQUEUE_TRANSFER_DESCRIPTOR; - -C_ASSERT(FIELD_OFFSET(QUEUE_TRANSFER_DESCRIPTOR, PhysicalAddr) == 0x34); - -// -// EndPointSpeeds Flags and END_POINT_CHARACTERISTICS -// -#define QH_ENDPOINT_FULLSPEED 0x00 -#define QH_ENDPOINT_LOWSPEED 0x01 -#define QH_ENDPOINT_HIGHSPEED 0x02 -typedef struct _END_POINT_CHARACTERISTICS -{ - ULONG DeviceAddress:7; - ULONG InactiveOnNextTransaction:1; - ULONG EndPointNumber:4; - ULONG EndPointSpeed:2; - ULONG QEDTDataToggleControl:1; - ULONG HeadOfReclamation:1; - ULONG MaximumPacketLength:11; - ULONG ControlEndPointFlag:1; - ULONG NakCountReload:4; -} END_POINT_CHARACTERISTICS, *PEND_POINT_CHARACTERISTICS; - -// -// Capabilities -// -typedef struct _END_POINT_CAPABILITIES -{ - ULONG InterruptScheduleMask:8; - ULONG SplitCompletionMask:8; - ULONG HubAddr:7; - ULONG PortNumber:7; - ULONG NumberOfTransactionPerFrame:2; -} END_POINT_CAPABILITIES, *PEND_POINT_CAPABILITIES; - -// -// QUEUE HEAD Flags and Struct -// -#define QH_TYPE_IDT 0x00 -#define QH_TYPE_QH 0x02 -#define QH_TYPE_SITD 0x04 -#define QH_TYPE_FSTN 0x06 - -typedef struct _QUEUE_HEAD -{ - //Hardware - ULONG HorizontalLinkPointer; - END_POINT_CHARACTERISTICS EndPointCharacteristics; - END_POINT_CAPABILITIES EndPointCapabilities; - // TERMINATE_POINTER not valid for this member - ULONG CurrentLinkPointer; - // TERMINATE_POINTER valid - ULONG NextPointer; - // TERMINATE_POINTER valid, bits 1:4 is NAK_COUNTERd - ULONG AlternateNextPointer; - // Only DataToggle, InterruptOnComplete, ErrorCounter, PingState valid - union - { - QETD_TOKEN_BITS Bits; - ULONG DWord; - } Token; - ULONG BufferPointer[5]; - ULONG ExtendedBufferPointer[5]; - - //Software - ULONG PhysicalAddr; - LIST_ENTRY LinkedQueueHeads; - LIST_ENTRY TransferDescriptorListHead; - PVOID NextQueueHead; - PVOID Request; -} QUEUE_HEAD, *PQUEUE_HEAD; - -C_ASSERT(sizeof(END_POINT_CHARACTERISTICS) == 4); -C_ASSERT(sizeof(END_POINT_CAPABILITIES) == 4); - -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, HorizontalLinkPointer) == 0x00); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, EndPointCharacteristics) == 0x04); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, EndPointCapabilities) == 0x08); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, CurrentLinkPointer) == 0xC); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, NextPointer) == 0x10); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, AlternateNextPointer) == 0x14); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, Token) == 0x18); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, BufferPointer) == 0x1C); -C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, PhysicalAddr) == 0x44); - - -// -// Command register content -// -typedef struct _EHCI_USBCMD_CONTENT -{ - ULONG Run : 1; - ULONG HCReset : 1; - ULONG FrameListSize : 2; - ULONG PeriodicEnable : 1; - ULONG AsyncEnable : 1; - ULONG DoorBell : 1; - ULONG LightReset : 1; - ULONG AsyncParkCount : 2; - ULONG Reserved : 1; - ULONG AsyncParkEnable : 1; - ULONG Reserved1 : 4; - ULONG IntThreshold : 8; - ULONG Reserved2 : 8; -} EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT; - -typedef struct _EHCI_HCS_CONTENT -{ - ULONG PortCount : 4; - ULONG PortPowerControl: 1; - ULONG Reserved : 2; - ULONG PortRouteRules : 1; - ULONG PortPerCHC : 4; - ULONG CHCCount : 4; - ULONG PortIndicator : 1; - ULONG Reserved2 : 3; - ULONG DbgPortNum : 4; - ULONG Reserved3 : 8; - -} EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT; - -typedef struct _EHCI_HCC_CONTENT -{ - ULONG CurAddrBits : 1; - ULONG VarFrameList : 1; - ULONG ParkMode : 1; - ULONG Reserved : 1; - ULONG IsoSchedThreshold : 4; - ULONG EECPCapable : 8; - ULONG Reserved2 : 16; - -} EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT; - -typedef struct _EHCI_CAPS { - UCHAR Length; - UCHAR Reserved; - USHORT HCIVersion; - union - { - EHCI_HCS_CONTENT HCSParams; - ULONG HCSParamsLong; - }; - union - { - EHCI_HCC_CONTENT HCCParams; - ULONG HCCParamsLong; - }; - UCHAR PortRoute [15]; -} EHCI_CAPS, *PEHCI_CAPS; - -typedef struct -{ - ULONG PortStatus; - ULONG PortChange; -}EHCI_PORT_STATUS; - -#define EHCI_INTERRUPT_ENTRIES_COUNT (10 + 1) -#define EHCI_VFRAMELIST_ENTRIES_COUNT 128 -#define EHCI_FRAMELIST_ENTRIES_COUNT 1024 - -#define MAX_AVAILABLE_BANDWIDTH 125 // Microseconds - -#define EHCI_QH_CAPS_MULT_SHIFT 30 // Transactions per Micro-Frame -#define EHCI_QH_CAPS_MULT_MASK 0x03 -#define EHCI_QH_CAPS_PORT_SHIFT 23 // Hub Port (Split-Transaction) -#define EHCI_QH_CAPS_PORT_MASK 0x7f -#define EHCI_QH_CAPS_HUB_SHIFT 16 // Hub Address (Split-Transaction) -#define EHCI_QH_CAPS_HUB_MASK 0x7f -#define EHCI_QH_CAPS_SCM_SHIFT 8 // Split Completion Mask -#define EHCI_QH_CAPS_SCM_MASK 0xff -#define EHCI_QH_CAPS_ISM_SHIFT 0 // Interrupt Schedule Mask -#define EHCI_QH_CAPS_ISM_MASK 0xff diff --git a/drivers/usb/usbehci/interfaces.h b/drivers/usb/usbehci/interfaces.h deleted file mode 100644 index 58160fa1475..00000000000 --- a/drivers/usb/usbehci/interfaces.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef INTERFACES_HPP -#define INTERFACES_HPP - -//========================================================================================= -// -// class IUSBHardwareDevice -// -// Description: This class provides access to the usb hardware controller -// - -#define DEFINE_ABSTRACT_USBEHCIHARDWARE() \ - STDMETHOD_(VOID, SetAsyncListRegister)( THIS_ \ - IN ULONG PhysicalAddress) PURE; \ - \ - STDMETHOD_(VOID, SetPeriodicListRegister)( THIS_ \ - IN ULONG PhysicalAddress) PURE; \ - \ - STDMETHOD_(struct _QUEUE_HEAD *, GetAsyncListQueueHead)( THIS) PURE; \ - \ - STDMETHOD_(ULONG, GetPeriodicListRegister)( THIS) PURE; \ - \ - STDMETHOD_(VOID, SetCommandRegister)( THIS_ \ - IN struct _EHCI_USBCMD_CONTENT *UsbCmd) PURE; \ - \ - STDMETHOD_(VOID, GetCommandRegister)( THIS_ \ - OUT struct _EHCI_USBCMD_CONTENT *UsbCmd) PURE; - -#define IMP_IUSBEHCIHARDWARE \ - STDMETHODIMP_(VOID) SetAsyncListRegister( \ - IN ULONG PhysicalAddress); \ - \ - STDMETHODIMP_(VOID) SetPeriodicListRegister( \ - IN ULONG PhysicalAddress); \ - \ - STDMETHODIMP_(struct _QUEUE_HEAD *) GetAsyncListQueueHead(); \ - \ - STDMETHODIMP_(ULONG) GetPeriodicListRegister(); \ - \ - STDMETHODIMP_(VOID) SetCommandRegister( \ - IN struct _EHCI_USBCMD_CONTENT *UsbCmd); \ - STDMETHODIMP_(VOID) GetCommandRegister( \ - OUT struct _EHCI_USBCMD_CONTENT *UsbCmd); - -DECLARE_INTERFACE_(IEHCIHardwareDevice, IUSBHardwareDevice) -{ - DEFINE_ABSTRACT_UNKNOWN() - DEFINE_ABSTRACT_USBHARDWAREDEVICE() - DEFINE_ABSTRACT_USBEHCIHARDWARE() -}; - -typedef IEHCIHardwareDevice *PEHCIHARDWAREDEVICE; - -//========================================================================================= -// -// class IUSBRequest -// -// Description: This class is used to issue request to usb controller. The class is -// initialized using InitializeXXX methods. You also need to call SetEndpoint to define the endpoint -// In addition you can call SetCompletionDetails if you need to wait for the end of -// the request or want to complete an irp. You call AddUSBRequest to add the request to the queue. -// Once the request is completed the CompletionCallback is invoked. The CompletionCallback -// will take care of any completion details which have been set. If the request is cancelled, the -// CancelCallback routine is invoked. -// - -struct _QUEUE_HEAD; -struct _USB_ENDPOINT; - -#define DEFINE_ABSTRACT_USBEHCIREQUEST() \ - STDMETHOD_(VOID, CompletionCallback)( THIS_ \ - IN NTSTATUS NtStatusCode, \ - IN ULONG UrbStatusCode, \ - IN struct _QUEUE_HEAD *QueueHead) PURE; \ - \ - STDMETHOD_(NTSTATUS, GetQueueHead)( THIS_ \ - IN struct _QUEUE_HEAD ** OutHead) PURE; \ - \ - STDMETHOD_(BOOLEAN, ShouldReleaseRequestAfterCompletion)( THIS) PURE; \ - \ - \ - STDMETHOD_(VOID, FreeQueueHead)( THIS_ \ - IN struct _QUEUE_HEAD * QueueHead) PURE; \ - \ - STDMETHOD_(BOOLEAN, IsQueueHeadComplete)( THIS_ \ - IN struct _QUEUE_HEAD * QueueHead) PURE; \ - \ - STDMETHOD_(USB_DEVICE_SPEED, GetSpeed)( THIS) PURE; \ - \ - STDMETHOD_(UCHAR, GetInterval)( THIS) PURE; - -#define IMP_IEHCIREQUEST \ - STDMETHODIMP_(VOID) CompletionCallback( \ - IN NTSTATUS NtStatusCode, \ - IN ULONG UrbStatusCode, \ - IN struct _QUEUE_HEAD *QueueHead); \ - \ - STDMETHODIMP_(NTSTATUS) GetQueueHead( \ - IN struct _QUEUE_HEAD ** OutHead); \ - \ - STDMETHODIMP_(BOOLEAN) ShouldReleaseRequestAfterCompletion(); \ - \ - STDMETHODIMP_(VOID) FreeQueueHead(struct _QUEUE_HEAD * QueueHead); \ - \ - STDMETHODIMP_(BOOLEAN) IsQueueHeadComplete( \ - IN struct _QUEUE_HEAD * QueueHead); \ - \ - STDMETHODIMP_(USB_DEVICE_SPEED) GetSpeed( THIS); \ - \ - STDMETHODIMP_(UCHAR) GetInterval( THIS); - -DECLARE_INTERFACE_(IEHCIRequest, IUSBRequest) -{ - DEFINE_ABSTRACT_UNKNOWN() - DEFINE_ABSTRACT_USBREQUEST() - DEFINE_ABSTRACT_USBEHCIREQUEST() -}; - - -typedef IEHCIRequest *PEHCIREQUEST; - -//========================================================================================= -// -// class IUSBQueue -// -// Description: This class manages pending requests -// - -#define DEFINE_ABSTRACT_USBEHCIQUEUE() \ - STDMETHOD_(VOID, InterruptCallback)( THIS_ \ - IN NTSTATUS Status, \ - OUT PULONG ShouldRingDoorBell) PURE; \ - \ - STDMETHOD_(VOID, CompleteAsyncRequests)( THIS) PURE; - -#define IMP_IEHCIQUEUE \ - STDMETHODIMP_(VOID) InterruptCallback( \ - IN NTSTATUS Status, \ - OUT PULONG ShouldRingDoorBell); \ - \ - STDMETHODIMP_(VOID) CompleteAsyncRequests(); - -DECLARE_INTERFACE_(IEHCIQueue, IUSBQueue) -{ - DEFINE_ABSTRACT_UNKNOWN() - DEFINE_ABSTRACT_USBQUEUE() - DEFINE_ABSTRACT_USBEHCIQUEUE() -}; - -typedef IEHCIQueue *PEHCIQUEUE; - -#endif /* INTERFACES_HPP */ diff --git a/drivers/usb/usbehci/usb_queue.cpp b/drivers/usb/usbehci/usb_queue.cpp deleted file mode 100644 index 48a06d62c2d..00000000000 --- a/drivers/usb/usbehci/usb_queue.cpp +++ /dev/null @@ -1,1236 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbehci/usb_queue.cpp - * PURPOSE: USB EHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin(a)reactos.org) - * Johannes Anderwald (johannes.anderwald(a)reactos.org) - */ - -#include "usbehci.h" - -#define NDEBUG -#include <debug.h> - -class CUSBQueue : public IEHCIQueue -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - // IUSBQueue functions - IMP_IUSBQUEUE - - // IEHCIQueue functions - IMP_IEHCIQUEUE - - // constructor / destructor - CUSBQueue(IUnknown *OuterUnknown){} - virtual ~CUSBQueue(){} - -protected: - LONG m_Ref; // reference count - PKSPIN_LOCK m_Lock; // list lock - PDMA_ADAPTER m_Adapter; // dma adapter - PEHCIHARDWAREDEVICE m_Hardware; // stores hardware object - PQUEUE_HEAD AsyncListQueueHead; // async queue head - LIST_ENTRY m_CompletedRequestAsyncList; // completed async request list - LIST_ENTRY m_PendingRequestAsyncList; // pending async request list - ULONG m_MaxPeriodicListEntries; // max periodic list entries - ULONG m_MaxPollingInterval; // max polling interval - PHYSICAL_ADDRESS m_SyncFrameListAddr; // physical address of sync frame list - PULONG m_SyncFrameList; // virtual address of sync frame list - - // queue head manipulation functions - VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead); - VOID UnlinkQueueHead(PQUEUE_HEAD QueueHead); - VOID LinkQueueHeadChain(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead); - PQUEUE_HEAD UnlinkQueueHeadChain(PQUEUE_HEAD HeadQueueHead, ULONG Count); - - // processes the async list - VOID ProcessAsyncList(IN NTSTATUS Status, OUT PULONG ShouldRingDoorBell); - - // processes the async list - VOID ProcessPeriodicSchedule(IN NTSTATUS Status, OUT PULONG ShouldRingDoorBell); - - // called for each completed queue head - VOID QueueHeadCompletion(PQUEUE_HEAD QueueHead, NTSTATUS Status); - - // called for each completed queue head - VOID QueueHeadInterruptCompletion(PQUEUE_HEAD QueueHead, NTSTATUS Status); - - // called when the completion queue is cleaned up - VOID QueueHeadCleanup(PQUEUE_HEAD QueueHead); - - // initializes the sync schedule - NTSTATUS InitializeSyncSchedule(IN PEHCIHARDWAREDEVICE Hardware, IN PDMAMEMORYMANAGER MemManager); - - // links interrupt queue head - VOID LinkInterruptQueueHead(PQUEUE_HEAD QueueHead); - - // interval index - UCHAR GetIntervalIndex(UCHAR Interval); - - - // interrupt queue heads - PQUEUE_HEAD m_InterruptQueueHeads[EHCI_INTERRUPT_ENTRIES_COUNT]; - - // contains the periodic queue heads - LIST_ENTRY m_PeriodicQueueHeads; -}; - -//================================================================================================= -// COM -// -NTSTATUS -STDMETHODCALLTYPE -CUSBQueue::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - if (IsEqualGUIDAligned(refiid, IID_IUnknown)) - { - *Output = PVOID(PUNKNOWN(this)); - PUNKNOWN(*Output)->AddRef(); - return STATUS_SUCCESS; - } - - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBQueue::Initialize( - IN PUSBHARDWAREDEVICE Hardware, - IN PDMA_ADAPTER AdapterObject, - IN PDMAMEMORYMANAGER MemManager, - IN OPTIONAL PKSPIN_LOCK Lock) -{ - NTSTATUS Status = STATUS_SUCCESS; - - DPRINT("CUSBQueue::Initialize()\n"); - - ASSERT(Hardware); - - // - // store device lock - // - m_Lock = Lock; - - // - // store hardware object - // - m_Hardware = PEHCIHARDWAREDEVICE(Hardware); - - - // - // Get the AsyncQueueHead - // - AsyncListQueueHead = (PQUEUE_HEAD)m_Hardware->GetAsyncListQueueHead(); - - // - // Initialize the List Head - // - InitializeListHead(&AsyncListQueueHead->LinkedQueueHeads); - - // - // Initialize completed async list head - // - InitializeListHead(&m_CompletedRequestAsyncList); - - // - // Initialize pending async list head - // - InitializeListHead(&m_PendingRequestAsyncList); - - // - // initialize periodic queue heads - // - InitializeListHead(&m_PeriodicQueueHeads); - - // - // now initialize sync schedule - // - Status = InitializeSyncSchedule(m_Hardware, MemManager); - - - return Status; -} - -NTSTATUS -CUSBQueue::InitializeSyncSchedule( - IN PEHCIHARDWAREDEVICE Hardware, - IN PDMAMEMORYMANAGER MemManager) -{ - PHYSICAL_ADDRESS QueueHeadPhysAddr; - NTSTATUS Status; - ULONG Index, Interval, IntervalIndex; - PQUEUE_HEAD QueueHead; - - // - // FIXME: check if smaller list sizes are supported - // - m_MaxPeriodicListEntries = 1024; - - // - // use polling scheme of 512ms - // - m_MaxPollingInterval = 512; - - // - // first allocate a page to hold the queue array - // - Status = MemManager->Allocate(m_MaxPeriodicListEntries * sizeof(PVOID), (PVOID*)&m_SyncFrameList, &m_SyncFrameListAddr); - if (!NT_SUCCESS(Status)) - { - // - // failed to allocate sync frame list array - // - DPRINT1("Failed to allocate sync frame list\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - for(Index = 0; Index < EHCI_INTERRUPT_ENTRIES_COUNT; Index++) - { - // - // allocate queue head - // - Status = MemManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, &QueueHeadPhysAddr); - if (!NT_SUCCESS(Status)) - { - // - // failed to create queue head - // - DPRINT1("Failed to create queue head\n"); - return Status; - } - - // - // initialize queue head - // - QueueHead->HorizontalLinkPointer = TERMINATE_POINTER; - QueueHead->AlternateNextPointer = TERMINATE_POINTER; - QueueHead->NextPointer = TERMINATE_POINTER; - QueueHead->EndPointCharacteristics.MaximumPacketLength = 64; - QueueHead->EndPointCharacteristics.NakCountReload = 0x3; - QueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED; - QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01; - QueueHead->PhysicalAddr = QueueHeadPhysAddr.LowPart; - QueueHead->Token.Bits.Halted = TRUE; //FIXME - m_InterruptQueueHeads[Index]= QueueHead; - - if (Index > 0) - { - // link all to the first queue head - QueueHead->HorizontalLinkPointer = m_InterruptQueueHeads[0]->PhysicalAddr | QH_TYPE_QH; - QueueHead->NextQueueHead = m_InterruptQueueHeads[0]; - } - } - - // - // build interrupt tree - // - Interval = EHCI_FRAMELIST_ENTRIES_COUNT; - IntervalIndex = EHCI_INTERRUPT_ENTRIES_COUNT - 1; - while (Interval > 1) - { - for (Index = Interval / 2; Index < EHCI_FRAMELIST_ENTRIES_COUNT; Index += Interval) - { - DPRINT("Index %lu IntervalIndex %lu\n", Index, IntervalIndex); - m_SyncFrameList[Index] = m_InterruptQueueHeads[IntervalIndex]->PhysicalAddr | QH_TYPE_QH; - } - IntervalIndex--; - Interval /= 2; - } - - // - // now set the sync base - // - Hardware->SetPeriodicListRegister(m_SyncFrameListAddr.LowPart); - - // - // sync frame list initialized - // - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBQueue::AddUSBRequest( - IUSBRequest * Req) -{ - PQUEUE_HEAD QueueHead; - NTSTATUS Status; - ULONG Type; - KIRQL OldLevel; - PEHCIREQUEST Request; - - // sanity check - ASSERT(Req != NULL); - - // get internal req - Request = PEHCIREQUEST(Req); - - // get request type - Type = Request->GetTransferType(); - - // check if supported - switch(Type) - { - case USB_ENDPOINT_TYPE_ISOCHRONOUS: - /* NOT IMPLEMENTED IN QUEUE */ - Status = STATUS_NOT_SUPPORTED; - break; - case USB_ENDPOINT_TYPE_INTERRUPT: - case USB_ENDPOINT_TYPE_BULK: - case USB_ENDPOINT_TYPE_CONTROL: - Status = STATUS_SUCCESS; - break; - default: - /* BUG */ - PC_ASSERT(FALSE); - Status = STATUS_NOT_SUPPORTED; - } - - // check for success - if (!NT_SUCCESS(Status)) - { - // request not supported, please try later - return Status; - } - - // get queue head - Status = Request->GetQueueHead(&QueueHead); - - // check for success - if (!NT_SUCCESS(Status)) - { - // failed to get queue head - return Status; - } - - // acquire lock - KeAcquireSpinLock(m_Lock, &OldLevel); - - if (Type == USB_ENDPOINT_TYPE_BULK || Type == USB_ENDPOINT_TYPE_CONTROL) - { - // Add to list - LinkQueueHead(AsyncListQueueHead, QueueHead); - } - else if (Type == USB_ENDPOINT_TYPE_INTERRUPT) - { - // get interval - LinkInterruptQueueHead(QueueHead); - } - - // release lock - KeReleaseSpinLock(m_Lock, OldLevel); - - - // add extra reference which is released when the request is completed - Request->AddRef(); - - // done - return STATUS_SUCCESS; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBQueue::CreateUSBRequest( - IUSBRequest **OutRequest) -{ - PUSBREQUEST UsbRequest; - NTSTATUS Status; - - *OutRequest = NULL; - Status = InternalCreateUSBRequest(&UsbRequest); - - if (NT_SUCCESS(Status)) - { - *OutRequest = UsbRequest; - } - - return Status; -} - -UCHAR -CUSBQueue::GetIntervalIndex( - UCHAR Interval) -{ - UCHAR IntervalIndex; - - ASSERT(Interval != 0); - if (Interval == 1) - IntervalIndex = 1; - else if (Interval == 2) - IntervalIndex = 2; - else if (Interval <= 4) - IntervalIndex = 3; - else if (Interval <= 8) - IntervalIndex = 4; - else if (Interval <= 16) - IntervalIndex = 5; - else if (Interval <= 32) - IntervalIndex = 6; - else if (Interval <= 64) - IntervalIndex = 7; - else if (Interval <= 128) - IntervalIndex = 8; - else - IntervalIndex = 9; - - ASSERT(IntervalIndex < EHCI_INTERRUPT_ENTRIES_COUNT); - return IntervalIndex; -} - -VOID -CUSBQueue::LinkInterruptQueueHead( - PQUEUE_HEAD QueueHead) -{ - PEHCIREQUEST Request; - UCHAR Interval, IntervalIndex; - USB_DEVICE_SPEED DeviceSpeed; - PQUEUE_HEAD InterruptQueueHead; - - // get internal req - Request = PEHCIREQUEST(QueueHead->Request); - ASSERT(Request); - - // get interval - Interval = Request->GetInterval(); - - // get device speed - DeviceSpeed = Request->GetSpeed(); - if (DeviceSpeed == UsbHighSpeed) - { - // interrupt queue head can be scheduled on each possible micro frame - QueueHead->EndPointCapabilities.InterruptScheduleMask = 0xFF; - } - else - { - // As we do not yet support FSTNs to correctly reference low/full - // speed interrupt transfers, we simply put them into the 1 interval - // queue. This way we ensure that we reach them on every micro frame - // and can do the corresponding start/complete split transactions. - // ToDo: use FSTNs to correctly link non high speed interrupt transfers - Interval = 1; - - // For now we also force start splits to be in micro frame 0 and - // complete splits to be in micro frame 2, 3 and 4. - QueueHead->EndPointCapabilities.InterruptScheduleMask = 0x01; - QueueHead->EndPointCapabilities.SplitCompletionMask = 0x1C; - } - - // sanitize interrupt interval - Interval = max(1, Interval); - - // get interval index - IntervalIndex = GetIntervalIndex(Interval); - - - // get interrupt queue head - InterruptQueueHead = m_InterruptQueueHeads[IntervalIndex]; - - // link queue head - QueueHead->HorizontalLinkPointer = InterruptQueueHead->HorizontalLinkPointer; - QueueHead->NextQueueHead = InterruptQueueHead->NextQueueHead; - - InterruptQueueHead->HorizontalLinkPointer = QueueHead->PhysicalAddr | QH_TYPE_QH; - InterruptQueueHead->NextQueueHead = QueueHead; - - // store in periodic list - InsertTailList(&m_PeriodicQueueHeads, &QueueHead->LinkedQueueHeads); -} - -// -// LinkQueueHead - Links one QueueHead to the end of HeadQueueHead list, updating HorizontalLinkPointer. -// -VOID -CUSBQueue::LinkQueueHead( - PQUEUE_HEAD HeadQueueHead, - PQUEUE_HEAD NewQueueHead) -{ - PQUEUE_HEAD LastQueueHead, NextQueueHead; - PLIST_ENTRY Entry; - ASSERT(HeadQueueHead); - ASSERT(NewQueueHead); - - // - // Link the LIST_ENTRYs - // - //ASSERT(IsListEmpty(&HeadQueueHead->LinkedQueueHeads)); - InsertTailList(&HeadQueueHead->LinkedQueueHeads, &NewQueueHead->LinkedQueueHeads); - - // - // Update HLP for NewQueueHead to point to next, which should be the HeadQueueHead - // - Entry = NewQueueHead->LinkedQueueHeads.Flink; - NextQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - //ASSERT(NextQueueHead == HeadQueueHead); - NewQueueHead->HorizontalLinkPointer = (NextQueueHead->PhysicalAddr | QH_TYPE_QH); - - _ReadWriteBarrier(); - - // - // Update HLP for Previous QueueHead, which should be the last in list. - // - Entry = NewQueueHead->LinkedQueueHeads.Blink; - LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - //ASSERT(LastQueueHead == HeadQueueHead); - LastQueueHead->HorizontalLinkPointer = (NewQueueHead->PhysicalAddr | QH_TYPE_QH); - - // - // head queue head must be halted - // - //PC_ASSERT(HeadQueueHead->Token.Bits.Halted == TRUE); -} - -// -// UnlinkQueueHead - Unlinks one QueueHead, updating HorizontalLinkPointer. -// -VOID -CUSBQueue::UnlinkQueueHead( - PQUEUE_HEAD QueueHead) -{ - PQUEUE_HEAD PreviousQH, NextQH; - PLIST_ENTRY Entry; - - // - // sanity check: there must be at least one queue head with halted bit set - // - //PC_ASSERT(QueueHead->Token.Bits.Halted == 0); - - // - // get previous link - // - Entry = QueueHead->LinkedQueueHeads.Blink; - - // - // get queue head structure - // - PreviousQH = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // get next link - // - Entry = QueueHead->LinkedQueueHeads.Flink; - - // - // get queue head structure - // - NextQH = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // sanity check - // - ASSERT(QueueHead->HorizontalLinkPointer == (NextQH->PhysicalAddr | QH_TYPE_QH)); - - // - // remove queue head from linked list - // - PreviousQH->HorizontalLinkPointer = NextQH->PhysicalAddr | QH_TYPE_QH; - - // - // remove software link - // - RemoveEntryList(&QueueHead->LinkedQueueHeads); -} - -// -// LinkQueueHeadChain - Links a list of QueueHeads to the HeadQueueHead list, updating HorizontalLinkPointer. -// -VOID -CUSBQueue::LinkQueueHeadChain( - PQUEUE_HEAD HeadQueueHead, - PQUEUE_HEAD NewQueueHead) -{ - PQUEUE_HEAD LastQueueHead; - PLIST_ENTRY Entry; - ASSERT(HeadQueueHead); - ASSERT(NewQueueHead); - - // - // Find the last QueueHead in NewQueueHead - // - Entry = NewQueueHead->LinkedQueueHeads.Blink; - ASSERT(Entry != NewQueueHead->LinkedQueueHeads.Flink); - LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // Set the LinkPointer and Flink - // - LastQueueHead->HorizontalLinkPointer = HeadQueueHead->PhysicalAddr | QH_TYPE_QH; - LastQueueHead->LinkedQueueHeads.Flink = &HeadQueueHead->LinkedQueueHeads; - - // - // Fine the last QueueHead in HeadQueueHead - // - Entry = HeadQueueHead->LinkedQueueHeads.Blink; - HeadQueueHead->LinkedQueueHeads.Blink = &LastQueueHead->LinkedQueueHeads; - LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - LastQueueHead->LinkedQueueHeads.Flink = &NewQueueHead->LinkedQueueHeads; - LastQueueHead->HorizontalLinkPointer = NewQueueHead->PhysicalAddr | QH_TYPE_QH; -} - -// -// UnlinkQueueHeadChain - Unlinks a list number of QueueHeads from HeadQueueHead list, updating HorizontalLinkPointer. -// returns the chain of QueueHeads removed from HeadQueueHead. -// -PQUEUE_HEAD -CUSBQueue::UnlinkQueueHeadChain( - PQUEUE_HEAD HeadQueueHead, - ULONG Count) -{ - PQUEUE_HEAD LastQueueHead, FirstQueueHead; - PLIST_ENTRY Entry; - ULONG Index; - - // - // Find the last QueueHead in NewQueueHead - // - Entry = &HeadQueueHead->LinkedQueueHeads; - FirstQueueHead = CONTAINING_RECORD(Entry->Flink, QUEUE_HEAD, LinkedQueueHeads); - - for (Index = 0; Index < Count; Index++) - { - Entry = Entry->Flink; - - if (Entry == &HeadQueueHead->LinkedQueueHeads) - { - DPRINT1("Warning; Only %lu QueueHeads in HeadQueueHead\n", Index); - Count = Index + 1; - break; - } - } - - LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - HeadQueueHead->LinkedQueueHeads.Flink = LastQueueHead->LinkedQueueHeads.Flink; - if (Count + 1 == Index) - { - HeadQueueHead->LinkedQueueHeads.Blink = &HeadQueueHead->LinkedQueueHeads; - } - else - HeadQueueHead->LinkedQueueHeads.Blink = LastQueueHead->LinkedQueueHeads.Flink; - - FirstQueueHead->LinkedQueueHeads.Blink = &LastQueueHead->LinkedQueueHeads; - LastQueueHead->LinkedQueueHeads.Flink = &FirstQueueHead->LinkedQueueHeads; - LastQueueHead->HorizontalLinkPointer = TERMINATE_POINTER; - return FirstQueueHead; -} - -VOID -CUSBQueue::QueueHeadInterruptCompletion( - PQUEUE_HEAD QueueHead, - NTSTATUS Status) -{ - PEHCIREQUEST Request; - UCHAR Interval, IntervalIndex; - PQUEUE_HEAD InterruptQueueHead, LastQueueHead = NULL; - - - // - // sanity check - // - PC_ASSERT(QueueHead->Request); - - // - // get IUSBRequest interface - // - Request = (PEHCIREQUEST)QueueHead->Request; - - // get interval - Interval = Request->GetInterval(); - - // sanitize interval - Interval = max(1, Interval); - - // get interval index - IntervalIndex = GetIntervalIndex(Interval); - - // get interrupt queue head from index - InterruptQueueHead = m_InterruptQueueHeads[IntervalIndex]; - - while(InterruptQueueHead != NULL) - { - if (InterruptQueueHead == QueueHead) - break; - - // move to next queue head - LastQueueHead = InterruptQueueHead; - InterruptQueueHead = (PQUEUE_HEAD)InterruptQueueHead->NextQueueHead; - } - - if (InterruptQueueHead != QueueHead) - { - // queue head not in list - ASSERT(FALSE); - return; - } - - // now unlink queue head - LastQueueHead->HorizontalLinkPointer = QueueHead->HorizontalLinkPointer; - LastQueueHead->NextQueueHead = QueueHead->NextQueueHead; - - DPRINT1("Periodic QueueHead %p Addr %x unlinked\n", QueueHead, QueueHead->PhysicalAddr); - - // insert into completed list - InsertTailList(&m_CompletedRequestAsyncList, &QueueHead->LinkedQueueHeads); -} - - - -VOID -CUSBQueue::QueueHeadCompletion( - PQUEUE_HEAD CurrentQH, - NTSTATUS Status) -{ - // - // now unlink the queue head - // FIXME: implement chained queue heads - // no need to acquire locks, as it is called with locks held - // - - // - // unlink queue head - // - UnlinkQueueHead(CurrentQH); - - // - // insert into completed list - // - InsertTailList(&m_CompletedRequestAsyncList, &CurrentQH->LinkedQueueHeads); -} - - -VOID -CUSBQueue::ProcessPeriodicSchedule( - IN NTSTATUS Status, - OUT PULONG ShouldRingDoorBell) -{ - KIRQL OldLevel; - PLIST_ENTRY Entry; - PQUEUE_HEAD QueueHead; - PEHCIREQUEST Request; - BOOLEAN IsQueueHeadComplete; - - // - // lock completed async list - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - // - // walk async list - // - ASSERT(AsyncListQueueHead); - Entry = m_PeriodicQueueHeads.Flink; - - while(Entry != &m_PeriodicQueueHeads) - { - // - // get queue head structure - // - QueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // sanity check - // - PC_ASSERT(QueueHead->Request); - - // - // get IUSBRequest interface - // - Request = (PEHCIREQUEST)QueueHead->Request; - - // - // move to next entry - // - Entry = Entry->Flink; - - // - // check if queue head is complete - // - IsQueueHeadComplete = Request->IsQueueHeadComplete(QueueHead); - - DPRINT("Request %p QueueHead %p Complete %c\n", Request, QueueHead, IsQueueHeadComplete); - - // - // check if queue head is complete - // - if (IsQueueHeadComplete) - { - // - // current queue head is complete - // - QueueHeadInterruptCompletion(QueueHead, Status); - - // - // ring door bell is going to be necessary - // - *ShouldRingDoorBell = TRUE; - } - } - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); - -} - -VOID -CUSBQueue::ProcessAsyncList( - IN NTSTATUS Status, - OUT PULONG ShouldRingDoorBell) -{ - KIRQL OldLevel; - PLIST_ENTRY Entry; - PQUEUE_HEAD QueueHead; - PEHCIREQUEST Request; - BOOLEAN IsQueueHeadComplete; - - // - // lock completed async list - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - // - // walk async list - // - ASSERT(AsyncListQueueHead); - Entry = AsyncListQueueHead->LinkedQueueHeads.Flink; - - while(Entry != &AsyncListQueueHead->LinkedQueueHeads) - { - // - // get queue head structure - // - QueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // sanity check - // - PC_ASSERT(QueueHead->Request); - - // - // get IUSBRequest interface - // - Request = (PEHCIREQUEST)QueueHead->Request; - - // - // move to next entry - // - Entry = Entry->Flink; - - // - // check if queue head is complete - // - IsQueueHeadComplete = Request->IsQueueHeadComplete(QueueHead); - - DPRINT("Request %p QueueHead %p Complete %c\n", Request, QueueHead, IsQueueHeadComplete); - - // - // check if queue head is complete - // - if (IsQueueHeadComplete) - { - // - // current queue head is complete - // - QueueHeadCompletion(QueueHead, Status); - - // - // ring door bell is going to be necessary - // - *ShouldRingDoorBell = TRUE; - } - } - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); -} - - -VOID -STDMETHODCALLTYPE -CUSBQueue::InterruptCallback( - IN NTSTATUS Status, - OUT PULONG ShouldRingDoorBell) -{ - DPRINT("CUSBQueue::InterruptCallback\n"); - - // - // process periodic schedule - // - ProcessPeriodicSchedule(Status, ShouldRingDoorBell); - - // - // iterate asynchronous list - // - *ShouldRingDoorBell = FALSE; - ProcessAsyncList(Status, ShouldRingDoorBell); -} - -VOID -CUSBQueue::QueueHeadCleanup( - PQUEUE_HEAD CurrentQH) -{ - PQUEUE_HEAD NewQueueHead; - PEHCIREQUEST Request; - BOOLEAN ShouldReleaseWhenDone; - USBD_STATUS UrbStatus; - KIRQL OldLevel; - - // - // sanity checks - // - PC_ASSERT(CurrentQH->Token.Bits.Active == 0); - PC_ASSERT(CurrentQH->Request); - - - // - // get request - // - Request = (PEHCIREQUEST)CurrentQH->Request; - - // - // sanity check - // - PC_ASSERT(Request); - - // - // check if the queue head was completed with errors - // - if (CurrentQH->Token.Bits.Halted) - { - if (CurrentQH->Token.Bits.DataBufferError) - { - // - // data buffer error - // - UrbStatus = USBD_STATUS_DATA_BUFFER_ERROR; - } - else if (CurrentQH->Token.Bits.BabbleDetected) - { - // - // babble detected - // - UrbStatus = USBD_STATUS_BABBLE_DETECTED; - } - else - { - // - // stall pid - // - UrbStatus = USBD_STATUS_STALL_PID; - } - } - else - { - // - // well done ;) - // - UrbStatus = USBD_STATUS_SUCCESS; - } - - // - // Check if the transfer was completed and if UrbStatus is ok - // - if ((Request->IsRequestComplete() == FALSE) && (UrbStatus == USBD_STATUS_SUCCESS)) - { - // - // request is incomplete, get new queue head - // - if (Request->GetQueueHead(&NewQueueHead) == STATUS_SUCCESS) - { - // - // let IUSBRequest free the queue head - // - Request->FreeQueueHead(CurrentQH); - - // - // first acquire request lock - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - // - // add to pending list - // - InsertTailList(&m_PendingRequestAsyncList, &NewQueueHead->LinkedQueueHeads); - - // - // release queue head - // - KeReleaseSpinLock(m_Lock, OldLevel); - - // - // Done for now - // - return; - } - DPRINT1("Unable to create a new QueueHead\n"); - //ASSERT(FALSE); - - // - // Else there was a problem - // FIXME: Find better return - UrbStatus = USBD_STATUS_INSUFFICIENT_RESOURCES; - } - - if (UrbStatus != USBD_STATUS_SUCCESS) - { - DPRINT1("URB failed with status 0x%x\n", UrbStatus); - //PC_ASSERT(FALSE); - } - - // - // notify request that a transfer has completed - // - Request->CompletionCallback(UrbStatus != USBD_STATUS_SUCCESS ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS, - UrbStatus, - CurrentQH); - - // - // let IUSBRequest free the queue head - // - Request->FreeQueueHead(CurrentQH); - - // - // check if we should release request when done - // - ShouldReleaseWhenDone = Request->ShouldReleaseRequestAfterCompletion(); - - // - // release reference when the request was added - // - Request->Release(); - - // - // check if the operation was asynchronous - // - if (ShouldReleaseWhenDone) - { - // - // release outstanding reference count - // - Request->Release(); - } - - // - // request is now released - // -} - -VOID -STDMETHODCALLTYPE -CUSBQueue::CompleteAsyncRequests() -{ - KIRQL OldLevel; - PLIST_ENTRY Entry; - PQUEUE_HEAD CurrentQH; - - DPRINT("CUSBQueue::CompleteAsyncRequests\n"); - - // - // first acquire request lock - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - // - // the list should not be empty - // - PC_ASSERT(!IsListEmpty(&m_CompletedRequestAsyncList)); - - while(!IsListEmpty(&m_CompletedRequestAsyncList)) - { - // - // remove first entry - // - Entry = RemoveHeadList(&m_CompletedRequestAsyncList); - - // - // get queue head structure - // - CurrentQH = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); - - // - // complete request now - // - QueueHeadCleanup(CurrentQH); - - // - // first acquire request lock - // - KeAcquireSpinLock(m_Lock, &OldLevel); - } - - // - // is there a pending async entry - // - if (!IsListEmpty(&m_PendingRequestAsyncList)) - { - // - // remove first entry - // - Entry = RemoveHeadList(&m_PendingRequestAsyncList); - - // - // get queue head structure - // - CurrentQH = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - - // - // Add it to the AsyncList list - // - LinkQueueHead(AsyncListQueueHead, CurrentQH); - } - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBQueue::AbortDevicePipe( - IN UCHAR DeviceAddress, - IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor) -{ - KIRQL OldLevel; - PLIST_ENTRY Entry; - PQUEUE_HEAD QueueHead; - LIST_ENTRY ListHead; - - // - // lock completed async list - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - DPRINT1("AbortDevicePipe DeviceAddress %x EndpointDescriptor %p Addr %x\n", DeviceAddress, EndpointDescriptor, EndpointDescriptor->bEndpointAddress); - - // - // init list head - // - InitializeListHead(&ListHead); - - - // - // walk async list - // - ASSERT(AsyncListQueueHead); - Entry = AsyncListQueueHead->LinkedQueueHeads.Flink; - - while(Entry != &AsyncListQueueHead->LinkedQueueHeads) - { - // - // get queue head structure - // - QueueHead = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - ASSERT(QueueHead); - - // - // move to next entry - // - Entry = Entry->Flink; - - if (QueueHead->EndPointCharacteristics.DeviceAddress == DeviceAddress && - QueueHead->EndPointCharacteristics.EndPointNumber == (EndpointDescriptor->bEndpointAddress & 0xF) && QueueHead->Token.Bits.Halted) - { - // - // unlink queue head - // - UnlinkQueueHead(QueueHead); - - // - // add to temp list - // - InsertTailList(&ListHead, &QueueHead->LinkedQueueHeads); - } - } - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); - - while(!IsListEmpty(&ListHead)) - { - // - // remove entry - // - Entry = RemoveHeadList(&ListHead); - - // - // get queue head structure - // - QueueHead = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); - ASSERT(QueueHead); - - // - // cleanup queue head - // - QueueHeadCleanup(QueueHead); - } - return STATUS_SUCCESS; -} - - -NTSTATUS -NTAPI -CreateUSBQueue( - PUSBQUEUE *OutUsbQueue) -{ - PUSBQUEUE This; - - // - // allocate controller - // - This = new(NonPagedPool, TAG_USBEHCI) CUSBQueue(0); - if (!This) - { - // - // failed to allocate - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // add reference count - // - This->AddRef(); - - // - // return result - // - *OutUsbQueue = (PUSBQUEUE)This; - - // - // done - // - return STATUS_SUCCESS; -} - diff --git a/drivers/usb/usbehci/usb_request.cpp b/drivers/usb/usbehci/usb_request.cpp deleted file mode 100644 index abffd0dc679..00000000000 --- a/drivers/usb/usbehci/usb_request.cpp +++ /dev/null @@ -1,1852 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbehci/usb_request.cpp - * PURPOSE: USB EHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin(a)reactos.org) - * Johannes Anderwald (johannes.anderwald(a)reactos.org) - */ - -#include "usbehci.h" - -#define NDEBUG -#include <debug.h> - -class CUSBRequest : public IEHCIRequest -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - // IUSBRequest interface functions - IMP_IUSBREQUEST - // IEHCI Request interface functions - IMP_IEHCIREQUEST - - // local functions - ULONG InternalGetTransferType(); - UCHAR InternalGetPidDirection(); - NTSTATUS BuildControlTransferQueueHead(PQUEUE_HEAD * OutHead); - NTSTATUS BuildBulkInterruptTransferQueueHead(PQUEUE_HEAD * OutHead); - NTSTATUS STDMETHODCALLTYPE CreateDescriptor(PQUEUE_TRANSFER_DESCRIPTOR *OutDescriptor); - NTSTATUS CreateQueueHead(PQUEUE_HEAD *OutQueueHead); - UCHAR STDMETHODCALLTYPE GetDeviceAddress(); - NTSTATUS BuildSetupPacket(); - NTSTATUS BuildSetupPacketFromURB(); - ULONG InternalCalculateTransferLength(); - NTSTATUS STDMETHODCALLTYPE BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset); - VOID STDMETHODCALLTYPE InitDescriptor(IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR DataToggle, OUT PULONG OutDescriptorLength); - VOID DumpQueueHead(IN PQUEUE_HEAD QueueHead); - - // constructor / destructor - CUSBRequest(IUnknown *OuterUnknown); - virtual ~CUSBRequest(); - -protected: - LONG m_Ref; - - // - // memory manager for allocating setup packet / queue head / transfer descriptors - // - PDMAMEMORYMANAGER m_DmaManager; - - // - // caller provided irp packet containing URB request - // - PIRP m_Irp; - - // - // transfer buffer length - // - ULONG m_TransferBufferLength; - - // - // current transfer length - // - ULONG m_TransferBufferLengthCompleted; - - // - // Total Transfer Length - // - ULONG m_TotalBytesTransferred; - - // - // transfer buffer MDL - // - PMDL m_TransferBufferMDL; - - // - // caller provided setup packet - // - PUSB_DEFAULT_PIPE_SETUP_PACKET m_SetupPacket; - - // - // completion event for callers who initialized request with setup packet - // - PKEVENT m_CompletionEvent; - - // - // device address for callers who initialized it with device address - // - UCHAR m_DeviceAddress; - - // - // store end point address - // - PUSB_ENDPOINT m_EndpointDescriptor; - - // - // DMA queue head - // - PQUEUE_HEAD m_QueueHead; - - // - // allocated setup packet from the DMA pool - // - PUSB_DEFAULT_PIPE_SETUP_PACKET m_DescriptorPacket; - PHYSICAL_ADDRESS m_DescriptorSetupPacket; - - // - // stores the result of the operation - // - NTSTATUS m_NtStatusCode; - ULONG m_UrbStatusCode; - - // buffer base address - PVOID m_Base; - - // device speed - USB_DEVICE_SPEED m_Speed; - -}; - -//---------------------------------------------------------------------------------------- -CUSBRequest::CUSBRequest(IUnknown *OuterUnknown) : - m_CompletionEvent(NULL) -{ - UNREFERENCED_PARAMETER(OuterUnknown); -} - -//---------------------------------------------------------------------------------------- -CUSBRequest::~CUSBRequest() -{ - if (m_CompletionEvent != NULL) - { - ExFreePoolWithTag(m_CompletionEvent, TAG_USBEHCI); - } -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CUSBRequest::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - return STATUS_UNSUCCESSFUL; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CUSBRequest::InitializeWithSetupPacket( - IN PDMAMEMORYMANAGER DmaManager, - IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, - IN PUSBDEVICE Device, - IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, - IN OUT ULONG TransferBufferLength, - IN OUT PMDL TransferBuffer) -{ - // - // sanity checks - // - PC_ASSERT(DmaManager); - PC_ASSERT(SetupPacket); - - // - // initialize packet - // - m_DmaManager = DmaManager; - m_SetupPacket = SetupPacket; - m_TransferBufferLength = TransferBufferLength; - m_TransferBufferMDL = TransferBuffer; - m_DeviceAddress = Device->GetDeviceAddress(); - m_Speed = Device->GetSpeed(); - m_EndpointDescriptor = EndpointDescriptor; - m_TotalBytesTransferred = 0; - - // - // Set Length Completed to 0 - // - m_TransferBufferLengthCompleted = 0; - - // - // allocate completion event - // - m_CompletionEvent = (PKEVENT)ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_USBEHCI); - if (!m_CompletionEvent) - { - // - // failed to allocate completion event - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize completion event - // - KeInitializeEvent(m_CompletionEvent, NotificationEvent, FALSE); - - // - // done - // - return STATUS_SUCCESS; -} -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CUSBRequest::InitializeWithIrp( - IN PDMAMEMORYMANAGER DmaManager, - IN PUSBDEVICE Device, - IN OUT PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PURB Urb; - - // - // sanity checks - // - PC_ASSERT(DmaManager); - PC_ASSERT(Irp); - - m_DmaManager = DmaManager; - m_TotalBytesTransferred = 0; - m_Speed = Device->GetSpeed(); - - // - // get current irp stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // - // sanity check - // - PC_ASSERT(IoStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL); - PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB); - PC_ASSERT(IoStack->Parameters.Others.Argument1 != 0); - - // - // get urb - // - Urb = (PURB)IoStack->Parameters.Others.Argument1; - - // - // store irp - // - m_Irp = Irp; - - // - // check function type - // - switch (Urb->UrbHeader.Function) - { - // - // luckily those request have the same structure layout - // - case URB_FUNCTION_CLASS_INTERFACE: - case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: - case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: - { - // - // bulk interrupt transfer - // - if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength) - { - // - // Check if there is a MDL - // - if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL) - { - // - // sanity check - // - PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer); - - // - // Create one using TransferBuffer - // - DPRINT("Creating Mdl from Urb Buffer %p Length %lu\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); - m_TransferBufferMDL = IoAllocateMdl(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, - Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, - FALSE, - FALSE, - NULL); - - if (!m_TransferBufferMDL) - { - // - // failed to allocate mdl - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // build mdl for non paged pool - // FIXME: Does hub driver already do this when passing MDL? - // - MmBuildMdlForNonPagedPool(m_TransferBufferMDL); - - // - // Keep that ehci created the MDL and needs to free it. - // - } - else - { - m_TransferBufferMDL = Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL; - } - - // - // save buffer length - // - m_TransferBufferLength = Urb->UrbBulkOrInterruptTransfer.TransferBufferLength; - - // - // Set Length Completed to 0 - // - m_TransferBufferLengthCompleted = 0; - - // - // get endpoint descriptor - // - m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbBulkOrInterruptTransfer.PipeHandle; - - } - break; - } - default: - DPRINT1("URB Function: not supported %x\n", Urb->UrbHeader.Function); - //ASSERT(FALSE); - } - - // - // done - // - return STATUS_SUCCESS; - -} - -//---------------------------------------------------------------------------------------- -VOID -STDMETHODCALLTYPE -CUSBRequest::CompletionCallback( - IN NTSTATUS NtStatusCode, - IN ULONG UrbStatusCode, - IN struct _QUEUE_HEAD *QueueHead) -{ - PIO_STACK_LOCATION IoStack; - PURB Urb; - - // - // FIXME: support linked queue heads - // - - // - // store completion code - // - m_NtStatusCode = NtStatusCode; - m_UrbStatusCode = UrbStatusCode; - - if (m_Irp) - { - // - // set irp completion status - // - m_Irp->IoStatus.Status = NtStatusCode; - - // - // get current irp stack location - // - IoStack = IoGetCurrentIrpStackLocation(m_Irp); - - // - // get urb - // - Urb = (PURB)IoStack->Parameters.Others.Argument1; - - // - // store urb status - // - Urb->UrbHeader.Status = UrbStatusCode; - - // - // Check if the MDL was created - // - if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL) - { - // - // Free Mdl - // - IoFreeMdl(m_TransferBufferMDL); - } - - // - // check if the request was successful - // - if (!NT_SUCCESS(NtStatusCode)) - { - // - // set returned length to zero in case of error - // - Urb->UrbHeader.Length = 0; - } - else - { - // - // calculate transfer length - // - Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = InternalCalculateTransferLength(); - } - - DPRINT("Request %p Completing Irp %p NtStatusCode %x UrbStatusCode %x Transferred Length %lu\n", this, m_Irp, NtStatusCode, UrbStatusCode, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); - - // - // FIXME: check if the transfer was split - // if yes dont complete irp yet - // - IoCompleteRequest(m_Irp, IO_NO_INCREMENT); - } - else - { - // - // signal completion event - // - PC_ASSERT(m_CompletionEvent); - KeSetEvent(m_CompletionEvent, 0, FALSE); - } -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CUSBRequest::GetQueueHead( - struct _QUEUE_HEAD ** OutHead) -{ - ULONG TransferType; - NTSTATUS Status; - - // - // first get transfer type - // - TransferType = InternalGetTransferType(); - - // - // build request depending on type - // - switch(TransferType) - { - case USB_ENDPOINT_TYPE_CONTROL: - Status = BuildControlTransferQueueHead(OutHead); - break; - case USB_ENDPOINT_TYPE_INTERRUPT: - case USB_ENDPOINT_TYPE_BULK: - Status = BuildBulkInterruptTransferQueueHead(OutHead); - break; - case USB_ENDPOINT_TYPE_ISOCHRONOUS: - DPRINT1("USB_ENDPOINT_TYPE_ISOCHRONOUS not implemented\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - default: - PC_ASSERT(FALSE); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - - if (NT_SUCCESS(Status)) - { - // - // store queue head - // - m_QueueHead = *OutHead; - - // - // store request object - // - (*OutHead)->Request = PVOID(this); - } - - // - // done - // - return Status; -} - -//---------------------------------------------------------------------------------------- -BOOLEAN -STDMETHODCALLTYPE -CUSBRequest::IsRequestComplete() -{ - // - // FIXME: check if request was split - // - - // - // Check if the transfer was completed, only valid for Bulk Transfers - // - if ((m_TransferBufferLengthCompleted < m_TransferBufferLength) - && (GetTransferType() == USB_ENDPOINT_TYPE_BULK)) - { - // - // Transfer not completed - // - return FALSE; - } - return TRUE; -} -//---------------------------------------------------------------------------------------- -ULONG -STDMETHODCALLTYPE -CUSBRequest::GetTransferType() -{ - // - // call internal implementation - // - return InternalGetTransferType(); -} - -//---------------------------------------------------------------------------------------- -ULONG -CUSBRequest::InternalGetTransferType() -{ - ULONG TransferType; - - // - // check if an irp is provided - // - if (m_Irp) - { - ASSERT(m_EndpointDescriptor); - - // - // end point is defined in the low byte of bmAttributes - // - TransferType = (m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK); - } - else - { - // - // initialized with setup packet, must be a control transfer - // - TransferType = USB_ENDPOINT_TYPE_CONTROL; - ASSERT(m_EndpointDescriptor == NULL); - } - - // - // done - // - return TransferType; -} - -UCHAR -CUSBRequest::InternalGetPidDirection() -{ - if (m_EndpointDescriptor) - { - // - // end point direction is highest bit in bEndpointAddress - // - return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7; - } - else - { - // - // request arrives on the control pipe, extract direction from setup packet - // - ASSERT(m_DescriptorPacket); - return (m_DescriptorPacket->bmRequestType.B >> 7); - } -} - -VOID -STDMETHODCALLTYPE -CUSBRequest::InitDescriptor( - IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor, - IN PVOID TransferBuffer, - IN ULONG TransferBufferLength, - IN UCHAR PidCode, - IN UCHAR DataToggle, - OUT PULONG OutDescriptorLength) -{ - ULONG Index, Length = 0, PageOffset, BufferLength; - PHYSICAL_ADDRESS Address; - - // - // init transfer descriptor - // - CurrentDescriptor->Token.Bits.PIDCode = PidCode; - CurrentDescriptor->Token.Bits.TotalBytesToTransfer = 0; - CurrentDescriptor->Token.Bits.DataToggle = DataToggle; - - // - // sanity check - // - ASSERT(TransferBufferLength); - - // - // store buffers - // - Index = 0; - do - { - // - // get address (HACK) - // - *(volatile char *)TransferBuffer; - Address = MmGetPhysicalAddress(TransferBuffer); - - // - // use physical address - // - CurrentDescriptor->BufferPointer[Index] = Address.LowPart; - CurrentDescriptor->ExtendedBufferPointer[Index] = Address.HighPart; - - // - // Get the offset from page size - // - PageOffset = BYTE_OFFSET(CurrentDescriptor->BufferPointer[Index]); - if (PageOffset != 0) - { - // - // move to next page - // - TransferBuffer = (PVOID)ROUND_TO_PAGES(TransferBuffer); - } - else - { - // - // move to next page - // - TransferBuffer = (PVOID)((ULONG_PTR)TransferBuffer + PAGE_SIZE); - } - - // - // calculate buffer length - // - BufferLength = min(TransferBufferLength, PAGE_SIZE - PageOffset); - - // - // increment transfer bytes - // - CurrentDescriptor->Token.Bits.TotalBytesToTransfer += BufferLength; - CurrentDescriptor->TotalBytesToTransfer += BufferLength; - Length += BufferLength; - DPRINT("Index %lu TransferBufferLength %lu PageOffset %x BufferLength %lu Buffer Phy %p TransferBuffer %p\n", Index, TransferBufferLength, PageOffset, BufferLength, CurrentDescriptor->BufferPointer[Index], TransferBuffer); - - // - // decrement available byte count - // - TransferBufferLength -= BufferLength; - if (TransferBufferLength == 0) - { - // - // end reached - // - break; - } - - // - // sanity check - // - if (Index > 1) - { - // - // no equal buffers - // - ASSERT(CurrentDescriptor->BufferPointer[Index] != CurrentDescriptor->BufferPointer[Index-1]); - } - - // - // next descriptor index - // - Index++; - }while(Index < 5); - - // - // store result - // - *OutDescriptorLength = Length; -} - -NTSTATUS -STDMETHODCALLTYPE -CUSBRequest::BuildTransferDescriptorChain( - IN PQUEUE_HEAD QueueHead, - IN PVOID TransferBuffer, - IN ULONG TransferBufferLength, - IN UCHAR PidCode, - IN UCHAR InitialDataToggle, - OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, - OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, - OUT PUCHAR OutDataToggle, - OUT PULONG OutTransferBufferOffset) -{ - PQUEUE_TRANSFER_DESCRIPTOR FirstDescriptor = NULL, CurrentDescriptor, LastDescriptor = NULL; - NTSTATUS Status; - ULONG DescriptorLength, TransferBufferOffset = 0; - ULONG MaxPacketSize = 0, TransferSize; - - // - // is there an endpoint descriptor - // - if (m_EndpointDescriptor) - { - // - // use endpoint packet size - // - MaxPacketSize = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize; - } - - do - { - // - // allocate transfer descriptor - // - Status = CreateDescriptor(&CurrentDescriptor); - if (!NT_SUCCESS(Status)) - { - // - // failed to allocate transfer descriptor - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - if (MaxPacketSize) - { - // - // transfer size is minimum available buffer or endpoint size - // - TransferSize = min(TransferBufferLength - TransferBufferOffset, MaxPacketSize); - } - else - { - // - // use available buffer - // - TransferSize = TransferBufferLength - TransferBufferOffset; - } - - // - // now init the descriptor - // - InitDescriptor(CurrentDescriptor, - (PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset), - TransferSize, - PidCode, - InitialDataToggle, - &DescriptorLength); - - // - // insert into queue head - // - InsertTailList(&QueueHead->TransferDescriptorListHead, &CurrentDescriptor->DescriptorEntry); - - // - // adjust offset - // - TransferBufferOffset += DescriptorLength; - - if (LastDescriptor) - { - // - // link to current descriptor - // - LastDescriptor->NextPointer = CurrentDescriptor->PhysicalAddr; - LastDescriptor = CurrentDescriptor; - } - else - { - // - // first descriptor in chain - // - LastDescriptor = FirstDescriptor = CurrentDescriptor; - } - - // - // flip data toggle - // - InitialDataToggle = !InitialDataToggle; - - if(TransferBufferLength == TransferBufferOffset) - { - // - // end reached - // - break; - } - - }while(TRUE); - - if (OutFirstDescriptor) - { - // - // store first descriptor - // - *OutFirstDescriptor = FirstDescriptor; - } - - if (OutLastDescriptor) - { - // - // store last descriptor - // - *OutLastDescriptor = CurrentDescriptor; - } - - if (OutDataToggle) - { - // - // store result data toggle - // - *OutDataToggle = InitialDataToggle; - } - - if (OutTransferBufferOffset) - { - // - // store offset - // - *OutTransferBufferOffset = TransferBufferOffset; - } - - // - // done - // - return STATUS_SUCCESS; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBRequest::BuildControlTransferQueueHead( - PQUEUE_HEAD * OutHead) -{ - NTSTATUS Status; - ULONG DescriptorChainLength; - PQUEUE_HEAD QueueHead; - PQUEUE_TRANSFER_DESCRIPTOR SetupDescriptor, StatusDescriptor, FirstDescriptor, LastDescriptor; - - // - // first allocate the queue head - // - Status = CreateQueueHead(&QueueHead); - if (!NT_SUCCESS(Status)) - { - // - // failed to allocate queue head - // - DPRINT1("[EHCI] Failed to create queue head\n"); - return Status; - } - - // - // sanity check - // - PC_ASSERT(QueueHead); - - // - // create setup packet - // - Status = BuildSetupPacket(); - if (!NT_SUCCESS(Status)) - { - // failed to create setup packet - DPRINT1("[EHCI] Failed to create setup packet\n"); - - // release queue head - m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD)); - return Status; - } - - // - // create setup descriptor - // - Status = CreateDescriptor(&SetupDescriptor); - if (!NT_SUCCESS(Status)) - { - // failed to create setup transfer descriptor - DPRINT1("[EHCI] Failed to create setup descriptor\n"); - - if (m_DescriptorPacket) - { - // release packet descriptor - m_DmaManager->Release(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - } - - // release queue head - m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD)); - return Status; - } - - // - // create status descriptor - // - Status = CreateDescriptor(&StatusDescriptor); - if (!NT_SUCCESS(Status)) - { - // failed to create status transfer descriptor - DPRINT1("[EHCI] Failed to create status descriptor\n"); - - // release setup transfer descriptor - m_DmaManager->Release(SetupDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR)); - - if (m_DescriptorPacket) - { - // release packet descriptor - m_DmaManager->Release(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - } - - // release queue head - m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD)); - return Status; - } - - // - // now initialize the queue head - // - QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress(); - - ASSERT(m_EndpointDescriptor == NULL); - - // - // init setup descriptor - // - SetupDescriptor->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN; - SetupDescriptor->Token.Bits.TotalBytesToTransfer = sizeof(USB_DEFAULT_PIPE_SETUP_PACKET); - SetupDescriptor->Token.Bits.DataToggle = FALSE; - SetupDescriptor->BufferPointer[0] = m_DescriptorSetupPacket.LowPart; - SetupDescriptor->ExtendedBufferPointer[0] = m_DescriptorSetupPacket.HighPart; - InsertTailList(&QueueHead->TransferDescriptorListHead, &SetupDescriptor->DescriptorEntry); - - - // - // init status descriptor - // - StatusDescriptor->Token.Bits.TotalBytesToTransfer = 0; - StatusDescriptor->Token.Bits.DataToggle = TRUE; - StatusDescriptor->Token.Bits.InterruptOnComplete = TRUE; - - // - // is there data - // - if (m_TransferBufferLength) - { - Status = BuildTransferDescriptorChain(QueueHead, - MmGetMdlVirtualAddress(m_TransferBufferMDL), - m_TransferBufferLength, - InternalGetPidDirection(), - TRUE, - &FirstDescriptor, - &LastDescriptor, - NULL, - &DescriptorChainLength); - if (!NT_SUCCESS(Status)) - { - // failed to create descriptor chain - DPRINT1("[EHCI] Failed to create descriptor chain\n"); - - // release status transfer descriptor - m_DmaManager->Release(StatusDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR)); - - // release setup transfer descriptor - m_DmaManager->Release(SetupDescriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR)); - - if (m_DescriptorPacket) - { - // release packet descriptor - m_DmaManager->Release(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - } - - // release queue head - m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD)); - return Status; - } - - if (m_TransferBufferLength != DescriptorChainLength) - { - DPRINT1("DescriptorChainLength %x\n", DescriptorChainLength); - DPRINT1("m_TransferBufferLength %x\n", m_TransferBufferLength); - ASSERT(FALSE); - } - - // - // now link the descriptors - // - SetupDescriptor->NextPointer = FirstDescriptor->PhysicalAddr; - SetupDescriptor->AlternateNextPointer = FirstDescriptor->PhysicalAddr; - LastDescriptor->NextPointer = StatusDescriptor->PhysicalAddr; - LastDescriptor->AlternateNextPointer = StatusDescriptor->PhysicalAddr; - - - // - // pid code is flipped for ops with data stage - // - StatusDescriptor->Token.Bits.PIDCode = !InternalGetPidDirection(); - } - else - { - // - // direct link - // - SetupDescriptor->NextPointer = StatusDescriptor->PhysicalAddr; - SetupDescriptor->AlternateNextPointer = StatusDescriptor->PhysicalAddr; - - // - // retrieve result of operation - // - StatusDescriptor->Token.Bits.PIDCode = PID_CODE_IN_TOKEN; - } - - // - // insert status descriptor - // - InsertTailList(&QueueHead->TransferDescriptorListHead, &StatusDescriptor->DescriptorEntry); - - - // - // link transfer descriptors to queue head - // - QueueHead->NextPointer = SetupDescriptor->PhysicalAddr; - - // - // store result - // - *OutHead = QueueHead; - - // - // displays the current request - // - //DumpQueueHead(QueueHead); - - DPRINT("BuildControlTransferQueueHead done\n"); - // - // done - // - return STATUS_SUCCESS; -} - -VOID -CUSBRequest::DumpQueueHead( - IN PQUEUE_HEAD QueueHead) -{ - PLIST_ENTRY Entry; - PQUEUE_TRANSFER_DESCRIPTOR Descriptor; - ULONG Index = 0; - - DPRINT1("QueueHead %p Addr %x\n", QueueHead, QueueHead->PhysicalAddr); - DPRINT1("QueueHead AlternateNextPointer %x\n", QueueHead->AlternateNextPointer); - DPRINT1("QueueHead NextPointer %x\n", QueueHead->NextPointer); - - DPRINT1("QueueHead HubAddr %x\n", QueueHead->EndPointCharacteristics.ControlEndPointFlag); - DPRINT1("QueueHead DeviceAddress %x\n", QueueHead->EndPointCharacteristics.DeviceAddress); - DPRINT1("QueueHead EndPointNumber %x\n", QueueHead->EndPointCharacteristics.EndPointNumber); - DPRINT1("QueueHead EndPointSpeed %x\n", QueueHead->EndPointCharacteristics.EndPointSpeed); - DPRINT1("QueueHead HeadOfReclamation %x\n", QueueHead->EndPointCharacteristics.HeadOfReclamation); - DPRINT1("QueueHead InactiveOnNextTransaction %x\n", QueueHead->EndPointCharacteristics.InactiveOnNextTransaction); - DPRINT1("QueueHead MaximumPacketLength %x\n", QueueHead->EndPointCharacteristics.MaximumPacketLength); - DPRINT1("QueueHead NakCountReload %x\n", QueueHead->EndPointCharacteristics.NakCountReload); - DPRINT1("QueueHead QEDTDataToggleControl %x\n", QueueHead->EndPointCharacteristics.QEDTDataToggleControl); - DPRINT1("QueueHead HubAddr %x\n", QueueHead->EndPointCapabilities.HubAddr); - DPRINT1("QueueHead InterruptScheduleMask %x\n", QueueHead->EndPointCapabilities.InterruptScheduleMask); - DPRINT1("QueueHead NumberOfTransactionPerFrame %x\n", QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame); - DPRINT1("QueueHead PortNumber %x\n", QueueHead->EndPointCapabilities.PortNumber); - DPRINT1("QueueHead SplitCompletionMask %x\n", QueueHead->EndPointCapabilities.SplitCompletionMask); - - Entry = QueueHead->TransferDescriptorListHead.Flink; - while(Entry != &QueueHead->TransferDescriptorListHead) - { - // - // get transfer descriptor - // - Descriptor = (PQUEUE_TRANSFER_DESCRIPTOR)CONTAINING_RECORD(Entry, QUEUE_TRANSFER_DESCRIPTOR, DescriptorEntry); - - DPRINT1("TransferDescriptor %lu Addr %x\n", Index, Descriptor->PhysicalAddr); - DPRINT1("TransferDescriptor %lu Next %x\n", Index, Descriptor->NextPointer); - DPRINT1("TransferDescriptor %lu AlternateNextPointer %x\n", Index, Descriptor->AlternateNextPointer); - DPRINT1("TransferDescriptor %lu Active %lu\n", Index, Descriptor->Token.Bits.Active); - DPRINT1("TransferDescriptor %lu BabbleDetected %lu\n", Index, Descriptor->Token.Bits.BabbleDetected); - DPRINT1("TransferDescriptor %lu CurrentPage %lu\n", Index, Descriptor->Token.Bits.CurrentPage); - DPRINT1("TransferDescriptor %lu DataBufferError %lu\n", Index, Descriptor->Token.Bits.DataBufferError); - DPRINT1("TransferDescriptor %lu DataToggle %lu\n", Index, Descriptor->Token.Bits.DataToggle); - DPRINT1("TransferDescriptor %lu ErrorCounter %lu\n", Index, Descriptor->Token.Bits.ErrorCounter); - DPRINT1("TransferDescriptor %lu Halted %lu\n", Index, Descriptor->Token.Bits.Halted); - DPRINT1("TransferDescriptor %lu InterruptOnComplete %x\n", Index, Descriptor->Token.Bits.InterruptOnComplete); - DPRINT1("TransferDescriptor %lu MissedMicroFrame %lu\n", Index, Descriptor->Token.Bits.MissedMicroFrame); - DPRINT1("TransferDescriptor %lu PIDCode %lu\n", Index, Descriptor->Token.Bits.PIDCode); - DPRINT1("TransferDescriptor %lu PingState %lu\n", Index, Descriptor->Token.Bits.PingState); - DPRINT1("TransferDescriptor %lu SplitTransactionState %lu\n", Index, Descriptor->Token.Bits.SplitTransactionState); - DPRINT1("TransferDescriptor %lu TotalBytesToTransfer %lu\n", Index, Descriptor->Token.Bits.TotalBytesToTransfer); - DPRINT1("TransferDescriptor %lu TransactionError %lu\n", Index, Descriptor->Token.Bits.TransactionError); - - DPRINT1("TransferDescriptor %lu Buffer Pointer 0 %x\n", Index, Descriptor->BufferPointer[0]); - DPRINT1("TransferDescriptor %lu Buffer Pointer 1 %x\n", Index, Descriptor->BufferPointer[1]); - DPRINT1("TransferDescriptor %lu Buffer Pointer 2 %x\n", Index, Descriptor->BufferPointer[2]); - DPRINT1("TransferDescriptor %lu Buffer Pointer 3 %x\n", Index, Descriptor->BufferPointer[3]); - DPRINT1("TransferDescriptor %lu Buffer Pointer 4 %x\n", Index, Descriptor->BufferPointer[4]); - Entry = Entry->Flink; - Index++; - } -} - - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBRequest::BuildBulkInterruptTransferQueueHead( - PQUEUE_HEAD * OutHead) -{ - NTSTATUS Status; - PQUEUE_HEAD QueueHead; - PVOID Base; - ULONG ChainDescriptorLength; - PQUEUE_TRANSFER_DESCRIPTOR FirstDescriptor, LastDescriptor; - - // - // Allocate the queue head - // - Status = CreateQueueHead(&QueueHead); - if (!NT_SUCCESS(Status)) - { - // - // failed to allocate queue head - // - DPRINT1("[EHCI] Failed to create queue head\n"); - return Status; - } - - // - // sanity checks - // - PC_ASSERT(QueueHead); - PC_ASSERT(m_TransferBufferLength); - - if (!m_Base) - { - // - // get virtual base of mdl - // - m_Base = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority); - } - - // - // Increase the size of last transfer, 0 in case this is the first - // - Base = (PVOID)((ULONG_PTR)m_Base + m_TransferBufferLengthCompleted); - - PC_ASSERT(m_EndpointDescriptor); - PC_ASSERT(Base); - - // - // sanity check - // - ASSERT(m_EndpointDescriptor); - - // - // use 4 * PAGE_SIZE at max for each new request - // - ULONG MaxTransferLength = min(4 * PAGE_SIZE, m_TransferBufferLength - m_TransferBufferLengthCompleted); - - // - // build bulk transfer descriptor chain - // - Status = BuildTransferDescriptorChain(QueueHead, - Base, - MaxTransferLength, - InternalGetPidDirection(), - m_EndpointDescriptor->DataToggle, - &FirstDescriptor, - &LastDescriptor, - &m_EndpointDescriptor->DataToggle, - &ChainDescriptorLength); - if (!NT_SUCCESS(Status)) - { - // - // failed to build transfer descriptor chain - // - DPRINT1("[EHCI] Failed to create descriptor chain\n"); - m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD)); - return Status; - } - - // - // move to next offset - // - m_TransferBufferLengthCompleted += ChainDescriptorLength; - - // - // init queue head - // - QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress(); - QueueHead->EndPointCharacteristics.EndPointNumber = m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0x0F; - QueueHead->EndPointCharacteristics.MaximumPacketLength = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize; - QueueHead->NextPointer = FirstDescriptor->PhysicalAddr; - QueueHead->CurrentLinkPointer = FirstDescriptor->PhysicalAddr; - QueueHead->AlternateNextPointer = TERMINATE_POINTER; - - ASSERT(QueueHead->EndPointCharacteristics.DeviceAddress); - ASSERT(QueueHead->EndPointCharacteristics.EndPointNumber); - ASSERT(QueueHead->EndPointCharacteristics.MaximumPacketLength); - ASSERT(QueueHead->NextPointer); - - // - // interrupt on last descriptor - // - LastDescriptor->Token.Bits.InterruptOnComplete = TRUE; - - // - // store result - // - *OutHead = QueueHead; - - // - // dump status - // - //DumpQueueHead(QueueHead); - - // - // done - // - return STATUS_SUCCESS; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CUSBRequest::CreateDescriptor( - PQUEUE_TRANSFER_DESCRIPTOR *OutDescriptor) -{ - PQUEUE_TRANSFER_DESCRIPTOR Descriptor; - NTSTATUS Status; - PHYSICAL_ADDRESS TransferDescriptorPhysicalAddress; - - // - // allocate descriptor - // - Status = m_DmaManager->Allocate(sizeof(QUEUE_TRANSFER_DESCRIPTOR), (PVOID*)&Descriptor, &TransferDescriptorPhysicalAddress); - if (!NT_SUCCESS(Status)) - { - // - // failed to allocate transfer descriptor - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize transfer descriptor - // - Descriptor->NextPointer = TERMINATE_POINTER; - Descriptor->AlternateNextPointer = TERMINATE_POINTER; - Descriptor->Token.Bits.DataToggle = TRUE; - Descriptor->Token.Bits.ErrorCounter = 0x03; - Descriptor->Token.Bits.Active = TRUE; - Descriptor->PhysicalAddr = TransferDescriptorPhysicalAddress.LowPart; - - // - // store result - // - *OutDescriptor = Descriptor; - - // - // done - // - return Status; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBRequest::CreateQueueHead( - PQUEUE_HEAD *OutQueueHead) -{ - PQUEUE_HEAD QueueHead; - PHYSICAL_ADDRESS QueueHeadPhysicalAddress; - NTSTATUS Status; - - // - // allocate queue head - // - Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead, &QueueHeadPhysicalAddress); - if (!NT_SUCCESS(Status)) - { - // - // failed to allocate queue head - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize queue head - // - QueueHead->HorizontalLinkPointer = TERMINATE_POINTER; - QueueHead->AlternateNextPointer = TERMINATE_POINTER; - QueueHead->NextPointer = TERMINATE_POINTER; - InitializeListHead(&QueueHead->TransferDescriptorListHead); - - // - // 1 for non high speed, 0 for high speed device - // - QueueHead->EndPointCharacteristics.ControlEndPointFlag = 0; - QueueHead->EndPointCharacteristics.HeadOfReclamation = FALSE; - QueueHead->EndPointCharacteristics.MaximumPacketLength = 64; - - // - // Set NakCountReload to max value possible - // - QueueHead->EndPointCharacteristics.NakCountReload = 0x3; - - // - // Get the Initial Data Toggle from the QEDT - // - QueueHead->EndPointCharacteristics.QEDTDataToggleControl = TRUE; - - // - // FIXME: check if High Speed Device - // - QueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED; - QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01; - QueueHead->Token.DWord = 0; - QueueHead->Token.Bits.InterruptOnComplete = FALSE; - - // - // store address - // - QueueHead->PhysicalAddr = QueueHeadPhysicalAddress.LowPart; - - // - // output queue head - // - *OutQueueHead = QueueHead; - - // - // done - // - return STATUS_SUCCESS; -} - -//---------------------------------------------------------------------------------------- -UCHAR -STDMETHODCALLTYPE -CUSBRequest::GetDeviceAddress() -{ - PIO_STACK_LOCATION IoStack; - PURB Urb; - PUSBDEVICE UsbDevice; - - // - // check if there is an irp provided - // - if (!m_Irp) - { - // - // used provided address - // - return m_DeviceAddress; - } - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(m_Irp); - - // - // get contained urb - // - Urb = (PURB)IoStack->Parameters.Others.Argument1; - - // - // check if there is a pipe handle provided - // - if (Urb->UrbHeader.UsbdDeviceHandle) - { - // - // there is a device handle provided - // - UsbDevice = (PUSBDEVICE)Urb->UrbHeader.UsbdDeviceHandle; - - // - // return device address - // - return UsbDevice->GetDeviceAddress(); - } - - // - // no device handle provided, it is the host root bus - // - return 0; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBRequest::BuildSetupPacket() -{ - NTSTATUS Status; - - // - // allocate common buffer setup packet - // - Status = m_DmaManager->Allocate(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET), (PVOID*)&m_DescriptorPacket, &m_DescriptorSetupPacket); - if (!NT_SUCCESS(Status)) - { - // - // no memory - // - return Status; - } - - if (m_SetupPacket) - { - // - // copy setup packet - // - RtlCopyMemory(m_DescriptorPacket, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - } - else - { - // - // build setup packet from urb - // - Status = BuildSetupPacketFromURB(); - } - - // - // done - // - return Status; -} - - -NTSTATUS -CUSBRequest::BuildSetupPacketFromURB() -{ - PIO_STACK_LOCATION IoStack; - PURB Urb; - NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - - // - // sanity checks - // - PC_ASSERT(m_Irp); - PC_ASSERT(m_DescriptorPacket); - - // - // get stack location - // - IoStack = IoGetCurrentIrpStackLocation(m_Irp); - - // - // get urb - // - Urb = (PURB)IoStack->Parameters.Others.Argument1; - - // - // zero descriptor packet - // - RtlZeroMemory(m_DescriptorPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - - - switch (Urb->UrbHeader.Function) - { - /* CLEAR FEATURE */ - case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: - case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: - case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: - UNIMPLEMENTED; - break; - - /* GET CONFIG */ - case URB_FUNCTION_GET_CONFIGURATION: - m_DescriptorPacket->bRequest = USB_REQUEST_GET_CONFIGURATION; - m_DescriptorPacket->bmRequestType.B = 0x80; - m_DescriptorPacket->wLength = 1; - break; - - /* GET DESCRIPTOR */ - case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: - m_DescriptorPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR; - m_DescriptorPacket->wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; - m_DescriptorPacket->wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; - m_DescriptorPacket->wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; - m_DescriptorPacket->wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength; - m_DescriptorPacket->bmRequestType.B = 0x80; - break; - - /* GET INTERFACE */ - case URB_FUNCTION_GET_INTERFACE: - m_DescriptorPacket->bRequest = USB_REQUEST_GET_CONFIGURATION; - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x80; - m_DescriptorPacket->wLength = 1; - break; - - /* GET STATUS */ - case URB_FUNCTION_GET_STATUS_FROM_DEVICE: - m_DescriptorPacket->bRequest = USB_REQUEST_GET_STATUS; - ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x80; - m_DescriptorPacket->wLength = 2; - break; - - case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: - m_DescriptorPacket->bRequest = USB_REQUEST_GET_STATUS; - ASSERT(Urb->UrbControlGetStatusRequest.Index != 0); - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x81; - m_DescriptorPacket->wLength = 2; - break; - - case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: - m_DescriptorPacket->bRequest = USB_REQUEST_GET_STATUS; - ASSERT(Urb->UrbControlGetStatusRequest.Index != 0); - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x82; - m_DescriptorPacket->wLength = 2; - break; - - /* SET ADDRESS */ - - /* SET CONFIG */ - case URB_FUNCTION_SELECT_CONFIGURATION: - m_DescriptorPacket->bRequest = USB_REQUEST_SET_CONFIGURATION; - m_DescriptorPacket->wValue.W = Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue; - m_DescriptorPacket->wIndex.W = 0; - m_DescriptorPacket->wLength = 0; - m_DescriptorPacket->bmRequestType.B = 0x00; - break; - - /* SET DESCRIPTOR */ - case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE: - case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE: - case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT: - UNIMPLEMENTED; - break; - - /* SET FEATURE */ - case URB_FUNCTION_SET_FEATURE_TO_DEVICE: - m_DescriptorPacket->bRequest = USB_REQUEST_SET_FEATURE; - ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x80; - break; - - case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: - m_DescriptorPacket->bRequest = USB_REQUEST_SET_FEATURE; - ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x81; - break; - - case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: - m_DescriptorPacket->bRequest = USB_REQUEST_SET_FEATURE; - ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); - m_DescriptorPacket->wIndex.W = Urb->UrbControlGetStatusRequest.Index; - m_DescriptorPacket->bmRequestType.B = 0x82; - break; - - /* SET INTERFACE*/ - case URB_FUNCTION_SELECT_INTERFACE: - m_DescriptorPacket->bRequest = USB_REQUEST_SET_INTERFACE; - m_DescriptorPacket->wValue.W = Urb->UrbSelectInterface.Interface.AlternateSetting; - m_DescriptorPacket->wIndex.W = Urb->UrbSelectInterface.Interface.InterfaceNumber; - m_DescriptorPacket->wLength = 0; - m_DescriptorPacket->bmRequestType.B = 0x01; - break; - - /* SYNC FRAME */ - case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: - UNIMPLEMENTED; - break; - default: - UNIMPLEMENTED; - break; - } - - return Status; -} - -//---------------------------------------------------------------------------------------- -VOID -STDMETHODCALLTYPE -CUSBRequest::GetResultStatus( - OUT OPTIONAL NTSTATUS * NtStatusCode, - OUT OPTIONAL PULONG UrbStatusCode) -{ - // - // sanity check - // - PC_ASSERT(m_CompletionEvent); - - // - // wait for the operation to complete - // - KeWaitForSingleObject(m_CompletionEvent, Executive, KernelMode, FALSE, NULL); - - // - // copy status - // - if (NtStatusCode) - { - *NtStatusCode = m_NtStatusCode; - } - - // - // copy urb status - // - if (UrbStatusCode) - { - *UrbStatusCode = m_UrbStatusCode; - } - -} - -//----------------------------------------------------------------------------------------- -BOOLEAN -STDMETHODCALLTYPE -CUSBRequest::ShouldReleaseRequestAfterCompletion() -{ - if (m_Irp) - { ... 21788 lines suppressed ...
4 years, 11 months
1
0
0
0
[reactos] 01/01: [WINHTTP_WINETEST] Skip several tests from execution in order to prevent testbot hangs. ROSTESTS-350
by Victor Perevertkin
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0685e02d9ee69ba5ff4d0…
commit 0685e02d9ee69ba5ff4d024d41ec40801d701161 Author: Victor Perevertkin <victor.perevertkin(a)reactos.org> AuthorDate: Mon Jan 6 05:36:39 2020 +0300 Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org> CommitDate: Mon Jan 6 05:36:39 2020 +0300 [WINHTTP_WINETEST] Skip several tests from execution in order to prevent testbot hangs. ROSTESTS-350 --- modules/rostests/winetests/winhttp/winhttp.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/modules/rostests/winetests/winhttp/winhttp.c b/modules/rostests/winetests/winhttp/winhttp.c index 7ed8a527fca..776ee53e379 100644 --- a/modules/rostests/winetests/winhttp/winhttp.c +++ b/modules/rostests/winetests/winhttp/winhttp.c @@ -3228,9 +3228,12 @@ static void test_multiple_reads(int port) ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); ok(ret, "failed to send request %u\n", GetLastError()); + trace("waiting for response\n"); ret = WinHttpReceiveResponse(req, NULL); ok(ret == TRUE, "expected success\n"); + trace("finished waiting for response\n"); + for (;;) { DWORD len = 0xdeadbeef; @@ -3249,6 +3252,7 @@ static void test_multiple_reads(int port) HeapFree( GetProcessHeap(), 0, buf ); if (!bytes_read) break; total_len += bytes_read; + trace("read bytes %u, total_len: %u\n", bytes_read, total_len); } if (!len) break; } @@ -4880,6 +4884,22 @@ START_TEST (winhttp) test_multi_authentication(si.port); test_large_data_authentication(si.port); test_bad_header(si.port); +#ifdef __REACTOS__ + if (!winetest_interactive) + { + skip("Skipping tests due to hang. See ROSTESTS-350\n"); + } + else + { + test_multiple_reads(si.port); + test_cookies(si.port); + test_request_path_escapes(si.port); + test_passport_auth(si.port); + + /* send the basic request again to shutdown the server thread */ + test_basic_request(si.port, NULL, quitW); + } +#else test_multiple_reads(si.port); test_cookies(si.port); test_request_path_escapes(si.port); @@ -4887,6 +4907,7 @@ START_TEST (winhttp) /* send the basic request again to shutdown the server thread */ test_basic_request(si.port, NULL, quitW); +#endif WaitForSingleObject(thread, 3000); CloseHandle(thread);
4 years, 11 months
1
0
0
0
← Newer
1
...
6
7
8
9
10
11
12
13
14
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Results per page:
10
25
50
100
200