ReactOS 0.4.16-dev-197-g92996da
device.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/device.c
5 * PURPOSE: Device Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <pci.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS ******************************************************************/
17
18VOID
21{
22 PPCI_COMMON_HEADER PciData;
23 PIO_RESOURCE_DESCRIPTOR IoDescriptor;
26 PULONG BarArray;
27 ULONG Bar, BarMask, i;
28
29 /* Get variables from context */
30 PciData = Context->Current;
31 Resources = Context->PdoExtension->Resources;
32
33 /* Loop all the PCI BARs */
34 BarArray = PciData->u.type0.BaseAddresses;
35 for (i = 0; i <= PCI_TYPE0_ADDRESSES; i++)
36 {
37 /* Get the resource descriptor and limit descriptor for this BAR */
38 CmDescriptor = &Resources->Current[i];
39 IoDescriptor = &Resources->Limit[i];
40
41 /* Build the resource descriptor based on the limit descriptor */
42 CmDescriptor->Type = IoDescriptor->Type;
43 if (CmDescriptor->Type == CmResourceTypeNull) continue;
44 CmDescriptor->Flags = IoDescriptor->Flags;
45 CmDescriptor->ShareDisposition = IoDescriptor->ShareDisposition;
46 CmDescriptor->u.Generic.Start.HighPart = 0;
47 CmDescriptor->u.Generic.Length = IoDescriptor->u.Generic.Length;
48
49 /* Check if we're handling PCI BARs, or the ROM BAR */
51 {
52 /* Read the actual BAR value */
53 Bar = BarArray[i];
54
55 /* Check if this is an I/O BAR */
57 {
58 /* Use the right mask to get the I/O port base address */
59 ASSERT(CmDescriptor->Type == CmResourceTypePort);
61 }
62 else
63 {
64 /* It's a RAM BAR, use the right mask to get the base address */
65 ASSERT(CmDescriptor->Type == CmResourceTypeMemory);
67
68 /* Check if it's a 64-bit BAR */
70 {
71 /* The next BAR value is actually the high 32-bits */
72 CmDescriptor->u.Memory.Start.HighPart = BarArray[i + 1];
73 }
75 {
76 /* Legacy BAR, don't read more than 20 bits of the address */
77 BarMask = 0xFFFF0;
78 }
79 }
80 }
81 else
82 {
83 /* Actually a ROM BAR, so read the correct register */
84 Bar = PciData->u.type0.ROMBaseAddress;
85
86 /* Apply the correct mask for ROM BARs */
88
89 /* Make sure it's enabled */
91 {
92 /* If it isn't, then a descriptor won't be built for it */
93 CmDescriptor->Type = CmResourceTypeNull;
94 continue;
95 }
96 }
97
98 /* Now we have the right mask, read the actual address from the BAR */
99 Bar &= BarMask;
100 CmDescriptor->u.Memory.Start.LowPart = Bar;
101
102 /* And check for invalid BAR addresses */
103 if (!(CmDescriptor->u.Memory.Start.HighPart | Bar))
104 {
105 /* Skip these descriptors */
106 CmDescriptor->Type = CmResourceTypeNull;
107 DPRINT1("Invalid BAR\n");
108 }
109 }
110
111 /* Also save the sub-IDs that came directly from the PCI header */
112 Context->PdoExtension->SubsystemVendorId = PciData->u.type0.SubVendorID;
113 Context->PdoExtension->SubsystemId = PciData->u.type0.SubSystemID;
114}
115
116VOID
117NTAPI
119{
120 PPCI_COMMON_HEADER Current, PciData;
122 PULONG BarArray;
124 ULONG i;
125
126 /* Get pointers from the context */
127 PdoExtension = Context->PdoExtension;
128 Current = Context->Current;
129 PciData = Context->PciData;
130
131 /* And get the array of bARs */
132 BarArray = PciData->u.type0.BaseAddresses;
133
134 /* First, check for IDE controllers that are not in native mode */
135 if ((PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
137 (PdoExtension->ProgIf & 5) != 5)
138 {
139 /* They should not be using any non-legacy resources */
140 BarArray[0] = 0;
141 BarArray[1] = 0;
142 BarArray[2] = 0;
143 BarArray[3] = 0;
144 }
145 else if ((PdoExtension->VendorId == 0x5333) &&
146 ((PdoExtension->DeviceId == 0x88F0) ||
147 (PdoExtension->DeviceId == 0x8880)))
148 {
149 /*
150 * The problem is caused by the S3 Vision 968/868 video controller which
151 * is used on the Diamond Stealth 64 Video 3000 series, Number Nine 9FX
152 * motion 771, and other popular video cards, all containing a memory bug.
153 * The 968/868 claims to require 32 MB of memory, but it actually decodes
154 * 64 MB of memory.
155 */
156 for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
157 {
158 /* Find its 32MB RAM BAR */
159 if (BarArray[i] == 0xFE000000)
160 {
161 /* Increase it to 64MB to make sure nobody touches the buffer */
162 BarArray[i] = 0xFC000000;
163 DPRINT1("PCI - Adjusted broken S3 requirement from 32MB to 64MB\n");
164 }
165 }
166 }
167
168 /* Check for Cirrus Logic GD5430/5440 cards */
169 if ((PdoExtension->VendorId == 0x1013) && (PdoExtension->DeviceId == 0xA0))
170 {
171 /* Check for the I/O port requirement */
172 if (BarArray[1] == 0xFC01)
173 {
174 /* Check for completely bogus BAR */
175 if (Current->u.type0.BaseAddresses[1] == 1)
176 {
177 /* Ignore it */
178 BarArray[1] = 0;
179 DPRINT1("PCI - Ignored Cirrus GD54xx broken IO requirement (400 ports)\n");
180 }
181 else
182 {
183 /* Otherwise, this BAR seems okay */
184 DPRINT1("PCI - Cirrus GD54xx 400 port IO requirement has a valid setting (%08x)\n",
185 Current->u.type0.BaseAddresses[1]);
186 }
187 }
188 else if (BarArray[1])
189 {
190 /* Strange, the I/O BAR was not found as expected (or at all) */
191 DPRINT1("PCI - Warning Cirrus Adapter 101300a0 has unexpected resource requirement (%08x)\n",
192 BarArray[1]);
193 }
194 }
195
196 /* Finally, process all the limit descriptors */
197 Limit = PdoExtension->Resources->Limit;
198 for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
199 {
200 /* And build them based on the BARs */
201 if (PciCreateIoDescriptorFromBarLimit(&Limit[i], &BarArray[i], FALSE))
202 {
203 /* This function returns TRUE if the BAR was 64-bit, handle this */
205 i++;
206 Limit[i].Type = CmResourceTypeNull;
207 }
208 }
209
210 /* Create the last descriptor based on the ROM address */
212 &PciData->u.type0.ROMBaseAddress,
213 TRUE);
214}
215
216VOID
217NTAPI
219{
220 PPCI_COMMON_HEADER PciData;
222 PULONG BarArray;
223 ULONG i = 0;
224
225 /* Get pointers from context data */
226 PdoExtension = Context->PdoExtension;
227 PciData = Context->PciData;
228
229 /* Get the array of BARs */
230 BarArray = PciData->u.type0.BaseAddresses;
231
232 /* Check for IDE controllers that are not in native mode */
233 if ((PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
235 (PdoExtension->ProgIf & 5) != 5)
236 {
237 /* These controllers only use legacy resources */
238 i = 4;
239 }
240
241 /* Set all the bits on, which will allow us to recover the limit data */
242 for (i = 0; i < PCI_TYPE0_ADDRESSES; i++) BarArray[i] = 0xFFFFFFFF;
243
244 /* Do the same for the PCI ROM BAR */
245 PciData->u.type0.ROMBaseAddress = PCI_ADDRESS_ROM_ADDRESS_MASK;
246}
247
248VOID
249NTAPI
251{
253 /* Nothing to do for devices */
254 return;
255}
256
257VOID
258NTAPI
260 IN PPCI_COMMON_HEADER PciData,
261 IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
262{
264 UNREFERENCED_PARAMETER(PciData);
265 UNREFERENCED_PARAMETER(IoDescriptor);
266 /* Not yet implemented */
268}
269
270VOID
271NTAPI
273 IN PPCI_COMMON_HEADER PciData)
274{
276 UNREFERENCED_PARAMETER(PciData);
277 /* Not yet implemented */
279}
280
281VOID
282NTAPI
284 IN PPCI_COMMON_HEADER PciData)
285{
287 UNREFERENCED_PARAMETER(PciData);
288 /* Not yet implemented */
290}
291
292/* EOF */
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID NTAPI Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: device.c:259
VOID NTAPI Device_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: device.c:283
VOID NTAPI Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:118
VOID NTAPI Device_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:218
VOID NTAPI Device_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:20
VOID NTAPI Device_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: device.c:272
VOID NTAPI Device_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:250
BOOLEAN NTAPI PciCreateIoDescriptorFromBarLimit(PIO_RESOURCE_DESCRIPTOR ResourceDescriptor, IN PULONG BarArray, IN BOOLEAN Rom)
Definition: utils.c:1175
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
@ PdoExtension
Definition: precomp.h:49
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CmResourceTypeNull
Definition: hwresource.cpp:122
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define ASSERT(a)
Definition: mode.c:44
void Bar(void)
Definition: terminate.cpp:70
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@396 Memory
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@392 Generic
union _IO_RESOURCE_DESCRIPTOR::@2051 u
struct _IO_RESOURCE_DESCRIPTOR::@2051::@2056 Generic
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define PCI_TYPE_64BIT
Definition: iotypes.h:4239
#define PCI_ADDRESS_IO_ADDRESS_MASK
Definition: iotypes.h:4233
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3500
#define PCI_CLASS_MASS_STORAGE_CTLR
Definition: iotypes.h:4104
#define PCI_ADDRESS_IO_SPACE
Definition: iotypes.h:4230
#define PCI_SUBCLASS_MSC_IDE_CTLR
Definition: iotypes.h:4129
#define PCI_TYPE_20BIT
Definition: iotypes.h:4238
#define PCI_ADDRESS_ROM_ADDRESS_MASK
Definition: iotypes.h:4235
#define PCI_ADDRESS_MEMORY_ADDRESS_MASK
Definition: iotypes.h:4234
#define PCI_ROMADDRESS_ENABLED
Definition: iotypes.h:4241
#define PCI_ADDRESS_MEMORY_TYPE_MASK
Definition: iotypes.h:4231
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:304