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

308 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. enum.c
  5. Abstract:
  6. This module contains the bus enum code for SDBUS driver
  7. Authors:
  8. Neil Sandlin (neilsa) 1-Jan-2002
  9. Environment:
  10. Kernel mode only
  11. Notes:
  12. Revision History:
  13. --*/
  14. #include "pch.h"
  15. //
  16. // Internal References
  17. //
  18. NTSTATUS
  19. SdbusCreatePdo(
  20. IN PDEVICE_OBJECT Fdo,
  21. OUT PDEVICE_OBJECT *PdoPtr
  22. );
  23. #ifdef ALLOC_PRAGMA
  24. #pragma alloc_text(PAGE, SdbusEnumerateDevices)
  25. #pragma alloc_text(PAGE, SdbusCreatePdo)
  26. #endif
  27. NTSTATUS
  28. SdbusEnumerateDevices(
  29. IN PDEVICE_OBJECT Fdo,
  30. IN PIRP Irp
  31. )
  32. /*++
  33. Routine Description:
  34. This enumerates the sd bus which is represented by Fdo (a pointer to the device object representing
  35. the sd controller. It creates new PDOs for any new PC-Cards which have been discovered
  36. since the last enumeration
  37. Notes:
  38. Arguments:
  39. Fdo - Pointer to the functional device object for the SD controller which needs to be enumerated
  40. Return value:
  41. None
  42. --*/
  43. {
  44. PFDO_EXTENSION fdoExtension = Fdo->DeviceExtension;
  45. PPDO_EXTENSION pdoExtension = NULL;
  46. PDEVICE_OBJECT pdo;
  47. NTSTATUS status = STATUS_SUCCESS;
  48. ULONG i;
  49. PDEVICE_OBJECT nextPdo;
  50. PSD_CARD_DATA cardData;
  51. ULONG response;
  52. PAGED_CODE();
  53. DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x enumerate devices - %s\n", Fdo,
  54. SOCKET_STATE_STRING(fdoExtension->SocketState)));
  55. switch(fdoExtension->SocketState) {
  56. case SOCKET_EMPTY:
  57. // mark pdo's removed
  58. for (pdo = fdoExtension->PdoList; pdo != NULL; pdo = pdoExtension->NextPdoInFdoChain) {
  59. pdoExtension = pdo->DeviceExtension;
  60. MarkDevicePhysicallyRemoved(pdoExtension);
  61. }
  62. //ISSUE: NEED TO IMPLEMENT SYNCHRONIZATION
  63. SdbusCleanupCardData(fdoExtension->CardData);
  64. fdoExtension->CardData = NULL;
  65. SdbusExecuteWorkSynchronous(SDWP_POWER_OFF, fdoExtension, NULL);
  66. (*(fdoExtension->FunctionBlock->SetFunctionType))(fdoExtension, SDBUS_FUNCTION_TYPE_MEMORY);
  67. break;
  68. case CARD_NEEDS_ENUMERATION:
  69. status = SdbusGetCardConfigData(fdoExtension, &cardData);
  70. //ISSUE: HACKHACK: UNIMPLEMENTED: temp code for test
  71. if (NT_SUCCESS(status) && fdoExtension->CardData) {
  72. // here we cheat, and just assume it is the same card
  73. // Normally we would want to compare the carddata we just
  74. // built with what was in the fdo extension.
  75. SdbusCleanupCardData(cardData);
  76. break;
  77. }
  78. if (!NT_SUCCESS(status)) {
  79. DebugPrint((SDBUS_DEBUG_FAIL, "fdo %08x error from GetCardConfig %08x\n", Fdo, status));
  80. break;
  81. }
  82. if (NT_SUCCESS(status)) {
  83. UCHAR function;
  84. //ISSUE: would be better here to loop through the function data structures
  85. for (function=1; function <= fdoExtension->numFunctions; function++) {
  86. status = SdbusCreatePdo(fdoExtension->DeviceObject, &pdo);
  87. if (!NT_SUCCESS(status)) {
  88. return status;
  89. }
  90. DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x created PDO %08x\n", fdoExtension->DeviceObject, pdo));
  91. //
  92. // initialize the pointers
  93. //
  94. pdoExtension = pdo->DeviceExtension;
  95. pdoExtension->NextPdoInFdoChain = fdoExtension->PdoList;
  96. fdoExtension->PdoList = pdo;
  97. pdoExtension->FdoExtension = fdoExtension;
  98. pdoExtension->Function = function;
  99. pdoExtension->FunctionType = SDBUS_FUNCTION_TYPE_IO;
  100. }
  101. if (fdoExtension->memFunction) {
  102. status = SdbusCreatePdo(fdoExtension->DeviceObject, &pdo);
  103. if (!NT_SUCCESS(status)) {
  104. return status;
  105. }
  106. DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x created PDO %08x\n", fdoExtension->DeviceObject, pdo));
  107. //
  108. // initialize the pointers
  109. //
  110. pdoExtension = pdo->DeviceExtension;
  111. pdoExtension->NextPdoInFdoChain = fdoExtension->PdoList;
  112. fdoExtension->PdoList = pdo;
  113. pdoExtension->FdoExtension = fdoExtension;
  114. pdoExtension->Function = 8;
  115. pdoExtension->FunctionType = SDBUS_FUNCTION_TYPE_MEMORY;
  116. }
  117. fdoExtension->CardData = cardData;
  118. }
  119. break;
  120. case CARD_DETECTED:
  121. case CARD_ACTIVE:
  122. case CARD_LOGICALLY_REMOVED:
  123. DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x enum state %s not implemented\n", Fdo,
  124. SOCKET_STATE_STRING(fdoExtension->SocketState)));
  125. break;
  126. default:
  127. ASSERT(FALSE);
  128. }
  129. fdoExtension->LivePdoCount = 0;
  130. for (pdo = fdoExtension->PdoList; pdo != NULL; pdo = pdoExtension->NextPdoInFdoChain) {
  131. pdoExtension = pdo->DeviceExtension;
  132. if (!IsDevicePhysicallyRemoved(pdoExtension)) {
  133. fdoExtension->LivePdoCount++;
  134. }
  135. }
  136. DebugPrint((SDBUS_DEBUG_ENUM, "fdo %08x live pdo count = %d\n", Fdo, fdoExtension->LivePdoCount));
  137. if (fdoExtension->LivePdoCount == 0) {
  138. //
  139. // ISSUE: active power management not implemented
  140. // Hint for the controller to check if it should turn itself off
  141. //
  142. // SdbusFdoCheckForIdle(fdoExtension);
  143. }
  144. return status;
  145. }
  146. NTSTATUS
  147. SdbusCreatePdo(
  148. IN PDEVICE_OBJECT Fdo,
  149. OUT PDEVICE_OBJECT *PdoPtr
  150. )
  151. /*++
  152. Routine Description:
  153. Creates and initializes a device object - which will be referred to as a Physical Device
  154. Object or PDO - for the PC-Card in the socket represented by Socket, hanging off the SDBUS
  155. controller represented by Fdo.
  156. Arguments:
  157. Fdo - Functional device object representing the SDBUS controller
  158. Socket - Socket in which the PC-Card for which we're creating a PDO resides
  159. PdoPtr - Pointer to an area of memory where the created PDO is returned
  160. Return value:
  161. STATUS_SUCCESS - Pdo creation/initialization successful, PdoPtr contains the pointer
  162. to the Pdo
  163. Any other status - creation/initialization unsuccessful
  164. --*/
  165. {
  166. ULONG pdoNameIndex = 0;
  167. PPDO_EXTENSION pdoExtension;
  168. PFDO_EXTENSION fdoExtension=Fdo->DeviceExtension;
  169. char deviceName[128];
  170. ANSI_STRING ansiName;
  171. UNICODE_STRING unicodeName;
  172. NTSTATUS status;
  173. PAGED_CODE();
  174. //
  175. // Allocate space for the Unicode string:(handles upto 0xFFFF
  176. // devices for now :)
  177. //
  178. sprintf(deviceName, "%s-%d", "\\Device\\SdBus", 0xFFFF);
  179. RtlInitAnsiString(&ansiName, deviceName);
  180. status = RtlAnsiStringToUnicodeString(&unicodeName, &ansiName, TRUE);
  181. if (!NT_SUCCESS(status)) {
  182. return status;
  183. }
  184. //
  185. // Attempt to create the device with a unique name
  186. //
  187. do {
  188. sprintf(deviceName, "%s-%d", "\\Device\\SdBus", pdoNameIndex++);
  189. RtlInitAnsiString(&ansiName, deviceName);
  190. status = RtlAnsiStringToUnicodeString(&unicodeName, &ansiName, FALSE);
  191. if (!NT_SUCCESS(status)) {
  192. RtlFreeUnicodeString(&unicodeName);
  193. return status;
  194. }
  195. status = IoCreateDevice(
  196. Fdo->DriverObject,
  197. sizeof(PDO_EXTENSION),
  198. &unicodeName,
  199. FILE_DEVICE_UNKNOWN,
  200. 0,
  201. FALSE,
  202. PdoPtr
  203. );
  204. } while ((status == STATUS_OBJECT_NAME_EXISTS) ||
  205. (status == STATUS_OBJECT_NAME_COLLISION));
  206. RtlFreeUnicodeString(&unicodeName);
  207. if (!NT_SUCCESS(status)) {
  208. return status;
  209. }
  210. //
  211. // Initialize the device extension for the PDO
  212. //
  213. pdoExtension = (*PdoPtr)->DeviceExtension;
  214. RtlZeroMemory(pdoExtension, sizeof(PDO_EXTENSION));
  215. pdoExtension->Signature = SDBUS_PDO_EXTENSION_SIGNATURE;
  216. pdoExtension->DeviceObject = *PdoPtr;
  217. //
  218. // Initialize power states
  219. //
  220. pdoExtension->SystemPowerState = PowerSystemWorking;
  221. pdoExtension->DevicePowerState = PowerDeviceD0;
  222. //
  223. // ISSUE: Is this still relevant?
  224. //
  225. // PNP is going to mark the PDO as a DO_BUS_ENUMERATED_DEVICE,
  226. // but for CardBus cards- the PDO we return is owned by PCI.
  227. // Hence we need to mark this device object (in that case a
  228. // filter on top of PCI's PDO) as PDO explicitly.
  229. //
  230. // MARK_AS_PDO(*PdoPtr);
  231. return STATUS_SUCCESS;
  232. }