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.

915 lines
31 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1999
  3. Module Name:
  4. p12843dl.c
  5. Abstract:
  6. This module contains utility code used by 1284.3 Data Link.
  7. Author:
  8. Robbie Harris (Hewlett-Packard) 10-September-1998
  9. Environment:
  10. Kernel mode
  11. Revision History :
  12. --*/
  13. #include "pch.h"
  14. #include "readwrit.h"
  15. #if PAR_TEST_HARNESS
  16. #include "parharns.h"
  17. #endif
  18. UCHAR Dot3_StartOfFrame1 = 0x55;
  19. UCHAR Dot3_StartOfFrame2 = 0xaa;
  20. UCHAR Dot3_EndOfFrame1 = 0x00;
  21. UCHAR Dot3_EndOfFrame2 = 0xff;
  22. NTSTATUS
  23. ParDot3Connect(
  24. IN PDEVICE_EXTENSION Extension
  25. )
  26. {
  27. NTSTATUS Status = STATUS_SUCCESS;
  28. ULONG ParFwdSkip, ParRevSkip;
  29. ULONG ParResetChannel, ParResetByteCount, ParResetByte;
  30. ULONG ParSkipDefault = 0;
  31. ULONG ParResetChannelDefault = -1;
  32. // If an MLC device hangs we can sometimes wake it up by wacking it with
  33. // 4 Zeros sent to the reset channel (typically 78 or 0x4E). Make this
  34. // configurable via registry setting.
  35. ULONG ParResetByteCountDefault = 4; // from MLC spec
  36. ULONG ParResetByteDefault = 0; // from MLC spec
  37. BOOLEAN bPrefs = FALSE; // used to determine if we were able
  38. // to get some preferred modes to
  39. // work with.
  40. BOOLEAN bConsiderEppDangerous = FALSE;
  41. if (P12843DL_OFF == Extension->P12843DL.DataLinkMode)
  42. {
  43. ParDump2(PARINFO, ("ParDot3Connect: Neither Dot3 or MLC are supported.\r\n"));
  44. return STATUS_UNSUCCESSFUL;
  45. }
  46. if (Extension->P12843DL.bEventActive)
  47. {
  48. ParDump2(PARINFO, ("ParDot3Connect: Already connected.\r\n"));
  49. return STATUS_UNSUCCESSFUL;
  50. }
  51. // Let's get a Device Id so we can pull settings
  52. // for this device
  53. ParTerminate(Extension);
  54. {
  55. PCHAR buffer = NULL;
  56. ULONG bufferLength;
  57. // ULONG bytesRead;
  58. UCHAR resultString[MAX_ID_SIZE];
  59. ANSI_STRING AnsiIdString;
  60. UNICODE_STRING UnicodeTemp;
  61. RTL_QUERY_REGISTRY_TABLE paramTable[6];
  62. UNICODE_STRING Dot3Key;
  63. USHORT Dot3NameSize;
  64. NTSTATUS status;
  65. // BOOLEAN boolResult;
  66. RtlZeroMemory(resultString, MAX_ID_SIZE);
  67. // ask the device how large of a buffer is needed to hold it's raw device id
  68. if ( Extension->Ieee1284Flags & ( 1 << Extension->Ieee1284_3DeviceId ) ) {
  69. buffer = Par3QueryDeviceId(Extension, NULL, 0, &bufferLength, FALSE, TRUE);
  70. }
  71. else{
  72. buffer = Par3QueryDeviceId(Extension, NULL, 0, &bufferLength, FALSE, FALSE);
  73. }
  74. if( !buffer ) {
  75. ParDump2(PARERRORS, ("ParDot3Connect: FAIL. Couldn't alloc pool for DevId\n") );
  76. return STATUS_UNSUCCESSFUL;
  77. }
  78. ParDump2(PARDOT3DL, ("ParDot3Connect:\"RAW\" ID string = <%s>\n", buffer) );
  79. // extract the part of the ID that we want from the raw string
  80. // returned by the hardware
  81. Status = ParPnpGetId( (PUCHAR)buffer, BusQueryDeviceID, resultString, NULL );
  82. StringSubst ((PUCHAR) resultString, ' ', '_', (USHORT)strlen(resultString));
  83. ParDump2(PARDOT3DL, ("ParDot3Connect: resultString Post StringSubst = <%s>\n", resultString) );
  84. // were we able to extract the info that we want from the raw ID string?
  85. if( !NT_SUCCESS(Status) ) {
  86. ParDump2(PARERRORS, ("ParDot3Connect: FAIL. Call to ParPnpGetId Failed\n") );
  87. return STATUS_UNSUCCESSFUL;
  88. }
  89. // Does the ID that we just retrieved from the device match the one
  90. // that we previously saved in the device extension?
  91. if(0 != strcmp( (const PCHAR)Extension->DeviceIdString, (const PCHAR)resultString)) {
  92. ParDump2(PARDOT3DL, ("ParDot3Connect: strcmp shows NO MATCH\n") );
  93. // DVDF - we may want to trigger a reenumeration since we know that the device changed
  94. }
  95. // Ok, now we have what we need to look in the registry
  96. // and pull some prefs.
  97. RtlZeroMemory(&paramTable[0], sizeof(paramTable));
  98. paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  99. paramTable[0].Name = (PWSTR)L"ParFwdSkip";
  100. paramTable[0].EntryContext = &ParFwdSkip;
  101. paramTable[0].DefaultType = REG_DWORD;
  102. paramTable[0].DefaultData = &ParSkipDefault;
  103. paramTable[0].DefaultLength = sizeof(ULONG);
  104. paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  105. paramTable[1].Name = (PWSTR)L"ParRevSkip";
  106. paramTable[1].EntryContext = &ParRevSkip;
  107. paramTable[1].DefaultType = REG_DWORD;
  108. paramTable[1].DefaultData = &ParSkipDefault;
  109. paramTable[1].DefaultLength = sizeof(ULONG);
  110. paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  111. paramTable[2].Name = (PWSTR)L"ParRC";
  112. paramTable[2].EntryContext = &ParResetChannel;
  113. paramTable[2].DefaultType = REG_DWORD;
  114. paramTable[2].DefaultData = &ParResetChannelDefault;
  115. paramTable[2].DefaultLength = sizeof(ULONG);
  116. paramTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
  117. paramTable[3].Name = (PWSTR)L"ParRBC";
  118. paramTable[3].EntryContext = &ParResetByteCount;
  119. paramTable[3].DefaultType = REG_DWORD;
  120. paramTable[3].DefaultData = &ParResetByteCountDefault;
  121. paramTable[3].DefaultLength = sizeof(ULONG);
  122. paramTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT;
  123. paramTable[4].Name = (PWSTR)L"ParRBD";
  124. paramTable[4].EntryContext = &ParResetByte;
  125. paramTable[4].DefaultType = REG_DWORD;
  126. paramTable[4].DefaultData = &ParResetByteDefault;
  127. paramTable[4].DefaultLength = sizeof(ULONG);
  128. Dot3Key.Buffer = NULL;
  129. Dot3Key.Length = 0;
  130. Dot3NameSize = sizeof(L"Dot3\\") + sizeof(UNICODE_NULL);
  131. Dot3Key.MaximumLength = (USHORT)( Dot3NameSize + (sizeof(resultString) * sizeof(WCHAR)) );
  132. Dot3Key.Buffer = ExAllocatePool(PagedPool,
  133. Dot3Key.MaximumLength);
  134. if (!Dot3Key.Buffer)
  135. {
  136. ParDump2(PARERRORS, ("ParDot3Connect: FAIL. ExAllocatePool for Registry Check.\n") );
  137. return STATUS_UNSUCCESSFUL;
  138. }
  139. ParDump2(PARDOT3DL, ("ParDot3Connect: ready to Zero buffer, &Dot3Key= %x , MaximumLength=%d\n",
  140. &Dot3Key, Dot3Key.MaximumLength));
  141. RtlZeroMemory(Dot3Key.Buffer, Dot3Key.MaximumLength);
  142. status = RtlAppendUnicodeToString(&Dot3Key, (PWSTR)L"Dot3\\");
  143. ASSERT( NT_SUCCESS(status) );
  144. ParDump2(PARDOT3DL, ("ParDot3Connect:\"UNICODE\" Dot3Key S = <%S>\n", Dot3Key.Buffer) );
  145. ParDump2(PARDOT3DL, ("ParDot3Connect:\"UNICODE\" Dot3Key wZ = <%wZ>\n", &Dot3Key) );
  146. ParDump2(PARDOT3DL, ("ParDot3Connect:\"RAW\" resultString string = <%s>\n", resultString) );
  147. RtlInitAnsiString(&AnsiIdString,resultString);
  148. status = RtlAnsiStringToUnicodeString(&UnicodeTemp,&AnsiIdString,TRUE);
  149. if( NT_SUCCESS( status ) ) {
  150. ParDump2(PARDOT3DL, ("ParDot3Connect:\"UNICODE\" UnicodeTemp = <%S>\n", UnicodeTemp.Buffer) );
  151. Dot3Key.Buffer[(Dot3NameSize / sizeof(WCHAR)) - 1] = UNICODE_NULL;
  152. ParDump2(PARDOT3DL, ("ParDot3Connect:\"UNICODE\" Dot3Key (preappend) = <%S>\n", Dot3Key.Buffer) );
  153. status = RtlAppendUnicodeStringToString(&Dot3Key, &UnicodeTemp);
  154. if( NT_SUCCESS( status ) ) {
  155. ParDump2(PARDOT3DL, ("ParDot3Connect: ready to call RtlQuery...\n") );
  156. Status = RtlQueryRegistryValues( RTL_REGISTRY_CONTROL, Dot3Key.Buffer, &paramTable[0], NULL, NULL);
  157. ParDump2(PARINFO, ("ParDot3Connect: RtlQueryRegistryValues Status = %x\n", Status));
  158. }
  159. RtlFreeUnicodeString(&UnicodeTemp);
  160. }
  161. if (Dot3Key.Buffer)
  162. ExFreePool (Dot3Key.Buffer);
  163. // no longer needed
  164. ExFreePool(buffer);
  165. if (!NT_SUCCESS(Status)) {
  166. // registry read failed
  167. ParDump2(PARINFO, ("ParDot3Connect: No Periph Defaults in Registry\n") );
  168. ParDump2(PARDOT3DL, ("ParDot3Connect: No Periph Defaults in Registry\n") );
  169. // registry read failed, use defaults and consider EPP to be dangerous
  170. ParRevSkip = ParFwdSkip = ParSkipDefault;
  171. bConsiderEppDangerous = TRUE;
  172. }
  173. ParDump2(PARDOT3DL, ("ParDot3Connect: pre IeeeNegotiateBestMode\n") );
  174. // if we don't have registry overrides then use what the
  175. // peripheral told us otherwise stick with defaults.
  176. if (ParSkipDefault == ParRevSkip)
  177. ParRevSkip = Extension->P12843DL.RevSkipMask;
  178. else
  179. Extension->P12843DL.RevSkipMask = (USHORT) ParRevSkip;
  180. if (ParSkipDefault == ParFwdSkip)
  181. ParFwdSkip = Extension->P12843DL.FwdSkipMask;
  182. else
  183. Extension->P12843DL.FwdSkipMask = (USHORT) ParFwdSkip;
  184. if( bConsiderEppDangerous ) {
  185. ParFwdSkip |= EPP_ANY;
  186. ParRevSkip |= EPP_ANY;
  187. }
  188. Status = IeeeNegotiateBestMode(Extension, (USHORT)ParRevSkip, (USHORT)ParFwdSkip);
  189. if( !NT_SUCCESS(Status) ) {
  190. ParDump2(PARERRORS, ("ParDot3Connect: FAIL. Peripheral Negotiation Failed\n") );
  191. return Status;
  192. }
  193. Extension->ForwardInterfaceAddress = Extension->P12843DL.DataChannel;
  194. if (Extension->P12843DL.DataLinkMode == P12843DL_MLC_DL)
  195. {
  196. if (ParResetChannel != ParResetChannelDefault)
  197. {
  198. Extension->P12843DL.ResetByte = (UCHAR) ParResetByte & 0xff;
  199. Extension->P12843DL.ResetByteCount = (UCHAR) ParResetByteCount & 0xff;
  200. if (ParResetChannel == PAR_COMPATIBILITY_RESET)
  201. Extension->P12843DL.fnReset = ParMLCCompatReset;
  202. else
  203. {
  204. // Max ECP channel is 127 so let's mask off bogus bits.
  205. Extension->P12843DL.ResetChannel = (UCHAR) ParResetChannel & 0x7f;
  206. Extension->P12843DL.fnReset = ParMLCECPReset;
  207. }
  208. }
  209. }
  210. if (Extension->P12843DL.fnReset)
  211. {
  212. ParDump2(PARDOT3DL, ("ParDot3Connect: MLCReset is supported on %x\n", Extension->P12843DL.ResetChannel) );
  213. Status = ((PDOT3_RESET_ROUTINE) (Extension->P12843DL.fnReset))(Extension);
  214. }
  215. else
  216. {
  217. ParDump2(PARDOT3DL, ("ParDot3Connect: MLCReset is not supported\n") );
  218. Status = ParSetFwdAddress(Extension);
  219. }
  220. if( !NT_SUCCESS(Status) ) {
  221. ParDump2(PARERRORS, ("ParDot3Connect: FAIL. Couldn't Set Address\n") );
  222. return Status;
  223. }
  224. // Check to make sure we are ECP, BECP, or EPP
  225. ParDump2(PARDOT3DL, ("ParDot3Connect: pre check of ECP, BECP, EPP\n") );
  226. if (afpForward[Extension->IdxForwardProtocol].ProtocolFamily != FAMILY_BECP &&
  227. afpForward[Extension->IdxForwardProtocol].ProtocolFamily != FAMILY_ECP &&
  228. afpForward[Extension->IdxForwardProtocol].ProtocolFamily != FAMILY_EPP)
  229. {
  230. ParDump2(PARERRORS, ("ParDot3Connect: FAIL. We did not reach ECP or EPP.\n") );
  231. return STATUS_UNSUCCESSFUL;
  232. }
  233. }
  234. #if PAR_TEST_HARNESS
  235. ParHarnessLoad(Extension);
  236. #endif
  237. if (Extension->P12843DL.DataLinkMode == P12843DL_DOT3_DL)
  238. {
  239. ParDump2(PARDOT3DL, ("ParDot3Connect: P12843DL_DOT3_DL\n") );
  240. Extension->P12843DL.fnRead = (PVOID) arpReverse[Extension->IdxReverseProtocol].fnRead;
  241. Extension->P12843DL.fnWrite = (PVOID) afpForward[Extension->IdxForwardProtocol].fnWrite;
  242. #if (1 == DVRH_USE_CORRECT_PTRS)
  243. Extension->fnRead = ParDot3Read;
  244. Extension->fnWrite = ParDot3Write;
  245. #else
  246. arpReverse[Extension->IdxReverseProtocol].fnRead = ParDot3Read;
  247. afpForward[Extension->IdxForwardProtocol].fnWrite = ParDot3Write;
  248. #endif
  249. }
  250. // DVDF 990504 - removed: Extension->P12843DL.bEventActive = NT_SUCCESS(Status);
  251. ParDump2(PARDOT3DL, ("ParDot3Connect: Exit %d\n", NT_SUCCESS(Status)) );
  252. return Status;
  253. }
  254. VOID
  255. ParDot3CreateObject(
  256. IN PDEVICE_EXTENSION Extension,
  257. IN PUCHAR DOT3DL,
  258. IN PUCHAR DOT3C
  259. )
  260. {
  261. Extension->P12843DL.DataLinkMode = P12843DL_OFF;
  262. Extension->P12843DL.fnReset = NULL;
  263. ParDump2(PARDUMP_PNP_DL, ("ParDot3CreateObject: DOT3DL [%s] DOT3C\n",
  264. DOT3DL, DOT3C) );
  265. if (DOT3DL)
  266. {
  267. ULONG dataChannel;
  268. ULONG pid = 0x285; // pid for dot4
  269. // Only use the first channel.
  270. if (!String2Num(&DOT3DL, ',', &dataChannel))
  271. {
  272. dataChannel = 77;
  273. ParDump2(PARINFO, ("ParDot3CreateObject: No DataChannel Defined.\r\n"));
  274. }
  275. if (DOT3C)
  276. {
  277. if (!String2Num(&DOT3C, ',', &pid))
  278. {
  279. pid = 0x285;
  280. ParDump2(PARINFO, ("ParDot3CreateObject: No CurrentPID Defined.\r\n"));
  281. }
  282. ParDump2(PARINFO, ("ParDot3CreateObject: .3 mode is ON.\r\n"));
  283. }
  284. Extension->P12843DL.DataChannel = (UCHAR)dataChannel;
  285. Extension->P12843DL.CurrentPID = (USHORT)pid;
  286. Extension->P12843DL.DataLinkMode = P12843DL_DOT3_DL;
  287. ParDump2(PARINFO, ("ParDot3CreateObject: Data [%x] CurrentPID [%x]\r\n",
  288. Extension->P12843DL.DataChannel,
  289. Extension->P12843DL.CurrentPID));
  290. }
  291. #if DBG
  292. if (Extension->P12843DL.DataLinkMode == P12843DL_OFF)
  293. {
  294. ParDump2(PARINFO, ("ParDot3CreateObject: DANGER: .3 mode is OFF.\r\n"));
  295. }
  296. #endif
  297. }
  298. VOID
  299. ParDot4CreateObject(
  300. IN PDEVICE_EXTENSION Extension,
  301. IN PUCHAR DOT4DL
  302. )
  303. {
  304. Extension->P12843DL.DataLinkMode = P12843DL_OFF;
  305. Extension->P12843DL.fnReset = NULL;
  306. ParDump2(PARDUMP_PNP_DL, ("ParDot3CreateObject: DOT4DL [%s]\n",
  307. DOT4DL) );
  308. if (DOT4DL)
  309. {
  310. UCHAR numValues = StringCountValues(DOT4DL, ',');
  311. ULONG dataChannel, resetChannel, ResetByteCount;
  312. ParDump2(PARDUMP_PNP_DL, ("ParDot3CreateObject: numValues [%d]\n",
  313. numValues) );
  314. if (!String2Num(&DOT4DL, ',', &dataChannel))
  315. {
  316. dataChannel = 77;
  317. ParDump2(PARINFO, ("ParDot4CreateObject: No DataChannel Defined.\r\n"));
  318. }
  319. if ((String2Num(&DOT4DL, ',', &resetChannel))
  320. && (numValues > 1))
  321. {
  322. if (resetChannel == -1)
  323. {
  324. Extension->P12843DL.fnReset = ParMLCCompatReset;
  325. }
  326. else
  327. {
  328. Extension->P12843DL.fnReset = ParMLCECPReset;
  329. }
  330. ParDump2(PARINFO, ("ParDot4CreateObject: ResetChannel Defined.\r\n"));
  331. }
  332. else
  333. {
  334. Extension->P12843DL.fnReset = NULL;
  335. ParDump2(PARINFO, ("ParDot4CreateObject: No ResetChannel Defined.\r\n"));
  336. }
  337. if ((!String2Num(&DOT4DL, 0, &ResetByteCount))
  338. && (numValues > 2))
  339. {
  340. ResetByteCount = 4;
  341. ParDump2(PARINFO, ("ParDot4CreateObject: No ResetByteCount Defined.\r\n"));
  342. }
  343. Extension->P12843DL.DataChannel = (UCHAR)dataChannel;
  344. Extension->P12843DL.ResetChannel = (UCHAR)resetChannel;
  345. Extension->P12843DL.ResetByteCount = (UCHAR)ResetByteCount;
  346. Extension->P12843DL.DataLinkMode = P12843DL_DOT4_DL;
  347. ParDump2(PARINFO, ("ParDot4CreateObject: .4DL mode is ON.\r\n"));
  348. ParDump2(PARINFO, ("ParDot4CreateObject: Data [%x] Reset [%x] Bytes [%x]\r\n",
  349. Extension->P12843DL.DataChannel,
  350. Extension->P12843DL.ResetChannel,
  351. Extension->P12843DL.ResetByteCount));
  352. }
  353. #if DBG
  354. if (Extension->P12843DL.DataLinkMode == P12843DL_OFF)
  355. {
  356. ParDump2(PARINFO, ("ParDot4CreateObject: DANGER: .4DL mode is OFF.\r\n"));
  357. }
  358. #endif
  359. }
  360. VOID
  361. ParMLCCreateObject(
  362. IN PDEVICE_EXTENSION Extension,
  363. IN PUCHAR CMDField
  364. )
  365. {
  366. // UCHAR ForwardInterfaceAddress;
  367. // UCHAR ReverseInterfaceAddress;
  368. Extension->P12843DL.DataLinkMode = P12843DL_OFF;
  369. Extension->P12843DL.fnReset = NULL;
  370. if (CMDField)
  371. {
  372. Extension->P12843DL.DataChannel = 77;
  373. Extension->P12843DL.DataLinkMode = P12843DL_MLC_DL;
  374. ParDump2(PARINFO, ("ParMLCCreateObject: MLC mode is on.\r\n"));
  375. }
  376. #if DBG
  377. if (Extension->P12843DL.DataLinkMode == P12843DL_OFF)
  378. {
  379. ParDump2(PARINFO, ("ParMLCCreateObject: DANGER: MLC mode is OFF.\r\n"));
  380. }
  381. #endif
  382. }
  383. VOID
  384. ParDot3DestroyObject(
  385. IN PDEVICE_EXTENSION Extension
  386. )
  387. {
  388. Extension->P12843DL.DataLinkMode = P12843DL_OFF;
  389. }
  390. NTSTATUS
  391. ParDot3Disconnect(
  392. IN PDEVICE_EXTENSION Extension
  393. )
  394. {
  395. #if PAR_TEST_HARNESS
  396. ParHarnessUnload(Extension);
  397. #endif
  398. if (Extension->P12843DL.DataLinkMode == P12843DL_DOT3_DL)
  399. {
  400. #if (1 == DVRH_USE_CORRECT_PTRS)
  401. Extension->fnRead = arpReverse[Extension->IdxReverseProtocol].fnRead;
  402. Extension->fnWrite = afpForward[Extension->IdxForwardProtocol].fnWrite;
  403. #else
  404. arpReverse[Extension->IdxReverseProtocol].fnRead = (PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead;
  405. afpForward[Extension->IdxForwardProtocol].fnWrite = (PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite;
  406. #endif
  407. }
  408. Extension->P12843DL.bEventActive = FALSE;
  409. Extension->P12843DL.Event = 0;
  410. return STATUS_SUCCESS;
  411. }
  412. VOID
  413. ParDot3ParseModes(
  414. IN PDEVICE_EXTENSION Extension,
  415. IN PUCHAR DOT3M
  416. )
  417. {
  418. ULONG fwd = 0;
  419. ULONG rev = 0;
  420. ParDump2(PARDUMP_PNP_DL, ("ParDot3ParseModes: DOT3M [%s]\n",
  421. DOT3M) );
  422. if (DOT3M)
  423. {
  424. UCHAR numValues = StringCountValues(DOT3M, ',');
  425. if (numValues != 2)
  426. {
  427. // The periph gave me bad values. I'm not gonna read
  428. // them. I will set the defaults to the lowest
  429. // common denominator.
  430. ParDump2(PARINFO, ("ParDot3ParseModes: Malformed 1284.3M field.\r\n"));
  431. Extension->P12843DL.FwdSkipMask = (USHORT) PAR_FWD_MODE_SKIP_MASK;
  432. Extension->P12843DL.RevSkipMask = (USHORT) PAR_REV_MODE_SKIP_MASK;
  433. return;
  434. }
  435. // Only use the first channel.
  436. if (!String2Num(&DOT3M, ',', &fwd))
  437. {
  438. fwd = (USHORT) PAR_FWD_MODE_SKIP_MASK;
  439. ParDump2(PARINFO, ("ParDot3ParseModes: Couldn't read fwd of 1284.3M.\r\n"));
  440. }
  441. if (!String2Num(&DOT3M, ',', &rev))
  442. {
  443. rev = (USHORT) PAR_REV_MODE_SKIP_MASK;
  444. ParDump2(PARINFO, ("ParDot3ParseModes: Couldn't read rev of 1284.3M.\r\n"));
  445. }
  446. }
  447. Extension->P12843DL.FwdSkipMask = (USHORT) fwd;
  448. Extension->P12843DL.RevSkipMask = (USHORT) rev;
  449. }
  450. NTSTATUS
  451. ParDot3Read(
  452. IN PDEVICE_EXTENSION Extension,
  453. IN PVOID Buffer,
  454. IN ULONG BufferSize,
  455. OUT PULONG BytesTransferred
  456. )
  457. {
  458. NTSTATUS Status;
  459. UCHAR ucScrap1;
  460. UCHAR ucScrap2[2];
  461. USHORT usScrap1;
  462. ULONG bytesToRead;
  463. ULONG bytesTransferred;
  464. USHORT Dot3CheckSum;
  465. USHORT Dot3DataLen;
  466. // ================================== Read the first byte of SOF
  467. bytesToRead = 1;
  468. bytesTransferred = 0;
  469. do
  470. {
  471. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &ucScrap1, bytesToRead, &bytesTransferred);
  472. }
  473. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  474. // ================================== Check the first byte of SOF
  475. if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_StartOfFrame1)
  476. {
  477. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  478. *BytesTransferred = 0;
  479. return(Status);
  480. }
  481. // ================================== Read the second byte of SOF
  482. bytesToRead = 1;
  483. bytesTransferred = 0;
  484. do
  485. {
  486. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &ucScrap1, bytesToRead, &bytesTransferred);
  487. }
  488. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  489. // ================================== Check the second byte of SOF
  490. if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_StartOfFrame2)
  491. {
  492. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  493. *BytesTransferred = 0;
  494. return(Status);
  495. }
  496. // ================================== Read the PID (Should be in Big Endian)
  497. bytesToRead = 2;
  498. bytesTransferred = 0;
  499. do
  500. {
  501. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &usScrap1, bytesToRead, &bytesTransferred);
  502. }
  503. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  504. // ================================== Check the PID
  505. if (!NT_SUCCESS(Status) || usScrap1 != Extension->P12843DL.CurrentPID)
  506. {
  507. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  508. *BytesTransferred = 0;
  509. return(Status);
  510. }
  511. // ================================== Read the DataLen
  512. bytesToRead = 2;
  513. bytesTransferred = 0;
  514. do
  515. {
  516. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &ucScrap2[0], bytesToRead, &bytesTransferred);
  517. }
  518. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  519. Dot3DataLen = (USHORT)((USHORT)(ucScrap2[0]<<8 | ucScrap2[1]) + 1);
  520. // ================================== Check the DataLen
  521. if (!NT_SUCCESS(Status))
  522. {
  523. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  524. *BytesTransferred = 0;
  525. return(Status);
  526. }
  527. // ================================== Read the Checksum
  528. bytesToRead = 2;
  529. bytesTransferred = 0;
  530. do
  531. {
  532. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &ucScrap2[0], bytesToRead, &bytesTransferred);
  533. }
  534. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  535. Dot3CheckSum = (USHORT)(ucScrap2[0]<<8 | ucScrap2[1]);
  536. // ================================== Check the DataLen
  537. if (!NT_SUCCESS(Status))
  538. {
  539. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  540. *BytesTransferred = 0;
  541. return(Status);
  542. }
  543. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, Buffer, BufferSize, BytesTransferred);
  544. if (!NT_SUCCESS(Status))
  545. {
  546. ParDump2(PARERRORS, ("ParDot3Read: Data Read Failed. We're Hosed!\n"));
  547. return(Status);
  548. }
  549. // BUG BUG.... What do I do if the buffer < data
  550. if ((ULONG)Dot3DataLen > BufferSize)
  551. {
  552. // buffer overflow - abort operation
  553. ParDump2(PARERRORS, ("ParDot3Read: Bad 1284.3DL Data Len. Buffer overflow. We're Hosed!\n"));
  554. return STATUS_BUFFER_OVERFLOW;
  555. }
  556. // Check Checksum
  557. if (~((~Extension->P12843DL.CurrentPID)+ (~(BufferSize - 1))) != Dot3CheckSum)
  558. {
  559. ParDump2(PARERRORS, ("ParDot3Read: Bad 1284.3DL Checksum. We're Hosed!\n"));
  560. return STATUS_DEVICE_PROTOCOL_ERROR;
  561. }
  562. // ================================== Read the first byte of EOF
  563. bytesToRead = 1;
  564. bytesTransferred = 0;
  565. do
  566. {
  567. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &ucScrap1, bytesToRead, &bytesTransferred);
  568. }
  569. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  570. // ================================== Check the first byte of EOF
  571. if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_EndOfFrame1)
  572. {
  573. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  574. *BytesTransferred = 0;
  575. return(Status);
  576. }
  577. // ================================== Read the second byte of EOF
  578. bytesToRead = 1;
  579. bytesTransferred = 0;
  580. do
  581. {
  582. Status = ((PPROTOCOL_READ_ROUTINE) Extension->P12843DL.fnRead)(Extension, &ucScrap1, bytesToRead, &bytesTransferred);
  583. }
  584. while(NT_SUCCESS(Status) && bytesTransferred != bytesToRead);
  585. // ================================== Check the second byte of EOF
  586. if (!NT_SUCCESS(Status) || ucScrap1 != Dot3_EndOfFrame2)
  587. {
  588. ParDump2(PARERRORS, ("ParDot3Read: Header Read Failed. We're Hosed!\n"));
  589. *BytesTransferred = 0;
  590. return(Status);
  591. }
  592. return Status;
  593. }
  594. NTSTATUS
  595. ParDot3Write(
  596. IN PDEVICE_EXTENSION Extension,
  597. IN PVOID Buffer,
  598. IN ULONG BufferSize,
  599. OUT PULONG BytesTransferred
  600. )
  601. {
  602. NTSTATUS Status;
  603. ULONG frameBytesTransferred;
  604. ULONG bytesToWrite;
  605. USHORT scrap1;
  606. USHORT scrap2;
  607. USHORT scrapHigh;
  608. USHORT scrapLow;
  609. PUCHAR p;
  610. // ========================= Write out first Byte of SOF
  611. bytesToWrite = 1;
  612. frameBytesTransferred = 0;
  613. do
  614. {
  615. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &Dot3_StartOfFrame1, bytesToWrite, &frameBytesTransferred);
  616. }
  617. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  618. // ========================= Check first Byte of SOF
  619. if (!NT_SUCCESS(Status))
  620. {
  621. *BytesTransferred = 0;
  622. return(Status);
  623. }
  624. // ========================= Write out second Byte of SOF
  625. bytesToWrite = 1;
  626. frameBytesTransferred = 0;
  627. do
  628. {
  629. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &Dot3_StartOfFrame2, bytesToWrite, &frameBytesTransferred);
  630. }
  631. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  632. // ========================= Check second Byte of SOF
  633. if (!NT_SUCCESS(Status))
  634. {
  635. *BytesTransferred = 0;
  636. return(Status);
  637. }
  638. // ========================= Write out PID (which should be in Big Endian already)
  639. bytesToWrite = 2;
  640. frameBytesTransferred = 0;
  641. do
  642. {
  643. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &Extension->P12843DL.CurrentPID, bytesToWrite, &frameBytesTransferred);
  644. }
  645. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  646. // ========================= Check PID
  647. if (!NT_SUCCESS(Status))
  648. {
  649. *BytesTransferred = 0;
  650. return(Status);
  651. }
  652. // ========================= Write out Length of Data
  653. bytesToWrite = 2;
  654. frameBytesTransferred = 0;
  655. scrap1 = (USHORT) (BufferSize - 1);
  656. scrapLow = (UCHAR) (scrap1 && 0xff);
  657. scrapHigh = (UCHAR) (scrap1 >> 8);
  658. p = (PUCHAR)&scrap2;
  659. *p++ = (UCHAR)scrapHigh;
  660. *p = (UCHAR)scrapLow;
  661. do
  662. {
  663. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &scrap2, bytesToWrite, &frameBytesTransferred);
  664. }
  665. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  666. // ========================= Check Length of Data
  667. if (!NT_SUCCESS(Status))
  668. {
  669. *BytesTransferred = 0;
  670. return(Status);
  671. }
  672. // ========================= Write out Checksum
  673. bytesToWrite = 2;
  674. frameBytesTransferred = 0;
  675. scrap1=~((USHORT)(~Extension->P12843DL.CurrentPID)+ (~((USHORT)BufferSize - 1)));
  676. scrapLow = (UCHAR) (scrap1 && 0xff);
  677. scrapHigh = (UCHAR) (scrap1 >> 8);
  678. p = (PUCHAR)&scrap2;
  679. *p++ = (UCHAR)scrapHigh;
  680. *p = (UCHAR)scrapLow;
  681. do
  682. {
  683. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &scrap2, bytesToWrite, &frameBytesTransferred);
  684. }
  685. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  686. // ========================= Check Checksum
  687. if (!NT_SUCCESS(Status))
  688. {
  689. *BytesTransferred = 0;
  690. return(Status);
  691. }
  692. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, Buffer, BufferSize, BytesTransferred);
  693. if (NT_SUCCESS(Status))
  694. {
  695. // ========================= Write out first Byte of EOF
  696. bytesToWrite = 1;
  697. frameBytesTransferred = 0;
  698. do
  699. {
  700. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &Dot3_EndOfFrame1, bytesToWrite, &frameBytesTransferred);
  701. }
  702. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  703. // ========================= Check first Byte of EOF
  704. if (!NT_SUCCESS(Status))
  705. {
  706. *BytesTransferred = 0;
  707. return(Status);
  708. }
  709. // ========================= Write out second Byte of EOF
  710. bytesToWrite = 1;
  711. frameBytesTransferred = 0;
  712. do
  713. {
  714. Status = ((PPROTOCOL_WRITE_ROUTINE) Extension->P12843DL.fnWrite)(Extension, &Dot3_EndOfFrame2, bytesToWrite, &frameBytesTransferred);
  715. }
  716. while(NT_SUCCESS(Status) && frameBytesTransferred != bytesToWrite);
  717. // ========================= Check second Byte of EOF
  718. if (!NT_SUCCESS(Status))
  719. {
  720. *BytesTransferred = 0;
  721. return(Status);
  722. }
  723. }
  724. return Status;
  725. }
  726. NTSTATUS
  727. ParMLCCompatReset(
  728. IN PDEVICE_EXTENSION Extension
  729. )
  730. {
  731. NTSTATUS Status = STATUS_SUCCESS;
  732. UCHAR Reset[256]; // Reset should not require more than 256 chars
  733. const ULONG ResetLen = Extension->P12843DL.ResetByteCount;
  734. ULONG BytesWritten;
  735. ParDump2( PARENTRY, ("ParMLCCompatReset: Start\n"));
  736. if (Extension->P12843DL.DataLinkMode != P12843DL_MLC_DL &&
  737. Extension->P12843DL.DataLinkMode != P12843DL_DOT4_DL)
  738. {
  739. ParDump2(PARINFO, ("ParMLCCompatReset: not MLC.\n") );
  740. return STATUS_SUCCESS;
  741. }
  742. ParTerminate(Extension);
  743. // Sending NULLs for reset
  744. ParDump2(PARINFO, ("ParMLCCompatReset: Zeroing Reset Bytes.\n") );
  745. RtlFillMemory(Reset, ResetLen, Extension->P12843DL.ResetByte);
  746. ParDump2(PARINFO, ("ParMLCCompatReset: Sending Reset Bytes.\n") );
  747. // Don't use the Dot3Write since we are in MLC Mode.
  748. Status = SppWrite(Extension, Reset, ResetLen, &BytesWritten);
  749. if (!NT_SUCCESS(Status) || BytesWritten != ResetLen)
  750. {
  751. ParDump2(PARERRORS, ("ParMLCCompatReset: FAIL. Write Failed\n") );
  752. return Status;
  753. }
  754. ParDump2(PARINFO, ("ParMLCCompatReset: Reset Bytes were sent.\n") );
  755. return Status;
  756. }
  757. NTSTATUS
  758. ParMLCECPReset(
  759. IN PDEVICE_EXTENSION Extension
  760. )
  761. {
  762. NTSTATUS Status = STATUS_SUCCESS;
  763. UCHAR Reset[256]; // Reset should not require more than 256 chars
  764. const ULONG ResetLen = Extension->P12843DL.ResetByteCount;
  765. ULONG BytesWritten;
  766. ParDump2( PARENTRY, ("ParMLCECPReset: Start\n"));
  767. if (Extension->P12843DL.DataLinkMode != P12843DL_MLC_DL &&
  768. Extension->P12843DL.DataLinkMode != P12843DL_DOT4_DL)
  769. {
  770. ParDump2(PARINFO, ("ParMLCECPReset: not MLC.\n") );
  771. return STATUS_SUCCESS;
  772. }
  773. Status = ParReverseToForward(Extension);
  774. Extension->ForwardInterfaceAddress = Extension->P12843DL.ResetChannel;
  775. Status = ParSetFwdAddress(Extension);
  776. if (!NT_SUCCESS(Status))
  777. {
  778. ParDump2(PARERRORS, ("ParMLCECPReset: FAIL. Couldn't Set Reset Channel\n") );
  779. return Status;
  780. }
  781. // Sending NULLs for reset
  782. ParDump2(PARINFO, ("ParMLCECPReset: Zeroing Reset Bytes.\n") );
  783. RtlFillMemory(Reset, ResetLen, Extension->P12843DL.ResetByte);
  784. ParDump2(PARINFO, ("ParMLCECPReset: Sending Reset Bytes.\n") );
  785. // Don't use the Dot3Write since we are in MLC Mode.
  786. Status = afpForward[Extension->IdxForwardProtocol].fnWrite(Extension, Reset, ResetLen, &BytesWritten);
  787. if (!NT_SUCCESS(Status) || BytesWritten != ResetLen)
  788. {
  789. ParDump2(PARERRORS, ("ParMLCECPReset: FAIL. Write Failed\n") );
  790. return Status;
  791. }
  792. ParDump2(PARINFO, ("ParMLCECPReset: Reset Bytes were sent.\n") );
  793. Extension->ForwardInterfaceAddress = Extension->P12843DL.DataChannel;
  794. Status = ParSetFwdAddress(Extension);
  795. if (!NT_SUCCESS(Status))
  796. {
  797. ParDump2(PARERRORS, ("ParMLCECPReset: FAIL. Couldn't Set Data Channel\n") );
  798. return Status;
  799. }
  800. return Status;
  801. }