1 /* 2 * PROJECT: ReactOS ISA PnP Bus driver 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: FDO-specific code 5 * COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman@reactos.org> 6 * Copyright 2020 Hervé Poussineau <hpoussin@reactos.org> 7 * Copyright 2021 Dmitry Borisov <di.sean@protonmail.com> 8 */ 9 10 #include "isapnp.h" 11 12 #define NDEBUG 13 #include <debug.h> 14 15 static 16 CODE_SEG("PAGE") 17 NTSTATUS 18 IsaFdoStartDevice( 19 _In_ PISAPNP_FDO_EXTENSION FdoExt, 20 _Inout_ PIRP Irp) 21 { 22 NTSTATUS Status; 23 24 PAGED_CODE(); 25 26 if (!IoForwardIrpSynchronously(FdoExt->Ldo, Irp)) 27 { 28 return STATUS_UNSUCCESSFUL; 29 } 30 Status = Irp->IoStatus.Status; 31 if (!NT_SUCCESS(Status)) 32 { 33 return Status; 34 } 35 36 FdoExt->Common.State = dsStarted; 37 38 return STATUS_SUCCESS; 39 } 40 41 static 42 CODE_SEG("PAGE") 43 NTSTATUS 44 IsaFdoQueryBusRelations( 45 _In_ PISAPNP_FDO_EXTENSION FdoExt, 46 _Inout_ PIRP Irp) 47 { 48 PAGED_CODE(); 49 50 return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE); 51 } 52 53 static 54 CODE_SEG("PAGE") 55 NTSTATUS 56 IsaFdoRemoveDevice( 57 _In_ PISAPNP_FDO_EXTENSION FdoExt, 58 _Inout_ PIRP Irp) 59 { 60 NTSTATUS Status; 61 PLIST_ENTRY Entry; 62 63 PAGED_CODE(); 64 65 IsaPnpAcquireDeviceDataLock(FdoExt); 66 67 /* Remove our logical devices */ 68 while (!IsListEmpty(&FdoExt->DeviceListHead)) 69 { 70 PISAPNP_LOGICAL_DEVICE LogDevice = CONTAINING_RECORD(RemoveHeadList(&FdoExt-> 71 DeviceListHead), 72 ISAPNP_LOGICAL_DEVICE, 73 DeviceLink); 74 75 --FdoExt->DeviceCount; 76 77 if (LogDevice->Pdo) 78 { 79 IsaPnpRemoveLogicalDeviceDO(LogDevice->Pdo); 80 } 81 } 82 83 IsaPnpReleaseDeviceDataLock(FdoExt); 84 85 IsaPnpAcquireBusDataLock(); 86 87 /* Remove the Read Port */ 88 if (FdoExt->ReadPortPdo) 89 { 90 IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo); 91 ReadPortCreated = FALSE; 92 } 93 94 /* Find the next ISA bus, if any */ 95 Entry = BusListHead.Flink; 96 if (Entry != &BusListHead) 97 { 98 PISAPNP_FDO_EXTENSION NextIsaBus = CONTAINING_RECORD(Entry, 99 ISAPNP_FDO_EXTENSION, 100 BusLink); 101 102 /* Create a new Read Port for it */ 103 if (!ReadPortCreated) 104 IoInvalidateDeviceRelations(NextIsaBus->Pdo, BusRelations); 105 } 106 107 RemoveEntryList(&FdoExt->BusLink); 108 109 IsaPnpReleaseBusDataLock(); 110 111 Irp->IoStatus.Status = STATUS_SUCCESS; 112 IoSkipCurrentIrpStackLocation(Irp); 113 Status = IoCallDriver(FdoExt->Ldo, Irp); 114 115 IoDetachDevice(FdoExt->Ldo); 116 IoDeleteDevice(FdoExt->Common.Self); 117 118 return Status; 119 } 120 121 CODE_SEG("PAGE") 122 NTSTATUS 123 IsaFdoPnp( 124 _In_ PISAPNP_FDO_EXTENSION FdoExt, 125 _Inout_ PIRP Irp, 126 _In_ PIO_STACK_LOCATION IrpSp) 127 { 128 NTSTATUS Status; 129 130 PAGED_CODE(); 131 132 DPRINT("%s(%p, %p) FDO %lu, Minor - %X\n", 133 __FUNCTION__, 134 FdoExt, 135 Irp, 136 FdoExt->BusNumber, 137 IrpSp->MinorFunction); 138 139 switch (IrpSp->MinorFunction) 140 { 141 case IRP_MN_START_DEVICE: 142 Status = IsaFdoStartDevice(FdoExt, Irp); 143 144 Irp->IoStatus.Status = Status; 145 IoCompleteRequest(Irp, IO_NO_INCREMENT); 146 return Status; 147 148 case IRP_MN_QUERY_DEVICE_RELATIONS: 149 { 150 if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) 151 break; 152 153 Status = IsaFdoQueryBusRelations(FdoExt, Irp); 154 if (!NT_SUCCESS(Status)) 155 { 156 Irp->IoStatus.Status = Status; 157 IoCompleteRequest(Irp, IO_NO_INCREMENT); 158 159 return Status; 160 } 161 162 Irp->IoStatus.Status = Status; 163 break; 164 } 165 166 case IRP_MN_REMOVE_DEVICE: 167 return IsaFdoRemoveDevice(FdoExt, Irp); 168 169 case IRP_MN_QUERY_PNP_DEVICE_STATE: 170 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; 171 Irp->IoStatus.Status = STATUS_SUCCESS; 172 break; 173 174 case IRP_MN_QUERY_INTERFACE: 175 { 176 Status = IsaFdoQueryInterface(FdoExt, IrpSp); 177 if (Status == STATUS_NOT_SUPPORTED) 178 { 179 break; 180 } 181 else if (!NT_SUCCESS(Status)) 182 { 183 Irp->IoStatus.Status = Status; 184 IoCompleteRequest(Irp, IO_NO_INCREMENT); 185 186 return Status; 187 } 188 189 Irp->IoStatus.Status = Status; 190 break; 191 } 192 193 case IRP_MN_SURPRISE_REMOVAL: 194 case IRP_MN_QUERY_STOP_DEVICE: 195 case IRP_MN_QUERY_REMOVE_DEVICE: 196 case IRP_MN_CANCEL_STOP_DEVICE: 197 case IRP_MN_CANCEL_REMOVE_DEVICE: 198 case IRP_MN_STOP_DEVICE: 199 Irp->IoStatus.Status = STATUS_SUCCESS; 200 break; 201 202 default: 203 DPRINT("Unknown PnP code: %X\n", IrpSp->MinorFunction); 204 break; 205 } 206 207 IoSkipCurrentIrpStackLocation(Irp); 208 209 return IoCallDriver(FdoExt->Ldo, Irp); 210 } 211