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.

588 lines
12 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. This module contains the code for a serial imaging devices driver
  7. miscellaneous utility functions
  8. Author:
  9. Vlad Sadovsky vlads 10-April-1998
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. vlads 04/10/1998 Created first draft
  14. --*/
  15. #include "serscan.h"
  16. #include "serlog.h"
  17. #if DBG
  18. extern ULONG SerScanDebugLevel;
  19. #endif
  20. NTSTATUS
  21. SerScanSynchCompletionRoutine(
  22. IN PDEVICE_OBJECT DeviceObject,
  23. IN PIRP Irp,
  24. IN PKEVENT Event
  25. )
  26. /*++
  27. Routine Description:
  28. This routine is for use with synchronous IRP processing.
  29. All it does is signal an event, so the driver knows it
  30. can continue.
  31. Arguments:
  32. DriverObject - Pointer to driver object created by system.
  33. Irp - Irp that just completed
  34. Event - Event we'll signal to say Irp is done
  35. Return Value:
  36. None.
  37. --*/
  38. {
  39. KeSetEvent((PKEVENT) Event, 0, FALSE);
  40. return (STATUS_MORE_PROCESSING_REQUIRED);
  41. }
  42. NTSTATUS
  43. SerScanCompleteIrp(
  44. IN PDEVICE_OBJECT DeviceObject,
  45. IN PIRP Irp,
  46. IN PVOID Context
  47. )
  48. /*++
  49. Routine Description:
  50. This routine is for use with synchronous IRP processing.
  51. All it does is signal an event, so the driver knows it
  52. can continue.
  53. Arguments:
  54. DriverObject - Pointer to driver object created by system.
  55. Irp - Irp that just completed
  56. Event - Event we'll signal to say Irp is done
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. NTSTATUS Status;
  62. //
  63. // WORKWORK Do any post IO processing here...
  64. //
  65. if (Irp->PendingReturned) {
  66. IoMarkIrpPending (Irp);
  67. }
  68. Status = Irp->IoStatus.Status;
  69. return (Status);
  70. }
  71. NTSTATUS
  72. SerScanCallParent(
  73. IN PDEVICE_EXTENSION Extension,
  74. IN PIRP pIrp,
  75. IN BOOLEAN Wait,
  76. IN PIO_COMPLETION_ROUTINE CompletionRoutine
  77. )
  78. /*++
  79. Routine Description:
  80. This routine will call the next driver in the WDM chain
  81. Arguments:
  82. Extension - Device Extension.
  83. Irp - Irp to call parent with.
  84. Return Value:
  85. NTSTATUS.
  86. --*/
  87. {
  88. PIO_STACK_LOCATION pIrpStack;
  89. PIO_STACK_LOCATION pNextIrpStack;
  90. KEVENT Event;
  91. PVOID Context;
  92. NTSTATUS Status;
  93. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  94. Context = NULL;
  95. //
  96. // Prepare to call down to the parent with the I/O Request...
  97. //
  98. pNextIrpStack = IoGetNextIrpStackLocation(pIrp);
  99. pNextIrpStack->MajorFunction = pIrpStack->MajorFunction;
  100. pNextIrpStack->MinorFunction = pIrpStack->MinorFunction;
  101. RtlCopyMemory(&pNextIrpStack->Parameters,
  102. &pIrpStack->Parameters,
  103. sizeof(pIrpStack->Parameters.Others));
  104. if (Wait) {
  105. KeInitializeEvent(&Event, NotificationEvent, FALSE);
  106. CompletionRoutine = SerScanSynchCompletionRoutine;
  107. Context = (PVOID)&Event;
  108. }
  109. IoSetCompletionRoutine(
  110. pIrp,
  111. CompletionRoutine,
  112. Context,
  113. TRUE,
  114. TRUE,
  115. TRUE
  116. );
  117. //
  118. // Call down to our parent
  119. //
  120. Status = IoCallDriver(Extension->LowerDevice, pIrp);
  121. if (Wait && Status == STATUS_PENDING) {
  122. //
  123. // Still pending, wait for the IRP to complete
  124. //
  125. KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
  126. Status = pIrp->IoStatus.Status;
  127. }
  128. return Status;
  129. }
  130. VOID
  131. SerScanLogError(
  132. IN PDRIVER_OBJECT DriverObject,
  133. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  134. IN PHYSICAL_ADDRESS P1,
  135. IN PHYSICAL_ADDRESS P2,
  136. IN ULONG SequenceNumber,
  137. IN UCHAR MajorFunctionCode,
  138. IN UCHAR RetryCount,
  139. IN ULONG UniqueErrorValue,
  140. IN NTSTATUS FinalStatus,
  141. IN NTSTATUS SpecificIOStatus
  142. )
  143. /*++
  144. Routine Description:
  145. This routine allocates an error log entry, copies the supplied data
  146. to it, and requests that it be written to the error log file.
  147. Arguments:
  148. DriverObject - Supplies a pointer to the driver object for the
  149. device.
  150. DeviceObject - Supplies a pointer to the device object associated
  151. with the device that had the error, early in
  152. initialization, one may not yet exist.
  153. P1,P2 - Supplies the physical addresses for the controller
  154. ports involved with the error if they are available
  155. and puts them through as dump data.
  156. SequenceNumber - Supplies a ulong value that is unique to an IRP over
  157. the life of the irp in this driver - 0 generally
  158. means an error not associated with an irp.
  159. MajorFunctionCode - Supplies the major function code of the irp if there
  160. is an error associated with it.
  161. RetryCount - Supplies the number of times a particular operation
  162. has been retried.
  163. UniqueErrorValue - Supplies a unique long word that identifies the
  164. particular call to this function.
  165. FinalStatus - Supplies the final status given to the irp that was
  166. associated with this error. If this log entry is
  167. being made during one of the retries this value
  168. will be STATUS_SUCCESS.
  169. SpecificIOStatus - Supplies the IO status for this particular error.
  170. Return Value:
  171. None.
  172. --*/
  173. {
  174. PIO_ERROR_LOG_PACKET ErrorLogEntry;
  175. PVOID ObjectToUse;
  176. SHORT DumpToAllocate;
  177. if (ARGUMENT_PRESENT(DeviceObject)) {
  178. ObjectToUse = DeviceObject;
  179. } else {
  180. ObjectToUse = DriverObject;
  181. }
  182. DumpToAllocate = 0;
  183. if (P1.LowPart != 0 || P1.HighPart != 0) {
  184. DumpToAllocate = (SHORT) sizeof(PHYSICAL_ADDRESS);
  185. }
  186. if (P2.LowPart != 0 || P2.HighPart != 0) {
  187. DumpToAllocate += (SHORT) sizeof(PHYSICAL_ADDRESS);
  188. }
  189. ErrorLogEntry = IoAllocateErrorLogEntry(ObjectToUse,
  190. (UCHAR) (sizeof(IO_ERROR_LOG_PACKET) + DumpToAllocate));
  191. if (!ErrorLogEntry) {
  192. return;
  193. }
  194. ErrorLogEntry->ErrorCode = SpecificIOStatus;
  195. ErrorLogEntry->SequenceNumber = SequenceNumber;
  196. ErrorLogEntry->MajorFunctionCode = MajorFunctionCode;
  197. ErrorLogEntry->RetryCount = RetryCount;
  198. ErrorLogEntry->UniqueErrorValue = UniqueErrorValue;
  199. ErrorLogEntry->FinalStatus = FinalStatus;
  200. ErrorLogEntry->DumpDataSize = DumpToAllocate;
  201. if (DumpToAllocate) {
  202. RtlCopyMemory((PUCHAR)ErrorLogEntry->DumpData, &P1, sizeof(PHYSICAL_ADDRESS));
  203. if (DumpToAllocate > sizeof(PHYSICAL_ADDRESS)) {
  204. RtlCopyMemory(((PUCHAR) ErrorLogEntry->DumpData) +
  205. sizeof(PHYSICAL_ADDRESS), &P2,
  206. sizeof(PHYSICAL_ADDRESS));
  207. }
  208. }
  209. IoWriteErrorLogEntry(ErrorLogEntry);
  210. }
  211. NTSTATUS
  212. SerScanPassThrough(
  213. IN PDEVICE_OBJECT DeviceObject,
  214. IN PIRP Irp
  215. )
  216. /*++
  217. Routine Description:
  218. Arguments:
  219. DriverObject - Supplies the driver object.
  220. Return Value:
  221. None.
  222. --*/
  223. {
  224. PDEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
  225. PDEVICE_OBJECT AttachedDevice=Extension->AttachedDeviceObject;
  226. if (AttachedDevice != NULL) {
  227. //IoCopyCurrentIrpStackLocationToNext( Irp );
  228. IoSkipCurrentIrpStackLocation(Irp);
  229. return IoCallDriver(
  230. AttachedDevice,
  231. Irp
  232. );
  233. } else {
  234. Irp->IoStatus.Status = STATUS_PORT_DISCONNECTED;
  235. Irp->IoStatus.Information=0L;
  236. IoCompleteRequest(
  237. Irp,
  238. IO_NO_INCREMENT
  239. );
  240. return STATUS_PORT_DISCONNECTED;
  241. }
  242. }
  243. VOID
  244. RemoveReferenceAndCompleteRequest(
  245. PDEVICE_OBJECT DeviceObject,
  246. PIRP Irp,
  247. NTSTATUS StatusToReturn
  248. )
  249. {
  250. PDEVICE_EXTENSION Extension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
  251. LONG NewReferenceCount;
  252. NewReferenceCount=InterlockedDecrement(&Extension->ReferenceCount);
  253. if (NewReferenceCount == 0) {
  254. //
  255. // device is being removed, set event
  256. //
  257. KeSetEvent(
  258. &Extension->RemoveEvent,
  259. 0,
  260. FALSE
  261. );
  262. }
  263. Irp->IoStatus.Status = StatusToReturn;
  264. IoCompleteRequest(
  265. Irp,
  266. IO_SERIAL_INCREMENT
  267. );
  268. return;
  269. }
  270. NTSTATUS
  271. CheckStateAndAddReference(
  272. PDEVICE_OBJECT DeviceObject,
  273. PIRP Irp
  274. )
  275. {
  276. PDEVICE_EXTENSION Extension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
  277. KIRQL OldIrql;
  278. InterlockedIncrement(&Extension->ReferenceCount);
  279. if (Extension->Removing) {
  280. //
  281. // driver not accepting requests already
  282. //
  283. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  284. if (irpSp->MajorFunction == IRP_MJ_POWER) {
  285. PoStartNextPowerIrp(Irp);
  286. }
  287. RemoveReferenceAndCompleteRequest(
  288. DeviceObject,
  289. Irp,
  290. STATUS_UNSUCCESSFUL
  291. );
  292. return STATUS_UNSUCCESSFUL;
  293. }
  294. //InterlockedIncrement(&Extension->PendingIoCount);
  295. return STATUS_SUCCESS;
  296. }
  297. VOID
  298. RemoveReference(
  299. PDEVICE_OBJECT DeviceObject
  300. )
  301. {
  302. PDEVICE_EXTENSION Extension=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
  303. LONG NewReferenceCount;
  304. NewReferenceCount=InterlockedDecrement(&Extension->ReferenceCount);
  305. if (NewReferenceCount == 0) {
  306. //
  307. // device is being removed, set event
  308. //
  309. KeSetEvent(
  310. &Extension->RemoveEvent,
  311. 0,
  312. FALSE
  313. );
  314. }
  315. return;
  316. }
  317. NTSTATUS
  318. WaitForLowerDriverToCompleteIrp(
  319. PDEVICE_OBJECT TargetDeviceObject,
  320. PIRP Irp,
  321. PKEVENT Event
  322. )
  323. {
  324. NTSTATUS Status;
  325. KeResetEvent(Event);
  326. IoSetCompletionRoutine(
  327. Irp,
  328. SerScanSynchCompletionRoutine,
  329. Event,
  330. TRUE,
  331. TRUE,
  332. TRUE
  333. );
  334. Status = IoCallDriver(TargetDeviceObject, Irp);
  335. if (Status == STATUS_PENDING) {
  336. KeWaitForSingleObject(
  337. Event,
  338. Executive,
  339. KernelMode,
  340. FALSE,
  341. NULL
  342. );
  343. }
  344. return Irp->IoStatus.Status;
  345. }
  346. #ifdef DEAD_CODE
  347. VOID
  348. SSIncrementIoCount(
  349. IN PDEVICE_OBJECT pDeviceObject
  350. )
  351. /*++
  352. Routine Description:
  353. Performs interlocked increment of pending i/o counter.
  354. Arguments:
  355. Device Object
  356. Return Value:
  357. None
  358. --*/
  359. {
  360. PDEVICE_EXTENSION Extension;
  361. Extension = (PDEVICE_EXTENSION)(pDeviceObject -> DeviceExtension);
  362. InterlockedIncrement(&Extension -> PendingIoCount);
  363. }
  364. LONG
  365. SSDecrementIoCount(
  366. IN PDEVICE_OBJECT pDeviceObject
  367. )
  368. /*++
  369. Routine Description:
  370. Performs interlocked decrement of i/o counter and when it eaches zero
  371. initiates device object destruction
  372. Arguments:
  373. Device Object
  374. Return Value:
  375. None
  376. --*/
  377. {
  378. PDEVICE_EXTENSION Extension;
  379. LONG ioCount;
  380. Extension = (PDEVICE_EXTENSION)(pDeviceObject -> DeviceExtension);
  381. ioCount = InterlockedDecrement(&Extension -> PendingIoCount);
  382. if (0 == ioCount) {
  383. KeSetEvent(&Extension -> PendingIoEvent,1,FALSE);
  384. }
  385. return ioCount;
  386. }
  387. #endif