Leaked source code of windows server 2003
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.

2533 lines
81 KiB

  1. /*** object.c - Object access functions
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created 01/27/97
  6. *
  7. * MODIFICATION HISTORY
  8. */
  9. #include "pch.h"
  10. #ifdef LOCKABLE_PRAGMA
  11. #pragma ACPI_LOCKABLE_DATA
  12. #pragma ACPI_LOCKABLE_CODE
  13. #endif
  14. /***LP ReadObject - Read object
  15. *
  16. * ENTRY
  17. * pctxt -> CTXT
  18. * pdataObj -> object
  19. * pdataResult -> result object
  20. *
  21. * EXIT-SUCCESS
  22. * returns STATUS_SUCCESS
  23. * EXIT-FAILURE
  24. * returns AMLIERR_ code
  25. */
  26. NTSTATUS LOCAL ReadObject(PCTXT pctxt, POBJDATA pdataObj, POBJDATA pdataResult)
  27. {
  28. TRACENAME("READOBJECT")
  29. NTSTATUS rc = STATUS_SUCCESS;
  30. PACCFIELDUNIT pafu;
  31. ENTER(3, ("ReadObject(pctxt=%x,pdataObj=%x,pdataResult=%x)\n",
  32. pctxt, pdataObj, pdataResult));
  33. pdataObj = GetBaseData(pdataObj);
  34. switch (pdataObj->dwDataType)
  35. {
  36. case OBJTYPE_FIELDUNIT:
  37. if ((rc = PushFrame(pctxt, SIG_ACCFIELDUNIT, sizeof(ACCFIELDUNIT),
  38. AccFieldUnit, &pafu)) == STATUS_SUCCESS)
  39. {
  40. pafu->pdataObj = pdataObj;
  41. pafu->FrameHdr.dwfFrame = AFUF_READFIELDUNIT;
  42. pafu->pdata = pdataResult;
  43. }
  44. break;
  45. case OBJTYPE_BUFFFIELD:
  46. rc = ReadField(pctxt, pdataObj,
  47. &((PBUFFFIELDOBJ)pdataObj->pbDataBuff)->FieldDesc,
  48. pdataResult);
  49. break;
  50. default:
  51. ASSERT(pdataResult->dwDataType == OBJTYPE_UNKNOWN);
  52. CopyObjData(pdataResult, pdataObj);
  53. #ifdef DEBUGGER
  54. if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  55. {
  56. PRINTF("=");
  57. PrintObject(pdataResult);
  58. }
  59. #endif
  60. }
  61. EXIT(3, ("ReadObject=%x (Type=%s,Value=%x,Buff=%x)\n",
  62. rc, GetObjectTypeName(pdataResult->dwDataType),
  63. pdataResult->uipDataValue, pdataResult->pbDataBuff));
  64. return rc;
  65. } //ReadObject
  66. /***LP WriteObject - Write object
  67. *
  68. * ENTRY
  69. * pctxt -> CTXT
  70. * pdataObj -> object
  71. * pdataSrc -> source data
  72. *
  73. * EXIT-SUCCESS
  74. * returns STATUS_SUCCESS
  75. * EXIT-FAILURE
  76. * returns AMLIERR_ code
  77. */
  78. NTSTATUS LOCAL WriteObject(PCTXT pctxt, POBJDATA pdataObj, POBJDATA pdataSrc)
  79. {
  80. TRACENAME("WRITEOBJECT")
  81. NTSTATUS rc = STATUS_SUCCESS;
  82. PACCFIELDUNIT pafu;
  83. ENTER(3, ("WriteObject(pctxt=%x,pdataObj=%x,pdataSrc=%x)\n",
  84. pctxt, pdataObj, pdataSrc));
  85. pdataObj = GetBaseData(pdataObj);
  86. switch (pdataObj->dwDataType)
  87. {
  88. case OBJTYPE_FIELDUNIT:
  89. if ((rc = PushFrame(pctxt, SIG_ACCFIELDUNIT, sizeof(ACCFIELDUNIT),
  90. AccFieldUnit, &pafu)) == STATUS_SUCCESS)
  91. {
  92. pafu->pdataObj = pdataObj;
  93. pafu->pdata = pdataSrc;
  94. }
  95. break;
  96. case OBJTYPE_BUFFFIELD:
  97. rc = WriteField(pctxt, pdataObj,
  98. &((PBUFFFIELDOBJ)pdataObj->pbDataBuff)->FieldDesc,
  99. pdataSrc);
  100. break;
  101. case OBJTYPE_DEBUG:
  102. #ifdef DEBUGGER
  103. if (gDebugger.dwfDebugger & DBGF_VERBOSE_ON)
  104. {
  105. DumpObject(pdataSrc, NULL, 0);
  106. }
  107. #endif
  108. rc = STATUS_SUCCESS;
  109. break;
  110. case OBJTYPE_UNKNOWN:
  111. //
  112. // Since the target object could be a global NameSpace object,
  113. // allocate memory from the global heap just to be safe.
  114. //
  115. rc = DupObjData(gpheapGlobal, pdataObj, pdataSrc);
  116. break;
  117. case OBJTYPE_INTDATA:
  118. rc = CopyObjBuffer((PUCHAR)&pdataObj->uipDataValue, sizeof(ULONG),
  119. pdataSrc);
  120. break;
  121. case OBJTYPE_STRDATA:
  122. rc = CopyObjBuffer(pdataObj->pbDataBuff, pdataObj->dwDataLen - 1,
  123. pdataSrc);
  124. break;
  125. case OBJTYPE_BUFFDATA:
  126. rc = CopyObjBuffer(pdataObj->pbDataBuff, pdataObj->dwDataLen,
  127. pdataSrc);
  128. break;
  129. default:
  130. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  131. ("WriteObject: unexpected target object type (type=%s)",
  132. GetObjectTypeName(pdataObj->dwDataType)));
  133. }
  134. EXIT(3, ("WriteObject=%x (ObjType=%s,DataType=%x,Value=%x,Buff=%x)\n",
  135. rc, GetObjectTypeName(pdataObj->dwDataType), pdataSrc->dwDataType,
  136. pdataSrc->uipDataValue, pdataSrc->pbDataBuff));
  137. return rc;
  138. } //WriteObject
  139. /***LP AccFieldUnit - Access a FieldUnit object
  140. *
  141. * ENTRY
  142. * pctxt -> CTXT
  143. * pafu -> ACCFIELDUNIT
  144. * rc - status code
  145. *
  146. * EXIT-SUCCESS
  147. * returns STATUS_SUCCESS
  148. * EXIT-FAILURE
  149. * returns AMLIERR_ code
  150. */
  151. NTSTATUS LOCAL AccFieldUnit(PCTXT pctxt, PACCFIELDUNIT pafu, NTSTATUS rc)
  152. {
  153. TRACENAME("ACCFIELDUNIT")
  154. ULONG dwStage = (rc == STATUS_SUCCESS)?
  155. (pafu->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 3;
  156. PFIELDUNITOBJ pfu;
  157. POBJDATA pdataParent, pdataBank;
  158. PBANKFIELDOBJ pbf;
  159. ENTER(3, ("AccFieldUnit(Stage=%d,pctxt=%x,pafu=%x,rc=%x)\n",
  160. dwStage, pctxt, pafu, rc));
  161. ASSERT(pafu->FrameHdr.dwSig == SIG_ACCFIELDUNIT);
  162. pfu = (PFIELDUNITOBJ)pafu->pdataObj->pbDataBuff;
  163. switch (dwStage)
  164. {
  165. case 0:
  166. //
  167. // Stage 0: Set bank if necessary.
  168. //
  169. pafu->FrameHdr.dwfFrame++;
  170. pdataParent = &pfu->pnsFieldParent->ObjData;
  171. if (pdataParent->dwDataType == OBJTYPE_BANKFIELD)
  172. {
  173. pbf = (PBANKFIELDOBJ)pdataParent->pbDataBuff;
  174. pdataBank = &pbf->pnsBank->ObjData;
  175. rc = PushAccFieldObj(pctxt, WriteFieldObj, pdataBank,
  176. &((PFIELDUNITOBJ)pdataBank->pbDataBuff)->FieldDesc,
  177. (PUCHAR)&pbf->dwBankValue,
  178. sizeof(ULONG));
  179. break;
  180. }
  181. case 1:
  182. //
  183. // Stage 1: Acquire GlobalLock if necessary.
  184. //
  185. pafu->FrameHdr.dwfFrame++;
  186. if (NeedGlobalLock(pfu))
  187. {
  188. if ((rc = AcquireGL(pctxt)) != STATUS_SUCCESS)
  189. {
  190. break;
  191. }
  192. }
  193. case 2:
  194. //
  195. // Stage 2: Read/Write the field.
  196. //
  197. pafu->FrameHdr.dwfFrame++;
  198. //
  199. // If we come here and we need global lock, we must have got it.
  200. //
  201. if (pfu->FieldDesc.dwFieldFlags & FDF_NEEDLOCK)
  202. {
  203. pafu->FrameHdr.dwfFrame |= AFUF_HAVE_GLOBALLOCK;
  204. }
  205. if (pafu->FrameHdr.dwfFrame & AFUF_READFIELDUNIT)
  206. {
  207. rc = ReadField(pctxt, pafu->pdataObj, &pfu->FieldDesc,
  208. pafu->pdata);
  209. }
  210. else
  211. {
  212. rc = WriteField(pctxt, pafu->pdataObj, &pfu->FieldDesc,
  213. pafu->pdata);
  214. }
  215. if ((rc == AMLISTA_PENDING) ||
  216. (&pafu->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  217. {
  218. break;
  219. }
  220. case 3:
  221. //
  222. // Stage 3: Clean up.
  223. //
  224. if (pafu->FrameHdr.dwfFrame & AFUF_HAVE_GLOBALLOCK)
  225. {
  226. ReleaseGL(pctxt);
  227. }
  228. #ifdef DEBUGGER
  229. if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
  230. {
  231. if (pafu->FrameHdr.dwfFrame & AFUF_READFIELDUNIT)
  232. {
  233. PRINTF("=");
  234. PrintObject(pafu->pdata);
  235. }
  236. }
  237. #endif
  238. PopFrame(pctxt);
  239. }
  240. EXIT(3, ("AccFieldUnit=%x\n", rc));
  241. return rc;
  242. } //AccFieldUnit
  243. /***LP ReadField - Read data from a field object
  244. *
  245. * ENTRY
  246. * pctxt -> CTXT
  247. * pdataObj -> object
  248. * pfd -> field descriptor
  249. * pdataResult -> result object
  250. *
  251. * EXIT-SUCCESS
  252. * returns STATUS_SUCCESS
  253. * EXIT-FAILURE
  254. * returns AMLIERR_ code
  255. */
  256. NTSTATUS LOCAL ReadField(PCTXT pctxt, POBJDATA pdataObj, PFIELDDESC pfd,
  257. POBJDATA pdataResult)
  258. {
  259. TRACENAME("READFIELD")
  260. NTSTATUS rc = STATUS_SUCCESS;
  261. ENTER(3, ("ReadField(pctxt=%x,pdataObj=%x,FieldDesc=%x,pdataResult=%x)\n",
  262. pctxt, pdataObj, pfd, pdataResult));
  263. if ((pfd->dwFieldFlags & ACCTYPE_MASK) <= ACCTYPE_DWORD)
  264. {
  265. PUCHAR pb;
  266. ULONG dwcb;
  267. switch (pdataResult->dwDataType)
  268. {
  269. case OBJTYPE_UNKNOWN:
  270. if (!(pfd->dwFieldFlags & FDF_BUFFER_TYPE) &&
  271. (pfd->dwNumBits <= sizeof(ULONG)*8))
  272. {
  273. pdataResult->dwDataType = OBJTYPE_INTDATA;
  274. pb = (PUCHAR)&pdataResult->uipDataValue;
  275. dwcb = sizeof(ULONG);
  276. }
  277. else
  278. {
  279. pdataResult->dwDataType = OBJTYPE_BUFFDATA;
  280. pdataResult->dwDataLen = (pfd->dwNumBits + 7)/8;
  281. if ((pdataResult->pbDataBuff =
  282. NEWBDOBJ(gpheapGlobal, pdataResult->dwDataLen))
  283. == NULL)
  284. {
  285. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  286. ("ReadField: failed to allocate target buffer (size=%d)",
  287. pdataResult->dwDataLen));
  288. pb = NULL;
  289. dwcb = 0;
  290. }
  291. else
  292. {
  293. MEMZERO(pdataResult->pbDataBuff,
  294. pdataResult->dwDataLen);
  295. pb = pdataResult->pbDataBuff;
  296. dwcb = pdataResult->dwDataLen;
  297. }
  298. }
  299. break;
  300. case OBJTYPE_INTDATA:
  301. pb = (PUCHAR)&pdataResult->uipDataValue;
  302. dwcb = sizeof(ULONG);
  303. break;
  304. case OBJTYPE_STRDATA:
  305. pb = pdataResult->pbDataBuff;
  306. dwcb = pdataResult->dwDataLen - 1;
  307. break;
  308. case OBJTYPE_BUFFDATA:
  309. pb = pdataResult->pbDataBuff;
  310. dwcb = pdataResult->dwDataLen;
  311. break;
  312. default:
  313. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  314. ("ReadField: invalid target data type (type=%s)",
  315. GetObjectTypeName(pdataResult->dwDataType)));
  316. pb = NULL;
  317. dwcb = 0;
  318. }
  319. if (rc == STATUS_SUCCESS)
  320. rc = PushAccFieldObj(pctxt, ReadFieldObj, pdataObj, pfd, pb, dwcb);
  321. }
  322. else if (pdataObj->dwDataType == OBJTYPE_FIELDUNIT)
  323. {
  324. //
  325. // This is an access type we don't know how to handle, so try to find
  326. // a raw access handler to handle it.
  327. //
  328. rc = RawFieldAccess(pctxt, RSACCESS_READ, pdataObj, pdataResult);
  329. }
  330. else
  331. {
  332. rc = AMLI_LOGERR(AMLIERR_INVALID_ACCSIZE,
  333. ("ReadField: invalid access size for buffer field (FieldFlags=%x)",
  334. pfd->dwFieldFlags));
  335. }
  336. EXIT(3, ("ReadField=%x\n", rc));
  337. return rc;
  338. } //ReadField
  339. /***LP WriteField - Write data to a field object
  340. *
  341. * ENTRY
  342. * pctxt -> CTXT
  343. * pdataObj -> object
  344. * pfd -> field descriptor
  345. * pdataSrc -> source data
  346. *
  347. * EXIT-SUCCESS
  348. * returns STATUS_SUCCESS
  349. * EXIT-FAILURE
  350. * returns AMLIERR_ code
  351. */
  352. NTSTATUS LOCAL WriteField(PCTXT pctxt, POBJDATA pdataObj, PFIELDDESC pfd,
  353. POBJDATA pdataSrc)
  354. {
  355. TRACENAME("WRITEFIELD")
  356. NTSTATUS rc = STATUS_SUCCESS;
  357. ULONG dwDataInc = (pfd->dwNumBits + 7)/8;
  358. PUCHAR pbBuff;
  359. ULONG dwBuffSize;
  360. ENTER(3, ("WriteField(pctxt=%x,pdataObj=%x,FieldDesc=%x,pdataSrc=%x)\n",
  361. pctxt, pdataObj, pfd, pdataSrc));
  362. if ((pfd->dwFieldFlags & ACCTYPE_MASK) <= ACCTYPE_DWORD)
  363. {
  364. PWRFIELDLOOP pwfl;
  365. switch (pdataSrc->dwDataType)
  366. {
  367. case OBJTYPE_INTDATA:
  368. dwBuffSize = MIN(sizeof(ULONG), dwDataInc);
  369. pbBuff = (PUCHAR)&pdataSrc->uipDataValue;
  370. break;
  371. case OBJTYPE_STRDATA:
  372. dwBuffSize = pdataSrc->dwDataLen - 1;
  373. pbBuff = pdataSrc->pbDataBuff;
  374. break;
  375. case OBJTYPE_BUFFDATA:
  376. dwBuffSize = pdataSrc->dwDataLen;
  377. pbBuff = pdataSrc->pbDataBuff;
  378. break;
  379. default:
  380. rc = AMLI_LOGERR(AMLIERR_UNEXPECTED_OBJTYPE,
  381. ("WriteField: invalid source data type (type=%s)\n",
  382. GetObjectTypeName(pdataSrc->dwDataType)));
  383. dwBuffSize = 0;
  384. pbBuff = NULL;
  385. }
  386. if ((rc == STATUS_SUCCESS) &&
  387. ((rc = PushFrame(pctxt, SIG_WRFIELDLOOP, sizeof(WRFIELDLOOP),
  388. WriteFieldLoop, &pwfl)) == STATUS_SUCCESS))
  389. {
  390. pwfl->pdataObj = pdataObj;
  391. pwfl->pfd = pfd;
  392. pwfl->pbBuff = pbBuff;
  393. pwfl->dwBuffSize = dwBuffSize;
  394. pwfl->dwDataInc = dwDataInc;
  395. }
  396. }
  397. else if (pdataObj->dwDataType == OBJTYPE_FIELDUNIT)
  398. {
  399. //
  400. // This is an access type we don't know how to handle, so try to find
  401. // a raw access handler to handle it.
  402. //
  403. rc = RawFieldAccess(pctxt, RSACCESS_WRITE, pdataObj, pdataSrc);
  404. }
  405. else
  406. {
  407. rc = AMLI_LOGERR(AMLIERR_INVALID_ACCSIZE,
  408. ("WriteField: invalid access size for buffer field (FieldFlags=%x)",
  409. pfd->dwFieldFlags));
  410. }
  411. EXIT(3, ("WriteField=%x\n", rc));
  412. return rc;
  413. } //WriteField
  414. /***LP WriteFieldLoop - executing the loop for the WriteField operation
  415. *
  416. * ENTRY
  417. * pctxt -> CTXT
  418. * pwfl -> WRFIELDLOOP
  419. * rc - status code
  420. *
  421. * EXIT-SUCCESS
  422. * returns STATUS_SUCCESS
  423. * EXIT-FAILURE
  424. * returns AMLIERR_ code
  425. */
  426. NTSTATUS LOCAL WriteFieldLoop(PCTXT pctxt, PWRFIELDLOOP pwfl, NTSTATUS rc)
  427. {
  428. TRACENAME("WRITEFIELDLOOP")
  429. ULONG dwStage = (rc == STATUS_SUCCESS)?
  430. (pwfl->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 1;
  431. ULONG dwXactionSize;
  432. ENTER(3, ("WriteFieldLoop(Stage=%d,pctxt=%x,pwfl=%x,rc=%x)\n",
  433. dwStage, pctxt, pwfl, rc));
  434. ASSERT(pwfl->FrameHdr.dwSig == SIG_WRFIELDLOOP);
  435. switch (dwStage)
  436. {
  437. case 0:
  438. //
  439. // Stage 0: Do loop.
  440. //
  441. if (pwfl->dwBuffSize > 0)
  442. {
  443. dwXactionSize = MIN(pwfl->dwDataInc, pwfl->dwBuffSize);
  444. rc = PushAccFieldObj(pctxt, WriteFieldObj, pwfl->pdataObj,
  445. pwfl->pfd, pwfl->pbBuff, dwXactionSize);
  446. pwfl->dwBuffSize -= dwXactionSize;
  447. pwfl->pbBuff += dwXactionSize;
  448. break;
  449. }
  450. pwfl->FrameHdr.dwfFrame++;
  451. case 1:
  452. //
  453. // Stage 1: Clean up.
  454. //
  455. PopFrame(pctxt);
  456. }
  457. EXIT(3, ("WriteFieldLoop=%x\n", rc));
  458. return rc;
  459. } //WriteFieldLoop
  460. /***LP PushAccFieldObj - Push a AccFieldObj frame on the stack
  461. *
  462. * ENTRY
  463. * pctxt -> CTXT
  464. * pfnAcc -> access function
  465. * pdataObj -> object
  466. * pfd -> field descriptor
  467. * pb -> data buffer
  468. * dwcb - buffer size
  469. *
  470. * EXIT-SUCCESS
  471. * returns STATUS_SUCCESS
  472. * EXIT-FAILURE
  473. * returns AMLIERR_ code
  474. */
  475. NTSTATUS LOCAL PushAccFieldObj(PCTXT pctxt, PFNPARSE pfnAcc, POBJDATA pdataObj,
  476. PFIELDDESC pfd, PUCHAR pb, ULONG dwcb)
  477. {
  478. TRACENAME("PUSHACCFIELDOBJ")
  479. NTSTATUS rc = STATUS_SUCCESS;
  480. PACCFIELDOBJ pafo;
  481. ENTER(3, ("PushAccFieldObj(pctxt=%x,pfnAcc=%x,pdataObj=%x,FieldDesc=%x,pb=%x,Size=%d)\n",
  482. pctxt, pfnAcc, pdataObj, pfd, pb, dwcb));
  483. if ((rc = PushFrame(pctxt, SIG_ACCFIELDOBJ, sizeof(ACCFIELDOBJ), pfnAcc,
  484. &pafo)) == STATUS_SUCCESS)
  485. {
  486. pafo->pdataObj = pdataObj;
  487. pafo->pbBuff = pb;
  488. pafo->pbBuffEnd = pb + dwcb;
  489. pafo->dwAccSize = ACCSIZE(pfd->dwFieldFlags);
  490. ASSERT((pafo->dwAccSize == sizeof(UCHAR)) ||
  491. (pafo->dwAccSize == sizeof(USHORT)) ||
  492. (pafo->dwAccSize == sizeof(ULONG)));
  493. pafo->dwcAccesses = (pfd->dwStartBitPos + pfd->dwNumBits +
  494. pafo->dwAccSize*8 - 1)/(pafo->dwAccSize*8);
  495. pafo->dwDataMask = SHIFTLEFT(1L, pafo->dwAccSize*8) - 1;
  496. pafo->iLBits = pafo->dwAccSize*8 - pfd->dwStartBitPos;
  497. pafo->iRBits = (int)pfd->dwStartBitPos;
  498. MEMCPY(&pafo->fd, pfd, sizeof(FIELDDESC));
  499. }
  500. EXIT(3, ("PushAccFieldObj=%x\n", rc));
  501. return rc;
  502. } //PushAccFieldObj
  503. /***LP ReadFieldObj - Read data from a field object
  504. *
  505. * ENTRY
  506. * pctxt -> CTXT
  507. * pafo -> ACCFIELDOBJ
  508. * rc - status code
  509. *
  510. * EXIT-SUCCESS
  511. * returns STATUS_SUCCESS
  512. * EXIT-FAILURE
  513. * returns AMLIERR_ code
  514. */
  515. NTSTATUS LOCAL ReadFieldObj(PCTXT pctxt, PACCFIELDOBJ pafo, NTSTATUS rc)
  516. {
  517. TRACENAME("READFIELDOBJ")
  518. ULONG dwStage = (rc == STATUS_SUCCESS)?
  519. (pafo->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 3;
  520. POBJDATA pdataParent;
  521. ENTER(3, ("ReadFieldObj(Stage=%d,pctxt=%x,pafo=%x,rc=%x)\n",
  522. dwStage, pctxt, pafo, rc));
  523. ASSERT(pafo->FrameHdr.dwSig == SIG_ACCFIELDOBJ);
  524. switch (dwStage)
  525. {
  526. case 0:
  527. Stage0:
  528. //
  529. // Stage 0: Set Index if necessary.
  530. //
  531. if (pafo->iAccess >= (int)pafo->dwcAccesses)
  532. {
  533. //
  534. // No access necessary, go straight to clean up.
  535. //
  536. pafo->FrameHdr.dwfFrame += 3;
  537. goto Stage3;
  538. }
  539. else
  540. {
  541. pafo->FrameHdr.dwfFrame++;
  542. if (pafo->pdataObj->dwDataType == OBJTYPE_FIELDUNIT)
  543. {
  544. pdataParent =
  545. &((PFIELDUNITOBJ)pafo->pdataObj->pbDataBuff)->pnsFieldParent->ObjData;
  546. if (pdataParent->dwDataType == OBJTYPE_INDEXFIELD)
  547. {
  548. PINDEXFIELDOBJ pif = (PINDEXFIELDOBJ)pdataParent->pbDataBuff;
  549. rc = PushAccFieldObj(pctxt, WriteFieldObj,
  550. &pif->pnsIndex->ObjData,
  551. &((PFIELDUNITOBJ)pif->pnsIndex->ObjData.pbDataBuff)->FieldDesc,
  552. (PUCHAR)&pafo->fd.dwByteOffset,
  553. sizeof(ULONG));
  554. break;
  555. }
  556. }
  557. }
  558. case 1:
  559. //
  560. // Stage 1: Access field data.
  561. //
  562. pafo->FrameHdr.dwfFrame++;
  563. rc = AccessFieldData(pctxt, pafo->pdataObj, &pafo->fd,
  564. &pafo->dwData, TRUE);
  565. if ((rc != STATUS_SUCCESS) ||
  566. (&pafo->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  567. {
  568. break;
  569. }
  570. case 2:
  571. //
  572. // Stage 2: Massage data into the right bit position.
  573. //
  574. if (pafo->iAccess > 0)
  575. {
  576. WriteSystemMem((ULONG_PTR)pafo->pbBuff, pafo->dwAccSize,
  577. SHIFTLEFT(pafo->dwData, pafo->iLBits) &
  578. pafo->dwDataMask,
  579. (SHIFTLEFT(1L, pafo->iRBits) - 1) << pafo->iLBits);
  580. pafo->pbBuff += pafo->dwAccSize;
  581. if (pafo->pbBuff >= pafo->pbBuffEnd)
  582. {
  583. //
  584. // We ran out of buffer, so we are done (go to clean up).
  585. //
  586. pafo->FrameHdr.dwfFrame++;
  587. goto Stage3;
  588. }
  589. }
  590. pafo->dwData >>= pafo->iRBits;
  591. if ((int)pafo->fd.dwNumBits < pafo->iLBits)
  592. {
  593. pafo->dwData &= SHIFTLEFT(1L, pafo->fd.dwNumBits) - 1;
  594. }
  595. WriteSystemMem((ULONG_PTR)pafo->pbBuff, pafo->dwAccSize,
  596. pafo->dwData,
  597. (SHIFTLEFT(1L, pafo->iLBits) - 1) >> pafo->iRBits);
  598. pafo->fd.dwByteOffset += pafo->dwAccSize;
  599. pafo->fd.dwNumBits -= pafo->dwAccSize*8 - pafo->fd.dwStartBitPos;
  600. pafo->fd.dwStartBitPos = 0;
  601. pafo->iAccess++;
  602. if (pafo->iAccess < (int)pafo->dwcAccesses)
  603. {
  604. //
  605. // Still more accesses to go, back to stage 0.
  606. //
  607. pafo->FrameHdr.dwfFrame -= 2;
  608. goto Stage0;
  609. }
  610. else
  611. {
  612. //
  613. // No more accesses, continue to clean up.
  614. //
  615. pafo->FrameHdr.dwfFrame++;
  616. }
  617. case 3:
  618. Stage3:
  619. //
  620. // Stage 3: Clean up.
  621. //
  622. PopFrame(pctxt);
  623. }
  624. EXIT(3, ("ReadFieldObj=%x\n", rc));
  625. return rc;
  626. } //ReadFieldObj
  627. /***LP WriteFieldObj - Write data to a field object
  628. *
  629. * ENTRY
  630. * pctxt -> CTXT
  631. * pafo -> ACCFIELDOBJ
  632. * rc - status code
  633. *
  634. * EXIT-SUCCESS
  635. * returns STATUS_SUCCESS
  636. * EXIT-FAILURE
  637. * returns AMLIERR_ code
  638. */
  639. NTSTATUS LOCAL WriteFieldObj(PCTXT pctxt, PACCFIELDOBJ pafo, NTSTATUS rc)
  640. {
  641. TRACENAME("WRITEFIELDOBJ")
  642. ULONG dwStage = (rc == STATUS_SUCCESS)?
  643. (pafo->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 3;
  644. POBJDATA pdataParent;
  645. ULONG dwData1;
  646. ENTER(3, ("WriteFieldObj(Stage=%d,pctxt=%x,pafo=%x,rc=%x)\n",
  647. dwStage, pctxt, pafo, rc));
  648. ASSERT(pafo->FrameHdr.dwSig == SIG_ACCFIELDOBJ);
  649. switch (dwStage)
  650. {
  651. case 0:
  652. Stage0:
  653. //
  654. // Stage 0: Set Index if necessary.
  655. //
  656. if (pafo->iAccess >= (int)pafo->dwcAccesses)
  657. {
  658. //
  659. // No access necessary, go straight to clean up.
  660. //
  661. pafo->FrameHdr.dwfFrame += 3;
  662. goto Stage3;
  663. }
  664. else
  665. {
  666. pafo->FrameHdr.dwfFrame++;
  667. if (pafo->pdataObj->dwDataType == OBJTYPE_FIELDUNIT)
  668. {
  669. pdataParent =
  670. &((PFIELDUNITOBJ)pafo->pdataObj->pbDataBuff)->pnsFieldParent->ObjData;
  671. if (pdataParent->dwDataType == OBJTYPE_INDEXFIELD)
  672. {
  673. PINDEXFIELDOBJ pif = (PINDEXFIELDOBJ)pdataParent->pbDataBuff;
  674. rc = PushAccFieldObj(pctxt, WriteFieldObj,
  675. &pif->pnsIndex->ObjData,
  676. &((PFIELDUNITOBJ)pif->pnsIndex->ObjData.pbDataBuff)->FieldDesc,
  677. (PUCHAR)&pafo->fd.dwByteOffset,
  678. sizeof(ULONG));
  679. break;
  680. }
  681. }
  682. }
  683. case 1:
  684. //
  685. // Stage 1: Massage data into the right bit position and write it.
  686. //
  687. pafo->FrameHdr.dwfFrame++;
  688. dwData1 = ReadSystemMem((ULONG_PTR)pafo->pbBuff, pafo->dwAccSize,
  689. pafo->dwDataMask);
  690. if (pafo->iAccess > 0)
  691. {
  692. pafo->dwData = dwData1 >> pafo->iLBits;
  693. pafo->pbBuff += pafo->dwAccSize;
  694. if (pafo->pbBuff >= pafo->pbBuffEnd)
  695. {
  696. dwData1 = 0;
  697. }
  698. else
  699. {
  700. dwData1 = ReadSystemMem((ULONG_PTR)pafo->pbBuff,
  701. pafo->dwAccSize, pafo->dwDataMask);
  702. }
  703. }
  704. else
  705. {
  706. pafo->dwData = 0;
  707. }
  708. pafo->dwData |= (dwData1 << pafo->iRBits) & pafo->dwDataMask;
  709. rc = AccessFieldData(pctxt, pafo->pdataObj, &pafo->fd,
  710. &pafo->dwData, FALSE);
  711. if ((rc == AMLISTA_PENDING) ||
  712. (&pafo->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
  713. {
  714. break;
  715. }
  716. case 2:
  717. //
  718. // Stage 2: Check for more iterations.
  719. //
  720. pafo->fd.dwByteOffset += pafo->dwAccSize;
  721. pafo->fd.dwNumBits -= pafo->dwAccSize*8 - pafo->fd.dwStartBitPos;
  722. pafo->fd.dwStartBitPos = 0;
  723. pafo->iAccess++;
  724. if (pafo->iAccess < (int)pafo->dwcAccesses)
  725. {
  726. //
  727. // Still more accesses to go, back to stage 0.
  728. //
  729. pafo->FrameHdr.dwfFrame -= 2;
  730. goto Stage0;
  731. }
  732. else
  733. {
  734. pafo->FrameHdr.dwfFrame++;
  735. }
  736. case 3:
  737. Stage3:
  738. //
  739. // Stage 3: Clean up.
  740. //
  741. PopFrame(pctxt);
  742. }
  743. EXIT(3, ("WriteFieldObj=%x\n", rc));
  744. return rc;
  745. } //WriteFieldObj
  746. /***LP RawFieldAccess - Find and call the RawAccess handler for the RegionSpace
  747. *
  748. * ENTRY
  749. * pctxt -> CTXT
  750. * dwAccType - read/write
  751. * pdataObj -> field unit object
  752. * pdataResult -> result object
  753. *
  754. * EXIT-SUCCESS
  755. * returns STATUS_SUCCESS
  756. * EXIT-FAILURE
  757. * returns AMLIERR_ code
  758. */
  759. NTSTATUS LOCAL RawFieldAccess(PCTXT pctxt, ULONG dwAccType, POBJDATA pdataObj,
  760. POBJDATA pdataResult)
  761. {
  762. TRACENAME("RAWFIELDACCESS")
  763. NTSTATUS rc = STATUS_SUCCESS;
  764. POBJDATA pdataParent;
  765. POPREGIONOBJ pop;
  766. PRSACCESS prsa;
  767. PFIELDUNITOBJ pfuFieldUnit;
  768. ENTER(3, ("RawFieldAccess(pctxt=%x,AccType=%x,pdataObj=%x,pdata=%x)\n",
  769. pctxt, dwAccType, pdataObj, pdataResult));
  770. pdataParent =
  771. &((PFIELDUNITOBJ)pdataObj->pbDataBuff)->pnsFieldParent->ObjData;
  772. switch (pdataParent->dwDataType)
  773. {
  774. case OBJTYPE_FIELD:
  775. pop = (POPREGIONOBJ)
  776. ((PFIELDOBJ)pdataParent->pbDataBuff)->pnsBase->ObjData.pbDataBuff;
  777. break;
  778. default:
  779. rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
  780. ("RawFieldAccess: invalid field parent type (type=%s)",
  781. pdataParent->dwDataType));
  782. pop = NULL;
  783. }
  784. if (rc == STATUS_SUCCESS)
  785. {
  786. if (((prsa = FindRSAccess(pop->bRegionSpace)) != NULL) &&
  787. (prsa->pfnRawAccess != NULL))
  788. {
  789. #ifdef DEBUGGER
  790. ULONG dwOldFlags = gDebugger.dwfDebugger;
  791. if (dwOldFlags & DBGF_AMLTRACE_ON)
  792. {
  793. gDebugger.dwfDebugger &= ~DBGF_AMLTRACE_ON;
  794. }
  795. #endif
  796. ASSERT(!(pctxt->dwfCtxt & CTXTF_READY));
  797. if ((pfuFieldUnit = NEWFUOBJ(pctxt->pheapCurrent, sizeof (FIELDUNITOBJ))) == NULL) {
  798. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  799. ("RawFieldAccess: failed to allocate Field unit"));
  800. } else {
  801. RtlCopyMemory (pfuFieldUnit, (PFIELDUNITOBJ)pdataObj->pbDataBuff, sizeof (FIELDUNITOBJ));
  802. pfuFieldUnit->FieldDesc.dwByteOffset += (ULONG) pop->uipOffset;
  803. rc = prsa->pfnRawAccess(dwAccType,
  804. pfuFieldUnit,
  805. pdataResult, prsa->uipRawParam,
  806. RestartCtxtCallback, &pctxt->CtxtData);
  807. if (rc == STATUS_BUFFER_TOO_SMALL) {
  808. //
  809. // When opregion handler returns STATUS_BUFFER_TOO_SMALL, this indicates that it
  810. // needs to have a buffer alloocated for it. The buffer size is returned in
  811. // pdataResult->dwDataValue
  812. //
  813. ASSERT(pdataResult->dwDataType == OBJTYPE_INTDATA);
  814. if ((pdataResult->pbDataBuff = NEWBDOBJ(gpheapGlobal, pdataResult->dwDataValue)) == NULL) {
  815. rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  816. ("Buffer: failed to allocate data buffer (size=%d)",
  817. pdataResult->dwDataValue));
  818. } else {
  819. pdataResult->dwDataLen = pdataResult->dwDataValue;
  820. pdataResult->dwDataType = OBJTYPE_BUFFDATA;
  821. rc = prsa->pfnRawAccess(dwAccType,
  822. pfuFieldUnit,
  823. pdataResult, prsa->uipRawParam,
  824. RestartCtxtCallback, &pctxt->CtxtData);
  825. }
  826. }
  827. }
  828. #ifdef DEBUGGER
  829. gDebugger.dwfDebugger = dwOldFlags;
  830. #endif
  831. if (rc == STATUS_PENDING)
  832. {
  833. rc = AMLISTA_PENDING;
  834. }
  835. else if (rc != STATUS_SUCCESS)
  836. {
  837. rc = AMLI_LOGERR(AMLIERR_RS_ACCESS,
  838. ("RawFieldAccess: RegionSpace %x handler returned error %x",
  839. pop->bRegionSpace, rc));
  840. }
  841. }
  842. else
  843. {
  844. rc = AMLI_LOGERR(AMLIERR_INVALID_REGIONSPACE,
  845. ("RawFieldAccess: no handler for RegionSpace %x",
  846. pop->bRegionSpace));
  847. }
  848. }
  849. EXIT(3, ("RawFieldAccess=%x\n", rc));
  850. return rc;
  851. } //RawFieldAccess
  852. /***LP AccessFieldData - Read/Write field object data
  853. *
  854. * ENTRY
  855. * pctxt -> CTXT
  856. * pdataObj -> object
  857. * pfd -> field descriptor
  858. * pdwData -> to hold data read or data to be written
  859. * fRead - TRUE if read access
  860. *
  861. * EXIT-SUCCESS
  862. * returns STATUS_SUCCESS
  863. * EXIT-FAILURE
  864. * returns AMLIERR_ code
  865. */
  866. NTSTATUS LOCAL AccessFieldData(PCTXT pctxt, POBJDATA pdataObj, PFIELDDESC pfd,
  867. PULONG pdwData, BOOLEAN fRead)
  868. {
  869. TRACENAME("ACCESSFIELDDATA")
  870. NTSTATUS rc = STATUS_SUCCESS;
  871. ENTER(3, ("AccessFieldData(pctxt=%x,pdataObj=%x,FieldDesc=%x,pdwData=%x,fRead=%x)\n",
  872. pctxt, pdataObj, pfd, pdwData, fRead));
  873. if (pdataObj->dwDataType == OBJTYPE_BUFFFIELD)
  874. {
  875. if (fRead)
  876. {
  877. rc = ReadBuffField((PBUFFFIELDOBJ)pdataObj->pbDataBuff, pfd,
  878. pdwData);
  879. }
  880. else
  881. {
  882. rc = WriteBuffField((PBUFFFIELDOBJ)pdataObj->pbDataBuff, pfd,
  883. *pdwData);
  884. }
  885. }
  886. else //must be OBJTYPE_FIELDUNIT
  887. {
  888. POBJDATA pdataParent;
  889. PNSOBJ pnsBase = NULL;
  890. pdataParent = &((PFIELDUNITOBJ)pdataObj->pbDataBuff)->pnsFieldParent->ObjData;
  891. if (pdataParent->dwDataType == OBJTYPE_INDEXFIELD)
  892. {
  893. PINDEXFIELDOBJ pif = (PINDEXFIELDOBJ)pdataParent->pbDataBuff;
  894. if (fRead)
  895. {
  896. rc = PushAccFieldObj(pctxt, ReadFieldObj,
  897. &pif->pnsData->ObjData,
  898. &((PFIELDUNITOBJ)pif->pnsData->ObjData.pbDataBuff)->FieldDesc,
  899. (PUCHAR)pdwData, sizeof(ULONG));
  900. }
  901. else
  902. {
  903. ULONG dwPreserveMask, dwAccMask;
  904. dwPreserveMask = ~((SHIFTLEFT(1L, pfd->dwNumBits) - 1) <<
  905. pfd->dwStartBitPos);
  906. dwAccMask = SHIFTLEFT(1L, ACCSIZE(pfd->dwFieldFlags)*8) - 1;
  907. if (((pfd->dwFieldFlags & UPDATERULE_MASK) ==
  908. UPDATERULE_PRESERVE) &&
  909. ((dwPreserveMask & dwAccMask) != 0))
  910. {
  911. rc = PushPreserveWriteObj(pctxt, &pif->pnsData->ObjData,
  912. *pdwData, dwPreserveMask);
  913. }
  914. else
  915. {
  916. rc = PushAccFieldObj(pctxt, WriteFieldObj,
  917. &pif->pnsData->ObjData,
  918. &((PFIELDUNITOBJ)pif->pnsData->ObjData.pbDataBuff)->FieldDesc,
  919. (PUCHAR)pdwData, sizeof(ULONG));
  920. }
  921. }
  922. }
  923. else if ((rc = GetFieldUnitRegionObj(
  924. (PFIELDUNITOBJ)pdataObj->pbDataBuff, &pnsBase)) ==
  925. STATUS_SUCCESS && pnsBase != NULL)
  926. {
  927. rc = AccessBaseField(pctxt, pnsBase, pfd, pdwData, fRead);
  928. }
  929. }
  930. EXIT(3, ("AccessFieldData=%x (Data=%x)\n", rc, pdwData? *pdwData: 0));
  931. return rc;
  932. } //AccessFieldData
  933. /***LP PushPreserveWriteObj - Push a PreserveWrObj frame on the stack
  934. *
  935. * ENTRY
  936. * pctxt -> CTXT
  937. * pdataObj -> object
  938. * dwData - data to be written
  939. * dwPreserveMask - preserve bit mask
  940. *
  941. * EXIT-SUCCESS
  942. * returns STATUS_SUCCESS
  943. * EXIT-FAILURE
  944. * returns AMLIERR_ code
  945. */
  946. NTSTATUS LOCAL PushPreserveWriteObj(PCTXT pctxt, POBJDATA pdataObj,
  947. ULONG dwData, ULONG dwPreserveMask)
  948. {
  949. TRACENAME("PUSHPRESERVEWRITEOBJ")
  950. NTSTATUS rc = STATUS_SUCCESS;
  951. PPRESERVEWROBJ ppwro;
  952. ENTER(3, ("PushPreserveWriteObj(pctxt=%x,pdataObj=%x,Data=%x,PreserveMask=%x)\n",
  953. pctxt, pdataObj, dwData, dwPreserveMask));
  954. if ((rc = PushFrame(pctxt, SIG_PRESERVEWROBJ, sizeof(PRESERVEWROBJ),
  955. PreserveWriteObj, &ppwro)) == STATUS_SUCCESS)
  956. {
  957. ppwro->pdataObj = pdataObj;
  958. ppwro->dwWriteData = dwData;
  959. ppwro->dwPreserveMask = dwPreserveMask;
  960. }
  961. EXIT(3, ("PushPreserveWriteObj=%x\n", rc));
  962. return rc;
  963. } //PushPreserveWriteObj
  964. /***LP PreserveWriteObj - Preserve Write data to a field object
  965. *
  966. * ENTRY
  967. * pctxt -> CTXT
  968. * ppwro -> PRESERVEWROBJ
  969. * rc - status code
  970. *
  971. * EXIT-SUCCESS
  972. * returns STATUS_SUCCESS
  973. * EXIT-FAILURE
  974. * returns AMLIERR_ code
  975. */
  976. NTSTATUS LOCAL PreserveWriteObj(PCTXT pctxt, PPRESERVEWROBJ ppwro, NTSTATUS rc)
  977. {
  978. TRACENAME("PRESERVEWRITEOBJ")
  979. ULONG dwStage = (rc == STATUS_SUCCESS)?
  980. (ppwro->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2;
  981. ENTER(3, ("PreserveWriteObj(Stage=%d,pctxt=%x,ppwro=%x,rc=%x)\n",
  982. dwStage, pctxt, ppwro, rc));
  983. ASSERT(ppwro->FrameHdr.dwSig == SIG_PRESERVEWROBJ);
  984. switch (dwStage)
  985. {
  986. case 0:
  987. //
  988. // Stage 0: Read the object first.
  989. //
  990. ppwro->FrameHdr.dwfFrame++;
  991. rc = PushAccFieldObj(pctxt, ReadFieldObj, ppwro->pdataObj,
  992. &((PFIELDUNITOBJ)ppwro->pdataObj->pbDataBuff)->FieldDesc,
  993. (PUCHAR)&ppwro->dwReadData, sizeof(ULONG));
  994. break;
  995. case 1:
  996. //
  997. // Stage 1: OR the preserve bits to the data to be written and
  998. // write it.
  999. //
  1000. ppwro->FrameHdr.dwfFrame++;
  1001. ppwro->dwWriteData |= ppwro->dwReadData & ppwro->dwPreserveMask;
  1002. rc = PushAccFieldObj(pctxt, WriteFieldObj, ppwro->pdataObj,
  1003. &((PFIELDUNITOBJ)ppwro->pdataObj->pbDataBuff)->FieldDesc,
  1004. (PUCHAR)&ppwro->dwWriteData, sizeof(ULONG));
  1005. break;
  1006. case 2:
  1007. //
  1008. // Stage 2: Clean up.
  1009. //
  1010. PopFrame(pctxt);
  1011. }
  1012. EXIT(3, ("PreserveWriteObj=%x\n", rc));
  1013. return rc;
  1014. } //PreserveWriteObj
  1015. /***LP AccessBaseField - Access the base field object
  1016. *
  1017. * ENTRY
  1018. * pctxt -> CTXT
  1019. * pnsBase -> OpRegion object
  1020. * pfd -> FIELDDESC
  1021. * pdwData -> result data (for read access) or data to be written
  1022. * fRead - TRUE if read access
  1023. *
  1024. * EXIT-SUCCESS
  1025. * returns STATUS_SUCCESS
  1026. * EXIT-FAILURE
  1027. * returns AMLIERR_ code
  1028. *
  1029. * NOTE
  1030. * If pdwData is NULL, it implies a read access.
  1031. */
  1032. NTSTATUS LOCAL AccessBaseField(PCTXT pctxt, PNSOBJ pnsBase, PFIELDDESC pfd,
  1033. PULONG pdwData, BOOLEAN fRead)
  1034. {
  1035. TRACENAME("ACCESSBASEFIELD")
  1036. NTSTATUS rc = STATUS_SUCCESS;
  1037. POPREGIONOBJ pop;
  1038. ULONG_PTR uipAddr;
  1039. ULONG dwSize, dwDataMask, dwAccMask;
  1040. PRSACCESS prsa;
  1041. BOOLEAN fPreserve;
  1042. ENTER(3, ("AccessBaseField(pctxt=%x,pnsBase=%x,pfd=%x,pdwData=%x,fRead=%x)\n",
  1043. pctxt, pnsBase, pfd, pdwData, fRead));
  1044. ASSERT(pnsBase->ObjData.dwDataType == OBJTYPE_OPREGION);
  1045. pop = (POPREGIONOBJ)pnsBase->ObjData.pbDataBuff;
  1046. uipAddr = (ULONG_PTR)(pop->uipOffset + pfd->dwByteOffset);
  1047. dwSize = ACCSIZE(pfd->dwFieldFlags);
  1048. dwDataMask = (SHIFTLEFT(1L, pfd->dwNumBits) - 1) << pfd->dwStartBitPos;
  1049. dwAccMask = SHIFTLEFT(1L, dwSize*8) - 1;
  1050. fPreserve = (BOOLEAN)(((pfd->dwFieldFlags & UPDATERULE_MASK) ==
  1051. UPDATERULE_PRESERVE) &&
  1052. ((~dwDataMask & dwAccMask) != 0));
  1053. //
  1054. // update the result so we are left only with the relavant bits
  1055. //
  1056. *pdwData &= dwDataMask;
  1057. if (!fRead &&
  1058. ((pfd->dwFieldFlags & UPDATERULE_MASK) == UPDATERULE_WRITEASONES))
  1059. {
  1060. *pdwData |= ~dwDataMask;
  1061. }
  1062. switch (pop->bRegionSpace)
  1063. {
  1064. case REGSPACE_MEM:
  1065. if (fRead)
  1066. {
  1067. *pdwData = ReadSystemMem(uipAddr, dwSize, dwDataMask);
  1068. }
  1069. else
  1070. {
  1071. if (fPreserve)
  1072. {
  1073. *pdwData |= ReadSystemMem(uipAddr, dwSize, ~dwDataMask);
  1074. }
  1075. WriteSystemMem(uipAddr, dwSize, *pdwData, dwAccMask);
  1076. }
  1077. break;
  1078. case REGSPACE_IO:
  1079. if (fRead)
  1080. {
  1081. *pdwData = ReadSystemIO((ULONG)uipAddr, dwSize, dwDataMask);
  1082. }
  1083. else
  1084. {
  1085. if (fPreserve)
  1086. {
  1087. *pdwData |= ReadSystemIO((ULONG)uipAddr, dwSize, ~dwDataMask);
  1088. }
  1089. WriteSystemIO((ULONG)uipAddr, dwSize, *pdwData);
  1090. }
  1091. break;
  1092. default:
  1093. if (((prsa = FindRSAccess(pop->bRegionSpace)) != NULL) &&
  1094. (prsa->pfnCookAccess != NULL))
  1095. {
  1096. if (fRead)
  1097. {
  1098. #ifdef DEBUGGER
  1099. ULONG dwOldFlags = gDebugger.dwfDebugger;
  1100. if (dwOldFlags & DBGF_TRACE_NONEST)
  1101. {
  1102. gDebugger.dwfDebugger &= ~DBGF_AMLTRACE_ON;
  1103. }
  1104. #endif
  1105. //
  1106. // Read access.
  1107. //
  1108. ASSERT(!(pctxt->dwfCtxt & CTXTF_READY));
  1109. rc = prsa->pfnCookAccess(RSACCESS_READ, pnsBase, uipAddr,
  1110. dwSize, pdwData, prsa->uipCookParam,
  1111. RestartCtxtCallback,
  1112. &pctxt->CtxtData);
  1113. #ifdef DEBUGGER
  1114. gDebugger.dwfDebugger = dwOldFlags;
  1115. #endif
  1116. if (rc == STATUS_PENDING)
  1117. {
  1118. rc = AMLISTA_PENDING;
  1119. }
  1120. else if (rc != STATUS_SUCCESS)
  1121. {
  1122. rc = AMLI_LOGERR(AMLIERR_RS_ACCESS,
  1123. ("AccessBaseField: RegionSpace %x read handler returned error %x",
  1124. pop->bRegionSpace, rc));
  1125. }
  1126. }
  1127. else
  1128. {
  1129. PWRCOOKACC pwca;
  1130. //
  1131. // Write access.
  1132. //
  1133. if ((rc = PushFrame(pctxt, SIG_WRCOOKACC, sizeof(WRCOOKACC),
  1134. WriteCookAccess, &pwca)) ==
  1135. STATUS_SUCCESS)
  1136. {
  1137. pwca->pnsBase = pnsBase;
  1138. pwca->prsa = prsa;
  1139. pwca->dwAddr = (ULONG)uipAddr;
  1140. pwca->dwSize = dwSize;
  1141. pwca->dwData = *pdwData;
  1142. pwca->dwDataMask = dwDataMask;
  1143. pwca->fPreserve = fPreserve;
  1144. }
  1145. }
  1146. }
  1147. else
  1148. {
  1149. rc = AMLI_LOGERR(AMLIERR_INVALID_REGIONSPACE,
  1150. ("AccessBaseField: no handler for RegionSpace %x",
  1151. pop->bRegionSpace));
  1152. }
  1153. }
  1154. EXIT(3, ("AccessBaseField=%x (Value=%x,Addr=%x,Size=%d,DataMask=%x,AccMask=%x)\n",
  1155. rc, *pdwData, uipAddr, dwSize, dwDataMask, dwAccMask));
  1156. return rc;
  1157. } //AccessBaseField
  1158. /***LP WriteCookAccess - do a region space write cook access
  1159. *
  1160. * ENTRY
  1161. * pctxt -> CTXT
  1162. * pwca -> WRCOOKACC
  1163. * rc - status code
  1164. *
  1165. * EXIT-SUCCESS
  1166. * returns STATUS_SUCCESS
  1167. * EXIT-FAILURE
  1168. * returns AMLIERR_ code
  1169. */
  1170. NTSTATUS LOCAL WriteCookAccess(PCTXT pctxt, PWRCOOKACC pwca, NTSTATUS rc)
  1171. {
  1172. TRACENAME("WRCOOKACCESS")
  1173. ULONG dwStage = (rc == STATUS_SUCCESS)?
  1174. (pwca->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 3;
  1175. KIRQL oldIrql;
  1176. LONG busy;
  1177. POPREGIONOBJ pop = (POPREGIONOBJ)pwca->pnsBase->ObjData.pbDataBuff;
  1178. ENTER(3, ("WriteCookAccess(Stage=%d,pctxt=%x,pwca=%x,rc=%x)\n",
  1179. dwStage, pctxt, pwca, rc));
  1180. ASSERT(pwca->FrameHdr.dwSig == SIG_WRCOOKACC);
  1181. switch (dwStage)
  1182. {
  1183. case 0:
  1184. //
  1185. // Stage 0: if PRESERVE, do read first.
  1186. //
  1187. if (pwca->fPreserve)
  1188. {
  1189. #ifdef DEBUGGER
  1190. ULONG dwOldFlags = gDebugger.dwfDebugger;
  1191. if (dwOldFlags & DBGF_TRACE_NONEST)
  1192. {
  1193. gDebugger.dwfDebugger &= ~DBGF_AMLTRACE_ON;
  1194. }
  1195. #endif
  1196. KeAcquireSpinLock(&pop->listLock, &oldIrql);
  1197. if (busy = InterlockedExchange(&pop->RegionBusy, TRUE)) {
  1198. //
  1199. // Somebody is currently using this operation region.
  1200. // Queue this context so that it can be re-started later.
  1201. //
  1202. QueueContext(pctxt,
  1203. 0xffff,
  1204. &pop->plistWaiters);
  1205. }
  1206. KeReleaseSpinLock(&pop->listLock, oldIrql);
  1207. if (busy) {
  1208. rc = AMLISTA_PENDING;
  1209. break;
  1210. }
  1211. pwca->FrameHdr.dwfFrame++;
  1212. ASSERT(!(pctxt->dwfCtxt & CTXTF_READY));
  1213. rc = pwca->prsa->pfnCookAccess(RSACCESS_READ, pwca->pnsBase,
  1214. (ULONG_PTR)pwca->dwAddr,
  1215. pwca->dwSize,
  1216. &pwca->dwDataTmp,
  1217. pwca->prsa->uipCookParam,
  1218. RestartCtxtCallback,
  1219. &pctxt->CtxtData);
  1220. #ifdef DEBUGGER
  1221. gDebugger.dwfDebugger = dwOldFlags;
  1222. #endif
  1223. if (rc == STATUS_PENDING)
  1224. {
  1225. rc = AMLISTA_PENDING;
  1226. }
  1227. else if (rc != STATUS_SUCCESS)
  1228. {
  1229. rc = AMLI_LOGERR(AMLIERR_RS_ACCESS,
  1230. ("WriteCookAccess: RegionSpace %x read handler returned error %x",
  1231. pop->bRegionSpace, rc));
  1232. }
  1233. if (rc != STATUS_SUCCESS)
  1234. {
  1235. break;
  1236. }
  1237. }
  1238. else
  1239. {
  1240. //
  1241. // No preserve, we can skip the ORing.
  1242. //
  1243. pwca->FrameHdr.dwfFrame += 2;
  1244. goto Stage2;
  1245. }
  1246. case 1:
  1247. //
  1248. // Stage 1: OR the preserved bits.
  1249. //
  1250. pwca->dwData |= pwca->dwDataTmp & ~pwca->dwDataMask;
  1251. pwca->FrameHdr.dwfFrame++;
  1252. case 2:
  1253. Stage2:
  1254. //
  1255. // Stage 2: Write the data.
  1256. //
  1257. #ifdef DEBUGGER
  1258. {
  1259. ULONG dwOldFlags = gDebugger.dwfDebugger;
  1260. if (dwOldFlags & DBGF_TRACE_NONEST)
  1261. {
  1262. gDebugger.dwfDebugger &= ~DBGF_AMLTRACE_ON;
  1263. }
  1264. #endif
  1265. pwca->FrameHdr.dwfFrame++;
  1266. ASSERT(!(pctxt->dwfCtxt & CTXTF_READY));
  1267. rc = pwca->prsa->pfnCookAccess(RSACCESS_WRITE, pwca->pnsBase,
  1268. (ULONG_PTR)pwca->dwAddr,
  1269. pwca->dwSize,
  1270. &pwca->dwData,
  1271. pwca->prsa->uipCookParam,
  1272. RestartCtxtCallback,
  1273. &pctxt->CtxtData);
  1274. #ifdef DEBUGGER
  1275. gDebugger.dwfDebugger = dwOldFlags;
  1276. }
  1277. #endif
  1278. if (rc == STATUS_PENDING)
  1279. {
  1280. rc = AMLISTA_PENDING;
  1281. }
  1282. else if (rc != STATUS_SUCCESS)
  1283. {
  1284. rc = AMLI_LOGERR(AMLIERR_RS_ACCESS,
  1285. ("WriteCookAccess: RegionSpace %x read handler returned error %x",
  1286. pop->bRegionSpace, rc));
  1287. }
  1288. if (rc != STATUS_SUCCESS)
  1289. {
  1290. break;
  1291. }
  1292. case 3:
  1293. if (pwca->fPreserve) {
  1294. KeAcquireSpinLock(&pop->listLock, &oldIrql);
  1295. //
  1296. // Restart anybody who blocked while we were in here.
  1297. //
  1298. DequeueAndReadyContext(&pop->plistWaiters);
  1299. //
  1300. // Release the lock on this op-region.
  1301. //
  1302. InterlockedExchange(&pop->RegionBusy, FALSE);
  1303. KeReleaseSpinLock(&pop->listLock, oldIrql);
  1304. }
  1305. //
  1306. // Stage 3: Clean up.
  1307. //
  1308. PopFrame(pctxt);
  1309. }
  1310. EXIT(3, ("WriteCookAccess=%x\n", rc));
  1311. return rc;
  1312. } //WriteCookAccess
  1313. /***LP ReadBuffField - Read data from a buffer field
  1314. *
  1315. * ENTRY
  1316. * pbf -> buffer field object
  1317. * pfd -> field descriptor
  1318. * pdwData -> to hold result data
  1319. *
  1320. * EXIT-SUCCESS
  1321. * returns STATUS_SUCCESS
  1322. * EXIT-FAILURE
  1323. * returns AMLIERR_ code
  1324. */
  1325. NTSTATUS LOCAL ReadBuffField(PBUFFFIELDOBJ pbf, PFIELDDESC pfd, PULONG pdwData)
  1326. {
  1327. TRACENAME("READBUFFFIELD")
  1328. NTSTATUS rc = STATUS_SUCCESS;
  1329. ULONG dwAccSize = ACCSIZE(pfd->dwFieldFlags);
  1330. ENTER(3, ("ReadBuffField(pbf=%x,pfd=%x,pdwData=%x)\n", pbf, pfd, pdwData));
  1331. if (pfd->dwByteOffset + dwAccSize <= pbf->dwBuffLen)
  1332. {
  1333. ULONG dwMask = (SHIFTLEFT(1L, pfd->dwNumBits) - 1) <<
  1334. pfd->dwStartBitPos;
  1335. *pdwData = ReadSystemMem((ULONG_PTR)(pbf->pbDataBuff +
  1336. pfd->dwByteOffset),
  1337. dwAccSize, dwMask);
  1338. }
  1339. else
  1340. {
  1341. rc = AMLI_LOGERR(AMLIERR_INDEX_TOO_BIG,
  1342. ("ReadBuffField: offset exceeding buffer size (Offset=%x,BuffSize=%x,AccSize)",
  1343. pfd->dwByteOffset, pbf->dwBuffLen, dwAccSize));
  1344. }
  1345. EXIT(3, ("ReadBuffField=%x (Data=%x)\n", rc, *pdwData));
  1346. return rc;
  1347. } //ReadBuffField
  1348. /***LP WriteBuffField - Write data to a buffer field
  1349. *
  1350. * ENTRY
  1351. * pbf -> buffer field object
  1352. * pfd -> field descriptor
  1353. * dwData - data
  1354. *
  1355. * EXIT-SUCCESS
  1356. * returns STATUS_SUCCESS
  1357. * EXIT-FAILURE
  1358. * returns AMLIERR_ code
  1359. */
  1360. NTSTATUS LOCAL WriteBuffField(PBUFFFIELDOBJ pbf, PFIELDDESC pfd, ULONG dwData)
  1361. {
  1362. TRACENAME("WRITEBUFFFIELD")
  1363. NTSTATUS rc = STATUS_SUCCESS;
  1364. ULONG dwAccSize = ACCSIZE(pfd->dwFieldFlags);
  1365. ENTER(3, ("WriteBuffField(pbf=%x,pfd=%x,dwData=%x)\n", pbf, pfd, dwData));
  1366. if (pfd->dwByteOffset + dwAccSize <= pbf->dwBuffLen)
  1367. {
  1368. ULONG dwMask = (SHIFTLEFT(1L, pfd->dwNumBits) - 1) <<
  1369. pfd->dwStartBitPos;
  1370. WriteSystemMem((ULONG_PTR)(pbf->pbDataBuff + pfd->dwByteOffset),
  1371. dwAccSize, dwData & dwMask, dwMask);
  1372. }
  1373. else
  1374. {
  1375. rc = AMLI_LOGERR(AMLIERR_INDEX_TOO_BIG,
  1376. ("WriteBuffField: offset exceeding buffer size (Offset=%x,BuffSize=%x,AccSize=%x)",
  1377. pfd->dwByteOffset, pbf->dwBuffLen, dwAccSize));
  1378. }
  1379. EXIT(3, ("WriteBuffField=%x\n", rc));
  1380. return rc;
  1381. } //WriteBuffField
  1382. /***LP ReadSystemMem - Read system memory
  1383. *
  1384. * ENTRY
  1385. * uipAddr - memory address
  1386. * dwSize - size to read
  1387. * dwMask - data mask
  1388. *
  1389. * EXIT
  1390. * return memory content
  1391. */
  1392. ULONG LOCAL ReadSystemMem(ULONG_PTR uipAddr, ULONG dwSize, ULONG dwMask)
  1393. {
  1394. TRACENAME("READSYSTEMMEM")
  1395. ULONG dwData = 0;
  1396. ULONG dwCount;
  1397. ENTER(3, ("ReadSystemMem(Addr=%x,Size=%d,Mask=%x)\n",
  1398. uipAddr, dwSize, dwMask));
  1399. ASSERT((dwSize == sizeof(UCHAR)) || (dwSize == sizeof(USHORT)) ||
  1400. (dwSize == sizeof(ULONG)));
  1401. #if defined(_IA64_)
  1402. dwCount = dwSize/sizeof(UCHAR);
  1403. ASSERT(dwCount <= (sizeof(ULONG)/sizeof(UCHAR)));
  1404. //
  1405. // check for misalignment
  1406. //
  1407. if (uipAddr % dwCount) {
  1408. //
  1409. // unaligned, do the operation byte-wise
  1410. //
  1411. MEMCPY(&dwData, (PVOID)uipAddr, dwSize);
  1412. } else {
  1413. //
  1414. // aligned, just do the read atomically
  1415. //
  1416. switch (dwSize)
  1417. {
  1418. case sizeof(UCHAR):
  1419. dwData = (ULONG)READ_REGISTER_UCHAR((PUCHAR)uipAddr);
  1420. break;
  1421. case sizeof(USHORT):
  1422. dwData = (ULONG)READ_REGISTER_USHORT((PUSHORT)uipAddr);
  1423. break;
  1424. case sizeof(ULONG):
  1425. dwData = READ_REGISTER_ULONG((PULONG)uipAddr);
  1426. break;
  1427. }
  1428. }
  1429. #else
  1430. MEMCPY(&dwData, (PVOID)uipAddr, dwSize);
  1431. #endif
  1432. dwData &= dwMask;
  1433. EXIT(3, ("ReadSystemMem=%x\n", dwData));
  1434. return dwData;
  1435. } //ReadSystemMem
  1436. /***LP WriteSystemMem - Write system memory
  1437. *
  1438. * ENTRY
  1439. * uipAddr - memory address
  1440. * dwSize - size to write
  1441. * dwData - data to write
  1442. * dwMask - data mask
  1443. *
  1444. * EXIT
  1445. * return memory content
  1446. */
  1447. VOID LOCAL WriteSystemMem(ULONG_PTR uipAddr, ULONG dwSize, ULONG dwData,
  1448. ULONG dwMask)
  1449. {
  1450. TRACENAME("WRITESYSTEMMEM")
  1451. ULONG dwTmpData = 0;
  1452. ULONG dwCount;
  1453. ULONG SizeToMask[5] = { 0x0, 0xff, 0xffff, 0, 0xffffffff };
  1454. BOOLEAN SkipReadOperation = FALSE;
  1455. if (dwMask == SizeToMask[dwSize])
  1456. {
  1457. SkipReadOperation = TRUE;
  1458. }
  1459. ENTER(3, ("WriteSystemMem(Addr=%x,Size=%d,Data=%x,Mask=%x)\n",
  1460. uipAddr, dwSize, dwData, dwMask));
  1461. ASSERT((dwSize == sizeof(UCHAR)) || (dwSize == sizeof(USHORT)) ||
  1462. (dwSize == sizeof(ULONG)));
  1463. #if defined(_IA64_)
  1464. dwCount = dwSize/sizeof(UCHAR);
  1465. ASSERT(dwCount <= (sizeof(ULONG)/sizeof(UCHAR)));
  1466. //
  1467. // check for misalignment
  1468. //
  1469. if (uipAddr % dwCount)
  1470. {
  1471. //
  1472. // unaligned, do the operation byte-wise
  1473. //
  1474. if (!SkipReadOperation)
  1475. {
  1476. MEMCPY(&dwTmpData, (PVOID)uipAddr, dwSize);
  1477. }
  1478. dwTmpData &= ~dwMask;
  1479. dwTmpData |= dwData;
  1480. MEMCPY((PVOID)uipAddr, &dwTmpData, dwSize);
  1481. }
  1482. else
  1483. {
  1484. //
  1485. // aligned access. just get the data atomically.
  1486. //
  1487. switch (dwSize)
  1488. {
  1489. case sizeof(UCHAR):
  1490. if (!SkipReadOperation)
  1491. {
  1492. dwTmpData = READ_REGISTER_UCHAR((PUCHAR)uipAddr);
  1493. }
  1494. dwTmpData &= ~dwMask;
  1495. dwTmpData |= dwData;
  1496. WRITE_REGISTER_UCHAR((PUCHAR)uipAddr, (UCHAR)dwTmpData);
  1497. break;
  1498. case sizeof(USHORT):
  1499. if (!SkipReadOperation)
  1500. {
  1501. dwTmpData = READ_REGISTER_USHORT((PUCHAR)uipAddr);
  1502. }
  1503. dwTmpData &= ~dwMask;
  1504. dwTmpData |= dwData;
  1505. WRITE_REGISTER_USHORT((PUSHORT)uipAddr, (USHORT)dwTmpData);
  1506. break;
  1507. case sizeof(ULONG):
  1508. if (!SkipReadOperation)
  1509. {
  1510. dwTmpData = READ_REGISTER_ULONG((PUCHAR)uipAddr);
  1511. }
  1512. dwTmpData &= ~dwMask;
  1513. dwTmpData |= dwData;
  1514. WRITE_REGISTER_ULONG((PULONG)uipAddr, dwTmpData);
  1515. break;
  1516. }
  1517. }
  1518. #else
  1519. if (!SkipReadOperation)
  1520. {
  1521. MEMCPY(&dwTmpData, (PVOID)uipAddr, dwSize);
  1522. }
  1523. dwTmpData &= ~dwMask;
  1524. dwTmpData |= dwData;
  1525. MEMCPY((PVOID)uipAddr, &dwTmpData, dwSize);
  1526. #endif
  1527. EXIT(3, ("WriteSystemMem!\n"));
  1528. } //WriteSystemMem
  1529. /***LP ReadSystemIO - Read system IO
  1530. *
  1531. * ENTRY
  1532. * dwAddr - memory address
  1533. * dwSize - size to read
  1534. * dwMask - data mask
  1535. *
  1536. * EXIT
  1537. * return memory content
  1538. */
  1539. ULONG LOCAL ReadSystemIO(ULONG dwAddr, ULONG dwSize, ULONG dwMask)
  1540. {
  1541. TRACENAME("READSYSTEMIO")
  1542. ULONG dwData = 0;
  1543. ENTER(3, ("ReadSystemIO(Addr=%x,Size=%d,Mask=%x)\n",
  1544. dwAddr, dwSize, dwMask));
  1545. ASSERT((dwSize == sizeof(UCHAR)) || (dwSize == sizeof(USHORT)) ||
  1546. (dwSize == sizeof(ULONG)));
  1547. if(CheckSystemIOAddressValidity(TRUE, dwAddr, dwSize, &dwData))
  1548. {
  1549. //
  1550. // HACKHACK: We are adding this here because Dell Latitude laptops with Older
  1551. // BIOS (A07 and older) hang in SMI because there is a non zero value\
  1552. // in CH. We now clear CX to work around their bug.
  1553. //
  1554. #ifdef _X86_
  1555. __asm
  1556. {
  1557. xor cx,cx
  1558. }
  1559. #endif //_X86_
  1560. switch (dwSize)
  1561. {
  1562. case sizeof(UCHAR):
  1563. dwData = (ULONG)READ_PORT_UCHAR((PUCHAR)UlongToPtr(dwAddr));
  1564. break;
  1565. case sizeof(USHORT):
  1566. dwData = (ULONG)READ_PORT_USHORT((PUSHORT)UlongToPtr(dwAddr));
  1567. break;
  1568. case sizeof(ULONG):
  1569. dwData = READ_PORT_ULONG((PULONG)UlongToPtr(dwAddr));
  1570. break;
  1571. }
  1572. }
  1573. dwData &= dwMask;
  1574. EXIT(3, ("ReadSystemIO=%x\n", dwData));
  1575. return dwData;
  1576. } //ReadSystemIO
  1577. /***LP WriteSystemIO - Write system IO
  1578. *
  1579. * ENTRY
  1580. * dwAddr - memory address
  1581. * dwSize - size to write
  1582. * dwData - data to write
  1583. *
  1584. * EXIT
  1585. * return memory content
  1586. */
  1587. VOID LOCAL WriteSystemIO(ULONG dwAddr, ULONG dwSize, ULONG dwData)
  1588. {
  1589. TRACENAME("WRITESYSTEMIO")
  1590. ENTER(3, ("WriteSystemIO(Addr=%x,Size=%d,Data=%x)\n",
  1591. dwAddr, dwSize, dwData));
  1592. ASSERT((dwSize == sizeof(UCHAR)) || (dwSize == sizeof(USHORT)) ||
  1593. (dwSize == sizeof(ULONG)));
  1594. if(CheckSystemIOAddressValidity(FALSE, dwAddr, dwSize, &dwData))
  1595. {
  1596. //
  1597. // HACKHACK: We are adding this here because Dell Latitude laptops with Older
  1598. // BIOS (A07 and older) hang in SMI because there is a non zero value\
  1599. // in CH. We now clear CX to work around their bug.
  1600. //
  1601. #ifdef _X86_
  1602. __asm
  1603. {
  1604. xor cx,cx
  1605. }
  1606. #endif //_X86_
  1607. switch (dwSize)
  1608. {
  1609. case sizeof(UCHAR):
  1610. WRITE_PORT_UCHAR((PUCHAR)UlongToPtr(dwAddr), (UCHAR)dwData);
  1611. break;
  1612. case sizeof(USHORT):
  1613. WRITE_PORT_USHORT((PUSHORT)UlongToPtr(dwAddr), (USHORT)dwData);
  1614. break;
  1615. case sizeof(ULONG):
  1616. WRITE_PORT_ULONG((PULONG)UlongToPtr(dwAddr), dwData);
  1617. break;
  1618. }
  1619. }
  1620. EXIT(3, ("WriteSystemIO!\n"));
  1621. } //WriteSystemIO
  1622. #ifdef DEBUGGER
  1623. /***LP DumpObject - Dump object info.
  1624. *
  1625. * ENTRY
  1626. * pdata -> data
  1627. * pszName -> object name
  1628. * iLevel - indent level
  1629. *
  1630. * EXIT
  1631. * None
  1632. *
  1633. * NOTE
  1634. * If iLevel is negative, no indentation and newline are printed.
  1635. */
  1636. VOID LOCAL DumpObject(POBJDATA pdata, PSZ pszName, int iLevel)
  1637. {
  1638. TRACENAME("DUMPOBJECT")
  1639. BOOLEAN fPrintNewLine;
  1640. int i;
  1641. char szName1[sizeof(NAMESEG) + 1],
  1642. szName2[sizeof(NAMESEG) + 1];
  1643. ENTER(3, ("DumpObject(pdata=%x,Name=%s,Level=%d)\n",
  1644. pdata, pszName, iLevel));
  1645. fPrintNewLine = (BOOLEAN)(iLevel >= 0);
  1646. for (i = 0; i < iLevel; ++i)
  1647. {
  1648. PRINTF("| ");
  1649. }
  1650. if (pszName == NULL)
  1651. {
  1652. pszName = "";
  1653. }
  1654. switch (pdata->dwDataType)
  1655. {
  1656. case OBJTYPE_UNKNOWN:
  1657. PRINTF("Unknown(%s)", pszName);
  1658. break;
  1659. case OBJTYPE_INTDATA:
  1660. PRINTF("Integer(%s:Value=0x%08x[%d])",
  1661. pszName, pdata->uipDataValue, pdata->uipDataValue);
  1662. break;
  1663. case OBJTYPE_STRDATA:
  1664. PRINTF("String(%s:Str=\"%s\")", pszName, pdata->pbDataBuff);
  1665. break;
  1666. case OBJTYPE_BUFFDATA:
  1667. PRINTF("Buffer(%s:Ptr=%x,Len=%d)",
  1668. pszName, pdata->pbDataBuff, pdata->dwDataLen);
  1669. PrintBuffData(pdata->pbDataBuff, pdata->dwDataLen);
  1670. break;
  1671. case OBJTYPE_PKGDATA:
  1672. PRINTF("Package(%s:NumElements=%d){",
  1673. pszName, ((PPACKAGEOBJ)pdata->pbDataBuff)->dwcElements);
  1674. if (fPrintNewLine)
  1675. {
  1676. PRINTF("\n");
  1677. }
  1678. for (i = 0;
  1679. i < (int)((PPACKAGEOBJ)pdata->pbDataBuff)->dwcElements;
  1680. ++i)
  1681. {
  1682. DumpObject(&((PPACKAGEOBJ)pdata->pbDataBuff)->adata[i], NULL,
  1683. fPrintNewLine? iLevel + 1: -1);
  1684. if (!fPrintNewLine &&
  1685. (i < (int)((PPACKAGEOBJ)pdata->pbDataBuff)->dwcElements))
  1686. {
  1687. PRINTF(",");
  1688. }
  1689. }
  1690. for (i = 0; i < iLevel; ++i)
  1691. {
  1692. PRINTF("| ");
  1693. }
  1694. PRINTF("}");
  1695. break;
  1696. case OBJTYPE_FIELDUNIT:
  1697. PRINTF("FieldUnit(%s:FieldParent=%p,ByteOffset=0x%x,StartBit=0x%x,NumBits=%d,FieldFlags=0x%x)",
  1698. pszName,
  1699. ((PFIELDUNITOBJ)pdata->pbDataBuff)->pnsFieldParent,
  1700. ((PFIELDUNITOBJ)pdata->pbDataBuff)->FieldDesc.dwByteOffset,
  1701. ((PFIELDUNITOBJ)pdata->pbDataBuff)->FieldDesc.dwStartBitPos,
  1702. ((PFIELDUNITOBJ)pdata->pbDataBuff)->FieldDesc.dwNumBits,
  1703. ((PFIELDUNITOBJ)pdata->pbDataBuff)->FieldDesc.dwFieldFlags);
  1704. break;
  1705. case OBJTYPE_DEVICE:
  1706. PRINTF("Device(%s)", pszName);
  1707. break;
  1708. case OBJTYPE_EVENT:
  1709. PRINTF("Event(%s:pKEvent=%x)", pszName, pdata->pbDataBuff);
  1710. break;
  1711. case OBJTYPE_METHOD:
  1712. PRINTF("Method(%s:Flags=0x%x,CodeBuff=%p,Len=%d)",
  1713. pszName, ((PMETHODOBJ)pdata->pbDataBuff)->bMethodFlags,
  1714. ((PMETHODOBJ)pdata->pbDataBuff)->abCodeBuff,
  1715. pdata->dwDataLen - FIELD_OFFSET(METHODOBJ, abCodeBuff));
  1716. break;
  1717. case OBJTYPE_MUTEX:
  1718. PRINTF("Mutex(%s:pKMutex=%x)", pszName, pdata->pbDataBuff);
  1719. break;
  1720. case OBJTYPE_OPREGION:
  1721. PRINTF("OpRegion(%s:RegionSpace=%s,Offset=0x%x,Len=%d)",
  1722. pszName,
  1723. GetRegionSpaceName(((POPREGIONOBJ)pdata->pbDataBuff)->bRegionSpace),
  1724. ((POPREGIONOBJ)pdata->pbDataBuff)->uipOffset,
  1725. ((POPREGIONOBJ)pdata->pbDataBuff)->dwLen);
  1726. break;
  1727. case OBJTYPE_POWERRES:
  1728. PRINTF("PowerResource(%s:SystemLevel=0x%x,ResOrder=%d)",
  1729. pszName, ((PPOWERRESOBJ)pdata->pbDataBuff)->bSystemLevel,
  1730. ((PPOWERRESOBJ)pdata->pbDataBuff)->bResOrder);
  1731. break;
  1732. case OBJTYPE_PROCESSOR:
  1733. PRINTF("Processor(%s:ApicID=0x%x,PBlk=0x%x,PBlkLen=%d)",
  1734. pszName, ((PPROCESSOROBJ)pdata->pbDataBuff)->bApicID,
  1735. ((PPROCESSOROBJ)pdata->pbDataBuff)->dwPBlk,
  1736. ((PPROCESSOROBJ)pdata->pbDataBuff)->dwPBlkLen);
  1737. break;
  1738. case OBJTYPE_THERMALZONE:
  1739. PRINTF("ThermalZone(%s)", pszName);
  1740. break;
  1741. case OBJTYPE_BUFFFIELD:
  1742. PRINTF("BufferField(%s:Ptr=%x,Len=%d,ByteOffset=0x%x,StartBit=0x%x,NumBits=%d,FieldFlags=0x%x)",
  1743. pszName, ((PBUFFFIELDOBJ)pdata->pbDataBuff)->pbDataBuff,
  1744. ((PBUFFFIELDOBJ)pdata->pbDataBuff)->dwBuffLen,
  1745. ((PBUFFFIELDOBJ)pdata->pbDataBuff)->FieldDesc.dwByteOffset,
  1746. ((PBUFFFIELDOBJ)pdata->pbDataBuff)->FieldDesc.dwStartBitPos,
  1747. ((PBUFFFIELDOBJ)pdata->pbDataBuff)->FieldDesc.dwNumBits,
  1748. ((PBUFFFIELDOBJ)pdata->pbDataBuff)->FieldDesc.dwFieldFlags);
  1749. break;
  1750. case OBJTYPE_DDBHANDLE:
  1751. PRINTF("DDBHandle(%s:Handle=%x)", pszName, pdata->pbDataBuff);
  1752. break;
  1753. case OBJTYPE_OBJALIAS:
  1754. PRINTF("ObjectAlias(%s:Alias=%s,Type=%s)",
  1755. pszName, GetObjectPath(pdata->pnsAlias),
  1756. GetObjectTypeName(pdata->pnsAlias->ObjData.dwDataType));
  1757. break;
  1758. case OBJTYPE_DATAALIAS:
  1759. PRINTF("DataAlias(%s:Link=%x)", pszName, pdata->pdataAlias);
  1760. if (fPrintNewLine)
  1761. {
  1762. DumpObject(pdata->pdataAlias, NULL, iLevel + 1);
  1763. fPrintNewLine = FALSE;
  1764. }
  1765. break;
  1766. case OBJTYPE_BANKFIELD:
  1767. STRCPYN(szName1,
  1768. (PSZ)(&((PBANKFIELDOBJ)pdata->pbDataBuff)->pnsBase->dwNameSeg),
  1769. sizeof(NAMESEG));
  1770. STRCPYN(szName2,
  1771. (PSZ)(&((PBANKFIELDOBJ)pdata->pbDataBuff)->pnsBank->dwNameSeg),
  1772. sizeof(NAMESEG));
  1773. PRINTF("BankField(%s:Base=%s,BankName=%s,BankValue=0x%x)",
  1774. pszName, szName1, szName2,
  1775. ((PBANKFIELDOBJ)pdata->pbDataBuff)->dwBankValue);
  1776. break;
  1777. case OBJTYPE_FIELD:
  1778. STRCPYN(szName1,
  1779. (PSZ)(&((PFIELDOBJ)pdata->pbDataBuff)->pnsBase->dwNameSeg),
  1780. sizeof(NAMESEG));
  1781. PRINTF("Field(%s:Base=%s)", pszName, szName1);
  1782. break;
  1783. case OBJTYPE_INDEXFIELD:
  1784. STRCPYN(szName1,
  1785. (PSZ)(&((PINDEXFIELDOBJ)pdata->pbDataBuff)->pnsIndex->dwNameSeg),
  1786. sizeof(NAMESEG));
  1787. STRCPYN(szName2,
  1788. (PSZ)(&((PINDEXFIELDOBJ)pdata->pbDataBuff)->pnsData->dwNameSeg),
  1789. sizeof(NAMESEG));
  1790. PRINTF("IndexField(%s:IndexName=%s,DataName=%s)",
  1791. pszName, szName1, szName2);
  1792. break;
  1793. default:
  1794. AMLI_ERROR(("DumpObject: unexpected data object type (type=%x)",
  1795. pdata->dwDataType));
  1796. }
  1797. if (fPrintNewLine)
  1798. {
  1799. PRINTF("\n");
  1800. }
  1801. EXIT(3, ("DumpObject!\n"));
  1802. } //DumpObject
  1803. #endif
  1804. /***LP NeedGlobalLock - check if global lock is required
  1805. *
  1806. * ENTRY
  1807. * pfu - FIELDUNITOBJ
  1808. *
  1809. * EXIT-SUCCESS
  1810. * returns TRUE
  1811. * EXIT-FAILURE
  1812. * returns FALSE
  1813. */
  1814. BOOLEAN LOCAL NeedGlobalLock(PFIELDUNITOBJ pfu)
  1815. {
  1816. TRACENAME("NEEDGLOBALLOCK")
  1817. BOOLEAN rc = FALSE;
  1818. ENTER(3, ("NeedGlobalLock(pfu=%x)\n", pfu));
  1819. if ((pfu->FieldDesc.dwFieldFlags & FDF_NEEDLOCK) ||
  1820. (pfu->FieldDesc.dwFieldFlags & LOCKRULE_LOCK))
  1821. {
  1822. rc = TRUE;
  1823. }
  1824. else
  1825. {
  1826. POBJDATA pdataParent = &pfu->pnsFieldParent->ObjData;
  1827. PFIELDUNITOBJ pfuParent;
  1828. if (pdataParent->dwDataType == OBJTYPE_BANKFIELD)
  1829. {
  1830. pfuParent = (PFIELDUNITOBJ)
  1831. ((PBANKFIELDOBJ)pdataParent->pbDataBuff)->pnsBank->ObjData.pbDataBuff;
  1832. if (pfuParent->FieldDesc.dwFieldFlags & LOCKRULE_LOCK)
  1833. {
  1834. rc = TRUE;
  1835. }
  1836. }
  1837. else if (pdataParent->dwDataType == OBJTYPE_INDEXFIELD)
  1838. {
  1839. pfuParent = (PFIELDUNITOBJ)
  1840. ((PINDEXFIELDOBJ)pdataParent->pbDataBuff)->pnsIndex->ObjData.pbDataBuff;
  1841. if (pfuParent->FieldDesc.dwFieldFlags & LOCKRULE_LOCK)
  1842. {
  1843. rc = TRUE;
  1844. }
  1845. else
  1846. {
  1847. pfuParent = (PFIELDUNITOBJ)
  1848. ((PINDEXFIELDOBJ)pdataParent->pbDataBuff)->pnsData->ObjData.pbDataBuff;
  1849. if (pfuParent->FieldDesc.dwFieldFlags & LOCKRULE_LOCK)
  1850. {
  1851. rc = TRUE;
  1852. }
  1853. }
  1854. }
  1855. }
  1856. if (rc == TRUE)
  1857. {
  1858. pfu->FieldDesc.dwFieldFlags |= FDF_NEEDLOCK;
  1859. }
  1860. EXIT(3, ("NeedGlobalLock=%x\n", rc));
  1861. return rc;
  1862. } //NeedGlobalLock
  1863. /***LP CheckSystemIOAddressValidity - Check if the address is a legal IO address
  1864. *
  1865. * ENTRY
  1866. * fRead - TRUE iff access is a read. FALSE on write
  1867. * dwAddr - memory address
  1868. * ULONG dwSize - Size of data
  1869. * PULONG pdwData - Pointer to the data buffer.
  1870. *
  1871. * EXIT
  1872. * return TRUE on Valid address
  1873. */
  1874. BOOLEAN LOCAL CheckSystemIOAddressValidity( BOOLEAN fRead,
  1875. ULONG dwAddr,
  1876. ULONG dwSize,
  1877. PULONG pdwData
  1878. )
  1879. {
  1880. TRACENAME("CHECKSYSTEMIOADDRESSVALIDITY")
  1881. ULONG i = 0;
  1882. BOOLEAN bRet = TRUE;
  1883. ENTER(3, ("CheckSystemIOAddressValidity(fRead=%s, dwAddr=%x, dwSize=%x, pdwData=%x)\n", (fRead?"TRUE":"FALSE"),dwAddr, dwSize, pdwData));
  1884. //
  1885. // check if list exists on this platform.
  1886. //
  1887. if(gpBadIOAddressList)
  1888. {
  1889. //
  1890. // Walk the list till we hit the end.
  1891. //
  1892. for(i=0; gpBadIOAddressList[i].BadAddrSize != 0 ; i++)
  1893. {
  1894. //
  1895. // Check if the incoming address is in the range
  1896. //
  1897. if((dwAddr >= (gpBadIOAddressList[i].BadAddrBegin)) && (dwAddr < ((gpBadIOAddressList[i].BadAddrBegin) + (gpBadIOAddressList[i].BadAddrSize))))
  1898. {
  1899. //
  1900. // Check if we need to ignore this address for legacy reasons.
  1901. //
  1902. if(gpBadIOAddressList[i].OSVersionTrigger <= gdwHighestOSVerQueried)
  1903. {
  1904. bRet = FALSE;
  1905. PRINTF("CheckSystemIOAddressValidity: failing illegal IO address (0x%x).\n", dwAddr);
  1906. }
  1907. else
  1908. {
  1909. PRINTF("CheckSystemIOAddressValidity: Passing for compatibility reasons on illegal IO address (0x%x).\n", dwAddr);
  1910. if(gpBadIOAddressList[i].IOHandler)
  1911. {
  1912. //
  1913. // Since we are handeling this here we can return FALSE. This way the
  1914. // calling function will not process this request.
  1915. //
  1916. bRet = FALSE;
  1917. //
  1918. // Call HAL and let it handle this IO request
  1919. //
  1920. (gpBadIOAddressList[i].IOHandler)(fRead, dwAddr, dwSize, pdwData);
  1921. PRINTF("CheckSystemIOAddressValidity: HAL IO handler called to %s address (0x%x). %s 0x%8lx\n",
  1922. fRead ? "read" : "write",
  1923. dwAddr,
  1924. fRead ? "Read" : "Wrote",
  1925. *pdwData
  1926. );
  1927. }
  1928. }
  1929. //
  1930. // Log the illegal access to the event log.
  1931. //
  1932. if (KeGetCurrentIrql() < DISPATCH_LEVEL)
  1933. {
  1934. LogInErrorLog(fRead,
  1935. dwAddr,
  1936. i
  1937. );
  1938. }
  1939. else
  1940. {
  1941. PIO_WORKITEM Log_WorkItem = NULL;
  1942. PDEVICE_OBJECT pACPIDeviceObject = ACPIGetRootDeviceObject();
  1943. if(pACPIDeviceObject)
  1944. {
  1945. Log_WorkItem = IoAllocateWorkItem(pACPIDeviceObject);
  1946. if(Log_WorkItem)
  1947. {
  1948. PAMLI_LOG_WORKITEM_CONTEXT pWorkItemContext = NULL;
  1949. pWorkItemContext = (PAMLI_LOG_WORKITEM_CONTEXT) ExAllocatePoolWithTag(NonPagedPool,
  1950. sizeof(AMLI_LOG_WORKITEM_CONTEXT),
  1951. PRIV_TAG
  1952. );
  1953. if(pWorkItemContext)
  1954. {
  1955. pWorkItemContext->fRead = fRead;
  1956. pWorkItemContext->Address = dwAddr;
  1957. pWorkItemContext->Index = i;
  1958. pWorkItemContext->pIOWorkItem = Log_WorkItem;
  1959. IoQueueWorkItem(
  1960. Log_WorkItem,
  1961. DelayedLogInErrorLog,
  1962. DelayedWorkQueue,
  1963. (VOID*)pWorkItemContext
  1964. );
  1965. }
  1966. else
  1967. {
  1968. //
  1969. // not enough free pool exists to satisfy the request.
  1970. //
  1971. PRINTF("CheckSystemIOAddressValidity: Failed to allocate contxt block from pool to spin off a logging work item.\n");
  1972. IoFreeWorkItem(Log_WorkItem);
  1973. }
  1974. }
  1975. else
  1976. {
  1977. //
  1978. // insufficient resources
  1979. //
  1980. PRINTF("CheckSystemIOAddressValidity: Failed to allocate a workitem to spin off delayed logging.\n");
  1981. }
  1982. }
  1983. else
  1984. {
  1985. //
  1986. // Failed to get ACPI root DeviceObject
  1987. //
  1988. PRINTF("CheckSystemIOAddressValidity: Failed to get ACPI root DeviceObject.\n");
  1989. }
  1990. }
  1991. break;
  1992. }
  1993. }
  1994. }
  1995. EXIT(3, ("CheckSystemIOAddressValidity!\n"));
  1996. return bRet;
  1997. }
  1998. /***LP DelayedLogInErrorLog - Call LogInErrorLog
  1999. *
  2000. * ENTRY
  2001. * PDEVICE_OBJECT DeviceObject - Device Object.
  2002. * PVOID Context - Context pointer with data to call LogInErrorLog with.
  2003. *
  2004. * EXIT
  2005. * VOID
  2006. */
  2007. VOID DelayedLogInErrorLog(
  2008. IN PDEVICE_OBJECT DeviceObject,
  2009. IN PVOID Context
  2010. )
  2011. {
  2012. LogInErrorLog(((PAMLI_LOG_WORKITEM_CONTEXT)Context)->fRead,
  2013. ((PAMLI_LOG_WORKITEM_CONTEXT)Context)->Address,
  2014. ((PAMLI_LOG_WORKITEM_CONTEXT)Context)->Index
  2015. );
  2016. IoFreeWorkItem((PIO_WORKITEM)((PAMLI_LOG_WORKITEM_CONTEXT)Context)->pIOWorkItem);
  2017. ExFreePool(Context);
  2018. }
  2019. /***LP LogInErrorLog - Log illegal IO access to event log
  2020. *
  2021. * ENTRY
  2022. * fRead - TRUE iff access is a read. FALSE on write
  2023. * dwAddr - Memory address
  2024. * ArrayIndex - Index into BadIOAddressList array.
  2025. *
  2026. * EXIT
  2027. * None.
  2028. */
  2029. VOID LOCAL LogInErrorLog(BOOLEAN fRead, ULONG dwAddr, ULONG ArrayIndex)
  2030. {
  2031. TRACENAME("LOGERROR")
  2032. PWCHAR illegalIOPortAddress[3];
  2033. WCHAR AMLIName[6];
  2034. WCHAR addressBuffer[13];
  2035. WCHAR addressRangeBuffer[16];
  2036. ENTER(3, ("LogInErrorLog(fRead=%s, Addr=%x, ArrayIndex=%x)\n", (fRead?"TRUE":"FALSE"),dwAddr, ArrayIndex));
  2037. //
  2038. // Check to see if we need to log this address.
  2039. //
  2040. if(gpBadIOErrorLogDoneList)
  2041. {
  2042. //
  2043. // Check to see if we need to log this address.
  2044. //
  2045. if (!(gpBadIOErrorLogDoneList[ArrayIndex] & (fRead?READ_ERROR_NOTED:WRITE_ERROR_NOTED)))
  2046. {
  2047. gpBadIOErrorLogDoneList[ArrayIndex] |= (fRead?READ_ERROR_NOTED:WRITE_ERROR_NOTED);
  2048. //
  2049. // Turn the address into a string
  2050. //
  2051. swprintf( AMLIName, L"AMLI");
  2052. swprintf( addressBuffer, L"0x%x", dwAddr );
  2053. swprintf( addressRangeBuffer, L"0x%x - 0x%x",
  2054. gpBadIOAddressList[ArrayIndex].BadAddrBegin,
  2055. (gpBadIOAddressList[ArrayIndex].BadAddrBegin + (gpBadIOAddressList[ArrayIndex].BadAddrSize - 1)));
  2056. //
  2057. // Build the list of arguments to pass to the function that will write the
  2058. // error log to the registry
  2059. //
  2060. illegalIOPortAddress[0] = AMLIName;
  2061. illegalIOPortAddress[1] = addressBuffer;
  2062. illegalIOPortAddress[2] = addressRangeBuffer;
  2063. //
  2064. // Log error to event log
  2065. //
  2066. ACPIWriteEventLogEntry((fRead ? ACPI_ERR_AMLI_ILLEGAL_IO_READ_FATAL : ACPI_ERR_AMLI_ILLEGAL_IO_WRITE_FATAL),
  2067. illegalIOPortAddress,
  2068. 3,
  2069. NULL,
  2070. 0);
  2071. }
  2072. }
  2073. EXIT(3, ("LogInErrorLog!\n"));
  2074. return;
  2075. }
  2076. /***LP InitIllegalIOAddressListFromHAL - Initialize the Illegal IO
  2077. * address List from the HAL.
  2078. *
  2079. * ENTRY
  2080. * None.
  2081. *
  2082. * EXIT
  2083. * None.
  2084. */
  2085. VOID LOCAL InitIllegalIOAddressListFromHAL(VOID)
  2086. {
  2087. TRACENAME("InitIllegalIOAddressListFromHAL")
  2088. ULONG Length = 0;
  2089. NTSTATUS status;
  2090. ENTER(3, ("InitIllegalIOAddressListFromHAL\n"));
  2091. if(!gpBadIOAddressList)
  2092. {
  2093. //
  2094. // Query HAL to get the amount of memory to allocate
  2095. //
  2096. status = HalQuerySystemInformation (
  2097. HalQueryAMLIIllegalIOPortAddresses,
  2098. 0,
  2099. NULL,
  2100. &Length
  2101. );
  2102. if(status == STATUS_INFO_LENGTH_MISMATCH)
  2103. {
  2104. if(Length)
  2105. {
  2106. //
  2107. // Allocate memory.
  2108. //
  2109. if ((gpBadIOAddressList = (PHAL_AMLI_BAD_IO_ADDRESS_LIST) MALLOC(Length, PRIV_TAG)) == NULL)
  2110. {
  2111. AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  2112. ("InitIllegalIOAddressListFromHAL: failed to allocate Bad IO address list."));
  2113. }
  2114. else
  2115. {
  2116. //
  2117. // Get bad IO address list from HAL.
  2118. //
  2119. status = HalQuerySystemInformation(
  2120. HalQueryAMLIIllegalIOPortAddresses,
  2121. Length,
  2122. gpBadIOAddressList,
  2123. &Length
  2124. );
  2125. //
  2126. // Cleanup on failure.
  2127. //
  2128. if(status != STATUS_SUCCESS)
  2129. {
  2130. PRINTF("InitIllegalIOAddressListFromHAL: HalQuerySystemInformation failed to get list from HAL. Returned(%x).\n", status);
  2131. FreellegalIOAddressList();
  2132. }
  2133. // Allocate the errorlogdone list. this helps us track if we have logged
  2134. // a certain address.
  2135. //
  2136. else
  2137. {
  2138. //
  2139. // Calculate array length
  2140. //
  2141. ULONG ArrayLength = (Length / sizeof(HAL_AMLI_BAD_IO_ADDRESS_LIST)) - 1;
  2142. if(ArrayLength >= 1)
  2143. {
  2144. if ((gpBadIOErrorLogDoneList = (PULONG) MALLOC((ArrayLength * sizeof(ULONG)), PRIV_TAG)) == NULL)
  2145. {
  2146. AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
  2147. ("InitIllegalIOAddressListFromHAL: failed to allocate ErrorLogDone list."));
  2148. }
  2149. else
  2150. {
  2151. RtlZeroMemory(gpBadIOErrorLogDoneList, (ArrayLength * sizeof(ULONG)));
  2152. }
  2153. }
  2154. }
  2155. }
  2156. }
  2157. else
  2158. {
  2159. PRINTF("InitIllegalIOAddressListFromHAL: HalQuerySystemInformation (HalQueryIllegalIOPortAddresses) returned 0 Length.\n");
  2160. }
  2161. }
  2162. else if(status == STATUS_INVALID_LEVEL)
  2163. {
  2164. PRINTF("InitIllegalIOAddressListFromHAL: HalQuerySystemInformation does not support HalQueryIllegalIOPortAddresses returned (STATUS_INVALID_LEVEL).\n");
  2165. }
  2166. else
  2167. {
  2168. PRINTF("InitIllegalIOAddressListFromHAL: failed. Returned(0x%08lx).\n", status);
  2169. }
  2170. }
  2171. EXIT(3, ("InitIllegalIOAddressListFromHAL!\n"));
  2172. return;
  2173. }
  2174. /***LP FreellegalIOAddressList - Free the Illegal IO
  2175. * address List.
  2176. *
  2177. * ENTRY
  2178. * None.
  2179. *
  2180. * EXIT
  2181. * None.
  2182. */
  2183. VOID LOCAL FreellegalIOAddressList(VOID)
  2184. {
  2185. TRACENAME("FreellegalIOAddressList")
  2186. ENTER(3, ("FreellegalIOAddressList\n"));
  2187. if(gpBadIOAddressList)
  2188. {
  2189. MFREE(gpBadIOAddressList);
  2190. gpBadIOAddressList = NULL;
  2191. }
  2192. if(gpBadIOErrorLogDoneList)
  2193. {
  2194. MFREE(gpBadIOErrorLogDoneList);
  2195. gpBadIOErrorLogDoneList = NULL;
  2196. }
  2197. EXIT(3, ("FreellegalIOAddressList!\n"));
  2198. return;
  2199. }