1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: PCI IDE bus driver extension 4 * FILE: drivers/storage/pciidex/miniport.c 5 * PURPOSE: Miniport functions 6 * PROGRAMMERS: Herv� Poussineau (hpoussin@reactos.org) 7 */ 8 9 #include "pciidex.h" 10 11 #define NDEBUG 12 #include <debug.h> 13 14 /** @brief Global debugging level. Valid values are between 0 (Error) and 3 (Trace). */ 15 ULONG PciIdeDebug = 0; 16 17 static DRIVER_DISPATCH PciIdeXForwardOrIgnore; 18 static NTSTATUS NTAPI 19 PciIdeXForwardOrIgnore( 20 IN PDEVICE_OBJECT DeviceObject, 21 IN PIRP Irp) 22 { 23 if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) 24 return ForwardIrpAndForget(DeviceObject, Irp); 25 else 26 { 27 ULONG MajorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction; 28 NTSTATUS Status; 29 30 if (MajorFunction == IRP_MJ_CREATE || 31 MajorFunction == IRP_MJ_CLEANUP || 32 MajorFunction == IRP_MJ_CLOSE) 33 { 34 Status = STATUS_SUCCESS; 35 } 36 else 37 { 38 DPRINT1("PDO stub for major function 0x%lx\n", MajorFunction); 39 Status = STATUS_NOT_SUPPORTED; 40 } 41 Irp->IoStatus.Information = 0; 42 Irp->IoStatus.Status = Status; 43 IoCompleteRequest(Irp, IO_NO_INCREMENT); 44 return Status; 45 } 46 } 47 48 _Dispatch_type_(IRP_MJ_POWER) 49 static DRIVER_DISPATCH PciIdeXPowerDispatch; 50 static NTSTATUS NTAPI 51 PciIdeXPowerDispatch( 52 IN PDEVICE_OBJECT DeviceObject, 53 IN PIRP Irp) 54 { 55 NTSTATUS Status; 56 PIO_STACK_LOCATION IoStack; 57 PDEVICE_OBJECT LowerDevice; 58 59 IoStack = IoGetCurrentIrpStackLocation(Irp); 60 if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) 61 { 62 LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; 63 PoStartNextPowerIrp(Irp); 64 IoSkipCurrentIrpStackLocation(Irp); 65 return PoCallDriver(LowerDevice, Irp); 66 } 67 else 68 { 69 switch (IoStack->MinorFunction) 70 { 71 case IRP_MN_SET_POWER: 72 case IRP_MN_QUERY_POWER: 73 Irp->IoStatus.Status = STATUS_SUCCESS; 74 break; 75 } 76 Status = Irp->IoStatus.Status; 77 PoStartNextPowerIrp(Irp); 78 IoCompleteRequest(Irp, IO_NO_INCREMENT); 79 return Status; 80 } 81 } 82 83 _Dispatch_type_(IRP_MJ_PNP) 84 static DRIVER_DISPATCH PciIdeXPnpDispatch; 85 static NTSTATUS NTAPI 86 PciIdeXPnpDispatch( 87 IN PDEVICE_OBJECT DeviceObject, 88 IN PIRP Irp) 89 { 90 if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO) 91 return PciIdeXFdoPnpDispatch(DeviceObject, Irp); 92 else 93 return PciIdeXPdoPnpDispatch(DeviceObject, Irp); 94 } 95 96 /** 97 * @brief Prints the given string with printf-like formatting to the kernel debugger. 98 * @param[in] DebugPrintLevel Level of the debug message. 99 * Valid values are between 0 (Error) and 3 (Trace). 100 * @param[in] DebugMessage Format of the string/arguments. 101 * @param[in] ... Variable number of arguments matching the format 102 * specified in \a DebugMessage. 103 * @sa PciIdeDebug 104 */ 105 VOID 106 PciIdeXDebugPrint( 107 _In_ ULONG DebugPrintLevel, 108 _In_z_ _Printf_format_string_ PCCHAR DebugMessage, 109 ...) 110 { 111 va_list ap; 112 113 /* Check if we can print anything */ 114 if (DebugPrintLevel <= PciIdeDebug) 115 DebugPrintLevel = 0; 116 117 va_start(ap, DebugMessage); 118 vDbgPrintEx(DPFLTR_PCIIDE_ID, DebugPrintLevel, DebugMessage, ap); 119 va_end(ap); 120 } 121 122 NTSTATUS NTAPI 123 PciIdeXInitialize( 124 IN PDRIVER_OBJECT DriverObject, 125 IN PUNICODE_STRING RegistryPath, 126 IN PCONTROLLER_PROPERTIES HwGetControllerProperties, 127 IN ULONG ExtensionSize) 128 { 129 ULONG i; 130 PPCIIDEX_DRIVER_EXTENSION DriverExtension; 131 NTSTATUS Status; 132 133 DPRINT("PciIdeXInitialize(%p '%wZ' %p 0x%lx)\n", 134 DriverObject, RegistryPath, HwGetControllerProperties, ExtensionSize); 135 136 Status = IoAllocateDriverObjectExtension( 137 DriverObject, 138 DriverObject, 139 sizeof(PCIIDEX_DRIVER_EXTENSION), 140 (PVOID*)&DriverExtension); 141 if (!NT_SUCCESS(Status)) 142 return Status; 143 RtlZeroMemory(DriverExtension, sizeof(PCIIDEX_DRIVER_EXTENSION)); 144 DriverExtension->MiniControllerExtensionSize = ExtensionSize; 145 DriverExtension->HwGetControllerProperties = HwGetControllerProperties; 146 147 DriverObject->DriverExtension->AddDevice = PciIdeXAddDevice; 148 149 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) 150 DriverObject->MajorFunction[i] = PciIdeXForwardOrIgnore; 151 DriverObject->MajorFunction[IRP_MJ_POWER] = PciIdeXPowerDispatch; 152 DriverObject->MajorFunction[IRP_MJ_PNP] = PciIdeXPnpDispatch; 153 154 return STATUS_SUCCESS; 155 } 156 157 /* May be called at IRQL <= DISPATCH_LEVEL */ 158 NTSTATUS NTAPI 159 PciIdeXGetBusData( 160 IN PVOID DeviceExtension, 161 IN PVOID Buffer, 162 IN ULONG ConfigDataOffset, 163 IN ULONG BufferLength) 164 { 165 PFDO_DEVICE_EXTENSION FdoDeviceExtension; 166 ULONG BytesRead; 167 NTSTATUS Status = STATUS_UNSUCCESSFUL; 168 169 DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n", 170 DeviceExtension, Buffer, ConfigDataOffset, BufferLength); 171 172 FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension); 173 if (FdoDeviceExtension->BusInterface) 174 { 175 BytesRead = (*FdoDeviceExtension->BusInterface->GetBusData)( 176 FdoDeviceExtension->BusInterface->Context, 177 PCI_WHICHSPACE_CONFIG, 178 Buffer, 179 ConfigDataOffset, 180 BufferLength); 181 if (BytesRead == BufferLength) 182 Status = STATUS_SUCCESS; 183 } 184 185 return Status; 186 } 187 188 /* May be called at IRQL <= DISPATCH_LEVEL */ 189 NTSTATUS NTAPI 190 PciIdeXSetBusData( 191 IN PVOID DeviceExtension, 192 IN PVOID Buffer, 193 IN PVOID DataMask, 194 IN ULONG ConfigDataOffset, 195 IN ULONG BufferLength) 196 { 197 PFDO_DEVICE_EXTENSION FdoDeviceExtension; 198 PUCHAR CurrentBuffer = NULL; 199 ULONG i, BytesWritten; 200 NTSTATUS Status; 201 202 DPRINT("PciIdeXSetBusData(%p %p %p 0x%lx 0x%lx)\n", 203 DeviceExtension, Buffer, DataMask, ConfigDataOffset, BufferLength); 204 205 CurrentBuffer = ExAllocatePool(NonPagedPool, BufferLength); 206 if (!CurrentBuffer) 207 { 208 Status = STATUS_INSUFFICIENT_RESOURCES; 209 return Status; 210 } 211 212 Status = PciIdeXGetBusData(DeviceExtension, Buffer, ConfigDataOffset, BufferLength); 213 if (!NT_SUCCESS(Status)) 214 goto cleanup; 215 216 for (i = 0; i < BufferLength; i++) 217 CurrentBuffer[i] = (CurrentBuffer[i] & ~((PUCHAR)DataMask)[i]) | (((PUCHAR)DataMask)[i] & ((PUCHAR)Buffer)[i]); 218 219 FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension); 220 if (!FdoDeviceExtension->BusInterface) 221 { 222 Status = STATUS_UNSUCCESSFUL; 223 goto cleanup; 224 } 225 226 BytesWritten = (*FdoDeviceExtension->BusInterface->SetBusData)( 227 FdoDeviceExtension->BusInterface->Context, 228 PCI_WHICHSPACE_CONFIG, 229 CurrentBuffer, 230 ConfigDataOffset, 231 BufferLength); 232 if (BytesWritten == BufferLength) 233 Status = STATUS_SUCCESS; 234 else 235 Status = STATUS_UNSUCCESSFUL; 236 237 cleanup: 238 ExFreePool(CurrentBuffer); 239 return Status; 240 } 241