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.

385 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. smbclass.c
  5. Abstract:
  6. SMBus Class Driver
  7. Author:
  8. Ken Reneris
  9. Environment:
  10. Notes:
  11. Revision History:
  12. 27-Feb-97
  13. Pnp support - Bob Moore
  14. --*/
  15. #include "smbc.h"
  16. ULONG SMBCDebug = SMB_ERRORS;
  17. //
  18. // Prototypes
  19. //
  20. NTSTATUS
  21. DriverEntry (
  22. IN PDRIVER_OBJECT DriverObject,
  23. IN PUNICODE_STRING RegistryPath
  24. );
  25. NTSTATUS
  26. SmbClassInitializeDevice (
  27. IN ULONG MajorVersion,
  28. IN ULONG MinorVersion,
  29. IN PDRIVER_OBJECT DriverObject
  30. );
  31. NTSTATUS
  32. SmbClassDeviceInitialize (
  33. PSMB_CLASS SmbClass
  34. );
  35. VOID
  36. SmbCUnload(
  37. IN PDRIVER_OBJECT DriverObject
  38. );
  39. NTSTATUS
  40. SmbCInternalIoctl(
  41. IN PDEVICE_OBJECT DeviceObject,
  42. IN PIRP Irp
  43. );
  44. NTSTATUS
  45. SmbCPnpDispatch(
  46. IN PDEVICE_OBJECT DeviceObject,
  47. IN PIRP Irp
  48. );
  49. NTSTATUS
  50. SmbCPowerDispatch(
  51. IN PDEVICE_OBJECT DeviceObject,
  52. IN PIRP Irp
  53. );
  54. NTSTATUS
  55. SmbCForwardRequest(
  56. IN PDEVICE_OBJECT DeviceObject,
  57. IN PIRP Irp
  58. );
  59. #ifdef ALLOC_PRAGMA
  60. #pragma alloc_text(PAGE,DriverEntry)
  61. #pragma alloc_text(PAGE,SmbClassInitializeDevice)
  62. #pragma alloc_text(PAGE,SmbCUnload)
  63. #endif
  64. NTSTATUS
  65. DriverEntry (
  66. IN PDRIVER_OBJECT DriverObject,
  67. IN PUNICODE_STRING RegistryPath
  68. )
  69. {
  70. return STATUS_SUCCESS;
  71. }
  72. NTSTATUS
  73. SmbClassInitializeDevice (
  74. IN ULONG MajorVersion,
  75. IN ULONG MinorVersion,
  76. IN PDRIVER_OBJECT DriverObject
  77. )
  78. /*++
  79. Routine Description:
  80. This function is called by the SM bus miniport driver/DriverEntry
  81. to perform class specific initialization
  82. Arguments:
  83. MajorVersion - Version #
  84. MinorVersion - Version #
  85. DriverObject - From miniport DriverEntry
  86. Return Value:
  87. Status
  88. --*/
  89. {
  90. if (MajorVersion != SMB_CLASS_MAJOR_VERSION) {
  91. return STATUS_REVISION_MISMATCH;
  92. }
  93. //
  94. // Set up the device driver entry points.
  95. //
  96. DriverObject->DriverUnload = SmbCUnload;
  97. DriverObject->MajorFunction[IRP_MJ_POWER] = SmbCPowerDispatch;
  98. DriverObject->MajorFunction[IRP_MJ_PNP] = SmbCPnpDispatch;
  99. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = SmbCInternalIoctl;
  100. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SmbCForwardRequest;
  101. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SmbCForwardRequest;
  102. //
  103. // Miniport will set up the AddDevice entry
  104. //
  105. return STATUS_SUCCESS;
  106. }
  107. VOID
  108. SmbCUnload(
  109. IN PDRIVER_OBJECT DriverObject
  110. )
  111. {
  112. SmbPrint (SMB_NOTE, ("SmBCUnLoad: \n"));
  113. if (DriverObject->DeviceObject != NULL) {
  114. SmbPrint (SMB_ERROR, ("SmBCUnLoad: Unload called before all devices removed.\n"));
  115. }
  116. }
  117. NTSTATUS
  118. SmbCPowerDispatch(
  119. IN PDEVICE_OBJECT DeviceObject,
  120. IN PIRP Irp
  121. )
  122. /*++
  123. Routine Description:
  124. This is the dispatch routine for power requests.
  125. Arguments:
  126. DeviceObject - Pointer to class device object.
  127. Irp - Pointer to the request packet.
  128. Return Value:
  129. Status is returned.
  130. --*/
  131. {
  132. PIO_STACK_LOCATION irpStack;
  133. PSMBDATA SmbData;
  134. NTSTATUS status;
  135. SmbData = DeviceObject->DeviceExtension;
  136. //
  137. // What do we do with the irp?
  138. //
  139. PoStartNextPowerIrp( Irp );
  140. if (SmbData->Class.LowerDeviceObject != NULL) {
  141. //
  142. // Forward the request along
  143. //
  144. IoSkipCurrentIrpStackLocation( Irp );
  145. status = PoCallDriver( SmbData->Class.LowerDeviceObject, Irp );
  146. } else {
  147. //
  148. // Complete the request with the current status
  149. //
  150. status = Irp->IoStatus.Status;
  151. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  152. }
  153. return status;
  154. }
  155. NTSTATUS
  156. SmbCInternalIoctl (
  157. IN PDEVICE_OBJECT DeviceObject,
  158. IN PIRP Irp
  159. )
  160. /*++
  161. Routine Description:
  162. This routine is the dispatch routine for internal IOCTLs.
  163. Arguments:
  164. DeviceObject - Pointer to class device object.
  165. Irp - Pointer to the request packet.
  166. Return Value:
  167. Status is returned.
  168. --*/
  169. {
  170. PIO_STACK_LOCATION IrpSp;
  171. PSMB_REQUEST SmbReq;
  172. PSMBDATA Smb;
  173. NTSTATUS Status;
  174. //
  175. // Get a pointer to the current parameters for this request. The
  176. // information is contained in the current stack location.
  177. //
  178. Status = STATUS_NOT_SUPPORTED;
  179. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  180. Smb = (PSMBDATA) DeviceObject->DeviceExtension;
  181. switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
  182. case SMB_BUS_REQUEST:
  183. Irp->IoStatus.Information = 0;
  184. //
  185. // Verify bus request is valid
  186. //
  187. if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(SMB_REQUEST)) {
  188. // Invalid buffer length
  189. SmbPrint(SMB_NOTE, ("SmbCIoctl: Invalid bus_req length\n"));
  190. Status = STATUS_BUFFER_TOO_SMALL;
  191. Irp->IoStatus.Information = sizeof(SMB_REQUEST);
  192. break;
  193. }
  194. SmbReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
  195. if (SmbReq->Protocol > SMB_MAXIMUM_PROTOCOL ||
  196. SmbReq->Address > 0x7F ||
  197. (SmbReq->Protocol == SMB_WRITE_BLOCK &&
  198. SmbReq->BlockLength > SMB_MAX_DATA_SIZE)) {
  199. // Invalid param in request
  200. SmbPrint(SMB_NOTE, ("SmbCIoctl: Invalid bus_req\n"));
  201. break;
  202. }
  203. //
  204. // Mark request pending and queue it to the service queue
  205. //
  206. Status = STATUS_PENDING;
  207. Irp->IoStatus.Status = STATUS_PENDING;
  208. IoMarkIrpPending (Irp);
  209. SmbClassLockDevice (&Smb->Class);
  210. InsertTailList (&Smb->WorkQueue, &Irp->Tail.Overlay.ListEntry);
  211. //
  212. // Start IO if needed
  213. //
  214. SmbClassStartIo (Smb);
  215. SmbClassUnlockDevice (&Smb->Class);
  216. break;
  217. case SMB_REGISTER_ALARM_NOTIFY:
  218. //
  219. // Registry for alarm notifications
  220. //
  221. Irp->IoStatus.Information = 0;
  222. Status = SmbCRegisterAlarm (Smb, Irp);
  223. break;
  224. case SMB_DEREGISTER_ALARM_NOTIFY:
  225. //
  226. // Deregister for alarm notifications
  227. //
  228. Irp->IoStatus.Information = 0;
  229. Status = SmbCDeregisterAlarm (Smb, Irp);
  230. break;
  231. default:
  232. // Forard Irp or complete Irp without modifying it.
  233. return SmbCForwardRequest(DeviceObject, Irp);
  234. }
  235. if (Status != STATUS_PENDING) {
  236. Irp->IoStatus.Status = Status;
  237. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  238. }
  239. return Status;
  240. }
  241. NTSTATUS
  242. SmbCForwardRequest(
  243. IN PDEVICE_OBJECT DeviceObject,
  244. IN PIRP Irp
  245. )
  246. /*++
  247. Routine Description:
  248. This routine forwards the irp down the stack
  249. Arguments:
  250. DeviceObject - The target
  251. Irp - The request
  252. Return Value:
  253. NTSTATUS
  254. --*/
  255. {
  256. NTSTATUS Status;
  257. PSMBDATA Smb = (PSMBDATA) DeviceObject->DeviceExtension;
  258. if (Smb->Class.LowerDeviceObject != NULL) {
  259. IoSkipCurrentIrpStackLocation( Irp );
  260. Status = IoCallDriver( Smb->Class.LowerDeviceObject, Irp );
  261. } else {
  262. Status = Irp->IoStatus.Status;
  263. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  264. }
  265. return Status;
  266. }