@@ -164,41 +164,67 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
164
164
165
165
#define PCI_COMMAND_DECODE_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
166
166
167
+ /**
168
+ * __pci_size_bars - Read the raw BAR mask for a range of PCI BARs
169
+ * @dev: the PCI device
170
+ * @count: number of BARs to size
171
+ * @pos: starting config space position
172
+ * @sizes: array to store mask values
173
+ * @rom: indicate whether to use ROM mask, which avoids enabling ROM BARs
174
+ *
175
+ * Provided @sizes array must be sufficiently sized to store results for
176
+ * @count u32 BARs. Caller is responsible for disabling decode to specified
177
+ * BAR range around calling this function. This function is intended to avoid
178
+ * disabling decode around sizing each BAR individually, which can result in
179
+ * non-trivial overhead in virtualized environments with very large PCI BARs.
180
+ */
181
+ static void __pci_size_bars (struct pci_dev * dev , int count ,
182
+ unsigned int pos , u32 * sizes , bool rom )
183
+ {
184
+ u32 orig , mask = rom ? PCI_ROM_ADDRESS_MASK : ~0 ;
185
+ int i ;
186
+
187
+ for (i = 0 ; i < count ; i ++ , pos += 4 , sizes ++ ) {
188
+ pci_read_config_dword (dev , pos , & orig );
189
+ pci_write_config_dword (dev , pos , mask );
190
+ pci_read_config_dword (dev , pos , sizes );
191
+ pci_write_config_dword (dev , pos , orig );
192
+ }
193
+ }
194
+
195
+ void __pci_size_stdbars (struct pci_dev * dev , int count ,
196
+ unsigned int pos , u32 * sizes )
197
+ {
198
+ __pci_size_bars (dev , count , pos , sizes , false);
199
+ }
200
+
201
+ static void __pci_size_rom (struct pci_dev * dev , unsigned int pos , u32 * sizes )
202
+ {
203
+ __pci_size_bars (dev , 1 , pos , sizes , true);
204
+ }
205
+
167
206
/**
168
207
* __pci_read_base - Read a PCI BAR
169
208
* @dev: the PCI device
170
209
* @type: type of the BAR
171
210
* @res: resource buffer to be filled in
172
211
* @pos: BAR position in the config space
212
+ * @sizes: array of one or more pre-read BAR masks
173
213
*
174
214
* Returns 1 if the BAR is 64-bit, or 0 if 32-bit.
175
215
*/
176
216
int __pci_read_base (struct pci_dev * dev , enum pci_bar_type type ,
177
- struct resource * res , unsigned int pos )
217
+ struct resource * res , unsigned int pos , u32 * sizes )
178
218
{
179
- u32 l = 0 , sz = 0 , mask ;
219
+ u32 l = 0 , sz ;
180
220
u64 l64 , sz64 , mask64 ;
181
- u16 orig_cmd ;
182
221
struct pci_bus_region region , inverted_region ;
183
222
const char * res_name = pci_resource_name (dev , res - dev -> resource );
184
223
185
- mask = type ? PCI_ROM_ADDRESS_MASK : ~0 ;
186
-
187
- /* No printks while decoding is disabled! */
188
- if (!dev -> mmio_always_on ) {
189
- pci_read_config_word (dev , PCI_COMMAND , & orig_cmd );
190
- if (orig_cmd & PCI_COMMAND_DECODE_ENABLE ) {
191
- pci_write_config_word (dev , PCI_COMMAND ,
192
- orig_cmd & ~PCI_COMMAND_DECODE_ENABLE );
193
- }
194
- }
195
-
196
224
res -> name = pci_name (dev );
197
225
198
226
pci_read_config_dword (dev , pos , & l );
199
- pci_write_config_dword (dev , pos , l | mask );
200
- pci_read_config_dword (dev , pos , & sz );
201
- pci_write_config_dword (dev , pos , l );
227
+ sz = sizes [0 ];
202
228
203
229
/*
204
230
* All bits set in sz means the device isn't working properly.
@@ -238,18 +264,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
238
264
239
265
if (res -> flags & IORESOURCE_MEM_64 ) {
240
266
pci_read_config_dword (dev , pos + 4 , & l );
241
- pci_write_config_dword (dev , pos + 4 , ~0 );
242
- pci_read_config_dword (dev , pos + 4 , & sz );
243
- pci_write_config_dword (dev , pos + 4 , l );
267
+ sz = sizes [1 ];
244
268
245
269
l64 |= ((u64 )l << 32 );
246
270
sz64 |= ((u64 )sz << 32 );
247
271
mask64 |= ((u64 )~0 << 32 );
248
272
}
249
273
250
- if (!dev -> mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE ))
251
- pci_write_config_word (dev , PCI_COMMAND , orig_cmd );
252
-
253
274
if (!sz64 )
254
275
goto fail ;
255
276
@@ -320,7 +341,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
320
341
321
342
static void pci_read_bases (struct pci_dev * dev , unsigned int howmany , int rom )
322
343
{
344
+ u32 rombar , stdbars [PCI_STD_NUM_BARS ];
323
345
unsigned int pos , reg ;
346
+ u16 orig_cmd ;
347
+
348
+ BUILD_BUG_ON (howmany > PCI_STD_NUM_BARS );
324
349
325
350
if (dev -> non_compliant_bars )
326
351
return ;
@@ -329,18 +354,36 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
329
354
if (dev -> is_virtfn )
330
355
return ;
331
356
357
+ /* No printks while decoding is disabled! */
358
+ if (!dev -> mmio_always_on ) {
359
+ pci_read_config_word (dev , PCI_COMMAND , & orig_cmd );
360
+ if (orig_cmd & PCI_COMMAND_DECODE_ENABLE ) {
361
+ pci_write_config_word (dev , PCI_COMMAND ,
362
+ orig_cmd & ~PCI_COMMAND_DECODE_ENABLE );
363
+ }
364
+ }
365
+
366
+ __pci_size_stdbars (dev , howmany , PCI_BASE_ADDRESS_0 , stdbars );
367
+ if (rom )
368
+ __pci_size_rom (dev , rom , & rombar );
369
+
370
+ if (!dev -> mmio_always_on &&
371
+ (orig_cmd & PCI_COMMAND_DECODE_ENABLE ))
372
+ pci_write_config_word (dev , PCI_COMMAND , orig_cmd );
373
+
332
374
for (pos = 0 ; pos < howmany ; pos ++ ) {
333
375
struct resource * res = & dev -> resource [pos ];
334
376
reg = PCI_BASE_ADDRESS_0 + (pos << 2 );
335
- pos += __pci_read_base (dev , pci_bar_unknown , res , reg );
377
+ pos += __pci_read_base (dev , pci_bar_unknown ,
378
+ res , reg , & stdbars [pos ]);
336
379
}
337
380
338
381
if (rom ) {
339
382
struct resource * res = & dev -> resource [PCI_ROM_RESOURCE ];
340
383
dev -> rom_base_reg = rom ;
341
384
res -> flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
342
385
IORESOURCE_READONLY | IORESOURCE_SIZEALIGN ;
343
- __pci_read_base (dev , pci_bar_mem32 , res , rom );
386
+ __pci_read_base (dev , pci_bar_mem32 , res , rom , & rombar );
344
387
}
345
388
}
346
389
0 commit comments