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