1 /* 2 * PROJECT: ReactOS ISA PnP Bus driver 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Common header file 5 * COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman@reactos.org> 6 * Copyright 2020 Hervé Poussineau <hpoussin@reactos.org> 7 */ 8 9 #ifndef _ISAPNP_PCH_ 10 #define _ISAPNP_PCH_ 11 12 #include <ntddk.h> 13 #include <ntstrsafe.h> 14 #include <section_attribs.h> 15 #include "isapnphw.h" 16 17 #include <initguid.h> 18 #include <wdmguid.h> 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #define TAG_ISAPNP 'pasI' 25 26 /** @brief Maximum size of resource data structure supported by the driver. */ 27 #define ISAPNP_MAX_RESOURCEDATA 0x1000 28 29 /** @brief Maximum number of Start DF tags supported by the driver. */ 30 #define ISAPNP_MAX_ALTERNATIVES 8 31 32 typedef enum 33 { 34 dsStopped, 35 dsStarted 36 } ISAPNP_DEVICE_STATE; 37 38 typedef struct _ISAPNP_IO 39 { 40 USHORT CurrentBase; 41 ISAPNP_IO_DESCRIPTION Description; 42 UCHAR Index; 43 } ISAPNP_IO, *PISAPNP_IO; 44 45 typedef struct _ISAPNP_IRQ 46 { 47 UCHAR CurrentNo; 48 UCHAR CurrentType; 49 ISAPNP_IRQ_DESCRIPTION Description; 50 UCHAR Index; 51 } ISAPNP_IRQ, *PISAPNP_IRQ; 52 53 typedef struct _ISAPNP_DMA 54 { 55 UCHAR CurrentChannel; 56 ISAPNP_DMA_DESCRIPTION Description; 57 UCHAR Index; 58 } ISAPNP_DMA, *PISAPNP_DMA; 59 60 typedef struct _ISAPNP_MEMRANGE 61 { 62 ULONG CurrentBase; 63 ULONG CurrentLength; 64 ISAPNP_MEMRANGE_DESCRIPTION Description; 65 UCHAR Index; 66 } ISAPNP_MEMRANGE, *PISAPNP_MEMRANGE; 67 68 typedef struct _ISAPNP_MEMRANGE32 69 { 70 ULONG CurrentBase; 71 ULONG CurrentLength; 72 ISAPNP_MEMRANGE32_DESCRIPTION Description; 73 UCHAR Index; 74 } ISAPNP_MEMRANGE32, *PISAPNP_MEMRANGE32; 75 76 typedef struct _ISAPNP_COMPATIBLE_ID_ENTRY 77 { 78 UCHAR VendorId[3]; 79 USHORT ProdId; 80 LIST_ENTRY IdLink; 81 } ISAPNP_COMPATIBLE_ID_ENTRY, *PISAPNP_COMPATIBLE_ID_ENTRY; 82 83 typedef struct _ISAPNP_ALTERNATIVES 84 { 85 ISAPNP_IO_DESCRIPTION Io[ISAPNP_MAX_ALTERNATIVES]; 86 ISAPNP_IRQ_DESCRIPTION Irq[ISAPNP_MAX_ALTERNATIVES]; 87 ISAPNP_DMA_DESCRIPTION Dma[ISAPNP_MAX_ALTERNATIVES]; 88 ISAPNP_MEMRANGE_DESCRIPTION MemRange[ISAPNP_MAX_ALTERNATIVES]; 89 ISAPNP_MEMRANGE32_DESCRIPTION MemRange32[ISAPNP_MAX_ALTERNATIVES]; 90 UCHAR Priority[ISAPNP_MAX_ALTERNATIVES]; 91 UCHAR IoIndex; 92 UCHAR IrqIndex; 93 UCHAR DmaIndex; 94 UCHAR MemRangeIndex; 95 UCHAR MemRange32Index; 96 97 _Field_range_(0, ISAPNP_MAX_ALTERNATIVES) 98 UCHAR Count; 99 } ISAPNP_ALTERNATIVES, *PISAPNP_ALTERNATIVES; 100 101 typedef struct _ISAPNP_LOGICAL_DEVICE 102 { 103 PDEVICE_OBJECT Pdo; 104 105 /** 106 * @name The card data. 107 * @{ 108 */ 109 UCHAR CSN; 110 UCHAR VendorId[3]; 111 USHORT ProdId; 112 ULONG SerialNumber; 113 /**@}*/ 114 115 /** 116 * @name The logical device data. 117 * @{ 118 */ 119 UCHAR LDN; 120 UCHAR LogVendorId[3]; 121 USHORT LogProdId; 122 LIST_ENTRY CompatibleIdList; 123 PSTR FriendlyName; 124 PISAPNP_ALTERNATIVES Alternatives; 125 126 ISAPNP_IO Io[8]; 127 ISAPNP_IRQ Irq[2]; 128 ISAPNP_DMA Dma[2]; 129 ISAPNP_MEMRANGE MemRange[4]; 130 ISAPNP_MEMRANGE32 MemRange32[4]; 131 /**@}*/ 132 133 ULONG Flags; 134 #define ISAPNP_PRESENT 0x00000001 /**< @brief Cleared when the device is physically removed. */ 135 #define ISAPNP_HAS_MULTIPLE_LOGDEVS 0x00000002 /**< @brief Indicates if the parent card has multiple logical devices. */ 136 #define ISAPNP_HAS_RESOURCES 0x00000004 /**< @brief Cleared when the device has no boot resources. */ 137 138 LIST_ENTRY DeviceLink; 139 } ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE; 140 141 typedef enum _ISAPNP_SIGNATURE 142 { 143 IsaPnpBus = 'odFI', 144 IsaPnpLogicalDevice = 'veDI', 145 IsaPnpReadDataPort = 'pdRI' 146 } ISAPNP_SIGNATURE; 147 148 typedef struct _ISAPNP_COMMON_EXTENSION 149 { 150 ISAPNP_SIGNATURE Signature; 151 PDEVICE_OBJECT Self; 152 ISAPNP_DEVICE_STATE State; 153 } ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION; 154 155 typedef struct _ISAPNP_FDO_EXTENSION 156 { 157 ISAPNP_COMMON_EXTENSION Common; 158 PDEVICE_OBJECT Ldo; 159 PDEVICE_OBJECT Pdo; 160 PDEVICE_OBJECT ReadPortPdo; /**< @remarks The pointer is NULL for all inactive FDOs. */ 161 ULONG BusNumber; 162 KEVENT DeviceSyncEvent; 163 164 _Guarded_by_(DeviceSyncEvent) 165 LIST_ENTRY DeviceListHead; 166 167 _Guarded_by_(DeviceSyncEvent) 168 ULONG DeviceCount; 169 170 PDRIVER_OBJECT DriverObject; 171 PUCHAR ReadDataPort; 172 ULONG Cards; 173 LIST_ENTRY BusLink; 174 } ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION; 175 176 typedef struct _ISAPNP_PDO_EXTENSION 177 { 178 ISAPNP_COMMON_EXTENSION Common; 179 PISAPNP_LOGICAL_DEVICE IsaPnpDevice; 180 PISAPNP_FDO_EXTENSION FdoExt; 181 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; 182 183 PCM_RESOURCE_LIST ResourceList; 184 ULONG ResourceListSize; 185 186 ULONG Flags; 187 #define ISAPNP_ENUMERATED 0x00000001 /**< @brief Whether the device has been reported to the PnP manager. */ 188 #define ISAPNP_SCANNED_BY_READ_PORT 0x00000002 /**< @brief The bus has been scanned by Read Port PDO. */ 189 #define ISAPNP_READ_PORT_ALLOW_FDO_SCAN 0x00000004 /**< @brief Allows the active FDO to scan the bus. */ 190 #define ISAPNP_READ_PORT_NEED_REBALANCE 0x00000008 /**< @brief The I/O resource requirements have changed. */ 191 192 _Write_guarded_by_(_Global_interlock_) 193 volatile LONG SpecialFiles; 194 } ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION; 195 196 extern KEVENT BusSyncEvent; 197 198 _Guarded_by_(BusSyncEvent) 199 extern BOOLEAN ReadPortCreated; 200 201 _Guarded_by_(BusSyncEvent) 202 extern LIST_ENTRY BusListHead; 203 204 _Requires_lock_not_held_(BusSyncEvent) 205 _Acquires_lock_(BusSyncEvent) 206 FORCEINLINE 207 VOID 208 IsaPnpAcquireBusDataLock(VOID) 209 { 210 KeWaitForSingleObject(&BusSyncEvent, Executive, KernelMode, FALSE, NULL); 211 } 212 213 _Releases_lock_(BusSyncEvent) 214 FORCEINLINE 215 VOID 216 IsaPnpReleaseBusDataLock(VOID) 217 { 218 KeSetEvent(&BusSyncEvent, IO_NO_INCREMENT, FALSE); 219 } 220 221 _Requires_lock_not_held_(FdoExt->DeviceSyncEvent) 222 _Acquires_lock_(FdoExt->DeviceSyncEvent) 223 FORCEINLINE 224 VOID 225 IsaPnpAcquireDeviceDataLock( 226 _In_ PISAPNP_FDO_EXTENSION FdoExt) 227 { 228 KeWaitForSingleObject(&FdoExt->DeviceSyncEvent, Executive, KernelMode, FALSE, NULL); 229 } 230 231 _Releases_lock_(FdoExt->DeviceSyncEvent) 232 FORCEINLINE 233 VOID 234 IsaPnpReleaseDeviceDataLock( 235 _In_ PISAPNP_FDO_EXTENSION FdoExt) 236 { 237 KeSetEvent(&FdoExt->DeviceSyncEvent, IO_NO_INCREMENT, FALSE); 238 } 239 240 FORCEINLINE 241 BOOLEAN 242 HasIoAlternatives( 243 _In_ PISAPNP_ALTERNATIVES Alternatives) 244 { 245 return (Alternatives->Io[0].Length != 0); 246 } 247 248 FORCEINLINE 249 BOOLEAN 250 HasIrqAlternatives( 251 _In_ PISAPNP_ALTERNATIVES Alternatives) 252 { 253 return (Alternatives->Irq[0].Mask != 0); 254 } 255 256 FORCEINLINE 257 BOOLEAN 258 HasDmaAlternatives( 259 _In_ PISAPNP_ALTERNATIVES Alternatives) 260 { 261 return (Alternatives->Dma[0].Mask != 0); 262 } 263 264 FORCEINLINE 265 BOOLEAN 266 HasMemoryAlternatives( 267 _In_ PISAPNP_ALTERNATIVES Alternatives) 268 { 269 return (Alternatives->MemRange[0].Length != 0); 270 } 271 272 FORCEINLINE 273 BOOLEAN 274 HasMemory32Alternatives( 275 _In_ PISAPNP_ALTERNATIVES Alternatives) 276 { 277 return (Alternatives->MemRange32[0].Length != 0); 278 } 279 280 /* isapnp.c */ 281 282 CODE_SEG("PAGE") 283 BOOLEAN 284 FindIoDescriptor( 285 _In_ PISAPNP_LOGICAL_DEVICE LogDevice, 286 _In_opt_ ULONG Base, 287 _In_ ULONG RangeStart, 288 _In_ ULONG RangeEnd, 289 _Out_opt_ PUCHAR Information, 290 _Out_opt_ PULONG Length, 291 _Out_opt_ PUCHAR WriteOrder); 292 293 CODE_SEG("PAGE") 294 BOOLEAN 295 FindIrqDescriptor( 296 _In_ PISAPNP_LOGICAL_DEVICE LogDevice, 297 _In_ ULONG Vector, 298 _Out_opt_ PUCHAR WriteOrder); 299 300 CODE_SEG("PAGE") 301 BOOLEAN 302 FindDmaDescriptor( 303 _In_ PISAPNP_LOGICAL_DEVICE LogDevice, 304 _In_ ULONG Channel, 305 _Out_opt_ PUCHAR WriteOrder); 306 307 CODE_SEG("PAGE") 308 BOOLEAN 309 FindMemoryDescriptor( 310 _In_ PISAPNP_LOGICAL_DEVICE LogDevice, 311 _In_ ULONG RangeStart, 312 _In_ ULONG RangeEnd, 313 _Out_opt_ PBOOLEAN Memory32, 314 _Out_opt_ PUCHAR Information, 315 _Out_opt_ PUCHAR WriteOrder); 316 317 CODE_SEG("PAGE") 318 NTSTATUS 319 IsaPnpCreateReadPortDORequirements( 320 _In_ PISAPNP_PDO_EXTENSION PdoExt, 321 _In_opt_ ULONG SelectedReadPort); 322 323 CODE_SEG("PAGE") 324 VOID 325 IsaPnpRemoveReadPortDO( 326 _In_ PDEVICE_OBJECT Pdo); 327 328 CODE_SEG("PAGE") 329 NTSTATUS 330 IsaPnpFillDeviceRelations( 331 _In_ PISAPNP_FDO_EXTENSION FdoExt, 332 _Inout_ PIRP Irp, 333 _In_ BOOLEAN IncludeDataPort); 334 335 CODE_SEG("INIT") 336 DRIVER_INITIALIZE DriverEntry; 337 338 /* fdo.c */ 339 CODE_SEG("PAGE") 340 NTSTATUS 341 IsaFdoPnp( 342 _In_ PISAPNP_FDO_EXTENSION FdoExt, 343 _Inout_ PIRP Irp, 344 _In_ PIO_STACK_LOCATION IrpSp); 345 346 /* interface.c */ 347 CODE_SEG("PAGE") 348 NTSTATUS 349 IsaFdoQueryInterface( 350 _In_ PISAPNP_FDO_EXTENSION FdoExt, 351 _In_ PIO_STACK_LOCATION IrpSp); 352 353 /* pdo.c */ 354 CODE_SEG("PAGE") 355 NTSTATUS 356 IsaPdoPnp( 357 _In_ PISAPNP_PDO_EXTENSION PdoDeviceExtension, 358 _Inout_ PIRP Irp, 359 _In_ PIO_STACK_LOCATION IrpSp); 360 361 CODE_SEG("PAGE") 362 VOID 363 IsaPnpRemoveLogicalDeviceDO( 364 _In_ PDEVICE_OBJECT Pdo); 365 366 /* hardware.c */ 367 CODE_SEG("PAGE") 368 UCHAR 369 IsaHwTryReadDataPort( 370 _In_ PUCHAR ReadDataPort); 371 372 _Requires_lock_held_(FdoExt->DeviceSyncEvent) 373 CODE_SEG("PAGE") 374 NTSTATUS 375 IsaHwFillDeviceList( 376 _In_ PISAPNP_FDO_EXTENSION FdoExt); 377 378 CODE_SEG("PAGE") 379 NTSTATUS 380 IsaHwConfigureDevice( 381 _In_ PISAPNP_FDO_EXTENSION FdoExt, 382 _In_ PISAPNP_LOGICAL_DEVICE LogicalDevice, 383 _In_ PCM_RESOURCE_LIST Resources); 384 385 _IRQL_requires_max_(DISPATCH_LEVEL) 386 VOID 387 IsaHwWakeDevice( 388 _In_ PISAPNP_LOGICAL_DEVICE LogicalDevice); 389 390 _IRQL_requires_max_(DISPATCH_LEVEL) 391 VOID 392 IsaHwDeactivateDevice( 393 _In_ PISAPNP_LOGICAL_DEVICE LogicalDevice); 394 395 _IRQL_requires_max_(DISPATCH_LEVEL) 396 VOID 397 IsaHwActivateDevice( 398 _In_ PISAPNP_FDO_EXTENSION FdoExt, 399 _In_ PISAPNP_LOGICAL_DEVICE LogicalDevice); 400 401 _IRQL_requires_max_(DISPATCH_LEVEL) 402 VOID 403 IsaHwWaitForKey(VOID); 404 405 #ifdef __cplusplus 406 } 407 #endif 408 409 #endif /* _ISAPNP_PCH_ */ 410