PCI helper find_cap
[akaros.git] / kern / arch / x86 / pci.c
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * See LICENSE for details.
3  *
4  * Barret Rhoden <brho@cs.berkeley.edu>
5  * Original by Paul Pearce <pearce@eecs.berkeley.edu> */
6
7 #include <arch/x86.h>
8 #include <arch/pci.h>
9 #include <trap.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <kmalloc.h>
14 #include <arch/pci_defs.h>
15 #include <ros/errno.h>
16
17 /* List of all discovered devices */
18 struct pcidev_stailq pci_devices = STAILQ_HEAD_INITIALIZER(pci_devices);
19
20 /* PCI accesses are two-stage PIO, which need to complete atomically */
21 spinlock_t pci_lock = SPINLOCK_INITIALIZER_IRQSAVE;
22
23 static char STD_PCI_DEV[] = "Standard PCI Device";
24 static char PCI2PCI[] = "PCI-to-PCI Bridge";
25 static char PCI2CARDBUS[] = "PCI-Cardbus Bridge";
26
27 /* Gets any old raw bar, with some catches based on type. */
28 static uint32_t pci_getbar(struct pci_device *pcidev, unsigned int bar)
29 {
30         uint8_t type;
31         if (bar >= MAX_PCI_BAR)
32                 panic("Nonexistant bar requested!");
33         type = pcidev_read8(pcidev, PCI_HEADER_REG);
34         type &= ~0x80;  /* drop the MF bit */
35         /* Only types 0 and 1 have BARS */
36         if ((type != 0x00) && (type != 0x01))
37                 return 0;
38         /* Only type 0 has BAR2 - BAR5 */
39         if ((bar > 1) && (type != 0x00))
40                 return 0;
41         return pcidev_read32(pcidev, PCI_BAR0_STD + bar * PCI_BAR_OFF);
42 }
43
44 /* Determines if a given bar is IO (o/w, it's mem) */
45 static bool pci_is_iobar(uint32_t bar)
46 {
47         return bar & PCI_BAR_IO;
48 }
49
50 static bool pci_is_membar32(uint32_t bar)
51 {
52         if (pci_is_iobar(bar))
53                 return FALSE;
54         return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_32BIT;
55 }
56
57 static bool pci_is_membar64(uint32_t bar)
58 {
59         if (pci_is_iobar(bar))
60                 return FALSE;
61         return (bar & PCI_MEMBAR_TYPE) == PCI_MEMBAR_64BIT;
62 }
63
64 /* Helper to get the address from a membar.  Check the type beforehand */
65 static uint32_t pci_getmembar32(uint32_t bar)
66 {
67         uint8_t type = bar & PCI_MEMBAR_TYPE;
68         if (type != PCI_MEMBAR_32BIT) {
69                 warn("Unhandled PCI membar type: %02p\n", type >> 1);
70                 return 0;
71         }
72         return bar & 0xfffffff0;
73 }
74
75 /* Helper to get the address from an IObar.  Check the type beforehand */
76 static uint32_t pci_getiobar32(uint32_t bar)
77 {
78         return bar & 0xfffffffc;
79 }
80
81 /* memory bars have a little dance you go through to detect what the size of the
82  * memory region is.  for 64 bit bars, i'm assuming you only need to do this to
83  * the lower part (no device will need > 4GB, right?).
84  *
85  * Hold the dev's lock, or o/w avoid sync issues. */
86 static uint32_t __pci_membar_get_sz(struct pci_device *pcidev, int bar)
87 {
88         /* save the old value, write all 1s, invert, add 1, restore.
89          * http://wiki.osdev.org/PCI for details. */
90         uint32_t bar_off = PCI_BAR0_STD + bar * PCI_BAR_OFF;
91         uint32_t old_val = pcidev_read32(pcidev, bar_off);
92         uint32_t retval;
93         pcidev_write32(pcidev, bar_off, 0xffffffff);
94         /* Don't forget to mask the lower 3 bits! */
95         retval = pcidev_read32(pcidev, bar_off) & PCI_BAR_MEM_MASK;
96         retval = ~retval + 1;
97         pcidev_write32(pcidev, bar_off, old_val);
98         return retval;
99 }
100
101 /* process the bars.  these will tell us what address space (PIO or memory) and
102  * where the base is.  fills results into pcidev.  i don't know if you can have
103  * multiple bars with conflicting/different regions (like two separate PIO
104  * ranges).  I'm assuming you don't, and will warn if we see one. */
105 static void __pci_handle_bars(struct pci_device *pcidev)
106 {
107         uint32_t bar_val;
108         int max_bars;
109         if (pcidev->header_type == STD_PCI_DEV)
110                 max_bars = MAX_PCI_BAR;
111         else if (pcidev->header_type == PCI2PCI)
112                 max_bars = 2;
113         else
114                 max_bars = 0;
115         /* TODO: consider aborting for classes 00, 05 (memory ctlr), 06 (bridge) */
116         for (int i = 0; i < max_bars; i++) {
117                 bar_val = pci_getbar(pcidev, i);
118                 pcidev->bar[i].raw_bar = bar_val;
119                 if (!bar_val)   /* (0 denotes no valid data) */
120                         continue;
121                 if (pci_is_iobar(bar_val)) {
122                         pcidev->bar[i].pio_base = pci_getiobar32(bar_val);
123                 } else {
124                         if (pci_is_membar32(bar_val)) {
125                                 pcidev->bar[i].mmio_base32 = bar_val & PCI_BAR_MEM_MASK;
126                                 pcidev->bar[i].mmio_sz = __pci_membar_get_sz(pcidev, i);
127                         } else if (pci_is_membar64(bar_val)) {
128                                 /* 64 bit, the lower 32 are in this bar, the upper
129                                  * are in the next bar */
130                                 pcidev->bar[i].mmio_base64 = bar_val & PCI_BAR_MEM_MASK;
131                                 assert(i < max_bars - 1);
132                                 bar_val = pci_getbar(pcidev, i + 1);    /* read next bar */
133                                 /* note we don't check for IO or memsize.  the entire next bar
134                                  * is supposed to be for the upper 32 bits. */
135                                 pcidev->bar[i].mmio_base64 |= (uint64_t)bar_val << 32;
136                                 pcidev->bar[i].mmio_sz = __pci_membar_get_sz(pcidev, i);
137                                 i++;
138                         }
139                 }
140                 /* this will track the maximum bar we've had.  it'll include the 64 bit
141                  * uppers, as well as devices that have only higher numbered bars. */
142                 pcidev->nr_bars = i + 1;
143         }
144 }
145
146 static void __pci_parse_caps(struct pci_device *pcidev)
147 {
148         uint32_t cap_off;       /* not sure if this can be extended from u8 */
149         uint8_t cap_id;
150         if (!(pcidev_read16(pcidev, PCI_STATUS_REG) & (1 << 4)))
151                 return;
152         switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7f) {
153                 case 0:                         /* etc */
154                 case 1:                         /* pci to pci bridge */
155                         cap_off = 0x34;
156                         break;
157                 case 2:                         /* cardbus bridge */
158                         cap_off = 0x14;
159                         break;
160                 default:
161                         return;
162         }
163         /* initial offset points to the addr of the first cap */
164         cap_off = pcidev_read8(pcidev, cap_off);
165         cap_off &= ~0x3;        /* osdev says the lower 2 bits are reserved */
166         while (cap_off) {
167                 cap_id = pcidev_read8(pcidev, cap_off);
168                 if (cap_id > PCI_CAP_ID_MAX) {
169                         printk("PCI %x:%x:%x had bad cap 0x%x\n", pcidev->bus, pcidev->dev,
170                                pcidev->func, cap_id);
171                         return;
172                 }
173                 pcidev->caps[cap_id] = cap_off;
174                 cap_off = pcidev_read8(pcidev, cap_off + 1);
175                 /* not sure if subsequent caps must be aligned or not */
176                 if (cap_off & 0x3)
177                         printk("PCI %x:%x:%x had unaligned cap offset 0x%x\n", pcidev->bus,
178                                pcidev->dev, pcidev->func, cap_off);
179         }
180 }
181
182 /* Scans the PCI bus.  Won't actually work for anything other than bus 0, til we
183  * sort out how to handle bridge devices. */
184 void pci_init(void)
185 {
186         uint32_t result = 0;
187         uint16_t dev_id, ven_id;
188         struct pci_device *pcidev;
189         int max_nr_func;
190         for (int i = 0; i < PCI_MAX_BUS - 1; i++) {     /* phantoms at 0xff */
191                 for (int j = 0; j < PCI_MAX_DEV; j++) {
192                         max_nr_func = 1;
193                         for (int k = 0; k < max_nr_func; k++) {
194                                 result = pci_read32(i, j, k, PCI_DEV_VEND_REG);
195                                 dev_id = result >> 16;
196                                 ven_id = result & 0xffff;
197                                 /* Skip invalid IDs (not a device) */
198                                 if (ven_id == INVALID_VENDOR_ID) 
199                                         break;  /* skip functions too, they won't exist */
200                                 pcidev = kzmalloc(sizeof(struct pci_device), 0);
201                                 /* we don't need to lock it til we post the pcidev to the list*/
202                                 spinlock_init_irqsave(&pcidev->lock);
203                                 pcidev->bus = i;
204                                 pcidev->dev = j;
205                                 pcidev->func = k;
206                                 pcidev->dev_id = dev_id;
207                                 pcidev->ven_id = ven_id;
208                                 /* Get the Class/subclass */
209                                 pcidev->class = pcidev_read8(pcidev, PCI_CLASS_REG);
210                                 pcidev->subclass = pcidev_read8(pcidev, PCI_SUBCLASS_REG);
211                                 pcidev->progif = pcidev_read8(pcidev, PCI_PROGIF_REG);
212                                 /* All device types (0, 1, 2) have the IRQ in the same place */
213                                 /* This is the PIC IRQ the device is wired to */
214                                 pcidev->irqline = pcidev_read8(pcidev, PCI_IRQLINE_STD);
215                                 /* This is the interrupt pin the device uses (INTA# - INTD#) */
216                                 pcidev->irqpin = pcidev_read8(pcidev, PCI_IRQPIN_STD);
217                                 /* bottom 7 bits are header type */
218                                 switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c) {
219                                         case 0x00:
220                                                 pcidev->header_type = STD_PCI_DEV;
221                                                 break;
222                                         case 0x01:
223                                                 pcidev->header_type = PCI2PCI;
224                                                 break;
225                                         case 0x02:
226                                                 pcidev->header_type = PCI2CARDBUS;
227                                                 break;
228                                         default:
229                                                 pcidev->header_type = "Unknown Header Type";
230                                 }
231                                 __pci_handle_bars(pcidev);
232                                 __pci_parse_caps(pcidev);
233                                 /* we're the only writer at this point in the boot process */
234                                 STAILQ_INSERT_TAIL(&pci_devices, pcidev, all_dev);
235                                 #ifdef CONFIG_PCI_VERBOSE
236                                 pcidev_print_info(pcidev, 4);
237                                 #else
238                                 pcidev_print_info(pcidev, 0);
239                                 #endif /* CONFIG_PCI_VERBOSE */
240                                 /* Top bit determines if we have multiple functions on this
241                                  * device.  We can't just check for more functions, since
242                                  * non-multifunction devices exist that respond to different
243                                  * functions with the same underlying device (same bars etc).
244                                  * Note that this style allows for devices that only report
245                                  * multifunction in the first function's header. */
246                                 if (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x80)
247                                         max_nr_func = PCI_MAX_FUNC;
248                         }
249                 }
250         }
251 }
252
253 uint32_t pci_config_addr(uint8_t bus, uint8_t dev, uint8_t func, uint32_t reg)
254 {
255         return (uint32_t)(((uint32_t)bus << 16) |
256                           ((uint32_t)dev << 11) |
257                           ((uint32_t)func << 8) |
258                           (reg & 0xfc) |
259                           ((reg & 0xf00) << 16) |       /* extended PCI CFG space... */
260                                           0x80000000);
261 }
262
263 /* Helper to read 32 bits from the config space of B:D:F.  'Offset' is how far
264  * into the config space we offset before reading, aka: where we are reading. */
265 uint32_t pci_read32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
266 {
267         uint32_t ret;
268         spin_lock_irqsave(&pci_lock);
269         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
270         ret = inl(PCI_CONFIG_DATA);
271         spin_unlock_irqsave(&pci_lock);
272         return ret;
273 }
274
275 /* Same, but writes (doing 32bit at a time).  Never actually tested (not sure if
276  * PCI lets you write back). */
277 void pci_write32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
278                  uint32_t value)
279 {
280         spin_lock_irqsave(&pci_lock);
281         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
282         outl(PCI_CONFIG_DATA, value);
283         spin_unlock_irqsave(&pci_lock);
284 }
285
286 uint16_t pci_read16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
287 {
288         uint16_t ret;
289         spin_lock_irqsave(&pci_lock);
290         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
291         ret = inw(PCI_CONFIG_DATA + (offset & 2));
292         spin_unlock_irqsave(&pci_lock);
293         return ret;
294 }
295
296 void pci_write16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
297                  uint16_t value)
298 {
299         spin_lock_irqsave(&pci_lock);
300         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
301         outw(PCI_CONFIG_DATA + (offset & 2), value);
302         spin_unlock_irqsave(&pci_lock);
303 }
304
305 uint8_t pci_read8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset)
306 {
307         uint8_t ret;
308         spin_lock_irqsave(&pci_lock);
309         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
310         ret = inb(PCI_CONFIG_DATA + (offset & 3));
311         spin_unlock_irqsave(&pci_lock);
312         return ret;
313 }
314
315 void pci_write8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
316                 uint8_t value)
317 {
318         spin_lock_irqsave(&pci_lock);
319         outl(PCI_CONFIG_ADDR, pci_config_addr(bus, dev, func, offset));
320         outb(PCI_CONFIG_DATA + (offset & 3), value);
321         spin_unlock_irqsave(&pci_lock);
322 }
323
324 uint32_t pcidev_read32(struct pci_device *pcidev, uint32_t offset)
325 {
326         return pci_read32(pcidev->bus, pcidev->dev, pcidev->func, offset);
327 }
328
329 void pcidev_write32(struct pci_device *pcidev, uint32_t offset, uint32_t value)
330 {
331         pci_write32(pcidev->bus, pcidev->dev, pcidev->func, offset, value);
332 }
333
334 uint16_t pcidev_read16(struct pci_device *pcidev, uint32_t offset)
335 {
336         return pci_read16(pcidev->bus, pcidev->dev, pcidev->func, offset);
337 }
338
339 void pcidev_write16(struct pci_device *pcidev, uint32_t offset, uint16_t value)
340 {
341         pci_write16(pcidev->bus, pcidev->dev, pcidev->func, offset, value);
342 }
343
344 uint8_t pcidev_read8(struct pci_device *pcidev, uint32_t offset)
345 {
346         return pci_read8(pcidev->bus, pcidev->dev, pcidev->func, offset);
347 }
348
349 void pcidev_write8(struct pci_device *pcidev, uint32_t offset, uint8_t value)
350 {
351         pci_write8(pcidev->bus, pcidev->dev, pcidev->func, offset, value);
352 }
353
354 /* Helper to get the class description strings.  Adapted from
355  * http://www.pcidatabase.com/reports.php?type=c-header */
356 static void pcidev_get_cldesc(struct pci_device *pcidev, char **class,
357                               char **subclass, char **progif)
358 {
359         int     i ;
360         *class = *subclass = *progif = "";
361
362         for (i = 0; i < PCI_CLASSCODETABLE_LEN; i++) {
363                 if (PciClassCodeTable[i].BaseClass == pcidev->class) {
364                         if (!(**class))
365                                 *class = PciClassCodeTable[i].BaseDesc;
366                         if (PciClassCodeTable[i].SubClass == pcidev->subclass) {
367                                 if (!(**subclass))
368                                         *subclass = PciClassCodeTable[i].SubDesc;
369                                 if (PciClassCodeTable[i].ProgIf == pcidev->progif) {
370                                         *progif = PciClassCodeTable[i].ProgDesc;
371                                         break ;
372                                 }
373                         }
374                 }
375         }
376 }
377
378 /* Helper to get the vendor and device description strings */
379 static void pcidev_get_devdesc(struct pci_device *pcidev, char **vend_short,
380                                char **vend_full, char **chip, char **chip_desc)
381 {
382         int     i ;
383         *vend_short = *vend_full = *chip = *chip_desc = "";
384
385         for (i = 0; i < PCI_VENTABLE_LEN; i++) {
386                 if (PciVenTable[i].VenId == pcidev->ven_id) {
387                         *vend_short = PciVenTable[i].VenShort;
388                         *vend_full = PciVenTable[i].VenFull;
389                         break ;
390                 }
391         }
392         for (i = 0; i < PCI_DEVTABLE_LEN; i++) {
393                 if ((PciDevTable[i].VenId == pcidev->ven_id) &&
394                    (PciDevTable[i].DevId == pcidev->dev_id)) {
395                         *chip = PciDevTable[i].Chip;
396                         *chip_desc = PciDevTable[i].ChipDesc;
397                         break ;
398                 }
399         }
400 }
401
402 /* Prints info (like lspci) for a device */
403 void pcidev_print_info(struct pci_device *pcidev, int verbosity)
404 {
405         char *ven_sht, *ven_fl, *chip, *chip_txt, *class, *subcl, *progif;
406         pcidev_get_cldesc(pcidev, &class, &subcl, &progif);
407         pcidev_get_devdesc(pcidev, &ven_sht, &ven_fl, &chip, &chip_txt);
408
409         printk("%02x:%02x.%x %s: %s %s %s: %s\n",
410                pcidev->bus,
411                pcidev->dev,
412                pcidev->func,
413                subcl,
414                ven_sht,
415                chip,
416                chip_txt,
417                    pcidev->header_type);
418         if (verbosity < 1)      /* whatever */
419                 return;
420         printk("\tIRQ: %02d IRQ pin: 0x%02x\n",
421                pcidev->irqline,
422                pcidev->irqpin);
423         printk("\tVendor Id: 0x%04x Device Id: 0x%04x\n",
424                pcidev->ven_id,
425                pcidev->dev_id);
426         printk("\t%s %s %s\n",
427                class,
428                progif,
429                ven_fl);
430         for (int i = 0; i < pcidev->nr_bars; i++) {
431                 if (pcidev->bar[i].raw_bar == 0)
432                         continue;
433                 printk("\tBAR %d: ", i);
434                 if (pci_is_iobar(pcidev->bar[i].raw_bar)) {
435                         assert(pcidev->bar[i].pio_base);
436                         printk("IO port 0x%04x\n", pcidev->bar[i].pio_base);
437                 } else {
438                         bool bar_is_64 = pci_is_membar64(pcidev->bar[i].raw_bar);
439                         printk("MMIO Base%s %p, MMIO Size %p\n",
440                                bar_is_64 ? "64" : "32",
441                                bar_is_64 ? pcidev->bar[i].mmio_base64 :
442                                            pcidev->bar[i].mmio_base32,
443                                pcidev->bar[i].mmio_sz);
444                         /* Takes up two bars */
445                         if (bar_is_64) {
446                                 assert(!pcidev->bar[i].mmio_base32);    /* double-check */
447                                 i++;
448                         }
449                 }
450         }
451         printk("\tCapabilities:");
452         for (int i = 0; i < PCI_CAP_ID_MAX + 1; i++) {
453                 if (pcidev->caps[i])
454                         printk(" 0x%02x", i);
455         }
456         printk("\n");
457 }
458
459 void pci_set_bus_master(struct pci_device *pcidev)
460 {
461         spin_lock_irqsave(&pcidev->lock);
462         pcidev_write16(pcidev, PCI_CMD_REG, pcidev_read16(pcidev, PCI_CMD_REG) |
463                                             PCI_CMD_BUS_MAS);
464         spin_unlock_irqsave(&pcidev->lock);
465 }
466
467 void pci_clr_bus_master(struct pci_device *pcidev)
468 {
469         uint16_t reg;
470         spin_lock_irqsave(&pcidev->lock);
471         reg = pcidev_read16(pcidev, PCI_CMD_REG);
472         reg &= ~PCI_CMD_BUS_MAS;
473         pcidev_write16(pcidev, PCI_CMD_REG, reg);
474         spin_unlock_irqsave(&pcidev->lock);
475 }
476
477 struct pci_device *pci_match_tbdf(int tbdf)
478 {
479         struct pci_device *search;
480         int bus, dev, func;
481         bus = BUSBNO(tbdf);
482         dev = BUSDNO(tbdf);
483         func = BUSFNO(tbdf);
484
485         STAILQ_FOREACH(search, &pci_devices, all_dev) {
486                 if ((search->bus == bus) &&
487                     (search->dev == dev) &&
488                     (search->func == func))
489                         return search;
490         }
491         return NULL;
492 }
493
494 /* Helper to get the membar value for BAR index bir */
495 uintptr_t pci_get_membar(struct pci_device *pcidev, int bir)
496 {
497         if (bir >= pcidev->nr_bars)
498                 return 0;
499         if (pci_is_iobar(pcidev->bar[bir].raw_bar))
500                 return 0;
501         return (pci_is_membar64(pcidev->bar[bir].raw_bar) ?
502                 pcidev->bar[bir].mmio_base64 :
503                 pcidev->bar[bir].mmio_base32);
504 }
505
506 uintptr_t pci_get_iobar(struct pci_device *pcidev, int bir)
507 {
508         if (bir >= pcidev->nr_bars)
509                 return 0;
510         if (!pci_is_iobar(pcidev->bar[bir].raw_bar))
511                 return 0;
512         return pci_getiobar32(pcidev->bar[bir].raw_bar);
513 }
514
515 uint16_t pci_get_vendor(struct pci_device *pcidev)
516 {
517         return pcidev->ven_id;
518 }
519
520 uint16_t pci_get_device(struct pci_device *pcidev)
521 {
522         return pcidev->dev_id;
523 }
524
525 uint16_t pci_get_subvendor(struct pci_device *pcidev)
526 {
527         uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;
528         switch (header_type) {
529                 case 0x00: /* STD_PCI_DEV */
530                         return pcidev_read16(pcidev, PCI_SUBSYSVEN_STD);
531                 case 0x01: /* PCI2PCI */
532                         return -1;
533                 case 0x02: /* PCI2CARDBUS */
534                         return pcidev_read16(pcidev, PCI_SUBVENID_CB);
535                 default:
536                         warn("Unknown Header Type, %d", header_type);
537         }
538         return -1;
539 }
540
541 uint16_t pci_get_subdevice(struct pci_device *pcidev)
542 {
543         uint8_t header_type = pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c;
544         switch (header_type) {
545                 case 0x00: /* STD_PCI_DEV */
546                         return pcidev_read16(pcidev, PCI_SUBSYSID_STD);
547                 case 0x01: /* PCI2PCI */
548                         return -1;
549                 case 0x02: /* PCI2CARDBUS */
550                         return pcidev_read16(pcidev, PCI_SUBDEVID_CB);
551                 default:
552                         warn("Unknown Header Type, %d", header_type);
553         }
554         return -1;
555 }
556
557 void pci_dump_config(struct pci_device *pcidev, size_t len)
558 {
559         if (len > 256)
560                 printk("FYI, printing more than 256 bytes of PCI space\n");
561         printk("PCI Config space for %02x:%02x:%02x\n---------------------\n",
562                pcidev->bus, pcidev->dev, pcidev->func);
563         for (int i = 0; i < len; i += 4)
564                 printk("0x%03x | %08x\n", i, pcidev_read32(pcidev, i));
565 }
566
567 int pci_find_cap(struct pci_device *pcidev, uint8_t cap_id, uint32_t *cap_reg)
568 {
569         if (cap_id > PCI_CAP_ID_MAX)
570                 return -EINVAL;
571         if (!pcidev->caps[cap_id])
572                 return -ENOENT;
573         /* The actual value at caps[id] is the offset in the PCI config space where
574          * that ID was stored.  That's needed for accessing the capability. */
575         if (cap_reg)
576                 *cap_reg = pcidev->caps[cap_id];
577         return 0;
578 }