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

pcibus.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS HAL
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            hal/halx86/generic/bus/pcibus.c
00005  * PURPOSE:         PCI Bus Support (Configuration Space, Resource Allocation)
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <hal.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* GLOBALS *******************************************************************/
00016 
00017 extern BOOLEAN HalpPciLockSettings;
00018 ULONG HalpBusType;
00019 
00020 PCI_TYPE1_CFG_CYCLE_BITS HalpPciDebuggingDevice[2] = {{{{0}}}};
00021 
00022 BOOLEAN HalpPCIConfigInitialized;
00023 ULONG HalpMinPciBus, HalpMaxPciBus;
00024 KSPIN_LOCK HalpPCIConfigLock;
00025 PCI_CONFIG_HANDLER PCIConfigHandler;
00026 
00027 /* PCI Operation Matrix */
00028 UCHAR PCIDeref[4][4] =
00029 {
00030     {0, 1, 2, 2},   // ULONG-aligned offset
00031     {1, 1, 1, 1},   // UCHAR-aligned offset
00032     {2, 1, 2, 2},   // USHORT-aligned offset
00033     {1, 1, 1, 1}    // UCHAR-aligned offset
00034 };
00035 
00036 /* Type 1 PCI Bus */
00037 PCI_CONFIG_HANDLER PCIConfigHandlerType1 =
00038 {
00039     /* Synchronization */
00040     (FncSync)HalpPCISynchronizeType1,
00041     (FncReleaseSync)HalpPCIReleaseSynchronzationType1,
00042 
00043     /* Read */
00044     {
00045         (FncConfigIO)HalpPCIReadUlongType1,
00046         (FncConfigIO)HalpPCIReadUcharType1,
00047         (FncConfigIO)HalpPCIReadUshortType1
00048     },
00049 
00050     /* Write */
00051     {
00052         (FncConfigIO)HalpPCIWriteUlongType1,
00053         (FncConfigIO)HalpPCIWriteUcharType1,
00054         (FncConfigIO)HalpPCIWriteUshortType1
00055     }
00056 };
00057 
00058 /* Type 2 PCI Bus */
00059 PCI_CONFIG_HANDLER PCIConfigHandlerType2 =
00060 {
00061     /* Synchronization */
00062     (FncSync)HalpPCISynchronizeType2,
00063     (FncReleaseSync)HalpPCIReleaseSynchronizationType2,
00064 
00065     /* Read */
00066     {
00067         (FncConfigIO)HalpPCIReadUlongType2,
00068         (FncConfigIO)HalpPCIReadUcharType2,
00069         (FncConfigIO)HalpPCIReadUshortType2
00070     },
00071 
00072     /* Write */
00073     {
00074         (FncConfigIO)HalpPCIWriteUlongType2,
00075         (FncConfigIO)HalpPCIWriteUcharType2,
00076         (FncConfigIO)HalpPCIWriteUshortType2
00077     }
00078 };
00079 
00080 PCIPBUSDATA HalpFakePciBusData =
00081 {
00082     {
00083         PCI_DATA_TAG,
00084         PCI_DATA_VERSION,
00085         HalpReadPCIConfig,
00086         HalpWritePCIConfig,
00087         NULL,
00088         NULL,
00089         {{{0, 0, 0}}},
00090         {0, 0, 0, 0}
00091     },
00092     {{0, 0}},
00093     32,
00094 };
00095 
00096 BUS_HANDLER HalpFakePciBusHandler =
00097 {
00098     1,
00099     PCIBus,
00100     PCIConfiguration,
00101     0,
00102     NULL,
00103     NULL,
00104     &HalpFakePciBusData,
00105     0,
00106     NULL,
00107     {0, 0, 0, 0},
00108     (PGETSETBUSDATA)HalpGetPCIData,
00109     (PGETSETBUSDATA)HalpSetPCIData,
00110     NULL,
00111     HalpAssignPCISlotResources,
00112     NULL,
00113     NULL
00114 };
00115 
00116 /* TYPE 1 FUNCTIONS **********************************************************/
00117 
00118 VOID
00119 NTAPI
00120 HalpPCISynchronizeType1(IN PBUS_HANDLER BusHandler,
00121                         IN PCI_SLOT_NUMBER Slot,
00122                         IN PKIRQL Irql,
00123                         IN PPCI_TYPE1_CFG_BITS PciCfg1)
00124 {
00125     /* Setup the PCI Configuration Register */
00126     PciCfg1->u.AsULONG = 0;
00127     PciCfg1->u.bits.BusNumber = BusHandler->BusNumber;
00128     PciCfg1->u.bits.DeviceNumber = Slot.u.bits.DeviceNumber;
00129     PciCfg1->u.bits.FunctionNumber = Slot.u.bits.FunctionNumber;
00130     PciCfg1->u.bits.Enable = TRUE;
00131 
00132     /* Acquire the lock */
00133     KeRaiseIrql(HIGH_LEVEL, Irql);
00134     KiAcquireSpinLock(&HalpPCIConfigLock);
00135 }
00136 
00137 VOID
00138 NTAPI
00139 HalpPCIReleaseSynchronzationType1(IN PBUS_HANDLER BusHandler,
00140                                   IN KIRQL Irql)
00141 {
00142     PCI_TYPE1_CFG_BITS PciCfg1;
00143 
00144     /* Clear the PCI Configuration Register */
00145     PciCfg1.u.AsULONG = 0;
00146     WRITE_PORT_ULONG(((PPCIPBUSDATA)BusHandler->BusData)->Config.Type1.Address,
00147                      PciCfg1.u.AsULONG);
00148 
00149     /* Release the lock */
00150     KiReleaseSpinLock(&HalpPCIConfigLock);
00151     KeLowerIrql(Irql);
00152 }
00153 
00154 TYPE1_READ(HalpPCIReadUcharType1, UCHAR)
00155 TYPE1_READ(HalpPCIReadUshortType1, USHORT)
00156 TYPE1_READ(HalpPCIReadUlongType1, ULONG)
00157 TYPE1_WRITE(HalpPCIWriteUcharType1, UCHAR)
00158 TYPE1_WRITE(HalpPCIWriteUshortType1, USHORT)
00159 TYPE1_WRITE(HalpPCIWriteUlongType1, ULONG)
00160 
00161 /* TYPE 2 FUNCTIONS **********************************************************/
00162 
00163 VOID
00164 NTAPI
00165 HalpPCISynchronizeType2(IN PBUS_HANDLER BusHandler,
00166                         IN PCI_SLOT_NUMBER Slot,
00167                         IN PKIRQL Irql,
00168                         IN PPCI_TYPE2_ADDRESS_BITS PciCfg)
00169 {
00170     PCI_TYPE2_CSE_BITS PciCfg2Cse;
00171     PPCIPBUSDATA BusData = (PPCIPBUSDATA)BusHandler->BusData;
00172 
00173     /* Setup the configuration register */
00174     PciCfg->u.AsUSHORT = 0;
00175     PciCfg->u.bits.Agent = (USHORT)Slot.u.bits.DeviceNumber;
00176     PciCfg->u.bits.AddressBase = (USHORT)BusData->Config.Type2.Base;
00177 
00178     /* Acquire the lock */
00179     KeRaiseIrql(HIGH_LEVEL, Irql);
00180     KiAcquireSpinLock(&HalpPCIConfigLock);
00181 
00182     /* Setup the CSE Register */
00183     PciCfg2Cse.u.AsUCHAR = 0;
00184     PciCfg2Cse.u.bits.Enable = TRUE;
00185     PciCfg2Cse.u.bits.FunctionNumber = (UCHAR)Slot.u.bits.FunctionNumber;
00186     PciCfg2Cse.u.bits.Key = -1;
00187 
00188     /* Write the bus number and CSE */
00189     WRITE_PORT_UCHAR(BusData->Config.Type2.Forward,
00190                      (UCHAR)BusHandler->BusNumber);
00191     WRITE_PORT_UCHAR(BusData->Config.Type2.CSE, PciCfg2Cse.u.AsUCHAR);
00192 }
00193 
00194 VOID
00195 NTAPI
00196 HalpPCIReleaseSynchronizationType2(IN PBUS_HANDLER BusHandler,
00197                                    IN KIRQL Irql)
00198 {
00199     PCI_TYPE2_CSE_BITS PciCfg2Cse;
00200     PPCIPBUSDATA BusData = (PPCIPBUSDATA)BusHandler->BusData;
00201 
00202     /* Clear CSE and bus number */
00203     PciCfg2Cse.u.AsUCHAR = 0;
00204     WRITE_PORT_UCHAR(BusData->Config.Type2.CSE, PciCfg2Cse.u.AsUCHAR);
00205     WRITE_PORT_UCHAR(BusData->Config.Type2.Forward, 0);
00206 
00207     /* Release the lock */
00208     KiReleaseSpinLock(&HalpPCIConfigLock);
00209     KeLowerIrql(Irql);
00210 }
00211 
00212 TYPE2_READ(HalpPCIReadUcharType2, UCHAR)
00213 TYPE2_READ(HalpPCIReadUshortType2, USHORT)
00214 TYPE2_READ(HalpPCIReadUlongType2, ULONG)
00215 TYPE2_WRITE(HalpPCIWriteUcharType2, UCHAR)
00216 TYPE2_WRITE(HalpPCIWriteUshortType2, USHORT)
00217 TYPE2_WRITE(HalpPCIWriteUlongType2, ULONG)
00218 
00219 /* PCI CONFIGURATION SPACE ***************************************************/
00220 
00221 VOID
00222 NTAPI
00223 HalpPCIConfig(IN PBUS_HANDLER BusHandler,
00224               IN PCI_SLOT_NUMBER Slot,
00225               IN PUCHAR Buffer,
00226               IN ULONG Offset,
00227               IN ULONG Length,
00228               IN FncConfigIO *ConfigIO)
00229 {
00230     KIRQL OldIrql;
00231     ULONG i;
00232     UCHAR State[20];
00233 
00234     /* Synchronize the operation */
00235     PCIConfigHandler.Synchronize(BusHandler, Slot, &OldIrql, State);
00236 
00237     /* Loop every increment */
00238     while (Length)
00239     {
00240         /* Find out the type of read/write we need to do */
00241         i = PCIDeref[Offset % sizeof(ULONG)][Length % sizeof(ULONG)];
00242 
00243         /* Do the read/write and return the number of bytes */
00244         i = ConfigIO[i]((PPCIPBUSDATA)BusHandler->BusData,
00245                         State,
00246                         Buffer,
00247                         Offset);
00248 
00249         /* Increment the buffer position and offset, and decrease the length */
00250         Offset += i;
00251         Buffer += i;
00252         Length -= i;
00253     }
00254 
00255     /* Release the lock and PCI bus */
00256     PCIConfigHandler.ReleaseSynchronzation(BusHandler, OldIrql);
00257 }
00258 
00259 VOID
00260 NTAPI
00261 HalpReadPCIConfig(IN PBUS_HANDLER BusHandler,
00262                   IN PCI_SLOT_NUMBER Slot,
00263                   IN PVOID Buffer,
00264                   IN ULONG Offset,
00265                   IN ULONG Length)
00266 {
00267     /* Validate the PCI Slot */
00268     if (!HalpValidPCISlot(BusHandler, Slot))
00269     {
00270         /* Fill the buffer with invalid data */
00271         RtlFillMemory(Buffer, Length, -1);
00272     }
00273     else
00274     {
00275         /* Send the request */
00276         HalpPCIConfig(BusHandler,
00277                       Slot,
00278                       Buffer,
00279                       Offset,
00280                       Length,
00281                       PCIConfigHandler.ConfigRead);
00282     }
00283 }
00284 
00285 VOID
00286 NTAPI
00287 HalpWritePCIConfig(IN PBUS_HANDLER BusHandler,
00288                    IN PCI_SLOT_NUMBER Slot,
00289                    IN PVOID Buffer,
00290                    IN ULONG Offset,
00291                    IN ULONG Length)
00292 {
00293     /* Validate the PCI Slot */
00294     if (HalpValidPCISlot(BusHandler, Slot))
00295     {
00296         /* Send the request */
00297         HalpPCIConfig(BusHandler,
00298                       Slot,
00299                       Buffer,
00300                       Offset,
00301                       Length,
00302                       PCIConfigHandler.ConfigWrite);
00303     }
00304 }
00305 
00306 BOOLEAN
00307 NTAPI
00308 HalpValidPCISlot(IN PBUS_HANDLER BusHandler,
00309                  IN PCI_SLOT_NUMBER Slot)
00310 {
00311     PCI_SLOT_NUMBER MultiSlot;
00312     PPCIPBUSDATA BusData = (PPCIPBUSDATA)BusHandler->BusData;
00313     UCHAR HeaderType;
00314     //ULONG Device;
00315 
00316     /* Simple validation */
00317     if (Slot.u.bits.Reserved) return FALSE;
00318     if (Slot.u.bits.DeviceNumber >= BusData->MaxDevice) return FALSE;
00319 
00320     /* Function 0 doesn't need checking */
00321     if (!Slot.u.bits.FunctionNumber) return TRUE;
00322 
00323     /* Functions 0+ need Multi-Function support, so check the slot */
00324     //Device = Slot.u.bits.DeviceNumber;
00325     MultiSlot = Slot;
00326     MultiSlot.u.bits.FunctionNumber = 0;
00327 
00328     /* Send function 0 request to get the header back */
00329     HalpReadPCIConfig(BusHandler,
00330                       MultiSlot,
00331                       &HeaderType,
00332                       FIELD_OFFSET(PCI_COMMON_CONFIG, HeaderType),
00333                       sizeof(UCHAR));
00334 
00335     /* Now make sure the header is multi-function */
00336     if (!(HeaderType & PCI_MULTIFUNCTION) || (HeaderType == 0xFF)) return FALSE;
00337     return TRUE;
00338 }
00339 
00340 /* HAL PCI CALLBACKS *********************************************************/
00341 
00342 ULONG
00343 NTAPI
00344 HalpGetPCIData(IN PBUS_HANDLER BusHandler,
00345                IN PBUS_HANDLER RootHandler,
00346                IN PCI_SLOT_NUMBER Slot,
00347                IN PVOID Buffer,
00348                IN ULONG Offset,
00349                IN ULONG Length)
00350 {
00351     UCHAR PciBuffer[PCI_COMMON_HDR_LENGTH];
00352     PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)PciBuffer;
00353     ULONG Len = 0;
00354 
00355 #ifdef SARCH_XBOX
00356     /* Trying to get PCI config data from devices 0:0:1 and 0:0:2 will completely
00357      * hang the Xbox. Also, the device number doesn't seem to be decoded for the
00358      * video card, so it appears to be present on 1:0:0 - 1:31:0.
00359      * We hack around these problems by indicating "device not present" for devices
00360      * 0:0:1, 0:0:2, 1:1:0, 1:2:0, 1:3:0, ...., 1:31:0 */
00361     if ((0 == BusHandler->BusNumber && 0 == Slot.u.bits.DeviceNumber &&
00362          (1 == Slot.u.bits.FunctionNumber || 2 == Slot.u.bits.FunctionNumber)) ||
00363         (1 == BusHandler->BusNumber && 0 != Slot.u.bits.DeviceNumber))
00364     {
00365         DPRINT("Blacklisted PCI slot\n");
00366         if (0 == Offset && sizeof(USHORT) <= Length)
00367         {
00368             *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
00369             return sizeof(USHORT);
00370         }
00371         return 0;
00372     }
00373 #endif
00374 
00375     /* Normalize the length */
00376     if (Length > sizeof(PCI_COMMON_CONFIG)) Length = sizeof(PCI_COMMON_CONFIG);
00377 
00378     /* Check if this is a vendor-specific read */
00379     if (Offset >= PCI_COMMON_HDR_LENGTH)
00380     {
00381         /* Read the header */
00382         HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, sizeof(ULONG));
00383 
00384         /* Make sure the vendor is valid */
00385         if (PciConfig->VendorID == PCI_INVALID_VENDORID) return 0;
00386     }
00387     else
00388     {
00389         /* Read the entire header */
00390         Len = PCI_COMMON_HDR_LENGTH;
00391         HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, Len);
00392 
00393         /* Validate the vendor ID */
00394         if (PciConfig->VendorID == PCI_INVALID_VENDORID)
00395         {
00396             /* It's invalid, but we want to return this much */
00397             Len = sizeof(USHORT);
00398         }
00399 
00400         /* Now check if there's space left */
00401         if (Len < Offset) return 0;
00402 
00403         /* There is, so return what's after the offset and normalize */
00404         Len -= Offset;
00405         if (Len > Length) Len = Length;
00406 
00407         /* Copy the data into the caller's buffer */
00408         RtlMoveMemory(Buffer, PciBuffer + Offset, Len);
00409 
00410         /* Update buffer and offset, decrement total length */
00411         Offset += Len;
00412         Buffer = (PVOID)((ULONG_PTR)Buffer + Len);
00413         Length -= Len;
00414     }
00415 
00416     /* Now we still have something to copy */
00417     if (Length)
00418     {
00419         /* Check if it's vendor-specific data */
00420         if (Offset >= PCI_COMMON_HDR_LENGTH)
00421         {
00422             /* Read it now */
00423             HalpReadPCIConfig(BusHandler, Slot, Buffer, Offset, Length);
00424             Len += Length;
00425         }
00426     }
00427 
00428     /* Update the total length read */
00429     return Len;
00430 }
00431 
00432 ULONG
00433 NTAPI
00434 HalpSetPCIData(IN PBUS_HANDLER BusHandler,
00435                IN PBUS_HANDLER RootHandler,
00436                IN PCI_SLOT_NUMBER Slot,
00437                IN PVOID Buffer,
00438                IN ULONG Offset,
00439                IN ULONG Length)
00440 {
00441     UCHAR PciBuffer[PCI_COMMON_HDR_LENGTH];
00442     PPCI_COMMON_CONFIG PciConfig = (PPCI_COMMON_CONFIG)PciBuffer;
00443     ULONG Len = 0;
00444 
00445 #ifdef SARCH_XBOX
00446     /* Trying to get PCI config data from devices 0:0:1 and 0:0:2 will completely
00447      * hang the Xbox. Also, the device number doesn't seem to be decoded for the
00448      * video card, so it appears to be present on 1:0:0 - 1:31:0.
00449      * We hack around these problems by indicating "device not present" for devices
00450      * 0:0:1, 0:0:2, 1:1:0, 1:2:0, 1:3:0, ...., 1:31:0 */
00451     if ((0 == BusHandler->BusNumber && 0 == Slot.u.bits.DeviceNumber &&
00452          (1 == Slot.u.bits.FunctionNumber || 2 == Slot.u.bits.FunctionNumber)) ||
00453         (1 == BusHandler->BusNumber && 0 != Slot.u.bits.DeviceNumber))
00454     {
00455         DPRINT1("Trying to set data on blacklisted PCI slot\n");
00456         return 0;
00457     }
00458 #endif
00459 
00460     /* Normalize the length */
00461     if (Length > sizeof(PCI_COMMON_CONFIG)) Length = sizeof(PCI_COMMON_CONFIG);
00462 
00463     /* Check if this is a vendor-specific read */
00464     if (Offset >= PCI_COMMON_HDR_LENGTH)
00465     {
00466         /* Read the header */
00467         HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, sizeof(ULONG));
00468 
00469         /* Make sure the vendor is valid */
00470         if (PciConfig->VendorID == PCI_INVALID_VENDORID) return 0;
00471     }
00472     else
00473     {
00474         /* Read the entire header and validate the vendor ID */
00475         Len = PCI_COMMON_HDR_LENGTH;
00476         HalpReadPCIConfig(BusHandler, Slot, PciConfig, 0, Len);
00477         if (PciConfig->VendorID == PCI_INVALID_VENDORID) return 0;
00478 
00479         /* Return what's after the offset and normalize */
00480         Len -= Offset;
00481         if (Len > Length) Len = Length;
00482 
00483         /* Copy the specific caller data */
00484         RtlMoveMemory(PciBuffer + Offset, Buffer, Len);
00485 
00486         /* Write the actual configuration data */
00487         HalpWritePCIConfig(BusHandler, Slot, PciBuffer + Offset, Offset, Len);
00488 
00489         /* Update buffer and offset, decrement total length */
00490         Offset += Len;
00491         Buffer = (PVOID)((ULONG_PTR)Buffer + Len);
00492         Length -= Len;
00493     }
00494 
00495     /* Now we still have something to copy */
00496     if (Length)
00497     {
00498         /* Check if it's vendor-specific data */
00499         if (Offset >= PCI_COMMON_HDR_LENGTH)
00500         {
00501             /* Read it now */
00502             HalpWritePCIConfig(BusHandler, Slot, Buffer, Offset, Length);
00503             Len += Length;
00504         }
00505     }
00506 
00507     /* Update the total length read */
00508     return Len;
00509 }
00510 
00511 ULONG
00512 NTAPI
00513 HalpGetPCIIntOnISABus(IN PBUS_HANDLER BusHandler,
00514                       IN PBUS_HANDLER RootHandler,
00515                       IN ULONG BusInterruptLevel,
00516                       IN ULONG BusInterruptVector,
00517                       OUT PKIRQL Irql,
00518                       OUT PKAFFINITY Affinity)
00519 {
00520     /* Validate the level first */
00521     if (BusInterruptLevel < 1) return 0;
00522 
00523     /* PCI has its IRQs on top of ISA IRQs, so pass it on to the ISA handler */
00524     return HalGetInterruptVector(Isa,
00525                                  0,
00526                                  BusInterruptLevel,
00527                                  0,
00528                                  Irql,
00529                                  Affinity);
00530 }
00531 
00532 VOID
00533 NTAPI
00534 HalpPCIPin2ISALine(IN PBUS_HANDLER BusHandler,
00535                    IN PBUS_HANDLER RootHandler,
00536                    IN PCI_SLOT_NUMBER SlotNumber,
00537                    IN PPCI_COMMON_CONFIG PciData)
00538 {
00539     UNIMPLEMENTED;
00540     while (TRUE);
00541 }
00542 
00543 VOID
00544 NTAPI
00545 HalpPCIISALine2Pin(IN PBUS_HANDLER BusHandler,
00546                    IN PBUS_HANDLER RootHandler,
00547                    IN PCI_SLOT_NUMBER SlotNumber,
00548                    IN PPCI_COMMON_CONFIG PciNewData,
00549                    IN PPCI_COMMON_CONFIG PciOldData)
00550 {
00551     UNIMPLEMENTED;
00552     while (TRUE);
00553 }
00554 
00555 NTSTATUS
00556 NTAPI
00557 HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler,
00558                       IN PBUS_HANDLER RootHandler,
00559                       IN PCI_SLOT_NUMBER PciSlot,
00560                       OUT PSUPPORTED_RANGE *Range)
00561 {
00562     PCI_COMMON_HEADER PciData;
00563 
00564     /* Read PCI configuration data */
00565     HalGetBusData(PCIConfiguration,
00566                   BusHandler->BusNumber,
00567                   PciSlot.u.AsULONG,
00568                   &PciData,
00569                   PCI_COMMON_HDR_LENGTH);
00570 
00571     /* Make sure it's a real device */
00572     if (PciData.VendorID == PCI_INVALID_VENDORID) return STATUS_UNSUCCESSFUL;
00573 
00574     /* Allocate the supported range structure */
00575     *Range = ExAllocatePoolWithTag(PagedPool, sizeof(SUPPORTED_RANGE), TAG_HAL);
00576     if (!*Range) return STATUS_INSUFFICIENT_RESOURCES;
00577 
00578     /* Set it up */
00579     RtlZeroMemory(*Range, sizeof(SUPPORTED_RANGE));
00580     (*Range)->Base = 1;
00581 
00582     /* If the PCI device has no IRQ, nothing to do */
00583     if (!PciData.u.type0.InterruptPin) return STATUS_SUCCESS;
00584 
00585     /* FIXME: The PCI IRQ Routing Miniport should be called */
00586 
00587     /* Also if the INT# seems bogus, nothing to do either */
00588     if ((PciData.u.type0.InterruptLine == 0) ||
00589         (PciData.u.type0.InterruptLine == 255))
00590     {
00591         /* Fake success */
00592         return STATUS_SUCCESS;
00593     }
00594 
00595     /* Otherwise, the INT# should be valid, return it to the caller */
00596     (*Range)->Base = PciData.u.type0.InterruptLine;
00597     (*Range)->Limit = PciData.u.type0.InterruptLine;
00598     return STATUS_SUCCESS;
00599 }
00600 
00601 NTSTATUS
00602 NTAPI
00603 INIT_FUNCTION
00604 HalpSetupPciDeviceForDebugging(IN PVOID LoaderBlock,
00605                                IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
00606 {
00607     DPRINT1("Unimplemented!\n");
00608     return STATUS_NOT_IMPLEMENTED;
00609 }
00610 
00611 NTSTATUS
00612 NTAPI
00613 INIT_FUNCTION
00614 HalpReleasePciDeviceForDebugging(IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice)
00615 {
00616     DPRINT1("Unimplemented!\n");
00617     return STATUS_NOT_IMPLEMENTED;
00618 }
00619 
00620 VOID
00621 NTAPI
00622 INIT_FUNCTION
00623 HalpRegisterPciDebuggingDeviceInfo(VOID)
00624 {
00625     BOOLEAN Found = FALSE;
00626     ULONG i;
00627     PAGED_CODE();
00628 
00629     /* Loop PCI debugging devices */
00630     for (i = 0; i < 2; i++)
00631     {
00632         /* Reserved bit is set if we found one */
00633         if (HalpPciDebuggingDevice[i].u.bits.Reserved1)
00634         {
00635             Found = TRUE;
00636             break;
00637         }
00638     }
00639 
00640     /* Bail out if there aren't any */
00641     if (!Found) return;
00642 
00643     /* FIXME: TODO */
00644     DPRINT1("You have implemented the KD routines for searching PCI debugger"
00645             "devices, but you have forgotten to implement this routine\n");
00646     while (TRUE);
00647 }
00648 
00649 static ULONG NTAPI
00650 PciSize(ULONG Base, ULONG Mask)
00651 {
00652     ULONG Size = Mask & Base; /* Find the significant bits */
00653     Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */
00654     return Size;
00655 }
00656 
00657 NTSTATUS
00658 NTAPI
00659 HalpAdjustPCIResourceList(IN PBUS_HANDLER BusHandler,
00660                           IN PBUS_HANDLER RootHandler,
00661                           IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList)
00662 {
00663     PPCIPBUSDATA BusData;
00664     PCI_SLOT_NUMBER SlotNumber;
00665     PSUPPORTED_RANGE Interrupt;
00666     NTSTATUS Status;
00667 
00668     /* Get PCI bus data */
00669     BusData = BusHandler->BusData;
00670     SlotNumber.u.AsULONG = (*pResourceList)->SlotNumber;
00671 
00672     /* Get the IRQ supported range */
00673     Status = BusData->GetIrqRange(BusHandler, RootHandler, SlotNumber, &Interrupt);
00674     if (!NT_SUCCESS(Status)) return Status;
00675 #ifndef _MINIHAL_
00676     /* Handle the /PCILOCK feature */
00677     if (HalpPciLockSettings)
00678     {
00679         /* /PCILOCK is not yet supported */
00680         UNIMPLEMENTED;
00681         while (TRUE);
00682     }
00683 #endif
00684     /* Now create the correct resource list based on the supported bus ranges */
00685 #if 0
00686     Status = HaliAdjustResourceListRange(BusHandler->BusAddresses,
00687                                          Interrupt,
00688                                          pResourceList);
00689 #else
00690     DPRINT1("HAL: No PCI Resource Adjustment done! Hardware may malfunction\n");
00691     Status = STATUS_SUCCESS;
00692 #endif
00693 
00694     /* Return to caller */
00695     ExFreePool(Interrupt);
00696     return Status;
00697 }
00698 
00699 NTSTATUS
00700 NTAPI
00701 HalpAssignPCISlotResources(IN PBUS_HANDLER BusHandler,
00702                            IN PBUS_HANDLER RootHandler,
00703                            IN PUNICODE_STRING RegistryPath,
00704                            IN PUNICODE_STRING DriverClassName OPTIONAL,
00705                            IN PDRIVER_OBJECT DriverObject,
00706                            IN PDEVICE_OBJECT DeviceObject OPTIONAL,
00707                            IN ULONG Slot,
00708                            IN OUT PCM_RESOURCE_LIST *AllocatedResources)
00709 {
00710     PCI_COMMON_CONFIG PciConfig;
00711     SIZE_T Address;
00712     ULONG ResourceCount;
00713     ULONG Size[PCI_TYPE0_ADDRESSES];
00714     NTSTATUS Status = STATUS_SUCCESS;
00715     UCHAR Offset;
00716     PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
00717     PCI_SLOT_NUMBER SlotNumber;
00718     ULONG WriteBuffer;
00719     DPRINT1("WARNING: PCI Slot Resource Assignment is FOOBAR\n");
00720 
00721     /* FIXME: Should handle 64-bit addresses */
00722 
00723     /* Read configuration data */
00724     SlotNumber.u.AsULONG = Slot;
00725     HalpReadPCIConfig(BusHandler, SlotNumber, &PciConfig, 0, PCI_COMMON_HDR_LENGTH);
00726 
00727     /* Check if we read it correctly */
00728     if (PciConfig.VendorID == PCI_INVALID_VENDORID)
00729         return STATUS_NO_SUCH_DEVICE;
00730 
00731     /* Read the PCI configuration space for the device and store base address and
00732     size information in temporary storage. Count the number of valid base addresses */
00733     ResourceCount = 0;
00734     for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
00735     {
00736         if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address])
00737             PciConfig.u.type0.BaseAddresses[Address] = 0;
00738 
00739         /* Memory resource */
00740         if (0 != PciConfig.u.type0.BaseAddresses[Address])
00741         {
00742             ResourceCount++;
00743 
00744             Offset = (UCHAR)FIELD_OFFSET(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
00745 
00746             /* Write 0xFFFFFFFF there */
00747             WriteBuffer = 0xffffffff;
00748             HalpWritePCIConfig(BusHandler, SlotNumber, &WriteBuffer, Offset, sizeof(ULONG));
00749 
00750             /* Read that figure back from the config space */
00751             HalpReadPCIConfig(BusHandler, SlotNumber, &Size[Address], Offset, sizeof(ULONG));
00752 
00753             /* Write back initial value */
00754             HalpWritePCIConfig(BusHandler, SlotNumber, &PciConfig.u.type0.BaseAddresses[Address], Offset, sizeof(ULONG));
00755         }
00756     }
00757 
00758     /* Interrupt resource */
00759     if (0 != PciConfig.u.type0.InterruptPin &&
00760         0 != PciConfig.u.type0.InterruptLine &&
00761         0xFF != PciConfig.u.type0.InterruptLine)
00762         ResourceCount++;
00763 
00764     /* Allocate output buffer and initialize */
00765     *AllocatedResources = ExAllocatePoolWithTag(
00766         PagedPool,
00767         sizeof(CM_RESOURCE_LIST) +
00768         (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
00769         TAG_HAL);
00770 
00771     if (NULL == *AllocatedResources)
00772         return STATUS_NO_MEMORY;
00773 
00774     (*AllocatedResources)->Count = 1;
00775     (*AllocatedResources)->List[0].InterfaceType = PCIBus;
00776     (*AllocatedResources)->List[0].BusNumber = BusHandler->BusNumber;
00777     (*AllocatedResources)->List[0].PartialResourceList.Version = 1;
00778     (*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
00779     (*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount;
00780     Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
00781 
00782     /* Store configuration information */
00783     for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
00784     {
00785         if (0 != PciConfig.u.type0.BaseAddresses[Address])
00786         {
00787             if (PCI_ADDRESS_MEMORY_SPACE ==
00788                 (PciConfig.u.type0.BaseAddresses[Address] & 0x1))
00789             {
00790                 Descriptor->Type = CmResourceTypeMemory;
00791                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
00792                 Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;             /* FIXME Just a guess */
00793                 Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_ADDRESS_MEMORY_ADDRESS_MASK);
00794                 Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_ADDRESS_MEMORY_ADDRESS_MASK);
00795             }
00796             else if (PCI_ADDRESS_IO_SPACE ==
00797                 (PciConfig.u.type0.BaseAddresses[Address] & 0x1))
00798             {
00799                 Descriptor->Type = CmResourceTypePort;
00800                 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
00801                 Descriptor->Flags = CM_RESOURCE_PORT_IO;                       /* FIXME Just a guess */
00802                 Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_ADDRESS_IO_ADDRESS_MASK;
00803                 Descriptor->u.Port.Length = PciSize(Size[Address], PCI_ADDRESS_IO_ADDRESS_MASK & 0xffff);
00804             }
00805             else
00806             {
00807                 ASSERT(FALSE);
00808                 return STATUS_UNSUCCESSFUL;
00809             }
00810             Descriptor++;
00811         }
00812     }
00813 
00814     if (0 != PciConfig.u.type0.InterruptPin &&
00815         0 != PciConfig.u.type0.InterruptLine &&
00816         0xFF != PciConfig.u.type0.InterruptLine)
00817     {
00818         Descriptor->Type = CmResourceTypeInterrupt;
00819         Descriptor->ShareDisposition = CmResourceShareShared;          /* FIXME Just a guess */
00820         Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;     /* FIXME Just a guess */
00821         Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
00822         Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
00823         Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
00824 
00825         Descriptor++;
00826     }
00827 
00828     ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount);
00829 
00830     /* FIXME: Should store the resources in the registry resource map */
00831 
00832     return Status;
00833 }
00834 
00835 ULONG
00836 NTAPI
00837 HaliPciInterfaceReadConfig(IN PBUS_HANDLER RootBusHandler,
00838                            IN ULONG BusNumber,
00839                            IN PCI_SLOT_NUMBER SlotNumber,
00840                            IN PVOID Buffer,
00841                            IN ULONG Offset,
00842                            IN ULONG Length)
00843 {
00844     BUS_HANDLER BusHandler;
00845 
00846     /* Setup fake PCI Bus handler */
00847     RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
00848     BusHandler.BusNumber = BusNumber;
00849 
00850     /* Read configuration data */
00851     HalpReadPCIConfig(&BusHandler, SlotNumber, Buffer, Offset, Length);
00852 
00853     /* Return length */
00854     return Length;
00855 }
00856 
00857 PPCI_REGISTRY_INFO_INTERNAL
00858 NTAPI
00859 INIT_FUNCTION
00860 HalpQueryPciRegistryInfo(VOID)
00861 {
00862 #ifndef _MINIHAL_
00863     WCHAR NameBuffer[8];
00864     OBJECT_ATTRIBUTES  ObjectAttributes;
00865     UNICODE_STRING KeyName, ConfigName, IdentName;
00866     HANDLE KeyHandle, BusKeyHandle, CardListHandle;
00867     NTSTATUS Status;
00868     UCHAR KeyBuffer[sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + 100];
00869     PKEY_VALUE_FULL_INFORMATION ValueInfo = (PVOID)KeyBuffer;
00870     UCHAR PartialKeyBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
00871                            sizeof(PCI_CARD_DESCRIPTOR)];
00872     PKEY_VALUE_PARTIAL_INFORMATION PartialValueInfo = (PVOID)PartialKeyBuffer;
00873     KEY_FULL_INFORMATION KeyInformation;
00874     ULONG ResultLength;
00875     PWSTR Tag;
00876     ULONG i, ElementCount;
00877     PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
00878     PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
00879     PPCI_REGISTRY_INFO PciRegInfo;
00880     PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
00881     PPCI_CARD_DESCRIPTOR CardDescriptor;
00882 
00883     /* Setup the object attributes for the key */
00884     RtlInitUnicodeString(&KeyName,
00885                          L"\\Registry\\Machine\\Hardware\\Description\\"
00886                          L"System\\MultiFunctionAdapter");
00887     InitializeObjectAttributes(&ObjectAttributes,
00888                                &KeyName,
00889                                OBJ_CASE_INSENSITIVE,
00890                                NULL,
00891                                NULL);
00892 
00893     /* Open the key */
00894     Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
00895     if (!NT_SUCCESS(Status)) return NULL;
00896 
00897     /* Setup the receiving string */
00898     KeyName.Buffer = NameBuffer;
00899     KeyName.MaximumLength = sizeof(NameBuffer);
00900 
00901     /* Setup the configuration and identifier key names */
00902     RtlInitUnicodeString(&ConfigName, L"Configuration Data");
00903     RtlInitUnicodeString(&IdentName, L"Identifier");
00904 
00905     /* Keep looping for each ID */
00906     for (i = 0; TRUE; i++)
00907     {
00908         /* Setup the key name */
00909         RtlIntegerToUnicodeString(i, 10, &KeyName);
00910         InitializeObjectAttributes(&ObjectAttributes,
00911                                    &KeyName,
00912                                    OBJ_CASE_INSENSITIVE,
00913                                    KeyHandle,
00914                                    NULL);
00915 
00916         /* Open it */
00917         Status = ZwOpenKey(&BusKeyHandle, KEY_READ, &ObjectAttributes);
00918         if (!NT_SUCCESS(Status))
00919         {
00920             /* None left, fail */
00921             ZwClose(KeyHandle);
00922             return NULL;
00923         }
00924 
00925         /* Read the registry data */
00926         Status = ZwQueryValueKey(BusKeyHandle,
00927                                  &IdentName,
00928                                  KeyValueFullInformation,
00929                                  ValueInfo,
00930                                  sizeof(KeyBuffer),
00931                                  &ResultLength);
00932         if (!NT_SUCCESS(Status))
00933         {
00934             /* Failed, try the next one */
00935             ZwClose(BusKeyHandle);
00936             continue;
00937         }
00938 
00939         /* Get the PCI Tag and validate it */
00940         Tag = (PWSTR)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
00941         if ((Tag[0] != L'P') ||
00942             (Tag[1] != L'C') ||
00943             (Tag[2] != L'I') ||
00944             (Tag[3]))
00945         {
00946             /* Not a valid PCI entry, skip it */
00947             ZwClose(BusKeyHandle);
00948             continue;
00949         }
00950 
00951         /* Now read our PCI structure */
00952         Status = ZwQueryValueKey(BusKeyHandle,
00953                                  &ConfigName,
00954                                  KeyValueFullInformation,
00955                                  ValueInfo,
00956                                  sizeof(KeyBuffer),
00957                                  &ResultLength);
00958         ZwClose(BusKeyHandle);
00959         if (!NT_SUCCESS(Status)) continue;
00960 
00961         /* We read it OK! Get the actual resource descriptors */
00962         FullDescriptor  = (PCM_FULL_RESOURCE_DESCRIPTOR)
00963                           ((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
00964         PartialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
00965                             ((ULONG_PTR)FullDescriptor->
00966                                         PartialResourceList.PartialDescriptors);
00967 
00968         /* Check if this is our PCI Registry Information */
00969         if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
00970         {
00971             /* It is, stop searching */
00972             break;
00973         }
00974     }
00975 
00976     /* Close the key */
00977     ZwClose(KeyHandle);
00978 
00979     /* Save the PCI information for later */
00980     PciRegInfo = (PPCI_REGISTRY_INFO)(PartialDescriptor + 1);
00981 
00982     /* Assume no Card List entries */
00983     ElementCount = 0;
00984 
00985     /* Set up for checking the PCI Card List key */
00986     RtlInitUnicodeString(&KeyName,
00987                          L"\\Registry\\Machine\\System\\CurrentControlSet\\"
00988                          L"Control\\PnP\\PCI\\CardList");
00989     InitializeObjectAttributes(&ObjectAttributes,
00990                                &KeyName,
00991                                OBJ_CASE_INSENSITIVE,
00992                                NULL,
00993                                NULL);
00994 
00995     /* Attempt to open it */
00996     Status = ZwOpenKey(&CardListHandle, KEY_READ, &ObjectAttributes);
00997     if (NT_SUCCESS(Status))
00998     {
00999         /* It exists, so let's query it */
01000         Status = ZwQueryKey(CardListHandle,
01001                             KeyFullInformation,
01002                             &KeyInformation,
01003                             sizeof(KEY_FULL_INFORMATION),
01004                             &ResultLength);
01005         if (!NT_SUCCESS(Status))
01006         {
01007             /* Failed to query, so no info */
01008             PciRegistryInfo = NULL;
01009         }
01010         else
01011         {
01012             /* Allocate the full structure */
01013             PciRegistryInfo =
01014                 ExAllocatePoolWithTag(NonPagedPool,
01015                                       sizeof(PCI_REGISTRY_INFO_INTERNAL) +
01016                                       (KeyInformation.Values *
01017                                        sizeof(PCI_CARD_DESCRIPTOR)),
01018                                        TAG_HAL);
01019             if (PciRegistryInfo)
01020             {
01021                 /* Get the first card descriptor entry */
01022                 CardDescriptor = (PPCI_CARD_DESCRIPTOR)(PciRegistryInfo + 1);
01023 
01024                 /* Loop all the values */
01025                 for (i = 0; i < KeyInformation.Values; i++)
01026                 {
01027                     /* Attempt to get the value */
01028                     Status = ZwEnumerateValueKey(CardListHandle,
01029                                                  i,
01030                                                  KeyValuePartialInformation,
01031                                                  PartialValueInfo,
01032                                                  sizeof(PartialKeyBuffer),
01033                                                  &ResultLength);
01034                     if (!NT_SUCCESS(Status))
01035                     {
01036                         /* Something went wrong, stop the search */
01037                         break;
01038                     }
01039 
01040                     /* Make sure it is correctly sized */
01041                     if (PartialValueInfo->DataLength == sizeof(PCI_CARD_DESCRIPTOR))
01042                     {
01043                         /* Sure is, copy it over */
01044                         *CardDescriptor = *(PPCI_CARD_DESCRIPTOR)
01045                                            PartialValueInfo->Data;
01046 
01047                         /* One more Card List entry */
01048                         ElementCount++;
01049 
01050                         /* Move to the next descriptor */
01051                         CardDescriptor = (CardDescriptor + 1);
01052                     }
01053                 }
01054             }
01055         }
01056 
01057         /* Close the Card List key */
01058         ZwClose(CardListHandle);
01059     }
01060     else
01061     {
01062        /* No key, no Card List */
01063        PciRegistryInfo = NULL;
01064     }
01065 
01066     /* Check if we failed to get the full structure */
01067     if (!PciRegistryInfo)
01068     {
01069         /* Just allocate the basic structure then */
01070         PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool,
01071                                                 sizeof(PCI_REGISTRY_INFO_INTERNAL),
01072                                                 TAG_HAL);
01073         if (!PciRegistryInfo) return NULL;
01074     }
01075 
01076     /* Save the info we got */
01077     PciRegistryInfo->MajorRevision = PciRegInfo->MajorRevision;
01078     PciRegistryInfo->MinorRevision = PciRegInfo->MinorRevision;
01079     PciRegistryInfo->NoBuses = PciRegInfo->NoBuses;
01080     PciRegistryInfo->HardwareMechanism = PciRegInfo->HardwareMechanism;
01081     PciRegistryInfo->ElementCount = ElementCount;
01082 
01083     /* Return it */
01084     return PciRegistryInfo;
01085 #else
01086     return NULL;
01087 #endif
01088 }
01089 
01090 VOID
01091 NTAPI
01092 INIT_FUNCTION
01093 HalpInitializePciStubs(VOID)
01094 {
01095     PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
01096     UCHAR PciType;
01097     PPCIPBUSDATA BusData = (PPCIPBUSDATA)HalpFakePciBusHandler.BusData;
01098     ULONG i;
01099     PCI_SLOT_NUMBER j;
01100     ULONG VendorId = 0;
01101     ULONG MaxPciBusNumber;
01102 
01103     /* Query registry information */
01104     PciRegistryInfo = HalpQueryPciRegistryInfo();
01105     if (!PciRegistryInfo)
01106     {
01107         /* Assume type 1 */
01108         PciType = 1;
01109 
01110         /* Force a manual bus scan later */
01111         MaxPciBusNumber = MAXULONG;
01112     }
01113     else
01114     {
01115         /* Get the PCI type */
01116         PciType = PciRegistryInfo->HardwareMechanism & 0xF;
01117 
01118         /* Get MaxPciBusNumber and make it 0-based */
01119         MaxPciBusNumber = PciRegistryInfo->NoBuses - 1;
01120 
01121         /* Free the info structure */
01122         ExFreePoolWithTag(PciRegistryInfo, TAG_HAL);
01123     }
01124 
01125     /* Initialize the PCI lock */
01126     KeInitializeSpinLock(&HalpPCIConfigLock);
01127 
01128     /* Check the type of PCI bus */
01129     switch (PciType)
01130     {
01131         /* Type 1 PCI Bus */
01132         case 1:
01133 
01134             /* Copy the Type 1 handler data */
01135             RtlCopyMemory(&PCIConfigHandler,
01136                           &PCIConfigHandlerType1,
01137                           sizeof(PCIConfigHandler));
01138 
01139             /* Set correct I/O Ports */
01140             BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT;
01141             BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT;
01142             break;
01143 
01144         /* Type 2 PCI Bus */
01145         case 2:
01146 
01147             /* Copy the Type 2 handler data */
01148             RtlCopyMemory(&PCIConfigHandler,
01149                           &PCIConfigHandlerType2,
01150                           sizeof (PCIConfigHandler));
01151 
01152             /* Set correct I/O Ports */
01153             BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT;
01154             BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT;
01155             BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE;
01156 
01157             /* Only 16 devices supported, not 32 */
01158             BusData->MaxDevice = 16;
01159             break;
01160 
01161         default:
01162 
01163             /* Invalid type */
01164             DbgPrint("HAL: Unknown PCI type\n");
01165     }
01166 
01167     /* Run a forced bus scan if needed */
01168     if (MaxPciBusNumber == MAXULONG)
01169     {
01170         /* Initialize the max bus number to 0xFF */
01171         HalpMaxPciBus = 0xFF;
01172 
01173         /* Initialize the counter */
01174         MaxPciBusNumber = 0;
01175 
01176         /* Loop all possible buses */
01177         for (i = 0; i < HalpMaxPciBus; i++)
01178         {
01179             /* Loop all devices */
01180             for (j.u.AsULONG = 0; j.u.AsULONG < BusData->MaxDevice; j.u.AsULONG++)
01181             {
01182                 /* Query the interface */
01183                 if (HaliPciInterfaceReadConfig(NULL,
01184                                                i,
01185                                                j,
01186                                                &VendorId,
01187                                                0,
01188                                                sizeof(ULONG)))
01189                 {
01190                     /* Validate the vendor ID */
01191                     if ((VendorId & 0xFFFF) != PCI_INVALID_VENDORID)
01192                     {
01193                         /* Set this as the maximum ID */
01194                         MaxPciBusNumber = i;
01195                         break;
01196                     }
01197                 }
01198             }
01199         }
01200     }
01201 
01202     /* Set the real max bus number */
01203     HalpMaxPciBus = MaxPciBusNumber;
01204 
01205     /* We're done */
01206     HalpPCIConfigInitialized = TRUE;
01207 }
01208 
01209 /* EOF */
01210 

Generated on Thu May 24 2012 04:29:22 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.