xref: /reactos/drivers/storage/ide/pciidex/miniport.c (revision c0c57e23)
1 /*
2  * PROJECT:     PCI IDE bus driver extension
3  * LICENSE:     See COPYING in the top level directory
4  * PURPOSE:     Miniport functions
5  * COPYRIGHT:   Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
6  */
7 
8 #include "pciidex.h"
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 /** @brief Global debugging level. Valid values are between 0 (Error) and 3 (Trace). */
14 ULONG PciIdeDebug = 0;
15 
16 CODE_SEG("PAGE")
17 NTSTATUS
PciIdeXStartMiniport(_In_ PFDO_DEVICE_EXTENSION FdoExtension)18 PciIdeXStartMiniport(
19     _In_ PFDO_DEVICE_EXTENSION FdoExtension)
20 {
21     PPCIIDEX_DRIVER_EXTENSION DriverExtension;
22     NTSTATUS Status;
23 
24     PAGED_CODE();
25 
26     if (FdoExtension->MiniportStarted)
27         return STATUS_SUCCESS;
28 
29     DPRINT("Starting miniport\n");
30 
31     DriverExtension = IoGetDriverObjectExtension(FdoExtension->DriverObject,
32                                                  FdoExtension->DriverObject);
33     ASSERT(DriverExtension);
34 
35     FdoExtension->Properties.Size = sizeof(IDE_CONTROLLER_PROPERTIES);
36     FdoExtension->Properties.ExtensionSize = DriverExtension->MiniControllerExtensionSize;
37     Status = DriverExtension->HwGetControllerProperties(FdoExtension->MiniControllerExtension,
38                                                         &FdoExtension->Properties);
39     if (!NT_SUCCESS(Status))
40         return Status;
41 
42     FdoExtension->MiniportStarted = TRUE;
43     return STATUS_SUCCESS;
44 }
45 
46 CODE_SEG("PAGE")
47 IDE_CHANNEL_STATE
PciIdeXChannelState(_In_ PFDO_DEVICE_EXTENSION FdoExtension,_In_ ULONG Channel)48 PciIdeXChannelState(
49     _In_ PFDO_DEVICE_EXTENSION FdoExtension,
50     _In_ ULONG Channel)
51 {
52     PCIIDE_CHANNEL_ENABLED MiniportChannelEnabled;
53 
54     PAGED_CODE();
55 
56     MiniportChannelEnabled = FdoExtension->Properties.PciIdeChannelEnabled;
57     if (MiniportChannelEnabled)
58         return MiniportChannelEnabled(FdoExtension->MiniControllerExtension, Channel);
59 
60     return ChannelStateUnknown;
61 }
62 
63 /**
64  * @brief Prints the given string with printf-like formatting to the kernel debugger.
65  * @param[in] DebugPrintLevel Level of the debug message.
66  *                            Valid values are between 0 (Error) and 3 (Trace).
67  * @param[in] DebugMessage    Format of the string/arguments.
68  * @param[in] ...             Variable number of arguments matching the format
69  *                            specified in \a DebugMessage.
70  * @sa PciIdeDebug
71  */
72 VOID
PciIdeXDebugPrint(_In_ ULONG DebugPrintLevel,_In_z_ _Printf_format_string_ PCCHAR DebugMessage,...)73 PciIdeXDebugPrint(
74     _In_ ULONG DebugPrintLevel,
75     _In_z_ _Printf_format_string_ PCCHAR DebugMessage,
76     ...)
77 {
78     va_list ap;
79 
80     /* Check if we can print anything */
81     if (DebugPrintLevel <= PciIdeDebug)
82         DebugPrintLevel = 0;
83 
84     va_start(ap, DebugMessage);
85     vDbgPrintEx(DPFLTR_PCIIDE_ID, DebugPrintLevel, DebugMessage, ap);
86     va_end(ap);
87 }
88 
89 /* May be called at IRQL <= DISPATCH_LEVEL */
90 NTSTATUS
91 NTAPI
PciIdeXGetBusData(_In_ PVOID DeviceExtension,_Out_writes_bytes_all_ (BufferLength)PVOID Buffer,_In_ ULONG ConfigDataOffset,_In_ ULONG BufferLength)92 PciIdeXGetBusData(
93     _In_ PVOID DeviceExtension,
94     _Out_writes_bytes_all_(BufferLength) PVOID Buffer,
95     _In_ ULONG ConfigDataOffset,
96     _In_ ULONG BufferLength)
97 {
98     PFDO_DEVICE_EXTENSION FdoExtension;
99     ULONG BytesRead;
100 
101     DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
102            DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
103 
104     FdoExtension = CONTAINING_RECORD(DeviceExtension,
105                                      FDO_DEVICE_EXTENSION,
106                                      MiniControllerExtension);
107 
108     BytesRead = (*FdoExtension->BusInterface.GetBusData)(FdoExtension->BusInterface.Context,
109                                                          PCI_WHICHSPACE_CONFIG,
110                                                          Buffer,
111                                                          ConfigDataOffset,
112                                                          BufferLength);
113     if (BytesRead != BufferLength)
114         return STATUS_UNSUCCESSFUL;
115 
116     return STATUS_SUCCESS;
117 }
118 
119 /* May be called at IRQL <= DISPATCH_LEVEL */
120 NTSTATUS
121 NTAPI
PciIdeXSetBusData(_In_ PVOID DeviceExtension,_In_reads_bytes_ (BufferLength)PVOID Buffer,_In_reads_bytes_ (BufferLength)PVOID DataMask,_In_ ULONG ConfigDataOffset,_In_ ULONG BufferLength)122 PciIdeXSetBusData(
123     _In_ PVOID DeviceExtension,
124     _In_reads_bytes_(BufferLength) PVOID Buffer,
125     _In_reads_bytes_(BufferLength) PVOID DataMask,
126     _In_ ULONG ConfigDataOffset,
127     _In_ ULONG BufferLength)
128 {
129     PFDO_DEVICE_EXTENSION FdoExtension;
130     ULONG i, BytesWritten;
131     PUCHAR CurrentBuffer;
132     KIRQL OldIrql;
133     NTSTATUS Status;
134 
135     DPRINT("PciIdeXSetBusData(%p %p %p 0x%lx 0x%lx)\n",
136            DeviceExtension, Buffer, DataMask, ConfigDataOffset, BufferLength);
137 
138     CurrentBuffer = ExAllocatePoolWithTag(NonPagedPool, BufferLength, TAG_PCIIDEX);
139     if (!CurrentBuffer)
140         return STATUS_INSUFFICIENT_RESOURCES;
141 
142     FdoExtension = CONTAINING_RECORD(DeviceExtension,
143                                      FDO_DEVICE_EXTENSION,
144                                      MiniControllerExtension);
145 
146     KeAcquireSpinLock(&FdoExtension->BusDataLock, &OldIrql);
147 
148     Status = PciIdeXGetBusData(DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
149     if (!NT_SUCCESS(Status))
150         goto Cleanup;
151 
152     for (i = 0; i < BufferLength; i++)
153     {
154         CurrentBuffer[i] = (CurrentBuffer[i] & ~((PUCHAR)DataMask)[i]) |
155                            (((PUCHAR)DataMask)[i] & ((PUCHAR)Buffer)[i]);
156     }
157 
158     BytesWritten = (*FdoExtension->BusInterface.SetBusData)(FdoExtension->BusInterface.Context,
159                                                          PCI_WHICHSPACE_CONFIG,
160                                                          CurrentBuffer,
161                                                          ConfigDataOffset,
162                                                          BufferLength);
163     if (BytesWritten != BufferLength)
164         Status = STATUS_UNSUCCESSFUL;
165     else
166         Status = STATUS_SUCCESS;
167 
168 Cleanup:
169     KeReleaseSpinLock(&FdoExtension->BusDataLock, OldIrql);
170 
171     ExFreePoolWithTag(CurrentBuffer, TAG_PCIIDEX);
172     return Status;
173 }
174