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.

2868 lines
96 KiB

  1. /*--------------------------------------------------------------------------
  2. *
  3. * Copyright (C) Cyclades Corporation, 2000-2001.
  4. * All rights reserved.
  5. *
  6. * Cyclades-Z Enumerator Driver
  7. *
  8. * This file: pnp.c
  9. *
  10. * Description: This module contains contains the plugplay calls
  11. * PNP / WDM BUS driver.
  12. *
  13. * Notes: This code supports Windows 2000 and Windows XP,
  14. * x86 and ia64 processors.
  15. *
  16. * Complies with Cyclades SW Coding Standard rev 1.3.
  17. *
  18. *--------------------------------------------------------------------------
  19. */
  20. /*-------------------------------------------------------------------------
  21. *
  22. * Change History
  23. *
  24. *--------------------------------------------------------------------------
  25. * Initial implementation based on Microsoft sample code.
  26. *
  27. *--------------------------------------------------------------------------
  28. */
  29. #include "pch.h"
  30. static const PHYSICAL_ADDRESS CyzPhysicalZero = {0};
  31. // FANNY_ADDPAGABLE_LATER
  32. //#ifdef ALLOC_PRAGMA
  33. //#pragma alloc_text (PAGE, Cycladz_AddDevice)
  34. //#pragma alloc_text (PAGE, Cycladz_PnP)
  35. //#pragma alloc_text (PAGE, Cycladz_FDO_PnP)
  36. //#pragma alloc_text (PAGE, Cycladz_PDO_PnP)
  37. //#pragma alloc_text (PAGE, Cycladz_PnPRemove)
  38. //#pragma alloc_text (PAGE, Cycladz_StartDevice)
  39. ////#pragma alloc_text (PAGE, Cycladz_Remove)
  40. //#endif
  41. NTSTATUS
  42. Cycladz_AddDevice(
  43. IN PDRIVER_OBJECT DriverObject,
  44. IN PDEVICE_OBJECT BusPhysicalDeviceObject
  45. )
  46. /*++
  47. Routine Description.
  48. A bus has been found. Attach our FDO to it.
  49. Allocate any required resources. Set things up. And be prepared for the
  50. first ``start device.''
  51. Arguments:
  52. DriverObject - This very self referenced driver.
  53. BusPhysicalDeviceObject - Device object representing the bus. That to which
  54. we attach a new FDO.
  55. --*/
  56. {
  57. NTSTATUS status;
  58. PDEVICE_OBJECT deviceObject;
  59. PFDO_DEVICE_DATA DeviceData;
  60. ULONG nameLength;
  61. ULONG i;
  62. INTERFACE_TYPE interfaceType;
  63. ULONG interfaceTypeLength;
  64. ULONG uiNumber,uiNumberLength;
  65. PAGED_CODE ();
  66. Cycladz_KdPrint_Def (SER_DBG_PNP_TRACE, ("Add Device: 0x%x\n",
  67. BusPhysicalDeviceObject));
  68. //
  69. // Create our FDO
  70. //
  71. status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_DATA), NULL,
  72. FILE_DEVICE_BUS_EXTENDER, 0, TRUE, &deviceObject);
  73. if (NT_SUCCESS (status)) {
  74. DeviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
  75. RtlFillMemory (DeviceData, sizeof (FDO_DEVICE_DATA), 0);
  76. DeviceData->IsFDO = TRUE;
  77. DeviceData->DebugLevel = SER_DEFAULT_DEBUG_OUTPUT_LEVEL;
  78. DeviceData->Self = deviceObject;
  79. DeviceData->DriverObject = DriverObject;
  80. for (i=0; i<CYZ_MAX_PORTS; i++) {
  81. DeviceData->AttachedPDO[i] = NULL;
  82. }
  83. DeviceData->NumPDOs = 0;
  84. DeviceData->DeviceState = PowerDeviceD0;
  85. DeviceData->SystemState = PowerSystemWorking; // FANNY: This seems to be not needed
  86. DeviceData->SystemWake=PowerSystemUnspecified;
  87. DeviceData->DeviceWake=PowerDeviceUnspecified;
  88. INITIALIZE_PNP_STATE(DeviceData);
  89. // Set the PDO for use with PlugPlay functions
  90. DeviceData->UnderlyingPDO = BusPhysicalDeviceObject;
  91. //
  92. // Attach our filter driver to the device stack.
  93. // the return value of IoAttachDeviceToDeviceStack is the top of the
  94. // attachment chain. This is where all the IRPs should be routed.
  95. //
  96. // Our filter will send IRPs to the top of the stack and use the PDO
  97. // for all PlugPlay functions.
  98. //
  99. DeviceData->TopOfStack
  100. = IoAttachDeviceToDeviceStack(deviceObject, BusPhysicalDeviceObject);
  101. deviceObject->Flags |= DO_BUFFERED_IO;
  102. // Bias outstanding request to 1 so that we can look for a
  103. // transition to zero when processing the remove device PlugPlay IRP.
  104. DeviceData->OutstandingIO = 1;
  105. KeInitializeEvent(&DeviceData->RemoveEvent, SynchronizationEvent,
  106. FALSE);
  107. //
  108. // Tell the PlugPlay system that this device will need an interface
  109. // device class shingle.
  110. //
  111. // It may be that the driver cannot hang the shingle until it starts
  112. // the device itself, so that it can query some of its properties.
  113. // (Aka the shingles guid (or ref string) is based on the properties
  114. // of the device.)
  115. //
  116. status = IoRegisterDeviceInterface (BusPhysicalDeviceObject,
  117. (LPGUID) &GUID_CYCLADESZ_BUS_ENUMERATOR,
  118. NULL,
  119. &DeviceData->DevClassAssocName);
  120. if (!NT_SUCCESS (status)) {
  121. CyzLogError(DriverObject, NULL, CyzPhysicalZero, CyzPhysicalZero,
  122. 0, 0, 0, 0, status, CYZ_REGISTER_INTERFACE_FAILURE,
  123. 0, NULL, 0, NULL);
  124. Cycladz_KdPrint_Def (SER_DBG_PNP_ERROR,
  125. ("AddDevice: IoRegisterDCA failed (%x)", status));
  126. goto CycladzAddDevice_Error;
  127. }
  128. //
  129. // If for any reason you need to save values in a safe location that
  130. // clients of this DeviceClassAssociate might be interested in reading
  131. // here is the time to do so, with the function
  132. // IoOpenDeviceClassRegistryKey
  133. // the symbolic link name used is was returned in
  134. // DeviceData->DevClassAssocName (the same name which is returned by
  135. // IoGetDeviceClassAssociations and the SetupAPI equivs.
  136. //
  137. #if DBG
  138. {
  139. PWCHAR deviceName = NULL;
  140. status = IoGetDeviceProperty (BusPhysicalDeviceObject,
  141. DevicePropertyPhysicalDeviceObjectName,0,
  142. NULL,&nameLength);
  143. if ((nameLength != 0) && (status == STATUS_BUFFER_TOO_SMALL)) {
  144. deviceName = ExAllocatePool (NonPagedPool, nameLength);
  145. if (NULL == deviceName) {
  146. goto someDebugStuffExit;
  147. }
  148. IoGetDeviceProperty (BusPhysicalDeviceObject,
  149. DevicePropertyPhysicalDeviceObjectName,
  150. nameLength, deviceName, &nameLength);
  151. Cycladz_KdPrint_Def (SER_DBG_PNP_TRACE,
  152. ("AddDevice: %x to %x->%x (%ws) \n",
  153. deviceObject, DeviceData->TopOfStack,
  154. BusPhysicalDeviceObject, deviceName));
  155. }
  156. someDebugStuffExit:;
  157. if (deviceName != NULL) {
  158. ExFreePool(deviceName);
  159. }
  160. }
  161. #endif
  162. DeviceData->IsPci = 1; // Z is always PCI
  163. status = IoGetDeviceProperty (BusPhysicalDeviceObject,
  164. DevicePropertyUINumber ,
  165. sizeof(uiNumber),
  166. &uiNumber,
  167. &uiNumberLength);
  168. if (!NT_SUCCESS (status)) {
  169. uiNumber = 0xFFFFFFFF;
  170. Cycladz_KdPrint_Def (SER_DBG_PNP_ERROR,
  171. ("AddDevice: IoGetDeviceProperty DevicePropertyUINumber failed (%x)",
  172. status));
  173. }
  174. DeviceData->UINumber = uiNumber;
  175. //
  176. // Turn on the shingle and point it to the given device object.
  177. //
  178. status = IoSetDeviceInterfaceState (
  179. &DeviceData->DevClassAssocName,
  180. TRUE);
  181. if (!NT_SUCCESS (status)) {
  182. Cycladz_KdPrint_Def (SER_DBG_PNP_ERROR,
  183. ("AddDevice: IoSetDeviceClass failed (%x)", status));
  184. //return status;
  185. goto CycladzAddDevice_Error;
  186. }
  187. deviceObject->Flags |= DO_POWER_PAGABLE;
  188. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  189. } else {
  190. CyzLogError(DriverObject, NULL, CyzPhysicalZero, CyzPhysicalZero,
  191. 0, 0, 0, 0, status, CYZ_DEVICE_CREATION_FAILURE,
  192. 0, NULL, 0, NULL);
  193. }
  194. return status;
  195. CycladzAddDevice_Error:
  196. if (DeviceData->DevClassAssocName.Buffer) {
  197. RtlFreeUnicodeString(&DeviceData->DevClassAssocName);
  198. }
  199. if (DeviceData->TopOfStack) {
  200. IoDetachDevice(DeviceData->TopOfStack);
  201. }
  202. if (deviceObject) {
  203. IoDeleteDevice(deviceObject);
  204. }
  205. return status;
  206. }
  207. NTSTATUS
  208. Cycladz_PnP (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  209. /*++
  210. Routine Description:
  211. Answer the plethora of Irp Major PnP IRPS.
  212. --*/
  213. {
  214. PIO_STACK_LOCATION irpStack;
  215. NTSTATUS status;
  216. PCOMMON_DEVICE_DATA commonData;
  217. KIRQL oldIrq;
  218. #if DBG
  219. UCHAR MinorFunction;
  220. #endif
  221. PAGED_CODE ();
  222. irpStack = IoGetCurrentIrpStackLocation (Irp);
  223. ASSERT (irpStack->MajorFunction == IRP_MJ_PNP);
  224. #if DBG
  225. MinorFunction = irpStack->MinorFunction;
  226. #endif
  227. commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
  228. //
  229. // If removed, fail the request and get out
  230. //
  231. if (commonData->DevicePnPState == Deleted) { // if (commonData->Removed) added in build 2072.
  232. Cycladz_KdPrint(commonData, SER_DBG_PNP_TRACE,
  233. ("PNP: removed DO: %x got IRP: %x\n", DeviceObject,
  234. Irp));
  235. Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE;
  236. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  237. goto PnPDone;
  238. }
  239. //
  240. // Call either the FDO or PDO Pnp code
  241. //
  242. if (commonData->IsFDO) {
  243. Cycladz_KdPrint(commonData, SER_DBG_PNP_TRACE,
  244. ("FDO(%x):%s IRP:%x\n", DeviceObject,
  245. PnPMinorFunctionString(irpStack->MinorFunction),Irp));
  246. status = Cycladz_FDO_PnP(DeviceObject, Irp, irpStack,
  247. (PFDO_DEVICE_DATA) commonData);
  248. goto PnPDone;
  249. }
  250. //
  251. // PDO
  252. //
  253. Cycladz_KdPrint(commonData, SER_DBG_PNP_TRACE,
  254. ("PDO(%x):%s IRP:%x\n", DeviceObject,
  255. PnPMinorFunctionString(irpStack->MinorFunction),Irp));
  256. status = Cycladz_PDO_PnP(DeviceObject, Irp, irpStack,
  257. (PPDO_DEVICE_DATA) commonData);
  258. PnPDone:;
  259. return status;
  260. }
  261. NTSTATUS
  262. Cycladz_FDO_PnP (
  263. IN PDEVICE_OBJECT DeviceObject,
  264. IN PIRP Irp,
  265. IN PIO_STACK_LOCATION IrpStack,
  266. IN PFDO_DEVICE_DATA DeviceData
  267. )
  268. /*++
  269. Routine Description:
  270. Handle requests from the PlugPlay system for the BUS itself
  271. NB: the various Minor functions of the PlugPlay system will not be
  272. overlapped and do not have to be reentrant
  273. --*/
  274. {
  275. NTSTATUS status;
  276. KIRQL oldIrq;
  277. KEVENT event;
  278. ULONG length;
  279. ULONG i;
  280. PLIST_ENTRY entry;
  281. PPDO_DEVICE_DATA pdoData;
  282. PDEVICE_RELATIONS relations;
  283. PIO_STACK_LOCATION stack;
  284. PRTL_QUERY_REGISTRY_TABLE QueryTable = NULL;
  285. ULONG DebugLevelDefault = SER_DEFAULT_DEBUG_OUTPUT_LEVEL;
  286. HANDLE instanceKey;
  287. UNICODE_STRING keyName;
  288. ULONG numOfPorts;
  289. PAGED_CODE ();
  290. status = Cycladz_IncIoCount (DeviceData);
  291. if (!NT_SUCCESS (status)) {
  292. //Irp->IoStatus.Information = 0; Removed in build 2072
  293. Irp->IoStatus.Status = status;
  294. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  295. return status;
  296. }
  297. stack = IoGetCurrentIrpStackLocation (Irp);
  298. switch (IrpStack->MinorFunction) {
  299. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: {
  300. PIO_RESOURCE_REQUIREMENTS_LIST pReqList;
  301. PIO_RESOURCE_LIST pResList;
  302. PIO_RESOURCE_DESCRIPTOR pResDesc;
  303. ULONG i, j;
  304. ULONG reqCnt;
  305. ULONG gotPLX;
  306. ULONG gotMemory;
  307. ULONG gotInt;
  308. ULONG listNum;
  309. // FANNY: The serial driver had it as SynchronizationEvent.
  310. KeInitializeEvent(&event, NotificationEvent, FALSE);
  311. IoCopyCurrentIrpStackLocationToNext(Irp);
  312. IoSetCompletionRoutine(Irp, CycladzSyncCompletion, &event,
  313. TRUE, TRUE, TRUE);
  314. status = IoCallDriver(DeviceData->TopOfStack, Irp);
  315. //
  316. // Wait for lower drivers to be done with the Irp
  317. //
  318. if (status == STATUS_PENDING) {
  319. KeWaitForSingleObject (&event, Executive, KernelMode, FALSE,
  320. NULL);
  321. }
  322. if (Irp->IoStatus.Information == 0) {
  323. if (stack->Parameters.FilterResourceRequirements
  324. .IoResourceRequirementList == 0) {
  325. Cycladz_KdPrint(DeviceData, SER_DBG_CYCLADES, ("Can't filter NULL resources!"
  326. "\n"));
  327. status = Irp->IoStatus.Status;
  328. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  329. Cycladz_DecIoCount (DeviceData);
  330. return status;
  331. }
  332. Irp->IoStatus.Information = (ULONG_PTR)stack->Parameters
  333. .FilterResourceRequirements
  334. .IoResourceRequirementList;
  335. }
  336. //
  337. // Force ISR ports in IO_RES_REQ_LIST to shared status
  338. // Force interrupts to shared status
  339. //
  340. //
  341. // We will only process the first list -- multiport boards
  342. // should not have alternative resources
  343. //
  344. pReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information;
  345. pResList = &pReqList->List[0];
  346. Cycladz_KdPrint(DeviceData, SER_DBG_CYCLADES, ("------- List has %x lists "
  347. "(including alternatives)\n",
  348. pReqList->AlternativeLists));
  349. for (listNum = 0; listNum < (pReqList->AlternativeLists);
  350. listNum++) {
  351. gotPLX = 0;
  352. gotMemory = 0;
  353. gotInt = 0;
  354. Cycladz_KdPrint(DeviceData, SER_DBG_CYCLADES, ("------- List has %x resources in it\n",
  355. pResList->Count));
  356. for (j = 0; (j < pResList->Count); j++) {
  357. pResDesc = &pResList->Descriptors[j];
  358. switch (pResDesc->Type) {
  359. case CmResourceTypeMemory:
  360. if (pResDesc->u.Memory.Length == CYZ_RUNTIME_LENGTH) {
  361. gotPLX = 1;
  362. //wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  363. //pResDesc->ShareDisposition = CmResourceShareShared;
  364. //wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  365. //pResDesc->ShareDisposition = CmResourceShareDriverExclusive;
  366. //Cycladz_KdPrint(DeviceData,SER_DBG_CYCLADES,
  367. // ("------- Sharing PLX Memory for "
  368. // "device %x\n", DeviceData->TopOfStack));
  369. } else {
  370. gotMemory = 1;
  371. //wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  372. //pResDesc->ShareDisposition = CmResourceShareShared;
  373. //wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  374. //pResDesc->ShareDisposition = CmResourceShareDriverExclusive;
  375. //Cycladz_KdPrint(DeviceData,SER_DBG_CYCLADES,
  376. // ("------- Sharing Board Memory for "
  377. // "device %x\n", DeviceData->TopOfStack));
  378. }
  379. break;
  380. case CmResourceTypePort:
  381. Cycladz_KdPrint(DeviceData,SER_DBG_CYCLADES,
  382. ("------- We should not have Port resource\n"));
  383. break;
  384. case CmResourceTypeInterrupt:
  385. gotInt = 1;
  386. if (DeviceData->IsPci) {
  387. pResDesc->ShareDisposition = CmResourceShareShared;
  388. }
  389. Cycladz_KdPrint(DeviceData,SER_DBG_CYCLADES,("------- Sharing interrupt for "
  390. "device %x\n", DeviceData->TopOfStack));
  391. break;
  392. default:
  393. break;
  394. }
  395. //
  396. // If we found what we need, we can break out of the loop
  397. //
  398. // FANNY: STRANGE, THERE ARE TWICE FOR EACH TYPE. IT SEEMS THAT
  399. // BOTH RAW AND TRANSLATED ARE LISTED.
  400. // (gotPLX && gotMemory && gotInt) {
  401. // break;
  402. //
  403. }
  404. pResList = (PIO_RESOURCE_LIST)((PUCHAR)pResList
  405. + sizeof(IO_RESOURCE_LIST)
  406. + sizeof(IO_RESOURCE_DESCRIPTOR)
  407. * (pResList->Count - 1));
  408. }
  409. Irp->IoStatus.Status = STATUS_SUCCESS;
  410. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  411. Cycladz_DecIoCount (DeviceData);
  412. return STATUS_SUCCESS;
  413. }
  414. case IRP_MN_START_DEVICE:
  415. //
  416. // BEFORE you are allowed to ``touch'' the device object to which
  417. // the FDO is attached (that send an irp from the bus to the Device
  418. // object to which the bus is attached). You must first pass down
  419. // the start IRP. It might not be powered on, or able to access or
  420. // something.
  421. //
  422. // FANNY_TODO
  423. // SHOULD I CALL MmLockPagableCodeSection as the serial driver?
  424. // if (DeviceData->Started) {
  425. // Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  426. // ("Device already started\n"));
  427. // status = STATUS_SUCCESS;
  428. // break;
  429. // }
  430. KeInitializeEvent (&event, NotificationEvent, FALSE);
  431. IoCopyCurrentIrpStackLocationToNext (Irp);
  432. IoSetCompletionRoutine (Irp,
  433. CycladzSyncCompletion,
  434. &event,
  435. TRUE,
  436. TRUE,
  437. TRUE);
  438. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  439. if (STATUS_PENDING == status) {
  440. // wait for it...
  441. status = KeWaitForSingleObject (&event,
  442. Executive,
  443. KernelMode,
  444. FALSE, // Not allertable
  445. NULL); // No timeout structure
  446. ASSERT (STATUS_SUCCESS == status);
  447. status = Irp->IoStatus.Status;
  448. }
  449. if (NT_SUCCESS(status)) {
  450. //
  451. // Get the debug level from the registry
  452. //
  453. if (NULL == (QueryTable = ExAllocatePool(
  454. PagedPool,
  455. sizeof(RTL_QUERY_REGISTRY_TABLE)*2
  456. ))) {
  457. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_ERROR,
  458. ("Failed to allocate memory to query registy\n"));
  459. DeviceData->DebugLevel = DebugLevelDefault;
  460. } else {
  461. RtlZeroMemory(
  462. QueryTable,
  463. sizeof(RTL_QUERY_REGISTRY_TABLE)*2
  464. );
  465. QueryTable[0].QueryRoutine = NULL;
  466. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  467. QueryTable[0].EntryContext = &DeviceData->DebugLevel;
  468. QueryTable[0].Name = L"DebugLevel";
  469. QueryTable[0].DefaultType = REG_DWORD;
  470. QueryTable[0].DefaultData = &DebugLevelDefault;
  471. QueryTable[0].DefaultLength= sizeof(ULONG);
  472. // CIMEXCIMEX: The rest of the table isn't filled in! Comment changed bld 2128
  473. if (!NT_SUCCESS(RtlQueryRegistryValues(
  474. RTL_REGISTRY_SERVICES,
  475. L"cyclad-z",
  476. QueryTable,
  477. NULL,
  478. NULL))) {
  479. Cycladz_KdPrint (DeviceData,SER_DBG_PNP_ERROR,
  480. ("Failed to get debug level from registry. "
  481. "Using default\n"));
  482. DeviceData->DebugLevel = DebugLevelDefault;
  483. }
  484. ExFreePool( QueryTable );
  485. }
  486. status = Cycladz_GetResourceInfo(DeviceObject,
  487. IrpStack->Parameters.StartDevice.AllocatedResources,
  488. IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated);
  489. if (NT_SUCCESS(status)) {
  490. ULONG numberOfResources = CYZ_NUMBER_OF_RESOURCES;
  491. if (!DeviceData->IsPci) {
  492. numberOfResources--;
  493. }
  494. status = Cycladz_BuildResourceList(&DeviceData->PChildResourceList,
  495. &DeviceData->PChildResourceListSize,
  496. IrpStack->Parameters.StartDevice.AllocatedResources,
  497. numberOfResources);
  498. if (!NT_SUCCESS(status)) {
  499. goto CaseSTART_end;
  500. }
  501. status = Cycladz_BuildResourceList(&DeviceData->PChildResourceListTr,
  502. &DeviceData->PChildResourceListSizeTr,
  503. IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated,
  504. numberOfResources);
  505. if (!NT_SUCCESS(status)) {
  506. goto CaseSTART_end;
  507. }
  508. status = Cycladz_BuildRequirementsList(&DeviceData->PChildRequiredList,
  509. IrpStack->Parameters.StartDevice.AllocatedResources,
  510. numberOfResources);
  511. if (!NT_SUCCESS(status)) {
  512. goto CaseSTART_end;
  513. }
  514. //
  515. // See if we are in the proper power state.
  516. //
  517. if (DeviceData->DeviceState != PowerDeviceD0) {
  518. status = Cycladz_GotoPowerState(DeviceData->UnderlyingPDO, DeviceData,
  519. PowerDeviceD0);
  520. if (!NT_SUCCESS(status)) {
  521. goto CaseSTART_end;
  522. }
  523. }
  524. numOfPorts=Cycladz_DoesBoardExist(DeviceData);
  525. if (!numOfPorts){
  526. Cycladz_KdPrint(DeviceData,SER_DBG_CYCLADES,("Does Port exist test failed\n"));
  527. status = STATUS_SERIAL_NO_DEVICE_INITED;
  528. goto CaseSTART_end;
  529. }
  530. Cycladz_KdPrint(DeviceData,SER_DBG_CYCLADES,("Board found!\n"));
  531. // Save number of ports to the Registry, so that Property Page
  532. // code can retrieve it.
  533. IoOpenDeviceRegistryKey(DeviceData->UnderlyingPDO,PLUGPLAY_REGKEY_DEVICE,
  534. STANDARD_RIGHTS_WRITE,&instanceKey);
  535. RtlInitUnicodeString(&keyName,L"NumOfPorts");
  536. ZwSetValueKey(instanceKey,&keyName,0,REG_DWORD,&numOfPorts,sizeof(ULONG));
  537. ZwFlushKey(instanceKey);
  538. ZwClose(instanceKey);
  539. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  540. ("Start Device: Device started successfully\n"));
  541. SET_NEW_PNP_STATE(DeviceData, Started);
  542. // TODO: FOR NOW, LET'S KEEP THIS DEVICE IN POWER D0.
  543. // THE SERIAL DRIVER SEEMS TO POWER DOWN TO D3, AND BECOME D0 DURING OPEN.
  544. // BUT NOT SURE IF THE BOARD NEED TO BE IN D0 WHILE THE CHILD DEVICES
  545. // ARE ENUMARATED.
  546. }
  547. }
  548. CaseSTART_end:
  549. if (!NT_SUCCESS(status)) {
  550. Cycladz_ReleaseResources(DeviceData);
  551. }
  552. //
  553. // We must now complete the IRP, since we stopped it in the
  554. // completetion routine with MORE_PROCESSING_REQUIRED.
  555. //
  556. //Irp->IoStatus.Information = 0; Removed in build 2072
  557. break;
  558. case IRP_MN_QUERY_STOP_DEVICE:
  559. //
  560. // Test to see if there are any PDO created as children of this FDO
  561. // If there are then conclude the device is busy and fail the
  562. // query stop.
  563. //
  564. // CIMEXCIMEX (BUGBUG replaced by CIMEXCIMEX on build 2128 - Fanny)
  565. // We could do better, by seing if the children PDOs are actually
  566. // currently open. If they are not then we could stop, get new
  567. // resouces, fill in the new resouce values, and then when a new client
  568. // opens the PDO use the new resources. But this works for now.
  569. //
  570. //TODO FANNY: FOR NOW WE WILL ALWAYS ACCEPT TO STOP DEVICE. REVIEW THIS LATER...
  571. // if (DeviceData->AttachedPDO) {
  572. // status = STATUS_UNSUCCESSFUL;
  573. // } else {
  574. // status = STATUS_SUCCESS;
  575. // }
  576. status = STATUS_SUCCESS;
  577. Irp->IoStatus.Status = status;
  578. if (NT_SUCCESS(status)) {
  579. SET_NEW_PNP_STATE(DeviceData, StopPending);
  580. IoSkipCurrentIrpStackLocation (Irp);
  581. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  582. } else {
  583. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  584. }
  585. Cycladz_DecIoCount (DeviceData);
  586. return status;
  587. case IRP_MN_CANCEL_STOP_DEVICE:
  588. KeInitializeEvent (&event, NotificationEvent, FALSE);
  589. IoCopyCurrentIrpStackLocationToNext (Irp);
  590. IoSetCompletionRoutine (Irp,
  591. CycladzSyncCompletion,
  592. &event,
  593. TRUE,
  594. TRUE,
  595. TRUE);
  596. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  597. if (STATUS_PENDING == status) {
  598. // wait for it...
  599. status = KeWaitForSingleObject (&event,
  600. Executive,
  601. KernelMode,
  602. FALSE, // Not allertable
  603. NULL); // No timeout structure
  604. ASSERT (STATUS_SUCCESS == status);
  605. status = Irp->IoStatus.Status;
  606. }
  607. if(StopPending == DeviceData->DevicePnPState)
  608. {
  609. //
  610. // We did receive a query-stop, so restore.
  611. //
  612. RESTORE_PREVIOUS_PNP_STATE(DeviceData);
  613. ASSERT(DeviceData->DevicePnPState == Started);
  614. }
  615. break;
  616. case IRP_MN_STOP_DEVICE:
  617. //
  618. // After the start IRP has been sent to the lower driver object, the
  619. // bus may NOT send any more IRPS down ``touch'' until another START
  620. // has occured.
  621. // What ever access is required must be done before the Irp is passed
  622. // on.
  623. //
  624. // Stop device means that the resources given durring Start device
  625. // are no revoked. So we need to stop using them
  626. //
  627. if (DeviceData->Runtime && DeviceData->BoardMemory) {
  628. ULONG mail_box_0;
  629. mail_box_0 = CYZ_READ_ULONG(&(DeviceData->Runtime)->mail_box_0);
  630. if ((mail_box_0 == 0) || z_fpga_check(DeviceData)) {
  631. z_stop_cpu(DeviceData);
  632. }
  633. }
  634. Cycladz_ReleaseResources(DeviceData);
  635. SET_NEW_PNP_STATE(DeviceData, Stopped);
  636. //
  637. // We don't need a completion routine so fire and forget.
  638. //
  639. // Set the current stack location to the next stack location and
  640. // call the next device object.
  641. //
  642. Irp->IoStatus.Status = STATUS_SUCCESS;
  643. IoSkipCurrentIrpStackLocation (Irp);
  644. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  645. Cycladz_DecIoCount (DeviceData);
  646. return status;
  647. case IRP_MN_QUERY_REMOVE_DEVICE:
  648. //
  649. // If we were to fail this call then we would need to complete the
  650. // IRP here. Since we are not, set the status to SUCCESS and
  651. // call the next driver.
  652. //
  653. SET_NEW_PNP_STATE(DeviceData, RemovePending);
  654. Irp->IoStatus.Status = STATUS_SUCCESS;
  655. IoSkipCurrentIrpStackLocation (Irp);
  656. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  657. Cycladz_DecIoCount (DeviceData);
  658. return status;
  659. case IRP_MN_CANCEL_REMOVE_DEVICE:
  660. //
  661. // If we were to fail this call then we would need to complete the
  662. // IRP here. Since we are not, set the status to SUCCESS and
  663. // call the next driver.
  664. //
  665. //
  666. // First check to see whether you have received cancel-remove
  667. // without first receiving a query-remove. This could happen if
  668. // someone above us fails a query-remove and passes down the
  669. // subsequent cancel-remove.
  670. //
  671. if(RemovePending == DeviceData->DevicePnPState)
  672. {
  673. //
  674. // We did receive a query-remove, so restore.
  675. //
  676. RESTORE_PREVIOUS_PNP_STATE(DeviceData);
  677. }
  678. IoSkipCurrentIrpStackLocation (Irp);
  679. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  680. Cycladz_DecIoCount (DeviceData);
  681. return status;
  682. case IRP_MN_SURPRISE_REMOVAL:
  683. SET_NEW_PNP_STATE(DeviceData, SurpriseRemovePending);
  684. Irp->IoStatus.Status = STATUS_SUCCESS;
  685. IoSkipCurrentIrpStackLocation (Irp);
  686. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  687. Cycladz_DecIoCount (DeviceData);
  688. return status;
  689. case IRP_MN_REMOVE_DEVICE:
  690. //
  691. // The PlugPlay system has detected the removal of this device. We
  692. // have no choice but to detach and delete the device object.
  693. // (If we wanted to express and interest in preventing this removal,
  694. // we should have filtered the query remove and query stop routines.)
  695. //
  696. // Note! we might receive a remove WITHOUT first receiving a stop.
  697. // ASSERT (!DeviceData->Removed);
  698. // We will accept no new requests
  699. //
  700. // DeviceData->Removed = TRUE;
  701. SET_NEW_PNP_STATE(DeviceData, Deleted);
  702. //
  703. // Complete any outstanding IRPs queued by the driver here.
  704. //
  705. //
  706. // Make the DCA go away. Some drivers may choose to remove the DCA
  707. // when they receive a stop or even a query stop. We just don't care.
  708. //
  709. IoSetDeviceInterfaceState (&DeviceData->DevClassAssocName, FALSE);
  710. //
  711. // Here if we had any outstanding requests in a personal queue we should
  712. // complete them all now.
  713. //
  714. // Note, the device is guarenteed stopped, so we cannot send it any non-
  715. // PNP IRPS.
  716. //
  717. //
  718. // Wait for all outstanding requests to complete
  719. //
  720. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  721. ("Waiting for outstanding requests\n"));
  722. i = InterlockedDecrement (&DeviceData->OutstandingIO);
  723. ASSERT (0 < i);
  724. if (0 != InterlockedDecrement (&DeviceData->OutstandingIO)) {
  725. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_INFO,
  726. ("Remove Device waiting for request to complete\n"));
  727. KeWaitForSingleObject (&DeviceData->RemoveEvent,
  728. Executive,
  729. KernelMode,
  730. FALSE, // Not Alertable
  731. NULL); // No timeout
  732. }
  733. // Stop hw
  734. if (DeviceData->Runtime && DeviceData->BoardMemory) {
  735. ULONG mail_box_0;
  736. mail_box_0 = CYZ_READ_ULONG(&(DeviceData->Runtime)->mail_box_0);
  737. if ((mail_box_0 == 0) || z_fpga_check(DeviceData)) {
  738. z_stop_cpu(DeviceData);
  739. }
  740. //z_reset_board(DeviceData);
  741. }
  742. //
  743. // Fire and forget
  744. //
  745. Irp->IoStatus.Status = STATUS_SUCCESS;
  746. IoSkipCurrentIrpStackLocation (Irp);
  747. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  748. //
  749. // Free the associated resources
  750. //
  751. //
  752. // Detach from the underlying devices.
  753. //
  754. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_INFO,
  755. ("IoDetachDevice: 0x%x\n", DeviceData->TopOfStack));
  756. IoDetachDevice (DeviceData->TopOfStack);
  757. //
  758. // Clean up any resources here
  759. //
  760. Cycladz_ReleaseResources(DeviceData);
  761. ExFreePool (DeviceData->DevClassAssocName.Buffer);
  762. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_INFO,
  763. ("IoDeleteDevice: 0x%x\n", DeviceObject));
  764. //
  765. // Remove any PDO's we ejected
  766. //
  767. //FANNY: CHANGED TO SUPPORT MORE THAN ONE CHILD DEVICE
  768. // if (DeviceData->AttachedPDO != NULL) {
  769. // ASSERT(DeviceData->NumPDOs == 1);
  770. //
  771. // Cycladz_PnPRemove(DeviceData->AttachedPDO, DeviceData->PdoData);
  772. // DeviceData->PdoData = NULL;
  773. // DeviceData->AttachedPDO = NULL;
  774. // DeviceData->NumPDOs = 0;
  775. // }
  776. i=DeviceData->NumPDOs;
  777. while(i--) {
  778. if (DeviceData->AttachedPDO[i] != NULL) {
  779. //(DeviceData->PdoData[i])->Attached = FALSE; Moved to PDO IRP_MN_SURPRISE_REMOVAL.
  780. if(SurpriseRemovePending != (DeviceData->PdoData[i])->DevicePnPState) {
  781. Cycladz_PnPRemove(DeviceData->AttachedPDO[i], DeviceData->PdoData[i]);
  782. }
  783. DeviceData->PdoData[i] = NULL;
  784. DeviceData->AttachedPDO[i] = NULL;
  785. }
  786. }
  787. DeviceData->NumPDOs = 0;
  788. IoDeleteDevice(DeviceObject);
  789. return status;
  790. case IRP_MN_QUERY_DEVICE_RELATIONS:
  791. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  792. ("\tQueryDeviceRelation Type: %d\n",
  793. IrpStack->Parameters.QueryDeviceRelations.Type));
  794. if (BusRelations != IrpStack->Parameters.QueryDeviceRelations.Type) {
  795. //
  796. // We don't support this
  797. //
  798. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  799. ("Query Device Relations - Non bus\n"));
  800. goto CYZ_FDO_PNP_DEFAULT;
  801. }
  802. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  803. ("\tQuery Bus Relations\n"));
  804. // Check for new devices or if old devices still there.
  805. status = Cycladz_ReenumerateDevices(Irp, DeviceData );
  806. //
  807. // Tell the plug and play system about all the PDOs.
  808. //
  809. // There might also be device relations below and above this FDO,
  810. // so, be sure to propagate the relations from the upper drivers.
  811. //
  812. // No Completion routine is needed so long as the status is preset
  813. // to success. (PDOs complete plug and play irps with the current
  814. // IoStatus.Status and IoStatus.Information as the default.)
  815. //
  816. //KeAcquireSpinLock (&DeviceData->Spin, &oldIrq);
  817. i = (0 == Irp->IoStatus.Information) ? 0 :
  818. ((PDEVICE_RELATIONS) Irp->IoStatus.Information)->Count;
  819. // The current number of PDOs in the device relations structure
  820. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  821. ("#PDOS = %d + %d\n", i, DeviceData->NumPDOs));
  822. length = sizeof(DEVICE_RELATIONS) +
  823. ((DeviceData->NumPDOs + i) * sizeof (PDEVICE_OBJECT));
  824. relations = (PDEVICE_RELATIONS) ExAllocatePool (NonPagedPool, length);
  825. if (NULL == relations) {
  826. Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  827. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  828. Cycladz_DecIoCount(DeviceData);
  829. return STATUS_INSUFFICIENT_RESOURCES;
  830. }
  831. //
  832. // Copy in the device objects so far
  833. //
  834. if (i) {
  835. RtlCopyMemory (
  836. relations->Objects,
  837. ((PDEVICE_RELATIONS) Irp->IoStatus.Information)->Objects,
  838. i * sizeof (PDEVICE_OBJECT));
  839. }
  840. relations->Count = DeviceData->NumPDOs + i;
  841. //
  842. // For each PDO on this bus add a pointer to the device relations
  843. // buffer, being sure to take out a reference to that object.
  844. // The PlugPlay system will dereference the object when it is done with
  845. // it and free the device relations buffer.
  846. //
  847. //FANNY: CHANGED TO SUPPORT ADDITIONAL CHILD DEVICES
  848. // if (DeviceData->NumPDOs) {
  849. // relations->Objects[relations->Count-1] = DeviceData->AttachedPDO;
  850. // ObReferenceObject (DeviceData->AttachedPDO);
  851. // }
  852. for (i=0; i< DeviceData->NumPDOs; i++) {
  853. relations->Objects[relations->Count - DeviceData->NumPDOs + i] =
  854. DeviceData->AttachedPDO[i];
  855. ObReferenceObject (DeviceData->AttachedPDO[i]);
  856. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  857. ("Child PDOS: %x\n", DeviceData->AttachedPDO[i]));
  858. }
  859. //
  860. // Set up and pass the IRP further down the stack
  861. //
  862. Irp->IoStatus.Status = STATUS_SUCCESS;
  863. if (0 != Irp->IoStatus.Information) {
  864. ExFreePool ((PVOID) Irp->IoStatus.Information);
  865. }
  866. Irp->IoStatus.Information = (ULONG_PTR)relations;
  867. IoSkipCurrentIrpStackLocation (Irp);
  868. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  869. Cycladz_DecIoCount (DeviceData);
  870. return status;
  871. case IRP_MN_QUERY_CAPABILITIES: {
  872. PIO_STACK_LOCATION irpSp;
  873. //
  874. // Send this down to the PDO first
  875. //
  876. KeInitializeEvent (&event, NotificationEvent, FALSE);
  877. IoCopyCurrentIrpStackLocationToNext (Irp);
  878. IoSetCompletionRoutine (Irp,
  879. CycladzSyncCompletion,
  880. &event,
  881. TRUE,
  882. TRUE,
  883. TRUE);
  884. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  885. if (STATUS_PENDING == status) {
  886. // wait for it...
  887. status = KeWaitForSingleObject (&event,
  888. Executive,
  889. KernelMode,
  890. FALSE, // Not allertable
  891. NULL); // No timeout structure
  892. ASSERT (STATUS_SUCCESS == status);
  893. status = Irp->IoStatus.Status;
  894. }
  895. if (NT_SUCCESS(status)) {
  896. irpSp = IoGetCurrentIrpStackLocation(Irp);
  897. DeviceData->SystemWake
  898. = irpSp->Parameters.DeviceCapabilities.Capabilities->SystemWake;
  899. DeviceData->DeviceWake
  900. = irpSp->Parameters.DeviceCapabilities.Capabilities->DeviceWake;
  901. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_INFO, ("SystemWake %d\n",DeviceData->SystemWake));
  902. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_INFO, ("DeviceWake %d\n",DeviceData->DeviceWake));
  903. }
  904. break;
  905. }
  906. default:
  907. //
  908. // In the default case we merely call the next driver since
  909. // we don't know what to do.
  910. //
  911. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_TRACE,
  912. ("FDO(%x):%s not handled\n", DeviceObject,
  913. PnPMinorFunctionString(IrpStack->MinorFunction)));
  914. CYZ_FDO_PNP_DEFAULT:
  915. //
  916. // Fire and Forget
  917. //
  918. IoSkipCurrentIrpStackLocation (Irp);
  919. //
  920. // Done, do NOT complete the IRP, it will be processed by the lower
  921. // device object, which will complete the IRP
  922. //
  923. status = IoCallDriver (DeviceData->TopOfStack, Irp);
  924. Cycladz_DecIoCount (DeviceData);
  925. return status;
  926. }
  927. Irp->IoStatus.Status = status;
  928. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  929. Cycladz_DecIoCount (DeviceData);
  930. return status;
  931. }
  932. NTSTATUS
  933. Cycladz_PDO_PnP (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
  934. IN PIO_STACK_LOCATION IrpStack, IN PPDO_DEVICE_DATA DeviceData)
  935. /*++
  936. Routine Description:
  937. Handle requests from the PlugPlay system for the devices on the BUS
  938. --*/
  939. {
  940. PDEVICE_CAPABILITIES deviceCapabilities;
  941. ULONG information;
  942. PWCHAR buffer;
  943. ULONG length, i, j;
  944. NTSTATUS status;
  945. KIRQL oldIrq;
  946. HANDLE keyHandle;
  947. UNICODE_STRING keyName;
  948. PWCHAR returnBuffer = NULL;
  949. PAGED_CODE();
  950. status = Irp->IoStatus.Status;
  951. //
  952. // NB: since we are a bus enumerator, we have no one to whom we could
  953. // defer these irps. Therefore we do not pass them down but merely
  954. // return them.
  955. //
  956. switch (IrpStack->MinorFunction) {
  957. case IRP_MN_QUERY_CAPABILITIES:
  958. //
  959. // Get the packet.
  960. //
  961. deviceCapabilities=IrpStack->Parameters.DeviceCapabilities.Capabilities;
  962. //
  963. // Set the capabilities.
  964. //
  965. deviceCapabilities->Version = 1;
  966. deviceCapabilities->Size = sizeof (DEVICE_CAPABILITIES);
  967. //
  968. // We cannot wake the system.
  969. //
  970. deviceCapabilities->SystemWake
  971. = ((PFDO_DEVICE_DATA)DeviceData->ParentFdo->DeviceExtension)
  972. ->SystemWake;
  973. deviceCapabilities->DeviceWake
  974. = ((PFDO_DEVICE_DATA)DeviceData->ParentFdo->DeviceExtension)
  975. ->DeviceWake;
  976. //
  977. // We have no latencies
  978. //
  979. deviceCapabilities->D1Latency = 0;
  980. deviceCapabilities->D2Latency = 0;
  981. deviceCapabilities->D3Latency = 0;
  982. deviceCapabilities->UniqueID = FALSE;
  983. //
  984. // Initialize supported DeviceState
  985. //
  986. deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
  987. deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
  988. deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
  989. deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
  990. deviceCapabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
  991. deviceCapabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
  992. status = STATUS_SUCCESS;
  993. break;
  994. case IRP_MN_QUERY_DEVICE_TEXT: {
  995. if ((IrpStack->Parameters.QueryDeviceText.DeviceTextType
  996. != DeviceTextDescription) || DeviceData->DevDesc.Buffer == NULL) {
  997. break;
  998. }
  999. // FANNY - CHANGE TO MaximumLength
  1000. // returnBuffer = ExAllocatePool(PagedPool, DeviceData->DevDesc.Length);
  1001. returnBuffer = ExAllocatePool(PagedPool, DeviceData->DevDesc.MaximumLength);
  1002. Cycladz_KdPrint(DeviceData, SER_DBG_CYCLADES,("returnBuffer %x\n", returnBuffer));
  1003. if (returnBuffer == NULL) {
  1004. status = STATUS_INSUFFICIENT_RESOURCES;
  1005. break;
  1006. }
  1007. status = STATUS_SUCCESS;
  1008. // FANNY - CHANGE TO MaximumLength
  1009. // RtlCopyMemory(returnBuffer, DeviceData->DevDesc.Buffer,
  1010. // DeviceData->DevDesc.Length);
  1011. RtlCopyMemory(returnBuffer, DeviceData->DevDesc.Buffer,
  1012. DeviceData->DevDesc.MaximumLength);
  1013. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_TRACE,
  1014. ("TextID: buf %ws\n", returnBuffer));
  1015. Cycladz_KdPrint(DeviceData, SER_DBG_CYCLADES,
  1016. ("DevDesc.Length is %d and DevDesc.MaximumLength is %d\n",
  1017. DeviceData->DevDesc.Length,DeviceData->DevDesc.MaximumLength));
  1018. Irp->IoStatus.Information = (ULONG_PTR)returnBuffer;
  1019. break;
  1020. }
  1021. case IRP_MN_QUERY_ID:
  1022. //
  1023. // Query the IDs of the device
  1024. //
  1025. switch (IrpStack->Parameters.QueryId.IdType) {
  1026. case BusQueryDeviceID:
  1027. case BusQueryHardwareIDs:
  1028. case BusQueryCompatibleIDs:
  1029. case BusQueryInstanceID:
  1030. {
  1031. PUNICODE_STRING pId;
  1032. status = STATUS_SUCCESS;
  1033. switch (IrpStack->Parameters.QueryId.IdType) {
  1034. case BusQueryDeviceID:
  1035. pId = &DeviceData->DeviceIDs;
  1036. break;
  1037. case BusQueryHardwareIDs:
  1038. pId = &DeviceData->HardwareIDs;
  1039. break;
  1040. case BusQueryCompatibleIDs:
  1041. pId = &DeviceData->CompIDs;
  1042. break;
  1043. case BusQueryInstanceID:
  1044. // Build an instance ID. This is what PnP uses to tell if it has
  1045. // seen this thing before or not. Build it from the first hardware
  1046. // id and the port number.
  1047. pId = &DeviceData->InstanceIDs;
  1048. break;
  1049. }
  1050. buffer = pId->Buffer;
  1051. if (buffer != NULL) {
  1052. // FANNY CHANGED
  1053. //length = pId->Length;
  1054. length = pId->MaximumLength;
  1055. returnBuffer = ExAllocatePool(PagedPool, length);
  1056. if (returnBuffer != NULL) {
  1057. #if DBG
  1058. RtlFillMemory(returnBuffer, length, 0xff);
  1059. #endif
  1060. // FANNY CHANGED
  1061. //RtlCopyMemory(returnBuffer, buffer, pId->Length);
  1062. RtlCopyMemory(returnBuffer, buffer, length);
  1063. } else {
  1064. status = STATUS_INSUFFICIENT_RESOURCES;
  1065. }
  1066. } else {
  1067. // FANNY ADDED
  1068. status = STATUS_NOT_FOUND;
  1069. }
  1070. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_TRACE,
  1071. ("ID: Unicode 0x%x\n", pId));
  1072. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_TRACE,
  1073. ("ID: buf 0x%x\n", returnBuffer));
  1074. Irp->IoStatus.Information = (ULONG_PTR)returnBuffer;
  1075. }
  1076. break;
  1077. }
  1078. break;
  1079. case IRP_MN_QUERY_BUS_INFORMATION: {
  1080. PPNP_BUS_INFORMATION pBusInfo;
  1081. PFDO_DEVICE_DATA parentExtension;
  1082. parentExtension = (DeviceData->ParentFdo)->DeviceExtension;
  1083. ASSERTMSG("Cycladz appears not to be the sole bus?!?",
  1084. Irp->IoStatus.Information == (ULONG_PTR)NULL);
  1085. pBusInfo = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
  1086. if (pBusInfo == NULL) {
  1087. status = STATUS_INSUFFICIENT_RESOURCES;
  1088. break;
  1089. }
  1090. pBusInfo->BusTypeGuid = GUID_BUS_TYPE_CYCLADESZ;
  1091. if (parentExtension->IsPci) {
  1092. pBusInfo->LegacyBusType = PCIBus;
  1093. } else {
  1094. pBusInfo->LegacyBusType = Isa;
  1095. }
  1096. //
  1097. // We really can't track our bus number since we can be torn
  1098. // down with our bus
  1099. //
  1100. //pBusInfo->BusNumber = 0;
  1101. pBusInfo->BusNumber = parentExtension->UINumber;
  1102. Irp->IoStatus.Information = (ULONG_PTR)pBusInfo;
  1103. status = STATUS_SUCCESS;
  1104. break;
  1105. }
  1106. case IRP_MN_QUERY_DEVICE_RELATIONS:
  1107. Cycladz_KdPrint (DeviceData, SER_DBG_PNP_TRACE,
  1108. ("\tQueryDeviceRelation Type: %d\n",
  1109. IrpStack->Parameters.QueryDeviceRelations.Type));
  1110. switch (IrpStack->Parameters.QueryDeviceRelations.Type) {
  1111. case TargetDeviceRelation: {
  1112. PDEVICE_RELATIONS pDevRel;
  1113. //
  1114. // No one else should respond to this since we are the PDO
  1115. //
  1116. ASSERT(Irp->IoStatus.Information == 0);
  1117. if (Irp->IoStatus.Information != 0) {
  1118. break;
  1119. }
  1120. pDevRel = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
  1121. if (pDevRel == NULL) {
  1122. status = STATUS_INSUFFICIENT_RESOURCES;
  1123. break;
  1124. }
  1125. pDevRel->Count = 1;
  1126. pDevRel->Objects[0] = DeviceObject;
  1127. ObReferenceObject(DeviceObject);
  1128. status = STATUS_SUCCESS;
  1129. Irp->IoStatus.Information = (ULONG_PTR)pDevRel;
  1130. break;
  1131. }
  1132. default:
  1133. break;
  1134. }
  1135. break;
  1136. case IRP_MN_START_DEVICE:
  1137. //
  1138. // Set the hw resources in the registry for this device.
  1139. //
  1140. status = IoOpenDeviceRegistryKey(DeviceObject, PLUGPLAY_REGKEY_DEVICE,
  1141. STANDARD_RIGHTS_WRITE, &keyHandle);
  1142. if (!NT_SUCCESS(status)) {
  1143. //
  1144. // This is a fatal error. If we can't get to our registry key,
  1145. // we are sunk.
  1146. //
  1147. Cycladz_KdPrint(DeviceData, SER_DBG_SS_ERROR,
  1148. ("IoOpenDeviceRegistryKey failed - %x\n", status));
  1149. } else {
  1150. ULONG portIndex;
  1151. PFDO_DEVICE_DATA parentExtension;
  1152. // Set the Port Index in the Registry
  1153. RtlInitUnicodeString(&keyName, L"PortIndex");
  1154. portIndex = DeviceData->PortIndex;
  1155. //
  1156. // Doesn't matter whether this works or not.
  1157. //
  1158. ZwSetValueKey(keyHandle, &keyName, 0, REG_DWORD, &portIndex,
  1159. sizeof(ULONG));
  1160. parentExtension = (DeviceData->ParentFdo)->DeviceExtension;
  1161. RtlInitUnicodeString(&keyName, L"PortResources");
  1162. status = ZwSetValueKey(keyHandle, &keyName, 0, REG_RESOURCE_LIST,
  1163. parentExtension->PChildResourceList,
  1164. parentExtension->PChildResourceListSize);
  1165. RtlInitUnicodeString(&keyName, L"PortResourcesTr");
  1166. status = ZwSetValueKey(keyHandle, &keyName, 0, REG_RESOURCE_LIST,
  1167. parentExtension->PChildResourceListTr,
  1168. parentExtension->PChildResourceListSizeTr);
  1169. RtlInitUnicodeString(&keyName, L"FirmwareVersion");
  1170. status = ZwSetValueKey(keyHandle, &keyName, 0, REG_DWORD,
  1171. &parentExtension->FirmwareVersion,
  1172. sizeof(ULONG));
  1173. ZwFlushKey(keyHandle);
  1174. ZwClose(keyHandle);
  1175. }
  1176. SET_NEW_PNP_STATE(DeviceData, Started);
  1177. status = STATUS_SUCCESS;
  1178. break;
  1179. case IRP_MN_QUERY_STOP_DEVICE:
  1180. //
  1181. // No reason here why we can't stop the device.
  1182. // If there were a reason we should speak now for answering success
  1183. // here may result in a stop device irp.
  1184. //
  1185. SET_NEW_PNP_STATE(DeviceData, StopPending);
  1186. status = STATUS_SUCCESS;
  1187. break;
  1188. case IRP_MN_CANCEL_STOP_DEVICE:
  1189. //
  1190. // The stop was canceled. Whatever state we set, or resources we put
  1191. // on hold in anticipation of the forcoming STOP device IRP should be
  1192. // put back to normal. Someone, in the long list of concerned parties,
  1193. // has failed the stop device query.
  1194. //
  1195. //
  1196. // First check to see whether you have received cancel-stop
  1197. // without first receiving a query-stop. This could happen if someone
  1198. // above us fails a query-stop and passes down the subsequent
  1199. // cancel-stop.
  1200. //
  1201. if(StopPending == DeviceData->DevicePnPState)
  1202. {
  1203. //
  1204. // We did receive a query-stop, so restore.
  1205. //
  1206. RESTORE_PREVIOUS_PNP_STATE(DeviceData);
  1207. }
  1208. status = STATUS_SUCCESS;
  1209. break;
  1210. case IRP_MN_STOP_DEVICE:
  1211. //
  1212. // Here we shut down the device. The opposite of start.
  1213. //
  1214. SET_NEW_PNP_STATE(DeviceData, Stopped);
  1215. status = STATUS_SUCCESS;
  1216. break;
  1217. case IRP_MN_QUERY_REMOVE_DEVICE:
  1218. //
  1219. // Just like Query Stop only now the impending doom is the remove irp
  1220. //
  1221. SET_NEW_PNP_STATE(DeviceData, RemovePending);
  1222. status = STATUS_SUCCESS;
  1223. break;
  1224. case IRP_MN_CANCEL_REMOVE_DEVICE:
  1225. //
  1226. // Clean up a remove that did not go through, just like cancel STOP.
  1227. //
  1228. //
  1229. // First check to see whether you have received cancel-remove
  1230. // without first receiving a query-remove. This could happen if
  1231. // someone above us fails a query-remove and passes down the
  1232. // subsequent cancel-remove.
  1233. //
  1234. if(RemovePending == DeviceData->DevicePnPState)
  1235. {
  1236. //
  1237. // We did receive a query-remove, so restore.
  1238. //
  1239. RESTORE_PREVIOUS_PNP_STATE(DeviceData);
  1240. }
  1241. status = STATUS_SUCCESS;
  1242. break;
  1243. case IRP_MN_SURPRISE_REMOVAL:
  1244. //
  1245. // We should stop all access to the device and relinquish all the
  1246. // resources. Let's just mark that it happened and we will do
  1247. // the cleanup later in IRP_MN_REMOVE_DEVICE.
  1248. //
  1249. SET_NEW_PNP_STATE(DeviceData, SurpriseRemovePending);
  1250. DeviceData->Attached = FALSE;
  1251. status = STATUS_SUCCESS;
  1252. break;
  1253. case IRP_MN_REMOVE_DEVICE:
  1254. //
  1255. // Attached is only set to FALSE by the enumeration process.
  1256. //
  1257. if (!DeviceData->Attached) {
  1258. SET_NEW_PNP_STATE(DeviceData, Deleted);
  1259. status = Cycladz_PnPRemove(DeviceObject, DeviceData);
  1260. }
  1261. else { // else added in build 2128 - Fanny
  1262. //
  1263. // Succeed the remove
  1264. ///
  1265. SET_NEW_PNP_STATE(DeviceData, NotStarted);
  1266. status = STATUS_SUCCESS;
  1267. }
  1268. // Changed in build 2072
  1269. // status = STATUS_SUCCESS;
  1270. break;
  1271. case IRP_MN_QUERY_RESOURCES: {
  1272. #if 0
  1273. PCM_RESOURCE_LIST pChildRes, pQueryRes;
  1274. PFDO_DEVICE_DATA parentExtension;
  1275. ULONG listSize;
  1276. parentExtension = (DeviceData->ParentFdo)->DeviceExtension;
  1277. pChildRes = parentExtension->PChildResourceList;
  1278. listSize = parentExtension->PChildResourceListSize;
  1279. if (pChildRes) {
  1280. pQueryRes = ExAllocatePool(PagedPool, listSize);
  1281. if (pQueryRes == NULL) {
  1282. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  1283. status = STATUS_INSUFFICIENT_RESOURCES;
  1284. } else {
  1285. RtlCopyMemory(pQueryRes,pChildRes,listSize);
  1286. Irp->IoStatus.Information = (ULONG_PTR)pQueryRes;
  1287. status = STATUS_SUCCESS;
  1288. }
  1289. }
  1290. #endif
  1291. break;
  1292. }
  1293. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: {
  1294. #if 0
  1295. PIO_RESOURCE_REQUIREMENTS_LIST pChildReq, pQueryReq;
  1296. PFDO_DEVICE_DATA parentExtension;
  1297. parentExtension = (DeviceData->ParentFdo)->DeviceExtension;
  1298. pChildReq = parentExtension->PChildRequiredList;
  1299. if (pChildReq) {
  1300. pQueryReq = ExAllocatePool(PagedPool, pChildReq->ListSize);
  1301. if (pQueryReq == NULL) {
  1302. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  1303. status = STATUS_INSUFFICIENT_RESOURCES;
  1304. } else {
  1305. RtlCopyMemory(pQueryReq,pChildReq,pChildReq->ListSize);
  1306. Irp->IoStatus.Information = (ULONG_PTR)pQueryReq;
  1307. status = STATUS_SUCCESS;
  1308. }
  1309. }
  1310. #endif
  1311. break;
  1312. }
  1313. case IRP_MN_READ_CONFIG:
  1314. case IRP_MN_WRITE_CONFIG: // we have no config space
  1315. case IRP_MN_EJECT:
  1316. case IRP_MN_SET_LOCK:
  1317. case IRP_MN_QUERY_INTERFACE: // We do not have any non IRP based interfaces.
  1318. default:
  1319. Cycladz_KdPrint(DeviceData, SER_DBG_PNP_TRACE,
  1320. ("PDO(%x):%s not handled\n", DeviceObject,
  1321. PnPMinorFunctionString(IrpStack->MinorFunction)));
  1322. // For PnP requests to the PDO that we do not understand we should
  1323. // return the IRP WITHOUT setting the status or information fields.
  1324. // They may have already been set by a filter (eg acpi).
  1325. break;
  1326. }
  1327. Irp->IoStatus.Status = status;
  1328. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  1329. return status;
  1330. }
  1331. NTSTATUS
  1332. Cycladz_PnPRemove (PDEVICE_OBJECT Device, PPDO_DEVICE_DATA PdoData)
  1333. /*++
  1334. Routine Description:
  1335. The PlugPlay subsystem has instructed that this PDO should be removed.
  1336. We should therefore
  1337. - Complete any requests queued in the driver
  1338. - If the device is still attached to the system,
  1339. then complete the request and return.
  1340. - Otherwise, cleanup device specific allocations, memory, events...
  1341. - Call IoDeleteDevice
  1342. - Return from the dispatch routine.
  1343. Note that if the device is still connected to the bus (IE in this case
  1344. the control panel has not yet told us that the serial device has
  1345. disappeared) then the PDO must remain around, and must be returned during
  1346. any query Device relaions IRPS.
  1347. --*/
  1348. {
  1349. Cycladz_KdPrint(PdoData, SER_DBG_PNP_TRACE,
  1350. ("Cycladz_PnPRemove: 0x%x\n", Device));
  1351. //
  1352. // Complete any outstanding requests with STATUS_DELETE_PENDING.
  1353. //
  1354. // Serenum does not queue any irps at this time so we have nothing to do.
  1355. //
  1356. //REMOVED BY FANNY. THIS CHECK IS ALREADY DONE AT IRP_MN_REMOVE_DEVICE PDO.
  1357. //if (PdoData->Attached) {
  1358. // return STATUS_SUCCESS;
  1359. //}
  1360. //PdoData->Removed = TRUE;
  1361. //
  1362. // Free any resources.
  1363. //
  1364. CycladzFreeUnicodeString(&PdoData->HardwareIDs);
  1365. //CycladzFreeUnicodeString(&PdoData->CompIDs); We never allocate CompIDs.
  1366. RtlFreeUnicodeString(&PdoData->DeviceIDs);
  1367. RtlFreeUnicodeString(&PdoData->InstanceIDs);
  1368. RtlFreeUnicodeString(&PdoData->DevDesc);
  1369. Cycladz_KdPrint(PdoData, SER_DBG_PNP_INFO,
  1370. ("IoDeleteDevice: 0x%x\n", Device));
  1371. IoDeleteDevice(Device);
  1372. return STATUS_SUCCESS;
  1373. }
  1374. NTSTATUS
  1375. Cycladz_GetResourceInfo(IN PDEVICE_OBJECT PDevObj,
  1376. IN PCM_RESOURCE_LIST PResList,
  1377. IN PCM_RESOURCE_LIST PTrResList)
  1378. /*++
  1379. Routine Description:
  1380. This routine gets the resources that PnP allocated to this device.
  1381. Arguments:
  1382. PDevObj - Pointer to the devobj that is starting
  1383. PResList - Pointer to the untranslated resources needed by this device
  1384. PTrResList - Pointer to the translated resources needed by this device
  1385. Return Value:
  1386. STATUS_SUCCESS on success, something else appropriate on failure
  1387. --*/
  1388. {
  1389. PFDO_DEVICE_DATA pDevExt = PDevObj->DeviceExtension;
  1390. NTSTATUS status = STATUS_SUCCESS;
  1391. ULONG count;
  1392. ULONG i;
  1393. PCM_PARTIAL_RESOURCE_LIST pPartialResourceList, pPartialTrResourceList;
  1394. PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialResourceDesc, pPartialTrResourceDesc;
  1395. PCM_FULL_RESOURCE_DESCRIPTOR pFullResourceDesc = NULL,
  1396. pFullTrResourceDesc = NULL;
  1397. KAFFINITY Affinity;
  1398. KINTERRUPT_MODE InterruptMode;
  1399. ULONG zero = 0;
  1400. PAGED_CODE();
  1401. // Let's get our resources
  1402. pFullResourceDesc = &PResList->List[0];
  1403. pFullTrResourceDesc = &PTrResList->List[0];
  1404. if (pFullResourceDesc) {
  1405. pPartialResourceList = &pFullResourceDesc->PartialResourceList;
  1406. pPartialResourceDesc = pPartialResourceList->PartialDescriptors;
  1407. count = pPartialResourceList->Count;
  1408. pDevExt->InterfaceType = pFullResourceDesc->InterfaceType;
  1409. pDevExt->BusNumber = pFullResourceDesc->BusNumber;
  1410. for (i = 0; i < count; i++, pPartialResourceDesc++) {
  1411. switch (pPartialResourceDesc->Type) {
  1412. case CmResourceTypeMemory: {
  1413. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypeMemory\n"));
  1414. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Memory.Start = %x\n",
  1415. pPartialResourceDesc->u.Memory.Start));
  1416. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Memory.Length = %x\n",
  1417. pPartialResourceDesc->u.Memory.Length));
  1418. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Flags = %x\n",
  1419. pPartialResourceDesc->Flags));
  1420. if (pPartialResourceDesc->u.Memory.Length == CYZ_RUNTIME_LENGTH) {
  1421. pDevExt->PhysicalRuntime = pPartialResourceDesc->u.Memory.Start;
  1422. pDevExt->RuntimeLength = pPartialResourceDesc->u.Memory.Length;
  1423. } else {
  1424. pDevExt->PhysicalBoardMemory = pPartialResourceDesc->u.Memory.Start;
  1425. pDevExt->BoardMemoryLength = pPartialResourceDesc->u.Memory.Length;
  1426. }
  1427. break;
  1428. }
  1429. case CmResourceTypePort: {
  1430. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypePort\n"));
  1431. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Port.Start = %x\n",
  1432. pPartialResourceDesc->u.Port.Start));
  1433. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Port.Length = %x\n",
  1434. pPartialResourceDesc->u.Port.Length));
  1435. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Flags = %x\n",
  1436. pPartialResourceDesc->Flags));
  1437. break;
  1438. }
  1439. case CmResourceTypeInterrupt: {
  1440. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypeInterrupt\n"));
  1441. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Interrupt.Level = %x\n",
  1442. pPartialResourceDesc->u.Interrupt.Level));
  1443. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Interrupt.Vector = %x\n",
  1444. pPartialResourceDesc->u.Interrupt.Vector));
  1445. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Interrupt.Affinity = %x\n",
  1446. pPartialResourceDesc->u.Interrupt.Affinity));
  1447. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Flags = %x\n",
  1448. pPartialResourceDesc->Flags));
  1449. #ifndef POLL
  1450. pDevExt->OriginalIrql = pPartialResourceDesc->u.Interrupt.Level;
  1451. pDevExt->OriginalVector =pPartialResourceDesc->u.Interrupt.Vector;
  1452. Affinity = pPartialResourceDesc->u.Interrupt.Affinity;
  1453. if (pPartialResourceDesc->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
  1454. InterruptMode = Latched;
  1455. } else {
  1456. InterruptMode = LevelSensitive;
  1457. }
  1458. #endif
  1459. break;
  1460. }
  1461. case CmResourceTypeDeviceSpecific: {
  1462. PCM_SERIAL_DEVICE_DATA sDeviceData;
  1463. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypeDeviceSpecific\n"));
  1464. break;
  1465. }
  1466. default: {
  1467. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceType = %x\n",
  1468. pPartialResourceDesc->Type));
  1469. break;
  1470. }
  1471. } // switch (pPartialResourceDesc->Type)
  1472. } // for (i = 0; i < count; i++, pPartialResourceDesc++)
  1473. } // if (pFullResourceDesc)
  1474. //SEE_LATER_IF_IT_SHOULD_BE_ADDED
  1475. // //
  1476. // // Do the same for the translated resources
  1477. // //
  1478. //
  1479. // gotInt = 0;
  1480. // gotISR = 0;
  1481. // gotIO = 0;
  1482. // curIoIndex = 0;
  1483. //
  1484. if (pFullTrResourceDesc) {
  1485. pPartialTrResourceList = &pFullTrResourceDesc->PartialResourceList;
  1486. pPartialTrResourceDesc = pPartialTrResourceList->PartialDescriptors;
  1487. count = pPartialTrResourceList->Count;
  1488. //
  1489. // Reload PConfig with the translated values for later use
  1490. //
  1491. pDevExt->InterfaceType = pFullTrResourceDesc->InterfaceType;
  1492. pDevExt->BusNumber = pFullTrResourceDesc->BusNumber;
  1493. //FANNY
  1494. // pDevExt->TrInterruptStatus = SerialPhysicalZero;
  1495. for (i = 0; i < count; i++, pPartialTrResourceDesc++) {
  1496. switch (pPartialTrResourceDesc->Type) {
  1497. case CmResourceTypeMemory: {
  1498. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypeMemory translated\n"));
  1499. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Memory.Start = %x\n",
  1500. pPartialTrResourceDesc->u.Memory.Start));
  1501. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Memory.Length = %x\n",
  1502. pPartialTrResourceDesc->u.Memory.Length));
  1503. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Flags = %x\n",
  1504. pPartialTrResourceDesc->Flags));
  1505. if (pPartialTrResourceDesc->u.Memory.Length == CYZ_RUNTIME_LENGTH) {
  1506. pDevExt->TranslatedRuntime = pPartialTrResourceDesc->u.Memory.Start;
  1507. pDevExt->RuntimeLength = pPartialTrResourceDesc->u.Memory.Length;
  1508. } else {
  1509. pDevExt->TranslatedBoardMemory = pPartialTrResourceDesc->u.Memory.Start;
  1510. pDevExt->BoardMemoryLength = pPartialTrResourceDesc->u.Memory.Length;
  1511. }
  1512. break;
  1513. }
  1514. case CmResourceTypePort: {
  1515. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypePort translated\n"));
  1516. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Port.Start = %x\n",
  1517. pPartialTrResourceDesc->u.Port.Start));
  1518. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Port.Length = %x\n",
  1519. pPartialTrResourceDesc->u.Port.Length));
  1520. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Flags = %x\n",
  1521. pPartialTrResourceDesc->Flags));
  1522. break;
  1523. }
  1524. case CmResourceTypeInterrupt: {
  1525. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("CmResourceTypeInterrupt translated\n"));
  1526. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Interrupt.Level = %x\n",
  1527. pPartialTrResourceDesc->u.Interrupt.Level));
  1528. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Interrupt.Vector = %x\n",
  1529. pPartialTrResourceDesc->u.Interrupt.Vector));
  1530. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("u.Interrupt.Affinity = %x\n",
  1531. pPartialTrResourceDesc->u.Interrupt.Affinity));
  1532. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Flags = %x\n",
  1533. pPartialTrResourceDesc->Flags));
  1534. #ifndef POLL
  1535. pDevExt->Vector = pPartialTrResourceDesc->u.Interrupt.Vector;
  1536. pDevExt->Irql = (KIRQL) pPartialTrResourceDesc->u.Interrupt.Level;
  1537. Affinity = pPartialTrResourceDesc->u.Interrupt.Affinity;
  1538. #endif
  1539. break;
  1540. }
  1541. default: {
  1542. break;
  1543. }
  1544. } // switch (pPartialTrResourceDesc->Type)
  1545. } // for (i = 0; i < count; i++, pPartialTrResourceDesc++)
  1546. } // if (pFullTrResourceDesc)
  1547. //
  1548. // Do some error checking on the configuration info we have.
  1549. //
  1550. // Make sure that the interrupt is non zero (which we defaulted
  1551. // it to).
  1552. //
  1553. // Make sure that the portaddress is non zero (which we defaulted
  1554. // it to).
  1555. //
  1556. // Make sure that the DosDevices is not NULL (which we defaulted
  1557. // it to).
  1558. //
  1559. // We need to make sure that if an interrupt status
  1560. // was specified, that a port index was also specfied,
  1561. // and if so that the port index is <= maximum ports
  1562. // on a board.
  1563. //
  1564. // We should also validate that the bus type and number
  1565. // are correct.
  1566. //
  1567. // We will also validate that the interrupt mode makes
  1568. // sense for the bus.
  1569. //
  1570. if (!pDevExt->TranslatedRuntime.LowPart && pDevExt->IsPci) {
  1571. CyzLogError(
  1572. pDevExt->DriverObject,
  1573. NULL,
  1574. pDevExt->PhysicalBoardMemory,
  1575. CyzPhysicalZero,
  1576. 0,
  1577. 0,
  1578. 0,
  1579. 0,
  1580. STATUS_SUCCESS,
  1581. CYZ_INVALID_RUNTIME_REGISTERS,
  1582. 0,
  1583. NULL,
  1584. 0,
  1585. NULL
  1586. );
  1587. Cycladz_KdPrint (pDevExt,SER_DBG_CYCLADES,
  1588. ("Bogus Runtime address %x\n",
  1589. pDevExt->TranslatedRuntime.LowPart));
  1590. status = STATUS_INSUFFICIENT_RESOURCES;
  1591. goto GetResourceInfo_Cleanup;
  1592. }
  1593. if (!pDevExt->TranslatedBoardMemory.LowPart) {
  1594. CyzLogError(
  1595. pDevExt->DriverObject,
  1596. NULL,
  1597. pDevExt->PhysicalBoardMemory,
  1598. CyzPhysicalZero,
  1599. 0,
  1600. 0,
  1601. 0,
  1602. 0,
  1603. STATUS_SUCCESS,
  1604. CYZ_INVALID_BOARD_MEMORY,
  1605. 0,
  1606. NULL,
  1607. 0,
  1608. NULL
  1609. );
  1610. Cycladz_KdPrint (pDevExt,SER_DBG_CYCLADES,
  1611. ("Bogus BoardMemory address %x\n",
  1612. pDevExt->TranslatedBoardMemory.LowPart));
  1613. status = STATUS_INSUFFICIENT_RESOURCES;
  1614. goto GetResourceInfo_Cleanup;
  1615. }
  1616. #ifndef POLL
  1617. if (!pDevExt->OriginalVector) {
  1618. CyzLogError(
  1619. pDevExt->DriverObject,
  1620. NULL,
  1621. pDevExt->PhysicalBoardMemory,
  1622. CyzPhysicalZero,
  1623. 0,
  1624. 0,
  1625. 0,
  1626. 0,
  1627. STATUS_SUCCESS,
  1628. CYZ_INVALID_INTERRUPT,
  1629. 0,
  1630. NULL,
  1631. 0,
  1632. NULL
  1633. );
  1634. Cycladz_KdPrint (pDevExt,SER_DBG_CYCLADES,("Bogus vector %x\n",
  1635. pDevExt->OriginalVector));
  1636. status = STATUS_INSUFFICIENT_RESOURCES;
  1637. goto GetResourceInfo_Cleanup;
  1638. }
  1639. #endif
  1640. //
  1641. // We don't want to cause the hal to have a bad day,
  1642. // so let's check the interface type and bus number.
  1643. //
  1644. // We only need to check the registry if they aren't
  1645. // equal to the defaults.
  1646. //
  1647. if (pDevExt->BusNumber != 0) {
  1648. BOOLEAN foundIt = 0;
  1649. if (pDevExt->InterfaceType >= MaximumInterfaceType) {
  1650. CyzLogError(
  1651. pDevExt->DriverObject,
  1652. NULL,
  1653. pDevExt->PhysicalBoardMemory,
  1654. CyzPhysicalZero,
  1655. 0,
  1656. 0,
  1657. 0,
  1658. pDevExt->InterfaceType,
  1659. STATUS_SUCCESS,
  1660. CYZ_UNKNOWN_BUS,
  1661. 0,
  1662. NULL,
  1663. 0,
  1664. NULL
  1665. );
  1666. Cycladz_KdPrint (pDevExt,SER_DBG_CYCLADES,
  1667. ("Invalid Bus type %x\n", pDevExt->BusNumber));
  1668. //status = SERIAL_UNKNOWN_BUS;
  1669. status = STATUS_INSUFFICIENT_RESOURCES;
  1670. goto GetResourceInfo_Cleanup;
  1671. }
  1672. IoQueryDeviceDescription(
  1673. (INTERFACE_TYPE *)&pDevExt->InterfaceType,
  1674. &zero,
  1675. NULL,
  1676. NULL,
  1677. NULL,
  1678. NULL,
  1679. Cycladz_ItemCallBack,
  1680. &foundIt
  1681. );
  1682. if (!foundIt) {
  1683. CyzLogError(
  1684. pDevExt->DriverObject,
  1685. NULL,
  1686. pDevExt->PhysicalBoardMemory,
  1687. CyzPhysicalZero,
  1688. 0,
  1689. 0,
  1690. 0,
  1691. pDevExt->InterfaceType,
  1692. STATUS_SUCCESS,
  1693. CYZ_BUS_NOT_PRESENT,
  1694. 0,
  1695. NULL,
  1696. 0,
  1697. NULL
  1698. );
  1699. Cycladz_KdPrint(
  1700. pDevExt,
  1701. SER_DBG_CYCLADES,
  1702. ("There aren't that many of those\n"
  1703. "------- busses on this system,%x\n",
  1704. pDevExt->BusNumber)
  1705. );
  1706. //status = SERIAL_BUS_NOT_PRESENT;
  1707. status = STATUS_INSUFFICIENT_RESOURCES;
  1708. goto GetResourceInfo_Cleanup;
  1709. }
  1710. }
  1711. //
  1712. // Dump out the board configuration.
  1713. //
  1714. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES, ("PhysicalRuntime: %x\n",
  1715. pDevExt->PhysicalRuntime.LowPart));
  1716. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES, ("TranslatedRuntime: %x\n",
  1717. pDevExt->TranslatedRuntime.LowPart));
  1718. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES, ("RuntimeLength: %x\n",
  1719. pDevExt->RuntimeLength));
  1720. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES, ("PhysicalBoardMemory: %x\n",
  1721. pDevExt->PhysicalBoardMemory.LowPart));
  1722. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES, ("TranslatedBoardMemory: %x\n",
  1723. pDevExt->TranslatedBoardMemory.LowPart));
  1724. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES, ("BoardMemoryLength: %x\n",
  1725. pDevExt->BoardMemoryLength));
  1726. #ifndef POLL
  1727. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("OriginalIrql = %x\n",
  1728. pDevExt->OriginalIrql));
  1729. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("OriginalVector = %x\n",
  1730. pDevExt->OriginalVector));
  1731. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Irql = %x\n",
  1732. pDevExt->Irql));
  1733. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Vector = %x\n",
  1734. pDevExt->Vector));
  1735. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Affinity = %x\n",
  1736. Affinity));
  1737. #endif
  1738. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("InterfaceType = %x\n",
  1739. pDevExt->InterfaceType));
  1740. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("BusNumber = %x\n",
  1741. pDevExt->BusNumber));
  1742. // ABOVE: COPIED FROM SerialGetPortInfo
  1743. // ------------------------------------
  1744. // BELOW: COPIED FROM SerialInitController
  1745. if (pDevExt->IsPci) {
  1746. pDevExt->Runtime = MmMapIoSpace(pDevExt->TranslatedRuntime,
  1747. pDevExt->RuntimeLength,
  1748. FALSE);
  1749. if (!pDevExt->Runtime){
  1750. CyzLogError(
  1751. pDevExt->DriverObject,
  1752. NULL,
  1753. pDevExt->PhysicalBoardMemory,
  1754. CyzPhysicalZero,
  1755. 0,
  1756. 0,
  1757. 0,
  1758. 0,
  1759. STATUS_SUCCESS,
  1760. CYZ_RUNTIME_NOT_MAPPED,
  1761. 0,
  1762. NULL,
  1763. 0,
  1764. NULL
  1765. );
  1766. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Could not map memory for Runtime\n"));
  1767. status = STATUS_NONE_MAPPED;
  1768. goto GetResourceInfo_Cleanup;
  1769. }
  1770. }
  1771. pDevExt->BoardMemory = MmMapIoSpace(pDevExt->TranslatedBoardMemory,
  1772. pDevExt->BoardMemoryLength,
  1773. FALSE);
  1774. if (!pDevExt->BoardMemory){
  1775. CyzLogError(
  1776. pDevExt->DriverObject,
  1777. NULL,
  1778. pDevExt->PhysicalBoardMemory,
  1779. CyzPhysicalZero,
  1780. 0,
  1781. 0,
  1782. 0,
  1783. 0,
  1784. STATUS_SUCCESS,
  1785. CYZ_BOARD_NOT_MAPPED,
  1786. 0,
  1787. NULL,
  1788. 0,
  1789. NULL
  1790. );
  1791. Cycladz_KdPrint(pDevExt,SER_DBG_CYCLADES,("Could not map memory for DP memory"));
  1792. status = STATUS_NONE_MAPPED;
  1793. goto GetResourceInfo_Cleanup;
  1794. }
  1795. GetResourceInfo_Cleanup:
  1796. if (!NT_SUCCESS(status)) {
  1797. if (pDevExt->Runtime) {
  1798. MmUnmapIoSpace(pDevExt->Runtime, pDevExt->RuntimeLength);
  1799. pDevExt->Runtime = NULL;
  1800. }
  1801. if (pDevExt->BoardMemory) {
  1802. MmUnmapIoSpace(pDevExt->BoardMemory, pDevExt->BoardMemoryLength);
  1803. pDevExt->BoardMemory = NULL;
  1804. }
  1805. }
  1806. Cycladz_KdPrint (pDevExt,SER_DBG_CYCLADES, ("leaving Cycladz_GetResourceInfo\n"));
  1807. return status;
  1808. }
  1809. VOID
  1810. Cycladz_ReleaseResources(IN PFDO_DEVICE_DATA PDevExt)
  1811. {
  1812. Cycladz_KdPrint (PDevExt,SER_DBG_CYCLADES, ("entering Cycladz_ReleaseResources\n"));
  1813. if (PDevExt->PChildRequiredList) {
  1814. ExFreePool(PDevExt->PChildRequiredList);
  1815. PDevExt->PChildRequiredList = NULL;
  1816. }
  1817. if (PDevExt->PChildResourceList) {
  1818. ExFreePool(PDevExt->PChildResourceList);
  1819. PDevExt->PChildResourceList = NULL;
  1820. }
  1821. if (PDevExt->PChildResourceListTr) {
  1822. ExFreePool(PDevExt->PChildResourceListTr);
  1823. PDevExt->PChildResourceListTr = NULL;
  1824. }
  1825. if (PDevExt->Runtime) {
  1826. MmUnmapIoSpace(PDevExt->Runtime, PDevExt->RuntimeLength);
  1827. PDevExt->Runtime = NULL;
  1828. }
  1829. if (PDevExt->BoardMemory) {
  1830. MmUnmapIoSpace(PDevExt->BoardMemory, PDevExt->BoardMemoryLength);
  1831. PDevExt->BoardMemory = NULL;
  1832. }
  1833. Cycladz_KdPrint (PDevExt,SER_DBG_CYCLADES, ("leaving Cycladz_ReleaseResources\n"));
  1834. }
  1835. NTSTATUS
  1836. Cycladz_ItemCallBack(
  1837. IN PVOID Context,
  1838. IN PUNICODE_STRING PathName,
  1839. IN INTERFACE_TYPE BusType,
  1840. IN ULONG BusNumber,
  1841. IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
  1842. IN CONFIGURATION_TYPE ControllerType,
  1843. IN ULONG ControllerNumber,
  1844. IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
  1845. IN CONFIGURATION_TYPE PeripheralType,
  1846. IN ULONG PeripheralNumber,
  1847. IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
  1848. )
  1849. /*++
  1850. Routine Description:
  1851. This routine is called to check if a particular item
  1852. is present in the registry.
  1853. Arguments:
  1854. Context - Pointer to a boolean.
  1855. PathName - unicode registry path. Not Used.
  1856. BusType - Internal, Isa, ...
  1857. BusNumber - Which bus if we are on a multibus system.
  1858. BusInformation - Configuration information about the bus. Not Used.
  1859. ControllerType - Controller type.
  1860. ControllerNumber - Which controller if there is more than one
  1861. controller in the system.
  1862. ControllerInformation - Array of pointers to the three pieces of
  1863. registry information.
  1864. PeripheralType - Should be a peripheral.
  1865. PeripheralNumber - Which peripheral - not used..
  1866. PeripheralInformation - Configuration information. Not Used.
  1867. Return Value:
  1868. STATUS_SUCCESS
  1869. --*/
  1870. {
  1871. UNREFERENCED_PARAMETER (PathName);
  1872. UNREFERENCED_PARAMETER (BusType);
  1873. UNREFERENCED_PARAMETER (BusNumber);
  1874. UNREFERENCED_PARAMETER (BusInformation);
  1875. UNREFERENCED_PARAMETER (ControllerType);
  1876. UNREFERENCED_PARAMETER (ControllerNumber);
  1877. UNREFERENCED_PARAMETER (ControllerInformation);
  1878. UNREFERENCED_PARAMETER (PeripheralType);
  1879. UNREFERENCED_PARAMETER (PeripheralNumber);
  1880. UNREFERENCED_PARAMETER (PeripheralInformation);
  1881. PAGED_CODE();
  1882. *((BOOLEAN *)Context) = TRUE;
  1883. return STATUS_SUCCESS;
  1884. }
  1885. NTSTATUS
  1886. Cycladz_BuildRequirementsList(
  1887. OUT PIO_RESOURCE_REQUIREMENTS_LIST *PChildRequiredList_Pointer,
  1888. IN PCM_RESOURCE_LIST PResourceList, IN ULONG NumberOfResources
  1889. )
  1890. {
  1891. NTSTATUS status = STATUS_SUCCESS;
  1892. ULONG count;
  1893. ULONG i,j;
  1894. PCM_FULL_RESOURCE_DESCRIPTOR pFullResourceDesc = NULL;
  1895. PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
  1896. PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialResourceDesc;
  1897. ULONG requiredLength;
  1898. PIO_RESOURCE_REQUIREMENTS_LIST requiredList;
  1899. PIO_RESOURCE_LIST requiredResList;
  1900. PIO_RESOURCE_DESCRIPTOR requiredResDesc;
  1901. *PChildRequiredList_Pointer = NULL;
  1902. // Validate input parameter
  1903. if (PResourceList == NULL) {
  1904. status = STATUS_INSUFFICIENT_RESOURCES;
  1905. goto CycladzBuildRequirementList_Error;
  1906. }
  1907. ASSERT(PResourceList->Count == 1);
  1908. // Initialize requiredList
  1909. requiredLength = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
  1910. + sizeof(IO_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1);
  1911. requiredList = ExAllocatePool(PagedPool, requiredLength);
  1912. if (requiredList == NULL) {
  1913. status = STATUS_INSUFFICIENT_RESOURCES;
  1914. goto CycladzBuildRequirementList_Error;
  1915. }
  1916. RtlZeroMemory(requiredList, requiredLength);
  1917. // Get information from PResourceList and build requiredList
  1918. pFullResourceDesc = &PResourceList->List[0];
  1919. if (pFullResourceDesc) {
  1920. pPartialResourceList = &pFullResourceDesc->PartialResourceList;
  1921. pPartialResourceDesc = pPartialResourceList->PartialDescriptors;
  1922. count = pPartialResourceList->Count;
  1923. if (count < NumberOfResources) {
  1924. ExFreePool(requiredList);
  1925. return STATUS_INSUFFICIENT_RESOURCES;
  1926. }
  1927. requiredList->ListSize = requiredLength;
  1928. requiredList->InterfaceType = pFullResourceDesc->InterfaceType;
  1929. requiredList->BusNumber = pFullResourceDesc->BusNumber;
  1930. requiredList->SlotNumber = 0; //?????? There's no SlotNumber in the Resource List
  1931. requiredList->AlternativeLists = 1;
  1932. requiredResList = &requiredList->List[0];
  1933. requiredResList->Count = NumberOfResources;
  1934. requiredResDesc = &requiredResList->Descriptors[0];
  1935. for (i=0,j=0; i<count && j<NumberOfResources; i++,pPartialResourceDesc++) {
  1936. switch (pPartialResourceDesc->Type) {
  1937. case CmResourceTypeMemory: {
  1938. requiredResDesc->Type = pPartialResourceDesc->Type;
  1939. //requiredResDesc->ShareDisposition = pPartialResourceDesc->ShareDisposition;
  1940. requiredResDesc->ShareDisposition = CmResourceShareShared;
  1941. requiredResDesc->Flags = pPartialResourceDesc->Flags;
  1942. requiredResDesc->u.Memory.Length = pPartialResourceDesc->u.Memory.Length;
  1943. requiredResDesc->u.Memory.Alignment = 4;
  1944. requiredResDesc->u.Memory.MinimumAddress = pPartialResourceDesc->u.Memory.Start;
  1945. requiredResDesc->u.Memory.MaximumAddress.QuadPart
  1946. = pPartialResourceDesc->u.Memory.Start.QuadPart
  1947. + pPartialResourceDesc->u.Memory.Length - 1;
  1948. requiredResDesc++;
  1949. j++;
  1950. break;
  1951. }
  1952. case CmResourceTypePort: {
  1953. break;
  1954. }
  1955. case CmResourceTypeInterrupt: {
  1956. requiredResDesc->Type = pPartialResourceDesc->Type;
  1957. requiredResDesc->ShareDisposition = CmResourceShareShared;
  1958. requiredResDesc->Flags = pPartialResourceDesc->Flags;
  1959. requiredResDesc->u.Interrupt.MinimumVector
  1960. = pPartialResourceDesc->u.Interrupt.Vector;
  1961. requiredResDesc->u.Interrupt.MaximumVector
  1962. = pPartialResourceDesc->u.Interrupt.Vector;
  1963. requiredResDesc++;
  1964. j++;
  1965. break;
  1966. }
  1967. default:
  1968. break;
  1969. } // end switch
  1970. } // end for
  1971. } // end if (pFullResourceDesc)
  1972. *PChildRequiredList_Pointer = requiredList;
  1973. CycladzBuildRequirementList_Error:
  1974. return status;
  1975. }
  1976. NTSTATUS
  1977. Cycladz_BuildResourceList(
  1978. OUT PCM_RESOURCE_LIST *POutList_Pointer,
  1979. OUT ULONG *ListSize_Pointer,
  1980. IN PCM_RESOURCE_LIST PInList,
  1981. IN ULONG NumberOfResources
  1982. )
  1983. {
  1984. NTSTATUS status = STATUS_SUCCESS;
  1985. ULONG i,j;
  1986. PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialInDesc;
  1987. ULONG length;
  1988. PCM_RESOURCE_LIST pOutList;
  1989. PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialOutDesc;
  1990. *POutList_Pointer = NULL;
  1991. *ListSize_Pointer =0;
  1992. // Validate input parameter
  1993. if (PInList == NULL) {
  1994. status = STATUS_INSUFFICIENT_RESOURCES;
  1995. goto CycladzBuildResourceList_Error;
  1996. }
  1997. ASSERT(PInList->Count == 1);
  1998. if (PInList->List[0].PartialResourceList.Count < NumberOfResources) {
  1999. status = STATUS_INSUFFICIENT_RESOURCES;
  2000. goto CycladzBuildResourceList_Error;
  2001. }
  2002. // Initialize pOutList
  2003. length = sizeof(CM_RESOURCE_LIST)
  2004. + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1);
  2005. pOutList = ExAllocatePool(PagedPool, length);
  2006. if (pOutList == NULL) {
  2007. status = STATUS_INSUFFICIENT_RESOURCES;
  2008. goto CycladzBuildResourceList_Error;
  2009. }
  2010. RtlZeroMemory(pOutList, length);
  2011. // Get information from PInList and build pOutList
  2012. pOutList->Count = 1; // not sure if we have to report Translated information too.
  2013. pOutList->List[0].InterfaceType = PInList->List[0].InterfaceType;
  2014. pOutList->List[0].BusNumber = PInList->List[0].BusNumber;
  2015. pOutList->List[0].PartialResourceList.Count = NumberOfResources;
  2016. pPartialOutDesc = &pOutList->List[0].PartialResourceList.PartialDescriptors[0];
  2017. pPartialInDesc = &PInList->List[0].PartialResourceList.PartialDescriptors[0];
  2018. for (i=0,j=0; i < PInList->List[0].PartialResourceList.Count; i++,pPartialInDesc++) {
  2019. if (j==NumberOfResources) {
  2020. break;
  2021. }
  2022. switch(pPartialInDesc->Type) {
  2023. case CmResourceTypeMemory:
  2024. pPartialOutDesc->ShareDisposition = CmResourceShareShared;
  2025. pPartialOutDesc->Type = pPartialInDesc->Type;
  2026. pPartialOutDesc->Flags = pPartialInDesc->Flags;
  2027. pPartialOutDesc->u.Memory.Start = pPartialInDesc->u.Memory.Start;
  2028. pPartialOutDesc->u.Memory.Length = pPartialInDesc->u.Memory.Length;
  2029. pPartialOutDesc++;
  2030. j++;
  2031. break;
  2032. case CmResourceTypeInterrupt:
  2033. pPartialOutDesc->ShareDisposition = CmResourceShareShared;
  2034. pPartialOutDesc->Type = pPartialInDesc->Type;
  2035. pPartialOutDesc->Flags = pPartialInDesc->Flags;
  2036. pPartialOutDesc->u.Interrupt.Level = pPartialInDesc->u.Interrupt.Level;
  2037. pPartialOutDesc->u.Interrupt.Vector = pPartialInDesc->u.Interrupt.Vector;
  2038. pPartialOutDesc->u.Interrupt.Affinity = pPartialInDesc->u.Interrupt.Affinity;
  2039. pPartialOutDesc++;
  2040. j++;
  2041. break;
  2042. default:
  2043. break;
  2044. } // end switch
  2045. } // end for
  2046. *POutList_Pointer = pOutList;
  2047. *ListSize_Pointer = length;
  2048. CycladzBuildResourceList_Error:
  2049. return status;
  2050. }
  2051. #if 0
  2052. VOID
  2053. Cycladz_Delay(
  2054. ULONG NumberOfMilliseconds
  2055. )
  2056. /*--------------------------------------------------------------------------
  2057. Cycladz_Delay()
  2058. Routine Description: Delay routine.
  2059. Arguments:
  2060. NumberOfMilliseconds - Number of milliseconds to be delayed.
  2061. Return Value: none.
  2062. --------------------------------------------------------------------------*/
  2063. {
  2064. LARGE_INTEGER startOfSpin, nextQuery, difference, delayTime;
  2065. delayTime.QuadPart = NumberOfMilliseconds*10*1000; // unit is 100ns
  2066. KeQueryTickCount(&startOfSpin);
  2067. do {
  2068. KeQueryTickCount(&nextQuery);
  2069. difference.QuadPart = nextQuery.QuadPart - startOfSpin.QuadPart;
  2070. ASSERT(KeQueryTimeIncrement() <= MAXLONG);
  2071. if (difference.QuadPart * KeQueryTimeIncrement() >=
  2072. delayTime.QuadPart) {
  2073. break;
  2074. }
  2075. } while (1);
  2076. }
  2077. #endif
  2078. ULONG
  2079. Cycladz_DoesBoardExist(
  2080. IN PFDO_DEVICE_DATA Extension
  2081. )
  2082. /*++
  2083. Routine Description:
  2084. This routine examines if the board is present.
  2085. Arguments:
  2086. Extension - A pointer to a serial device extension.
  2087. Return Value:
  2088. Will return number of ports.
  2089. --*/
  2090. {
  2091. ULONG numPorts = 0;
  2092. int z_load_status;
  2093. ULONG j;
  2094. ULONG n_channel;
  2095. ULONG fw_version;
  2096. WCHAR FwVersionBuffer[10];
  2097. UNICODE_STRING FwVersion;
  2098. struct FIRM_ID *pt_firm_id;
  2099. struct ZFW_CTRL *pt_zfw;
  2100. struct BOARD_CTRL *pt_board_ctrl;
  2101. LARGE_INTEGER d250ms = RtlConvertLongToLargeInteger(-250*10000);
  2102. z_reset_board(Extension);
  2103. z_load_status = z_load(Extension, 0, L"zlogic.cyz");
  2104. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("z_load returned %x\n",z_load_status));
  2105. // Error injection
  2106. //z_load_status = ZL_RET_FPGA_ERROR;
  2107. //---
  2108. switch (z_load_status){
  2109. case ZL_RET_SUCCESS:
  2110. break; // Success
  2111. case ZL_RET_NO_MATCHING_FW_CONFIG:
  2112. CyzLogError( Extension->DriverObject,Extension->Self,
  2113. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2114. 0,0,0,0,STATUS_SUCCESS,CYZ_NO_MATCHING_FW_CONFIG,
  2115. 0,NULL,0,NULL);
  2116. break;
  2117. case ZL_RET_FILE_OPEN_ERROR:
  2118. CyzLogError( Extension->DriverObject,Extension->Self,
  2119. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2120. 0,0,0,0,STATUS_SUCCESS,CYZ_FILE_OPEN_ERROR,
  2121. 0,NULL,0,NULL);
  2122. break;
  2123. case ZL_RET_FPGA_ERROR:
  2124. CyzLogError( Extension->DriverObject,Extension->Self,
  2125. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2126. 0,0,0,0,STATUS_SUCCESS,CYZ_FPGA_ERROR,
  2127. 0,NULL,0,NULL);
  2128. break;
  2129. case ZL_RET_FILE_READ_ERROR:
  2130. CyzLogError( Extension->DriverObject,Extension->Self,
  2131. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2132. 0,0,0,0,STATUS_SUCCESS,CYZ_FILE_READ_ERROR,
  2133. 0,NULL,0,NULL);
  2134. break;
  2135. }
  2136. if (z_load_status != ZL_RET_SUCCESS) {
  2137. goto DoesBoardExistEnd;
  2138. }
  2139. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("z_load worked\n"));
  2140. pt_firm_id = (struct FIRM_ID *) (Extension->BoardMemory + ID_ADDRESS);
  2141. for (j=0; j<8; j++) {
  2142. KeDelayExecutionThread(KernelMode,FALSE,&d250ms);
  2143. if (CYZ_READ_ULONG(&pt_firm_id->signature) == ZFIRM_ID) {
  2144. break;
  2145. }
  2146. }
  2147. // Error injection
  2148. //j=8;
  2149. //--
  2150. if (j==8) {
  2151. if (CYZ_READ_ULONG(&pt_firm_id->signature) == ZFIRM_HLT) {
  2152. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("ZFIRM_HLT\n"));
  2153. CyzLogError( Extension->DriverObject,Extension->Self,
  2154. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2155. 0,0,0,0,STATUS_SUCCESS,CYZ_POWER_SUPPLY,
  2156. 0,NULL,0,NULL);
  2157. } else {
  2158. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("Firmware didn't start\n"));
  2159. CyzLogError( Extension->DriverObject,Extension->Self,
  2160. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2161. 0,0,0,0,STATUS_SUCCESS,CYZ_FIRMWARE_NOT_STARTED,
  2162. 0,NULL,0,NULL);
  2163. }
  2164. goto DoesBoardExistEnd;
  2165. }
  2166. // Firmware was correclty loaded and initialized.
  2167. // Get number of channels.
  2168. pt_zfw = (struct ZFW_CTRL *)(Extension->BoardMemory +
  2169. CYZ_READ_ULONG(&pt_firm_id->zfwctrl_addr));
  2170. pt_board_ctrl = &pt_zfw->board_ctrl;
  2171. n_channel = CYZ_READ_ULONG(&pt_board_ctrl->n_channel);
  2172. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("n_channel = %d\n",n_channel));
  2173. //------- TEMP CODE-----------
  2174. //n_channel = 1;
  2175. //------ END TEMP CODE -------
  2176. fw_version = CYZ_READ_ULONG(&pt_board_ctrl->fw_version);
  2177. RtlInitUnicodeString(&FwVersion, NULL);
  2178. FwVersion.MaximumLength = sizeof(FwVersionBuffer);
  2179. FwVersion.Buffer = FwVersionBuffer;
  2180. RtlIntegerToUnicodeString(fw_version, 16, &FwVersion);
  2181. CyzLogError( Extension->DriverObject,Extension->Self,
  2182. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2183. 0,0,0,0,STATUS_SUCCESS,CYZ_FIRMWARE_VERSION,
  2184. FwVersion.Length,FwVersion.Buffer,
  2185. 0,NULL);
  2186. if (n_channel == 0) {
  2187. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("No channel\n"));
  2188. CyzLogError( Extension->DriverObject,Extension->Self,
  2189. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2190. 0,0,0,0,STATUS_SUCCESS,CYZ_BOARD_WITH_NO_PORT,
  2191. 0,NULL,0,NULL);
  2192. goto DoesBoardExistEnd;
  2193. }
  2194. // Error injection
  2195. //n_channel = 65;
  2196. //-----
  2197. if (n_channel > 64) {
  2198. Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("Invalid number of channels (more than 64).\n"));
  2199. CyzLogError( Extension->DriverObject,Extension->Self,
  2200. Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2201. 0,0,0,0,STATUS_SUCCESS,CYZ_BOARD_WITH_TOO_MANY_PORTS,
  2202. 0,NULL,0,NULL);
  2203. goto DoesBoardExistEnd;
  2204. }
  2205. // // Error injection
  2206. // //if (fw_version >= Z_COMPATIBLE_FIRMWARE)
  2207. // //-----
  2208. //
  2209. // if (fw_version < Z_COMPATIBLE_FIRMWARE) {
  2210. // Cycladz_KdPrint(Extension,SER_DBG_CYCLADES,("Incompatible firmware\n"));
  2211. // CyzLogError( Extension->DriverObject,Extension->Self,
  2212. // Extension->PhysicalBoardMemory,CyzPhysicalZero,
  2213. // 0,0,0,0,STATUS_SUCCESS,CYZ_INCOMPATIBLE_FIRMWARE,
  2214. // 0,NULL,0,NULL);
  2215. // goto DoesBoardExistEnd;
  2216. // }
  2217. Extension->FirmwareVersion = fw_version;
  2218. Extension->NumPorts = n_channel;
  2219. numPorts = n_channel;
  2220. DoesBoardExistEnd:
  2221. return numPorts;
  2222. }
  2223. PCHAR
  2224. PnPMinorFunctionString (
  2225. UCHAR MinorFunction
  2226. )
  2227. {
  2228. switch (MinorFunction)
  2229. {
  2230. case IRP_MN_START_DEVICE:
  2231. return "IRP_MN_START_DEVICE";
  2232. case IRP_MN_QUERY_REMOVE_DEVICE:
  2233. return "IRP_MN_QUERY_REMOVE_DEVICE";
  2234. case IRP_MN_REMOVE_DEVICE:
  2235. return "IRP_MN_REMOVE_DEVICE";
  2236. case IRP_MN_CANCEL_REMOVE_DEVICE:
  2237. return "IRP_MN_CANCEL_REMOVE_DEVICE";
  2238. case IRP_MN_STOP_DEVICE:
  2239. return "IRP_MN_STOP_DEVICE";
  2240. case IRP_MN_QUERY_STOP_DEVICE:
  2241. return "IRP_MN_QUERY_STOP_DEVICE";
  2242. case IRP_MN_CANCEL_STOP_DEVICE:
  2243. return "IRP_MN_CANCEL_STOP_DEVICE";
  2244. case IRP_MN_QUERY_DEVICE_RELATIONS:
  2245. return "IRP_MN_QUERY_DEVICE_RELATIONS";
  2246. case IRP_MN_QUERY_INTERFACE:
  2247. return "IRP_MN_QUERY_INTERFACE";
  2248. case IRP_MN_QUERY_CAPABILITIES:
  2249. return "IRP_MN_QUERY_CAPABILITIES";
  2250. case IRP_MN_QUERY_RESOURCES:
  2251. return "IRP_MN_QUERY_RESOURCES";
  2252. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  2253. return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
  2254. case IRP_MN_QUERY_DEVICE_TEXT:
  2255. return "IRP_MN_QUERY_DEVICE_TEXT";
  2256. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
  2257. return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
  2258. case IRP_MN_READ_CONFIG:
  2259. return "IRP_MN_READ_CONFIG";
  2260. case IRP_MN_WRITE_CONFIG:
  2261. return "IRP_MN_WRITE_CONFIG";
  2262. case IRP_MN_EJECT:
  2263. return "IRP_MN_EJECT";
  2264. case IRP_MN_SET_LOCK:
  2265. return "IRP_MN_SET_LOCK";
  2266. case IRP_MN_QUERY_ID:
  2267. return "IRP_MN_QUERY_ID";
  2268. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  2269. return "IRP_MN_QUERY_PNP_DEVICE_STATE";
  2270. case IRP_MN_QUERY_BUS_INFORMATION:
  2271. return "IRP_MN_QUERY_BUS_INFORMATION";
  2272. case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  2273. return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
  2274. case IRP_MN_SURPRISE_REMOVAL:
  2275. return "IRP_MN_SURPRISE_REMOVAL";
  2276. case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
  2277. return "IRP_MN_QUERY_LEGACY_BUS_INFORMATION";
  2278. default:
  2279. return "IRP_MN_?????";
  2280. }
  2281. }