ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

config.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS PCI Bus Driver
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            drivers/bus/pci/pci/config.c
00005  * PURPOSE:         PCI Configuration Space Routines
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include <pci.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* GLOBALS ********************************************************************/
00016 
00017 BOOLEAN PciAssignBusNumbers;
00018 
00019 /* FUNCTIONS ******************************************************************/
00020 
00021 UCHAR
00022 NTAPI
00023 PciGetAdjustedInterruptLine(IN PPCI_PDO_EXTENSION PdoExtension)
00024 {
00025     UCHAR InterruptLine = 0, PciInterruptLine;
00026     ULONG Length;
00027 
00028     /* Does the device have an interrupt pin? */
00029     if (PdoExtension->InterruptPin)
00030     {
00031         /* Find the associated line on the parent bus */
00032         Length = HalGetBusDataByOffset(PCIConfiguration,
00033                                        PdoExtension->ParentFdoExtension->BaseBus,
00034                                        PdoExtension->Slot.u.AsULONG,
00035                                        &PciInterruptLine,
00036                                        FIELD_OFFSET(PCI_COMMON_HEADER,
00037                                                     u.type0.InterruptLine),
00038                                        sizeof(UCHAR));
00039         if (Length) InterruptLine = PciInterruptLine;
00040     }
00041 
00042     /* Either keep the original interrupt line, or the one on the master bus */
00043     return InterruptLine ? PdoExtension->RawInterruptLine : InterruptLine;
00044 }
00045 
00046 VOID
00047 NTAPI
00048 PciReadWriteConfigSpace(IN PPCI_FDO_EXTENSION DeviceExtension,
00049                         IN PCI_SLOT_NUMBER Slot,
00050                         IN PVOID Buffer,
00051                         IN ULONG Offset,
00052                         IN ULONG Length,
00053                         IN BOOLEAN Read)
00054 {
00055     PPCI_BUS_INTERFACE_STANDARD PciInterface;
00056     PBUS_HANDLER BusHandler;
00057     PPCIBUSDATA BusData;
00058     PciReadWriteConfig HalFunction;
00059 
00060     /* Only the root FDO can access configuration space */
00061     ASSERT(PCI_IS_ROOT_FDO(DeviceExtension->BusRootFdoExtension));
00062 
00063     /* Get the ACPI-compliant PCI interface */
00064     PciInterface = DeviceExtension->BusRootFdoExtension->PciBusInterface;
00065     if (PciInterface)
00066     {
00067         /* Currently this driver only supports the legacy HAL interface */
00068         UNIMPLEMENTED;
00069         while (TRUE);
00070     }
00071     else
00072     {
00073         /* Make sure there's a registered HAL bus handler */
00074         ASSERT(DeviceExtension->BusHandler);
00075 
00076         /* PCI Bus Number assignment is only valid on ACPI systems */
00077         ASSERT(!PciAssignBusNumbers);
00078 
00079         /* Grab the HAL PCI Bus Handler data */
00080         BusHandler = (PBUS_HANDLER)DeviceExtension->BusHandler;
00081         BusData = (PPCIBUSDATA)BusHandler->BusData;
00082 
00083         /* Choose the appropriate read or write function, and call it */
00084         HalFunction = Read ? BusData->ReadConfig : BusData->WriteConfig;
00085         HalFunction(BusHandler, Slot, Buffer, Offset, Length);
00086     }
00087 }
00088 
00089 VOID
00090 NTAPI
00091 PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension,
00092                      IN PVOID Buffer,
00093                      IN ULONG Offset,
00094                      IN ULONG Length)
00095 {
00096     /* Call the generic worker function */
00097     PciReadWriteConfigSpace(DeviceExtension->ParentFdoExtension,
00098                             DeviceExtension->Slot,
00099                             Buffer,
00100                             Offset,
00101                             Length,
00102                             FALSE);
00103 }
00104 
00105 VOID
00106 NTAPI
00107 PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension,
00108                     IN PVOID Buffer,
00109                     IN ULONG Offset,
00110                     IN ULONG Length)
00111 {
00112     /* Call the generic worker function */
00113     PciReadWriteConfigSpace(DeviceExtension->ParentFdoExtension,
00114                             DeviceExtension->Slot,
00115                             Buffer,
00116                             Offset,
00117                             Length,
00118                             TRUE);
00119 }
00120 
00121 VOID
00122 NTAPI
00123 PciReadSlotConfig(IN PPCI_FDO_EXTENSION DeviceExtension,
00124                   IN PCI_SLOT_NUMBER Slot,
00125                   IN PVOID Buffer,
00126                   IN ULONG Offset,
00127                   IN ULONG Length)
00128 {
00129     /* Call the generic worker function */
00130     PciReadWriteConfigSpace(DeviceExtension, Slot, Buffer, Offset, Length, TRUE);
00131 }
00132 
00133 NTSTATUS
00134 NTAPI
00135 PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension)
00136 {
00137     PDEVICE_OBJECT AttachedDevice;
00138     IO_STATUS_BLOCK IoStatusBlock;
00139     KEVENT Event;
00140     NTSTATUS Status;
00141     PIRP Irp;
00142     PIO_STACK_LOCATION IoStackLocation;
00143     PPCI_BUS_INTERFACE_STANDARD PciInterface;
00144     PAGED_CODE();
00145     ASSERT(PCI_IS_ROOT_FDO(FdoExtension));
00146 
00147     /* Allocate space for the inteface */
00148     PciInterface = ExAllocatePoolWithTag(NonPagedPool,
00149                                          sizeof(PCI_BUS_INTERFACE_STANDARD),
00150                                          PCI_POOL_TAG);
00151     if (!PciInterface) return STATUS_INSUFFICIENT_RESOURCES;
00152 
00153     /* Get the device the PDO is attached to, should be the Root (ACPI) */
00154     AttachedDevice = IoGetAttachedDeviceReference(FdoExtension->PhysicalDeviceObject);
00155 
00156     /* Build an IRP for this request */
00157     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
00158     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
00159                                        AttachedDevice,
00160                                        NULL,
00161                                        0,
00162                                        NULL,
00163                                        &Event,
00164                                        &IoStatusBlock);
00165     if (Irp)
00166     {
00167         /* Initialize the default PnP response */
00168         Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
00169         Irp->IoStatus.Information = 0;
00170 
00171         /* Make it a Query Interface IRP */
00172         IoStackLocation = IoGetNextIrpStackLocation(Irp);
00173         ASSERT(IoStackLocation->MajorFunction == IRP_MJ_PNP);
00174         IoStackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
00175         IoStackLocation->Parameters.QueryInterface.InterfaceType = &GUID_PCI_BUS_INTERFACE_STANDARD;
00176         IoStackLocation->Parameters.QueryInterface.Size = sizeof(GUID_PCI_BUS_INTERFACE_STANDARD);
00177         IoStackLocation->Parameters.QueryInterface.Version = PCI_BUS_INTERFACE_STANDARD_VERSION;
00178         IoStackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)PciInterface;
00179         IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData = NULL;
00180 
00181         /* Send it to the root PDO */
00182         Status = IoCallDriver(AttachedDevice, Irp);
00183         if (Status == STATUS_PENDING)
00184         {
00185             /* Wait for completion */
00186             KeWaitForSingleObject(&Event,
00187                                   Executive,
00188                                   KernelMode,
00189                                   FALSE,
00190                                   NULL);
00191             Status = Irp->IoStatus.Status;
00192         }
00193 
00194         /* Check if an interface was returned */
00195         if (!NT_SUCCESS(Status))
00196         {
00197             /* No interface was returned by the root PDO */
00198             FdoExtension->PciBusInterface = NULL;
00199             ExFreePoolWithTag(PciInterface, 0);
00200         }
00201         else
00202         {
00203             /* An interface was returned, save it */
00204             FdoExtension->PciBusInterface = PciInterface;
00205         }
00206 
00207         /* Dereference the device object because we took a reference earlier */
00208         ObDereferenceObject(AttachedDevice);
00209     }
00210     else
00211     {
00212         /* Failure path, dereference the device object and set failure code */
00213         if (AttachedDevice) ObDereferenceObject(AttachedDevice);
00214         ExFreePoolWithTag(PciInterface, 0);
00215         Status = STATUS_INSUFFICIENT_RESOURCES;
00216     }
00217 
00218     /* Return status code to caller */
00219     return Status;
00220 }
00221 
00222 NTSTATUS
00223 NTAPI
00224 PciGetConfigHandlers(IN PPCI_FDO_EXTENSION FdoExtension)
00225 {
00226     PBUS_HANDLER BusHandler;
00227     NTSTATUS Status;
00228     ASSERT(FdoExtension->BusHandler == NULL);
00229 
00230     /* Check if this is the FDO for the root bus */
00231     if (PCI_IS_ROOT_FDO(FdoExtension))
00232     {
00233         /* Query the PCI Bus Interface that ACPI exposes */
00234         ASSERT(FdoExtension->PciBusInterface == NULL);
00235         Status = PciQueryForPciBusInterface(FdoExtension);
00236         if (!NT_SUCCESS(Status))
00237         {
00238             /* No ACPI, so Bus Numbers should be maintained by BIOS */
00239             ASSERT(!PciAssignBusNumbers);
00240         }
00241         else
00242         {
00243             /* ACPI detected, PCI Bus Driver will reconfigure bus numbers*/
00244             PciAssignBusNumbers = TRUE;
00245         }
00246     }
00247     else
00248     {
00249         /* Check if the root bus already has the interface set up */
00250         if (FdoExtension->BusRootFdoExtension->PciBusInterface)
00251         {
00252             /* Nothing for this FDO to do */
00253             return STATUS_SUCCESS;
00254         }
00255 
00256         /* Fail into case below so we can query the HAL interface */
00257         Status = STATUS_NOT_SUPPORTED;
00258     }
00259 
00260     /* If the ACPI PCI Bus Interface couldn't be obtained, try the HAL */
00261     if (!NT_SUCCESS(Status))
00262     {
00263         /* Bus number assignment should be static */
00264         ASSERT(Status == STATUS_NOT_SUPPORTED);
00265         ASSERT(!PciAssignBusNumbers);
00266 
00267         /* Call the HAL to obtain the bus handler for PCI */
00268         BusHandler = HalReferenceHandlerForBus(PCIBus, FdoExtension->BaseBus);
00269         FdoExtension->BusHandler = BusHandler;
00270 
00271         /* Fail if the HAL does not have a PCI Bus Handler for this bus */
00272         if (!BusHandler) return STATUS_INVALID_DEVICE_REQUEST;
00273     }
00274 
00275     /* Appropriate interface was obtained */
00276     return STATUS_SUCCESS;
00277 }
00278 
00279 /* EOF */

Generated on Sat May 26 2012 04:17:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.