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.

687 lines
29 KiB

  1. #include "pch.h"
  2. NTSTATUS
  3. P4NibbleModeRead(
  4. IN PUCHAR Controller,
  5. IN PVOID Buffer,
  6. IN ULONG BufferSize,
  7. OUT PULONG BytesTransferred,
  8. IN OUT PIEEE_STATE IeeeState
  9. )
  10. /*++
  11. Routine Description:
  12. This routine performs a 1284 nibble mode read into the given
  13. buffer for no more than 'BufferSize' bytes.
  14. Arguments:
  15. Extension - Supplies the device extension.
  16. Buffer - Supplies the buffer to read into.
  17. BufferSize - Supplies the number of bytes in the buffer.
  18. BytesTransferred - Returns the number of bytes transferred.
  19. --*/
  20. {
  21. PUCHAR wPortDCR;
  22. PUCHAR wPortDSR;
  23. NTSTATUS Status = STATUS_SUCCESS;
  24. PUCHAR p = (PUCHAR)Buffer;
  25. UCHAR dsr, dcr;
  26. UCHAR nibble[2];
  27. ULONG i, j;
  28. wPortDCR = Controller + OFFSET_DCR;
  29. wPortDSR = Controller + OFFSET_DSR;
  30. // Read nibbles according to 1284 spec.
  31. dcr = P5ReadPortUchar(wPortDCR);
  32. switch (IeeeState->CurrentPhase) {
  33. case PHASE_NEGOTIATION:
  34. // Starting in state 6 - where do we go from here?
  35. // To Reverse Idle or Reverse Data Transfer Phase depending if
  36. // data is available.
  37. dsr = P5ReadPortUchar(wPortDSR);
  38. // =============== Periph State 6 ===============8
  39. // PeriphAck/PtrBusy = Don't Care
  40. // PeriphClk/PtrClk = Don't Care (should be high
  41. // and the nego. proc already
  42. // checked this)
  43. // nAckReverse/AckDataReq = Don't Care (should be high)
  44. // XFlag = Don't Care (should be low)
  45. // nPeriphReq/nDataAvail = High/Low (line status determines
  46. // which state we move to)
  47. IeeeState->CurrentEvent = 6;
  48. if (TEST_DSR(dsr, DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE, ACTIVE )) {
  49. // Data is NOT available - go to Reverse Idle
  50. DD(NULL,DDT,"P4NibbleModeRead - DataNotAvail - set PHASE_REVERSE_IDLE\n");
  51. // Host enters state 7 - officially in Reverse Idle now
  52. // Must stall for at least .5 microseconds before this state.
  53. KeStallExecutionProcessor(1);
  54. /* =============== Host State 7 Nibble Reverse Idle ===============8
  55. DIR = Don't Care
  56. IRQEN = Don't Care
  57. 1284/SelectIn = High
  58. nReverseReq/ (ECP only)= Don't Care
  59. HostAck/HostBusy = Low (signals State 7)
  60. HostClk/nStrobe = High
  61. ============================================================ */
  62. IeeeState->CurrentEvent = 7;
  63. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, ACTIVE, DONT_CARE, INACTIVE, ACTIVE);
  64. P5WritePortUchar(wPortDCR, dcr);
  65. P5BSetPhase( IeeeState, PHASE_REVERSE_IDLE );
  66. // FALL THRU TO reverse idle
  67. } else {
  68. // Data is available, go to Reverse Transfer Phase
  69. P5BSetPhase( IeeeState, PHASE_REVERSE_XFER );
  70. // DO NOT fall thru
  71. goto PhaseReverseXfer; // please save me from my sins!
  72. }
  73. case PHASE_REVERSE_IDLE:
  74. // Check to see if the peripheral has indicated Interrupt Phase and if so,
  75. // get us ready to reverse transfer.
  76. // See if data is available (looking for state 19)
  77. dsr = P5ReadPortUchar(Controller + OFFSET_DSR);
  78. if (!(dsr & DSR_NOT_DATA_AVAIL)) {
  79. dcr = P5ReadPortUchar(wPortDCR);
  80. // =========== Host State 20 Interrupt Phase ===========8
  81. // DIR = Don't Care
  82. // IRQEN = Don't Care
  83. // 1284/SelectIn = High
  84. // nReverseReq/ (ECP only) = Don't Care
  85. // HostAck/HostBusy = High (Signals state 20)
  86. // HostClk/nStrobe = High
  87. //
  88. // Data is available, get us to Reverse Transfer Phase
  89. IeeeState->CurrentEvent = 20;
  90. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, ACTIVE, DONT_CARE, ACTIVE, ACTIVE);
  91. P5WritePortUchar(wPortDCR, dcr);
  92. // =============== Periph State 21 HBDA ===============8
  93. // PeriphAck/PtrBusy = Don't Care
  94. // PeriphClk/PtrClk = Don't Care (should be high)
  95. // nAckReverse/AckDataReq = low (signals state 21)
  96. // XFlag = Don't Care (should be low)
  97. // nPeriphReq/nDataAvail = Don't Care (should be low)
  98. IeeeState->CurrentEvent = 21;
  99. if (CHECK_DSR(Controller,
  100. DONT_CARE, DONT_CARE, INACTIVE,
  101. DONT_CARE, DONT_CARE,
  102. IEEE_MAXTIME_TL)) {
  103. // Got state 21
  104. // Let's jump to Reverse Xfer and get the data
  105. P5BSetPhase( IeeeState, PHASE_REVERSE_XFER);
  106. goto PhaseReverseXfer;
  107. } else {
  108. // Timeout on state 21
  109. IeeeState->IsIeeeTerminateOk = TRUE;
  110. Status = STATUS_IO_DEVICE_ERROR;
  111. P5BSetPhase( IeeeState, PHASE_UNKNOWN );
  112. DD(NULL,DDT,"P4NibbleModeRead - Failed State 21: Controller %x dcr %x\n", Controller, dcr);
  113. // NOTE: Don't ASSERT Here. An Assert here can bite you if you are in
  114. // Nibble Rev and you device is off/offline.
  115. // dvrh 2/25/97
  116. goto NibbleReadExit;
  117. }
  118. } else {
  119. // Data is NOT available - do nothing
  120. // The device doesn't report any data, it still looks like it is
  121. // in ReverseIdle. Just to make sure it hasn't powered off or somehow
  122. // jumped out of Nibble mode, test also for AckDataReq high and XFlag low
  123. // and nDataAvaul high.
  124. IeeeState->CurrentEvent = 18;
  125. dsr = P5ReadPortUchar(Controller + OFFSET_DSR);
  126. if(( dsr & DSR_NIBBLE_VALIDATION )== DSR_NIBBLE_TEST_RESULT ) {
  127. P5BSetPhase( IeeeState, PHASE_REVERSE_IDLE );
  128. } else {
  129. #if DVRH_BUS_RESET_ON_ERROR
  130. BusReset(wPortDCR); // Pass in the dcr address
  131. #endif
  132. // Appears we failed state 19.
  133. IeeeState->IsIeeeTerminateOk = TRUE;
  134. Status = STATUS_IO_DEVICE_ERROR;
  135. P5BSetPhase( IeeeState, PHASE_UNKNOWN );
  136. DD(NULL,DDT,"P4NibbleModeRead - Failed State 19: Controller %x dcr %x\n", Controller, dcr);
  137. }
  138. goto NibbleReadExit;
  139. }
  140. PhaseReverseXfer:
  141. case PHASE_REVERSE_XFER:
  142. DD(NULL,DDT,"P4NibbleModeRead - case PHASE_REVERSE_XFER\n");
  143. for (i = 0; i < BufferSize; i++) {
  144. for (j = 0; j < 2; j++) {
  145. // Host enters state 7 or 12 depending if nibble 1 or 2
  146. dcr |= DCR_NOT_HOST_BUSY;
  147. P5WritePortUchar(wPortDCR, dcr);
  148. // =============== Periph State 9 ===============8
  149. // PeriphAck/PtrBusy = Don't Care (Bit 3 of Nibble)
  150. // PeriphClk/PtrClk = low (signals state 9)
  151. // nAckReverse/AckDataReq = Don't Care (Bit 2 of Nibble)
  152. // XFlag = Don't Care (Bit 1 of Nibble)
  153. // nPeriphReq/nDataAvail = Don't Care (Bit 0 of Nibble)
  154. IeeeState->CurrentEvent = 9;
  155. if (!CHECK_DSR(Controller,
  156. DONT_CARE, INACTIVE, DONT_CARE,
  157. DONT_CARE, DONT_CARE,
  158. IEEE_MAXTIME_TL)) {
  159. // Time out.
  160. // Bad things happened - timed out on this state,
  161. // Mark Status as bad and let our mgr kill current mode.
  162. IeeeState->IsIeeeTerminateOk = FALSE;
  163. Status = STATUS_IO_DEVICE_ERROR;
  164. DD(NULL,DDT,"P4NibbleModeRead - Failed State 9: Controller %x dcr %x\n", Controller, dcr);
  165. P5BSetPhase( IeeeState,PHASE_UNKNOWN );
  166. goto NibbleReadExit;
  167. }
  168. // Read Nibble
  169. nibble[j] = P5ReadPortUchar(wPortDSR);
  170. /* ============== Host State 10 Nibble Read ===============8
  171. DIR = Don't Care
  172. IRQEN = Don't Care
  173. 1284/SelectIn = High
  174. HostAck/HostBusy = High (signals State 10)
  175. HostClk/nStrobe = High
  176. ============================================================ */
  177. IeeeState->CurrentEvent = 10;
  178. dcr &= ~DCR_NOT_HOST_BUSY;
  179. P5WritePortUchar(wPortDCR, dcr);
  180. // =============== Periph State 11 ===============8
  181. // PeriphAck/PtrBusy = Don't Care (Bit 3 of Nibble)
  182. // PeriphClk/PtrClk = High (signals state 11)
  183. // nAckReverse/AckDataReq = Don't Care (Bit 2 of Nibble)
  184. // XFlag = Don't Care (Bit 1 of Nibble)
  185. // nPeriphReq/nDataAvail = Don't Care (Bit 0 of Nibble)
  186. IeeeState->CurrentEvent = 11;
  187. if (!CHECK_DSR(Controller,
  188. DONT_CARE, ACTIVE, DONT_CARE,
  189. DONT_CARE, DONT_CARE,
  190. IEEE_MAXTIME_TL)) {
  191. // Time out.
  192. // Bad things happened - timed out on this state,
  193. // Mark Status as bad and let our mgr kill current mode.
  194. Status = STATUS_IO_DEVICE_ERROR;
  195. IeeeState->IsIeeeTerminateOk = FALSE;
  196. DD(NULL,DDT,"P4NibbleModeRead - Failed State 11: Controller %x dcr %x\n", Controller, dcr);
  197. P5BSetPhase( IeeeState,PHASE_UNKNOWN );
  198. goto NibbleReadExit;
  199. }
  200. }
  201. // Read two nibbles - make them into one byte.
  202. p[i] = (((nibble[0]&0x38)>>3)&0x07) | ((nibble[0]&0x80) ? 0x00 : 0x08);
  203. p[i] |= (((nibble[1]&0x38)<<1)&0x70) | ((nibble[1]&0x80) ? 0x00 : 0x80);
  204. // DD(NULL,DDT,"P4NibbleModeRead:%x:%c\n", p[i], p[i]);
  205. // At this point, we've either received the number of bytes we
  206. // were looking for, or the peripheral has no more data to
  207. // send, or there was an error of some sort (of course, in the
  208. // error case we shouldn't get to this comment). Set the
  209. // phase to indicate reverse idle if no data available or
  210. // reverse data transfer if there's some waiting for us
  211. // to get next time.
  212. dsr = P5ReadPortUchar(wPortDSR);
  213. if (dsr & DSR_NOT_DATA_AVAIL) {
  214. // Data is NOT available - go to Reverse Idle
  215. // Really we are going to HBDNA, but if we set
  216. // current phase to reverse idle, the next time
  217. // we get into this function all we have to do
  218. // is set hostbusy low to indicate idle and
  219. // we have infinite time to do that.
  220. // Break out of the loop so we don't try to read
  221. // data that isn't there.
  222. // NOTE - this is a successful case even if we
  223. // didn't read all that the caller requested
  224. P5BSetPhase( IeeeState, PHASE_REVERSE_IDLE );
  225. i++; // account for this last byte transferred
  226. break;
  227. } else {
  228. // Data is available, go to (remain in ) Reverse Transfer Phase
  229. P5BSetPhase( IeeeState, PHASE_REVERSE_XFER );
  230. }
  231. } // end for i loop
  232. *BytesTransferred = i;
  233. // DON'T FALL THRU THIS ONE
  234. break;
  235. default:
  236. // I'm gonna mark this as false. There is not a correct answer here.
  237. // The peripheral and the host are out of sync. I'm gonna reset myself
  238. // and the peripheral.
  239. IeeeState->IsIeeeTerminateOk = FALSE;
  240. Status = STATUS_IO_DEVICE_ERROR;
  241. P5BSetPhase( IeeeState, PHASE_UNKNOWN );
  242. DD(NULL,DDT,"P4NibbleModeRead:Failed State 9: Unknown Phase. Controller %x dcr %x\n",
  243. Controller, dcr);
  244. DD(NULL,DDT,"P4NibbleModeRead: You're hosed man.\n" );
  245. DD(NULL,DDT,"P4NibbleModeRead: If you are here, you've got a bug somewhere else.\n" );
  246. DD(NULL,DDT,"P4NibbleModeRead: Go fix it!\n" );
  247. goto NibbleReadExit;
  248. break;
  249. } // end switch
  250. NibbleReadExit:
  251. if( IeeeState->CurrentPhase == PHASE_REVERSE_IDLE ) {
  252. // Host enters state 7 - officially in Reverse Idle now
  253. dcr |= DCR_NOT_HOST_BUSY;
  254. P5WritePortUchar (wPortDCR, dcr);
  255. }
  256. DD(NULL,DDT,"P4NibbleModeRead - returning status = %x\n",Status);
  257. if(NT_SUCCESS(Status)) {
  258. DD(NULL,DDT,"P4NibbleModeRead - bytes read = %d\n",*BytesTransferred);
  259. }
  260. return Status;
  261. }
  262. VOID
  263. P4IeeeTerminate1284Mode(
  264. IN PUCHAR Controller,
  265. IN OUT PIEEE_STATE IeeeState,
  266. IN enum XFlagOnEvent24 XFlagOnEvent24
  267. )
  268. /*++
  269. Routine Description:
  270. This routine terminates the interface back to compatibility mode.
  271. Arguments:
  272. Controller - Supplies the parallel port's controller address.
  273. Return Value:
  274. None.
  275. --*/
  276. {
  277. PUCHAR wPortDCR;
  278. UCHAR dcr, dsrMask, dsrValue;
  279. BOOLEAN bXFlag;
  280. BOOLEAN bUseXFlag = FALSE;
  281. DD(NULL,DDT,"P4IeeeTerminate1284Mode - enter - Controller=%x, IeeeState=%x\n",Controller,IeeeState);
  282. wPortDCR = Controller + OFFSET_DCR;
  283. dcr = P5ReadPortUchar(wPortDCR);
  284. if( PHASE_TERMINATE == IeeeState->CurrentPhase ) {
  285. // We are already terminated. This will fail if we don't just bypass this mess.
  286. goto Terminate_ExitLabel;
  287. }
  288. // Keep Negotiated XFLAG to use for termination.
  289. // xFlag, // Technically we should have
  290. // cached this value from state
  291. // 6 of nego. This peripheral's XFlag
  292. // at pre state 22 should be the
  293. // same as state 6.
  294. bXFlag = P5ReadPortUchar(Controller + OFFSET_DSR) & 0x10;
  295. // REVISIT: Do we need to ensure the preceeding state is a valid
  296. // state to terminate from. In other words, is there there
  297. // a black bar on the 1284 line for that state?
  298. // =============== Host State 22 Termination ===============8
  299. // DIR = Don't Care (Possibly Low)
  300. // IRQEN = Don't Care (Possibly Low)
  301. // 1284/SelectIn = Low (Signals state 22)
  302. // nReverseReq/**(ECP only) = Don't Care (High for ECP, otherwise unused)
  303. // HostAck/HostBusy/nAutoFeed = High
  304. // HostClk/nStrobe = High
  305. //
  306. IeeeState->CurrentEvent = 22;
  307. dcr = P5ReadPortUchar(wPortDCR);
  308. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, INACTIVE, DONT_CARE, ACTIVE, ACTIVE);
  309. P5WritePortUchar(wPortDCR, dcr);
  310. // Clear data lines so we don't have any random spew.
  311. P5WritePortUchar(Controller + OFFSET_DATA, 0);
  312. // *************** Periph State 23/24 Termination ***************8
  313. // PeriphAck/PtrBusy = High (Signals state 23 for ECP
  314. // otherwise already high)
  315. // PeriphClk/PtrClk = Low (Signals state 24 for ecp
  316. // Signals state 23 for Nibble)
  317. // nAckRev/AckDataReq/PE = Don't Care
  318. // XFlag = Low (ECP and Byte) (State 24)
  319. // = High (Nibble) (State 24)
  320. // = Low (All DeviceID Requests including Nibble) (State 24)
  321. // = Undefined (EPP)
  322. // nPeriphReq/nDataAvail = High
  323. // Don't check nPeriphReq/nDataAvail
  324. // Since it was in a "Don't Care"
  325. // state (ie. Double bar in the spec)
  326. // until state 23 for ECP mode.
  327. if (IeeeState->CurrentPhase == PHASE_REVERSE_IDLE ||
  328. IeeeState->CurrentPhase == PHASE_REVERSE_XFER) {
  329. // We must be in Nibble Reverse. Let's double check!!!
  330. if( FAMILY_REVERSE_NIBBLE == IeeeState->ProtocolFamily ||
  331. FAMILY_REVERSE_BYTE == IeeeState->ProtocolFamily ) {
  332. bUseXFlag = TRUE; // We're in Nibble or Byte
  333. if( XFlagOnEvent24 == IgnoreXFlagOnEvent24 ) {
  334. // normally we would honor XFlag but we need to work around Brother MFC-8700 firmware
  335. bUseXFlag = FALSE;
  336. }
  337. } else
  338. bUseXFlag = FALSE; // Don't know what mode we are in?
  339. } else {
  340. if( FAMILY_BECP == IeeeState->ProtocolFamily ||
  341. FAMILY_ECP == IeeeState->ProtocolFamily )
  342. bUseXFlag = TRUE; // We're in an ECP Flavor
  343. else
  344. bUseXFlag = FALSE; // Don't know what mode we are in?
  345. }
  346. if( bUseXFlag ) {
  347. dsrMask = DSR_TEST_MASK( DONT_CARE, INACTIVE, DONT_CARE, bXFlag ? INACTIVE : ACTIVE, DONT_CARE );
  348. dsrValue = DSR_TEST_VALUE( DONT_CARE, INACTIVE, DONT_CARE, bXFlag ? INACTIVE : ACTIVE, DONT_CARE );
  349. }
  350. else {
  351. dsrMask = DSR_TEST_MASK( DONT_CARE, INACTIVE, DONT_CARE, DONT_CARE, DONT_CARE );
  352. dsrValue = DSR_TEST_VALUE( DONT_CARE, INACTIVE, DONT_CARE, DONT_CARE, DONT_CARE );
  353. }
  354. IeeeState->CurrentEvent = 23;
  355. if( !CheckPort( Controller + OFFSET_DSR, dsrMask, dsrValue, IEEE_MAXTIME_TL ) ) {
  356. // We couldn't negotiate back to compatibility mode - just terminate.
  357. DD(NULL,DDT,"IeeeTerminate1284Mode:State 23/24 Failed: Controller %x dsr %x dcr %x\n",
  358. Controller, P5ReadPortUchar(Controller + OFFSET_DSR), dcr);
  359. goto Terminate_ExitLabel;
  360. }
  361. // =============== Host State 25 Termination ===============8
  362. // DIR = Don't Care (Possibly Low)
  363. // IRQEN = Don't Care (Possibly Low)
  364. // 1284/SelectIn = Low
  365. // nReverseReq/**(ECP only) = Don't Care (Possibly High)
  366. // HostAck/HostBusy/nAutoFeed = Low (Signals State 25)
  367. // HostClk/nStrobe = High
  368. //
  369. IeeeState->CurrentEvent = 25;
  370. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, INACTIVE, DONT_CARE, INACTIVE, ACTIVE);
  371. P5WritePortUchar(wPortDCR, dcr);
  372. // =============== State 26 Termination ===============8
  373. // Do nothing for state 26
  374. // =============== Periph State 27 Termination ===============8
  375. // PeriphAck/PtrBusy = High
  376. // PeriphClk/PtrClk = High (Signals State 27)
  377. // nAckRev/AckDataReq/PE = Don't Care (Invalid from State 23)
  378. // XFlag = Don't Care (All Modes) (Invlaid at State 27)
  379. // nPeriphReq/nDataAvial = Don't Care (Invalid from State 26)
  380. // dvrh 6/16/97
  381. IeeeState->CurrentEvent = 27;
  382. if( !CHECK_DSR(Controller, ACTIVE, ACTIVE, DONT_CARE, DONT_CARE, DONT_CARE, IEEE_MAXTIME_TL) ) {
  383. DD(NULL,DDE,"P4IeeeTerminate1284Mode - State 27 Failed - Controller %x dsr %x dcr %x\n",
  384. Controller, P5ReadPortUchar(Controller + OFFSET_DSR), dcr);
  385. }
  386. Terminate_ExitLabel:
  387. // =============== Host State 28 Termination ===============8
  388. // DIR = Don't Care (Possibly Low)
  389. // IRQEN = Don't Care (Possibly Low)
  390. // 1284/SelectIn = Low
  391. // nReverseReq/**(ECP only) = Don't Care (Possibly High)
  392. // HostAck/HostBusy/nAutoFeed = High (Signals State 28)
  393. // HostClk/nStrobe = High
  394. //
  395. IeeeState->CurrentEvent = 28;
  396. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, INACTIVE, DONT_CARE, ACTIVE, ACTIVE);
  397. P5WritePortUchar(wPortDCR, dcr);
  398. // We are now back in compatibility mode.
  399. IeeeState->CurrentPhase = PHASE_TERMINATE;
  400. IeeeState->Connected = FALSE;
  401. IeeeState->IsIeeeTerminateOk = FALSE;
  402. return;
  403. }
  404. NTSTATUS
  405. P4IeeeEnter1284Mode(
  406. IN PUCHAR Controller,
  407. IN UCHAR Extensibility,
  408. IN OUT PIEEE_STATE IeeeState
  409. )
  410. /*++
  411. Routine Description:
  412. This routine performs 1284 negotiation with the peripheral to the
  413. nibble mode protocol.
  414. Arguments:
  415. Controller - supplies the port base address
  416. Extensibility - supplies the IEEE 1284 mode desired
  417. IeeeState - tracks the state of the negotiation with the peripheral
  418. Return Value:
  419. STATUS_SUCCESS - Successful negotiation.
  420. otherwise - Unsuccessful negotiation.
  421. --*/
  422. {
  423. PUCHAR wPortDCR;
  424. UCHAR dcr;
  425. const USHORT sPeriphResponseTime = 35;
  426. wPortDCR = Controller + OFFSET_DCR;
  427. /* =============== Host Prep for Pre State 0 ===============8
  428. Set the following just in case someone didn't
  429. put the port in compatibility mode before we got it.
  430. DIR = Don't Care
  431. IRQEN = Don't Care
  432. 1284/SelectIn = Low
  433. nReverseReq/ (ECP only)= High for ECP / Don't Care for Nibble
  434. I will do ahead and set it to high
  435. since Nibble doesn't care.
  436. HostAck/HostBusy = High
  437. HostClk/nStrobe = Don't Care
  438. ============================================================ */
  439. dcr = P5ReadPortUchar(wPortDCR); // Get content of DCR.
  440. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, INACTIVE, ACTIVE, ACTIVE, DONT_CARE);
  441. P5WritePortUchar(wPortDCR, dcr);
  442. KeStallExecutionProcessor(2);
  443. /* =============== Host Pre State 0 Negotiation ===============8
  444. DIR = Low ( Don't Care by spec )
  445. IRQEN = Low ( Don't Care by spec )
  446. 1284/SelectIn = Low
  447. nReverseReq/ (ECP only)= High ( Don't Care by spec )
  448. HostAck/HostBusy = High
  449. HostClk/nStrobe = High
  450. ============================================================ */
  451. dcr = UPDATE_DCR(dcr, INACTIVE, INACTIVE, INACTIVE, ACTIVE, ACTIVE, ACTIVE);
  452. P5WritePortUchar(wPortDCR, dcr);
  453. KeStallExecutionProcessor(2);
  454. /* =============== Host State 0 Negotiation ===============8
  455. Place the extensibility request value on the data bus - state 0.
  456. ============================================================ */
  457. IeeeState->CurrentEvent = 0;
  458. P5WritePortUchar(Controller + DATA_OFFSET, Extensibility);
  459. KeStallExecutionProcessor(2);
  460. /* =========== Host State 1 Negotiation Phase ===========8
  461. DIR = Don't Care
  462. IRQEN = Don't Care
  463. 1284/SelectIn = High (Signals State 1)
  464. nReverseReq/ (ECP only)= Don't Care
  465. HostAck/HostBusy = Low (Signals state 1)
  466. HostClk/nStrobe = High
  467. ============================================================ */
  468. IeeeState->CurrentEvent = 1;
  469. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, ACTIVE, DONT_CARE, INACTIVE, ACTIVE);
  470. P5WritePortUchar(wPortDCR, dcr);
  471. /* =============== Periph State 2 Negotiation ===============8
  472. PeriphAck/PtrBusy = Don't Care
  473. PeriphClk/PtrClk = low Signals State 2
  474. nAckReverse/AckDataReq = high Signals State 2
  475. XFlag = high Signals State 2
  476. **Note: It is high at state 2
  477. for both ecp and nibble
  478. nPeriphReq/nDataAvail = high Signals State 2
  479. ============================================================ */
  480. IeeeState->CurrentEvent = 2;
  481. if (!CHECK_DSR(Controller, DONT_CARE, INACTIVE, ACTIVE, ACTIVE, ACTIVE,
  482. sPeriphResponseTime)) {
  483. KeStallExecutionProcessor(2);
  484. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, INACTIVE, DONT_CARE, ACTIVE, DONT_CARE);
  485. P5WritePortUchar(wPortDCR, dcr);
  486. DD(NULL,DDT,"IeeeEnter1284Mode: %x - Extensibility=%x, FAIL - TIMEOUT on Event 2\n", Controller, Extensibility);
  487. P5BSetPhase( IeeeState, PHASE_UNKNOWN );
  488. IeeeState->Connected = FALSE;
  489. IeeeState->IsIeeeTerminateOk = FALSE;
  490. return STATUS_INVALID_DEVICE_REQUEST;
  491. }
  492. /* =============== Host State 3 Negotiation ===============8
  493. DIR = Don't Care
  494. IRQEN = Don't Care
  495. 1284/SelectIn = High
  496. nReverseReq/ (ECP only)= Don't Care
  497. HostAck/HostBusy = Low
  498. HostClk/nStrobe = Low (signals State 3)
  499. NOTE: Strobe the Extensibility byte
  500. ============================================================ */
  501. IeeeState->CurrentEvent = 3;
  502. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, ACTIVE, DONT_CARE, INACTIVE, INACTIVE);
  503. P5WritePortUchar(wPortDCR, dcr);
  504. // HostClk must be help low for at least .5 microseconds.
  505. //
  506. KeStallExecutionProcessor(2);
  507. /* =============== Host State 4 Negotiation ===============8
  508. DIR = Don't Care
  509. IRQEN = Don't Care
  510. 1284/SelectIn = High
  511. nReverseReq/ (ECP only)= Don't Care
  512. HostAck/HostBusy = High (signals State 4)
  513. HostClk/nStrobe = High (signals State 4)
  514. NOTE: nReverseReq should be high in ECP, but this line is only
  515. valid for ECP. Since it isn't used for signaling
  516. anything in negotiation, let's just ignore it for now.
  517. ============================================================ */
  518. IeeeState->CurrentEvent = 4;
  519. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, ACTIVE, DONT_CARE, ACTIVE, ACTIVE);
  520. P5WritePortUchar(wPortDCR, dcr);
  521. /* ============== Periph State 5/6 Negotiation ===============
  522. PeriphAck/PtrBusy = Don't Care. low (ECP) / Don't Care (Nibble)
  523. Since this line differs based on Protocol
  524. Let's not check the line.
  525. PeriphClk/PtrClk = high (Signals State 6)
  526. nAckReverse/AckDataReq = Don't Care. low (ECP) / high (Nibble)
  527. Since this line differs based on Protocol
  528. Let's not check the line.
  529. XFlag = Don't Care. high (ECP) / low (Nibble)
  530. Since this line differs based on Protocol
  531. Let's not check the line.
  532. nPeriphReq/nDataAvail = Don't Care. high (ECP) / low (Nibble)
  533. Since this line differs based on Protocol
  534. Let's not check the line.
  535. ============== Periph State 5/6 Negotiation ==============8
  536. NOTES:
  537. - It's ok to lump states 5 and 6 together. In state 5 Nibble,
  538. the periph will set XFlag low and nPeriphReq/nDataAvail low.
  539. The periph will then hold for .5ms then set PeriphClk/PtrClk
  540. high. In ECP, state 5 is nAckReverse/AckDataReq going low and
  541. PeriphAck/PtrBusy going low. Followed by a .5ms pause.
  542. Followed by PeriphClk/PtrClk going high.
  543. ============================================================ */
  544. IeeeState->CurrentEvent = 5;
  545. if (!CHECK_DSR(Controller, DONT_CARE, ACTIVE, DONT_CARE, DONT_CARE, DONT_CARE,
  546. sPeriphResponseTime)) {
  547. dcr = UPDATE_DCR(dcr, DONT_CARE, DONT_CARE, INACTIVE, DONT_CARE, DONT_CARE, DONT_CARE);
  548. P5WritePortUchar(wPortDCR, dcr);
  549. DD(NULL,DDE,"P4IeeeEnter1284Mode - controller=%x - Extensibility=%x, FAIL - TIMEOUT on Events 5/6\n"
  550. , Controller, Extensibility);
  551. P5BSetPhase( IeeeState, PHASE_UNKNOWN );
  552. IeeeState->Connected = FALSE;
  553. IeeeState->IsIeeeTerminateOk = FALSE;
  554. return STATUS_INVALID_DEVICE_REQUEST;
  555. }
  556. KeStallExecutionProcessor(2);
  557. P5BSetPhase( IeeeState, PHASE_NEGOTIATION );
  558. IeeeState->Connected = TRUE;
  559. return STATUS_SUCCESS;
  560. }