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

361 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. n13cfg.c
  5. Abstract:
  6. This code is NOT part of ARP1394. Rather it is sample code that creates
  7. the config ROM unit directory for IP/1394-capable devices.
  8. It is here simply for safekeeping.
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. josephj 03-19-99 Created
  13. Notes:
  14. --*/
  15. #include <precomp.h>
  16. #ifdef TESTPROGRAM
  17. ULONG
  18. Bus1394Crc16(
  19. IN ULONG data,
  20. IN ULONG check
  21. );
  22. ULONG
  23. Bus1394CalculateCrc(
  24. IN PULONG Quadlet,
  25. IN ULONG length
  26. );
  27. // From \nt\private\ntos\dd\wdm\1394\bus\busdef.h
  28. //SPEC_ID_KEY_SIGNITURE
  29. //SOFTWARE_VERSION_KEY_SIGNITURE
  30. //MODEL_KEY_SIGNITURE
  31. #define SPEC_ID_KEY_SIGNATURE 0x12
  32. #define SOFTWARE_VERSION_KEY_SIGNATURE 0x13
  33. // #define MODEL_ID_KEY_SIGNATURE 0x17
  34. //#define VENDOR_KEY_SIGNATURE 0x81
  35. #define TEXTUAL_LEAF_INDIRECT_KEY_SIGNATURE 0x81
  36. #define MODEL_KEY_SIGNATURE 0x82
  37. //#define UNIT_DIRECTORY_KEY_SIGNATURE 0xd1
  38. //#define UNIT_DEP_DIR_KEY_SIGNATURE 0xd4
  39. //
  40. // IEEE 1212 Offset entry definition
  41. //
  42. typedef struct _OFFSET_ENTRY {
  43. ULONG OE_Offset:24;
  44. ULONG OE_Key:8;
  45. } OFFSET_ENTRY, *POFFSET_ENTRY;
  46. //
  47. // IEEE 1212 Immediate entry definition
  48. //
  49. typedef struct _IMMEDIATE_ENTRY {
  50. ULONG IE_Value:24;
  51. ULONG IE_Key:8;
  52. } IMMEDIATE_ENTRY, *PIMMEDIATE_ENTRY;
  53. //
  54. // IEEE 1212 Directory definition
  55. //
  56. typedef struct _DIRECTORY_INFO {
  57. union {
  58. USHORT DI_CRC;
  59. USHORT DI_Saved_Length;
  60. } u;
  61. USHORT DI_Length;
  62. } DIRECTORY_INFO, *PDIRECTORY_INFO;
  63. #define bswap(_val) SWAPBYTES_ULONG(_val)
  64. // Some NIC1394-specific constants
  65. //
  66. #define NIC1394_UnitSpecIdValue 0x5E // For "IANA"
  67. #define NIC1394_UnitSwVersionValue 0x1 // IP/1394 Spec
  68. #define NIC1394_ModelSpecIdValue 0x7bb0cf // Random (TBD by Microsoft)
  69. #define NIC1394_ModelName L"NIC1394"
  70. typedef struct _NIC1394_CONFIG_ROM
  71. {
  72. // The Unit Directory
  73. //
  74. struct
  75. {
  76. DIRECTORY_INFO Info;
  77. struct
  78. {
  79. IMMEDIATE_ENTRY SpecId;
  80. IMMEDIATE_ENTRY SwVersion;
  81. IMMEDIATE_ENTRY ModelId;
  82. OFFSET_ENTRY ModelIdTextOffset;
  83. } contents;
  84. } unit_dir;
  85. // The ModelId Text Leaf Directory
  86. //
  87. struct
  88. {
  89. DIRECTORY_INFO Info;
  90. struct
  91. {
  92. IMMEDIATE_ENTRY SpecId;
  93. ULONG LanguageId;
  94. ULONG Text[4]; // L"NIC1394"
  95. } contents;
  96. } model_text_dir;
  97. } NIC1394_CONFIG_ROM, *PNIC1394_CONFIG_ROM;
  98. VOID
  99. InitializeNic1394ConfigRom(
  100. IN PNIC1394_CONFIG_ROM Nic1394ConfigRom
  101. )
  102. /*++
  103. Routine Description:
  104. This routine initializes the configuration ROM unit directory (and the
  105. leaf directories it references) for NIC1394, the IP/1394-capable device.
  106. Arguments:
  107. Nic1394ConfigRom - Pointer to the unitialized config ROM structure.
  108. Return Value:
  109. None
  110. --*/
  111. {
  112. PNIC1394_CONFIG_ROM pCR = Nic1394ConfigRom;
  113. INT i;
  114. RtlZeroMemory(pCR, sizeof(*pCR));
  115. //
  116. // Initialize the unit directory header.
  117. //
  118. pCR->unit_dir.Info.DI_Length = sizeof(pCR->unit_dir.contents)/
  119. sizeof(ULONG);
  120. //
  121. // Initialize the entries of the unit directory.
  122. //
  123. pCR->unit_dir.contents.SpecId.IE_Key = SPEC_ID_KEY_SIGNATURE;
  124. pCR->unit_dir.contents.SpecId.IE_Value = NIC1394_UnitSpecIdValue;
  125. pCR->unit_dir.contents.SwVersion.IE_Key = SOFTWARE_VERSION_KEY_SIGNATURE;
  126. pCR->unit_dir.contents.SwVersion.IE_Value = NIC1394_UnitSwVersionValue;
  127. pCR->unit_dir.contents.ModelId.IE_Key = MODEL_KEY_SIGNATURE;
  128. pCR->unit_dir.contents.ModelId.IE_Value = NIC1394_ModelSpecIdValue;
  129. pCR->unit_dir.contents.ModelIdTextOffset.OE_Key
  130. = TEXTUAL_LEAF_INDIRECT_KEY_SIGNATURE;
  131. pCR->unit_dir.contents.ModelIdTextOffset.OE_Offset
  132. = ( FIELD_OFFSET(NIC1394_CONFIG_ROM, model_text_dir)
  133. -FIELD_OFFSET(NIC1394_CONFIG_ROM, unit_dir.contents.ModelIdTextOffset))
  134. / sizeof (ULONG);
  135. // Initialize the model text directory header.
  136. //
  137. pCR->model_text_dir.Info.DI_Length = sizeof(pCR->model_text_dir.contents)/
  138. sizeof(ULONG);
  139. //
  140. // Initialize the model text directory contents
  141. //
  142. pCR->model_text_dir.contents.SpecId.IE_Key = 0x80; // For "text leaf"
  143. pCR->model_text_dir.contents.SpecId.IE_Value= 0x0; // For "text leaf"
  144. pCR->model_text_dir.contents.LanguageId = 0x409; // For "unicode"
  145. ASSERT(sizeof(pCR->model_text_dir.contents.Text)>=sizeof(NIC1394_ModelName));
  146. RtlCopyMemory(
  147. pCR->model_text_dir.contents.Text,
  148. NIC1394_ModelName,
  149. sizeof(NIC1394_ModelName)
  150. );
  151. //
  152. // Now convert into over-the-wire format (watch out for the unicode string in
  153. // pCR->model_test_dir.contents.Text.
  154. //
  155. //
  156. // Byte swap the unicode strings here, cuz we're gonna byte swap
  157. // everything down below - so it'll come out a wash.
  158. //
  159. for (i=0; i < sizeof(pCR->model_text_dir.contents.Text)/sizeof(ULONG); i++)
  160. {
  161. pCR->model_text_dir.contents.Text[i] =
  162. bswap(pCR->model_text_dir.contents.Text[i]);
  163. }
  164. //
  165. // Now we've got to byte swap the entire config rom so other
  166. // nodes can read it correctly from accross the bus.
  167. // We need to do this BEFORE computing the CRC.
  168. //
  169. for (i=0; i < (sizeof(*pCR)/sizeof(ULONG)); i++)
  170. {
  171. ((PULONG) pCR)[i] = bswap(((PULONG) pCR)[i]);
  172. }
  173. //
  174. // Compute the following CRC:
  175. //
  176. // pCR->unit_dir.Info.DI_CRC
  177. // pCR->model_text_dir.Info.DI_CRC
  178. //
  179. // NOTE: we have bswapped all cfg rom, so we need to temporarily "unbswap"
  180. // the two DIRECTORY_INFOs to set the CRC.
  181. //
  182. {
  183. DIRECTORY_INFO Info;
  184. Info = pCR->unit_dir.Info; // Struct copy.
  185. *(PULONG)&Info = bswap(*(PULONG)&Info); // "unbswap"
  186. Info.u.DI_CRC = (USHORT) Bus1394CalculateCrc(
  187. (PULONG)&(pCR->unit_dir.contents),
  188. Info.DI_Length
  189. );
  190. *(PULONG)(&pCR->unit_dir.Info) = bswap (*(PULONG)&Info); // "re-bswap"
  191. Info = pCR->model_text_dir.Info; // Struct copy.
  192. *(PULONG)&Info = bswap(*(PULONG)&Info); // "unbeswap"
  193. Info.u.DI_CRC = (USHORT) Bus1394CalculateCrc(
  194. (PULONG)&(pCR->model_text_dir.contents),
  195. Info.DI_Length
  196. );
  197. *(PULONG)(&pCR->model_text_dir.Info) = bswap (*(PULONG)&Info); // "re-bswap"
  198. }
  199. }
  200. //
  201. // From bus\buspnp.c
  202. //
  203. ULONG
  204. Bus1394CalculateCrc(
  205. IN PULONG Quadlet,
  206. IN ULONG length
  207. )
  208. /*++
  209. Routine Description:
  210. This routine calculates a CRC for the pointer to the Quadlet data.
  211. Arguments:
  212. Quadlet - Pointer to data to CRC
  213. length - length of data to CRC
  214. Return Value:
  215. returns the CRC
  216. --*/
  217. {
  218. LONG temp;
  219. ULONG index;
  220. temp = index = 0;
  221. while (index < length) {
  222. temp = Bus1394Crc16(Quadlet[index++], temp);
  223. }
  224. return (temp);
  225. }
  226. ULONG
  227. Bus1394Crc16(
  228. IN ULONG data,
  229. IN ULONG check
  230. )
  231. /*++
  232. Routine Description:
  233. This routine derives the 16 bit CRC as defined by IEEE 1212
  234. clause 8.1.5. (ISO/IEC 13213) First edition 1994-10-05.
  235. Arguments:
  236. data - ULONG data to derive CRC from
  237. check - check value
  238. Return Value:
  239. Returns CRC.
  240. --*/
  241. {
  242. LONG shift, sum, next;
  243. for (next=check, shift=28; shift >= 0; shift -=4) {
  244. sum = ((next >> 12) ^ (data >> shift)) & 0xf;
  245. next = (next << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
  246. }
  247. return (next & 0xFFFF);
  248. }
  249. void DumpCfgRomCRC(void)
  250. {
  251. NIC1394_CONFIG_ROM Net1394ConfigRom;
  252. unsigned char *pb = (unsigned char*) &Net1394ConfigRom;
  253. INT i;
  254. InitializeNic1394ConfigRom(&Net1394ConfigRom);
  255. printf("unsigned char Net1394ConfigRom[%lu] = {", sizeof(Net1394ConfigRom));
  256. for (i=0; i<(sizeof(Net1394ConfigRom)-1); i++)
  257. {
  258. if ((i%8) == 0)
  259. {
  260. printf("\n\t");
  261. }
  262. printf("0x%02lx, ", pb[i]);
  263. }
  264. printf("0x%02lx\n};\n", pb[i]);
  265. }
  266. #endif // TESTPROGRAM