Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2686 lines
80 KiB

  1. /*++
  2. Copyright (C) SCM Micro Systems.
  3. Module Name:
  4. parstl.c
  5. Abstract:
  6. This is the module that generates unique device id
  7. for shuttle adapters, that do not have the capability
  8. to do so, by themselves.
  9. Author:
  10. Devanathan NR 21-Jun-1999
  11. Sudheendran TL
  12. Environment:
  13. Kernel mode
  14. Revision History :
  15. --*/
  16. #include "pch.h"
  17. #include "shuttle.h"
  18. BOOLEAN
  19. ParStlCheckIfStl(
  20. IN PPDO_EXTENSION Extension,
  21. IN ULONG ulDaisyIndex
  22. )
  23. /*++
  24. Routine Description:
  25. This function checks whether the indicated device
  26. is a shuttle device or not.
  27. Arguments:
  28. Extension - Device extension structure.
  29. ulDaisyIndex - The daisy index on which to do the check.
  30. Return Value:
  31. TRUE - Yes, it was a Shuttle device.
  32. FALSE - No, not a shuttle.
  33. --*/
  34. {
  35. BOOLEAN bStlNon1284_3Found = FALSE ;
  36. DD(NULL,DDW,"ParStlCheckIfStl - enter\n");
  37. Extension->Ieee1284Flags &= ( ~ ( 1 << ulDaisyIndex ) ) ;
  38. bStlNon1284_3Found = ParStlCheckIfNon1284_3Present( Extension ) ;
  39. if ( TRUE == ParStlCheckIfStl1284_3 ( Extension, ulDaisyIndex, bStlNon1284_3Found ) ) {
  40. // this adapter is a Shuttle 1284_3 adapter
  41. Extension->Ieee1284Flags |= ( 1 << ulDaisyIndex ) ;
  42. return TRUE ;
  43. }
  44. if ( TRUE == bStlNon1284_3Found ) {
  45. if ( TRUE == ParStlCheckIfStlProductId ( Extension, ulDaisyIndex ) ) {
  46. // this adapter is Shuttle non-1284_3 adapter
  47. Extension->Ieee1284Flags |= ( 1 << ulDaisyIndex ) ;
  48. return TRUE ;
  49. }
  50. }
  51. return FALSE ;
  52. }
  53. BOOLEAN
  54. ParStlCheckIfNon1284_3Present(
  55. IN PPDO_EXTENSION Extension
  56. )
  57. /*++
  58. Routine Description:
  59. Indicates whether one of the devices of the earlier
  60. specification is present in the chain.
  61. Arguments:
  62. Extension - Device Extension structure
  63. Return Value:
  64. TRUE : Atleast one of the adapters are of earlier spec.
  65. FALSE : None of the adapters of the earlier spec.
  66. --*/
  67. {
  68. BOOLEAN bReturnValue = FALSE ;
  69. UCHAR i, value, newvalue, status;
  70. ULONG Delay = 3;
  71. PUCHAR CurrentPort, CurrentStatus, CurrentControl;
  72. UCHAR ucAckStatus ;
  73. CurrentPort = Extension->Controller;
  74. CurrentStatus = CurrentPort + 1;
  75. CurrentControl = CurrentPort + 2;
  76. // get current ctl reg
  77. value = P5ReadPortUchar( CurrentControl );
  78. // make sure 1284.3 devices do not get reseted
  79. newvalue = (UCHAR)((value & ~DCR_SELECT_IN) | DCR_NOT_INIT);
  80. // make sure we can write
  81. newvalue = (UCHAR)(newvalue & ~DCR_DIRECTION);
  82. P5WritePortUchar( CurrentControl, newvalue ); // make sure we can write
  83. // bring nStrobe high
  84. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  85. // send first four bytes of the 1284.3 mode qualifier sequence out
  86. for ( i = 0; i < MODE_LEN_1284_3 - 3; i++ ) {
  87. P5WritePortUchar( CurrentPort, ModeQualifier[i] );
  88. KeStallExecutionProcessor( Delay );
  89. }
  90. // check for correct status
  91. status = P5ReadPortUchar( CurrentStatus );
  92. if ( (status & (UCHAR)0xb8 )
  93. == ( DSR_NOT_BUSY | DSR_PERROR | DSR_SELECT | DSR_NOT_FAULT )) {
  94. ucAckStatus = status & 0x40 ;
  95. // continue with fifth byte of mode qualifier
  96. P5WritePortUchar( CurrentPort, ModeQualifier[4] );
  97. KeStallExecutionProcessor( Delay );
  98. // check for correct status
  99. status = P5ReadPortUchar( CurrentStatus );
  100. // note busy is high too but is opposite so we see it as a low
  101. if (( status & (UCHAR) 0xb8 ) == (DSR_SELECT | DSR_NOT_FAULT)) {
  102. if ( ucAckStatus != ( status & 0x40 ) ) {
  103. // save current ack status
  104. ucAckStatus = status & 0x40 ;
  105. // continue with sixth byte
  106. P5WritePortUchar( CurrentPort, ModeQualifier[5] );
  107. KeStallExecutionProcessor( Delay );
  108. // check for correct status
  109. status = P5ReadPortUchar( CurrentStatus );
  110. // if status is valid there is a device out there responding
  111. if ((status & (UCHAR) 0x30 ) == ( DSR_PERROR | DSR_SELECT )) {
  112. bReturnValue = TRUE ;
  113. } // Third status
  114. } // ack of earlier adapters not seen
  115. // last byte
  116. P5WritePortUchar( CurrentPort, ModeQualifier[6] );
  117. } // Second status
  118. } // First status
  119. P5WritePortUchar( CurrentControl, value ); // restore everything
  120. DD(NULL,DDW,"ParStlCheckIfNon1284_3Present - returning %s\n",bReturnValue?"TRUE":"FALSE");
  121. return bReturnValue ;
  122. } // ParStlCheckIfNon1284_3Present
  123. BOOLEAN
  124. ParStlCheckIfStl1284_3(
  125. IN PPDO_EXTENSION Extension,
  126. IN ULONG ulDaisyIndex,
  127. IN BOOLEAN bNoStrobe
  128. )
  129. /*++
  130. Routine Description:
  131. This function checks to see whether the device indicated
  132. is a Shuttle 1284_3 type of device.
  133. Arguments:
  134. Extension - Device extension structure.
  135. ulDaisyIndex - The daisy chain id of the device that
  136. this function will check on.
  137. bNoStrobe - If set, indicates that the query
  138. Ep1284 command issued by this function
  139. need not assert strobe to latch the
  140. command.
  141. Return Value:
  142. TRUE - Yes. Device is Shuttle 1284_3 type of device.
  143. FALSE - No. This may mean that this device is either
  144. non-shuttle or Shuttle non-1284_3 type of
  145. device.
  146. --*/
  147. {
  148. BOOLEAN bReturnValue = FALSE ;
  149. UCHAR i, value, newvalue, status;
  150. ULONG Delay = 3;
  151. UCHAR ucExpectedPattern ;
  152. UCHAR ucReadValue, ucReadPattern;
  153. PUCHAR CurrentPort, CurrentStatus, CurrentControl;
  154. CurrentPort = Extension->Controller;
  155. CurrentStatus = CurrentPort + 1;
  156. CurrentControl = CurrentPort + 2;
  157. // get current ctl reg
  158. value = P5ReadPortUchar( CurrentControl );
  159. // make sure 1284.3 devices do not get reseted
  160. newvalue = (UCHAR)((value & ~DCR_SELECT_IN) | DCR_NOT_INIT);
  161. // make sure we can write
  162. newvalue = (UCHAR)(newvalue & ~DCR_DIRECTION);
  163. P5WritePortUchar( CurrentControl, newvalue ); // make sure we can write
  164. // bring nStrobe high
  165. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  166. // send first four bytes of the 1284.3 mode qualifier sequence out
  167. for ( i = 0; i < MODE_LEN_1284_3 - 3; i++ ) {
  168. P5WritePortUchar( CurrentPort, ModeQualifier[i] );
  169. KeStallExecutionProcessor( Delay );
  170. }
  171. // check for correct status
  172. status = P5ReadPortUchar( CurrentStatus );
  173. if ( (status & (UCHAR)0xb8 )
  174. == ( DSR_NOT_BUSY | DSR_PERROR | DSR_SELECT | DSR_NOT_FAULT )) {
  175. // continue with fifth byte of mode qualifier
  176. P5WritePortUchar( CurrentPort, ModeQualifier[4] );
  177. KeStallExecutionProcessor( Delay );
  178. // check for correct status
  179. status = P5ReadPortUchar( CurrentStatus );
  180. // note busy is high too but is opposite so we see it as a low
  181. if (( status & (UCHAR) 0xb8 ) == (DSR_SELECT | DSR_NOT_FAULT)) {
  182. // continue with sixth byte
  183. P5WritePortUchar( CurrentPort, ModeQualifier[5] );
  184. KeStallExecutionProcessor( Delay );
  185. // check for correct status
  186. status = P5ReadPortUchar( CurrentStatus );
  187. // if status is valid there is a device out there responding
  188. if ((status & (UCHAR) 0x30 ) == ( DSR_PERROR | DSR_SELECT )) {
  189. // Device is out there
  190. KeStallExecutionProcessor( Delay );
  191. // issue shuttle specific CPP command
  192. P5WritePortUchar( CurrentPort, (UCHAR) ( 0x88 | ulDaisyIndex ) );
  193. KeStallExecutionProcessor( Delay ); // wait a bit
  194. if ( ulDaisyIndex && ( bNoStrobe == FALSE ) ) {
  195. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) ); // bring nStrobe high
  196. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) ); // bring nStrobe low
  197. KeStallExecutionProcessor( Delay ); // wait a bit
  198. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) ); // bring nStrobe high
  199. KeStallExecutionProcessor( Delay ); // wait a bit
  200. }
  201. ucExpectedPattern = 0xF0 ;
  202. bReturnValue = TRUE ;
  203. while ( ucExpectedPattern ) {
  204. KeStallExecutionProcessor( Delay ); // wait a bit
  205. P5WritePortUchar( CurrentPort, (UCHAR) (0x80 | ulDaisyIndex )) ;
  206. KeStallExecutionProcessor( Delay ); // wait a bit
  207. P5WritePortUchar( CurrentPort, (UCHAR) (0x88 | ulDaisyIndex )) ;
  208. KeStallExecutionProcessor( Delay ); // wait a bit
  209. ucReadValue = P5ReadPortUchar( CurrentStatus ) ;
  210. ucReadPattern = ( ucReadValue << 1 ) & 0x70 ;
  211. ucReadPattern |= ( ucReadValue & 0x80 ) ;
  212. if ( ucReadPattern != ucExpectedPattern ) {
  213. // not Shuttle 1284_3 behaviour
  214. bReturnValue = FALSE ;
  215. break ;
  216. }
  217. ucExpectedPattern -= 0x10 ;
  218. }
  219. // last byte
  220. P5WritePortUchar( CurrentPort, ModeQualifier[6] );
  221. } // Third status
  222. } // Second status
  223. } // First status
  224. P5WritePortUchar( CurrentControl, value ); // restore everything
  225. DD(NULL,DDW,"ParStlCheckIfStl1284_3 - returning %s\n",bReturnValue?"TRUE":"FALSE");
  226. return bReturnValue ;
  227. } // end ParStlCheckIfStl1284_3()
  228. BOOLEAN
  229. ParStlCheckIfStlProductId(
  230. IN PPDO_EXTENSION Extension,
  231. IN ULONG ulDaisyIndex
  232. )
  233. /*++
  234. Routine Description:
  235. This function checks to see whether the device indicated
  236. is a Shuttle non-1284_3 type of device.
  237. Arguments:
  238. Extension - Device extension structure.
  239. ulDaisyIndex - The daisy chain id of the device that
  240. this function will check on.
  241. Return Value:
  242. TRUE - Yes. Device is Shuttle non-1284_3 type of device.
  243. FALSE - No. This may mean that this device is
  244. non-shuttle.
  245. --*/
  246. {
  247. BOOLEAN bReturnValue = FALSE ;
  248. UCHAR i, value, newvalue, status;
  249. ULONG Delay = 3;
  250. UCHAR ucProdIdHiByteHiNibble, ucProdIdHiByteLoNibble ;
  251. UCHAR ucProdIdLoByteHiNibble, ucProdIdLoByteLoNibble ;
  252. UCHAR ucProdIdHiByte, ucProdIdLoByte ;
  253. USHORT usProdId ;
  254. PUCHAR CurrentPort, CurrentStatus, CurrentControl;
  255. CurrentPort = Extension->Controller;
  256. CurrentStatus = CurrentPort + 1;
  257. CurrentControl = CurrentPort + 2;
  258. // get current ctl reg
  259. value = P5ReadPortUchar( CurrentControl );
  260. // make sure 1284.3 devices do not get reseted
  261. newvalue = (UCHAR)((value & ~DCR_SELECT_IN) | DCR_NOT_INIT);
  262. // make sure we can write
  263. newvalue = (UCHAR)(newvalue & ~DCR_DIRECTION);
  264. P5WritePortUchar( CurrentControl, newvalue ); // make sure we can write
  265. // bring nStrobe high
  266. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  267. // send first four bytes of the 1284.3 mode qualifier sequence out
  268. for ( i = 0; i < MODE_LEN_1284_3 - 3; i++ ) {
  269. P5WritePortUchar( CurrentPort, ModeQualifier[i] );
  270. KeStallExecutionProcessor( Delay );
  271. }
  272. // check for correct status
  273. status = P5ReadPortUchar( CurrentStatus );
  274. if ( (status & (UCHAR)0xb8 )
  275. == ( DSR_NOT_BUSY | DSR_PERROR | DSR_SELECT | DSR_NOT_FAULT )) {
  276. // continue with fifth byte of mode qualifier
  277. P5WritePortUchar( CurrentPort, ModeQualifier[4] );
  278. KeStallExecutionProcessor( Delay );
  279. // check for correct status
  280. status = P5ReadPortUchar( CurrentStatus );
  281. // note busy is high too but is opposite so we see it as a low
  282. if (( status & (UCHAR) 0xb8 ) == (DSR_SELECT | DSR_NOT_FAULT)) {
  283. // continue with sixth byte
  284. P5WritePortUchar( CurrentPort, ModeQualifier[5] );
  285. KeStallExecutionProcessor( Delay );
  286. // check for correct status
  287. status = P5ReadPortUchar( CurrentStatus );
  288. // if status is valid there is a device out there responding
  289. if ((status & (UCHAR) 0x30 ) == ( DSR_PERROR | DSR_SELECT )) {
  290. P5WritePortUchar ( CurrentPort, (UCHAR) (CPP_QUERY_PRODID | ulDaisyIndex )) ;
  291. KeStallExecutionProcessor( Delay );
  292. // Device is out there
  293. KeStallExecutionProcessor( Delay );
  294. ucProdIdLoByteHiNibble = P5ReadPortUchar( CurrentStatus ) ;
  295. ucProdIdLoByteHiNibble &= 0xF0 ;
  296. KeStallExecutionProcessor( Delay );
  297. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  298. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) ); // bring nStrobe low
  299. KeStallExecutionProcessor( Delay ); // wait a bit
  300. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) ); // bring nStrobe high
  301. KeStallExecutionProcessor( Delay ); // wait a bit
  302. ucProdIdLoByteLoNibble = P5ReadPortUchar( CurrentStatus ) ;
  303. ucProdIdLoByteLoNibble >>= 4 ;
  304. ucProdIdLoByte = ucProdIdLoByteHiNibble | ucProdIdLoByteLoNibble ;
  305. KeStallExecutionProcessor( Delay );
  306. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  307. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) ); // bring nStrobe low
  308. KeStallExecutionProcessor( Delay ); // wait a bit
  309. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) ); // bring nStrobe high
  310. KeStallExecutionProcessor( Delay ); // wait a bit
  311. ucProdIdHiByteHiNibble = P5ReadPortUchar( CurrentStatus ) ;
  312. ucProdIdHiByteHiNibble &= 0xF0 ;
  313. KeStallExecutionProcessor( Delay );
  314. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  315. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) ); // bring nStrobe low
  316. KeStallExecutionProcessor( Delay ); // wait a bit
  317. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) ); // bring nStrobe high
  318. KeStallExecutionProcessor( Delay ); // wait a bit
  319. ucProdIdHiByteLoNibble = P5ReadPortUchar( CurrentStatus ) ;
  320. ucProdIdHiByteLoNibble >>= 4 ;
  321. ucProdIdHiByte = ucProdIdHiByteHiNibble | ucProdIdHiByteLoNibble ;
  322. // last strobe
  323. KeStallExecutionProcessor( Delay );
  324. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) );
  325. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue | DCR_STROBE) ); // bring nStrobe low
  326. KeStallExecutionProcessor( Delay ); // wait a bit
  327. P5WritePortUchar( CurrentControl, (UCHAR)(newvalue & ~DCR_STROBE) ); // bring nStrobe high
  328. KeStallExecutionProcessor( Delay ); // wait a bit
  329. usProdId = ( ucProdIdHiByte << 8 ) | ucProdIdLoByte ;
  330. if ( ( SHTL_EPAT_PRODID == usProdId ) ||\
  331. ( SHTL_EPST_PRODID == usProdId ) ) {
  332. // one of the devices that conform to the earlier
  333. // draft is found
  334. bReturnValue = TRUE ;
  335. }
  336. // last byte
  337. P5WritePortUchar( CurrentPort, ModeQualifier[6] );
  338. } // Third status
  339. } // Second status
  340. } // First status
  341. P5WritePortUchar( CurrentControl, value ); // restore everything
  342. DD(NULL,DDW,"ParStlCheckIfStlProductId - returning %s\n",bReturnValue?"TRUE":"FALSE");
  343. return bReturnValue ;
  344. } // end ParStlCheckIfStlProductId()
  345. PCHAR
  346. ParStlQueryStlDeviceId(
  347. IN PPDO_EXTENSION Extension,
  348. OUT PCHAR CallerDeviceIdBuffer,
  349. IN ULONG CallerBufferSize,
  350. OUT PULONG DeviceIdSize,
  351. IN BOOLEAN bReturnRawString
  352. )
  353. /*++
  354. Routine Description:
  355. This routine retrieves/constructs the unique device id
  356. string from the selected shuttle device on the chain
  357. and updates the caller's buffer with the same.
  358. Arguments:
  359. IN Extension : The device extension
  360. OUT CallerDeviceIdBuffer : Caller's buffer
  361. IN CallerBufferSize : Size of caller's buffer
  362. OUT DeviceIdSize : Updated device id's size
  363. IN bReturnRawString : Whether to return raw
  364. string with the first two
  365. bytes or not.
  366. Return Value:
  367. Pointer to the read device ID string, if successful.
  368. NULL otherwise.
  369. --*/
  370. {
  371. PUCHAR Controller = Extension->Controller;
  372. NTSTATUS Status;
  373. UCHAR idSizeBuffer[2];
  374. ULONG bytesToRead;
  375. ULONG bytesRead = 0;
  376. USHORT deviceIdSize;
  377. USHORT deviceIdBufferSize;
  378. PCHAR deviceIdBuffer;
  379. PCHAR readPtr;
  380. DD(NULL,DDW,"ParStlQueryStlDeviceId - enter\n");
  381. *DeviceIdSize = 0;
  382. // assert idle state, to recover from undefined state,
  383. // just in case it gets into
  384. ParStlAssertIdleState ( Extension ) ;
  385. //
  386. // If we are currently connected to the peripheral via any 1284 mode
  387. // other than Compatibility/Spp mode (which does not require an IEEE
  388. // negotiation), we must first terminate the current mode/connection.
  389. //
  390. // dvdf - RMT - what if we are connected in a reverse mode?
  391. //
  392. if( (Extension->Connected) && (afpForward[Extension->IdxForwardProtocol].fnDisconnect) ) {
  393. afpForward[Extension->IdxForwardProtocol].fnDisconnect (Extension);
  394. }
  395. //
  396. // Negotiate the peripheral into nibble device id mode.
  397. //
  398. Status = ParEnterNibbleMode(Extension, REQUEST_DEVICE_ID);
  399. if( !NT_SUCCESS(Status) ) {
  400. ParTerminateNibbleMode(Extension);
  401. goto targetContinue;
  402. }
  403. //
  404. // Read first two bytes to get the total (including the 2 size bytes) size
  405. // of the Device Id string.
  406. //
  407. bytesToRead = 2;
  408. Status = ParNibbleModeRead(Extension, idSizeBuffer, bytesToRead, &bytesRead);
  409. if( !NT_SUCCESS( Status ) || ( bytesRead != bytesToRead ) ) {
  410. goto targetContinue;
  411. }
  412. //
  413. // Compute size of DeviceId string (including the 2 byte size prefix)
  414. //
  415. deviceIdSize = (USHORT)( idSizeBuffer[0]*0x100 + idSizeBuffer[1] );
  416. {
  417. const USHORT minValidDevId = 14; // 2 size bytes + "MFG:x;" + "MDL:y;"
  418. const USHORT maxValidDevId = 2048; // arbitrary, but we've never seen one > 1024
  419. if( (deviceIdSize < minValidDevId) || (deviceIdSize > maxValidDevId) ) {
  420. //
  421. // The device is reporting a 1284 ID string length that is probably bogus.
  422. // Ignore the device reported ID and skip to the code below that makes
  423. // up a VID/PID based 1284 ID based on the specific SCM Micro chip used
  424. // by the device.
  425. //
  426. goto targetContinue;
  427. }
  428. }
  429. //
  430. // Allocate a buffer to hold the DeviceId string and read the DeviceId into it.
  431. //
  432. if( bReturnRawString ) {
  433. //
  434. // Caller wants the raw string including the 2 size bytes
  435. //
  436. *DeviceIdSize = deviceIdSize;
  437. deviceIdBufferSize = (USHORT)(deviceIdSize + sizeof(CHAR)); // ID size + ID + terminating NULL
  438. } else {
  439. //
  440. // Caller does not want the 2 byte size prefix
  441. //
  442. *DeviceIdSize = deviceIdSize - 2*sizeof(CHAR);
  443. deviceIdBufferSize = (USHORT)(deviceIdSize - 2*sizeof(CHAR) + sizeof(CHAR)); // ID + terminating NULL
  444. }
  445. deviceIdBuffer = (PCHAR)ExAllocatePool(PagedPool, deviceIdBufferSize);
  446. if( !deviceIdBuffer ) {
  447. goto targetContinue;
  448. }
  449. //
  450. // NULL out the ID buffer to be safe
  451. //
  452. RtlZeroMemory( deviceIdBuffer, deviceIdBufferSize );
  453. //
  454. // Does the caller want the 2 byte size prefix?
  455. //
  456. if( bReturnRawString ) {
  457. //
  458. // Yes, caller wants the size prefix. Copy prefix to buffer to return.
  459. //
  460. *(deviceIdBuffer+0) = idSizeBuffer[0];
  461. *(deviceIdBuffer+1) = idSizeBuffer[1];
  462. readPtr = deviceIdBuffer + 2;
  463. } else {
  464. //
  465. // No, discard size prefix
  466. //
  467. readPtr = deviceIdBuffer;
  468. }
  469. //
  470. // Read remainder of DeviceId from device
  471. //
  472. bytesToRead = deviceIdSize - 2; // already have the 2 size bytes
  473. Status = ParNibbleModeRead(Extension, readPtr, bytesToRead, &bytesRead);
  474. ParTerminateNibbleMode( Extension );
  475. if( !NT_SUCCESS(Status) || (bytesRead < 1) ) {
  476. ExFreePool( deviceIdBuffer );
  477. goto targetContinue;
  478. }
  479. if ( strstr ( readPtr, "MFG:" ) == 0 ) {
  480. ExFreePool( deviceIdBuffer ) ;
  481. goto targetContinue;
  482. }
  483. deviceIdSize = (USHORT)strlen(deviceIdBuffer);
  484. *DeviceIdSize = deviceIdSize;
  485. if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize + sizeof(CHAR)) ) {
  486. // caller supplied buffer is large enough, use it
  487. RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
  488. RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
  489. ExFreePool( deviceIdBuffer );
  490. return CallerDeviceIdBuffer;
  491. }
  492. return deviceIdBuffer;
  493. targetContinue:
  494. // Builds later than 2080 fail to terminate in Compatibility mode.
  495. //IEEETerminate1284Mode fails after Event 23 (Extension->CurrentEvent equals 23)
  496. // with earlier 1284 draft.
  497. //So, we terminate the adapter ourselves, in some cases may be redundant.
  498. P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT);
  499. KeStallExecutionProcessor( 5 );
  500. P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT | DCR_AUTOFEED);
  501. KeStallExecutionProcessor( 5 );
  502. P5WritePortUchar(Controller + DCR_OFFSET, DCR_SELECT_IN | DCR_NOT_INIT);
  503. ParStlAssertIdleState ( Extension ) ;
  504. deviceIdBuffer = ParBuildStlDeviceId(Extension, bReturnRawString);
  505. if( !deviceIdBuffer ) {
  506. return NULL;
  507. }
  508. deviceIdSize = (USHORT)strlen(deviceIdBuffer);
  509. *DeviceIdSize = deviceIdSize;
  510. if( (NULL != CallerDeviceIdBuffer) && (CallerBufferSize >= deviceIdSize + sizeof(CHAR)) ) {
  511. // caller supplied buffer is large enough, use it
  512. RtlZeroMemory( CallerDeviceIdBuffer, CallerBufferSize );
  513. RtlCopyMemory( CallerDeviceIdBuffer, deviceIdBuffer, deviceIdSize );
  514. ExFreePool( deviceIdBuffer );
  515. return CallerDeviceIdBuffer;
  516. }
  517. return deviceIdBuffer;
  518. }
  519. PCHAR
  520. ParBuildStlDeviceId(
  521. IN PPDO_EXTENSION Extension,
  522. IN BOOLEAN bReturnRawString
  523. )
  524. /*++
  525. Routine Description:
  526. This function detects the type of shuttle adapter and
  527. builds an appropriate device id string and returns it
  528. back.
  529. It is assumed that the device is already in the
  530. selected state.
  531. Arguments:
  532. Nil.
  533. Return Value:
  534. Pointer to the read/built device ID string, if successful.
  535. NULL otherwise.
  536. --*/
  537. {
  538. LONG size = 0x80 ;
  539. PCHAR id ;
  540. STL_DEVICE_TYPE dtDeviceType ;
  541. CHAR szDeviceIdString[0x80] = {0};
  542. CHAR szVidPidString[] = "MFG:VID_04E6;CLS:SCSIADAPTER;MDL:PID_" ;
  543. CHAR szVidPidStringScan[] = "MFG:VID_04E6;CLS:IMAGE;MDL:PID_" ;
  544. LONG charsWritten;
  545. RtlZeroMemory(szDeviceIdString, sizeof(szDeviceIdString));
  546. // identify the shuttle adapter type by calling
  547. // Devtype routines here and build an unique id
  548. // string here.
  549. dtDeviceType = ParStlGetDeviceType(Extension, DEVICE_TYPE_AUTO_DETECT);
  550. switch ( dtDeviceType ) {
  551. case DEVICE_TYPE_NONE :
  552. return NULL;
  553. case DEVICE_TYPE_EPP_DEVICE :
  554. dtDeviceType |= 0x80000000 ;
  555. charsWritten = _snprintf(szDeviceIdString, size, "%s%08X;", szVidPidStringScan, dtDeviceType);
  556. if( (charsWritten >= size) || charsWritten < 0 ) {
  557. // insufficient room in array buffer, bail out
  558. ASSERT(FALSE); // should never happen
  559. return NULL;
  560. }
  561. break;
  562. default :
  563. dtDeviceType |= 0x80000000 ;
  564. charsWritten = _snprintf(szDeviceIdString, size, "%s%08X;", szVidPidString, dtDeviceType);
  565. if( (charsWritten >= size) || charsWritten < 0 ) {
  566. // insufficient room in array buffer, bail out
  567. ASSERT(FALSE); // should never happen
  568. return NULL;
  569. }
  570. break;
  571. }
  572. id = ExAllocatePool(PagedPool, size);
  573. if( id ) {
  574. RtlZeroMemory( id, size );
  575. if( bReturnRawString ) {
  576. //
  577. // Yes, caller wants the size prefix. Copy prefix to buffer to return.
  578. //
  579. *(id+0) = 0;
  580. *(id+1) = 0x80-2;
  581. RtlCopyMemory( id+2, szDeviceIdString, size - sizeof(NULL) - 2 );
  582. } else {
  583. RtlCopyMemory( id, szDeviceIdString, size - sizeof(NULL) );
  584. }
  585. return id;
  586. }
  587. return NULL;
  588. }
  589. STL_DEVICE_TYPE __cdecl
  590. ParStlGetDeviceType (
  591. IN PPDO_EXTENSION Extension,
  592. IN int nPreferredDeviceType
  593. )
  594. {
  595. STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
  596. ATAPIPARAMS atapiParams ;
  597. int i;
  598. for ( i=0 ; i<ATAPI_MAX_DRIVES ; i++){
  599. atapiParams.dsDeviceState[i] = DEVICE_STATE_INVALID ;
  600. }
  601. do
  602. {
  603. if ( TRUE == ParStlCheckIfScsiDevice(Extension))
  604. {
  605. // SCSI Device identified.
  606. dtDeviceType |= DEVICE_TYPE_SCSI_BIT ;
  607. break ;
  608. }
  609. if ( TRUE == NeedToEnableIoPads () )
  610. {
  611. // in some adapters, the IO pads need to be enabled, before
  612. // doing the device detection
  613. ParStlWriteReg( Extension, CONFIG_INDEX_REGISTER, EP1284_POWER_CONTROL_REG );
  614. ParStlWriteReg( Extension, CONFIG_DATA_REGISTER, ENABLE_IOPADS );
  615. }
  616. if ( TRUE == IsImpactSPresent() )
  617. {
  618. // as impact-s has been identified, the device type identification
  619. // can be done through personality configuration info
  620. dtDeviceType |= ParStlGetImpactSDeviceType( Extension, &atapiParams, nPreferredDeviceType );
  621. break;
  622. }
  623. if ( TRUE == IsImpactPresent() )
  624. {
  625. // as impact has been identified, the device type identification
  626. // can be done through personality configuration info
  627. dtDeviceType |= ParStlGetImpactDeviceType( Extension, &atapiParams, nPreferredDeviceType );
  628. break;
  629. }
  630. if (TRUE == ParStlCheckIfEppDevice(Extension))
  631. {
  632. // epp device identified
  633. if ( TRUE == ParStlCheckUMAXScannerPresence(Extension) ) {
  634. // umax identified
  635. dtDeviceType |= DEVICE_TYPE_UMAX_BIT;
  636. break;
  637. }
  638. if ( TRUE == ParStlCheckAvisionScannerPresence(Extension) ) {
  639. // avision identified
  640. dtDeviceType |= DEVICE_TYPE_AVISION_BIT;
  641. break;
  642. }
  643. // generice scanner peripheral detected
  644. dtDeviceType |= DEVICE_TYPE_EPP_DEVICE_BIT;
  645. break;
  646. }
  647. if (TRUE == ParStlCheckIfSSFDC(Extension))
  648. {
  649. // SSFDC identified
  650. dtDeviceType |= DEVICE_TYPE_SSFDC_BIT;
  651. break;
  652. }
  653. if (TRUE == ParStlCheckIfMMC(Extension,&atapiParams))
  654. {
  655. // MMC device identified
  656. dtDeviceType |= DEVICE_TYPE_MMC_BIT;
  657. break;
  658. }
  659. // set the 16 bit mode of the adapter
  660. ParStlSet16BitOperation(Extension) ;
  661. if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension, &atapiParams))
  662. {
  663. // necessary but not sufficient condition has passed
  664. // proceed for sufficency checks
  665. if (TRUE == ParStlCheckIfAtapiDevice(Extension, &atapiParams))
  666. {
  667. // sub-classify between HiFD and LS-120.
  668. if ( TRUE == ParStlCheckIfLS120(Extension))
  669. {
  670. // LS Engine is found.
  671. dtDeviceType |= DEVICE_TYPE_LS120_BIT ;
  672. break ;
  673. }
  674. // Check for HiFD.
  675. if (TRUE == ParStlCheckIfHiFD(Extension))
  676. {
  677. // HiFD device identified.
  678. dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
  679. break ;
  680. }
  681. // OtherWise, it is a generic ATAPI device.
  682. dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
  683. break ;
  684. }
  685. if (TRUE == ParStlCheckIfAtaDevice(Extension, &atapiParams))
  686. {
  687. // ata identified
  688. dtDeviceType |= DEVICE_TYPE_ATA_BIT;
  689. break;
  690. }
  691. }
  692. if (TRUE == ParStlCheckIfDazzle(Extension))
  693. {
  694. // dazzle identified
  695. dtDeviceType |= DEVICE_TYPE_DAZZLE_BIT;
  696. break;
  697. }
  698. if (TRUE == ParStlCheckIfFlash(Extension))
  699. {
  700. // flash identified
  701. dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
  702. break;
  703. }
  704. }
  705. while ( FALSE ) ;
  706. return dtDeviceType & nPreferredDeviceType ;
  707. }
  708. VOID
  709. ParStlWaitForMicroSeconds (
  710. int nMicroSecondsToWait
  711. ) {
  712. KeStallExecutionProcessor ( nMicroSecondsToWait ) ;
  713. }
  714. BOOLEAN
  715. ParStlCheckCardInsertionStatus (
  716. IN PPDO_EXTENSION Extension
  717. )
  718. {
  719. BOOLEAN bReturnValue = FALSE ;
  720. UCHAR byPowerRegData ;
  721. do
  722. {
  723. if ( FALSE == IsEp1284Present() )
  724. {
  725. break ;
  726. }
  727. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , 0x0F ) ;
  728. byPowerRegData = (UCHAR) ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
  729. if ( byPowerRegData & SHTL_CARD_INSERTED_STATUS )
  730. {
  731. // as the card not inserted status is reported, it is ATA / ATAPI
  732. // possibly, not flash. hence, we break here.
  733. break ;
  734. }
  735. bReturnValue = TRUE ;
  736. }
  737. while ( FALSE ) ;
  738. return ( bReturnValue ) ;
  739. }
  740. BOOLEAN
  741. ParStlSelectAdapterSocket (
  742. IN PPDO_EXTENSION Extension,
  743. IN int nSocketNumber
  744. )
  745. {
  746. BOOLEAN bReturnValue = FALSE ;
  747. UCHAR bySCRControlReg , byISAControlReg ;
  748. do
  749. {
  750. if ( ( nSocketNumber != SOCKET_0 ) &&
  751. ( nSocketNumber != SOCKET_1 ) )
  752. {
  753. // as an invalid socket number is provided, we
  754. // break here with error.
  755. break ;
  756. }
  757. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
  758. bySCRControlReg = (UCHAR) ParStlReadReg (Extension, CONFIG_DATA_REGISTER ) ;
  759. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , ISA_CONTROL_REGISTER ) ;
  760. byISAControlReg = (UCHAR) ParStlReadReg (Extension, CONFIG_DATA_REGISTER ) ;
  761. if ( SOCKET_1 == nSocketNumber )
  762. {
  763. bySCRControlReg |= (UCHAR)SOCKET_1 ;
  764. bySCRControlReg |= (UCHAR)PERIPHERAL_RESET_1 ;
  765. byISAControlReg &= ~(UCHAR)ISA_IO_SWAP ;
  766. }
  767. else
  768. {
  769. bySCRControlReg &= ~(UCHAR)SOCKET_1 ;
  770. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_0 ;
  771. }
  772. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , ISA_CONTROL_REGISTER ) ;
  773. ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , byISAControlReg ) ;
  774. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
  775. ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  776. if ( SOCKET_1 == nSocketNumber )
  777. {
  778. // Wait for a few milliseconds to provide an optimal puse width
  779. // for reset.
  780. ParStlWaitForMicroSeconds(1000);
  781. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_1 ;
  782. }
  783. else
  784. {
  785. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_0 ;
  786. }
  787. ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  788. bReturnValue = TRUE ;
  789. }
  790. while ( FALSE ) ;
  791. return bReturnValue ;
  792. }
  793. BOOLEAN
  794. ParStlCheckIfAtaAtapiDevice (
  795. IN PPDO_EXTENSION Extension,
  796. IN OUT PATAPIPARAMS atapiParams
  797. )
  798. {
  799. BOOLEAN bReturnValue = FALSE;
  800. do
  801. {
  802. if ( TRUE == ParStlCheckCardInsertionStatus(Extension) )
  803. {
  804. // as the card insertion status is valid, its probably
  805. // a flash
  806. break ;
  807. }
  808. if ( FALSE == ParStlCheckDrivePresent(Extension, atapiParams) )
  809. {
  810. // as the ATA/ATAPI controller is not present, it cant be
  811. // an ATA/ATAPI device
  812. break ;
  813. }
  814. bReturnValue = TRUE;
  815. }
  816. while ( FALSE ) ;
  817. return bReturnValue ;
  818. }
  819. BOOLEAN
  820. ParStlCheckIfAtapiDevice (
  821. IN PPDO_EXTENSION Extension,
  822. IN OUT PATAPIPARAMS atapiParams
  823. )
  824. {
  825. BOOLEAN bReturnValue = FALSE;
  826. do
  827. {
  828. // return whatever ATAPI initialization module says
  829. bReturnValue = ParStlAtapiInitialize(Extension, atapiParams) ;
  830. }
  831. while ( FALSE ) ;
  832. return bReturnValue ;
  833. }
  834. BOOLEAN
  835. ParStlCheckIfAtaDevice (
  836. IN PPDO_EXTENSION Extension,
  837. IN OUT PATAPIPARAMS atapiParams
  838. )
  839. {
  840. BOOLEAN bReturnValue = FALSE;
  841. do
  842. {
  843. // return whatever ATA initialization module says
  844. bReturnValue = ParStlAtaInitialize(Extension, atapiParams) ;
  845. }
  846. while ( FALSE ) ;
  847. return bReturnValue ;
  848. }
  849. BOOLEAN
  850. ParStlCheckDrivePresent (
  851. IN PPDO_EXTENSION Extension,
  852. IN OUT PATAPIPARAMS atapiParams
  853. )
  854. {
  855. BOOLEAN bReturnValue = FALSE ;
  856. UCHAR byOrgCylHigh, byOrgCylLow ;
  857. int nCurrentDrive = 0 , i ;
  858. UCHAR nDrvHdArray[]={ATAPI_MASTER, ATAPI_SLAVE};
  859. do
  860. {
  861. if ( atapiParams->dsDeviceState[nCurrentDrive] == DEVICE_STATE_VALID )
  862. {
  863. // this means that the MMC module had detected the presence
  864. // of an ATA/ATAPI device. So, we make use of that and break out
  865. bReturnValue = TRUE ;
  866. break ;
  867. }
  868. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, nDrvHdArray[nCurrentDrive]);
  869. // The Atapi Fuji MO drive is found to de-assert BSY and still
  870. // does not respond to reg. r/w when configured as slave with no media.
  871. // However, after a delay, it works ok.
  872. if ( nCurrentDrive )
  873. {
  874. ParStlWaitForMicroSeconds ( DELAY_1SECOND ) ;
  875. }
  876. // this dummy write of 0 is to zero out a possible
  877. // floating bus
  878. for ( i = 0 ; i < 16 ; i++ )
  879. {
  880. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER, i) ;
  881. if ( !( ParStlReadIoPort (Extension, ATA_TASK_STAT_REG ) & ATA_ST_BUSY ) )
  882. {
  883. break ;
  884. }
  885. }
  886. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  887. {
  888. // as the busy has been found permanently set, we check
  889. // for the slave also
  890. continue;
  891. }
  892. // as the drive head setup might have been performed in a busy state,
  893. // we set it up again after busy clears.
  894. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, nDrvHdArray[nCurrentDrive]);
  895. if ( ( ParStlReadIoPort(Extension, ATA_DRVHD_REG) & ATAPI_SLAVE ) != nDrvHdArray[nCurrentDrive] )
  896. {
  897. continue ;
  898. }
  899. // read original contents of the cyl ATA high/low registers
  900. byOrgCylLow = (UCHAR) ParStlReadIoPort(Extension, ATA_CYLLOW_REG);
  901. byOrgCylHigh = (UCHAR) ParStlReadIoPort(Extension, ATA_CYLHIGH_REG);
  902. // write a test pattern in the cyl ATA high/low registers
  903. ParStlWriteIoPort(Extension, ATA_CYLLOW_REG, TEST_PATTERN_1);
  904. ParStlWriteIoPort(Extension, ATA_CYLHIGH_REG, TEST_PATTERN_2);
  905. // read the test pattern in the cyl ATA high/low registers
  906. if ( ( TEST_PATTERN_1 != ParStlReadIoPort(Extension, ATA_CYLLOW_REG) ) ||\
  907. ( TEST_PATTERN_2 != ParStlReadIoPort(Extension, ATA_CYLHIGH_REG) ) )
  908. {
  909. // as we were not able to read back the written values
  910. // we break out here, indicating the absence of the device
  911. continue ;
  912. }
  913. // write back original contents in the cyl ATA high/low registers
  914. ParStlWriteIoPort(Extension, ATA_CYLLOW_REG, byOrgCylLow);
  915. ParStlWriteIoPort(Extension, ATA_CYLHIGH_REG, byOrgCylHigh);
  916. bReturnValue = TRUE ;
  917. atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_VALID ;
  918. }
  919. while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
  920. // reset back to master state, as check drive present
  921. // will be called successively
  922. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  923. return bReturnValue ;
  924. }
  925. BOOLEAN
  926. ParStlAtapiInitialize (
  927. IN PPDO_EXTENSION Extension,
  928. IN OUT PATAPIPARAMS atapiParams
  929. )
  930. {
  931. BOOLEAN bReturnValue = FALSE ;
  932. int nCurrentDrive = 0, i ;
  933. UCHAR byTempValue ;
  934. UCHAR chAtapiIdentifyBuffer [ ATAPI_IDENTIFY_LENGTH ] ;
  935. do
  936. {
  937. if ( DEVICE_STATE_VALID != atapiParams->dsDeviceState[nCurrentDrive] )
  938. {
  939. // the device is absent
  940. continue ;
  941. }
  942. if ( nCurrentDrive )
  943. {
  944. // as it is the next drive, choose the slave
  945. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_SLAVE);
  946. }
  947. else
  948. {
  949. // choose the master
  950. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  951. }
  952. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  953. {
  954. // as busy has permanently set after master/slave, we fail
  955. // the detection process
  956. continue ;
  957. }
  958. // check if the ATAPI signature is present in the cyl hi/lo
  959. // registers. If present, it is definitely an ATAPI device
  960. if ( ( ParStlReadIoPort(Extension, ATA_CYLLOW_REG) == ATAPI_SIGN_LOW ) &&\
  961. ( ParStlReadIoPort(Extension, ATA_CYLHIGH_REG) == ATAPI_SIGN_HI ) )
  962. {
  963. // as ATAPI signature is present, it is ATAPI type
  964. bReturnValue = TRUE ;
  965. // set this flag so that, ATA initialize will skip this
  966. // target
  967. atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_ATAPI ;
  968. // for Impact, since Ls120 engine is always present,
  969. // issuing ATAPI_IDENTIFY is mandatory.
  970. if ( !IsImpactPresent())
  971. {
  972. continue ;
  973. }
  974. }
  975. // issue the ata nop command
  976. ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATA_NOP_COMMAND) ;
  977. if ( FALSE == ParStlWaitForIrq(Extension) )
  978. {
  979. // ATAPI devices are expected to give interrrupt on NOP command
  980. // mandatorily.
  981. continue ;
  982. }
  983. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  984. {
  985. // as busy has permanently set, we proceed with the next
  986. // drive
  987. continue ;
  988. }
  989. // issue the atapi packet command
  990. ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATAPI_IDENTIFY) ;
  991. if ( FALSE == ParStlWaitForIrq(Extension) )
  992. {
  993. // ATAPI devices are expected to give interrrupt on 0xA1 command
  994. // mandatorily.
  995. continue ;
  996. }
  997. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  998. {
  999. // as busy has permanently set, we proceed with the next
  1000. // drive
  1001. continue ;
  1002. }
  1003. byTempValue = (UCHAR) ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) ;
  1004. if ( ! ( byTempValue & ATA_ST_ERROR ) )
  1005. {
  1006. // as the drive has passed the packet command, this is an atapi
  1007. // drive
  1008. // Wait for DRQ to be sit, as some drives are known
  1009. // to remove busy too early and set DRQ after some time.
  1010. if ( FALSE == ParStlWaitForDrq(Extension) )
  1011. {
  1012. // as there was no DRQ set, we proceed with the next
  1013. // drive
  1014. continue ;
  1015. }
  1016. bReturnValue = TRUE ;
  1017. // as the DRQ is still asserted, quell it, as certain ATA/ATAPI-4
  1018. // spec. dictates it so
  1019. // There is a need to check the device identifier returned in the
  1020. // ATAPI Identify cmd. to determine the presence of Ls-120.
  1021. ParStlReceiveData ( Extension, chAtapiIdentifyBuffer , SKIP_MEMORY_ADDRESS , ATAPI_IDENTIFY_LENGTH ) ;
  1022. for ( i = 0 ; i < ATAPI_NAME_LENGTH ; i++ )
  1023. {
  1024. atapiParams->szAtapiNameString[i] = chAtapiIdentifyBuffer[ ATAPI_NAME_OFFSET + i ] ;
  1025. }
  1026. // set this flag so that, ATA initialize will skip this
  1027. // target
  1028. atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_ATAPI ;
  1029. }
  1030. }
  1031. while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
  1032. // reset back to master state, as check drive present
  1033. // will be called successively
  1034. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  1035. return ( bReturnValue ) ;
  1036. }
  1037. BOOLEAN
  1038. ParStlAtaInitialize (
  1039. IN PPDO_EXTENSION Extension,
  1040. IN OUT PATAPIPARAMS atapiParams
  1041. )
  1042. {
  1043. BOOLEAN bReturnValue = FALSE ;
  1044. UCHAR byTempValue ;
  1045. int nCurrentDrive = 0 ;
  1046. do
  1047. {
  1048. if ( DEVICE_STATE_VALID != atapiParams->dsDeviceState[nCurrentDrive] )
  1049. {
  1050. // atapi module has marked its presence or the device is absent
  1051. continue ;
  1052. }
  1053. // select the possibly present device
  1054. if ( nCurrentDrive )
  1055. {
  1056. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_SLAVE ) ;
  1057. }
  1058. else
  1059. {
  1060. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER ) ;
  1061. }
  1062. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  1063. {
  1064. // as busy has permanently set after master/slave, we fail the
  1065. // detection process
  1066. continue ;
  1067. }
  1068. // issue the ata NOP command
  1069. ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATA_NOP_COMMAND) ;
  1070. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  1071. {
  1072. // as busy has permanently set, we fail the detection process
  1073. continue ;
  1074. }
  1075. byTempValue = (UCHAR) ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) ;
  1076. if ( ( byTempValue != BUS_LINES_IN_HIGH_IMPEDANCE ) &&\
  1077. ( byTempValue & ATA_ST_ERROR ) )
  1078. {
  1079. // as the bus is not reading 0xFF and the status register
  1080. // indicates an error, this is likely to be an ATA device
  1081. if ( ATA_ERROR_ABORTED_COMMAND == ( (UCHAR) ParStlReadIoPort ( Extension, ATA_ERROR_REG ) & 0x0F ) )
  1082. {
  1083. // as the error register, contains the ata aborted error
  1084. // in response to our ATA NOP command, we conclude that
  1085. // it is ATA! as it is already known that it is not ATAPI
  1086. bReturnValue = TRUE ;
  1087. break;
  1088. }
  1089. }
  1090. }
  1091. while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
  1092. // reset back to master state, as check drive present
  1093. // will be called successively
  1094. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  1095. return ( bReturnValue ) ;
  1096. }
  1097. BOOLEAN
  1098. ParStlWaitForBusyToClear (
  1099. IN PPDO_EXTENSION Extension,
  1100. IN int nRegisterToWaitOn
  1101. )
  1102. {
  1103. // The default timeout increased to 10secs as Fujitsu MO is found to set
  1104. // BUSY for >5secs for 0xA1 command.
  1105. int nMaxRetrials = MAX_RETRIES_FOR_10_SECS ;
  1106. BOOLEAN bRetVal = FALSE ;
  1107. while ( nMaxRetrials-- )
  1108. {
  1109. // the following service will be implemented by the caller
  1110. // the driver can use the STLMPORT service.
  1111. ParStlWaitForMicroSeconds ( DELAY_1MILLISECONDS ) ;
  1112. if ( ! ( ParStlReadIoPort ( Extension, nRegisterToWaitOn ) & ATA_ST_BUSY ) )
  1113. {
  1114. // as busy has cleared, we return clear here
  1115. bRetVal = TRUE ;
  1116. break ;
  1117. }
  1118. }
  1119. return bRetVal ;
  1120. }
  1121. BOOLEAN
  1122. ParStlWaitForDrq (
  1123. IN PPDO_EXTENSION Extension
  1124. )
  1125. {
  1126. int nMaxRetrials = MAX_RETRIES_FOR_5_SECS ;
  1127. BOOLEAN bRetVal = FALSE ;
  1128. while ( nMaxRetrials-- )
  1129. {
  1130. if ( ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) & ATA_ST_DRQ )
  1131. {
  1132. // as busy has cleared, we return clear here
  1133. bRetVal = TRUE ;
  1134. break ;
  1135. }
  1136. // the following service will be implemented by the caller
  1137. // the driver can use the STLMPORT service.
  1138. ParStlWaitForMicroSeconds ( DELAY_1MILLISECONDS ) ;
  1139. }
  1140. return bRetVal ;
  1141. }
  1142. BOOLEAN
  1143. ParStlWaitForIrq (
  1144. IN PPDO_EXTENSION Extension
  1145. )
  1146. {
  1147. int nMaxRetrials = MAX_RETRIES_FOR_10_SECS ;
  1148. BOOLEAN bRetVal = FALSE ;
  1149. while ( nMaxRetrials-- )
  1150. {
  1151. if ( ParStlReadReg ( Extension, EP1284_TRANSFER_CONTROL_REG ) & XFER_IRQ_BIT )
  1152. {
  1153. // as Irq has asserted, we return true here
  1154. bRetVal = TRUE ;
  1155. break ;
  1156. }
  1157. ParStlWaitForMicroSeconds ( DELAY_1MILLISECONDS ) ;
  1158. }
  1159. return bRetVal ;
  1160. }
  1161. VOID
  1162. ParStlSet16BitOperation (
  1163. IN PPDO_EXTENSION Extension
  1164. )
  1165. {
  1166. int nModeReg ;
  1167. nModeReg = ParStlReadReg ( Extension, EP1284_MODE_REGISTER ) ;
  1168. if ( 0 == ( nModeReg & EP1284_ENABLE_16BIT ) )
  1169. {
  1170. // as the bit is not already set, this needs to be set now
  1171. ParStlWriteReg ( Extension, EP1284_MODE_REGISTER, nModeReg | EP1284_ENABLE_16BIT ) ;
  1172. }
  1173. }
  1174. BOOLEAN
  1175. ParStlCheckIfEppDevice (
  1176. IN PPDO_EXTENSION Extension
  1177. )
  1178. {
  1179. BOOLEAN bReturnValue = FALSE;
  1180. do
  1181. {
  1182. if ( FALSE == IsEp1284Present() )
  1183. {
  1184. // as EPPDEVs live only on EP1284 we break here
  1185. break;
  1186. }
  1187. bReturnValue = ParStlCheckPersonalityForEppDevice(Extension) ;
  1188. }
  1189. while ( FALSE ) ;
  1190. return bReturnValue ;
  1191. }
  1192. BOOLEAN
  1193. ParStlCheckPersonalityForEppDevice (
  1194. IN PPDO_EXTENSION Extension
  1195. )
  1196. {
  1197. BOOLEAN bReturnValue = FALSE ;
  1198. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, EP1284_PERSONALITY_REG ) ;
  1199. if ( EPPDEV_SIGN == ( ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) & PERSONALITY_MASK ) )
  1200. {
  1201. // as the EPPDEV sign is found in the personality
  1202. // we break with success here
  1203. bReturnValue = TRUE ;
  1204. }
  1205. return bReturnValue ;
  1206. }
  1207. BOOLEAN
  1208. ParStlCheckIfFlash (
  1209. IN PPDO_EXTENSION Extension
  1210. )
  1211. {
  1212. BOOLEAN bReturnValue = FALSE ;
  1213. do
  1214. {
  1215. if ( !IsEp1284Present() && !IsImpactPresent() && !IsEpatPlusPresent() )
  1216. {
  1217. // Check the sign-on version checks for the existence of Shuttle
  1218. // adapter. If nothing is found, we break here.
  1219. break ;
  1220. }
  1221. // Perform a ATA-16bit check just in case, it turns out to be something else
  1222. bReturnValue = ParStlCheckFlashPersonality(Extension) ;
  1223. }
  1224. while ( FALSE ) ;
  1225. return bReturnValue ;
  1226. }
  1227. BOOLEAN
  1228. ParStlCheckFlashPersonality (
  1229. IN PPDO_EXTENSION Extension
  1230. )
  1231. {
  1232. BOOLEAN bReturnValue = FALSE ;
  1233. if ( IsEp1284Present() )
  1234. {
  1235. // as the personality configuration check only works for
  1236. // Ep1284, confim its presence before the actual check.
  1237. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, EP1284_PERSONALITY_REG ) ;
  1238. if ( FLASH_SIGN == ( ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) & FLASH_PERSONALITY_MASK ) )
  1239. {
  1240. // as the flash sign ATA-16bit device is found in the personality
  1241. // we break with success here
  1242. bReturnValue = TRUE ;
  1243. }
  1244. }
  1245. else
  1246. {
  1247. // always return true, if a shuttle adapter other than ep1284 is
  1248. // identified and assume it might be flash!
  1249. bReturnValue = TRUE ;
  1250. }
  1251. return bReturnValue ;
  1252. }
  1253. BOOLEAN
  1254. ParStlCheckIfDazzle (
  1255. IN PPDO_EXTENSION Extension
  1256. )
  1257. {
  1258. BOOLEAN bReturnValue = FALSE ;
  1259. UCHAR ucSignature ;
  1260. do
  1261. {
  1262. if ( !IsEp1284Present() )
  1263. {
  1264. // Check for EP1284 presence, as Dazzle is ONLY on EP1284
  1265. // adapters. If the adapter is not EP1284, we break.
  1266. break ;
  1267. }
  1268. // Check whether any card insertion is detected, to eliminate
  1269. // possible flash adapters with the card in
  1270. if ( TRUE == ParStlCheckCardInsertionStatus( Extension ) ) {
  1271. break ;
  1272. }
  1273. // code to read the pulled up pattern present on dazzle
  1274. // adapters.
  1275. ParStlWriteReg( Extension, DAZ_SELECT_BLK, DAZ_BLK0 ) ;
  1276. ucSignature = (UCHAR) ParStlReadReg( Extension, DAZ_REG1 ) ;
  1277. if ( ( ucSignature == DAZ_CONFIGURED ) ||\
  1278. ( ucSignature == DAZ_NOT_CONFIGURED ) ) {
  1279. // the pulled up pattern generally found ONLY
  1280. // on the DAZZLE adapter is found. So, we
  1281. // conclude that it is a Dazzle adapter
  1282. bReturnValue = TRUE ;
  1283. }
  1284. }
  1285. while ( FALSE ) ;
  1286. return bReturnValue ;
  1287. }
  1288. BOOLEAN
  1289. ParStlCheckIfHiFD (
  1290. IN PPDO_EXTENSION Extension
  1291. )
  1292. {
  1293. BOOLEAN bReturnValue = FALSE;
  1294. do
  1295. {
  1296. if ( FALSE == ParStlSelectAdapterSocket(Extension, SOCKET_1) )
  1297. {
  1298. // as the socket 1 selection failed,
  1299. // we break out here.
  1300. break ;
  1301. }
  1302. // check for the ready status of the floppy controller,
  1303. // after clearing the reset bit of the floppy controller.
  1304. if ( FALSE == ParStlHIFDCheckIfControllerReady(Extension) )
  1305. {
  1306. // since the controller didnot wake up after the
  1307. // reset pin was asserted, we break here.
  1308. break ;
  1309. }
  1310. if ( FALSE == ParStlHIFDCheckSMCController(Extension) )
  1311. {
  1312. // as the SMC ID retrieval failed,
  1313. // we break out here.
  1314. break ;
  1315. }
  1316. bReturnValue = TRUE ;
  1317. }
  1318. while ( FALSE ) ;
  1319. // Reset the socket to zero.
  1320. ParStlSelectAdapterSocket(Extension, SOCKET_0);
  1321. return bReturnValue ;
  1322. }
  1323. BOOLEAN
  1324. ParStlHIFDCheckIfControllerReady (
  1325. IN PPDO_EXTENSION Extension
  1326. )
  1327. {
  1328. BOOLEAN bReturnValue = FALSE ;
  1329. UCHAR bySCRControlReg ;
  1330. do
  1331. {
  1332. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
  1333. bySCRControlReg = (UCHAR) ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
  1334. bySCRControlReg |= (UCHAR)PERIPHERAL_RESET_1 ;
  1335. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  1336. ParStlWaitForMicroSeconds ( HIFD_WAIT_10_MILLISEC ) ;
  1337. ParStlWriteIoPort ( Extension, HIFD_DIGITAL_OUTPUT_REGISTER ,
  1338. 0x00 ) ;
  1339. ParStlWaitForMicroSeconds ( HIFD_WAIT_1_MILLISEC ) ;
  1340. ParStlWriteIoPort ( Extension, HIFD_DIGITAL_OUTPUT_REGISTER ,
  1341. HIFD_DOR_RESET_BIT | HIFD_ENABLE_DMA_BIT ) ;
  1342. ParStlWaitForMicroSeconds ( HIFD_WAIT_10_MILLISEC ) ;
  1343. if ( HIFD_CONTROLLER_READY_STATUS == ParStlReadIoPort ( Extension, HIFD_MAIN_STATUS_REGISTER ) )
  1344. {
  1345. bReturnValue = TRUE ;
  1346. }
  1347. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_1 ;
  1348. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  1349. }
  1350. while ( FALSE ) ;
  1351. return bReturnValue ;
  1352. }
  1353. BOOLEAN
  1354. ParStlHIFDCheckSMCController (
  1355. IN PPDO_EXTENSION Extension
  1356. )
  1357. {
  1358. BOOLEAN bReturnValue = FALSE ;
  1359. do
  1360. {
  1361. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_COMMAND_TO_CONTROLLER ) ;
  1362. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_COMMAND_TO_CONTROLLER ) ;
  1363. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_CTL_REG_0D ) ;
  1364. if ( SMC_DEVICE_ID == ParStlReadIoPort ( Extension, HIFD_STATUS_REGISTER_B ) )
  1365. {
  1366. bReturnValue = TRUE ;
  1367. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_CTL_REG_03 ) ;
  1368. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_B , SMC_ENABLE_MODE2 ) ;
  1369. }
  1370. ParStlWriteReg ( Extension, HIFD_STATUS_REGISTER_A , HIFD_TERMINATE_SEQUENCE ) ;
  1371. }
  1372. while ( FALSE ) ;
  1373. return bReturnValue ;
  1374. }
  1375. STL_DEVICE_TYPE
  1376. ParStlGetImpactDeviceType (
  1377. IN PPDO_EXTENSION Extension,
  1378. IN OUT PATAPIPARAMS atapiParams,
  1379. IN int nPreferredDeviceType
  1380. )
  1381. {
  1382. IMPACT_DEVICE_TYPE idtImpactDeviceType ;
  1383. STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
  1384. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, IMPACT_PERSONALITY_REG ) ;
  1385. idtImpactDeviceType = ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) >> 4 ;
  1386. switch ( idtImpactDeviceType )
  1387. {
  1388. case IMPACT_DEVICE_TYPE_ATA_ATAPI:
  1389. // set the 16 bit mode of the adapter
  1390. ParStlSet16BitOperation(Extension) ;
  1391. if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension,atapiParams))
  1392. {
  1393. // necessary but not sufficient condition has passed
  1394. // proceed for sufficency checks
  1395. if (TRUE == ParStlCheckIfAtapiDevice(Extension,atapiParams))
  1396. {
  1397. // atapi identified
  1398. // Check for Impact LS-120 device
  1399. if ( TRUE == ParStlCheckIfImpactLS120(Extension, atapiParams))
  1400. {
  1401. dtDeviceType |= DEVICE_TYPE_LS120_BIT ;
  1402. break ;
  1403. }
  1404. dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
  1405. break ;
  1406. }
  1407. if (TRUE == ParStlCheckIfAtaDevice(Extension, atapiParams))
  1408. {
  1409. // ata identified
  1410. dtDeviceType |= DEVICE_TYPE_ATA_BIT;
  1411. break;
  1412. }
  1413. }
  1414. break ;
  1415. case IMPACT_DEVICE_TYPE_CF:
  1416. dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
  1417. break ;
  1418. case IMPACT_DEVICE_TYPE_PCMCIA_CF:
  1419. dtDeviceType |= DEVICE_TYPE_PCMCIA_CF_BIT ;
  1420. break;
  1421. case IMPACT_DEVICE_TYPE_SSFDC:
  1422. dtDeviceType |= DEVICE_TYPE_SSFDC_BIT ;
  1423. break;
  1424. case IMPACT_DEVICE_TYPE_MMC:
  1425. dtDeviceType |= DEVICE_TYPE_MMC_BIT ;
  1426. break;
  1427. case IMPACT_DEVICE_TYPE_HIFD:
  1428. dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
  1429. break;
  1430. case IMPACT_DEVICE_TYPE_SOUND:
  1431. dtDeviceType |= DEVICE_TYPE_SOUND_BIT ;
  1432. break;
  1433. case IMPACT_DEVICE_TYPE_FLP_TAPE_DSK:
  1434. dtDeviceType |= DEVICE_TYPE_FLP_TAPE_DSK_BIT ;
  1435. break;
  1436. case IMPACT_DEVICE_TYPE_ATA_ATAPI_8BIT:
  1437. dtDeviceType |= DEVICE_TYPE_ATA_ATAPI_8BIT_BIT ;
  1438. break;
  1439. default:
  1440. break;
  1441. }
  1442. return dtDeviceType & nPreferredDeviceType ;
  1443. }
  1444. STL_DEVICE_TYPE
  1445. ParStlGetImpactSDeviceType (
  1446. IN PPDO_EXTENSION Extension,
  1447. IN OUT PATAPIPARAMS atapiParams,
  1448. IN int nPreferredDeviceType
  1449. )
  1450. {
  1451. IMPACT_DEVICE_TYPE idtImpactDeviceType ;
  1452. IMPACT_DEVICE_TYPE idtImpactSDeviceType ;
  1453. STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
  1454. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, IMPACT_PERSONALITY_REG ) ;
  1455. idtImpactDeviceType = ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) >> 4 ;
  1456. switch ( idtImpactDeviceType )
  1457. {
  1458. case IMPACT_DEVICE_TYPE_ATA_ATAPI:
  1459. // set the 16 bit mode of the adapter
  1460. ParStlSet16BitOperation(Extension) ;
  1461. if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension,atapiParams))
  1462. {
  1463. // necessary but not sufficient condition has passed
  1464. // proceed for sufficency checks
  1465. if (TRUE == ParStlCheckIfAtapiDevice(Extension,atapiParams))
  1466. {
  1467. // atapi identified
  1468. dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
  1469. break ;
  1470. }
  1471. if (TRUE == ParStlCheckIfAtaDevice(Extension,atapiParams))
  1472. {
  1473. // ata identified
  1474. dtDeviceType |= DEVICE_TYPE_ATA_BIT;
  1475. break;
  1476. }
  1477. }
  1478. break ;
  1479. case IMPACT_DEVICE_TYPE_CF:
  1480. dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
  1481. break ;
  1482. case IMPACT_DEVICE_TYPE_PCMCIA_CF:
  1483. dtDeviceType |= DEVICE_TYPE_PCMCIA_CF_BIT ;
  1484. break;
  1485. case IMPACT_DEVICE_TYPE_SSFDC:
  1486. dtDeviceType |= DEVICE_TYPE_SSFDC_BIT ;
  1487. break;
  1488. case IMPACT_DEVICE_TYPE_MMC:
  1489. dtDeviceType |= DEVICE_TYPE_MMC_BIT ;
  1490. break;
  1491. case IMPACT_DEVICE_TYPE_HIFD:
  1492. dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
  1493. break;
  1494. case IMPACT_DEVICE_TYPE_SOUND:
  1495. dtDeviceType |= DEVICE_TYPE_SOUND_BIT ;
  1496. break;
  1497. case IMPACT_DEVICE_TYPE_FLP_TAPE_DSK:
  1498. dtDeviceType |= DEVICE_TYPE_FLP_TAPE_DSK_BIT ;
  1499. break;
  1500. case IMPACT_DEVICE_TYPE_ATA_ATAPI_8BIT:
  1501. dtDeviceType |= DEVICE_TYPE_ATA_ATAPI_8BIT_BIT ;
  1502. break;
  1503. case IMPACTS_EXT_PERSONALITY_PRESENT:
  1504. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, IMPACTS_EXT_PERSONALITY_XREG ) ;
  1505. idtImpactSDeviceType = ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
  1506. dtDeviceType = DEVICE_TYPE_EXT_HWDETECT ;
  1507. dtDeviceType |= idtImpactSDeviceType ;
  1508. break ;
  1509. default:
  1510. break;
  1511. }
  1512. return dtDeviceType & nPreferredDeviceType ;
  1513. }
  1514. BOOLEAN
  1515. ParStlCheckIfLS120 (
  1516. IN PPDO_EXTENSION Extension
  1517. )
  1518. {
  1519. BOOLEAN bReturnValue = FALSE;
  1520. do
  1521. {
  1522. if ( FALSE == ParStlSelectAdapterSocket(Extension, SOCKET_1) )
  1523. {
  1524. // as the socket 1 selection failed,
  1525. // we break out here.
  1526. break ;
  1527. }
  1528. // check for engine version.
  1529. if ( LS120_ENGINE_VERSION == ParStlReadIoPort( Extension, LS120_ENGINE_VERSION_REGISTER ) )
  1530. {
  1531. // if the ls120 engine version is correct, we have
  1532. // found LS120.
  1533. bReturnValue = TRUE ;
  1534. }
  1535. // Reset the socket to zero.
  1536. ParStlSelectAdapterSocket ( Extension, SOCKET_0 ) ;
  1537. }
  1538. while ( FALSE ) ;
  1539. return bReturnValue ;
  1540. }
  1541. BOOLEAN
  1542. ParStlCheckIfImpactLS120 (
  1543. IN PPDO_EXTENSION Extension,
  1544. IN OUT PATAPIPARAMS atapiParams
  1545. )
  1546. {
  1547. BOOLEAN bReturnValue = FALSE ;
  1548. BOOLEAN bLs120NameFound= TRUE ;
  1549. char chLs120Name[] = "HU DlFpoyp";
  1550. char *pszAtapiName = atapiParams->szAtapiNameString ;
  1551. int i , nMemoryOnBoard ;
  1552. do
  1553. {
  1554. for ( i = 0 ;i < sizeof(chLs120Name)-1 ; i++ )
  1555. {
  1556. if ( pszAtapiName[i] != chLs120Name[i] )
  1557. {
  1558. bLs120NameFound = FALSE ;
  1559. break ;
  1560. }
  1561. }
  1562. if ( TRUE != bLs120NameFound )
  1563. {
  1564. // as LS-120 name string is not found, we conclude that it is
  1565. // not LS-120
  1566. break ;
  1567. }
  1568. nMemoryOnBoard = ParStlGetMemorySize(Extension) ;
  1569. if ( ( !IsShtlError ( nMemoryOnBoard ) ) && \
  1570. ( nMemoryOnBoard ) )
  1571. {
  1572. // there is memory on-board.
  1573. // hence, we return ls120 here
  1574. bReturnValue = TRUE ;
  1575. break ;
  1576. }
  1577. }
  1578. while ( FALSE ) ;
  1579. return bReturnValue ;
  1580. }
  1581. BOOLEAN
  1582. ParStlCheckIfMMC (
  1583. IN PPDO_EXTENSION Extension,
  1584. IN OUT PATAPIPARAMS atapiParams
  1585. )
  1586. {
  1587. BOOLEAN bReturnValue = FALSE;
  1588. do
  1589. {
  1590. if ( FALSE == IsEpatPlusPresent() )
  1591. {
  1592. // as mmc device can exist only on EPAT Plus adapter only
  1593. // we break out of here
  1594. break;
  1595. }
  1596. if ( TRUE == ParStlCheckIfAtaAtapiDevice (Extension,atapiParams) )
  1597. {
  1598. // as an ATA/ATAPI device is probably present,
  1599. // we break out of here
  1600. break;
  1601. }
  1602. bReturnValue = ParStlIsMMCEnginePresent(Extension) ;
  1603. }
  1604. while ( FALSE ) ;
  1605. return bReturnValue ;
  1606. }
  1607. BOOLEAN
  1608. ParStlIsMMCEnginePresent(
  1609. IN PPDO_EXTENSION Extension
  1610. )
  1611. {
  1612. BOOLEAN bReturnValue = FALSE;
  1613. do
  1614. {
  1615. // check if the ATAPI signature is present in the cyl hi/lo
  1616. // registers. If present, it is definitely an ATAPI device
  1617. if ( ( ParStlReadIoPort(Extension, CYLLOW_REG) == ATAPI_SIGN_LOW ) &&\
  1618. ( ParStlReadIoPort(Extension, CYLHIGH_REG) == ATAPI_SIGN_HI ) )
  1619. {
  1620. // as ATAPI signature is present, it cant be MMC
  1621. break ;
  1622. }
  1623. // write a zero pattern ( which will be a NOP for ATA/ATAPI devices )
  1624. // in the block size / possible ATA/ATAPI command register
  1625. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_BLOCK_SIZE_REG);
  1626. ParStlWriteReg(Extension, MMC_ENGINE_DATA, MMC_TEST_PATTERN_1);
  1627. if ( MMC_TEST_PATTERN_1 != ParStlReadReg(Extension, MMC_ENGINE_DATA) )
  1628. {
  1629. // as the written value is not available, it means device present
  1630. // has responded to the written value, in a way different from
  1631. // how an MMC would have.
  1632. break ;
  1633. }
  1634. // write a test pattern in the freq register
  1635. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_FREQ_SELECT_REG);
  1636. ParStlWriteReg(Extension, MMC_ENGINE_DATA, MMC_TEST_PATTERN_2);
  1637. // write another in the block size register
  1638. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_BLOCK_SIZE_REG);
  1639. ParStlWriteReg(Extension, MMC_ENGINE_DATA, MMC_TEST_PATTERN_3);
  1640. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_FREQ_SELECT_REG);
  1641. if ( MMC_TEST_PATTERN_2 != ParStlReadReg(Extension, MMC_ENGINE_DATA) )
  1642. {
  1643. // as we were not able to read back the written value
  1644. // we quit here
  1645. break;
  1646. }
  1647. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_BLOCK_SIZE_REG);
  1648. if ( MMC_TEST_PATTERN_3 != ParStlReadReg(Extension, MMC_ENGINE_DATA) )
  1649. {
  1650. // as we were not able to read back the written value
  1651. // we quit here
  1652. break;
  1653. }
  1654. // as all tests have passed, engine presence is confirmed
  1655. // here
  1656. bReturnValue = TRUE ;
  1657. }
  1658. while ( FALSE ) ;
  1659. return bReturnValue ;
  1660. }
  1661. BOOLEAN
  1662. ParStlCheckIfScsiDevice (
  1663. IN PPDO_EXTENSION Extension
  1664. )
  1665. {
  1666. BOOLEAN bReturnValue = FALSE;
  1667. do
  1668. {
  1669. if ( FALSE == IsEpstPresent() )
  1670. {
  1671. // as SCSI devices live only on EPST we break here
  1672. break;
  1673. }
  1674. bReturnValue = TRUE ;
  1675. }
  1676. while ( FALSE ) ;
  1677. return bReturnValue ;
  1678. }
  1679. BOOLEAN
  1680. ParStlCheckIfSSFDC (
  1681. IN PPDO_EXTENSION Extension
  1682. )
  1683. {
  1684. BOOLEAN bReturnValue = FALSE;
  1685. do
  1686. {
  1687. if ( FALSE == IsEp1284Present() )
  1688. {
  1689. // SSFDC lives on EP1284 alone, other than impact
  1690. // which is already taken care
  1691. break;
  1692. }
  1693. //check to see if the loop back of the EPCS and EPDO pins
  1694. //of the INDEX 00 register read the same. If so, it is
  1695. //SSFDC board characteristic
  1696. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , 0x00 ) ;
  1697. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , 0x10 ) ;
  1698. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , 0x12 ) ;
  1699. if ( 0x1A == ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) )
  1700. {
  1701. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , 0x10 ) ;
  1702. if ( ! ( ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) & 0x08 ) )
  1703. {
  1704. //as they are equal, SSFDC present
  1705. bReturnValue = TRUE ;
  1706. break ;
  1707. }
  1708. }
  1709. }
  1710. while ( FALSE ) ;
  1711. return bReturnValue ;
  1712. }
  1713. VOID
  1714. ParStlAssertIdleState (
  1715. IN PPDO_EXTENSION Extension
  1716. )
  1717. {
  1718. PUCHAR CurrentPort, CurrentControl ;
  1719. ULONG Delay = 5 ;
  1720. CurrentPort = Extension->Controller;
  1721. CurrentControl = CurrentPort + 2;
  1722. // place op-code for idle state in port base
  1723. P5WritePortUchar ( CurrentPort, (UCHAR) 0x00 ) ;
  1724. KeStallExecutionProcessor( Delay );
  1725. // bring down DCR_INIT and DCR_STROBE
  1726. P5WritePortUchar ( CurrentControl, (UCHAR) STB_INIT_LOW ) ;
  1727. KeStallExecutionProcessor( Delay );
  1728. // lift DCR_INIT and DCR_STROBE to high
  1729. P5WritePortUchar ( CurrentControl, (UCHAR) STB_INIT_AFXT_HI ) ;
  1730. KeStallExecutionProcessor( Delay );
  1731. }
  1732. BOOLEAN
  1733. ParStlCheckAvisionScannerPresence(
  1734. IN PPDO_EXTENSION Extension
  1735. )
  1736. {
  1737. BOOLEAN bReturnValue = FALSE ;
  1738. UCHAR data;
  1739. do {
  1740. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1741. if((data & 0x80) == 0) {
  1742. break ;
  1743. }
  1744. ParStlWriteReg( Extension, CONTROLPORT, 0x08 ) ;
  1745. ParStlWriteReg( Extension, CONTROLPORT, 0x08 ) ;
  1746. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1747. if((data & 0x80) != 0) {
  1748. break ;
  1749. }
  1750. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1751. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1752. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1753. if((data & 0x80) == 0) {
  1754. break ;
  1755. }
  1756. ParStlWriteReg( Extension, CONTROLPORT, 0x02 ) ;
  1757. ParStlWriteReg( Extension, CONTROLPORT, 0x02 ) ;
  1758. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1759. if((data & 0x80) != 0) {
  1760. break ;
  1761. }
  1762. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1763. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1764. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1765. if((data & 0x80) == 0) {
  1766. break ;
  1767. }
  1768. bReturnValue = TRUE ;
  1769. } while ( FALSE ) ;
  1770. return bReturnValue ;
  1771. }
  1772. BOOLEAN
  1773. ParStlCheckUMAXScannerPresence(
  1774. IN PPDO_EXTENSION Extension
  1775. )
  1776. {
  1777. UCHAR commandPacket_[6] = {0x55,0xaa,0,0,0,0} ;
  1778. PUCHAR commandPacket ;
  1779. USHORT status;
  1780. UCHAR idx;
  1781. PUCHAR saveCommandPacket;
  1782. ULONG dataLength;
  1783. ParStlWriteReg ( Extension, CONTROLPORT, 0 ) ; // scannner reset
  1784. KeStallExecutionProcessor ( 2000 ) ; // 2 m.secs delay
  1785. ParStlWriteReg ( Extension, CONTROLPORT, 0x0C ) ;
  1786. commandPacket = commandPacket_ ;
  1787. saveCommandPacket = commandPacket;
  1788. if ( TRUE == ParStlSetEPPMode(Extension) ) {
  1789. commandPacket+=2;
  1790. dataLength = *(ULONG*)commandPacket;
  1791. dataLength &= 0xffffff; //data bytes ordering (msb to lsb) will
  1792. // wrong .What we need here is whether the
  1793. // dataLength is 0 or not.
  1794. commandPacket = saveCommandPacket;
  1795. //Command phase
  1796. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1797. if((status & 0x700) != 0){
  1798. return FALSE; //TIMEOUT_ERROR);
  1799. }
  1800. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1801. if((status & 0x700 ) != 0){
  1802. return FALSE; //TIMEOUT_ERROR);
  1803. }
  1804. for(idx=0; idx<= 6 ;idx++){
  1805. if(status & 0x800){
  1806. break;
  1807. }
  1808. status = ParStlEPPRead(Extension);
  1809. }
  1810. if(idx == 7){
  1811. status = (status & 0xf800) | 0x100;
  1812. if ( status & 0x700 )
  1813. return FALSE;
  1814. }
  1815. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1816. if((status & 0x700 ) != 0){
  1817. return FALSE; //TIMEOUT_ERROR);
  1818. }
  1819. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1820. if((status & 0x700 ) != 0){
  1821. return FALSE; //TIMEOUT_ERROR);
  1822. }
  1823. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1824. if((status & 0x700 ) != 0){
  1825. return FALSE; //TIMEOUT_ERROR);
  1826. }
  1827. status = ParStlEPPWrite(Extension, *commandPacket);
  1828. if((status & 0x700 ) != 0){
  1829. return FALSE; //TIMEOUT_ERROR);
  1830. }
  1831. //Response phase
  1832. status = ParStlEPPRead(Extension);
  1833. commandPacket = saveCommandPacket;
  1834. if((status & 0x700) == 0){
  1835. if((commandPacket[5] == 0xc2)&& (dataLength == 0)){
  1836. status = ParStlEPPRead(Extension);
  1837. if((status & 0x0700) != 0){
  1838. return FALSE; //TIMEOUT_ERROR);
  1839. }
  1840. }
  1841. }
  1842. return TRUE;
  1843. }
  1844. return FALSE;
  1845. }
  1846. BOOLEAN
  1847. ParStlSetEPPMode(
  1848. IN PPDO_EXTENSION Extension
  1849. )
  1850. {
  1851. UCHAR idx;
  1852. BOOLEAN timeout = TRUE ;
  1853. ParStlWriteReg( Extension, CONTROLPORT, 0x0C ) ;
  1854. ParStlWriteReg( Extension, DATAPORT, 0x40 ) ;
  1855. ParStlWriteReg( Extension, CONTROLPORT, 0x06 ) ;
  1856. for(idx=0; idx<10; idx++){
  1857. if((ParStlReadReg(Extension, STATUSPORT) & 0x78) == 0x38){
  1858. timeout = FALSE;
  1859. break;
  1860. }
  1861. }
  1862. if(timeout == FALSE){
  1863. ParStlWriteReg( Extension, CONTROLPORT,0x7 );
  1864. timeout = TRUE;
  1865. for(idx=0; idx<10; idx++){
  1866. if((ParStlReadReg( Extension, STATUSPORT) & 0x78) == 0x38){
  1867. timeout = FALSE;
  1868. break;
  1869. }
  1870. }
  1871. if(timeout == FALSE){
  1872. ParStlWriteReg( Extension, CONTROLPORT,0x4 ) ;
  1873. timeout = TRUE;
  1874. for(idx=0; idx<10; idx++){
  1875. if((ParStlReadReg( Extension, STATUSPORT) & 0xf8) == 0xf8){
  1876. timeout = FALSE;
  1877. break;
  1878. }
  1879. }
  1880. if(timeout == FALSE){
  1881. timeout = TRUE;
  1882. ParStlWriteReg( Extension, CONTROLPORT, 0x5 );
  1883. for(idx=0; idx<10; idx++){
  1884. if( ParStlReadReg( Extension, CONTROLPORT ) == 0x5){
  1885. timeout = FALSE;
  1886. break;
  1887. }
  1888. }
  1889. if(timeout == FALSE){
  1890. ParStlWriteReg( Extension, CONTROLPORT, 0x84) ;
  1891. return TRUE ;
  1892. } // final check
  1893. } // third check
  1894. } // second check
  1895. } // first check
  1896. return(FALSE);
  1897. }
  1898. USHORT
  1899. ParStlEPPWrite(
  1900. IN PPDO_EXTENSION Extension,
  1901. IN UCHAR value
  1902. )
  1903. {
  1904. UCHAR idx;
  1905. USHORT statusData = 0;
  1906. BOOLEAN timeout;
  1907. timeout = TRUE;
  1908. for(idx=0; idx<10; idx++){
  1909. if( !( (statusData = (USHORT)ParStlReadReg( Extension, STATUSPORT)) & BUSY)){
  1910. timeout = FALSE;
  1911. break;
  1912. }
  1913. }
  1914. if(timeout == TRUE){
  1915. return(((statusData<<8) & 0xf800)|0x100);
  1916. }
  1917. ParStlWriteReg( Extension, EPPDATA0PORT,value );
  1918. return(((statusData & 0xf8) << 8)|value);
  1919. }
  1920. USHORT
  1921. ParStlEPPRead(
  1922. IN PPDO_EXTENSION Extension
  1923. )
  1924. {
  1925. UCHAR idx;
  1926. UCHAR eppData;
  1927. USHORT statusData = 0;
  1928. BOOLEAN timeout = TRUE ;
  1929. for(idx=0; idx<10; idx++){
  1930. if(!( (statusData = (USHORT)ParStlReadReg( Extension, STATUSPORT)) & PE)){
  1931. timeout = FALSE;
  1932. break;
  1933. }
  1934. }
  1935. if(timeout == TRUE){
  1936. return(((statusData<<8) & 0xf800)|0x100);
  1937. }
  1938. eppData = (UCHAR)ParStlReadReg( Extension, EPPDATA0PORT) ;
  1939. return(((statusData & 0x00f8)<<8) | eppData );
  1940. }
  1941. int __cdecl
  1942. ParStlReadReg (
  1943. IN PPDO_EXTENSION Extension,
  1944. IN unsigned reg
  1945. )
  1946. {
  1947. UCHAR byReadNibble ;
  1948. PUCHAR CurrentPort, CurrentStatus, CurrentControl ;
  1949. ULONG Delay = 5 ;
  1950. CurrentPort = Extension->Controller;
  1951. CurrentStatus = CurrentPort + 1;
  1952. CurrentControl = CurrentPort + 2;
  1953. // select the register to read
  1954. P5WritePortUchar ( CurrentPort, (UCHAR)reg ) ;
  1955. KeStallExecutionProcessor( Delay );
  1956. // issue nibble ctl signals to read
  1957. P5WritePortUchar ( CurrentControl, STB_INIT_LOW ) ;
  1958. KeStallExecutionProcessor( Delay );
  1959. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_LO ) ;
  1960. KeStallExecutionProcessor( Delay );
  1961. // read first nibble
  1962. byReadNibble = P5ReadPortUchar (CurrentStatus);
  1963. KeStallExecutionProcessor( Delay );
  1964. byReadNibble >>= 4 ;
  1965. // issue nibble ctl signals to read
  1966. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_HI ) ;
  1967. KeStallExecutionProcessor( Delay );
  1968. // read next nibble
  1969. byReadNibble |= ( P5ReadPortUchar ( CurrentStatus ) & 0xF0 ) ;
  1970. return (int)byReadNibble ;
  1971. }
  1972. int __cdecl
  1973. ParStlWriteReg (
  1974. IN PPDO_EXTENSION Extension,
  1975. IN unsigned reg,
  1976. IN int databyte
  1977. )
  1978. {
  1979. PUCHAR CurrentPort, CurrentStatus, CurrentControl ;
  1980. ULONG Delay = 5 ;
  1981. CurrentPort = Extension->Controller;
  1982. CurrentStatus = CurrentPort + 1;
  1983. CurrentControl = CurrentPort + 2;
  1984. // select the register to write
  1985. P5WritePortUchar ( CurrentPort, (UCHAR)( reg | 0x60 ) ) ;
  1986. KeStallExecutionProcessor( Delay );
  1987. // write to printer ctl port
  1988. P5WritePortUchar ( CurrentControl, STB_INIT_LOW ) ;
  1989. KeStallExecutionProcessor( Delay );
  1990. // write the requested data
  1991. P5WritePortUchar ( CurrentPort, (UCHAR)databyte ) ;
  1992. KeStallExecutionProcessor( Delay );
  1993. // write to printer ctl port
  1994. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_HI ) ;
  1995. KeStallExecutionProcessor( Delay );
  1996. return SHTL_NO_ERROR ;
  1997. }
  1998. int __cdecl
  1999. ParStlReceiveData (
  2000. IN PPDO_EXTENSION Extension,
  2001. IN VOID *hostBufferPointer,
  2002. IN long shuttleMemoryAddress,
  2003. IN unsigned count
  2004. )
  2005. {
  2006. PCHAR pchDataBuffer = (PCHAR) hostBufferPointer ;
  2007. unsigned int i = 0 ;
  2008. PUCHAR CurrentPort, CurrentStatus, CurrentControl ;
  2009. ULONG Delay = 5 ;
  2010. UNREFERENCED_PARAMETER( shuttleMemoryAddress );
  2011. CurrentPort = Extension->Controller;
  2012. CurrentStatus = CurrentPort + 1;
  2013. CurrentControl = CurrentPort + 2;
  2014. // set the block address register to ATA/ATAPI data register,
  2015. // as this function is currently used ONLY for ATA/ATAPI devices
  2016. // ATA/ATAPI data register 0x1F0 corresponds to 0x18 value
  2017. ParStlWriteReg ( Extension, EP1284_BLK_ADDR_REGISTER, 0x18 ) ;
  2018. // do the nibble block read sequence
  2019. // write the nibble block read op-code
  2020. P5WritePortUchar ( CurrentPort, OP_NIBBLE_BLOCK_READ ) ;
  2021. KeStallExecutionProcessor( Delay );
  2022. // set control ports to correct signals.
  2023. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_LO ) ;
  2024. KeStallExecutionProcessor( Delay );
  2025. // set data port to 0xFF
  2026. P5WritePortUchar ( CurrentPort, 0xFF ) ;
  2027. KeStallExecutionProcessor( Delay );
  2028. P5WritePortUchar ( CurrentControl, INIT_AFXT_HIGH ) ;
  2029. KeStallExecutionProcessor( Delay );
  2030. do
  2031. {
  2032. // low nibble is available in status after
  2033. // toggling sequences as in EP1284 manual
  2034. P5WritePortUchar ( CurrentControl, AFXT_LO_STB_HI ) ;
  2035. KeStallExecutionProcessor( Delay );
  2036. pchDataBuffer[i] = P5ReadPortUchar( CurrentStatus ) >> 4 ;
  2037. KeStallExecutionProcessor( Delay );
  2038. // high nibble is available in status after
  2039. // toggling sequences as in EP1284 manual
  2040. P5WritePortUchar ( CurrentControl, AFXT_HI_STB_HI ) ;
  2041. KeStallExecutionProcessor( Delay );
  2042. pchDataBuffer[i++] |= ( P5ReadPortUchar ( CurrentStatus ) & 0xF0 ) ;
  2043. KeStallExecutionProcessor( Delay );
  2044. if ( count - 1 == i )
  2045. {
  2046. // to read the last byte
  2047. P5WritePortUchar ( CurrentPort, 0xFD ) ;
  2048. KeStallExecutionProcessor( Delay );
  2049. }
  2050. P5WritePortUchar ( CurrentControl, AFXT_LO_STB_LO ) ;
  2051. KeStallExecutionProcessor( Delay );
  2052. pchDataBuffer[i] = P5ReadPortUchar ( CurrentStatus ) >> 4 ;
  2053. KeStallExecutionProcessor( Delay );
  2054. P5WritePortUchar ( CurrentControl, AFXT_HI_STB_LO ) ;
  2055. KeStallExecutionProcessor( Delay );
  2056. pchDataBuffer[i++] |= ( P5ReadPortUchar ( CurrentStatus ) & 0xF0 ) ;
  2057. KeStallExecutionProcessor( Delay );
  2058. }
  2059. while ( i <= count ) ;
  2060. // clean up
  2061. P5WritePortUchar ( CurrentPort, 0x00 ) ;
  2062. KeStallExecutionProcessor( Delay );
  2063. // done
  2064. return SHTL_NO_ERROR ;
  2065. }
  2066. int __cdecl
  2067. ParStlReadIoPort (
  2068. IN PPDO_EXTENSION Extension,
  2069. IN unsigned reg
  2070. )
  2071. {
  2072. switch ( reg )
  2073. {
  2074. case 0x08 :
  2075. reg = 0x16 ;
  2076. break ;
  2077. case 0x09 :
  2078. reg = 0x17 ;
  2079. break ;
  2080. default :
  2081. reg |= 0x18 ;
  2082. break;
  2083. }
  2084. return ParStlReadReg ( Extension, reg ) ;
  2085. }
  2086. int __cdecl
  2087. ParStlWriteIoPort (
  2088. IN PPDO_EXTENSION Extension,
  2089. IN unsigned reg,
  2090. IN int databyte
  2091. )
  2092. {
  2093. switch ( reg )
  2094. {
  2095. case 0x08 :
  2096. reg = 0x16 ;
  2097. break ;
  2098. case 0x09 :
  2099. reg = 0x17 ;
  2100. break ;
  2101. default :
  2102. reg |= 0x18 ;
  2103. break;
  2104. }
  2105. return ParStlWriteReg ( Extension, reg, databyte ) ;
  2106. }
  2107. int __cdecl
  2108. ParStlGetMemorySize (
  2109. IN PPDO_EXTENSION Extension
  2110. )
  2111. {
  2112. BOOLEAN bReturnValue = FALSE ;
  2113. UCHAR byTempValue ;
  2114. do
  2115. {
  2116. // Issue reset through control register
  2117. // first try on DRAM
  2118. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2119. byTempValue |= ENABLE_MEM|SELECT_DRAM|RESET_PTR ;
  2120. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2121. byTempValue &= ~RESET_PTR ;
  2122. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2123. // write to the first location in the memory
  2124. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_1 ) ;
  2125. // write to the next location in the memory
  2126. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_2 ) ;
  2127. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2128. byTempValue |= ENABLE_MEM|SELECT_DRAM|RESET_PTR ;
  2129. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2130. byTempValue &= ~RESET_PTR ;
  2131. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2132. // read from the first and next location in the memory
  2133. if ( ( TEST_PATTERN_1 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) &&\
  2134. ( TEST_PATTERN_2 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) )
  2135. {
  2136. bReturnValue = TRUE ;
  2137. break ;
  2138. }
  2139. if ( !IsImpactPresent () )
  2140. {
  2141. // as only DRAM can be present on non-impact adapters
  2142. break ;
  2143. }
  2144. // Issue reset through control register
  2145. // and next try on SRAM
  2146. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2147. byTempValue |= ENABLE_MEM|RESET_PTR ;
  2148. byTempValue &= SELECT_SRAM ;
  2149. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2150. byTempValue &= ~RESET_PTR ;
  2151. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2152. // write to the first location in the memory
  2153. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_1 ) ;
  2154. // write to the next location in the memory
  2155. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_2 ) ;
  2156. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2157. byTempValue |= ENABLE_MEM|RESET_PTR ;
  2158. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2159. byTempValue &= ~RESET_PTR ;
  2160. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2161. // read from the first location in the memory
  2162. if ( ( TEST_PATTERN_1 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) &&\
  2163. ( TEST_PATTERN_2 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) )
  2164. {
  2165. bReturnValue = TRUE ;
  2166. break ;
  2167. }
  2168. }
  2169. while ( FALSE ) ;
  2170. return bReturnValue ;
  2171. }
  2172. // end of file