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.

308 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. ioctl.c
  5. Abstract:
  6. This module handles device ioctl's to the pcmcia driver.
  7. Authors:
  8. Ravisankar Pudipeddi (ravisp) Oct 15 1996
  9. Neil Sandlin (neilsa) 1-Jun-1999
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. --*/
  14. #include "pch.h"
  15. NTSTATUS
  16. PcmciaDeviceControl(
  17. IN PDEVICE_OBJECT DeviceObject,
  18. IN PIRP Irp
  19. )
  20. /*++
  21. Routine Description:
  22. IOCTL device routine
  23. Arguments:
  24. DeviceObject - Pointer to the device object.
  25. Irp - Pointer to the IRP
  26. Return Value:
  27. Status
  28. --*/
  29. {
  30. PFDO_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  31. PDEVICE_OBJECT pdo;
  32. PPDO_EXTENSION pdoExtension;
  33. PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
  34. NTSTATUS status = STATUS_SUCCESS;
  35. ULONG index;
  36. PSOCKET socket;
  37. USHORT socketNum;
  38. PUCHAR buffer;
  39. ULONG bufferSize;
  40. DebugPrint((PCMCIA_DEBUG_IOCTL, "PcmciaDeviceControl: Entered\n"));
  41. //
  42. // Every request requires an input buffer.
  43. //
  44. if (!Irp->AssociatedIrp.SystemBuffer ||
  45. (currentIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(TUPLE_REQUEST))) {
  46. Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  47. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  48. return STATUS_INVALID_PARAMETER;
  49. }
  50. socketNum = ((PTUPLE_REQUEST)Irp->AssociatedIrp.SystemBuffer)->Socket;
  51. //
  52. // Find the socket pointer for the requested offset.
  53. //
  54. socket = deviceExtension->SocketList;
  55. index = 0;
  56. while (socket) {
  57. if (index == socketNum) {
  58. break;
  59. }
  60. socket = socket->NextSocket;
  61. index++;
  62. }
  63. if (socket == NULL) {
  64. status = STATUS_INVALID_PARAMETER;
  65. Irp->IoStatus.Status = status;
  66. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  67. return status;
  68. }
  69. pdo = socket->PdoList;
  70. if (pdo == NULL) {
  71. status = STATUS_UNSUCCESSFUL;
  72. Irp->IoStatus.Status = status;
  73. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  74. return status;
  75. }
  76. pdoExtension = pdo->DeviceExtension;
  77. switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode) {
  78. case IOCTL_GET_TUPLE_DATA: {
  79. DebugPrint((PCMCIA_DEBUG_IOCTL, "Get Tuple Data\n"));
  80. try {
  81. ULONG bufLen = currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
  82. //
  83. // Zero the target buffer
  84. //
  85. RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, bufLen);
  86. Irp->IoStatus.Information = (*(socket->SocketFnPtr->PCBReadCardMemory))(pdoExtension,
  87. PCCARD_ATTRIBUTE_MEMORY,
  88. 0,
  89. Irp->AssociatedIrp.SystemBuffer,
  90. bufLen);
  91. }except(EXCEPTION_EXECUTE_HANDLER) {
  92. status = GetExceptionCode();
  93. }
  94. break;
  95. }
  96. case IOCTL_SOCKET_INFORMATION: {
  97. PPCMCIA_SOCKET_INFORMATION infoRequest;
  98. DebugPrint((PCMCIA_DEBUG_IOCTL, "socket info\n"));
  99. infoRequest = (PPCMCIA_SOCKET_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
  100. if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PCMCIA_SOCKET_INFORMATION)) {
  101. status = STATUS_BUFFER_TOO_SMALL;
  102. break;
  103. }
  104. //
  105. // Insure caller data is zero - maintain value for socket.
  106. //
  107. index = (ULONG) infoRequest->Socket;
  108. RtlZeroMemory(infoRequest, sizeof(PCMCIA_SOCKET_INFORMATION));
  109. infoRequest->Socket = (USHORT) index;
  110. //
  111. // Only if there is a card in the socket does this proceed.
  112. //
  113. PCMCIA_ACQUIRE_DEVICE_LOCK(socket->DeviceExtension);
  114. infoRequest->CardInSocket =
  115. (*(socket->SocketFnPtr->PCBDetectCardInSocket))(socket);
  116. infoRequest->CardEnabled = (UCHAR) IsSocketFlagSet(pdoExtension->Socket, SOCKET_CARD_CONFIGURED);
  117. PCMCIA_RELEASE_DEVICE_LOCK(socket->DeviceExtension);
  118. if (infoRequest->CardInSocket) {
  119. PSOCKET_DATA socketData = pdoExtension->SocketData;
  120. //
  121. // For now returned the cached data.
  122. //
  123. if (socketData) {
  124. RtlMoveMemory(&infoRequest->Manufacturer[0], &socketData->Mfg[0], MANUFACTURER_NAME_LENGTH);
  125. RtlMoveMemory(&infoRequest->Identifier[0], &socketData->Ident[0], DEVICE_IDENTIFIER_LENGTH);
  126. infoRequest->TupleCrc = socketData->CisCrc;
  127. infoRequest->DeviceFunctionId = socketData->DeviceType;
  128. }
  129. }
  130. infoRequest->ControllerType = deviceExtension->ControllerType;
  131. Irp->IoStatus.Information = sizeof(PCMCIA_SOCKET_INFORMATION);
  132. break;
  133. }
  134. #if 0
  135. case IOCTL_PCMCIA_TEST: {
  136. PPCMCIA_TEST_INFORMATION testRequest;
  137. PDO_EXTENSION TestPdoExtension = {0};
  138. UCHAR attributeBuffer[] = {1, 2, 0, 0xff, 3, 0, 0xff, 0xff};
  139. UCHAR indirectBuffer[] = {0x13, 3, 0x43, 0x49, 0x53, 0x15, 0x2d, 5};
  140. ULONG index;
  141. DebugPrint((PCMCIA_DEBUG_IOCTL, "driver test\n"));
  142. //
  143. // TEST CODE
  144. // Check the CIS of the Margi DVD-to-go card
  145. // This card has the CIS in attribute indirect memory, and was having problems
  146. // on ToPIC controllers.
  147. //
  148. testRequest = (PPCMCIA_TEST_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
  149. if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PCMCIA_TEST_INFORMATION)) {
  150. status = STATUS_BUFFER_TOO_SMALL;
  151. break;
  152. }
  153. //
  154. // Insure caller data is zero - maintain value for socket.
  155. //
  156. index = (ULONG) testRequest->Socket;
  157. RtlZeroMemory(testRequest, sizeof(PCMCIA_TEST_INFORMATION));
  158. testRequest->Socket = (USHORT) index;
  159. if (!(*(socket->SocketFnPtr->PCBDetectCardInSocket))(socket)) {
  160. DebugPrint((PCMCIA_DEBUG_FAIL, "driver test: abort because no card\n"));
  161. status = STATUS_NOT_FOUND;
  162. break;
  163. }
  164. if (IsDeviceStarted(pdoExtension)) {
  165. DebugPrint((PCMCIA_DEBUG_FAIL, "driver test: abort because the pdo is started\n"));
  166. status = STATUS_INVALID_DEVICE_STATE;
  167. break;
  168. }
  169. if (IsSocketFlagSet(socket, SOCKET_CARD_POWERED_UP)) {
  170. PcmciaSetSocketPower(socket, NULL, NULL, PCMCIA_POWEROFF);
  171. }
  172. status = PcmciaSetSocketPower(socket, NULL, NULL, PCMCIA_POWERON);
  173. if (!NT_SUCCESS(status)) {
  174. DebugPrint((PCMCIA_DEBUG_FAIL, "driver test: abort because powerup failed\n"));
  175. break;
  176. }
  177. TestPdoExtension.Socket = socket;
  178. //
  179. // Read in attribute memory
  180. //
  181. for (index = 0; index <= 7; index++) {
  182. if (attributeBuffer[index] != PcmciaReadCISChar(&TestPdoExtension, PCCARD_ATTRIBUTE_MEMORY, index)) {
  183. status = STATUS_UNSUCCESSFUL;
  184. DebugPrint((PCMCIA_DEBUG_FAIL, "driver test: abort because attribute memory test failed\n"));
  185. break;
  186. }
  187. }
  188. if (!NT_SUCCESS(status)) {
  189. break;
  190. }
  191. //
  192. // Try Common memory
  193. //
  194. if (0xff != PcmciaReadCISChar(&TestPdoExtension, PCCARD_COMMON_MEMORY, 0)) {
  195. status = STATUS_UNSUCCESSFUL;
  196. DebugPrint((PCMCIA_DEBUG_FAIL, "driver test: abort because attribute memory test failed\n"));
  197. break;
  198. }
  199. //
  200. // Read in attribute memory indirect
  201. //
  202. for (index = 0; index <= 7; index++) {
  203. if (indirectBuffer[index] != PcmciaReadCISChar(&TestPdoExtension, PCCARD_ATTRIBUTE_MEMORY_INDIRECT, index)) {
  204. status = STATUS_UNSUCCESSFUL;
  205. DebugPrint((PCMCIA_DEBUG_FAIL, "driver test: abort because attribute memory indirect test failed\n"));
  206. break;
  207. }
  208. }
  209. if (!NT_SUCCESS(status)) {
  210. break;
  211. }
  212. PcmciaSetSocketPower(socket, NULL, NULL, PCMCIA_POWEROFF);
  213. testRequest->TestData = 0x123;
  214. Irp->IoStatus.Information = sizeof(PCMCIA_TEST_INFORMATION);
  215. break;
  216. }
  217. #endif
  218. default: {
  219. status = STATUS_INVALID_PARAMETER;
  220. break;
  221. }
  222. }
  223. Irp->IoStatus.Status = status;
  224. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  225. return status;
  226. }