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 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 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 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 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 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