reactos/drivers/storage/ide/pciidex/miniport.c

212 lines
5.5 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: PCI IDE bus driver extension
* FILE: drivers/storage/pciidex/miniport.c
* PURPOSE: Miniport functions
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/
#include "pciidex.h"
#define NDEBUG
#include <debug.h>
static DRIVER_DISPATCH PciIdeXForwardOrIgnore;
static NTSTATUS NTAPI
PciIdeXForwardOrIgnore(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
return ForwardIrpAndForget(DeviceObject, Irp);
else
{
ULONG MajorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction;
NTSTATUS Status;
if (MajorFunction == IRP_MJ_CREATE ||
MajorFunction == IRP_MJ_CLEANUP ||
MajorFunction == IRP_MJ_CLOSE)
{
Status = STATUS_SUCCESS;
}
else
{
DPRINT1("PDO stub for major function 0x%lx\n", MajorFunction);
Status = STATUS_NOT_SUPPORTED;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
}
_Dispatch_type_(IRP_MJ_POWER)
static DRIVER_DISPATCH PciIdeXPowerDispatch;
static NTSTATUS NTAPI
PciIdeXPowerDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PDEVICE_OBJECT LowerDevice;
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
{
LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(LowerDevice, Irp);
}
else
{
switch (IoStack->MinorFunction)
{
case IRP_MN_SET_POWER:
case IRP_MN_QUERY_POWER:
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
Status = Irp->IoStatus.Status;
PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
}
_Dispatch_type_(IRP_MJ_PNP)
static DRIVER_DISPATCH PciIdeXPnpDispatch;
static NTSTATUS NTAPI
PciIdeXPnpDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
return PciIdeXFdoPnpDispatch(DeviceObject, Irp);
else
return PciIdeXPdoPnpDispatch(DeviceObject, Irp);
}
NTSTATUS NTAPI
PciIdeXInitialize(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath,
IN PCONTROLLER_PROPERTIES HwGetControllerProperties,
IN ULONG ExtensionSize)
{
ULONG i;
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
NTSTATUS Status;
DPRINT("PciIdeXInitialize(%p '%wZ' %p 0x%lx)\n",
DriverObject, RegistryPath, HwGetControllerProperties, ExtensionSize);
Status = IoAllocateDriverObjectExtension(
DriverObject,
DriverObject,
sizeof(PCIIDEX_DRIVER_EXTENSION),
(PVOID*)&DriverExtension);
if (!NT_SUCCESS(Status))
return Status;
RtlZeroMemory(DriverExtension, sizeof(PCIIDEX_DRIVER_EXTENSION));
DriverExtension->MiniControllerExtensionSize = ExtensionSize;
DriverExtension->HwGetControllerProperties = HwGetControllerProperties;
DriverObject->DriverExtension->AddDevice = PciIdeXAddDevice;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = PciIdeXForwardOrIgnore;
DriverObject->MajorFunction[IRP_MJ_POWER] = PciIdeXPowerDispatch;
DriverObject->MajorFunction[IRP_MJ_PNP] = PciIdeXPnpDispatch;
return STATUS_SUCCESS;
}
/* May be called at IRQL <= DISPATCH_LEVEL */
NTSTATUS NTAPI
PciIdeXGetBusData(
IN PVOID DeviceExtension,
IN PVOID Buffer,
IN ULONG ConfigDataOffset,
IN ULONG BufferLength)
{
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
ULONG BytesRead;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension);
if (FdoDeviceExtension->BusInterface)
{
BytesRead = (*FdoDeviceExtension->BusInterface->GetBusData)(
FdoDeviceExtension->BusInterface->Context,
PCI_WHICHSPACE_CONFIG,
Buffer,
ConfigDataOffset,
BufferLength);
if (BytesRead == BufferLength)
Status = STATUS_SUCCESS;
}
return Status;
}
/* May be called at IRQL <= DISPATCH_LEVEL */
NTSTATUS NTAPI
PciIdeXSetBusData(
IN PVOID DeviceExtension,
IN PVOID Buffer,
IN PVOID DataMask,
IN ULONG ConfigDataOffset,
IN ULONG BufferLength)
{
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PUCHAR CurrentBuffer = NULL;
ULONG i, BytesWritten;
NTSTATUS Status;
DPRINT("PciIdeXSetBusData(%p %p %p 0x%lx 0x%lx)\n",
DeviceExtension, Buffer, DataMask, ConfigDataOffset, BufferLength);
CurrentBuffer = ExAllocatePool(NonPagedPool, BufferLength);
if (!CurrentBuffer)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
return Status;
}
Status = PciIdeXGetBusData(DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
if (!NT_SUCCESS(Status))
goto cleanup;
for (i = 0; i < BufferLength; i++)
CurrentBuffer[i] = (CurrentBuffer[i] & ~((PUCHAR)DataMask)[i]) | (((PUCHAR)DataMask)[i] & ((PUCHAR)Buffer)[i]);
FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension);
if (!FdoDeviceExtension->BusInterface)
{
Status = STATUS_UNSUCCESSFUL;
goto cleanup;
}
BytesWritten = (*FdoDeviceExtension->BusInterface->SetBusData)(
FdoDeviceExtension->BusInterface->Context,
PCI_WHICHSPACE_CONFIG,
CurrentBuffer,
ConfigDataOffset,
BufferLength);
if (BytesWritten == BufferLength)
Status = STATUS_SUCCESS;
else
Status = STATUS_UNSUCCESSFUL;
cleanup:
ExFreePool(CurrentBuffer);
return Status;
}