xref: /reactos/drivers/bus/isapnp/isapnp.h (revision 7353af1e)
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