Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

646 lines
15 KiB

  1. //**************************************************************************
  2. //
  3. // Title : WDMKServ.cpp
  4. //
  5. // Date : 1997.12.02 1st making
  6. //
  7. // Author : Toshiba [PCS](PSY) Hideki Yagi
  8. //
  9. // Copyright 1997 Toshiba Corporation. All Rights Reserved.
  10. //
  11. // -------------------------------------------------------------------------
  12. //
  13. // Change log :
  14. //
  15. // Date Revision Description
  16. // ------------ ---------- -----------------------------------------------
  17. // 1997.12.02 000.0000 1st making.
  18. //
  19. //**************************************************************************
  20. #include "includes.h"
  21. #include "hal.h"
  22. #include "wdmkserv.h"
  23. #include "mpevent.h"
  24. #include "classlib.h"
  25. #include "ctime.h"
  26. #include "schdat.h"
  27. #include "ccque.h"
  28. #include "ctvctrl.h"
  29. #include "hlight.h"
  30. #include "hwdevex.h"
  31. // 1998.06.09 Seichan
  32. // ����Define���L���ɂ����ƁAPCI�̃R���t�B�O���Ԃ𒼐ڑ��삷���悤�ɂȂ�
  33. //#define DIRECTPCICONFIG
  34. BOOL CWDMKernelService::Init( DWORD address, HW_DEVICE_EXTENSION *pHwDevExt, PCHAR szID )
  35. {
  36. if( address==0 || pHwDevExt==NULL ){
  37. return( FALSE );
  38. }
  39. m_ioBase = address;
  40. m_pHwDevExt = pHwDevExt;
  41. m_IntCount = 0;
  42. m_OldIrql = 0;
  43. m_pThread = NULL;
  44. m_Irql = (KIRQL)((pHwDevExt->Irq) & 0xFF );
  45. if( m_Irql>31 ){
  46. DBG_PRINTF( ("DVDWDM: Invalid IRQL!!\n\r") );
  47. DBG_BREAK();
  48. return( FALSE );
  49. }
  50. KeInitializeEvent( &m_Event, NotificationEvent, FALSE );
  51. DBG_PRINTF( ("KSERV:HwDevExt=%08x\n\r", m_pHwDevExt) );
  52. // save MAchine informaton.
  53. strncpy( m_MachineID, szID, 19 );
  54. m_MachineID[19] = '0';
  55. DBG_PRINTF( ("KSERV:MachineID = %s\n\r", m_MachineID ) );
  56. return( TRUE );
  57. }
  58. BOOL CWDMKernelService::InitConfig( DWORD Id )
  59. {
  60. #ifdef DIRECTPCICONFIG
  61. if( Id==0 ){
  62. return( FALSE );
  63. }
  64. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  65. m_PCIConfigData = 0xffffffff;
  66. for( ULONG i = 0 ; i < 32; i ++ )
  67. {
  68. for( ULONG j = 0 ; j < 32; j ++ )
  69. {
  70. WRITE_PORT_ULONG( (PULONG)0xcf8, ( i << 16 ) | (j << 11 ) | 0x80000000 );
  71. ULONG Data = READ_PORT_ULONG( (PULONG)0xcfc );
  72. if( Data != 0xffffffff )
  73. {
  74. DBG_PRINTF(("(%d,%d)=0x%x", i,j,Data ));
  75. };
  76. if( Data == Id )
  77. {
  78. DBG_PRINTF(("!!!!!!\r\n"));
  79. m_PCIConfigData = (i << 16 ) | (j << 11 ) | 0x80000000;
  80. break;
  81. }
  82. };
  83. };
  84. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  85. #endif
  86. return( TRUE );
  87. }
  88. BOOL CWDMKernelService::SetPCIConfigData( DWORD address, DWORD data )
  89. {
  90. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  91. return( FALSE );
  92. }
  93. if( address>0xFF ){
  94. DBG_BREAK();
  95. return( FALSE );
  96. }
  97. #ifdef DIRECTPCICONFIG
  98. // DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
  99. if( m_PCIConfigData == 0xffffffff )
  100. return FALSE;
  101. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  102. WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
  103. WRITE_PORT_ULONG( (PULONG)0xcfc, data );
  104. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  105. return TRUE;
  106. #else
  107. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  108. return( StreamClassReadWriteConfig( m_pHwDevExt,
  109. FALSE,
  110. &data,
  111. address,
  112. 4 ) );
  113. #endif
  114. }
  115. BOOL CWDMKernelService::SetPCIConfigData( DWORD address, WORD data )
  116. {
  117. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  118. return( FALSE );
  119. }
  120. if( address>0xFF ){
  121. DBG_BREAK();
  122. return( FALSE );
  123. }
  124. #ifdef DIRECTPCICONFIG
  125. // DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
  126. if( m_PCIConfigData == 0xffffffff )
  127. return FALSE;
  128. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  129. WRITE_PORT_ULONG( (PULONG)0xcf8, (m_PCIConfigData | address) & 0xfffffffc );
  130. ULONG OrgData = READ_PORT_ULONG( (PULONG)0xcfc );
  131. switch( address % 4 )
  132. {
  133. case 0:
  134. WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xffff0000 ) | (DWORD)data );
  135. break;
  136. case 2:
  137. WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0x0000ffff ) | ((DWORD)data << 16) );
  138. break;
  139. default:
  140. DBG_BREAK();
  141. };
  142. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  143. return TRUE;
  144. #else
  145. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  146. return( StreamClassReadWriteConfig( m_pHwDevExt,
  147. FALSE,
  148. &data,
  149. address,
  150. 2 ) );
  151. #endif
  152. }
  153. BOOL CWDMKernelService::SetPCIConfigData( DWORD address, BYTE data )
  154. {
  155. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  156. return( FALSE );
  157. }
  158. if( address>0xFF ){
  159. DBG_BREAK();
  160. return( FALSE );
  161. }
  162. #ifdef DIRECTPCICONFIG
  163. // DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
  164. if( m_PCIConfigData == 0xffffffff )
  165. return FALSE;
  166. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  167. WRITE_PORT_ULONG( (PULONG)0xcf8, (m_PCIConfigData | address) & 0xfffffffc );
  168. ULONG OrgData = READ_PORT_ULONG( (PULONG)0xcfc );
  169. switch( address % 4 )
  170. {
  171. case 0:
  172. WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xffffff00 ) | (DWORD)data );
  173. break;
  174. case 1:
  175. WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xffff00ff ) | ((DWORD)data << 8) );
  176. break;
  177. case 2:
  178. WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0xff00ffff ) | ((DWORD)data << 16) );
  179. break;
  180. case 3:
  181. WRITE_PORT_ULONG( (PULONG)0xcfc, (OrgData & 0x00ffffff ) | ((DWORD)data << 24) );
  182. break;
  183. };
  184. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  185. return TRUE;
  186. #else
  187. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  188. return( StreamClassReadWriteConfig( m_pHwDevExt,
  189. FALSE,
  190. &data,
  191. address,
  192. 1 ) );
  193. #endif
  194. }
  195. BOOL CWDMKernelService::GetPCIConfigData( DWORD address, DWORD *data )
  196. {
  197. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  198. return( FALSE );
  199. }
  200. if( address>0xFF ){
  201. DBG_BREAK();
  202. return( FALSE );
  203. }
  204. #ifdef DIRECTPCICONFIG
  205. // DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
  206. if( m_PCIConfigData == 0xffffffff )
  207. return FALSE;
  208. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  209. WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
  210. *data = READ_PORT_ULONG( (PULONG)0xcfc );
  211. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  212. // return TRUE;
  213. #else
  214. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  215. StreamClassReadWriteConfig( m_pHwDevExt,
  216. TRUE,
  217. data,
  218. address,
  219. 4 );
  220. #endif
  221. if( address==0x2C ){
  222. if( *data!=0x8888123F ){
  223. return( TRUE );
  224. }
  225. if( strncmp( m_MachineID, "TECRA", 5 )==0 ){
  226. *data = 0x00011179;
  227. }else if( strncmp( m_MachineID, "PORTEGE", 7 )==0 ){
  228. *data = 0x00021179;
  229. }
  230. }
  231. return( TRUE );
  232. }
  233. BOOL CWDMKernelService::GetPCIConfigData( DWORD address, WORD *data )
  234. {
  235. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  236. return( FALSE );
  237. }
  238. if( address>0xFF ){
  239. DBG_BREAK();
  240. return( FALSE );
  241. }
  242. #ifdef DIRECTPCICONFIG
  243. // DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
  244. if( m_PCIConfigData == 0xffffffff )
  245. return FALSE;
  246. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  247. WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
  248. switch( address % 4 )
  249. {
  250. case 0:
  251. *data = (WORD)(READ_PORT_ULONG( (PULONG)0xcfc ) & 0xffff);
  252. break;
  253. case 2:
  254. *data = (WORD)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 16 ) & 0xffff );
  255. break;
  256. default:
  257. *data = 0xffff;
  258. DBG_BREAK();
  259. };
  260. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  261. // return TRUE;
  262. #else
  263. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  264. StreamClassReadWriteConfig( m_pHwDevExt,
  265. TRUE,
  266. data,
  267. address,
  268. 2 );
  269. #endif
  270. if( address==0x2C ){
  271. if( *data!=0x123F ){
  272. return( TRUE );
  273. }
  274. if( strncmp( m_MachineID, "TECRA", 5 )==0 ){
  275. *data = 0x1179;
  276. }else if( strncmp( m_MachineID, "PORTEGE", 7 )==0 ){
  277. *data = 0x1179;
  278. }
  279. }
  280. if( address==0x2E ){
  281. if( *data!=0x8888 ){
  282. return( TRUE );
  283. }
  284. if( strncmp( m_MachineID, "TECRA", 5 )==0 ){
  285. *data = 0x0001;
  286. }else if( strncmp( m_MachineID, "PORTEGE", 7 )==0 ){
  287. *data = 0x0002;
  288. }
  289. }
  290. return( TRUE );
  291. }
  292. BOOL CWDMKernelService::GetPCIConfigData( DWORD address, BYTE *data )
  293. {
  294. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  295. return( FALSE );
  296. }
  297. if( address>0xFF ){
  298. DBG_BREAK();
  299. return( FALSE );
  300. }
  301. #ifdef DIRECTPCICONFIG
  302. // DBG_PRINTF( ("XXXPCIConfigData currIrql = 0x%0x LINE=%d\n\r", KeGetCurrentIrql(),__LINE__ ) );
  303. if( m_PCIConfigData == 0xffffffff )
  304. return FALSE;
  305. ULONG OldPort = READ_PORT_ULONG( (PULONG)0xcf8 );
  306. WRITE_PORT_ULONG( (PULONG)0xcf8, ( m_PCIConfigData | address) & 0xfffffffc );
  307. switch( address % 4 )
  308. {
  309. case 0:
  310. *data = (BYTE)(READ_PORT_ULONG( (PULONG)0xcfc ) & 0xff);
  311. break;
  312. case 1:
  313. *data = (BYTE)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 8 ) & 0xff );
  314. break;
  315. case 2:
  316. *data = (BYTE)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 16 ) & 0xff );
  317. break;
  318. case 3:
  319. *data = (BYTE)((READ_PORT_ULONG( (PULONG)0xcfc ) >> 24 ) & 0xff );
  320. break;
  321. };
  322. WRITE_PORT_ULONG( (PULONG)0xcf8, OldPort );
  323. return TRUE;
  324. #else
  325. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  326. return( StreamClassReadWriteConfig( m_pHwDevExt,
  327. TRUE,
  328. data,
  329. address,
  330. 1 ) );
  331. #endif
  332. }
  333. BOOL CWDMKernelService::SetPortData( DWORD address, DWORD data )
  334. {
  335. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  336. return( FALSE );
  337. }
  338. if( address>0xFFFF ){
  339. DBG_BREAK();
  340. return( FALSE );
  341. }
  342. PULONG addr = (PULONG)(m_ioBase + address);
  343. ULONG o_data = (ULONG)data;
  344. WRITE_PORT_ULONG( addr, o_data );
  345. return( TRUE );
  346. }
  347. BOOL CWDMKernelService::SetPortData( DWORD address, WORD data )
  348. {
  349. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  350. return( FALSE );
  351. }
  352. if( address>0xFFFF ){
  353. DBG_BREAK();
  354. return( FALSE );
  355. }
  356. PUSHORT addr = (PUSHORT)(m_ioBase + address);
  357. USHORT o_data = (USHORT)data;
  358. WRITE_PORT_USHORT( addr, o_data );
  359. return( TRUE );
  360. }
  361. BOOL CWDMKernelService::SetPortData( DWORD address, BYTE data )
  362. {
  363. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  364. return( FALSE );
  365. }
  366. if( address>0xFFFF ){
  367. DBG_BREAK();
  368. return( FALSE );
  369. }
  370. PUCHAR addr = (PUCHAR)(m_ioBase + address);
  371. UCHAR o_data = (UCHAR)data;
  372. WRITE_PORT_UCHAR( addr, o_data );
  373. return( TRUE );
  374. }
  375. BOOL CWDMKernelService::GetPortData( DWORD address, DWORD *data )
  376. {
  377. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  378. return( FALSE );
  379. }
  380. if( address>0xFFFF ){
  381. DBG_BREAK();
  382. return( FALSE );
  383. }
  384. PULONG addr = (PULONG)(m_ioBase + address);
  385. *data = READ_PORT_ULONG( addr );
  386. return( TRUE );
  387. }
  388. BOOL CWDMKernelService::GetPortData( DWORD address, WORD *data )
  389. {
  390. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  391. return( FALSE );
  392. }
  393. if( address>0xFFFF ){
  394. DBG_BREAK();
  395. return( FALSE );
  396. }
  397. PUSHORT addr = (PUSHORT)(m_ioBase + address);
  398. *data = READ_PORT_USHORT( addr );
  399. return( TRUE );
  400. }
  401. BOOL CWDMKernelService::GetPortData( DWORD address, BYTE *data )
  402. {
  403. if( m_ioBase==0 || m_pHwDevExt==NULL ){
  404. return( FALSE );
  405. }
  406. if( address>0xFFFF ){
  407. DBG_BREAK();
  408. return( FALSE );
  409. }
  410. PUCHAR addr = (PUCHAR)(m_ioBase + address);
  411. *data = READ_PORT_UCHAR( addr );
  412. return( TRUE );
  413. }
  414. BOOL CWDMKernelService::GetTickCount( DWORD *pTickCount )
  415. {
  416. ULONGLONG ticks;
  417. ULONGLONG rate;
  418. DWORD time;
  419. ticks = (ULONGLONG)KeQueryPerformanceCounter((PLARGE_INTEGER)&rate).QuadPart;
  420. //
  421. // convert from ticks to 100ns clock
  422. //
  423. ticks = ( (ticks & 0xFFFFFFFF00000000) / rate * 10000000 +
  424. (ticks & 0xFFFFFFFF) * 10000000 /rate );
  425. //
  426. // convert from ticks to 1ms clock
  427. //
  428. time = (DWORD)( ticks / 10000 );
  429. *pTickCount = time;
  430. return( TRUE );
  431. }
  432. BOOL CWDMKernelService::Sleep( DWORD SleepCount )
  433. {
  434. DWORD StartTime, EndTime, CurrentTime;
  435. LARGE_INTEGER time, rate;
  436. LARGE_INTEGER waittime;
  437. time = KeQueryPerformanceCounter( &rate );
  438. CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
  439. // DBG_PRINTF(("Sleep: Start = x0x%x\n\r", CurrentTime ));
  440. time = KeQueryPerformanceCounter( &rate );
  441. StartTime = (DWORD)( (time.QuadPart*1000)/rate.QuadPart );
  442. EndTime = StartTime + SleepCount;
  443. if( KeGetCurrentIrql() > PASSIVE_LEVEL ){
  444. while( TRUE ){
  445. KeStallExecutionProcessor( 1000 );
  446. time = KeQueryPerformanceCounter( &rate );
  447. CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
  448. //DBG_PRINTF(("Sleep: Current = x0%x, End = 0x%x\r\n", CurrentTime, EndTime ));
  449. if( CurrentTime>=EndTime )
  450. break;
  451. }
  452. }else{
  453. waittime.QuadPart = SleepCount * 10000;
  454. while( TRUE ){
  455. KeWaitForSingleObject( &m_Event, Executive,
  456. KernelMode, FALSE, &waittime );
  457. time = KeQueryPerformanceCounter( &rate );
  458. CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
  459. if( CurrentTime >= EndTime ){
  460. break;
  461. }else{
  462. waittime.QuadPart = (EndTime-CurrentTime) * 10000;
  463. }
  464. }
  465. }
  466. time = KeQueryPerformanceCounter( &rate );
  467. CurrentTime = (DWORD)(( (time.QuadPart*1000)/(rate.QuadPart) ));
  468. // DBG_PRINTF(("Sleep: End = 0x%x\n\r", CurrentTime ));
  469. return( TRUE );
  470. }
  471. void CWDMKernelService::DisableHwInt( void )
  472. {
  473. KIRQL currIrql;
  474. currIrql = KeGetCurrentIrql();
  475. if( m_IntCount==0 ){
  476. if( currIrql == m_Irql ){
  477. m_OldIrql = m_Irql;
  478. m_IntCount++;
  479. return;
  480. }
  481. KeRaiseIrql( m_Irql, &m_OldIrql );
  482. }
  483. m_IntCount++;
  484. return;
  485. }
  486. void CWDMKernelService::EnableHwInt( void )
  487. {
  488. m_IntCount--;
  489. if( m_IntCount==0 ){
  490. if( m_OldIrql == m_Irql ){
  491. return;
  492. }
  493. KeLowerIrql( m_OldIrql );
  494. }
  495. return;
  496. }
  497. BOOL CWDMKernelService::CheckInt( void )
  498. {
  499. if( m_IntCount != 0 ){
  500. DBG_BREAK();
  501. }
  502. return(TRUE);
  503. }