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.

1264 lines
27 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. tuples.c
  5. Abstract:
  6. This program converses with the PCMCIA support driver to display
  7. tuple and other information.
  8. Author:
  9. Bob Rinne
  10. Environment:
  11. User process.
  12. Notes:
  13. Revision History:
  14. Ravisankar Pudipeddi (ravisp) June 27 1997
  15. - command line options & support for multiple controllers
  16. Neil Sandlin (neilsa) Sept 20, 1998
  17. - more commands
  18. --*/
  19. #include <pch.h>
  20. //
  21. // Tuple output strings
  22. //
  23. StringTable CommandCodes[] = {
  24. "CISTPL_NULL", CISTPL_NULL,
  25. "CISTPL_DEVICE", CISTPL_DEVICE,
  26. "CISTPL_LONGLINK_MFC", CISTPL_LONGLINK_MFC,
  27. "CISTPL_CHECKSUM", CISTPL_CHECKSUM,
  28. "CISTPL_LONGLINK_A", CISTPL_LONGLINK_A,
  29. "CISTPL_LONGLINK_C", CISTPL_LONGLINK_C,
  30. "CISTPL_LINKTARGET", CISTPL_LINKTARGET,
  31. "CISTPL_NO_LINK", CISTPL_NO_LINK,
  32. "CISTPL_VERS_1", CISTPL_VERS_1,
  33. "CISTPL_ALTSTR", CISTPL_ALTSTR,
  34. "CISTPL_DEVICE_A", CISTPL_DEVICE_A,
  35. "CISTPL_JEDEC_C", CISTPL_JEDEC_C,
  36. "CISTPL_JEDEC_A", CISTPL_JEDEC_A,
  37. "CISTPL_CONFIG", CISTPL_CONFIG,
  38. "CISTPL_CFTABLE_ENTRY", CISTPL_CFTABLE_ENTRY,
  39. "CISTPL_DEVICE_OC", CISTPL_DEVICE_OC,
  40. "CISTPL_DEVICE_OA", CISTPL_DEVICE_OA,
  41. "CISTPL_GEODEVICE", CISTPL_GEODEVICE,
  42. "CISTPL_GEODEVICE_A", CISTPL_GEODEVICE_A,
  43. "CISTPL_MANFID", CISTPL_MANFID,
  44. "CISTPL_FUNCID", CISTPL_FUNCID,
  45. "CISTPL_FUNCE", CISTPL_FUNCE,
  46. "CISTPL_VERS_2", CISTPL_VERS_2,
  47. "CISTPL_FORMAT", CISTPL_FORMAT,
  48. "CISTPL_GEOMETRY", CISTPL_GEOMETRY,
  49. "CISTPL_BYTEORDER", CISTPL_BYTEORDER,
  50. "CISTPL_DATE", CISTPL_DATE,
  51. "CISTPL_BATTERY", CISTPL_BATTERY,
  52. "CISTPL_ORG", CISTPL_ORG,
  53. //
  54. // CISTPL_END must be the last one in the table.
  55. //
  56. "CISTPL_END", CISTPL_END
  57. };
  58. //
  59. // Procedures
  60. //
  61. NTSTATUS
  62. ReadTuple(
  63. IN HANDLE Handle,
  64. IN LONG SlotNumber,
  65. IN PUCHAR Buffer,
  66. IN LONG BufferSize
  67. )
  68. /*++
  69. Routine Description:
  70. Perform the NT function to get the tuple data from the
  71. pcmcia support driver.
  72. Arguments:
  73. Handle - an open handle to the driver.
  74. SlotNumber - The socket offset
  75. Buffer - return buffer for the data.
  76. BufferSize - the size of the return buffer area.
  77. Return Value:
  78. The results of the NT call.
  79. --*/
  80. {
  81. NTSTATUS status;
  82. IO_STATUS_BLOCK statusBlock;
  83. TUPLE_REQUEST commandBlock;
  84. commandBlock.Socket = (USHORT) SlotNumber;
  85. status = NtDeviceIoControlFile(Handle,
  86. NULL,
  87. NULL,
  88. NULL,
  89. &statusBlock,
  90. IOCTL_GET_TUPLE_DATA,
  91. &commandBlock,
  92. sizeof(commandBlock),
  93. Buffer,
  94. BufferSize);
  95. return status;
  96. }
  97. PUCHAR
  98. FindTupleCodeName(
  99. UCHAR TupleCode
  100. )
  101. /*++
  102. Routine Description:
  103. Return an ascii string that describes the tuple code provided.
  104. Arguments:
  105. TupleCode - what code to look up.
  106. Return Value:
  107. A string pointer - always.
  108. --*/
  109. {
  110. ULONG index;
  111. for (index = 0; CommandCodes[index].CommandCode != CISTPL_END; index++) {
  112. if (CommandCodes[index].CommandCode == TupleCode) {
  113. return CommandCodes[index].CommandName;
  114. }
  115. }
  116. return "Command Unknown";
  117. }
  118. PUCHAR DeviceTypeString[] = {
  119. "DTYPE_NULL",
  120. "DTYPE_ROM",
  121. "DTYPE_OTPROM",
  122. "DTYPE_EPROM",
  123. "DTYPE_EEPROM",
  124. "DTYPE_FLASH",
  125. "DTYPE_SRAM",
  126. "DTYPE_DRAM",
  127. "Reserved8",
  128. "Reserved9",
  129. "Reserveda",
  130. "Reservedb",
  131. "Reservedc",
  132. "DTYPE_FUNCSPEC",
  133. "DTYPE_EXTEND"
  134. "Reservedf",
  135. };
  136. PUCHAR DeviceSpeedString[] = {
  137. "DSPEED_NULL",
  138. "DSPEED_250NS",
  139. "DSPEED_200NS",
  140. "DSPEED_150NS",
  141. "DSPEED_100NS",
  142. "DSPEED_RES1",
  143. "DSPEED_RES2",
  144. "DSPEED_EXT"
  145. };
  146. VOID
  147. DisplayDeviceTuple(
  148. PUCHAR TupleBuffer,
  149. UCHAR TupleSize
  150. )
  151. /*++
  152. Routine Description:
  153. Display the data at the given pointer as a CISTPL_DEVICE structure.
  154. Arguments:
  155. TupleBuffer - the CISTPL_DEVICE to display.
  156. TupleSize - the link value for the tuple.
  157. Return Value:
  158. None
  159. --*/
  160. {
  161. UCHAR mantissa = MANTISSA_RES1;
  162. UCHAR exponent;
  163. UCHAR deviceTypeCode;
  164. UCHAR wps;
  165. UCHAR deviceSpeed;
  166. UCHAR temp;
  167. temp = *TupleBuffer;
  168. deviceTypeCode = DeviceTypeCode(temp);
  169. wps = DeviceWPS(temp);
  170. deviceSpeed = DeviceSpeedField(temp);
  171. temp = *(TupleBuffer + 1);
  172. if (deviceSpeed == DSPEED_EXT) {
  173. exponent = SpeedExponent(temp);
  174. mantissa = SpeedMantissa(temp);
  175. }
  176. printf("DeviceType: %s DeviceSpeed: ", DeviceTypeString[deviceTypeCode]);
  177. if (mantissa != MANTISSA_RES1) {
  178. printf("Mantissa %.2x, Exponent %.2x\n", mantissa, exponent);
  179. } else {
  180. printf("%s\n", DeviceSpeedString[deviceSpeed]);
  181. }
  182. }
  183. VOID
  184. DisplayVers1(
  185. PUCHAR TupleBuffer,
  186. UCHAR TupleSize,
  187. USHORT Crc
  188. )
  189. /*++
  190. Routine Description:
  191. Display the data as a Version tuple
  192. Arguments:
  193. TupleBuffer - the CISTPL_DEVICE to display.
  194. TupleSize - the link value for the tuple.
  195. Return Value:
  196. None
  197. --*/
  198. {
  199. PUCHAR string;
  200. PUCHAR cp;
  201. //
  202. // Step around the MAJOR and MINOR codes of 4/1 at
  203. // the beginning of the tuple to get to the strings.
  204. //
  205. string = TupleBuffer;
  206. string++;
  207. string++;
  208. printf("Manufacturer:\t%s\n", string);
  209. while (*string++) {
  210. }
  211. printf("Product Name:\t%s\n", string);
  212. printf("CRC: \t%.4x\n", Crc);
  213. while (*string++) {
  214. }
  215. printf("Product Info:\t");
  216. if (isprint(*string)) {
  217. printf("%s", string);
  218. } else {
  219. while (*string) {
  220. printf("%.2x ", *string);
  221. string++;
  222. }
  223. }
  224. printf("\n");
  225. }
  226. VOID
  227. DisplayConfigTuple(
  228. PUCHAR TupleBuffer,
  229. UCHAR TupleSize
  230. )
  231. /*++
  232. Routine Description:
  233. Display the data at the given pointer as a CISTPL_CONFIG tuple.
  234. Arguments:
  235. TupleBuffer - the CISTPL_DEVICE to display.
  236. TupleSize - the link value for the tuple.
  237. Return Value:
  238. None
  239. --*/
  240. {
  241. UCHAR sizeField;
  242. UCHAR tpccRfsz;
  243. UCHAR tpccRmsz;
  244. UCHAR tpccRasz;
  245. UCHAR last;
  246. ULONG baseAddress;
  247. PUCHAR ptr;
  248. sizeField = *TupleBuffer;
  249. last = *(TupleBuffer + 1);
  250. tpccRfsz = TpccRfsz(sizeField);
  251. tpccRmsz = TpccRmsz(sizeField);
  252. tpccRasz = TpccRasz(sizeField);
  253. printf("TPCC_SZ %.2x (%.2x/%.2x/%.2x) - Last %.2x\n",
  254. sizeField,
  255. tpccRasz,
  256. tpccRmsz,
  257. tpccRfsz,
  258. last);
  259. baseAddress = 0;
  260. ptr = TupleBuffer + 2;
  261. switch (tpccRasz) {
  262. case 3:
  263. baseAddress = *(ptr + 3) << 24;
  264. case 2:
  265. baseAddress |= *(ptr + 2) << 16;
  266. case 1:
  267. baseAddress |= *(ptr + 1) << 8;
  268. default:
  269. baseAddress |= *ptr;
  270. }
  271. printf("Base Address: %8x - ", baseAddress);
  272. ptr += tpccRasz + 1;
  273. baseAddress = 0;
  274. switch (tpccRmsz) {
  275. case 3:
  276. baseAddress = *(ptr + 3) << 24;
  277. case 2:
  278. baseAddress |= *(ptr + 2) << 16;
  279. case 1:
  280. baseAddress |= *(ptr + 1) << 8;
  281. default:
  282. baseAddress |= *ptr;
  283. }
  284. printf("Register Presence Mask: %8x\n", baseAddress);
  285. }
  286. PUCHAR
  287. ProcessMemSpace(
  288. PUCHAR Buffer,
  289. UCHAR MemSpace
  290. )
  291. /*++
  292. Routine Description:
  293. Display and process memspace information
  294. Arguments:
  295. Buffer - start of memspace information
  296. MemSpace - the memspace value from the feature byte.
  297. Return Value:
  298. location of byte after all memory space information
  299. --*/
  300. {
  301. PUCHAR ptr = Buffer;
  302. UCHAR item = *ptr++;
  303. UCHAR lengthSize;
  304. UCHAR addrSize;
  305. UCHAR number;
  306. UCHAR hasHostAddress;
  307. ULONG cardAddress;
  308. ULONG length;
  309. ULONG hostAddress;
  310. if (MemSpace == 3) {
  311. lengthSize = (item & 0x18) >> 3;
  312. addrSize = (item & 0x60) >> 5;
  313. number = (item & 0x07) + 1;
  314. hasHostAddress = item & 0x80;
  315. printf("(0x%.2x) %s - %d entries - LengthSize %d - AddrSize %d\n",
  316. item,
  317. hasHostAddress ? "Host address" : "no host",
  318. number,
  319. lengthSize,
  320. addrSize);
  321. while (number) {
  322. cardAddress = length = hostAddress = 0;
  323. switch (lengthSize) {
  324. case 3:
  325. length |= (*(ptr + 2)) << 16;
  326. case 2:
  327. length |= (*(ptr + 1)) << 8;
  328. case 1:
  329. length |= *ptr;
  330. }
  331. ptr += lengthSize;
  332. switch (addrSize) {
  333. case 3:
  334. cardAddress |= (*(ptr + 2)) << 16;
  335. case 2:
  336. cardAddress |= (*(ptr + 1)) << 8;
  337. case 1:
  338. cardAddress |= *ptr;
  339. }
  340. ptr += addrSize;
  341. if (hasHostAddress) {
  342. switch (addrSize) {
  343. case 3:
  344. hostAddress |= (*(ptr + 2)) << 16;
  345. case 2:
  346. hostAddress |= (*(ptr + 1)) << 8;
  347. case 1:
  348. hostAddress |= *ptr;
  349. }
  350. printf("\tHost 0x%.8x ", hostAddress * 256);
  351. ptr += addrSize;
  352. } else {
  353. printf("\t");
  354. }
  355. printf("Card 0x%.8x Size 0x%.8x\n",
  356. cardAddress * 256,
  357. length * 256);
  358. number--;
  359. }
  360. }
  361. return ptr;
  362. }
  363. USHORT VoltageConversionTable[16] = {
  364. 10, 12, 13, 14, 20, 25, 30, 35,
  365. 40, 45, 50, 55, 60, 70, 80, 90
  366. };
  367. UCHAR
  368. ConvertVoltage(
  369. UCHAR MantissaExponentByte,
  370. UCHAR ExtensionByte
  371. )
  372. /*++
  373. Routine Description:
  374. Arguments:
  375. Return Value:
  376. --*/
  377. {
  378. USHORT power;
  379. USHORT value;
  380. value = VoltageConversionTable[(MantissaExponentByte >> 3) & 0x0f];
  381. power = 1;
  382. if ((MantissaExponentByte & EXTENSION_BYTE_FOLLOWS) &&
  383. (ExtensionByte < 100)) {
  384. value = (100 * value + (ExtensionByte & 0x7f));
  385. power += 2;
  386. }
  387. power = (MantissaExponentByte & 0x07) - 4 - power;
  388. while (power > 0) {
  389. value *= 10;
  390. power--;
  391. }
  392. while (power < 0) {
  393. value /= 10;
  394. power++;
  395. }
  396. return (UCHAR) value;
  397. }
  398. PUCHAR PowerTypeTable[] = {
  399. "Nominal",
  400. "Minimum",
  401. "Maximum",
  402. "Static",
  403. "Average",
  404. "Peak",
  405. "PwrDown"
  406. };
  407. PUCHAR VoltagePinTable[] = {
  408. "Vcc",
  409. "Vpp1",
  410. "Vpp2"
  411. };
  412. PUCHAR
  413. ProcessPower(
  414. PUCHAR Buffer,
  415. UCHAR FeatureByte
  416. )
  417. /*++
  418. Routine Description:
  419. Display and process power information
  420. Arguments:
  421. Power - start of power information
  422. Return Value:
  423. location of byte after all power information
  424. --*/
  425. {
  426. UCHAR powerSelect;
  427. UCHAR bit;
  428. UCHAR item;
  429. UCHAR entries;
  430. PUCHAR ptr = Buffer;
  431. UCHAR count = FeatureByte;
  432. powerSelect = *ptr;
  433. printf("Parameter Selection Byte = 0x%.2x\n", powerSelect);
  434. entries = 0;
  435. while (entries < count) {
  436. powerSelect = *ptr++;
  437. printf("\t%s \"%d%d%d%d%d%d%d%d\"\n",
  438. VoltagePinTable[entries],
  439. powerSelect & 0x80 ? 1 : 0,
  440. powerSelect & 0x40 ? 1 : 0,
  441. powerSelect & 0x20 ? 1 : 0,
  442. powerSelect & 0x10 ? 1 : 0,
  443. powerSelect & 0x08 ? 1 : 0,
  444. powerSelect & 0x04 ? 1 : 0,
  445. powerSelect & 0x02 ? 1 : 0,
  446. powerSelect & 0x01 ? 1 : 0);
  447. for (bit = 0; bit < 7; bit++) {
  448. if (powerSelect & (1 << bit)) {
  449. if (!bit) {
  450. //
  451. // Convert nominal power for output.
  452. //
  453. item = ConvertVoltage(*ptr,
  454. (UCHAR) (*ptr & EXTENSION_BYTE_FOLLOWS ?
  455. *(ptr + 1) :
  456. (UCHAR) 0));
  457. }
  458. printf("\t\t%s power =\t%d/10 volts\n", PowerTypeTable[bit], item);
  459. while (*ptr++ & EXTENSION_BYTE_FOLLOWS) {
  460. }
  461. }
  462. }
  463. entries++;
  464. }
  465. return ptr;
  466. }
  467. PUCHAR
  468. ProcessTiming(
  469. PUCHAR Buffer
  470. )
  471. /*++
  472. Routine Description:
  473. Arguments:
  474. Return Value:
  475. --*/
  476. {
  477. PUCHAR ptr = Buffer;
  478. UCHAR item = *ptr++;
  479. UCHAR reservedScale = (item & 0xe0) >> 5;
  480. UCHAR readyBusyScale = (item & 0x1c) >> 2;
  481. UCHAR waitScale = (item & 0x03);
  482. printf("Timing (0x%.2x): reservedScale 0x%.2x, readyBusyScale 0x%.2x, waitScale 0x%.2x\n",
  483. item,
  484. reservedScale,
  485. readyBusyScale,
  486. waitScale);
  487. if (waitScale != 3) {
  488. printf("\tWaitSpeed 0x%.2x\n", *ptr);
  489. ptr++;
  490. while (*ptr & EXTENSION_BYTE_FOLLOWS) {
  491. ptr++;
  492. }
  493. }
  494. if (readyBusyScale != 7) {
  495. printf("\tReadyBusySpeed 0x%.2x\n", *ptr);
  496. ptr++;
  497. while (*ptr & EXTENSION_BYTE_FOLLOWS) {
  498. ptr++;
  499. }
  500. }
  501. if (reservedScale != 7) {
  502. printf("\tReservedSpeed 0x%.2x\n", *ptr);
  503. ptr++;
  504. while (*ptr & EXTENSION_BYTE_FOLLOWS) {
  505. ptr++;
  506. }
  507. }
  508. return ptr;
  509. }
  510. PUCHAR
  511. ProcessIoSpace(
  512. PUCHAR Buffer
  513. )
  514. /*++
  515. Routine Description:
  516. Display and process iospace information
  517. Arguments:
  518. Buffer - start of IoSpace information
  519. Return Value:
  520. location of byte after all power information
  521. --*/
  522. {
  523. UCHAR item;
  524. UCHAR ioAddrLines;
  525. UCHAR bus8;
  526. UCHAR bus16;
  527. UCHAR ranges;
  528. UCHAR lengthSize;
  529. UCHAR addressSize;
  530. ULONG address;
  531. PUCHAR ptr = Buffer;
  532. item = *ptr++;
  533. ioAddrLines = item & IO_ADDRESS_LINES_MASK;
  534. bus8 = Is8BitAccess(item);
  535. bus16 = Is16BitAccess(item);
  536. ranges = HasRanges(item);
  537. printf("IoSpace (%.2x): IoAddressLines %.2d - %s/%s\n",
  538. item,
  539. ioAddrLines,
  540. bus8 ? "8bit" : "",
  541. bus16 ? "16bit" : "");
  542. //
  543. // This is what it looks like the IBM token ring card
  544. // does. It is unclear in the specification if this
  545. // is correct or not.
  546. //
  547. if ((!ranges) && (!ioAddrLines)) {
  548. ranges = 0xFF;
  549. }
  550. if (ranges) {
  551. if (ranges == 0xff) {
  552. //
  553. // This is based on the tuple data as given by
  554. // the IBM token ring card. This is not the
  555. // way I would interpret the specification.
  556. //
  557. addressSize = 2;
  558. lengthSize = 1;
  559. ranges = 1;
  560. } else {
  561. item = *ptr++;
  562. ranges = item & 0x0f;
  563. ranges++;
  564. addressSize = GetAddressSize(item);
  565. lengthSize = GetLengthSize(item);
  566. }
  567. while (ranges) {
  568. address = 0;
  569. switch (addressSize) {
  570. case 4:
  571. address |= (*(ptr + 3)) << 24;
  572. case 3:
  573. address |= (*(ptr + 2)) << 16;
  574. case 2:
  575. address |= (*(ptr + 1)) << 8;
  576. case 1:
  577. address |= *ptr;
  578. }
  579. ptr += addressSize;
  580. printf("\tStart %.8x - Length ", address);
  581. address = 0;
  582. switch (lengthSize) {
  583. case 4:
  584. address |= (*(ptr + 3)) << 24;
  585. case 3:
  586. address |= (*(ptr + 2)) << 16;
  587. case 2:
  588. address |= (*(ptr + 1)) << 8;
  589. case 1:
  590. address |= *ptr;
  591. }
  592. ptr += lengthSize;
  593. printf("%.8x\n", address);
  594. ranges--;
  595. }
  596. } else {
  597. printf("\tResponds to all ranges.\n");
  598. }
  599. return ptr;
  600. }
  601. PUCHAR
  602. ProcessIrq(
  603. PUCHAR Buffer
  604. )
  605. /*++
  606. Routine Description:
  607. Display and process irq information
  608. Arguments:
  609. Buffer - start of irq information
  610. Return Value:
  611. location of byte after all irq information
  612. --*/
  613. {
  614. PUCHAR ptr = Buffer;
  615. UCHAR level;
  616. USHORT mask;
  617. ULONG irqNumber;
  618. level = *ptr++;
  619. if (!level) {
  620. //
  621. // NOTE: It looks like Future Domain messed up on this
  622. // and puts an extra zero byte into the structure.
  623. // skip it for now.
  624. //
  625. level = *ptr++;
  626. }
  627. if (level & 0x80) {
  628. printf("Share ");
  629. }
  630. if (level & 0x40) {
  631. printf("Pulse ");
  632. }
  633. if (level & 0x20) {
  634. printf("Level ");
  635. }
  636. if (level & 0x10) {
  637. mask = *ptr | (*(ptr + 1) << 8);
  638. ptr += 2;
  639. printf("mask = %.4x - ", mask);
  640. for (irqNumber = 0; mask; irqNumber++, mask = mask >> 1) {
  641. if (mask & 0x0001) {
  642. printf("IRQ%d ", irqNumber);
  643. }
  644. }
  645. printf("- ");
  646. if (level & 0x08) {
  647. printf("Vend ");
  648. }
  649. if (level & 0x04) {
  650. printf("Berr ");
  651. }
  652. if (level & 0x02) {
  653. printf("IOCK ");
  654. }
  655. if (level & 0x01) {
  656. printf("NMI");
  657. }
  658. printf("\n");
  659. } else {
  660. printf("irq = %d\n", level & 0x0f);
  661. }
  662. return ptr;
  663. }
  664. PUCHAR InterfaceTypeStrings[] = {
  665. "Memory",
  666. "I/O",
  667. "Reserved 2",
  668. "Reserved 3",
  669. "Custom 0",
  670. "Custom 1",
  671. "Custom 2",
  672. "Custom 3",
  673. "Reserved 8",
  674. "Reserved 9",
  675. "Reserved a",
  676. "Reserved b",
  677. "Reserved c",
  678. "Reserved d",
  679. "Reserved e",
  680. "Reserved f",
  681. };
  682. VOID
  683. DisplayCftableEntryTuple(
  684. PUCHAR TupleBuffer,
  685. UCHAR TupleSize
  686. )
  687. /*++
  688. Routine Description:
  689. Display the data at the given pointer as a CISTPL_CFTABLE_ENTRY tuple.
  690. Arguments:
  691. TupleBuffer - the CISTPL_DEVICE to display.
  692. TupleSize - the link value for the tuple.
  693. Return Value:
  694. None
  695. --*/
  696. {
  697. UCHAR temp;
  698. UCHAR item;
  699. UCHAR defaultbit;
  700. UCHAR memSpace;
  701. UCHAR power;
  702. PUCHAR ptr;
  703. temp = *TupleBuffer;
  704. item = IntFace(temp);
  705. defaultbit = Default(temp);
  706. temp = ConfigEntryNumber(temp);
  707. printf("ConfigurationEntryNumber %.2x (%s/%s)\n",
  708. temp,
  709. item ? "intface" : "",
  710. defaultbit ? "default" : "");
  711. ptr = TupleBuffer + 1;
  712. if (item) {
  713. temp = *ptr++;
  714. item = temp & 0x0F;
  715. printf("InterfaceDescription (%.2x) %s (%s/%s/%s/%s)\n",
  716. temp,
  717. InterfaceTypeStrings[item],
  718. temp & 0x80 ? "WaitReq" : "",
  719. temp & 0x40 ? "RdyBsy" : "",
  720. temp & 0x20 ? "WP" : "",
  721. temp & 0x10 ? "BVD" : "");
  722. }
  723. item = *ptr++;
  724. memSpace = MemSpaceInformation(item);
  725. power = PowerInformation(item);
  726. printf("The following structures are present:\n");
  727. switch (power) {
  728. case 3:
  729. printf("Vcc, Vpp1, Vpp2; ");
  730. break;
  731. case 2:
  732. printf("Vcc and Vpp; ");
  733. break;
  734. case 1:
  735. printf("Vcc; ");
  736. break;
  737. case 0:
  738. break;
  739. }
  740. if (power) {
  741. ptr = ProcessPower(ptr, power);
  742. }
  743. if (TimingInformation(item)) {
  744. ptr = ProcessTiming(ptr);
  745. }
  746. if (IoSpaceInformation(item)) {
  747. ptr = ProcessIoSpace(ptr);
  748. }
  749. if (IRQInformation(item)) {
  750. printf("IRQ: ");
  751. ptr = ProcessIrq(ptr);
  752. }
  753. switch (memSpace) {
  754. case 3:
  755. printf("Memory selection: ");
  756. break;
  757. case 2:
  758. printf("Length and Card Address: ");
  759. break;
  760. case 1:
  761. printf("2-byte length: ");
  762. break;
  763. case 0:
  764. break;
  765. }
  766. if (memSpace) {
  767. ptr = ProcessMemSpace(ptr, memSpace);
  768. }
  769. if (MiscInformation(item)) {
  770. printf("Misc fields present");
  771. }
  772. printf("\n");
  773. }
  774. UCHAR TplList[] = {
  775. CISTPL_DEVICE,
  776. CISTPL_VERS_1,
  777. CISTPL_CONFIG,
  778. CISTPL_CFTABLE_ENTRY,
  779. CISTPL_MANFID,
  780. CISTPL_END
  781. };
  782. static unsigned short crc16a[] = {
  783. 0000000, 0140301, 0140601, 0000500,
  784. 0141401, 0001700, 0001200, 0141101,
  785. 0143001, 0003300, 0003600, 0143501,
  786. 0002400, 0142701, 0142201, 0002100,
  787. };
  788. static unsigned short crc16b[] = {
  789. 0000000, 0146001, 0154001, 0012000,
  790. 0170001, 0036000, 0024000, 0162001,
  791. 0120001, 0066000, 0074000, 0132001,
  792. 0050000, 0116001, 0104001, 0043000,
  793. };
  794. USHORT
  795. GetCRC(
  796. PUCHAR TupleBuffer
  797. )
  798. /*++
  799. Routine Description:
  800. Using the same algorithm as Windows 95, calculate the CRC value
  801. to be appended with the manufacturer name and device name to
  802. obtain the unique identifier for the PCCARD.
  803. Arguments:
  804. TupleBuffer - the tuple data
  805. Return Value:
  806. A USHORT CRC value.
  807. --*/
  808. {
  809. USHORT crc = 0;
  810. USHORT index;
  811. USHORT length;
  812. PUCHAR tupleData;
  813. PUCHAR cp;
  814. PUCHAR tplBuffer;
  815. UCHAR tupleCode;
  816. UCHAR linkValue;
  817. UCHAR tmp;
  818. //
  819. // Calculate CRC
  820. //
  821. tplBuffer = TupleBuffer;
  822. printf("Calculating CRC ");
  823. while (1) {
  824. tupleData = tplBuffer + 2;
  825. tupleCode = *tplBuffer++;
  826. if (tupleCode == CISTPL_END) {
  827. break;
  828. }
  829. linkValue = (tupleCode) ? *tplBuffer++ : 0;
  830. length = linkValue;
  831. printf("%x", tupleCode);
  832. for (index = 0; TplList[index] != CISTPL_END; index++) {
  833. if (tupleCode == TplList[index]) {
  834. //
  835. // This one is included in the CRC calculation
  836. //
  837. printf("*", tupleCode);
  838. if (tupleCode == CISTPL_VERS_1) {
  839. cp = tupleData + 2;
  840. //
  841. // Include all of the manufacturer name.
  842. //
  843. while (*cp) {
  844. cp++;
  845. }
  846. //
  847. // Include the product string
  848. //
  849. cp++;
  850. while (*cp) {
  851. cp++;
  852. }
  853. cp++;
  854. length = (USHORT)(cp - tupleData);
  855. }
  856. for (cp = tupleData; length; length--, cp++) {
  857. tmp = *cp ^ (UCHAR)crc;
  858. crc = (crc >> 8) ^ crc16a[tmp & 0x0f] ^ crc16b[tmp >> 4];
  859. }
  860. break;
  861. }
  862. }
  863. printf(" ");
  864. tplBuffer = tplBuffer + linkValue;
  865. }
  866. printf("++\n");
  867. return crc;
  868. }
  869. VOID
  870. DumpTuple(
  871. PUCHAR Buffer
  872. )
  873. /*++
  874. Routine Description:
  875. Control routine to process the tuple data.
  876. Arguments:
  877. Buffer - the tuple data.
  878. Return Value:
  879. None
  880. --*/
  881. {
  882. PUCHAR tupleBuffer = Buffer;
  883. PUCHAR tupleCodeName;
  884. USHORT crc;
  885. UCHAR index;
  886. UCHAR tupleCode;
  887. UCHAR linkValue;
  888. crc = GetCRC(tupleBuffer);
  889. while (1) {
  890. tupleCode = *tupleBuffer++;
  891. linkValue = (tupleCode) ? *tupleBuffer : 0;
  892. if (tupleCode == CISTPL_END) {
  893. break;
  894. }
  895. tupleCodeName = FindTupleCodeName(tupleCode);
  896. printf("Tuple Code\t%s\t%.2x - Link %.2x:", tupleCodeName, tupleCode, linkValue);
  897. if (linkValue) {
  898. for (index = 0; index < linkValue; index++) {
  899. if ((index & 0x0F) == 0) {
  900. printf("\n");
  901. }
  902. printf(" %.2x", *(tupleBuffer + index + 1));
  903. }
  904. }
  905. printf("\n");
  906. tupleBuffer++;
  907. switch (tupleCode) {
  908. case CISTPL_DEVICE:
  909. DisplayDeviceTuple(tupleBuffer, linkValue);
  910. break;
  911. case CISTPL_VERS_1:
  912. DisplayVers1(tupleBuffer, linkValue, crc);
  913. break;
  914. case CISTPL_CONFIG:
  915. DisplayConfigTuple(tupleBuffer, linkValue);
  916. break;
  917. case CISTPL_CFTABLE_ENTRY:
  918. DisplayCftableEntryTuple(tupleBuffer, linkValue);
  919. break;
  920. case CISTPL_LONGLINK_MFC:
  921. case CISTPL_LONGLINK_A:
  922. case CISTPL_LONGLINK_C:
  923. case CISTPL_LINKTARGET:
  924. case CISTPL_NO_LINK:
  925. default:
  926. break;
  927. }
  928. tupleBuffer = tupleBuffer + linkValue;
  929. printf("\n");
  930. }
  931. }
  932. VOID
  933. DumpCIS(
  934. IN PHOST_INFO hostInfo
  935. )
  936. /*++
  937. Routine Description:
  938. Arguments:
  939. Return Value:
  940. --*/
  941. {
  942. NTSTATUS status;
  943. PUCHAR currentBufferPointer;
  944. UCHAR hexBuffer[260];
  945. UCHAR ascii[100];
  946. ULONG i;
  947. UCHAR c;
  948. PUCHAR buffer;
  949. HANDLE handle;
  950. handle = GetHandleForIoctl(hostInfo);
  951. if (handle == INVALID_HANDLE_VALUE) {
  952. return;
  953. }
  954. buffer = malloc(BUFFER_SIZE);
  955. if (!buffer) {
  956. printf("Unable to malloc\n");
  957. NtClose(handle);
  958. return;
  959. }
  960. memset(buffer, 0, BUFFER_SIZE);
  961. status = ReadTuple(handle, hostInfo->SocketNumber, buffer, BUFFER_SIZE);
  962. //
  963. // Don't bother dumping tuples for cards that aren't there.
  964. //
  965. if (!NT_SUCCESS(status)) {
  966. NtClose(handle);
  967. return;
  968. }
  969. printf("\nCIS Tuples for Socket Number %d:\n\n", hostInfo->SocketNumber);
  970. hexBuffer[0] = '\0';
  971. ascii[0] = '\0';
  972. currentBufferPointer = buffer;
  973. for (i = 0; i < 512; i++) {
  974. c = *currentBufferPointer;
  975. sprintf(hexBuffer, "%s %.2x", hexBuffer, c);
  976. c = isprint(c) ? c : '.';
  977. sprintf(ascii, "%s%c", ascii, c);
  978. currentBufferPointer++;
  979. //
  980. // Display the line every 16 bytes.
  981. //
  982. if ((i & 0x0f) == 0x0f) {
  983. printf("%s", hexBuffer);
  984. printf(" *%s*\n", ascii);
  985. hexBuffer[0] = '\0';
  986. ascii[0] = '\0';
  987. }
  988. }
  989. printf("%s", hexBuffer);
  990. printf("\t\t*%s*\n\n", ascii);
  991. DumpTuple(buffer);
  992. NtClose(handle);
  993. }