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.

2675 lines
77 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) ) {
  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) ) {
  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. ULONG size = 0x80 ;
  539. PCHAR id ;
  540. STL_DEVICE_TYPE dtDeviceType ;
  541. CHAR szDeviceIdString[0x80] ;
  542. CHAR szVidPidString[] = "MFG:VID_04E6;CLS:SCSIADAPTER;MDL:PID_" ;
  543. CHAR szVidPidStringScan[] = "MFG:VID_04E6;CLS:IMAGE;MDL:PID_" ;
  544. RtlZeroMemory(szDeviceIdString, sizeof(szDeviceIdString));
  545. // identify the shuttle adapter type by calling
  546. // Devtype routines here and build an unique id
  547. // string here.
  548. dtDeviceType = ParStlGetDeviceType(Extension, DEVICE_TYPE_AUTO_DETECT);
  549. switch ( dtDeviceType ) {
  550. case DEVICE_TYPE_NONE :
  551. return NULL;
  552. case DEVICE_TYPE_EPP_DEVICE :
  553. dtDeviceType |= 0x80000000 ;
  554. sprintf(szDeviceIdString, "%s%08X;", szVidPidStringScan, dtDeviceType);
  555. break;
  556. default :
  557. dtDeviceType |= 0x80000000 ;
  558. sprintf(szDeviceIdString, "%s%08X;", szVidPidString, dtDeviceType);
  559. break;
  560. }
  561. id = ExAllocatePool(PagedPool, size);
  562. if( id ) {
  563. RtlZeroMemory( id, size );
  564. if( bReturnRawString ) {
  565. //
  566. // Yes, caller wants the size prefix. Copy prefix to buffer to return.
  567. //
  568. *(id+0) = 0;
  569. *(id+1) = 0x80-2;
  570. RtlCopyMemory( id+2, szDeviceIdString, size - sizeof(NULL) - 2 );
  571. } else {
  572. RtlCopyMemory( id, szDeviceIdString, size - sizeof(NULL) );
  573. }
  574. return id;
  575. }
  576. return NULL;
  577. }
  578. STL_DEVICE_TYPE __cdecl
  579. ParStlGetDeviceType (
  580. IN PPDO_EXTENSION Extension,
  581. IN int nPreferredDeviceType
  582. )
  583. {
  584. STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
  585. ATAPIPARAMS atapiParams ;
  586. int i;
  587. for ( i=0 ; i<ATAPI_MAX_DRIVES ; i++){
  588. atapiParams.dsDeviceState[i] = DEVICE_STATE_INVALID ;
  589. }
  590. do
  591. {
  592. if ( TRUE == ParStlCheckIfScsiDevice(Extension))
  593. {
  594. // SCSI Device identified.
  595. dtDeviceType |= DEVICE_TYPE_SCSI_BIT ;
  596. break ;
  597. }
  598. if ( TRUE == NeedToEnableIoPads () )
  599. {
  600. // in some adapters, the IO pads need to be enabled, before
  601. // doing the device detection
  602. ParStlWriteReg( Extension, CONFIG_INDEX_REGISTER, EP1284_POWER_CONTROL_REG );
  603. ParStlWriteReg( Extension, CONFIG_DATA_REGISTER, ENABLE_IOPADS );
  604. }
  605. if ( TRUE == IsImpactSPresent() )
  606. {
  607. // as impact-s has been identified, the device type identification
  608. // can be done through personality configuration info
  609. dtDeviceType |= ParStlGetImpactSDeviceType( Extension, &atapiParams, nPreferredDeviceType );
  610. break;
  611. }
  612. if ( TRUE == IsImpactPresent() )
  613. {
  614. // as impact has been identified, the device type identification
  615. // can be done through personality configuration info
  616. dtDeviceType |= ParStlGetImpactDeviceType( Extension, &atapiParams, nPreferredDeviceType );
  617. break;
  618. }
  619. if (TRUE == ParStlCheckIfEppDevice(Extension))
  620. {
  621. // epp device identified
  622. if ( TRUE == ParStlCheckUMAXScannerPresence(Extension) ) {
  623. // umax identified
  624. dtDeviceType |= DEVICE_TYPE_UMAX_BIT;
  625. break;
  626. }
  627. if ( TRUE == ParStlCheckAvisionScannerPresence(Extension) ) {
  628. // avision identified
  629. dtDeviceType |= DEVICE_TYPE_AVISION_BIT;
  630. break;
  631. }
  632. // generice scanner peripheral detected
  633. dtDeviceType |= DEVICE_TYPE_EPP_DEVICE_BIT;
  634. break;
  635. }
  636. if (TRUE == ParStlCheckIfSSFDC(Extension))
  637. {
  638. // SSFDC identified
  639. dtDeviceType |= DEVICE_TYPE_SSFDC_BIT;
  640. break;
  641. }
  642. if (TRUE == ParStlCheckIfMMC(Extension,&atapiParams))
  643. {
  644. // MMC device identified
  645. dtDeviceType |= DEVICE_TYPE_MMC_BIT;
  646. break;
  647. }
  648. // set the 16 bit mode of the adapter
  649. ParStlSet16BitOperation(Extension) ;
  650. if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension, &atapiParams))
  651. {
  652. // necessary but not sufficient condition has passed
  653. // proceed for sufficency checks
  654. if (TRUE == ParStlCheckIfAtapiDevice(Extension, &atapiParams))
  655. {
  656. // sub-classify between HiFD and LS-120.
  657. if ( TRUE == ParStlCheckIfLS120(Extension))
  658. {
  659. // LS Engine is found.
  660. dtDeviceType |= DEVICE_TYPE_LS120_BIT ;
  661. break ;
  662. }
  663. // Check for HiFD.
  664. if (TRUE == ParStlCheckIfHiFD(Extension))
  665. {
  666. // HiFD device identified.
  667. dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
  668. break ;
  669. }
  670. // OtherWise, it is a generic ATAPI device.
  671. dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
  672. break ;
  673. }
  674. if (TRUE == ParStlCheckIfAtaDevice(Extension, &atapiParams))
  675. {
  676. // ata identified
  677. dtDeviceType |= DEVICE_TYPE_ATA_BIT;
  678. break;
  679. }
  680. }
  681. if (TRUE == ParStlCheckIfDazzle(Extension))
  682. {
  683. // dazzle identified
  684. dtDeviceType |= DEVICE_TYPE_DAZZLE_BIT;
  685. break;
  686. }
  687. if (TRUE == ParStlCheckIfFlash(Extension))
  688. {
  689. // flash identified
  690. dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
  691. break;
  692. }
  693. }
  694. while ( FALSE ) ;
  695. return dtDeviceType & nPreferredDeviceType ;
  696. }
  697. VOID
  698. ParStlWaitForMicroSeconds (
  699. int nMicroSecondsToWait
  700. ) {
  701. KeStallExecutionProcessor ( nMicroSecondsToWait ) ;
  702. }
  703. BOOLEAN
  704. ParStlCheckCardInsertionStatus (
  705. IN PPDO_EXTENSION Extension
  706. )
  707. {
  708. BOOLEAN bReturnValue = FALSE ;
  709. UCHAR byPowerRegData ;
  710. do
  711. {
  712. if ( FALSE == IsEp1284Present() )
  713. {
  714. break ;
  715. }
  716. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , 0x0F ) ;
  717. byPowerRegData = (UCHAR) ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
  718. if ( byPowerRegData & SHTL_CARD_INSERTED_STATUS )
  719. {
  720. // as the card not inserted status is reported, it is ATA / ATAPI
  721. // possibly, not flash. hence, we break here.
  722. break ;
  723. }
  724. bReturnValue = TRUE ;
  725. }
  726. while ( FALSE ) ;
  727. return ( bReturnValue ) ;
  728. }
  729. BOOLEAN
  730. ParStlSelectAdapterSocket (
  731. IN PPDO_EXTENSION Extension,
  732. IN int nSocketNumber
  733. )
  734. {
  735. BOOLEAN bReturnValue = FALSE ;
  736. UCHAR bySCRControlReg , byISAControlReg ;
  737. do
  738. {
  739. if ( ( nSocketNumber != SOCKET_0 ) &&
  740. ( nSocketNumber != SOCKET_1 ) )
  741. {
  742. // as an invalid socket number is provided, we
  743. // break here with error.
  744. break ;
  745. }
  746. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
  747. bySCRControlReg = (UCHAR) ParStlReadReg (Extension, CONFIG_DATA_REGISTER ) ;
  748. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , ISA_CONTROL_REGISTER ) ;
  749. byISAControlReg = (UCHAR) ParStlReadReg (Extension, CONFIG_DATA_REGISTER ) ;
  750. if ( SOCKET_1 == nSocketNumber )
  751. {
  752. bySCRControlReg |= (UCHAR)SOCKET_1 ;
  753. bySCRControlReg |= (UCHAR)PERIPHERAL_RESET_1 ;
  754. byISAControlReg &= ~(UCHAR)ISA_IO_SWAP ;
  755. }
  756. else
  757. {
  758. bySCRControlReg &= ~(UCHAR)SOCKET_1 ;
  759. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_0 ;
  760. }
  761. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , ISA_CONTROL_REGISTER ) ;
  762. ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , byISAControlReg ) ;
  763. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
  764. ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  765. if ( SOCKET_1 == nSocketNumber )
  766. {
  767. // Wait for a few milliseconds to provide an optimal puse width
  768. // for reset.
  769. ParStlWaitForMicroSeconds(1000);
  770. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_1 ;
  771. }
  772. else
  773. {
  774. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_0 ;
  775. }
  776. ParStlWriteReg(Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  777. bReturnValue = TRUE ;
  778. }
  779. while ( FALSE ) ;
  780. return bReturnValue ;
  781. }
  782. BOOLEAN
  783. ParStlCheckIfAtaAtapiDevice (
  784. IN PPDO_EXTENSION Extension,
  785. IN OUT PATAPIPARAMS atapiParams
  786. )
  787. {
  788. BOOLEAN bReturnValue = FALSE;
  789. do
  790. {
  791. if ( TRUE == ParStlCheckCardInsertionStatus(Extension) )
  792. {
  793. // as the card insertion status is valid, its probably
  794. // a flash
  795. break ;
  796. }
  797. if ( FALSE == ParStlCheckDrivePresent(Extension, atapiParams) )
  798. {
  799. // as the ATA/ATAPI controller is not present, it cant be
  800. // an ATA/ATAPI device
  801. break ;
  802. }
  803. bReturnValue = TRUE;
  804. }
  805. while ( FALSE ) ;
  806. return bReturnValue ;
  807. }
  808. BOOLEAN
  809. ParStlCheckIfAtapiDevice (
  810. IN PPDO_EXTENSION Extension,
  811. IN OUT PATAPIPARAMS atapiParams
  812. )
  813. {
  814. BOOLEAN bReturnValue = FALSE;
  815. do
  816. {
  817. // return whatever ATAPI initialization module says
  818. bReturnValue = ParStlAtapiInitialize(Extension, atapiParams) ;
  819. }
  820. while ( FALSE ) ;
  821. return bReturnValue ;
  822. }
  823. BOOLEAN
  824. ParStlCheckIfAtaDevice (
  825. IN PPDO_EXTENSION Extension,
  826. IN OUT PATAPIPARAMS atapiParams
  827. )
  828. {
  829. BOOLEAN bReturnValue = FALSE;
  830. do
  831. {
  832. // return whatever ATA initialization module says
  833. bReturnValue = ParStlAtaInitialize(Extension, atapiParams) ;
  834. }
  835. while ( FALSE ) ;
  836. return bReturnValue ;
  837. }
  838. BOOLEAN
  839. ParStlCheckDrivePresent (
  840. IN PPDO_EXTENSION Extension,
  841. IN OUT PATAPIPARAMS atapiParams
  842. )
  843. {
  844. BOOLEAN bReturnValue = FALSE ;
  845. UCHAR byOrgCylHigh, byOrgCylLow ;
  846. int nCurrentDrive = 0 , i ;
  847. UCHAR nDrvHdArray[]={ATAPI_MASTER, ATAPI_SLAVE};
  848. do
  849. {
  850. if ( atapiParams->dsDeviceState[nCurrentDrive] == DEVICE_STATE_VALID )
  851. {
  852. // this means that the MMC module had detected the presence
  853. // of an ATA/ATAPI device. So, we make use of that and break out
  854. bReturnValue = TRUE ;
  855. break ;
  856. }
  857. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, nDrvHdArray[nCurrentDrive]);
  858. // The Atapi Fuji MO drive is found to de-assert BSY and still
  859. // does not respond to reg. r/w when configured as slave with no media.
  860. // However, after a delay, it works ok.
  861. if ( nCurrentDrive )
  862. {
  863. ParStlWaitForMicroSeconds ( DELAY_1SECOND ) ;
  864. }
  865. // this dummy write of 0 is to zero out a possible
  866. // floating bus
  867. for ( i = 0 ; i < 16 ; i++ )
  868. {
  869. ParStlWriteReg(Extension, CONFIG_INDEX_REGISTER, i) ;
  870. if ( !( ParStlReadIoPort (Extension, ATA_TASK_STAT_REG ) & ATA_ST_BUSY ) )
  871. {
  872. break ;
  873. }
  874. }
  875. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  876. {
  877. // as the busy has been found permanently set, we check
  878. // for the slave also
  879. continue;
  880. }
  881. // as the drive head setup might have been performed in a busy state,
  882. // we set it up again after busy clears.
  883. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, nDrvHdArray[nCurrentDrive]);
  884. if ( ( ParStlReadIoPort(Extension, ATA_DRVHD_REG) & ATAPI_SLAVE ) != nDrvHdArray[nCurrentDrive] )
  885. {
  886. continue ;
  887. }
  888. // read original contents of the cyl ATA high/low registers
  889. byOrgCylLow = (UCHAR) ParStlReadIoPort(Extension, ATA_CYLLOW_REG);
  890. byOrgCylHigh = (UCHAR) ParStlReadIoPort(Extension, ATA_CYLHIGH_REG);
  891. // write a test pattern in the cyl ATA high/low registers
  892. ParStlWriteIoPort(Extension, ATA_CYLLOW_REG, TEST_PATTERN_1);
  893. ParStlWriteIoPort(Extension, ATA_CYLHIGH_REG, TEST_PATTERN_2);
  894. // read the test pattern in the cyl ATA high/low registers
  895. if ( ( TEST_PATTERN_1 != ParStlReadIoPort(Extension, ATA_CYLLOW_REG) ) ||\
  896. ( TEST_PATTERN_2 != ParStlReadIoPort(Extension, ATA_CYLHIGH_REG) ) )
  897. {
  898. // as we were not able to read back the written values
  899. // we break out here, indicating the absence of the device
  900. continue ;
  901. }
  902. // write back original contents in the cyl ATA high/low registers
  903. ParStlWriteIoPort(Extension, ATA_CYLLOW_REG, byOrgCylLow);
  904. ParStlWriteIoPort(Extension, ATA_CYLHIGH_REG, byOrgCylHigh);
  905. bReturnValue = TRUE ;
  906. atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_VALID ;
  907. }
  908. while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
  909. // reset back to master state, as check drive present
  910. // will be called successively
  911. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  912. return bReturnValue ;
  913. }
  914. BOOLEAN
  915. ParStlAtapiInitialize (
  916. IN PPDO_EXTENSION Extension,
  917. IN OUT PATAPIPARAMS atapiParams
  918. )
  919. {
  920. BOOLEAN bReturnValue = FALSE ;
  921. int nCurrentDrive = 0, i ;
  922. UCHAR byTempValue ;
  923. UCHAR chAtapiIdentifyBuffer [ ATAPI_IDENTIFY_LENGTH ] ;
  924. do
  925. {
  926. if ( DEVICE_STATE_VALID != atapiParams->dsDeviceState[nCurrentDrive] )
  927. {
  928. // the device is absent
  929. continue ;
  930. }
  931. if ( nCurrentDrive )
  932. {
  933. // as it is the next drive, choose the slave
  934. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_SLAVE);
  935. }
  936. else
  937. {
  938. // choose the master
  939. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  940. }
  941. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  942. {
  943. // as busy has permanently set after master/slave, we fail
  944. // the detection process
  945. continue ;
  946. }
  947. // check if the ATAPI signature is present in the cyl hi/lo
  948. // registers. If present, it is definitely an ATAPI device
  949. if ( ( ParStlReadIoPort(Extension, ATA_CYLLOW_REG) == ATAPI_SIGN_LOW ) &&\
  950. ( ParStlReadIoPort(Extension, ATA_CYLHIGH_REG) == ATAPI_SIGN_HI ) )
  951. {
  952. // as ATAPI signature is present, it is ATAPI type
  953. bReturnValue = TRUE ;
  954. // set this flag so that, ATA initialize will skip this
  955. // target
  956. atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_ATAPI ;
  957. // for Impact, since Ls120 engine is always present,
  958. // issuing ATAPI_IDENTIFY is mandatory.
  959. if ( !IsImpactPresent())
  960. {
  961. continue ;
  962. }
  963. }
  964. // issue the ata nop command
  965. ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATA_NOP_COMMAND) ;
  966. if ( FALSE == ParStlWaitForIrq(Extension) )
  967. {
  968. // ATAPI devices are expected to give interrrupt on NOP command
  969. // mandatorily.
  970. continue ;
  971. }
  972. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  973. {
  974. // as busy has permanently set, we proceed with the next
  975. // drive
  976. continue ;
  977. }
  978. // issue the atapi packet command
  979. ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATAPI_IDENTIFY) ;
  980. if ( FALSE == ParStlWaitForIrq(Extension) )
  981. {
  982. // ATAPI devices are expected to give interrrupt on 0xA1 command
  983. // mandatorily.
  984. continue ;
  985. }
  986. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  987. {
  988. // as busy has permanently set, we proceed with the next
  989. // drive
  990. continue ;
  991. }
  992. byTempValue = (UCHAR) ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) ;
  993. if ( ! ( byTempValue & ATA_ST_ERROR ) )
  994. {
  995. // as the drive has passed the packet command, this is an atapi
  996. // drive
  997. // Wait for DRQ to be sit, as some drives are known
  998. // to remove busy too early and set DRQ after some time.
  999. if ( FALSE == ParStlWaitForDrq(Extension) )
  1000. {
  1001. // as there was no DRQ set, we proceed with the next
  1002. // drive
  1003. continue ;
  1004. }
  1005. bReturnValue = TRUE ;
  1006. // as the DRQ is still asserted, quell it, as certain ATA/ATAPI-4
  1007. // spec. dictates it so
  1008. // There is a need to check the device identifier returned in the
  1009. // ATAPI Identify cmd. to determine the presence of Ls-120.
  1010. ParStlReceiveData ( Extension, chAtapiIdentifyBuffer , SKIP_MEMORY_ADDRESS , ATAPI_IDENTIFY_LENGTH ) ;
  1011. for ( i = 0 ; i < ATAPI_NAME_LENGTH ; i++ )
  1012. {
  1013. atapiParams->szAtapiNameString[i] = chAtapiIdentifyBuffer[ ATAPI_NAME_OFFSET + i ] ;
  1014. }
  1015. // set this flag so that, ATA initialize will skip this
  1016. // target
  1017. atapiParams->dsDeviceState[nCurrentDrive] = DEVICE_STATE_ATAPI ;
  1018. }
  1019. }
  1020. while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
  1021. // reset back to master state, as check drive present
  1022. // will be called successively
  1023. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  1024. return ( bReturnValue ) ;
  1025. }
  1026. BOOLEAN
  1027. ParStlAtaInitialize (
  1028. IN PPDO_EXTENSION Extension,
  1029. IN OUT PATAPIPARAMS atapiParams
  1030. )
  1031. {
  1032. BOOLEAN bReturnValue = FALSE ;
  1033. UCHAR byTempValue ;
  1034. int nCurrentDrive = 0 ;
  1035. do
  1036. {
  1037. if ( DEVICE_STATE_VALID != atapiParams->dsDeviceState[nCurrentDrive] )
  1038. {
  1039. // atapi module has marked its presence or the device is absent
  1040. continue ;
  1041. }
  1042. // select the possibly present device
  1043. if ( nCurrentDrive )
  1044. {
  1045. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_SLAVE ) ;
  1046. }
  1047. else
  1048. {
  1049. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER ) ;
  1050. }
  1051. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  1052. {
  1053. // as busy has permanently set after master/slave, we fail the
  1054. // detection process
  1055. continue ;
  1056. }
  1057. // issue the ata NOP command
  1058. ParStlWriteIoPort(Extension, ATA_TASK_CMD_REG, ATA_NOP_COMMAND) ;
  1059. if ( FALSE == ParStlWaitForBusyToClear(Extension, ATA_TASK_STAT_REG) )
  1060. {
  1061. // as busy has permanently set, we fail the detection process
  1062. continue ;
  1063. }
  1064. byTempValue = (UCHAR) ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) ;
  1065. if ( ( byTempValue != BUS_LINES_IN_HIGH_IMPEDANCE ) &&\
  1066. ( byTempValue & ATA_ST_ERROR ) )
  1067. {
  1068. // as the bus is not reading 0xFF and the status register
  1069. // indicates an error, this is likely to be an ATA device
  1070. if ( ATA_ERROR_ABORTED_COMMAND == ( (UCHAR) ParStlReadIoPort ( Extension, ATA_ERROR_REG ) & 0x0F ) )
  1071. {
  1072. // as the error register, contains the ata aborted error
  1073. // in response to our ATA NOP command, we conclude that
  1074. // it is ATA! as it is already known that it is not ATAPI
  1075. bReturnValue = TRUE ;
  1076. break;
  1077. }
  1078. }
  1079. }
  1080. while ( ++nCurrentDrive < ATAPI_MAX_DRIVES );
  1081. // reset back to master state, as check drive present
  1082. // will be called successively
  1083. ParStlWriteIoPort(Extension, ATA_DRVHD_REG, ATAPI_MASTER);
  1084. return ( bReturnValue ) ;
  1085. }
  1086. BOOLEAN
  1087. ParStlWaitForBusyToClear (
  1088. IN PPDO_EXTENSION Extension,
  1089. IN int nRegisterToWaitOn
  1090. )
  1091. {
  1092. // The default timeout increased to 10secs as Fujitsu MO is found to set
  1093. // BUSY for >5secs for 0xA1 command.
  1094. int nMaxRetrials = MAX_RETRIES_FOR_10_SECS ;
  1095. BOOLEAN bRetVal = FALSE ;
  1096. while ( nMaxRetrials-- )
  1097. {
  1098. // the following service will be implemented by the caller
  1099. // the driver can use the STLMPORT service.
  1100. ParStlWaitForMicroSeconds ( DELAY_1MILLISECONDS ) ;
  1101. if ( ! ( ParStlReadIoPort ( Extension, nRegisterToWaitOn ) & ATA_ST_BUSY ) )
  1102. {
  1103. // as busy has cleared, we return clear here
  1104. bRetVal = TRUE ;
  1105. break ;
  1106. }
  1107. }
  1108. return bRetVal ;
  1109. }
  1110. BOOLEAN
  1111. ParStlWaitForDrq (
  1112. IN PPDO_EXTENSION Extension
  1113. )
  1114. {
  1115. int nMaxRetrials = MAX_RETRIES_FOR_5_SECS ;
  1116. BOOLEAN bRetVal = FALSE ;
  1117. while ( nMaxRetrials-- )
  1118. {
  1119. if ( ParStlReadIoPort ( Extension, ATA_TASK_STAT_REG ) & ATA_ST_DRQ )
  1120. {
  1121. // as busy has cleared, we return clear here
  1122. bRetVal = TRUE ;
  1123. break ;
  1124. }
  1125. // the following service will be implemented by the caller
  1126. // the driver can use the STLMPORT service.
  1127. ParStlWaitForMicroSeconds ( DELAY_1MILLISECONDS ) ;
  1128. }
  1129. return bRetVal ;
  1130. }
  1131. BOOLEAN
  1132. ParStlWaitForIrq (
  1133. IN PPDO_EXTENSION Extension
  1134. )
  1135. {
  1136. int nMaxRetrials = MAX_RETRIES_FOR_10_SECS ;
  1137. BOOLEAN bRetVal = FALSE ;
  1138. while ( nMaxRetrials-- )
  1139. {
  1140. if ( ParStlReadReg ( Extension, EP1284_TRANSFER_CONTROL_REG ) & XFER_IRQ_BIT )
  1141. {
  1142. // as Irq has asserted, we return true here
  1143. bRetVal = TRUE ;
  1144. break ;
  1145. }
  1146. ParStlWaitForMicroSeconds ( DELAY_1MILLISECONDS ) ;
  1147. }
  1148. return bRetVal ;
  1149. }
  1150. VOID
  1151. ParStlSet16BitOperation (
  1152. IN PPDO_EXTENSION Extension
  1153. )
  1154. {
  1155. int nModeReg ;
  1156. nModeReg = ParStlReadReg ( Extension, EP1284_MODE_REGISTER ) ;
  1157. if ( 0 == ( nModeReg & EP1284_ENABLE_16BIT ) )
  1158. {
  1159. // as the bit is not already set, this needs to be set now
  1160. ParStlWriteReg ( Extension, EP1284_MODE_REGISTER, nModeReg | EP1284_ENABLE_16BIT ) ;
  1161. }
  1162. }
  1163. BOOLEAN
  1164. ParStlCheckIfEppDevice (
  1165. IN PPDO_EXTENSION Extension
  1166. )
  1167. {
  1168. BOOLEAN bReturnValue = FALSE;
  1169. do
  1170. {
  1171. if ( FALSE == IsEp1284Present() )
  1172. {
  1173. // as EPPDEVs live only on EP1284 we break here
  1174. break;
  1175. }
  1176. bReturnValue = ParStlCheckPersonalityForEppDevice(Extension) ;
  1177. }
  1178. while ( FALSE ) ;
  1179. return bReturnValue ;
  1180. }
  1181. BOOLEAN
  1182. ParStlCheckPersonalityForEppDevice (
  1183. IN PPDO_EXTENSION Extension
  1184. )
  1185. {
  1186. BOOLEAN bReturnValue = FALSE ;
  1187. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, EP1284_PERSONALITY_REG ) ;
  1188. if ( EPPDEV_SIGN == ( ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) & PERSONALITY_MASK ) )
  1189. {
  1190. // as the EPPDEV sign is found in the personality
  1191. // we break with success here
  1192. bReturnValue = TRUE ;
  1193. }
  1194. return bReturnValue ;
  1195. }
  1196. BOOLEAN
  1197. ParStlCheckIfFlash (
  1198. IN PPDO_EXTENSION Extension
  1199. )
  1200. {
  1201. BOOLEAN bReturnValue = FALSE ;
  1202. do
  1203. {
  1204. if ( !IsEp1284Present() && !IsImpactPresent() && !IsEpatPlusPresent() )
  1205. {
  1206. // Check the sign-on version checks for the existence of Shuttle
  1207. // adapter. If nothing is found, we break here.
  1208. break ;
  1209. }
  1210. // Perform a ATA-16bit check just in case, it turns out to be something else
  1211. bReturnValue = ParStlCheckFlashPersonality(Extension) ;
  1212. }
  1213. while ( FALSE ) ;
  1214. return bReturnValue ;
  1215. }
  1216. BOOLEAN
  1217. ParStlCheckFlashPersonality (
  1218. IN PPDO_EXTENSION Extension
  1219. )
  1220. {
  1221. BOOLEAN bReturnValue = FALSE ;
  1222. if ( IsEp1284Present() )
  1223. {
  1224. // as the personality configuration check only works for
  1225. // Ep1284, confim its presence before the actual check.
  1226. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, EP1284_PERSONALITY_REG ) ;
  1227. if ( FLASH_SIGN == ( ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) & FLASH_PERSONALITY_MASK ) )
  1228. {
  1229. // as the flash sign ATA-16bit device is found in the personality
  1230. // we break with success here
  1231. bReturnValue = TRUE ;
  1232. }
  1233. }
  1234. else
  1235. {
  1236. // always return true, if a shuttle adapter other than ep1284 is
  1237. // identified and assume it might be flash!
  1238. bReturnValue = TRUE ;
  1239. }
  1240. return bReturnValue ;
  1241. }
  1242. BOOLEAN
  1243. ParStlCheckIfDazzle (
  1244. IN PPDO_EXTENSION Extension
  1245. )
  1246. {
  1247. BOOLEAN bReturnValue = FALSE ;
  1248. UCHAR ucSignature ;
  1249. do
  1250. {
  1251. if ( !IsEp1284Present() )
  1252. {
  1253. // Check for EP1284 presence, as Dazzle is ONLY on EP1284
  1254. // adapters. If the adapter is not EP1284, we break.
  1255. break ;
  1256. }
  1257. // Check whether any card insertion is detected, to eliminate
  1258. // possible flash adapters with the card in
  1259. if ( TRUE == ParStlCheckCardInsertionStatus( Extension ) ) {
  1260. break ;
  1261. }
  1262. // code to read the pulled up pattern present on dazzle
  1263. // adapters.
  1264. ParStlWriteReg( Extension, DAZ_SELECT_BLK, DAZ_BLK0 ) ;
  1265. ucSignature = (UCHAR) ParStlReadReg( Extension, DAZ_REG1 ) ;
  1266. if ( ( ucSignature == DAZ_CONFIGURED ) ||\
  1267. ( ucSignature == DAZ_NOT_CONFIGURED ) ) {
  1268. // the pulled up pattern generally found ONLY
  1269. // on the DAZZLE adapter is found. So, we
  1270. // conclude that it is a Dazzle adapter
  1271. bReturnValue = TRUE ;
  1272. }
  1273. }
  1274. while ( FALSE ) ;
  1275. return bReturnValue ;
  1276. }
  1277. BOOLEAN
  1278. ParStlCheckIfHiFD (
  1279. IN PPDO_EXTENSION Extension
  1280. )
  1281. {
  1282. BOOLEAN bReturnValue = FALSE;
  1283. do
  1284. {
  1285. if ( FALSE == ParStlSelectAdapterSocket(Extension, SOCKET_1) )
  1286. {
  1287. // as the socket 1 selection failed,
  1288. // we break out here.
  1289. break ;
  1290. }
  1291. // check for the ready status of the floppy controller,
  1292. // after clearing the reset bit of the floppy controller.
  1293. if ( FALSE == ParStlHIFDCheckIfControllerReady(Extension) )
  1294. {
  1295. // since the controller didnot wake up after the
  1296. // reset pin was asserted, we break here.
  1297. break ;
  1298. }
  1299. if ( FALSE == ParStlHIFDCheckSMCController(Extension) )
  1300. {
  1301. // as the SMC ID retrieval failed,
  1302. // we break out here.
  1303. break ;
  1304. }
  1305. bReturnValue = TRUE ;
  1306. }
  1307. while ( FALSE ) ;
  1308. // Reset the socket to zero.
  1309. ParStlSelectAdapterSocket(Extension, SOCKET_0);
  1310. return bReturnValue ;
  1311. }
  1312. BOOLEAN
  1313. ParStlHIFDCheckIfControllerReady (
  1314. IN PPDO_EXTENSION Extension
  1315. )
  1316. {
  1317. BOOLEAN bReturnValue = FALSE ;
  1318. UCHAR bySCRControlReg ;
  1319. do
  1320. {
  1321. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , SOCKET_CONTROL_REGISTER ) ;
  1322. bySCRControlReg = (UCHAR) ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
  1323. bySCRControlReg |= (UCHAR)PERIPHERAL_RESET_1 ;
  1324. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  1325. ParStlWaitForMicroSeconds ( HIFD_WAIT_10_MILLISEC ) ;
  1326. ParStlWriteIoPort ( Extension, HIFD_DIGITAL_OUTPUT_REGISTER ,
  1327. 0x00 ) ;
  1328. ParStlWaitForMicroSeconds ( HIFD_WAIT_1_MILLISEC ) ;
  1329. ParStlWriteIoPort ( Extension, HIFD_DIGITAL_OUTPUT_REGISTER ,
  1330. HIFD_DOR_RESET_BIT | HIFD_ENABLE_DMA_BIT ) ;
  1331. ParStlWaitForMicroSeconds ( HIFD_WAIT_10_MILLISEC ) ;
  1332. if ( HIFD_CONTROLLER_READY_STATUS == ParStlReadIoPort ( Extension, HIFD_MAIN_STATUS_REGISTER ) )
  1333. {
  1334. bReturnValue = TRUE ;
  1335. }
  1336. bySCRControlReg &= ~(UCHAR)PERIPHERAL_RESET_1 ;
  1337. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , bySCRControlReg ) ;
  1338. }
  1339. while ( FALSE ) ;
  1340. return bReturnValue ;
  1341. }
  1342. BOOLEAN
  1343. ParStlHIFDCheckSMCController (
  1344. IN PPDO_EXTENSION Extension
  1345. )
  1346. {
  1347. BOOLEAN bReturnValue = FALSE ;
  1348. do
  1349. {
  1350. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_COMMAND_TO_CONTROLLER ) ;
  1351. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_COMMAND_TO_CONTROLLER ) ;
  1352. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_CTL_REG_0D ) ;
  1353. if ( SMC_DEVICE_ID == ParStlReadIoPort ( Extension, HIFD_STATUS_REGISTER_B ) )
  1354. {
  1355. bReturnValue = TRUE ;
  1356. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_A , HIFD_CTL_REG_03 ) ;
  1357. ParStlWriteIoPort ( Extension, HIFD_STATUS_REGISTER_B , SMC_ENABLE_MODE2 ) ;
  1358. }
  1359. ParStlWriteReg ( Extension, HIFD_STATUS_REGISTER_A , HIFD_TERMINATE_SEQUENCE ) ;
  1360. }
  1361. while ( FALSE ) ;
  1362. return bReturnValue ;
  1363. }
  1364. STL_DEVICE_TYPE
  1365. ParStlGetImpactDeviceType (
  1366. IN PPDO_EXTENSION Extension,
  1367. IN OUT PATAPIPARAMS atapiParams,
  1368. IN int nPreferredDeviceType
  1369. )
  1370. {
  1371. IMPACT_DEVICE_TYPE idtImpactDeviceType ;
  1372. STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
  1373. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, IMPACT_PERSONALITY_REG ) ;
  1374. idtImpactDeviceType = ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) >> 4 ;
  1375. switch ( idtImpactDeviceType )
  1376. {
  1377. case IMPACT_DEVICE_TYPE_ATA_ATAPI:
  1378. // set the 16 bit mode of the adapter
  1379. ParStlSet16BitOperation(Extension) ;
  1380. if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension,atapiParams))
  1381. {
  1382. // necessary but not sufficient condition has passed
  1383. // proceed for sufficency checks
  1384. if (TRUE == ParStlCheckIfAtapiDevice(Extension,atapiParams))
  1385. {
  1386. // atapi identified
  1387. // Check for Impact LS-120 device
  1388. if ( TRUE == ParStlCheckIfImpactLS120(Extension, atapiParams))
  1389. {
  1390. dtDeviceType |= DEVICE_TYPE_LS120_BIT ;
  1391. break ;
  1392. }
  1393. dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
  1394. break ;
  1395. }
  1396. if (TRUE == ParStlCheckIfAtaDevice(Extension, atapiParams))
  1397. {
  1398. // ata identified
  1399. dtDeviceType |= DEVICE_TYPE_ATA_BIT;
  1400. break;
  1401. }
  1402. }
  1403. break ;
  1404. case IMPACT_DEVICE_TYPE_CF:
  1405. dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
  1406. break ;
  1407. case IMPACT_DEVICE_TYPE_PCMCIA_CF:
  1408. dtDeviceType |= DEVICE_TYPE_PCMCIA_CF_BIT ;
  1409. break;
  1410. case IMPACT_DEVICE_TYPE_SSFDC:
  1411. dtDeviceType |= DEVICE_TYPE_SSFDC_BIT ;
  1412. break;
  1413. case IMPACT_DEVICE_TYPE_MMC:
  1414. dtDeviceType |= DEVICE_TYPE_MMC_BIT ;
  1415. break;
  1416. case IMPACT_DEVICE_TYPE_HIFD:
  1417. dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
  1418. break;
  1419. case IMPACT_DEVICE_TYPE_SOUND:
  1420. dtDeviceType |= DEVICE_TYPE_SOUND_BIT ;
  1421. break;
  1422. case IMPACT_DEVICE_TYPE_FLP_TAPE_DSK:
  1423. dtDeviceType |= DEVICE_TYPE_FLP_TAPE_DSK_BIT ;
  1424. break;
  1425. case IMPACT_DEVICE_TYPE_ATA_ATAPI_8BIT:
  1426. dtDeviceType |= DEVICE_TYPE_ATA_ATAPI_8BIT_BIT ;
  1427. break;
  1428. default:
  1429. break;
  1430. }
  1431. return dtDeviceType & nPreferredDeviceType ;
  1432. }
  1433. STL_DEVICE_TYPE
  1434. ParStlGetImpactSDeviceType (
  1435. IN PPDO_EXTENSION Extension,
  1436. IN OUT PATAPIPARAMS atapiParams,
  1437. IN int nPreferredDeviceType
  1438. )
  1439. {
  1440. IMPACT_DEVICE_TYPE idtImpactDeviceType ;
  1441. IMPACT_DEVICE_TYPE idtImpactSDeviceType ;
  1442. STL_DEVICE_TYPE dtDeviceType = DEVICE_TYPE_NONE ;
  1443. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, IMPACT_PERSONALITY_REG ) ;
  1444. idtImpactDeviceType = ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) >> 4 ;
  1445. switch ( idtImpactDeviceType )
  1446. {
  1447. case IMPACT_DEVICE_TYPE_ATA_ATAPI:
  1448. // set the 16 bit mode of the adapter
  1449. ParStlSet16BitOperation(Extension) ;
  1450. if (TRUE == ParStlCheckIfAtaAtapiDevice(Extension,atapiParams))
  1451. {
  1452. // necessary but not sufficient condition has passed
  1453. // proceed for sufficency checks
  1454. if (TRUE == ParStlCheckIfAtapiDevice(Extension,atapiParams))
  1455. {
  1456. // atapi identified
  1457. dtDeviceType |= DEVICE_TYPE_ATAPI_BIT;
  1458. break ;
  1459. }
  1460. if (TRUE == ParStlCheckIfAtaDevice(Extension,atapiParams))
  1461. {
  1462. // ata identified
  1463. dtDeviceType |= DEVICE_TYPE_ATA_BIT;
  1464. break;
  1465. }
  1466. }
  1467. break ;
  1468. case IMPACT_DEVICE_TYPE_CF:
  1469. dtDeviceType |= DEVICE_TYPE_FLASH_BIT;
  1470. break ;
  1471. case IMPACT_DEVICE_TYPE_PCMCIA_CF:
  1472. dtDeviceType |= DEVICE_TYPE_PCMCIA_CF_BIT ;
  1473. break;
  1474. case IMPACT_DEVICE_TYPE_SSFDC:
  1475. dtDeviceType |= DEVICE_TYPE_SSFDC_BIT ;
  1476. break;
  1477. case IMPACT_DEVICE_TYPE_MMC:
  1478. dtDeviceType |= DEVICE_TYPE_MMC_BIT ;
  1479. break;
  1480. case IMPACT_DEVICE_TYPE_HIFD:
  1481. dtDeviceType |= DEVICE_TYPE_HIFD_BIT ;
  1482. break;
  1483. case IMPACT_DEVICE_TYPE_SOUND:
  1484. dtDeviceType |= DEVICE_TYPE_SOUND_BIT ;
  1485. break;
  1486. case IMPACT_DEVICE_TYPE_FLP_TAPE_DSK:
  1487. dtDeviceType |= DEVICE_TYPE_FLP_TAPE_DSK_BIT ;
  1488. break;
  1489. case IMPACT_DEVICE_TYPE_ATA_ATAPI_8BIT:
  1490. dtDeviceType |= DEVICE_TYPE_ATA_ATAPI_8BIT_BIT ;
  1491. break;
  1492. case IMPACTS_EXT_PERSONALITY_PRESENT:
  1493. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER, IMPACTS_EXT_PERSONALITY_XREG ) ;
  1494. idtImpactSDeviceType = ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) ;
  1495. dtDeviceType = DEVICE_TYPE_EXT_HWDETECT ;
  1496. dtDeviceType |= idtImpactSDeviceType ;
  1497. break ;
  1498. default:
  1499. break;
  1500. }
  1501. return dtDeviceType & nPreferredDeviceType ;
  1502. }
  1503. BOOLEAN
  1504. ParStlCheckIfLS120 (
  1505. IN PPDO_EXTENSION Extension
  1506. )
  1507. {
  1508. BOOLEAN bReturnValue = FALSE;
  1509. do
  1510. {
  1511. if ( FALSE == ParStlSelectAdapterSocket(Extension, SOCKET_1) )
  1512. {
  1513. // as the socket 1 selection failed,
  1514. // we break out here.
  1515. break ;
  1516. }
  1517. // check for engine version.
  1518. if ( LS120_ENGINE_VERSION == ParStlReadIoPort( Extension, LS120_ENGINE_VERSION_REGISTER ) )
  1519. {
  1520. // if the ls120 engine version is correct, we have
  1521. // found LS120.
  1522. bReturnValue = TRUE ;
  1523. }
  1524. // Reset the socket to zero.
  1525. ParStlSelectAdapterSocket ( Extension, SOCKET_0 ) ;
  1526. }
  1527. while ( FALSE ) ;
  1528. return bReturnValue ;
  1529. }
  1530. BOOLEAN
  1531. ParStlCheckIfImpactLS120 (
  1532. IN PPDO_EXTENSION Extension,
  1533. IN OUT PATAPIPARAMS atapiParams
  1534. )
  1535. {
  1536. BOOLEAN bReturnValue = FALSE ;
  1537. BOOLEAN bLs120NameFound= TRUE ;
  1538. char chLs120Name[] = "HU DlFpoyp";
  1539. char *pszAtapiName = atapiParams->szAtapiNameString ;
  1540. int i , nMemoryOnBoard ;
  1541. do
  1542. {
  1543. for ( i = 0 ;i < sizeof(chLs120Name)-1 ; i++ )
  1544. {
  1545. if ( pszAtapiName[i] != chLs120Name[i] )
  1546. {
  1547. bLs120NameFound = FALSE ;
  1548. break ;
  1549. }
  1550. }
  1551. if ( TRUE != bLs120NameFound )
  1552. {
  1553. // as LS-120 name string is not found, we conclude that it is
  1554. // not LS-120
  1555. break ;
  1556. }
  1557. nMemoryOnBoard = ParStlGetMemorySize(Extension) ;
  1558. if ( ( !IsShtlError ( nMemoryOnBoard ) ) && \
  1559. ( nMemoryOnBoard ) )
  1560. {
  1561. // there is memory on-board.
  1562. // hence, we return ls120 here
  1563. bReturnValue = TRUE ;
  1564. break ;
  1565. }
  1566. }
  1567. while ( FALSE ) ;
  1568. return bReturnValue ;
  1569. }
  1570. BOOLEAN
  1571. ParStlCheckIfMMC (
  1572. IN PPDO_EXTENSION Extension,
  1573. IN OUT PATAPIPARAMS atapiParams
  1574. )
  1575. {
  1576. BOOLEAN bReturnValue = FALSE;
  1577. do
  1578. {
  1579. if ( FALSE == IsEpatPlusPresent() )
  1580. {
  1581. // as mmc device can exist only on EPAT Plus adapter only
  1582. // we break out of here
  1583. break;
  1584. }
  1585. if ( TRUE == ParStlCheckIfAtaAtapiDevice (Extension,atapiParams) )
  1586. {
  1587. // as an ATA/ATAPI device is probably present,
  1588. // we break out of here
  1589. break;
  1590. }
  1591. bReturnValue = ParStlIsMMCEnginePresent(Extension) ;
  1592. }
  1593. while ( FALSE ) ;
  1594. return bReturnValue ;
  1595. }
  1596. BOOLEAN
  1597. ParStlIsMMCEnginePresent(
  1598. IN PPDO_EXTENSION Extension
  1599. )
  1600. {
  1601. BOOLEAN bReturnValue = FALSE;
  1602. do
  1603. {
  1604. // check if the ATAPI signature is present in the cyl hi/lo
  1605. // registers. If present, it is definitely an ATAPI device
  1606. if ( ( ParStlReadIoPort(Extension, CYLLOW_REG) == ATAPI_SIGN_LOW ) &&\
  1607. ( ParStlReadIoPort(Extension, CYLHIGH_REG) == ATAPI_SIGN_HI ) )
  1608. {
  1609. // as ATAPI signature is present, it cant be MMC
  1610. break ;
  1611. }
  1612. // write a zero pattern ( which will be a NOP for ATA/ATAPI devices )
  1613. // in the block size / possible ATA/ATAPI command register
  1614. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_BLOCK_SIZE_REG);
  1615. ParStlWriteReg(Extension, MMC_ENGINE_DATA, MMC_TEST_PATTERN_1);
  1616. if ( MMC_TEST_PATTERN_1 != ParStlReadReg(Extension, MMC_ENGINE_DATA) )
  1617. {
  1618. // as the written value is not available, it means device present
  1619. // has responded to the written value, in a way different from
  1620. // how an MMC would have.
  1621. break ;
  1622. }
  1623. // write a test pattern in the freq register
  1624. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_FREQ_SELECT_REG);
  1625. ParStlWriteReg(Extension, MMC_ENGINE_DATA, MMC_TEST_PATTERN_2);
  1626. // write another in the block size register
  1627. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_BLOCK_SIZE_REG);
  1628. ParStlWriteReg(Extension, MMC_ENGINE_DATA, MMC_TEST_PATTERN_3);
  1629. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_FREQ_SELECT_REG);
  1630. if ( MMC_TEST_PATTERN_2 != ParStlReadReg(Extension, MMC_ENGINE_DATA) )
  1631. {
  1632. // as we were not able to read back the written value
  1633. // we quit here
  1634. break;
  1635. }
  1636. ParStlWriteReg(Extension, MMC_ENGINE_INDEX, MMC_BLOCK_SIZE_REG);
  1637. if ( MMC_TEST_PATTERN_3 != ParStlReadReg(Extension, MMC_ENGINE_DATA) )
  1638. {
  1639. // as we were not able to read back the written value
  1640. // we quit here
  1641. break;
  1642. }
  1643. // as all tests have passed, engine presence is confirmed
  1644. // here
  1645. bReturnValue = TRUE ;
  1646. }
  1647. while ( FALSE ) ;
  1648. return bReturnValue ;
  1649. }
  1650. BOOLEAN
  1651. ParStlCheckIfScsiDevice (
  1652. IN PPDO_EXTENSION Extension
  1653. )
  1654. {
  1655. BOOLEAN bReturnValue = FALSE;
  1656. do
  1657. {
  1658. if ( FALSE == IsEpstPresent() )
  1659. {
  1660. // as SCSI devices live only on EPST we break here
  1661. break;
  1662. }
  1663. bReturnValue = TRUE ;
  1664. }
  1665. while ( FALSE ) ;
  1666. return bReturnValue ;
  1667. }
  1668. BOOLEAN
  1669. ParStlCheckIfSSFDC (
  1670. IN PPDO_EXTENSION Extension
  1671. )
  1672. {
  1673. BOOLEAN bReturnValue = FALSE;
  1674. do
  1675. {
  1676. if ( FALSE == IsEp1284Present() )
  1677. {
  1678. // SSFDC lives on EP1284 alone, other than impact
  1679. // which is already taken care
  1680. break;
  1681. }
  1682. //check to see if the loop back of the EPCS and EPDO pins
  1683. //of the INDEX 00 register read the same. If so, it is
  1684. //SSFDC board characteristic
  1685. ParStlWriteReg ( Extension, CONFIG_INDEX_REGISTER , 0x00 ) ;
  1686. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , 0x10 ) ;
  1687. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , 0x12 ) ;
  1688. if ( 0x1A == ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) )
  1689. {
  1690. ParStlWriteReg ( Extension, CONFIG_DATA_REGISTER , 0x10 ) ;
  1691. if ( ! ( ParStlReadReg ( Extension, CONFIG_DATA_REGISTER ) & 0x08 ) )
  1692. {
  1693. //as they are equal, SSFDC present
  1694. bReturnValue = TRUE ;
  1695. break ;
  1696. }
  1697. }
  1698. }
  1699. while ( FALSE ) ;
  1700. return bReturnValue ;
  1701. }
  1702. VOID
  1703. ParStlAssertIdleState (
  1704. IN PPDO_EXTENSION Extension
  1705. )
  1706. {
  1707. PUCHAR CurrentPort, CurrentControl ;
  1708. ULONG Delay = 5 ;
  1709. CurrentPort = Extension->Controller;
  1710. CurrentControl = CurrentPort + 2;
  1711. // place op-code for idle state in port base
  1712. P5WritePortUchar ( CurrentPort, (UCHAR) 0x00 ) ;
  1713. KeStallExecutionProcessor( Delay );
  1714. // bring down DCR_INIT and DCR_STROBE
  1715. P5WritePortUchar ( CurrentControl, (UCHAR) STB_INIT_LOW ) ;
  1716. KeStallExecutionProcessor( Delay );
  1717. // lift DCR_INIT and DCR_STROBE to high
  1718. P5WritePortUchar ( CurrentControl, (UCHAR) STB_INIT_AFXT_HI ) ;
  1719. KeStallExecutionProcessor( Delay );
  1720. }
  1721. BOOLEAN
  1722. ParStlCheckAvisionScannerPresence(
  1723. IN PPDO_EXTENSION Extension
  1724. )
  1725. {
  1726. BOOLEAN bReturnValue = FALSE ;
  1727. UCHAR data;
  1728. do {
  1729. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1730. if((data & 0x80) == 0) {
  1731. break ;
  1732. }
  1733. ParStlWriteReg( Extension, CONTROLPORT, 0x08 ) ;
  1734. ParStlWriteReg( Extension, CONTROLPORT, 0x08 ) ;
  1735. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1736. if((data & 0x80) != 0) {
  1737. break ;
  1738. }
  1739. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1740. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1741. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1742. if((data & 0x80) == 0) {
  1743. break ;
  1744. }
  1745. ParStlWriteReg( Extension, CONTROLPORT, 0x02 ) ;
  1746. ParStlWriteReg( Extension, CONTROLPORT, 0x02 ) ;
  1747. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1748. if((data & 0x80) != 0) {
  1749. break ;
  1750. }
  1751. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1752. ParStlWriteReg( Extension, CONTROLPORT, 0x00 ) ;
  1753. data = (UCHAR) ParStlReadReg( Extension, STATUSPORT);
  1754. if((data & 0x80) == 0) {
  1755. break ;
  1756. }
  1757. bReturnValue = TRUE ;
  1758. } while ( FALSE ) ;
  1759. return bReturnValue ;
  1760. }
  1761. BOOLEAN
  1762. ParStlCheckUMAXScannerPresence(
  1763. IN PPDO_EXTENSION Extension
  1764. )
  1765. {
  1766. UCHAR commandPacket_[6] = {0x55,0xaa,0,0,0,0} ;
  1767. PUCHAR commandPacket ;
  1768. USHORT status;
  1769. UCHAR idx;
  1770. PUCHAR saveCommandPacket;
  1771. ULONG dataLength;
  1772. ParStlWriteReg ( Extension, CONTROLPORT, 0 ) ; // scannner reset
  1773. KeStallExecutionProcessor ( 2000 ) ; // 2 m.secs delay
  1774. ParStlWriteReg ( Extension, CONTROLPORT, 0x0C ) ;
  1775. commandPacket = commandPacket_ ;
  1776. saveCommandPacket = commandPacket;
  1777. if ( TRUE == ParStlSetEPPMode(Extension) ) {
  1778. commandPacket+=2;
  1779. dataLength = *(ULONG*)commandPacket;
  1780. dataLength &= 0xffffff; //data bytes ordering (msb to lsb) will
  1781. // wrong .What we need here is whether the
  1782. // dataLength is 0 or not.
  1783. commandPacket = saveCommandPacket;
  1784. //Command phase
  1785. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1786. if((status & 0x700) != 0){
  1787. return FALSE; //TIMEOUT_ERROR);
  1788. }
  1789. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1790. if((status & 0x700 ) != 0){
  1791. return FALSE; //TIMEOUT_ERROR);
  1792. }
  1793. for(idx=0; idx<= 6 ;idx++){
  1794. if(status & 0x800){
  1795. break;
  1796. }
  1797. status = ParStlEPPRead(Extension);
  1798. }
  1799. if(idx == 7){
  1800. status = (status & 0xf800) | 0x100;
  1801. if ( status & 0x700 )
  1802. return FALSE;
  1803. }
  1804. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1805. if((status & 0x700 ) != 0){
  1806. return FALSE; //TIMEOUT_ERROR);
  1807. }
  1808. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1809. if((status & 0x700 ) != 0){
  1810. return FALSE; //TIMEOUT_ERROR);
  1811. }
  1812. status = ParStlEPPWrite(Extension, *(commandPacket)++);
  1813. if((status & 0x700 ) != 0){
  1814. return FALSE; //TIMEOUT_ERROR);
  1815. }
  1816. status = ParStlEPPWrite(Extension, *commandPacket);
  1817. if((status & 0x700 ) != 0){
  1818. return FALSE; //TIMEOUT_ERROR);
  1819. }
  1820. //Response phase
  1821. status = ParStlEPPRead(Extension);
  1822. commandPacket = saveCommandPacket;
  1823. if((status & 0x700) == 0){
  1824. if((commandPacket[5] == 0xc2)&& (dataLength == 0)){
  1825. status = ParStlEPPRead(Extension);
  1826. if((status & 0x0700) != 0){
  1827. return FALSE; //TIMEOUT_ERROR);
  1828. }
  1829. }
  1830. }
  1831. return TRUE;
  1832. }
  1833. return FALSE;
  1834. }
  1835. BOOLEAN
  1836. ParStlSetEPPMode(
  1837. IN PPDO_EXTENSION Extension
  1838. )
  1839. {
  1840. UCHAR idx;
  1841. BOOLEAN timeout = TRUE ;
  1842. ParStlWriteReg( Extension, CONTROLPORT, 0x0C ) ;
  1843. ParStlWriteReg( Extension, DATAPORT, 0x40 ) ;
  1844. ParStlWriteReg( Extension, CONTROLPORT, 0x06 ) ;
  1845. for(idx=0; idx<10; idx++){
  1846. if((ParStlReadReg(Extension, STATUSPORT) & 0x78) == 0x38){
  1847. timeout = FALSE;
  1848. break;
  1849. }
  1850. }
  1851. if(timeout == FALSE){
  1852. ParStlWriteReg( Extension, CONTROLPORT,0x7 );
  1853. timeout = TRUE;
  1854. for(idx=0; idx<10; idx++){
  1855. if((ParStlReadReg( Extension, STATUSPORT) & 0x78) == 0x38){
  1856. timeout = FALSE;
  1857. break;
  1858. }
  1859. }
  1860. if(timeout == FALSE){
  1861. ParStlWriteReg( Extension, CONTROLPORT,0x4 ) ;
  1862. timeout = TRUE;
  1863. for(idx=0; idx<10; idx++){
  1864. if((ParStlReadReg( Extension, STATUSPORT) & 0xf8) == 0xf8){
  1865. timeout = FALSE;
  1866. break;
  1867. }
  1868. }
  1869. if(timeout == FALSE){
  1870. timeout = TRUE;
  1871. ParStlWriteReg( Extension, CONTROLPORT, 0x5 );
  1872. for(idx=0; idx<10; idx++){
  1873. if( ParStlReadReg( Extension, CONTROLPORT ) == 0x5){
  1874. timeout = FALSE;
  1875. break;
  1876. }
  1877. }
  1878. if(timeout == FALSE){
  1879. ParStlWriteReg( Extension, CONTROLPORT, 0x84) ;
  1880. return TRUE ;
  1881. } // final check
  1882. } // third check
  1883. } // second check
  1884. } // first check
  1885. return(FALSE);
  1886. }
  1887. USHORT
  1888. ParStlEPPWrite(
  1889. IN PPDO_EXTENSION Extension,
  1890. IN UCHAR value
  1891. )
  1892. {
  1893. UCHAR idx;
  1894. USHORT statusData = 0;
  1895. BOOLEAN timeout;
  1896. timeout = TRUE;
  1897. for(idx=0; idx<10; idx++){
  1898. if( !( (statusData = (USHORT)ParStlReadReg( Extension, STATUSPORT)) & BUSY)){
  1899. timeout = FALSE;
  1900. break;
  1901. }
  1902. }
  1903. if(timeout == TRUE){
  1904. return(((statusData<<8) & 0xf800)|0x100);
  1905. }
  1906. ParStlWriteReg( Extension, EPPDATA0PORT,value );
  1907. return(((statusData & 0xf8) << 8)|value);
  1908. }
  1909. USHORT
  1910. ParStlEPPRead(
  1911. IN PPDO_EXTENSION Extension
  1912. )
  1913. {
  1914. UCHAR idx;
  1915. UCHAR eppData;
  1916. USHORT statusData = 0;
  1917. BOOLEAN timeout = TRUE ;
  1918. for(idx=0; idx<10; idx++){
  1919. if(!( (statusData = (USHORT)ParStlReadReg( Extension, STATUSPORT)) & PE)){
  1920. timeout = FALSE;
  1921. break;
  1922. }
  1923. }
  1924. if(timeout == TRUE){
  1925. return(((statusData<<8) & 0xf800)|0x100);
  1926. }
  1927. eppData = (UCHAR)ParStlReadReg( Extension, EPPDATA0PORT) ;
  1928. return(((statusData & 0x00f8)<<8) | eppData );
  1929. }
  1930. int __cdecl
  1931. ParStlReadReg (
  1932. IN PPDO_EXTENSION Extension,
  1933. IN unsigned reg
  1934. )
  1935. {
  1936. UCHAR byReadNibble ;
  1937. PUCHAR CurrentPort, CurrentStatus, CurrentControl ;
  1938. ULONG Delay = 5 ;
  1939. CurrentPort = Extension->Controller;
  1940. CurrentStatus = CurrentPort + 1;
  1941. CurrentControl = CurrentPort + 2;
  1942. // select the register to read
  1943. P5WritePortUchar ( CurrentPort, (UCHAR)reg ) ;
  1944. KeStallExecutionProcessor( Delay );
  1945. // issue nibble ctl signals to read
  1946. P5WritePortUchar ( CurrentControl, STB_INIT_LOW ) ;
  1947. KeStallExecutionProcessor( Delay );
  1948. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_LO ) ;
  1949. KeStallExecutionProcessor( Delay );
  1950. // read first nibble
  1951. byReadNibble = P5ReadPortUchar (CurrentStatus);
  1952. KeStallExecutionProcessor( Delay );
  1953. byReadNibble >>= 4 ;
  1954. // issue nibble ctl signals to read
  1955. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_HI ) ;
  1956. KeStallExecutionProcessor( Delay );
  1957. // read next nibble
  1958. byReadNibble |= ( P5ReadPortUchar ( CurrentStatus ) & 0xF0 ) ;
  1959. return (int)byReadNibble ;
  1960. }
  1961. int __cdecl
  1962. ParStlWriteReg (
  1963. IN PPDO_EXTENSION Extension,
  1964. IN unsigned reg,
  1965. IN int databyte
  1966. )
  1967. {
  1968. PUCHAR CurrentPort, CurrentStatus, CurrentControl ;
  1969. ULONG Delay = 5 ;
  1970. CurrentPort = Extension->Controller;
  1971. CurrentStatus = CurrentPort + 1;
  1972. CurrentControl = CurrentPort + 2;
  1973. // select the register to write
  1974. P5WritePortUchar ( CurrentPort, (UCHAR)( reg | 0x60 ) ) ;
  1975. KeStallExecutionProcessor( Delay );
  1976. // write to printer ctl port
  1977. P5WritePortUchar ( CurrentControl, STB_INIT_LOW ) ;
  1978. KeStallExecutionProcessor( Delay );
  1979. // write the requested data
  1980. P5WritePortUchar ( CurrentPort, (UCHAR)databyte ) ;
  1981. KeStallExecutionProcessor( Delay );
  1982. // write to printer ctl port
  1983. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_HI ) ;
  1984. KeStallExecutionProcessor( Delay );
  1985. return SHTL_NO_ERROR ;
  1986. }
  1987. int __cdecl
  1988. ParStlReceiveData (
  1989. IN PPDO_EXTENSION Extension,
  1990. IN VOID *hostBufferPointer,
  1991. IN long shuttleMemoryAddress,
  1992. IN unsigned count
  1993. )
  1994. {
  1995. PCHAR pchDataBuffer = (PCHAR) hostBufferPointer ;
  1996. unsigned int i = 0 ;
  1997. PUCHAR CurrentPort, CurrentStatus, CurrentControl ;
  1998. ULONG Delay = 5 ;
  1999. UNREFERENCED_PARAMETER( shuttleMemoryAddress );
  2000. CurrentPort = Extension->Controller;
  2001. CurrentStatus = CurrentPort + 1;
  2002. CurrentControl = CurrentPort + 2;
  2003. // set the block address register to ATA/ATAPI data register,
  2004. // as this function is currently used ONLY for ATA/ATAPI devices
  2005. // ATA/ATAPI data register 0x1F0 corresponds to 0x18 value
  2006. ParStlWriteReg ( Extension, EP1284_BLK_ADDR_REGISTER, 0x18 ) ;
  2007. // do the nibble block read sequence
  2008. // write the nibble block read op-code
  2009. P5WritePortUchar ( CurrentPort, OP_NIBBLE_BLOCK_READ ) ;
  2010. KeStallExecutionProcessor( Delay );
  2011. // set control ports to correct signals.
  2012. P5WritePortUchar ( CurrentControl, STB_INIT_AFXT_LO ) ;
  2013. KeStallExecutionProcessor( Delay );
  2014. // set data port to 0xFF
  2015. P5WritePortUchar ( CurrentPort, 0xFF ) ;
  2016. KeStallExecutionProcessor( Delay );
  2017. P5WritePortUchar ( CurrentControl, INIT_AFXT_HIGH ) ;
  2018. KeStallExecutionProcessor( Delay );
  2019. do
  2020. {
  2021. // low nibble is available in status after
  2022. // toggling sequences as in EP1284 manual
  2023. P5WritePortUchar ( CurrentControl, AFXT_LO_STB_HI ) ;
  2024. KeStallExecutionProcessor( Delay );
  2025. pchDataBuffer[i] = P5ReadPortUchar( CurrentStatus ) >> 4 ;
  2026. KeStallExecutionProcessor( Delay );
  2027. // high nibble is available in status after
  2028. // toggling sequences as in EP1284 manual
  2029. P5WritePortUchar ( CurrentControl, AFXT_HI_STB_HI ) ;
  2030. KeStallExecutionProcessor( Delay );
  2031. pchDataBuffer[i++] |= ( P5ReadPortUchar ( CurrentStatus ) & 0xF0 ) ;
  2032. KeStallExecutionProcessor( Delay );
  2033. if ( count - 1 == i )
  2034. {
  2035. // to read the last byte
  2036. P5WritePortUchar ( CurrentPort, 0xFD ) ;
  2037. KeStallExecutionProcessor( Delay );
  2038. }
  2039. P5WritePortUchar ( CurrentControl, AFXT_LO_STB_LO ) ;
  2040. KeStallExecutionProcessor( Delay );
  2041. pchDataBuffer[i] = P5ReadPortUchar ( CurrentStatus ) >> 4 ;
  2042. KeStallExecutionProcessor( Delay );
  2043. P5WritePortUchar ( CurrentControl, AFXT_HI_STB_LO ) ;
  2044. KeStallExecutionProcessor( Delay );
  2045. pchDataBuffer[i++] |= ( P5ReadPortUchar ( CurrentStatus ) & 0xF0 ) ;
  2046. KeStallExecutionProcessor( Delay );
  2047. }
  2048. while ( i <= count ) ;
  2049. // clean up
  2050. P5WritePortUchar ( CurrentPort, 0x00 ) ;
  2051. KeStallExecutionProcessor( Delay );
  2052. // done
  2053. return SHTL_NO_ERROR ;
  2054. }
  2055. int __cdecl
  2056. ParStlReadIoPort (
  2057. IN PPDO_EXTENSION Extension,
  2058. IN unsigned reg
  2059. )
  2060. {
  2061. switch ( reg )
  2062. {
  2063. case 0x08 :
  2064. reg = 0x16 ;
  2065. break ;
  2066. case 0x09 :
  2067. reg = 0x17 ;
  2068. break ;
  2069. default :
  2070. reg |= 0x18 ;
  2071. break;
  2072. }
  2073. return ParStlReadReg ( Extension, reg ) ;
  2074. }
  2075. int __cdecl
  2076. ParStlWriteIoPort (
  2077. IN PPDO_EXTENSION Extension,
  2078. IN unsigned reg,
  2079. IN int databyte
  2080. )
  2081. {
  2082. switch ( reg )
  2083. {
  2084. case 0x08 :
  2085. reg = 0x16 ;
  2086. break ;
  2087. case 0x09 :
  2088. reg = 0x17 ;
  2089. break ;
  2090. default :
  2091. reg |= 0x18 ;
  2092. break;
  2093. }
  2094. return ParStlWriteReg ( Extension, reg, databyte ) ;
  2095. }
  2096. int __cdecl
  2097. ParStlGetMemorySize (
  2098. IN PPDO_EXTENSION Extension
  2099. )
  2100. {
  2101. BOOLEAN bReturnValue = FALSE ;
  2102. UCHAR byTempValue ;
  2103. do
  2104. {
  2105. // Issue reset through control register
  2106. // first try on DRAM
  2107. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2108. byTempValue |= ENABLE_MEM|SELECT_DRAM|RESET_PTR ;
  2109. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2110. byTempValue &= ~RESET_PTR ;
  2111. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2112. // write to the first location in the memory
  2113. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_1 ) ;
  2114. // write to the next location in the memory
  2115. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_2 ) ;
  2116. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2117. byTempValue |= ENABLE_MEM|SELECT_DRAM|RESET_PTR ;
  2118. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2119. byTempValue &= ~RESET_PTR ;
  2120. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2121. // read from the first and next location in the memory
  2122. if ( ( TEST_PATTERN_1 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) &&\
  2123. ( TEST_PATTERN_2 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) )
  2124. {
  2125. bReturnValue = TRUE ;
  2126. break ;
  2127. }
  2128. if ( !IsImpactPresent () )
  2129. {
  2130. // as only DRAM can be present on non-impact adapters
  2131. break ;
  2132. }
  2133. // Issue reset through control register
  2134. // and next try on SRAM
  2135. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2136. byTempValue |= ENABLE_MEM|RESET_PTR ;
  2137. byTempValue &= SELECT_SRAM ;
  2138. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2139. byTempValue &= ~RESET_PTR ;
  2140. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2141. // write to the first location in the memory
  2142. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_1 ) ;
  2143. // write to the next location in the memory
  2144. ParStlWriteReg ( Extension, EP1284_BUFFER_DATA_REG, TEST_PATTERN_2 ) ;
  2145. byTempValue = (UCHAR) ParStlReadReg ( Extension, EP1284_CONTROL_REG ) ;
  2146. byTempValue |= ENABLE_MEM|RESET_PTR ;
  2147. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2148. byTempValue &= ~RESET_PTR ;
  2149. ParStlWriteReg ( Extension, EP1284_CONTROL_REG, byTempValue ) ;
  2150. // read from the first location in the memory
  2151. if ( ( TEST_PATTERN_1 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) &&\
  2152. ( TEST_PATTERN_2 == (UCHAR) ParStlReadReg ( Extension, EP1284_BUFFER_DATA_REG ) ) )
  2153. {
  2154. bReturnValue = TRUE ;
  2155. break ;
  2156. }
  2157. }
  2158. while ( FALSE ) ;
  2159. return bReturnValue ;
  2160. }
  2161. // end of file