Sync with trunk r58740.
[reactos.git] / drivers / bus / pci / pdo.c
index a339179..644bffe 100644 (file)
@@ -766,6 +766,9 @@ PdoQueryResources(
         Descriptor->u.Port.Start.QuadPart =
           (ULONGLONG)Base;
         Descriptor->u.Port.Length = Length;
+
+        /* Enable IO space access */
+        DeviceExtension->PciDevice->EnableIoSpace = TRUE;
       }
       else
       {
@@ -775,6 +778,9 @@ PdoQueryResources(
         Descriptor->u.Memory.Start.QuadPart =
           (ULONGLONG)Base;
         Descriptor->u.Memory.Length = Length;
+
+        /* Enable memory space access */
+        DeviceExtension->PciDevice->EnableMemorySpace = TRUE;
       }
 
       Descriptor++;
@@ -792,6 +798,9 @@ PdoQueryResources(
       Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
       Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
     }
+
+    /* Allow bus master mode */
+    DeviceExtension->PciDevice->EnableBusMaster = TRUE;
   }
   else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
   {
@@ -821,6 +830,9 @@ PdoQueryResources(
         Descriptor->u.Port.Start.QuadPart =
           (ULONGLONG)Base;
         Descriptor->u.Port.Length = Length;
+
+        /* Enable IO space access */
+        DeviceExtension->PciDevice->EnableIoSpace = TRUE;
       }
       else
       {
@@ -830,6 +842,9 @@ PdoQueryResources(
         Descriptor->u.Memory.Start.QuadPart =
           (ULONGLONG)Base;
         Descriptor->u.Memory.Length = Length;
+
+        /* Enable memory space access */
+        DeviceExtension->PciDevice->EnableMemorySpace = TRUE;
       }
 
       Descriptor++;
@@ -1206,45 +1221,88 @@ PdoStartDevice(
   IN PIRP Irp,
   PIO_STACK_LOCATION IrpSp)
 {
-  PCM_RESOURCE_LIST RawResList = IrpSp->Parameters.StartDevice.AllocatedResources;
-  PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc;
-  PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc;
-  ULONG i, ii;
-  PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
-  UCHAR Irq;
+    PCM_RESOURCE_LIST RawResList = IrpSp->Parameters.StartDevice.AllocatedResources;
+    PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc;
+    ULONG i, ii;
+    PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    UCHAR Irq;
+    USHORT Command;
 
-  if (!RawResList)
-      return STATUS_SUCCESS;
+    if (!RawResList)
+        return STATUS_SUCCESS;
 
-  /* TODO: Assign the other resources we get to the card */
+    /* TODO: Assign the other resources we get to the card */
 
-  for (i = 0; i < RawResList->Count; i++)
-  {
-      RawFullDesc = &RawResList->List[i];
+    for (i = 0; i < RawResList->Count; i++)
+    {
+        RawFullDesc = &RawResList->List[i];
 
-      for (ii = 0; ii < RawFullDesc->PartialResourceList.Count; ii++)
-      {
-          RawPartialDesc = &RawFullDesc->PartialResourceList.PartialDescriptors[ii];
+        for (ii = 0; ii < RawFullDesc->PartialResourceList.Count; ii++)
+        {
+            RawPartialDesc = &RawFullDesc->PartialResourceList.PartialDescriptors[ii];
+
+            if (RawPartialDesc->Type == CmResourceTypeInterrupt)
+            {
+                DPRINT1("Assigning IRQ %d to PCI device 0x%x on bus 0x%x\n",
+                        RawPartialDesc->u.Interrupt.Vector,
+                        DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                        DeviceExtension->PciDevice->BusNumber);
+
+                Irq = (UCHAR)RawPartialDesc->u.Interrupt.Vector;
+                HalSetBusDataByOffset(PCIConfiguration,
+                                      DeviceExtension->PciDevice->BusNumber,
+                                      DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                                      &Irq,
+                                      0x3c /* PCI_INTERRUPT_LINE */,
+                                      sizeof(UCHAR));
+            }
+        }
+    }
 
-          if (RawPartialDesc->Type == CmResourceTypeInterrupt)
-          {
-              DPRINT1("Assigning IRQ %x to PCI device (%x, %x)\n",
-                      RawPartialDesc->u.Interrupt.Vector,
-                      DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
-                      DeviceExtension->PciDevice->BusNumber);
-
-              Irq = (UCHAR)RawPartialDesc->u.Interrupt.Vector;
-              HalSetBusDataByOffset(PCIConfiguration,
-                                    DeviceExtension->PciDevice->BusNumber,
-                                    DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
-                                    &Irq,
-                                    0x3c /* PCI_INTERRUPT_LINE */,
-                                    sizeof(UCHAR));
-          }
-      }
-   }
+    Command = 0;
+
+    DPRINT1("Enabling command flags for PCI device 0x%x on bus 0x%x: ",
+            DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+            DeviceExtension->PciDevice->BusNumber);
+    if (DeviceExtension->PciDevice->EnableBusMaster)
+    {
+        Command |= PCI_ENABLE_BUS_MASTER;
+        DbgPrint("[Bus master] ");
+    }
+
+    if (DeviceExtension->PciDevice->EnableMemorySpace)
+    {
+        Command |= PCI_ENABLE_MEMORY_SPACE;
+        DbgPrint("[Memory space enable] ");
+    }
+
+    if (DeviceExtension->PciDevice->EnableIoSpace)
+    {
+        Command |= PCI_ENABLE_IO_SPACE;
+        DbgPrint("[I/O space enable] ");
+    }
+
+    if (Command != 0)
+    {
+        DbgPrint("\n");
+
+        /* OR with the previous value */
+        Command |= DeviceExtension->PciDevice->PciConfig.Command;
+
+        HalSetBusDataByOffset(PCIConfiguration,
+                              DeviceExtension->PciDevice->BusNumber,
+                              DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
+                              &Command,
+                              FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
+                              sizeof(USHORT));
+    }
+    else
+    {
+        DbgPrint("None\n");
+    }
 
-   return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 static NTSTATUS
@@ -1443,11 +1501,34 @@ PdoPnpControl(
   case IRP_MN_STOP_DEVICE:
   case IRP_MN_QUERY_REMOVE_DEVICE:
   case IRP_MN_CANCEL_REMOVE_DEVICE:
-  case IRP_MN_REMOVE_DEVICE:
   case IRP_MN_SURPRISE_REMOVAL:
     Status = STATUS_SUCCESS;
     break;
 
+  case IRP_MN_REMOVE_DEVICE:
+  {
+    PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension = DeviceExtension->Fdo->DeviceExtension;
+    KIRQL OldIrql;
+
+    /* Remove it from the device list */
+    KeAcquireSpinLock(&FdoDeviceExtension->DeviceListLock, &OldIrql);
+    RemoveEntryList(&DeviceExtension->PciDevice->ListEntry);
+    FdoDeviceExtension->DeviceListCount--;
+    KeReleaseSpinLock(&FdoDeviceExtension->DeviceListLock, OldIrql);
+
+    /* Free the device */
+    ExFreePool(DeviceExtension->PciDevice);
+
+    /* Complete the IRP */
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    /* Delete the DO */
+    IoDeleteDevice(DeviceObject);
+    return STATUS_SUCCESS;
+  }
+
   case IRP_MN_QUERY_INTERFACE:
     DPRINT("IRP_MN_QUERY_INTERFACE received\n");
     Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);