Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevice.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
1.7.6.1
|