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

device.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/device.c
00005  * PURPOSE:         Device Management
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 /* FUNCTIONS ******************************************************************/
00018 
00019 VOID
00020 NTAPI
00021 Device_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
00022 {
00023     PPCI_COMMON_HEADER PciData;
00024     PIO_RESOURCE_DESCRIPTOR IoDescriptor;
00025     PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor;
00026     PPCI_FUNCTION_RESOURCES Resources;
00027     PULONG BarArray;
00028     ULONG Bar, BarMask, i;
00029 
00030     /* Get variables from context */
00031     PciData = Context->Current;
00032     Resources = Context->PdoExtension->Resources;
00033 
00034     /* Loop all the PCI BARs */
00035     BarArray = PciData->u.type0.BaseAddresses;
00036     for (i = 0; i <= PCI_TYPE0_ADDRESSES; i++)
00037     {
00038         /* Get the resource descriptor and limit descriptor for this BAR */
00039         CmDescriptor = &Resources->Current[i];
00040         IoDescriptor = &Resources->Limit[i];
00041 
00042         /* Build the resource descriptor based on the limit descriptor */
00043         CmDescriptor->Type = IoDescriptor->Type;
00044         if (CmDescriptor->Type == CmResourceTypeNull) continue;
00045         CmDescriptor->Flags = IoDescriptor->Flags;
00046         CmDescriptor->ShareDisposition = IoDescriptor->ShareDisposition;
00047         CmDescriptor->u.Generic.Start.HighPart = 0;
00048         CmDescriptor->u.Generic.Length = IoDescriptor->u.Generic.Length;
00049 
00050         /* Read the actual BAR value */
00051         Bar = BarArray[i];
00052 
00053         /* Check which BAR is being processed now */
00054         if (i != PCI_TYPE0_ADDRESSES)
00055         {
00056             /* Check if this is an I/O BAR */
00057             if (Bar & PCI_ADDRESS_IO_SPACE)
00058             {
00059                 /* Use the right mask to get the I/O port base address */
00060                 ASSERT(CmDescriptor->Type == CmResourceTypePort);
00061                 BarMask = PCI_ADDRESS_IO_ADDRESS_MASK;
00062             }
00063             else
00064             {
00065                 /* It's a RAM BAR, use the right mask to get the base address */
00066                 ASSERT(CmDescriptor->Type == CmResourceTypeMemory);
00067                 BarMask = PCI_ADDRESS_MEMORY_ADDRESS_MASK;
00068 
00069                 /* Check if it's a 64-bit BAR */
00070                 if ((Bar & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
00071                 {
00072                     /* The next BAR value is actually the high 32-bits */
00073                     CmDescriptor->u.Memory.Start.HighPart = BarArray[i + 1];
00074                 }
00075                 else if ((Bar & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_20BIT)
00076                 {
00077                     /* Legacy BAR, don't read more than 20 bits of the address */
00078                     BarMask = 0xFFFF0;
00079                 }
00080             }
00081         }
00082         else
00083         {
00084             /* Actually a ROM BAR, so read the correct register */
00085             Bar = PciData->u.type0.ROMBaseAddress;
00086 
00087             /* Apply the correct mask for ROM BARs */
00088             BarMask = PCI_ADDRESS_ROM_ADDRESS_MASK;
00089 
00090             /* Make sure it's enabled */
00091             if (!(Bar & PCI_ROMADDRESS_ENABLED))
00092             {
00093                 /* If it isn't, then a descriptor won't be built for it */
00094                 CmDescriptor->Type = CmResourceTypeNull;
00095                 continue;
00096             }
00097         }
00098 
00099         /* Now we have the right mask, read the actual address from the BAR */
00100         Bar &= BarMask;
00101         CmDescriptor->u.Memory.Start.LowPart = Bar;
00102 
00103         /* And check for invalid BAR addresses */
00104         if (!(CmDescriptor->u.Memory.Start.HighPart | Bar))
00105         {
00106             /* Skip these descriptors */
00107             CmDescriptor->Type = CmResourceTypeNull;
00108             DPRINT1("Invalid BAR\n");
00109         }
00110     }
00111 
00112     /* Also save the sub-IDs that came directly from the PCI header */
00113     Context->PdoExtension->SubsystemVendorId = PciData->u.type0.SubVendorID;
00114     Context->PdoExtension->SubsystemId = PciData->u.type0.SubSystemID;
00115 }
00116 
00117 VOID
00118 NTAPI
00119 Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
00120 {
00121     PPCI_COMMON_HEADER Current, PciData;
00122     PPCI_PDO_EXTENSION PdoExtension;
00123     PULONG BarArray;
00124     PIO_RESOURCE_DESCRIPTOR Limit;
00125     ULONG i;
00126 
00127     /* Get pointers from the context */
00128     PdoExtension = Context->PdoExtension;
00129     Current = Context->Current;
00130     PciData = Context->PciData;
00131 
00132     /* And get the array of bARs */
00133     BarArray = PciData->u.type0.BaseAddresses;
00134 
00135     /* First, check for IDE controllers that are not in native mode */
00136     if ((PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
00137         (PdoExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR) &&
00138         (PdoExtension->ProgIf & 5) != 5)
00139     {
00140         /* They should not be using any non-legacy resources */
00141         BarArray[0] = 0;
00142         BarArray[1] = 0;
00143         BarArray[2] = 0;
00144         BarArray[3] = 0;
00145     }
00146     else if ((PdoExtension->VendorId == 0x5333) &&
00147              ((PdoExtension->DeviceId == 0x88F0) ||
00148               (PdoExtension->DeviceId == 0x8880)))
00149     {
00150         /*
00151          * The problem is caused by the S3 Vision 968/868 video controller which
00152          * is used on the Diamond Stealth 64 Video 3000 series, Number Nine 9FX
00153          * motion 771, and other popular video cards, all containing a memory bug.
00154          * The 968/868 claims to require 32 MB of memory, but it actually decodes
00155          * 64 MB of memory.
00156          */
00157         for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
00158         {
00159             /* Find its 32MB RAM BAR */
00160             if (BarArray[i] == 0xFE000000)
00161             {
00162                 /* Increase it to 64MB to make sure nobody touches the buffer */
00163                 BarArray[i] = 0xFC000000;
00164                 DPRINT1("PCI - Adjusted broken S3 requirement from 32MB to 64MB\n");
00165             }
00166         }
00167     }
00168 
00169     /* Check for Cirrus Logic GD5430/5440 cards */
00170     if ((PdoExtension->VendorId == 0x1013) && (PdoExtension->DeviceId == 0xA0))
00171     {
00172         /* Check for the I/O port requirement */
00173         if (BarArray[1] == 0xFC01)
00174         {
00175             /* Check for completely bogus BAR */
00176             if (Current->u.type0.BaseAddresses[1] == 1)
00177             {
00178                 /* Ignore it */
00179                 BarArray[1] = 0;
00180                 DPRINT1("PCI - Ignored Cirrus GD54xx broken IO requirement (400 ports)\n");
00181             }
00182             else
00183             {
00184                 /* Otherwise, this BAR seems okay */
00185                 DPRINT1("PCI - Cirrus GD54xx 400 port IO requirement has a valid setting (%08x)\n",
00186                         Current->u.type0.BaseAddresses[1]);
00187             }
00188         }
00189         else if (BarArray[1])
00190         {
00191             /* Strange, the I/O BAR was not found as expected (or at all) */
00192             DPRINT1("PCI - Warning Cirrus Adapter 101300a0 has unexpected resource requirement (%08x)\n",
00193                     BarArray[1]);
00194         }
00195     }
00196 
00197     /* Finally, process all the limit descriptors */
00198     Limit = PdoExtension->Resources->Limit;
00199     for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
00200     {
00201         /* And build them based on the BARs */
00202         if (PciCreateIoDescriptorFromBarLimit(&Limit[i], &BarArray[i], FALSE))
00203         {
00204             /* This function returns TRUE if the BAR was 64-bit, handle this */
00205             ASSERT((i + 1) < PCI_TYPE0_ADDRESSES);
00206             i++;
00207             Limit[i].Type = CmResourceTypeNull;
00208         }
00209     }
00210 
00211     /* Create the last descriptor based on the ROM address */
00212     PciCreateIoDescriptorFromBarLimit(&Limit[i],
00213                                       &PciData->u.type0.ROMBaseAddress,
00214                                       TRUE);
00215 }
00216 
00217 VOID
00218 NTAPI
00219 Device_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
00220 {
00221     PPCI_COMMON_HEADER PciData;
00222     PPCI_PDO_EXTENSION PdoExtension;
00223     PULONG BarArray;
00224     ULONG i = 0;
00225 
00226     /* Get pointers from context data */
00227     PdoExtension = Context->PdoExtension;
00228     PciData = Context->PciData;
00229 
00230     /* Get the array of BARs */
00231     BarArray = PciData->u.type0.BaseAddresses;
00232 
00233     /* Check for IDE controllers that are not in native mode */
00234     if ((PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
00235         (PdoExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR) &&
00236         (PdoExtension->ProgIf & 5) != 5)
00237     {
00238         /* These controllers only use legacy resources */
00239         i = 4;
00240     }
00241 
00242     /* Set all the bits on, which will allow us to recover the limit data */
00243     for (i = 0; i < PCI_TYPE0_ADDRESSES; i++) BarArray[i] = 0xFFFFFFFF;
00244 
00245     /* Do the same for the PCI ROM BAR */
00246     PciData->u.type0.ROMBaseAddress = PCI_ADDRESS_ROM_ADDRESS_MASK;
00247 }
00248 
00249 VOID
00250 NTAPI
00251 Device_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
00252 {
00253     /* Nothing to do for devices */
00254     return;
00255 }
00256 
00257 VOID
00258 NTAPI
00259 Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
00260                                         IN PPCI_COMMON_HEADER PciData,
00261                                         IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
00262 {
00263     /* Not yet implemented */
00264     UNIMPLEMENTED;
00265     while (TRUE);
00266 }
00267 
00268 VOID
00269 NTAPI
00270 Device_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
00271                    IN PPCI_COMMON_HEADER PciData)
00272 {
00273     /* Not yet implemented */
00274     UNIMPLEMENTED;
00275     while (TRUE);
00276 }
00277 
00278 VOID
00279 NTAPI
00280 Device_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
00281                               IN PPCI_COMMON_HEADER PciData)
00282 {
00283     /* Not yet implemented */
00284     UNIMPLEMENTED;
00285     while (TRUE);
00286 }
00287 
00288 /* EOF */

Generated on Sun May 27 2012 04:21:21 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.