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.

442 lines
17 KiB

  1. /*
  2. * $Log: $
  3. */
  4. /************************************************************************/
  5. /* */
  6. /* FAT-FTL Lite Software Development Kit */
  7. /* Copyright (C) M-Systems Ltd. 1995-1996 */
  8. /* */
  9. /************************************************************************/
  10. #include "flsocket.h"
  11. #include "scsi.h"
  12. #include "tffsport.h"
  13. #include "INITGUID.H"
  14. #include "ntddpcm.h"
  15. #define ANTI_CRASH_WINDOW
  16. #ifdef ANTI_CRASH_WINDOW
  17. CHAR antiCrashWindow_socketnt[0x2000];
  18. #endif
  19. /*NTsocketParams driveInfo[SOCKETS];
  20. NTsocketParams * pdriveInfo = driveInfo;
  21. */
  22. extern NTsocketParams driveInfo[SOCKETS];
  23. extern NTsocketParams * pdriveInfo;
  24. PCMCIA_INTERFACE_STANDARD driveContext[SOCKETS];
  25. NTSTATUS queryInterfaceCompletionRoutine (
  26. IN PDEVICE_OBJECT DeviceObject,
  27. IN PIRP Irp,
  28. IN PVOID Context
  29. )
  30. {
  31. PKEVENT event = Context;
  32. KeSetEvent(event, EVENT_INCREMENT, FALSE);
  33. return STATUS_MORE_PROCESSING_REQUIRED;
  34. }
  35. NTSTATUS
  36. updatePcmciaSocketParams(PDEVICE_EXTENSION fdoExtension)
  37. {
  38. PIRP irp = NULL;
  39. NTSTATUS status;
  40. //
  41. // Setup a query interface request for the pcmcia pdo
  42. //
  43. irp = IoAllocateIrp(fdoExtension->LowerDeviceObject->StackSize, FALSE);
  44. if (irp)
  45. {
  46. PIO_STACK_LOCATION irpSp;
  47. KEVENT event;
  48. ULONG device = fdoExtension->UnitNumber;
  49. irpSp = IoGetNextIrpStackLocation(irp);
  50. irpSp->MajorFunction = IRP_MJ_PNP;
  51. irpSp->MinorFunction = IRP_MN_QUERY_INTERFACE;
  52. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  53. irpSp->Parameters.QueryInterface.InterfaceType = &GUID_PCMCIA_INTERFACE_STANDARD;
  54. irpSp->Parameters.QueryInterface.Size = sizeof(PCMCIA_INTERFACE_STANDARD);
  55. irpSp->Parameters.QueryInterface.Version = 1;
  56. irpSp->Parameters.QueryInterface.Interface = (PINTERFACE) &driveContext[device];
  57. irpSp->Parameters.QueryInterface.InterfaceSpecificData = NULL;
  58. KeInitializeEvent(&event, NotificationEvent, FALSE);
  59. IoSetCompletionRoutine(irp, queryInterfaceCompletionRoutine, &event, TRUE, TRUE, TRUE);
  60. status = IoCallDriver(fdoExtension->LowerDeviceObject, irp);
  61. if (status == STATUS_PENDING)
  62. {
  63. status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  64. }
  65. status = irp->IoStatus.Status;
  66. IoFreeIrp (irp);
  67. if (NT_SUCCESS(status))
  68. {
  69. driveInfo[device].windowSize = fdoExtension->pcmciaParams.windowSize;
  70. driveInfo[device].physWindow = fdoExtension->pcmciaParams.physWindow;
  71. driveInfo[device].winBase = fdoExtension->pcmciaParams.windowBase;
  72. driveInfo[device].fdoExtension = (PVOID) fdoExtension;
  73. driveInfo[device].interfAlive = 1;
  74. }
  75. }
  76. else
  77. {
  78. status = STATUS_INSUFFICIENT_RESOURCES;
  79. }
  80. return status;
  81. }
  82. /************************************************************************/
  83. /* */
  84. /* Beginning of controller-customizable code */
  85. /* */
  86. /* The function prototypes and interfaces in this section are standard */
  87. /* and are used in this form by the non-customizable code. However, the */
  88. /* function implementations are specific to the 82365SL controller. */
  89. /* */
  90. /* You should replace the function bodies here with the implementation */
  91. /* that is appropriate for your controller. */
  92. /* */
  93. /* All the functions in this section have no parameters. This is */
  94. /* because the parameters needed for an operation may be themselves */
  95. /* depend on the controller. Instead, you should use the value in the */
  96. /* 'vol' structure as parameters. */
  97. /* If you need socket-state variables specific to your implementation, */
  98. /* it is recommended to add them to the 'vol' structure rather than */
  99. /* define them as separate static variables. */
  100. /* */
  101. /************************************************************************/
  102. /*----------------------------------------------------------------------*/
  103. /* c a r d D e t e c t e d */
  104. /* */
  105. /* Detect if a card is present (inserted) */
  106. /* */
  107. /* Parameters: */
  108. /* vol : Pointer identifying drive */
  109. /* */
  110. /* Returns: */
  111. /* 0 = card not present, other = card present */
  112. /*----------------------------------------------------------------------*/
  113. FLBoolean cardDetected_socketnt(FLSocket vol)
  114. {
  115. return TRUE; /* we will know when card is removed */
  116. /*Implemented by upper layers*/
  117. }
  118. /*----------------------------------------------------------------------*/
  119. /* V c c O n */
  120. /* */
  121. /* Turns on Vcc (3.3/5 Volts). Vcc must be known to be good on exit. */
  122. /* */
  123. /* Parameters: */
  124. /* vol : Pointer identifying drive */
  125. /* */
  126. /*----------------------------------------------------------------------*/
  127. VOID VccOn_socketnt(FLSocket vol)
  128. {
  129. }
  130. /*----------------------------------------------------------------------*/
  131. /* V c c O f f */
  132. /* */
  133. /* Turns off Vcc. */
  134. /* */
  135. /* Parameters: */
  136. /* vol : Pointer identifying drive */
  137. /* */
  138. /*----------------------------------------------------------------------*/
  139. VOID VccOff_socketnt(FLSocket vol)
  140. {
  141. }
  142. #ifdef SOCKET_12_VOLTS
  143. /*----------------------------------------------------------------------*/
  144. /* V p p O n */
  145. /* */
  146. /* Turns on Vpp (12 Volts. Vpp must be known to be good on exit. */
  147. /* */
  148. /* Parameters: */
  149. /* vol : Pointer identifying drive */
  150. /* */
  151. /* Returns: */
  152. /* FLStatus : 0 on success, failed otherwise */
  153. /*----------------------------------------------------------------------*/
  154. FLStatus VppOn_socketnt(FLSocket vol)
  155. {
  156. if (driveInfo[vol.volNo].fdoExtension != NULL) {
  157. if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) {
  158. return flVppFailure;
  159. }
  160. }
  161. else
  162. return flVppFailure;
  163. if (driveContext[vol.volNo].SetVpp(driveContext[vol.volNo].Context, PCMCIA_VPP_12V)) {
  164. return flOK;
  165. }
  166. else {
  167. return flVppFailure;
  168. }
  169. }
  170. /*----------------------------------------------------------------------*/
  171. /* V p p O f f */
  172. /* */
  173. /* Turns off Vpp. */
  174. /* */
  175. /* Parameters: */
  176. /* vol : Pointer identifying drive */
  177. /* */
  178. /*----------------------------------------------------------------------*/
  179. VOID VppOff_socketnt(FLSocket vol)
  180. {
  181. if (driveInfo[vol.volNo].fdoExtension != NULL) {
  182. if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) {
  183. return;
  184. }
  185. }
  186. else
  187. return;
  188. if (driveInfo[vol.volNo].interfAlive) {
  189. driveContext[vol.volNo].SetVpp(driveContext[vol.volNo].Context, PCMCIA_VPP_IS_VCC);
  190. }
  191. }
  192. #endif /* SOCKET_12_VOLTS */
  193. /*----------------------------------------------------------------------*/
  194. /* i n i t S o c k e t */
  195. /* */
  196. /* Perform all necessary initializations of the socket or controller */
  197. /* */
  198. /* Parameters: */
  199. /* vol : Pointer identifying drive */
  200. /* */
  201. /* Returns: */
  202. /* FLStatus : 0 on success, failed otherwise */
  203. /*----------------------------------------------------------------------*/
  204. FLStatus initSocket_socketnt(FLSocket vol)
  205. {
  206. return flOK; /* nothing to initialize */
  207. }
  208. /*----------------------------------------------------------------------*/
  209. /* s e t W i n d o w */
  210. /* */
  211. /* Sets in hardware all current window parameters: Base address, size, */
  212. /* speed and bus width. */
  213. /* The requested settings are given in the 'vol.window' structure. */
  214. /* */
  215. /* If it is not possible to set the window size requested in */
  216. /* 'vol.window.size', the window size should be set to a larger value, */
  217. /* if possible. In any case, 'vol.window.size' should contain the */
  218. /* actual window size (in 4 KB units) on exit. */
  219. /* */
  220. /* Parameters: */
  221. /* vol : Pointer identifying drive */
  222. /* */
  223. /*----------------------------------------------------------------------*/
  224. VOID setWindow_socketnt(FLSocket vol)
  225. {
  226. vol.window.size = driveInfo[vol.volNo].windowSize;
  227. vol.window.base = driveInfo[vol.volNo].winBase;
  228. }
  229. /*----------------------------------------------------------------------*/
  230. /* s e t M a p p i n g C o n t e x t */
  231. /* */
  232. /* Sets the window mapping register to a card address. */
  233. /* */
  234. /* The window should be set to the value of 'vol.window.currentPage', */
  235. /* which is the card address divided by 4 KB. An address over 128KB, */
  236. /* (page over 32K) specifies an attribute-space address. */
  237. /* */
  238. /* The page to map is guaranteed to be on a full window-size boundary. */
  239. /* */
  240. /* Parameters: */
  241. /* vol : Pointer identifying drive */
  242. /* */
  243. /*----------------------------------------------------------------------*/
  244. VOID setMappingContext_socketnt(FLSocket vol, unsigned page)
  245. {
  246. UCHAR winSpeed;
  247. if (driveInfo[vol.volNo].fdoExtension != NULL) {
  248. if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) {
  249. #ifdef ANTI_CRASH_WINDOW
  250. vol.window.base = antiCrashWindow_socketnt;
  251. #else
  252. vol.window.base = NULL;
  253. #endif
  254. return;
  255. }
  256. }
  257. else {
  258. #ifdef ANTI_CRASH_WINDOW
  259. vol.window.base = antiCrashWindow_socketnt;
  260. #else
  261. vol.window.base = NULL;
  262. #endif
  263. return;
  264. }
  265. winSpeed = (UCHAR)(4 - ((vol.window.speed - 100) % 50));
  266. driveContext[vol.volNo].ModifyMemoryWindow(driveContext[vol.volNo].Context,
  267. driveInfo[vol.volNo].physWindow,
  268. ((ULONGLONG)page << 12),
  269. FALSE,
  270. vol.window.size,
  271. winSpeed,
  272. (UCHAR)((vol.window.busWidth == 16) ? PCMCIA_MEMORY_16BIT_ACCESS : PCMCIA_MEMORY_8BIT_ACCESS),
  273. FALSE);
  274. if (!(driveContext[vol.volNo].ModifyMemoryWindow(driveContext[vol.volNo].Context,
  275. driveInfo[vol.volNo].physWindow,
  276. ((ULONGLONG)page << 12),
  277. TRUE,
  278. vol.window.size,
  279. winSpeed,
  280. (UCHAR)((vol.window.busWidth == 16) ? PCMCIA_MEMORY_16BIT_ACCESS : PCMCIA_MEMORY_8BIT_ACCESS),
  281. FALSE))) {
  282. #ifdef ANTI_CRASH_WINDOW
  283. vol.window.base = antiCrashWindow_socketnt;
  284. #else
  285. vol.window.base = NULL;
  286. #endif
  287. }
  288. }
  289. /*----------------------------------------------------------------------*/
  290. /* g e t A n d C l e a r C a r d C h a n g e I n d i c a t o r */
  291. /* */
  292. /* Returns the hardware card-change indicator and clears it if set. */
  293. /* */
  294. /* Parameters: */
  295. /* vol : Pointer identifying drive */
  296. /* */
  297. /* Returns: */
  298. /* 0 = Card not changed, other = card changed */
  299. /*----------------------------------------------------------------------*/
  300. FLBoolean getAndClearCardChangeIndicator_socketnt(FLSocket vol)
  301. {
  302. return FALSE;
  303. }
  304. /*----------------------------------------------------------------------*/
  305. /* w r i t e P r o t e c t e d */
  306. /* */
  307. /* Returns the write-protect state of the media */
  308. /* */
  309. /* Parameters: */
  310. /* vol : Pointer identifying drive */
  311. /* */
  312. /* Returns: */
  313. /* 0 = not write-protected, other = write-protected */
  314. /*----------------------------------------------------------------------*/
  315. FLBoolean writeProtected_socketnt(FLSocket vol)
  316. {
  317. if (driveInfo[vol.volNo].fdoExtension != NULL) {
  318. if (((PDEVICE_EXTENSION)driveInfo[vol.volNo].fdoExtension)->DeviceFlags & DEVICE_FLAG_REMOVED) {
  319. return TRUE;
  320. }
  321. }
  322. else
  323. return TRUE;
  324. return driveContext[vol.volNo].IsWriteProtected(driveContext[vol.volNo].Context);
  325. }
  326. #ifdef EXIT
  327. /*----------------------------------------------------------------------*/
  328. /* f r e e S o c k e t */
  329. /* */
  330. /* Free resources that were allocated for this socket. */
  331. /* This function is called when FLite exits. */
  332. /* */
  333. /* Parameters: */
  334. /* vol : Pointer identifying drive */
  335. /* */
  336. /*----------------------------------------------------------------------*/
  337. VOID freeSocket_socketnt(FLSocket vol)
  338. {
  339. }
  340. #endif /* EXIT */
  341. /*----------------------------------------------------------------------*/
  342. /* f l R e g i s t e r P C I C */
  343. /* */
  344. /* Installs routines for the PCIC socket controller. */
  345. /* */
  346. /* Returns: */
  347. /* FLStatus : 0 on success, otherwise failure */
  348. /*----------------------------------------------------------------------*/
  349. FLStatus flRegisterNT5PCIC()
  350. {
  351. LONG serialNo = 0;
  352. for (; noOfSockets < SOCKETS; noOfSockets++) {
  353. FLSocket vol = flSocketOf(noOfSockets);
  354. vol.volNo = noOfSockets;
  355. vol.serialNo = serialNo;
  356. vol.cardDetected = cardDetected_socketnt;
  357. vol.VccOn = VccOn_socketnt;
  358. vol.VccOff = VccOff_socketnt;
  359. #ifdef SOCKET_12_VOLTS
  360. vol.VppOn = VppOn_socketnt;
  361. vol.VppOff = VppOff_socketnt;
  362. #endif
  363. vol.initSocket = initSocket_socketnt;
  364. vol.setWindow = setWindow_socketnt;
  365. vol.setMappingContext = setMappingContext_socketnt;
  366. vol.getAndClearCardChangeIndicator = getAndClearCardChangeIndicator_socketnt;
  367. vol.writeProtected = writeProtected_socketnt;
  368. #ifdef EXIT
  369. vol.freeSocket = freeSocket_socketnt;
  370. #endif
  371. PRINTF("Debug: flRegisterNT5PCIC():Socket No %d is register.\n", noOfSockets);
  372. }
  373. if (noOfSockets == 0)
  374. return flAdapterNotFound;
  375. return flOK;
  376. }