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.

894 lines
29 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: readwrit.c
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // This file contains functions associated with handling Read and Write requests
  12. //
  13. #include "pch.h"
  14. #include "ecp.h"
  15. #include "readwrit.h"
  16. NTSTATUS
  17. ParForwardToReverse(
  18. IN PDEVICE_EXTENSION Extension
  19. )
  20. /*++
  21. Routine Description:
  22. This routine flips the bus from Forward to Reverse direction.
  23. Arguments:
  24. Extension - Supplies the device extension.
  25. Return Value:
  26. None.
  27. --*/
  28. {
  29. NTSTATUS Status = STATUS_SUCCESS;
  30. // Do a quick check to see if we are where we want to be.
  31. // Happy punt if everything is ok.
  32. if (Extension->Connected &&
  33. (Extension->CurrentPhase == PHASE_REVERSE_IDLE ||
  34. Extension->CurrentPhase == PHASE_REVERSE_XFER))
  35. {
  36. ParDump2(PARINFO, ( "ParForwardToReverse: Already in Reverse Mode!\r\n" ));
  37. return Status;
  38. }
  39. if (Extension->Connected) {
  40. if (Extension->CurrentPhase != PHASE_REVERSE_IDLE &&
  41. Extension->CurrentPhase != PHASE_REVERSE_XFER) {
  42. if (afpForward[Extension->IdxForwardProtocol].ProtocolFamily ==
  43. arpReverse[Extension->IdxReverseProtocol].ProtocolFamily) {
  44. ParDump2(PARINFO, ( "ParForwardToReverse: Protocol families match!\r\n" ));
  45. // Protocol Families match and we are in Fwd. Exit Fwd to cleanup the state
  46. // machine, fifo, etc. We will call EnterReverse later to
  47. // actually bus flip. Also only do this if in safe mode
  48. if ( (afpForward[Extension->IdxForwardProtocol].fnExitForward) ) {
  49. Status = afpForward[Extension->IdxForwardProtocol].fnExitForward(Extension);
  50. }
  51. } else {
  52. ParDump2(PARINFO, ( "ParForwardToReverse: Protocol families DO NOT match!\r\n" ));
  53. //
  54. // Protocol Families don't match...need to terminate from the forward mode
  55. //
  56. if (afpForward[Extension->IdxForwardProtocol].fnDisconnect)
  57. {
  58. ParDump2(PARINFO, ("ParForwardToReverse: Calling afpForward.fnDisconnect\r\n"));
  59. afpForward[Extension->IdxForwardProtocol].fnDisconnect (Extension);
  60. }
  61. if ((Extension->ForwardInterfaceAddress != DEFAULT_ECP_CHANNEL) &&
  62. (afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress))
  63. Extension->SetForwardAddress = TRUE;
  64. }
  65. }
  66. }
  67. if ((!Extension->Connected) &&
  68. (arpReverse[Extension->IdxReverseProtocol].fnConnect)) {
  69. ParDump2(PARINFO, ( "ParForwardToReverse: Not Connected so Calling Reverse Connect!\r\n" ));
  70. //
  71. // If we are still connected the protocol families match...
  72. //
  73. Status = arpReverse[Extension->IdxReverseProtocol].fnConnect(Extension, FALSE);
  74. //
  75. // Makes the assumption that the connected address is always 0
  76. //
  77. if ((NT_SUCCESS(Status)) &&
  78. (arpReverse[Extension->IdxReverseProtocol].fnSetInterfaceAddress) &&
  79. (Extension->ReverseInterfaceAddress != DEFAULT_ECP_CHANNEL)) {
  80. Extension->SetReverseAddress = TRUE;
  81. }
  82. }
  83. //
  84. // Set the channel address if we need to.
  85. //
  86. if (NT_SUCCESS(Status) && Extension->SetReverseAddress &&
  87. (arpReverse[Extension->IdxReverseProtocol].fnSetInterfaceAddress)) {
  88. Status = arpReverse[Extension->IdxReverseProtocol].fnSetInterfaceAddress (
  89. Extension,
  90. Extension->ReverseInterfaceAddress);
  91. if (NT_SUCCESS(Status))
  92. Extension->SetReverseAddress = FALSE;
  93. else
  94. Extension->SetReverseAddress = TRUE;
  95. }
  96. //
  97. // Do we need to reverse?
  98. //
  99. if ( (NT_SUCCESS(Status)) &&
  100. ((Extension->CurrentPhase != PHASE_REVERSE_IDLE) &&
  101. (Extension->CurrentPhase != PHASE_REVERSE_XFER)) ) {
  102. ParDump2(PARINFO, ( "ParForwardToReverse: Not IN REVERSE IDLE so Calling Reverse ENTER!\r\n" ));
  103. if ((arpReverse[Extension->IdxReverseProtocol].fnEnterReverse))
  104. Status = arpReverse[Extension->IdxReverseProtocol].fnEnterReverse(Extension);
  105. }
  106. ParDump2(PAREXIT, ( "ParForwardToReverse: Exit [%d]\r\n", NT_SUCCESS(Status)));
  107. return Status;
  108. }
  109. BOOLEAN
  110. ParHaveReadData(
  111. IN PDEVICE_EXTENSION Extension
  112. )
  113. /*++
  114. Routine Description:
  115. This method determines if the peripheral has any data ready
  116. to send to the host.
  117. Arguments:
  118. Extension - Supplies the device EXTENSION.
  119. Return Value:
  120. TRUE - Either the peripheral has data
  121. FALSE - No data
  122. --*/
  123. {
  124. if (Extension->CurrentPhase == PHASE_REVERSE_IDLE ||
  125. Extension->CurrentPhase == PHASE_REVERSE_XFER)
  126. {
  127. if (arpReverse[Extension->IdxReverseProtocol].fnHaveReadData)
  128. {
  129. if (arpReverse[Extension->IdxReverseProtocol].fnHaveReadData(Extension))
  130. return TRUE;
  131. // Don't have data. This could be a fluke. Let's
  132. // flip the bus and try in Fwd mode.
  133. ParReverseToForward(Extension);
  134. }
  135. }
  136. if (Extension->CurrentPhase == PHASE_FORWARD_IDLE ||
  137. Extension->CurrentPhase == PHASE_FORWARD_XFER)
  138. {
  139. if (afpForward[Extension->IdxForwardProtocol].ProtocolFamily == FAMILY_BECP ||
  140. afpForward[Extension->IdxForwardProtocol].Protocol & ECP_HW_NOIRQ ||
  141. afpForward[Extension->IdxForwardProtocol].Protocol & ECP_HW_IRQ)
  142. {
  143. if (ParEcpHwHaveReadData(Extension))
  144. return TRUE;
  145. // Hmmm. No data. Is the chip stuck?
  146. #define DVRH_DO_RETRY 0
  147. #if (1 == DVRH_DO_RETRY)
  148. // retry - slap periph to wake it up, then try again
  149. ParPing(Extension);
  150. return ParEcpHwHaveReadData(Extension);
  151. #else
  152. return FALSE;
  153. #endif
  154. }
  155. else if (afpForward[Extension->IdxForwardProtocol].Protocol & ECP_SW)
  156. return ParEcpHaveReadData(Extension);
  157. }
  158. // DVRH RMT
  159. // We got here because the protocol doesn't support peeking.
  160. // Let's go ahead and flip the bus to see if there is anything
  161. // there.
  162. return TRUE;
  163. }
  164. NTSTATUS
  165. ParPing(
  166. IN PDEVICE_EXTENSION Extension
  167. )
  168. /*++
  169. Routine Description:
  170. This method pings the device.
  171. Arguments:
  172. Extension - Supplies the device EXTENSION.
  173. Return Value:
  174. none
  175. --*/
  176. {
  177. NTSTATUS NtStatus = STATUS_SUCCESS;
  178. #if 0
  179. if ((Extension->CurrentPhase == PHASE_REVERSE_IDLE) ||
  180. (Extension->CurrentPhase == PHASE_REVERSE_XFER))
  181. {
  182. ParReverseToForward(Extension);
  183. if (arpReverse[Extension->IdxReverseProtocol].fnDisconnect)
  184. {
  185. ParDump2(PARINFO, ("ParPing: Calling arpReverse.fnDisconnect\n"));
  186. arpReverse[Extension->IdxReverseProtocol].fnDisconnect(Extension);
  187. }
  188. } else if ((Extension->CurrentPhase != PHASE_REVERSE_IDLE) &&
  189. (Extension->CurrentPhase != PHASE_REVERSE_XFER))
  190. {
  191. if (afpForward[Extension->IdxForwardProtocol].fnDisconnect)
  192. {
  193. ParDump2(PARINFO, ("ParPing: Calling afpForward.fnDisconnect\n"));
  194. afpForward[Extension->IdxForwardProtocol].fnDisconnect(Extension);
  195. }
  196. }
  197. if (afpForward[Extension->IdxForwardProtocol].fnConnect)
  198. {
  199. NtStatus = afpForward[Extension->IdxForwardProtocol].fnConnect(Extension, FALSE);
  200. if (NT_SUCCESS(NtStatus) &&
  201. (Extension->ForwardInterfaceAddress != DEFAULT_ECP_CHANNEL) &&
  202. (afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress))
  203. {
  204. NtStatus = afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress(Extension, Extension->ForwardInterfaceAddress);
  205. }
  206. }
  207. #endif
  208. return NtStatus;
  209. }
  210. NTSTATUS
  211. ParReadWrite(
  212. IN PDEVICE_OBJECT DeviceObject,
  213. IN PIRP Irp
  214. )
  215. /*++
  216. Routine Description:
  217. This is the dispatch routine for READ and WRITE requests.
  218. Arguments:
  219. DeviceObject - Supplies the device object.
  220. Irp - Supplies the I/O request packet.
  221. Return Value:
  222. STATUS_PENDING - Request pending - a worker thread will carry
  223. out the request at PASSIVE_LEVEL IRQL
  224. STATUS_SUCCESS - Success - asked for a read or write of
  225. length zero.
  226. STATUS_INVALID_PARAMETER - Invalid parameter.
  227. STATUS_DELETE_PENDING - This device object is being deleted.
  228. --*/
  229. {
  230. PIO_STACK_LOCATION IrpSp;
  231. PDEVICE_EXTENSION Extension;
  232. Irp->IoStatus.Information = 0;
  233. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  234. Extension = DeviceObject->DeviceExtension;
  235. ParTimerMainCheck( ("Enter ParReadWrite(...) - %wZ\r\n", &Extension->SymbolicLinkName) );
  236. //
  237. // bail out if a delete is pending for this device object
  238. //
  239. if(Extension->DeviceStateFlags & PAR_DEVICE_DELETE_PENDING) {
  240. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  241. ParCompleteRequest(Irp, IO_NO_INCREMENT);
  242. return STATUS_DELETE_PENDING;
  243. }
  244. //
  245. // bail out if a remove is pending for our ParPort device object
  246. //
  247. if(Extension->DeviceStateFlags & PAR_DEVICE_PORT_REMOVE_PENDING) {
  248. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  249. ParCompleteRequest(Irp, IO_NO_INCREMENT);
  250. return STATUS_DELETE_PENDING;
  251. }
  252. //
  253. // bail out if device has been removed
  254. //
  255. if(Extension->DeviceStateFlags & (PAR_DEVICE_REMOVED|PAR_DEVICE_SURPRISE_REMOVAL) ) {
  256. Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
  257. ParCompleteRequest(Irp, IO_NO_INCREMENT);
  258. return STATUS_DEVICE_REMOVED;
  259. }
  260. //
  261. // Note that checks of the Write IRP parameters also handles Read IRPs
  262. // because the Write and Read structures are identical in the
  263. // IO_STACK_LOCATION.Parameters union
  264. //
  265. //
  266. // bail out on nonzero offset
  267. //
  268. if( (IrpSp->Parameters.Write.ByteOffset.HighPart != 0) ||
  269. (IrpSp->Parameters.Write.ByteOffset.LowPart != 0) ) {
  270. Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  271. ParCompleteRequest(Irp, IO_NO_INCREMENT);
  272. return STATUS_INVALID_PARAMETER;
  273. }
  274. //
  275. // immediately succeed read or write request of length zero
  276. //
  277. if (IrpSp->Parameters.Write.Length == 0) {
  278. Irp->IoStatus.Status = STATUS_SUCCESS;
  279. ParCompleteRequest(Irp, IO_NO_INCREMENT);
  280. return STATUS_SUCCESS;
  281. }
  282. //
  283. // Request appears to be valid, queue it for our worker thread to handle at
  284. // PASSIVE_LEVEL IRQL and wake up the thread to do the work
  285. //
  286. {
  287. KIRQL OldIrql;
  288. // make sure IRP isn't cancelled out from under us
  289. IoAcquireCancelSpinLock(&OldIrql);
  290. if (Irp->Cancel) {
  291. // IRP has been cancelled, bail out
  292. IoReleaseCancelSpinLock(OldIrql);
  293. return STATUS_CANCELLED;
  294. } else {
  295. BOOLEAN needToSignalSemaphore = IsListEmpty( &Extension->WorkQueue );
  296. IoSetCancelRoutine(Irp, ParCancelRequest);
  297. IoMarkIrpPending(Irp);
  298. InsertTailList(&Extension->WorkQueue, &Irp->Tail.Overlay.ListEntry);
  299. IoReleaseCancelSpinLock(OldIrql);
  300. if( needToSignalSemaphore ) {
  301. KeReleaseSemaphore(&Extension->RequestSemaphore, 0, 1, FALSE);
  302. }
  303. return STATUS_PENDING;
  304. }
  305. }
  306. }
  307. NTSTATUS
  308. ParRead(
  309. IN PDEVICE_EXTENSION Extension,
  310. OUT PVOID Buffer,
  311. IN ULONG NumBytesToRead,
  312. OUT PULONG NumBytesRead
  313. )
  314. {
  315. NTSTATUS Status = STATUS_SUCCESS;
  316. PUCHAR lpsBufPtr = (PUCHAR)Buffer; // Pointer to buffer cast to desired data type
  317. ULONG Bytes = 0;
  318. #if (1 == DVRH_RAISE_IRQL)
  319. KIRQL OldIrql;
  320. #endif
  321. *NumBytesRead = Bytes;
  322. #if (1 == DVRH_RAISE_IRQL)
  323. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  324. #endif
  325. // only do this if we are in safe mode
  326. if ( Extension->ModeSafety == SAFE_MODE ) {
  327. if (arpReverse[Extension->IdxReverseProtocol].fnReadShadow) {
  328. Queue *pQueue;
  329. pQueue = &(Extension->ShadowBuffer);
  330. arpReverse[Extension->IdxReverseProtocol].fnReadShadow(pQueue,
  331. lpsBufPtr,
  332. NumBytesToRead,
  333. &Bytes);
  334. NumBytesToRead -= Bytes;
  335. *NumBytesRead += Bytes;
  336. lpsBufPtr += Bytes;
  337. if ( 0 == NumBytesToRead ) {
  338. ParDump2(PARINFO, ( "ParRead: Read everything from the ShadowBuffer\r\n" ));
  339. Status = STATUS_SUCCESS;
  340. if ((!Queue_IsEmpty(pQueue)) &&
  341. (TRUE == Extension->P12843DL.bEventActive) ) {
  342. KeSetEvent(Extension->P12843DL.Event, 0, FALSE);
  343. }
  344. goto ParRead_ExitLabel;
  345. }
  346. }
  347. if (arpReverse[Extension->IdxReverseProtocol].fnHaveReadData) {
  348. if (!arpReverse[Extension->IdxReverseProtocol].fnHaveReadData(Extension))
  349. {
  350. ParDump2(PARINFO, ( "ParRead: Periph doesn't have data. Happy punt to give cycles to someone else.\r\n" ));
  351. Status = STATUS_SUCCESS;
  352. goto ParRead_ExitLabel;
  353. }
  354. }
  355. }
  356. // Go ahead and flip the bus if need be. The proc will just make sure we're properly
  357. // connected and pointing in the right direction.
  358. Status = ParForwardToReverse( Extension );
  359. //
  360. // The read mode will vary depending upon the currently negotiated mode.
  361. // Default: Nibble
  362. //
  363. if (NT_SUCCESS(Status))
  364. {
  365. #if (1 == DVRH_USE_CORRECT_PTRS)
  366. if (Extension->fnRead || arpReverse[Extension->IdxReverseProtocol].fnRead) {
  367. //
  368. // Do the read...
  369. //
  370. if(Extension->fnRead) {
  371. Status = ((PPROTOCOL_READ_ROUTINE)Extension->fnRead)(Extension,
  372. (PVOID)lpsBufPtr,
  373. NumBytesToRead,
  374. &Bytes);
  375. } else {
  376. Status = arpReverse[Extension->IdxReverseProtocol].fnRead(Extension,
  377. (PVOID)lpsBufPtr,
  378. NumBytesToRead,
  379. &Bytes);
  380. }
  381. #else
  382. if (arpReverse[Extension->IdxReverseProtocol].fnRead) {
  383. //
  384. // Do the read...
  385. //
  386. Status = arpReverse[Extension->IdxReverseProtocol].fnRead(Extension,
  387. (PVOID)lpsBufPtr,
  388. NumBytesToRead,
  389. &Bytes);
  390. #endif
  391. *NumBytesRead += Bytes;
  392. NumBytesToRead -= Bytes;
  393. #if DVRH_SHOW_BYTE_LOG
  394. {
  395. ULONG i=0;
  396. DbgPrint("Parallel:Read: ");
  397. for (i=0; i<*NumBytesRead; ++i) {
  398. DbgPrint(" %02x",((PUCHAR)lpsBufPtr)[i]);
  399. }
  400. DbgPrint("\n");
  401. }
  402. #endif
  403. }
  404. #if DBG
  405. else {
  406. ParDump2(PARERRORS, ( "ParRead: Don't have a fnRead! Can't Read!\r\n" ));
  407. ParDump2(PARERRORS, ( "ParRead: You're hosed man.\r\n" ));
  408. ParDump2(PARERRORS, ( "ParRead: If you are here, you've got a bug somewhere else.\r\n" ));
  409. ParDump2(PARERRORS, ( "ParRead: Go fix it!\r\n" ));
  410. }
  411. #endif
  412. }
  413. #if DBG
  414. else {
  415. ParDump2(PARERRORS, ( "ParRead: Failure from Above! Didn't call Read!\r\n" ));
  416. ParDump2(PARERRORS, ( "ParRead: You're hosed man.\r\n" ));
  417. ParDump2(PARERRORS, ( "ParRead: If you are here, you've got a bug somewhere else.\r\n" ));
  418. ParDump2(PARERRORS, ( "ParRead: Go fix it!\r\n" ));
  419. }
  420. #endif
  421. ParRead_ExitLabel:
  422. #if (1 == DVRH_RAISE_IRQL)
  423. KeLowerIrql(OldIrql);
  424. #endif
  425. return Status;
  426. }
  427. VOID
  428. ParReadIrp(
  429. IN PDEVICE_EXTENSION Extension
  430. )
  431. /*++
  432. Routine Description:
  433. This routine implements a READ request with the extension's current irp.
  434. Arguments:
  435. Extension - Supplies the device extension.
  436. Return Value:
  437. None.
  438. --*/
  439. {
  440. PIRP Irp;
  441. PIO_STACK_LOCATION IrpSp;
  442. ULONG NumBytesRead;
  443. Irp = Extension->CurrentOpIrp;
  444. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  445. ParDump2(PARENTRY, ( "ParReadIrp: Start. BytesToRead[%d]\r\n", IrpSp->Parameters.Read.Length ));
  446. ParTimerCheck(( "ParReadIrp: Start. BytesToRead[%d]\r\n", IrpSp->Parameters.Read.Length ));
  447. Irp->IoStatus.Status = ParRead( Extension,
  448. Irp->AssociatedIrp.SystemBuffer,
  449. IrpSp->Parameters.Read.Length,
  450. &NumBytesRead);
  451. Irp->IoStatus.Information = NumBytesRead;
  452. ParTimerCheck(( "ParReadIrp: End. BytesRead[%d]\r\n", NumBytesRead ));
  453. }
  454. NTSTATUS
  455. ParReverseToForward(
  456. IN PDEVICE_EXTENSION Extension
  457. )
  458. /*++
  459. Routine Description:
  460. This routine flips the bus from Reverse to Forward direction.
  461. Arguments:
  462. Extension - Supplies the device extension.
  463. Return Value:
  464. None.
  465. --*/
  466. {
  467. NTSTATUS Status = STATUS_SUCCESS;
  468. // dvdr
  469. ParDump2(PARINFO, ("ParReverseToForward: Entering\n"));
  470. if (Extension->Connected)
  471. {
  472. // Do a quick check to see if we are where we want to be.
  473. // Happy punt if everything is ok.
  474. if (Extension->CurrentPhase == PHASE_FORWARD_IDLE ||
  475. Extension->CurrentPhase == PHASE_FORWARD_XFER)
  476. {
  477. ParDump2(PAREXIT, ( "ParReverseToForward: Already in Fwd. Exit STATUS_SUCCESS\n" ));
  478. return Status;
  479. }
  480. else
  481. {
  482. if (afpForward[Extension->IdxForwardProtocol].ProtocolFamily !=
  483. arpReverse[Extension->IdxReverseProtocol].ProtocolFamily)
  484. {
  485. //
  486. // Protocol Families don't match...need to terminate from the forward mode
  487. //
  488. if (arpReverse[Extension->IdxReverseProtocol].fnDisconnect) {
  489. ParDump2(PARINFO, ("ParReverseToForward: Calling arpReverse.fnDisconnect\r\n"));
  490. arpReverse[Extension->IdxReverseProtocol].fnDisconnect (Extension);
  491. }
  492. if ((Extension->ReverseInterfaceAddress != DEFAULT_ECP_CHANNEL) &&
  493. (arpReverse[Extension->IdxReverseProtocol].fnSetInterfaceAddress))
  494. Extension->SetReverseAddress = TRUE;
  495. }
  496. else if ((Extension->CurrentPhase == PHASE_REVERSE_IDLE) ||
  497. (Extension->CurrentPhase == PHASE_REVERSE_XFER))
  498. {
  499. if ( (arpReverse[Extension->IdxReverseProtocol].fnExitReverse) ) {
  500. Status = arpReverse[Extension->IdxReverseProtocol].fnExitReverse(Extension);
  501. }
  502. }
  503. else
  504. {
  505. // We are in a screwy state.
  506. ParDump2(PARERRORS, ( "ParReverseToForward: We're lost! Gonna start spewing!\r\n" ));
  507. ParDump2(PARERRORS, ( "ParReverseToForward: You're hosed man.\r\n" ));
  508. ParDump2(PARERRORS, ( "ParReverseToForward: If you are here, you've got a bug somewhere else.\r\n" ));
  509. ParDump2(PARERRORS, ( "ParReverseToForward: Go fix it!\r\n" ));
  510. Status = STATUS_IO_TIMEOUT; // I picked a RetVal from thin air!
  511. }
  512. }
  513. }
  514. // Yes, we stil want to check for connection since we might have temrinated in the previous
  515. // code block!
  516. if (!Extension->Connected &&
  517. afpForward[Extension->IdxForwardProtocol].fnConnect) {
  518. Status = afpForward[Extension->IdxForwardProtocol].fnConnect (
  519. Extension,
  520. FALSE);
  521. //
  522. // Makes the assumption that the connected address is always 0
  523. //
  524. if ((NT_SUCCESS(Status)) &&
  525. (Extension->ForwardInterfaceAddress != DEFAULT_ECP_CHANNEL)) {
  526. Extension->SetForwardAddress = TRUE;
  527. }
  528. }
  529. //
  530. // Do we need to enter a forward mode?
  531. //
  532. if ( (NT_SUCCESS(Status)) &&
  533. (Extension->CurrentPhase != PHASE_FORWARD_IDLE) &&
  534. (Extension->CurrentPhase != PHASE_FORWARD_XFER) &&
  535. (afpForward[Extension->IdxForwardProtocol].fnEnterForward) ) {
  536. Status = afpForward[Extension->IdxForwardProtocol].fnEnterForward(Extension);
  537. }
  538. ParDump2(PAREXIT, ( "ParReverseToForward: Exit [%d]\r\n", NT_SUCCESS(Status) ));
  539. return Status;
  540. }
  541. NTSTATUS
  542. ParSetFwdAddress(
  543. IN PDEVICE_EXTENSION Extension
  544. )
  545. {
  546. NTSTATUS Status = STATUS_SUCCESS;
  547. ParDump2( PARENTRY, ("ParSetFwdAddress: Start: Channel [%x]\n", Extension->ForwardInterfaceAddress));
  548. if (afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress)
  549. {
  550. Status = ParReverseToForward(Extension);
  551. if (!NT_SUCCESS(Status))
  552. {
  553. ParDump2(PARERRORS, ("ParSetFwdAddress: FAIL. Couldn't flip the bus for Set ECP/EPP Channel failed.\n") );
  554. goto ParSetFwdAddress_ExitLabel;
  555. }
  556. Status = afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress (
  557. Extension,
  558. Extension->ForwardInterfaceAddress);
  559. if (NT_SUCCESS(Status))
  560. Extension->SetForwardAddress = FALSE;
  561. else
  562. {
  563. ParDump2(PARERRORS, ("ParSetFwdAddress: FAIL. Set ECP/EPP Channel failed.\n") );
  564. goto ParSetFwdAddress_ExitLabel;
  565. }
  566. }
  567. else
  568. {
  569. ParDump2(PARERRORS, ("ParSetFwdAddress: FAIL. Protocol doesn't support SetECP/EPP Channel\n") );
  570. Status = STATUS_UNSUCCESSFUL;
  571. goto ParSetFwdAddress_ExitLabel;
  572. }
  573. ParSetFwdAddress_ExitLabel:
  574. return Status;
  575. }
  576. VOID
  577. ParTerminate(
  578. IN PDEVICE_EXTENSION Extension
  579. )
  580. {
  581. if (!Extension->Connected)
  582. return;
  583. if (Extension->CurrentPhase == PHASE_REVERSE_IDLE ||
  584. Extension->CurrentPhase == PHASE_REVERSE_XFER)
  585. {
  586. if (afpForward[Extension->IdxForwardProtocol].ProtocolFamily !=
  587. arpReverse[Extension->IdxReverseProtocol].ProtocolFamily)
  588. {
  589. if (arpReverse[Extension->IdxReverseProtocol].fnDisconnect)
  590. {
  591. ParDump2(PARINFO, ("ParTerminate: Calling arpReverse.fnDisconnect\r\n"));
  592. arpReverse[Extension->IdxReverseProtocol].fnDisconnect (Extension);
  593. }
  594. return;
  595. }
  596. ParReverseToForward(Extension);
  597. }
  598. if (afpForward[Extension->IdxForwardProtocol].fnDisconnect)
  599. {
  600. ParDump2(PARINFO, ("ParTerminate: Calling afpForward.fnDisconnect\r\n"));
  601. afpForward[Extension->IdxForwardProtocol].fnDisconnect (Extension);
  602. }
  603. }
  604. NTSTATUS
  605. ParWrite(
  606. IN PDEVICE_EXTENSION Extension,
  607. OUT PVOID Buffer,
  608. IN ULONG NumBytesToWrite,
  609. OUT PULONG NumBytesWritten
  610. )
  611. {
  612. NTSTATUS Status = STATUS_SUCCESS;
  613. #if (1 == DVRH_RAISE_IRQL)
  614. KIRQL OldIrql;
  615. #endif
  616. #if (1 == DVRH_RAISE_IRQL)
  617. KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
  618. #endif
  619. // dvdr
  620. ParDump2(PARINFO, ("ParWrite: Entering\n"));
  621. //
  622. // The routine which performs the write varies depending upon the currently
  623. // negotiated mode. Start I/O moves the IRP into the Extension (CurrentOpIrp)
  624. //
  625. // Default mode: Centronics
  626. //
  627. // dvdr
  628. ParDump2(PARINFO, ("ParWrite: Calling ParReverseToForward\n"));
  629. // Go ahead and flip the bus if need be. The proc will just make sure we're properly
  630. // connected and pointing in the right direction.
  631. Status = ParReverseToForward( Extension );
  632. // only do this if we are in safe mode
  633. if ( Extension->ModeSafety == SAFE_MODE ) {
  634. //
  635. // Set the channel address if we need to.
  636. //
  637. if (NT_SUCCESS(Status) && Extension->SetForwardAddress &&
  638. (afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress))
  639. {
  640. // dvdr
  641. ParDump2(PARINFO, ("ParWrite: Calling Protocol %x\n", Extension->IdxForwardProtocol));
  642. Status = afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress (
  643. Extension,
  644. Extension->ForwardInterfaceAddress);
  645. if (NT_SUCCESS(Status))
  646. Extension->SetForwardAddress = FALSE;
  647. else
  648. Extension->SetForwardAddress = TRUE;
  649. }
  650. }
  651. if (NT_SUCCESS(Status)) {
  652. #if (1 == DVRH_USE_CORRECT_PTRS)
  653. if (Extension->fnWrite || afpForward[Extension->IdxForwardProtocol].fnWrite) {
  654. #else
  655. if (afpForward[Extension->IdxForwardProtocol].fnWrite) {
  656. #endif
  657. *NumBytesWritten = 0;
  658. #if DVRH_SHOW_BYTE_LOG
  659. {
  660. ULONG i=0;
  661. DbgPrint("Parallel:Write: ");
  662. for (i=0; i<NumBytesToWrite; ++i) { DbgPrint(" %02x",*((PUCHAR)Buffer+i)); }
  663. DbgPrint("\n");
  664. }
  665. #endif
  666. #if (1 == DVRH_USE_CORRECT_PTRS)
  667. if( Extension->fnWrite) {
  668. Status = ((PPROTOCOL_WRITE_ROUTINE)Extension->fnWrite)(Extension,
  669. Buffer,
  670. NumBytesToWrite,
  671. NumBytesWritten);
  672. } else {
  673. Status = afpForward[Extension->IdxForwardProtocol].fnWrite(Extension,
  674. Buffer,
  675. NumBytesToWrite,
  676. NumBytesWritten);
  677. }
  678. #else
  679. Status = afpForward[Extension->IdxForwardProtocol].fnWrite(Extension,
  680. Buffer,
  681. NumBytesToWrite,
  682. NumBytesWritten);
  683. #endif
  684. }
  685. #if DBG
  686. else {
  687. ParDump2(PARERRORS, ( "ParReadIrp: Don't have a fnWrite!\r\n" ));
  688. ParDump2(PARERRORS, ( "ParReadIrp: You're hosed man.\r\n" ));
  689. ParDump2(PARERRORS, ( "ParReadIrp: If you are here, you've got a bug somewhere else.\r\n" ));
  690. ParDump2(PARERRORS, ( "ParReadIrp: Go fix it!\r\n" ));
  691. }
  692. #endif
  693. }
  694. #if DBG
  695. else {
  696. ParDump2(PARERRORS, ( "ParReadIrp: Failure from above! Didn't call Write!\r\n" ));
  697. ParDump2(PARERRORS, ( "ParReadIrp: You're hosed man.\r\n" ));
  698. ParDump2(PARERRORS, ( "ParReadIrp: If you are here, you've got a bug somewhere else.\r\n" ));
  699. ParDump2(PARERRORS, ( "ParReadIrp: Go fix it!\r\n" ));
  700. }
  701. #endif
  702. #if (1 == DVRH_RAISE_IRQL)
  703. KeLowerIrql(OldIrql);
  704. #endif
  705. // dvdr
  706. ParDump2(PARINFO, ("ParWrite: Leaving\n"));
  707. return Status;
  708. }
  709. VOID
  710. ParWriteIrp(
  711. IN PDEVICE_EXTENSION Extension
  712. )
  713. /*++
  714. Routine Description:
  715. This routine implements a WRITE request with the extension's current irp.
  716. Arguments:
  717. Extension - Supplies the device extension.
  718. Return Value:
  719. None.
  720. --*/
  721. {
  722. PIRP Irp;
  723. PIO_STACK_LOCATION IrpSp;
  724. ULONG NumBytesWritten = 0;
  725. Irp = Extension->CurrentOpIrp;
  726. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  727. ParTimerCheck(( "ParWriteIrp: Start. BytesToWrite[%d]\r\n", IrpSp->Parameters.Write.Length ));
  728. Irp->IoStatus.Status = ParWrite(Extension,
  729. Irp->AssociatedIrp.SystemBuffer,
  730. IrpSp->Parameters.Write.Length,
  731. &NumBytesWritten);
  732. Irp->IoStatus.Information = NumBytesWritten;
  733. ParTimerCheck(( "ParWriteIrp: End. BytesWritten[%d]\r\n", NumBytesWritten ));
  734. }