Ignore:
Timestamp:
Nov 4, 2005, 3:34:08 AM (14 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
758ee5c
Parents:
cca22863
Message:

2005-11-03 Till Straumann <strauman@…>

  • shared/motorola/motorola.c, shared/pci/detect_raven_bridge.c, shared/pci/pci.c, shared/pci/pci.h, shared/pci/pcifinddevice.c: Several PCI enhancements and fixes: all BSP flavors now use the generic clear_hostbridge_errors() routine (this means that only polling memory probing is possible [see detect_raven_bridge.c for details]). Interrupt fixup routine now supports multi-function devices. Interrupt fixup routine now honours a flag/option so that wrong firmware values can be overridden. Fixed irq routing table for mvme2100 [PMC]. Added irq routing table for mvme2300. Added a BSP_pciScan() routine that executes a user callback on each non-empty slot/fun. Added BSP_pciConfigDump() to display basic config headers.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c

    rcca22863 r98afe31  
    1313#include <bsp/pci.h>
    1414#include <rtems/bspIo.h>
     15#include <stdio.h>
     16
     17/* Stolen from i386... */
     18
     19/*
     20 * Make device signature from bus number, device number and function
     21 * number
     22 */
     23#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
     24
     25/*
     26 * Extract various parts from device signature
     27 */
     28#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
     29#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
     30#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
     31
     32typedef struct {
     33        unsigned short  vid,did;
     34        int                             inst;
     35} fd_arg;
     36
     37static int
     38find_dev_cb(
     39   int bus,
     40   int dev,
     41   int fun,
     42   void *uarg
     43) {
     44fd_arg         *a = uarg;
     45unsigned short  s;
     46
     47  pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
     48  if (a->vid == s) {
     49    pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
     50        if (a->did == s && 0 == a->inst-- ) {
     51          a->inst = PCIB_DEVSIG_MAKE( bus, dev, fun );
     52          return 1;
     53        }
     54  }
     55  return 0;
     56}
    1557
    1658int
     
    2365  int *pfun
    2466) {
     67fd_arg a;
     68void   *h;
     69        a.vid  = vendorid;
     70        a.did  = deviceid;
     71        a.inst = instance;
     72
     73        if ( (h = BSP_pciScan(0, find_dev_cb, (void*)&a)) ) {
     74      *pbus = PCIB_DEVSIG_BUS(  a.inst );
     75      *pdev = PCIB_DEVSIG_DEV(  a.inst );
     76      *pfun = PCIB_DEVSIG_FUNC( a.inst );
     77          return 0;
     78        }
     79        return -1;
     80}
     81
     82static int
     83dump_dev_cb(
     84   int bus,
     85   int dev,
     86   int fun,
     87   void *uarg
     88) {
     89unsigned short vi,di;
     90unsigned short cd,st;
     91unsigned int   b1,b2;
     92unsigned char  il,ip;
     93FILE           *f = uarg;
     94
     95        pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID,      &vi);
     96        pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID,      &di);
     97        pci_read_config_word (bus, dev, fun, PCI_COMMAND,        &cd);
     98        pci_read_config_word (bus, dev, fun, PCI_STATUS,         &st);
     99        pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1);
     100        pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2);
     101        pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il);
     102        pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN,  &ip);
     103
     104        fprintf(f,"%3d:0x%02x:%d    0x%04x-0x%04x:  0x%04x 0x%04x 0x%08x 0x%08x       %d -> %3d (=0x%02x)\n",
     105                bus, dev, fun, vi, di, cd, st, b1, b2, ip, il, il);
     106        return 0;
     107}
     108
     109void
     110BSP_pciConfigDump(FILE *f)
     111{
     112        if ( !f )
     113                f = stdout;
     114        fprintf(f,"BUS:SLOT:FUN  VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 BASE_ADDR1 IRQ_PIN -> IRQ_LINE\n");
     115        BSP_pciScan(0, dump_dev_cb, f);
     116}
     117
     118BSP_PciScanHandle
     119BSP_pciScan(
     120  BSP_PciScanHandle handle,
     121  BSP_PciScannerCb cb,
     122  void *uarg
     123) {
     124
    25125   unsigned int d;
    26    unsigned short s;
    27126   unsigned char bus,dev,fun,hd;
    28127
    29    for (bus=0; bus<pci_bus_count(); bus++) {
    30      for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
     128   bus = PCIB_DEVSIG_BUS(  (unsigned long)handle );
     129   dev = PCIB_DEVSIG_DEV(  (unsigned long)handle );
     130   fun = PCIB_DEVSIG_FUNC( (unsigned long)handle );
    31131
    32        pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
    33        hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
     132   hd = fun > 0 ? PCI_MAX_FUNCTIONS : 1;
    34133
    35        for (fun=0; fun<hd; fun++) {
     134   for (; bus<pci_bus_count(); bus++, dev=0) {
     135     for (; dev<PCI_MAX_DEVICES; dev++, fun=0) {
     136       for (; fun<hd; fun++) {
    36137         /*
    37138          * The last devfn id/slot is special; must skip it
    38139          */
    39         if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
    40           break;
     140         if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
     141           break;
     142
     143         (void)pci_read_config_dword(bus,dev,0,PCI_VENDOR_ID,&d);
     144         if (PCI_INVALID_VENDORDEVICEID == d)
     145           continue;
     146
     147         if ( 0 == fun ) {
     148           pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
     149           hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
     150                 }
     151
    41152        (void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
    42153        if (PCI_INVALID_VENDORDEVICEID == d)
    43154          continue;
    44155#ifdef PCI_DEBUG
    45         printk("pci_find_by_devid: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
     156        printk("BSP_pciScan: found 0x%08x at %d/x%02x/%d\n",d,bus,dev,fun);
    46157#endif
    47         (void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
    48         if (vendorid != s)
    49           continue;
    50         (void) pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
    51         if (deviceid == s) {
    52           if (instance--) continue;
    53           *pbus=bus; *pdev=dev; *pfun=fun;
    54           return 0;
    55         }
     158                if ( cb(bus,dev,fun,uarg) > 0 ) {
     159                        if ( ++fun >= hd ) {
     160                                fun = 0;
     161                                if ( ++dev >= PCI_MAX_DEVICES ) {
     162                                        dev = 0;
     163                                        bus++;
     164                                }
     165                        }
     166                        return (void*) PCIB_DEVSIG_MAKE(bus,dev,fun);
     167                }
    56168      }
    57169    }
    58170  }
    59   return -1;
     171  return 0;
    60172}
Note: See TracChangeset for help on using the changeset viewer.