/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel * FILE: drivers/bus/pcmcia/pcmcia.c * PURPOSE: PCMCIA Bus Driver * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) */ #include //#define NDEBUG #include BOOLEAN IoctlEnabled; DRIVER_DISPATCH PcmciaCreateClose; NTSTATUS NTAPI PcmciaCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) { UNREFERENCED_PARAMETER(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; DPRINT("PCMCIA: Create/Close\n"); IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } DRIVER_DISPATCH PcmciaDeviceControl; NTSTATUS NTAPI PcmciaDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); NTSTATUS Status; UNREFERENCED_PARAMETER(DeviceObject); DPRINT("PCMCIA: DeviceIoControl\n"); Irp->IoStatus.Information = 0; switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { default: DPRINT1("PCMCIA: Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); Status = STATUS_NOT_SUPPORTED; } Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } DRIVER_UNLOAD PcmciaUnload; VOID NTAPI PcmciaUnload(PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); DPRINT("PCMCIA: Unload\n"); } DRIVER_DISPATCH PcmciaPlugPlay; NTSTATUS NTAPI PcmciaPlugPlay(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension; DPRINT("PCMCIA: PnP\n"); if (Common->IsFDO) { return PcmciaFdoPlugPlay((PPCMCIA_FDO_EXTENSION)Common, Irp); } else { return PcmciaPdoPlugPlay((PPCMCIA_PDO_EXTENSION)Common, Irp); } } DRIVER_DISPATCH PcmciaPower; NTSTATUS NTAPI PcmciaPower(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); NTSTATUS Status; switch (IrpSp->MinorFunction) { case IRP_MN_QUERY_POWER: /* I don't see any reason that we should care */ DPRINT("PCMCIA: IRP_MN_QUERY_POWER\n"); Status = STATUS_SUCCESS; break; case IRP_MN_POWER_SEQUENCE: DPRINT("PCMCIA: IRP_MN_POWER_SEQUENCE\n"); RtlCopyMemory(IrpSp->Parameters.PowerSequence.PowerSequence, &Common->PowerSequence, sizeof(POWER_SEQUENCE)); Status = STATUS_SUCCESS; break; case IRP_MN_WAIT_WAKE: /* Not really sure about this */ DPRINT("PCMCIA: IRP_MN_WAIT_WAKE\n"); Status = STATUS_NOT_SUPPORTED; break; case IRP_MN_SET_POWER: DPRINT("PCMCIA: IRP_MN_SET_POWER\n"); if (IrpSp->Parameters.Power.Type == SystemPowerState) { Common->SystemPowerState = IrpSp->Parameters.Power.State.SystemState; Status = STATUS_SUCCESS; } else { Common->DevicePowerState = IrpSp->Parameters.Power.State.DeviceState; /* Update the POWER_SEQUENCE struct */ if (Common->DevicePowerState <= PowerDeviceD1) Common->PowerSequence.SequenceD1++; if (Common->DevicePowerState <= PowerDeviceD2) Common->PowerSequence.SequenceD2++; if (Common->DevicePowerState <= PowerDeviceD3) Common->PowerSequence.SequenceD3++; /* Start the underlying device if we are handling this for a PDO */ if (!Common->IsFDO) Status = PcmciaPdoSetPowerState((PPCMCIA_PDO_EXTENSION)Common); else Status = STATUS_SUCCESS; } /* Report that we changed state to the Power Manager */ PoSetPowerState(DeviceObject, IrpSp->Parameters.Power.Type, IrpSp->Parameters.Power.State); break; default: DPRINT1("PCMCIA: Invalid MN code in MJ_POWER handler %x\n", IrpSp->MinorFunction); ASSERT(FALSE); Status = STATUS_INVALID_DEVICE_REQUEST; break; } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } DRIVER_ADD_DEVICE PcmciaAddDevice; NTSTATUS NTAPI PcmciaAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject) { PPCMCIA_FDO_EXTENSION FdoExt; PDEVICE_OBJECT Fdo; NTSTATUS Status; DPRINT("PCMCIA: AddDevice\n"); Status = IoCreateDevice(DriverObject, sizeof(*FdoExt), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, FALSE, &Fdo); if (!NT_SUCCESS(Status)) return Status; FdoExt = Fdo->DeviceExtension; RtlZeroMemory(FdoExt, sizeof(*FdoExt)); InitializeListHead(&FdoExt->ChildDeviceList); KeInitializeSpinLock(&FdoExt->Lock); FdoExt->Common.Self = Fdo; FdoExt->Common.IsFDO = TRUE; FdoExt->Common.State = dsStopped; FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject); Fdo->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { RTL_QUERY_REGISTRY_TABLE QueryTable[2]; NTSTATUS Status; UNREFERENCED_PARAMETER(RegistryPath); DPRINT1("PCMCIA: DriverEntry\n"); DriverObject->MajorFunction[IRP_MJ_CREATE] = PcmciaCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = PcmciaCreateClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PcmciaDeviceControl; DriverObject->MajorFunction[IRP_MJ_PNP] = PcmciaPlugPlay; DriverObject->MajorFunction[IRP_MJ_POWER] = PcmciaPower; DriverObject->DriverExtension->AddDevice = PcmciaAddDevice; DriverObject->DriverUnload = PcmciaUnload; RtlZeroMemory(QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; QueryTable[0].Name = L"IoctlInterface"; QueryTable[0].EntryContext = &IoctlEnabled; Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, L"Pcmcia\\Parameters", QueryTable, NULL, NULL); if (!NT_SUCCESS(Status)) { /* Key not present so assume disabled */ IoctlEnabled = FALSE; } DPRINT("PCMCIA: Ioctl interface %s\n", (IoctlEnabled ? "enabled" : "disabled")); return STATUS_SUCCESS; }