bf6f2e9a209d5800935b8c56454248acabaf07dd
[reactos.git] / reactos / drivers / storage / pciidex / miniport.c
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 #define NDEBUG
10 #include <debug.h>
11
12 #define INITGUID
13 #include "pciidex.h"
14
15 static NTSTATUS NTAPI
16 PciIdeXPnpDispatch(
17 IN PDEVICE_OBJECT DeviceObject,
18 IN PIRP Irp)
19 {
20 if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
21 return PciIdeXFdoPnpDispatch(DeviceObject, Irp);
22 else
23 return PciIdeXPdoPnpDispatch(DeviceObject, Irp);
24 }
25
26 NTSTATUS NTAPI
27 PciIdeXInitialize(
28 IN PDRIVER_OBJECT DriverObject,
29 IN PUNICODE_STRING RegistryPath,
30 IN PCONTROLLER_PROPERTIES HwGetControllerProperties,
31 IN ULONG ExtensionSize)
32 {
33 ULONG i;
34 PPCIIDEX_DRIVER_EXTENSION DriverExtension;
35 NTSTATUS Status;
36
37 DPRINT("PciIdeXInitialize(%p '%wZ' %p 0x%lx)\n",
38 DriverObject, RegistryPath, HwGetControllerProperties, ExtensionSize);
39
40 Status = IoAllocateDriverObjectExtension(
41 DriverObject,
42 DriverObject,
43 sizeof(PCIIDEX_DRIVER_EXTENSION),
44 (PVOID*)&DriverExtension);
45 if (!NT_SUCCESS(Status))
46 return Status;
47 RtlZeroMemory(DriverExtension, sizeof(PCIIDEX_DRIVER_EXTENSION));
48 DriverExtension->MiniControllerExtensionSize = ExtensionSize;
49 DriverExtension->HwGetControllerProperties = HwGetControllerProperties;
50
51 DriverObject->DriverExtension->AddDevice = PciIdeXAddDevice;
52
53 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
54 DriverObject->MajorFunction[i] = ForwardIrpAndForget;
55 DriverObject->MajorFunction[IRP_MJ_PNP] = PciIdeXPnpDispatch;
56
57 return STATUS_SUCCESS;
58 }
59
60 /* May be called at IRQL <= DISPATCH_LEVEL */
61 NTSTATUS NTAPI
62 PciIdeXGetBusData(
63 IN PVOID DeviceExtension,
64 IN PVOID Buffer,
65 IN ULONG ConfigDataOffset,
66 IN ULONG BufferLength)
67 {
68 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
69 ULONG BytesRead;
70 NTSTATUS Status = STATUS_UNSUCCESSFUL;
71
72 DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
73 DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
74
75 FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension);
76 if (FdoDeviceExtension->BusInterface)
77 {
78 BytesRead = (*FdoDeviceExtension->BusInterface->GetBusData)(
79 FdoDeviceExtension->BusInterface->Context,
80 PCI_WHICHSPACE_CONFIG,
81 Buffer,
82 ConfigDataOffset,
83 BufferLength);
84 if (BytesRead == BufferLength)
85 Status = STATUS_SUCCESS;
86 }
87
88 return Status;
89 }
90
91 /* May be called at IRQL <= DISPATCH_LEVEL */
92 NTSTATUS NTAPI
93 PciIdeXSetBusData(
94 IN PVOID DeviceExtension,
95 IN PVOID Buffer,
96 IN PVOID DataMask,
97 IN ULONG ConfigDataOffset,
98 IN ULONG BufferLength)
99 {
100 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
101 PBYTE CurrentBuffer = NULL;
102 ULONG i, BytesWritten;
103 NTSTATUS Status;
104
105 DPRINT("PciIdeXSetBusData(%p %p %p 0x%lx 0x%lx)\n",
106 DeviceExtension, Buffer, DataMask, ConfigDataOffset, BufferLength);
107
108 CurrentBuffer = ExAllocatePool(NonPagedPool, BufferLength);
109 if (!CurrentBuffer)
110 {
111 Status = STATUS_INSUFFICIENT_RESOURCES;
112 goto cleanup;
113 }
114
115 Status = PciIdeXGetBusData(DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
116 if (!NT_SUCCESS(Status))
117 goto cleanup;
118
119 for (i = 0; i < BufferLength; i++)
120 CurrentBuffer[i] = (CurrentBuffer[i] & ~((PBYTE)DataMask)[i]) | (((PBYTE)DataMask)[i] & ((PBYTE)Buffer)[i]);
121
122 FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension);
123 if (!FdoDeviceExtension->BusInterface)
124 {
125 Status = STATUS_UNSUCCESSFUL;
126 goto cleanup;
127 }
128
129 BytesWritten = (*FdoDeviceExtension->BusInterface->SetBusData)(
130 FdoDeviceExtension->BusInterface->Context,
131 PCI_WHICHSPACE_CONFIG,
132 CurrentBuffer,
133 ConfigDataOffset,
134 BufferLength);
135 if (BytesWritten == BufferLength)
136 Status = STATUS_SUCCESS;
137 else
138 Status = STATUS_UNSUCCESSFUL;
139
140 cleanup:
141 ExFreePool(CurrentBuffer);
142 return Status;
143 }