Activate serial device interface only at the very end of IRP_MN_START_DEVICE
[reactos.git] / reactos / drivers / dd / serial / pnp.c
index 9b90140..e1a9bcf 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id:
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         Serial port driver
  * FILE:            drivers/dd/serial/pnp.c
  * PURPOSE:         Serial IRP_MJ_PNP operations
  *
- * PROGRAMMERS:     HervĂ© Poussineau (poussine@freesurf.fr)
+ * PROGRAMMERS:     HervĂ© Poussineau (hpoussin@reactos.com)
  */
 /* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
 
@@ -126,7 +125,8 @@ SerialAddDevice(
 NTSTATUS STDCALL
 SerialPnpStartDevice(
        IN PDEVICE_OBJECT DeviceObject,
-       IN PCM_RESOURCE_LIST ResourceList)
+       IN PCM_RESOURCE_LIST ResourceList,
+       IN PCM_RESOURCE_LIST ResourceListTranslated)
 {
        PSERIAL_DEVICE_EXTENSION DeviceExtension;
        WCHAR DeviceNameBuffer[32];
@@ -162,6 +162,7 @@ SerialPnpStartDevice(
                for (j = 0; j < ResourceList->List[i].PartialResourceList.Count; j++)
                {
                        PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[i].PartialResourceList.PartialDescriptors[j];
+                       PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated = &ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
                        switch (PartialDescriptor->Type)
                        {
                                case CmResourceTypePort:
@@ -172,16 +173,14 @@ SerialPnpStartDevice(
                                        DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
                                        break;
                                case CmResourceTypeInterrupt:
-                                       if (Dirql != 0)
-                                               return STATUS_UNSUCCESSFUL;
-                                       Dirql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
-                                       Vector = PartialDescriptor->u.Interrupt.Vector;
-                                       Affinity = PartialDescriptor->u.Interrupt.Affinity;
-                                       if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
+                                       Dirql = (KIRQL)PartialDescriptorTranslated->u.Interrupt.Level;
+                                       Vector = PartialDescriptorTranslated->u.Interrupt.Vector;
+                                       Affinity = PartialDescriptorTranslated->u.Interrupt.Affinity;
+                                       if (PartialDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
                                                InterruptMode = Latched;
                                        else
                                                InterruptMode = LevelSensitive;
-                                       ShareInterrupt = (PartialDescriptor->ShareDisposition == CmResourceShareShared);
+                                       ShareInterrupt = (PartialDescriptorTranslated->ShareDisposition == CmResourceShareShared);
                                        break;
                        }
                }
@@ -243,15 +242,6 @@ SerialPnpStartDevice(
                return Status;
        }
 
-       /* Activate serial interface */
-       Status = IoSetDeviceInterfaceState(&DeviceExtension->SerialInterfaceName, TRUE);
-       if (!NT_SUCCESS(Status))
-       {
-               DPRINT("Serial: IoSetDeviceInterfaceState() failed with status 0x%08x\n", Status);
-               IoDeleteSymbolicLink(&LinkName);
-               return Status;
-       }
-
        /* Connect interrupt and enable them */
        Status = IoConnectInterrupt(
                &DeviceExtension->Interrupt, SerialInterruptService,
@@ -275,7 +265,7 @@ SerialPnpStartDevice(
        if (NT_SUCCESS(Status))
        {
                /* Key = \Device\Serialx, Value = COMx */
-               ZwSetValueKey(hKey, &DeviceName, 0, REG_SZ, &ComPortBuffer, ComPort.Length + sizeof(WCHAR));
+               ZwSetValueKey(hKey, &DeviceName, 0, REG_SZ, ComPortBuffer, ComPort.Length + sizeof(WCHAR));
                ZwClose(hKey);
        }
 
@@ -290,6 +280,10 @@ SerialPnpStartDevice(
        DeviceExtension->MCR |= SR_MCR_DTR | SR_MCR_RTS;
        WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
 
+       /* Activate serial interface */
+       IoSetDeviceInterfaceState(&DeviceExtension->SerialInterfaceName, TRUE);
+       /* We don't really care if the call succeeded or not... */
+
        return STATUS_SUCCESS;
 }
 
@@ -338,16 +332,9 @@ SerialPnp(
                        BOOLEAN ConflictDetected;
                        DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
 
-                       /* FIXME: first HACK: PnP manager can send multiple
-                        * IRP_MN_START_DEVICE for one device
-                        */
-                       if (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState != dsStopped)
-                       {
-                               DPRINT1("Serial: device already started. Ignoring this irp!\n");
-                               Status = STATUS_SUCCESS;
-                               break;
-                       }
-                       /* FIXME: second HACK: verify that we have some allocated resources.
+                       ASSERT(((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState == dsStopped);
+
+                       /* FIXME: HACK: verify that we have some allocated resources.
                         * It seems not to be always the case on some hardware
                         */
                        if (Stack->Parameters.StartDevice.AllocatedResources == NULL)
@@ -357,7 +344,7 @@ SerialPnp(
                                Status = STATUS_INSUFFICIENT_RESOURCES;
                                break;
                        }
-                       /* FIXME: third HACK: verify that we don't have resource conflict,
+                       /* FIXME: HACK: verify that we don't have resource conflict,
                         * because PnP manager doesn't do it automatically
                         */
                        Status = IoReportResourceForDetection(
@@ -377,7 +364,8 @@ SerialPnp(
                        if (NT_SUCCESS(Status))
                                Status = SerialPnpStartDevice(
                                        DeviceObject,
-                                       Stack->Parameters.StartDevice.AllocatedResources);
+                                       Stack->Parameters.StartDevice.AllocatedResources,
+                                       Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
                        break;
                }
                case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */