Subversion Repositories Kolibri OS

Rev

Rev 9079 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <syscall.h>
  2. #include <linux/pci.h>
  3.  
  4. LIST_HEAD(devices);
  5.  
  6. /* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
  7. #define IORESOURCE_PCI_FIXED            (1<<4)  /* Do not move resource */
  8.  
  9. #define LEGACY_IO_RESOURCE      (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
  10.  
  11. #define IORESOURCE_ROM_COPY             (1<<2)  /* ROM is alloc'd copy, resource field overlaid */
  12. #define IORESOURCE_ROM_BIOS_COPY        (1<<3)  /* ROM is BIOS copy, resource field overlaid */
  13.  
  14.  
  15. static inline unsigned int pci_calc_resource_flags(unsigned int flags)
  16. {
  17.     if (flags & PCI_BASE_ADDRESS_SPACE_IO)
  18.         return IORESOURCE_IO;
  19.  
  20.     if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
  21.         return IORESOURCE_MEM | IORESOURCE_PREFETCH;
  22.  
  23.     return IORESOURCE_MEM;
  24. }
  25.  
  26. static u32 pci_size(u32 base, u32 maxbase, u32 mask)
  27. {
  28.     u32 size = mask & maxbase;      /* Find the significant bits */
  29.  
  30.     if (!size)
  31.         return 0;
  32.  
  33.     /* Get the lowest of them to find the decode size, and
  34.        from that the extent.  */
  35.     size = (size & ~(size-1)) - 1;
  36.  
  37.     /* base == maxbase can be valid only if the BAR has
  38.        already been programmed with all 1s.  */
  39.     if (base == maxbase && ((base | size) & mask) != mask)
  40.         return 0;
  41.  
  42.     return size;
  43. }
  44.  
  45. static u64 pci_size64(u64 base, u64 maxbase, u64 mask)
  46. {
  47.     u64 size = mask & maxbase;      /* Find the significant bits */
  48.  
  49.     if (!size)
  50.         return 0;
  51.  
  52.     /* Get the lowest of them to find the decode size, and
  53.        from that the extent.  */
  54.     size = (size & ~(size-1)) - 1;
  55.  
  56.     /* base == maxbase can be valid only if the BAR has
  57.        already been programmed with all 1s.  */
  58.     if (base == maxbase && ((base | size) & mask) != mask)
  59.         return 0;
  60.  
  61.     return size;
  62. }
  63.  
  64. static inline int is_64bit_memory(u32 mask)
  65. {
  66.     if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
  67.         (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
  68.         return 1;
  69.     return 0;
  70. }
  71.  
  72. static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
  73. {
  74.     u32  pos, reg, next;
  75.     u32  l, sz;
  76.     struct resource *res;
  77.  
  78.     for(pos=0; pos < howmany; pos = next)
  79.     {
  80.         u64  l64;
  81.         u64  sz64;
  82.         u32  raw_sz;
  83.  
  84.         next = pos + 1;
  85.  
  86.         res  = &dev->resource[pos];
  87.  
  88.         reg = PCI_BASE_ADDRESS_0 + (pos << 2);
  89.         l = PciRead32(dev->busnr, dev->devfn, reg);
  90.         PciWrite32(dev->busnr, dev->devfn, reg, ~0);
  91.         sz = PciRead32(dev->busnr, dev->devfn, reg);
  92.         PciWrite32(dev->busnr, dev->devfn, reg, l);
  93.  
  94.         if (!sz || sz == 0xffffffff)
  95.             continue;
  96.  
  97.         if (l == 0xffffffff)
  98.             l = 0;
  99.  
  100.         raw_sz = sz;
  101.         if ((l & PCI_BASE_ADDRESS_SPACE) ==
  102.                         PCI_BASE_ADDRESS_SPACE_MEMORY)
  103.         {
  104.             sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
  105.             /*
  106.              * For 64bit prefetchable memory sz could be 0, if the
  107.              * real size is bigger than 4G, so we need to check
  108.              * szhi for that.
  109.              */
  110.             if (!is_64bit_memory(l) && !sz)
  111.                     continue;
  112.             res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
  113.             res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
  114.         }
  115.         else {
  116.             sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
  117.             if (!sz)
  118.                 continue;
  119.             res->start = l & PCI_BASE_ADDRESS_IO_MASK;
  120.             res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
  121.         }
  122.         res->end = res->start + (unsigned long) sz;
  123.         res->flags |= pci_calc_resource_flags(l);
  124.         if (is_64bit_memory(l))
  125.         {
  126.             u32 szhi, lhi;
  127.  
  128.             lhi = PciRead32(dev->busnr, dev->devfn, reg+4);
  129.             PciWrite32(dev->busnr, dev->devfn, reg+4, ~0);
  130.             szhi = PciRead32(dev->busnr, dev->devfn, reg+4);
  131.             PciWrite32(dev->busnr, dev->devfn, reg+4, lhi);
  132.             sz64 = ((u64)szhi << 32) | raw_sz;
  133.             l64 = ((u64)lhi << 32) | l;
  134.             sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
  135.             next++;
  136.  
  137. #if BITS_PER_LONG == 64
  138.             if (!sz64) {
  139.                 res->start = 0;
  140.                 res->end = 0;
  141.                 res->flags = 0;
  142.                 continue;
  143.             }
  144.             res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
  145.             res->end = res->start + sz64;
  146. #else
  147.             if (sz64 > 0x100000000ULL) {
  148.                 printk(KERN_ERR "PCI: Unable to handle 64-bit "
  149.                                 "BAR for device %s\n", pci_name(dev));
  150.                 res->start = 0;
  151.                 res->flags = 0;
  152.             }
  153.             else if (lhi)
  154.             {
  155.                 /* 64-bit wide address, treat as disabled */
  156.                 PciWrite32(dev->busnr, dev->devfn, reg,
  157.                         l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
  158.                 PciWrite32(dev->busnr, dev->devfn, reg+4, 0);
  159.                 res->start = 0;
  160.                 res->end = sz;
  161.             }
  162. #endif
  163.         }
  164.     }
  165.  
  166.     if ( rom )
  167.     {
  168.         dev->rom_base_reg = rom;
  169.         res = &dev->resource[PCI_ROM_RESOURCE];
  170.  
  171.         l = PciRead32(dev->busnr, dev->devfn, rom);
  172.         PciWrite32(dev->busnr, dev->devfn, rom, ~PCI_ROM_ADDRESS_ENABLE);
  173.         sz = PciRead32(dev->busnr, dev->devfn, rom);
  174.         PciWrite32(dev->busnr, dev->devfn, rom, l);
  175.  
  176.         if (l == 0xffffffff)
  177.             l = 0;
  178.  
  179.         if (sz && sz != 0xffffffff)
  180.         {
  181.             sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);
  182.  
  183.             if (sz)
  184.             {
  185.                 res->flags = (l & IORESOURCE_ROM_ENABLE) |
  186.                                   IORESOURCE_MEM | IORESOURCE_PREFETCH |
  187.                                   IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
  188.                 res->start = l & PCI_ROM_ADDRESS_MASK;
  189.                 res->end = res->start + (unsigned long) sz;
  190.             }
  191.         }
  192.     }
  193. }
  194.  
  195. static void pci_read_irq(struct pci_dev *dev)
  196. {
  197.     u8 irq;
  198.  
  199.     irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_PIN);
  200.     dev->pin = irq;
  201.     if (irq)
  202.         irq = PciRead8(dev->busnr, dev->devfn, PCI_INTERRUPT_LINE);
  203.     dev->irq = irq;
  204. };
  205.  
  206.  
  207. int pci_setup_device(struct pci_dev *dev)
  208. {
  209.     u32  class;
  210.  
  211.     class = PciRead32(dev->busnr, dev->devfn, PCI_CLASS_REVISION);
  212.     dev->revision = class & 0xff;
  213.     class >>= 8;                                /* upper 3 bytes */
  214.     dev->class = class;
  215.  
  216.     /* "Unknown power state" */
  217. //    dev->current_state = PCI_UNKNOWN;
  218.  
  219.     /* Early fixups, before probing the BARs */
  220.  //   pci_fixup_device(pci_fixup_early, dev);
  221.     class = dev->class >> 8;
  222.  
  223.     switch (dev->hdr_type)
  224.     {
  225.         case PCI_HEADER_TYPE_NORMAL:                /* standard header */
  226.             if (class == PCI_CLASS_BRIDGE_PCI)
  227.                 goto bad;
  228.             pci_read_irq(dev);
  229.             pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
  230.             dev->subsystem_vendor = PciRead16(dev->busnr, dev->devfn,PCI_SUBSYSTEM_VENDOR_ID);
  231.             dev->subsystem_device = PciRead16(dev->busnr, dev->devfn, PCI_SUBSYSTEM_ID);
  232.  
  233.             /*
  234.              *      Do the ugly legacy mode stuff here rather than broken chip
  235.              *      quirk code. Legacy mode ATA controllers have fixed
  236.              *      addresses. These are not always echoed in BAR0-3, and
  237.              *      BAR0-3 in a few cases contain junk!
  238.              */
  239.             if (class == PCI_CLASS_STORAGE_IDE)
  240.             {
  241.                 u8 progif;
  242.  
  243.                 progif = PciRead8(dev->busnr, dev->devfn,PCI_CLASS_PROG);
  244.                 if ((progif & 1) == 0)
  245.                 {
  246.                     dev->resource[0].start = 0x1F0;
  247.                     dev->resource[0].end = 0x1F7;
  248.                     dev->resource[0].flags = LEGACY_IO_RESOURCE;
  249.                     dev->resource[1].start = 0x3F6;
  250.                     dev->resource[1].end = 0x3F6;
  251.                     dev->resource[1].flags = LEGACY_IO_RESOURCE;
  252.                 }
  253.                 if ((progif & 4) == 0)
  254.                 {
  255.                     dev->resource[2].start = 0x170;
  256.                     dev->resource[2].end = 0x177;
  257.                     dev->resource[2].flags = LEGACY_IO_RESOURCE;
  258.                     dev->resource[3].start = 0x376;
  259.                     dev->resource[3].end = 0x376;
  260.                     dev->resource[3].flags = LEGACY_IO_RESOURCE;
  261.                 };
  262.             }
  263.             break;
  264.  
  265.         case PCI_HEADER_TYPE_BRIDGE:                /* bridge header */
  266.                 if (class != PCI_CLASS_BRIDGE_PCI)
  267.                         goto bad;
  268.                 /* The PCI-to-PCI bridge spec requires that subtractive
  269.                    decoding (i.e. transparent) bridge must have programming
  270.                    interface code of 0x01. */
  271.                 pci_read_irq(dev);
  272.                 dev->transparent = ((dev->class & 0xff) == 1);
  273.                 pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
  274.                 break;
  275.  
  276.         case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header */
  277.                 if (class != PCI_CLASS_BRIDGE_CARDBUS)
  278.                         goto bad;
  279.                 pci_read_irq(dev);
  280.                 pci_read_bases(dev, 1, 0);
  281.                 dev->subsystem_vendor = PciRead16(dev->busnr,
  282.                                                   dev->devfn,
  283.                                                   PCI_CB_SUBSYSTEM_VENDOR_ID);
  284.  
  285.                 dev->subsystem_device = PciRead16(dev->busnr,
  286.                                                   dev->devfn,
  287.                                                   PCI_CB_SUBSYSTEM_ID);
  288.                 break;
  289.  
  290.         default:                                    /* unknown header */
  291.                 printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
  292.                         pci_name(dev), dev->hdr_type);
  293.                 return -1;
  294.  
  295.         bad:
  296.                 printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
  297.                        pci_name(dev), class, dev->hdr_type);
  298.                 dev->class = PCI_CLASS_NOT_DEFINED;
  299.     }
  300.  
  301.     /* We found a fine healthy device, go go go... */
  302.  
  303.     return 0;
  304. };
  305.  
  306. static pci_dev_t* pci_scan_device(u32 busnr, int devfn)
  307. {
  308.     pci_dev_t  *dev;
  309.  
  310.     u32   id;
  311.     u8    hdr;
  312.  
  313.     int     timeout = 10;
  314.  
  315.     id = PciRead32(busnr, devfn, PCI_VENDOR_ID);
  316.     /* some broken boards return 0 or ~0 if a slot is empty: */
  317.     if (id == 0xffffffff || id == 0x00000000 ||
  318.         id == 0x0000ffff || id == 0xffff0000)
  319.         return NULL;
  320.  
  321.     while (id == 0xffff0001)
  322.     {
  323.  
  324.         delay(timeout/10);
  325.         timeout *= 2;
  326.  
  327.         id = PciRead32(busnr, devfn, PCI_VENDOR_ID);
  328.  
  329.         /* Card hasn't responded in 60 seconds?  Must be stuck. */
  330.         if (timeout > 60 * 100)
  331.         {
  332.             printk(KERN_WARNING "Device %04x:%02x:%02x.%d not "
  333.                    "responding\n", busnr,PCI_SLOT(devfn),PCI_FUNC(devfn));
  334.             return NULL;
  335.         }
  336.     };
  337.  
  338.   /* if( pci_scan_filter(id, busnr, devfn) == 0)
  339.         return NULL;*/
  340.  
  341.     hdr = PciRead8(busnr, devfn, PCI_HEADER_TYPE);
  342.  
  343.     dev = (pci_dev_t*)KernelZeroAlloc(sizeof(pci_dev_t));
  344.     if(unlikely(dev == NULL))
  345.         return NULL;
  346.  
  347.     INIT_LIST_HEAD(&dev->link);
  348.  
  349.     dev->pci_dev.busnr    = busnr;
  350.     dev->pci_dev.devfn    = devfn;
  351.     dev->pci_dev.hdr_type = hdr & 0x7f;
  352.     dev->pci_dev.multifunction    = !!(hdr & 0x80);
  353.     dev->pci_dev.vendor   = id & 0xffff;
  354.     dev->pci_dev.device   = (id >> 16) & 0xffff;
  355.  
  356.     pci_setup_device(&dev->pci_dev);
  357.  
  358.     return dev;
  359.  
  360. };
  361.  
  362.  
  363.  
  364. int _pci_scan_slot(u32 bus, int devfn)
  365. {
  366.     int  func, nr = 0;
  367.  
  368.     for (func = 0; func < 8; func++, devfn++)
  369.     {
  370.         pci_dev_t  *dev;
  371.  
  372.         dev = pci_scan_device(bus, devfn);
  373.         if( dev )
  374.         {
  375.             list_add(&dev->link, &devices);
  376.             nr++;
  377.  
  378.             /*
  379.              * If this is a single function device,
  380.              * don't scan past the first function.
  381.              */
  382.             if (!dev->pci_dev.multifunction)
  383.             {
  384.                 if (func > 0) {
  385.                     dev->pci_dev.multifunction = 1;
  386.                 }
  387.                 else {
  388.                     break;
  389.                 }
  390.              }
  391.         }
  392.         else {
  393.             if (func == 0)
  394.                 break;
  395.         }
  396.     };
  397.  
  398.     return nr;
  399. };
  400.  
  401. #define PCI_FIND_CAP_TTL    48
  402.  
  403. static int __pci_find_next_cap_ttl(unsigned int bus, unsigned int devfn,
  404.                    u8 pos, int cap, int *ttl)
  405. {
  406.     u8 id;
  407.  
  408.     while ((*ttl)--) {
  409.         pos = PciRead8(bus, devfn, pos);
  410.         if (pos < 0x40)
  411.             break;
  412.         pos &= ~3;
  413.         id = PciRead8(bus, devfn, pos + PCI_CAP_LIST_ID);
  414.         if (id == 0xff)
  415.             break;
  416.         if (id == cap)
  417.             return pos;
  418.         pos += PCI_CAP_LIST_NEXT;
  419.     }
  420.     return 0;
  421. }
  422.  
  423. static int __pci_find_next_cap(unsigned int bus, unsigned int devfn,
  424.                    u8 pos, int cap)
  425. {
  426.     int ttl = PCI_FIND_CAP_TTL;
  427.  
  428.     return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
  429. }
  430.  
  431. static int __pci_bus_find_cap_start(unsigned int bus,
  432.                     unsigned int devfn, u8 hdr_type)
  433. {
  434.     u16 status;
  435.  
  436.     status = PciRead16(bus, devfn, PCI_STATUS);
  437.     if (!(status & PCI_STATUS_CAP_LIST))
  438.         return 0;
  439.  
  440.     switch (hdr_type) {
  441.     case PCI_HEADER_TYPE_NORMAL:
  442.     case PCI_HEADER_TYPE_BRIDGE:
  443.         return PCI_CAPABILITY_LIST;
  444.     case PCI_HEADER_TYPE_CARDBUS:
  445.         return PCI_CB_CAPABILITY_LIST;
  446.     default:
  447.         return 0;
  448.     }
  449.  
  450.     return 0;
  451. }
  452.  
  453.  
  454. int pci_find_capability(struct pci_dev *dev, int cap)
  455. {
  456.     int pos;
  457.  
  458.     pos = __pci_bus_find_cap_start(dev->busnr, dev->devfn, dev->hdr_type);
  459.     if (pos)
  460.         pos = __pci_find_next_cap(dev->busnr, dev->devfn, pos, cap);
  461.  
  462.     return pos;
  463. }
  464.  
  465.  
  466. int enum_pci_devices(void)
  467. {
  468.     pci_dev_t  *dev;
  469.     u32       last_bus;
  470.     u32       bus = 0 , devfn = 0;
  471.  
  472.     last_bus = PciApi(1);
  473.  
  474.     if( unlikely(last_bus == -1))
  475.         return -1;
  476.  
  477.     for(;bus <= last_bus; bus++)
  478.     {
  479.         for (devfn = 0; devfn < 0x100; devfn += 8){
  480.             _pci_scan_slot(bus, devfn);
  481.         }
  482.     }
  483.     dev = (pci_dev_t*)devices.next;
  484.    
  485.     while(&dev->link != &devices)
  486.     {
  487.         /*printk("PCI device %x:%x bus:%x devfn:%x\n",
  488.                 dev->pci_dev.vendor,
  489.                 dev->pci_dev.device,
  490.                 dev->pci_dev.busnr,
  491.                 dev->pci_dev.devfn);*/
  492.         dev = (pci_dev_t*)dev->link.next;
  493.     }
  494.     return 0;
  495. }
  496.  
  497. void free_pci_devices(void)
  498. {
  499.     pci_dev_t *dev = (pci_dev_t*)devices.next;
  500.     while(&dev->link != &devices) {
  501.         pci_dev_t *temp = dev;
  502.         dev = (pci_dev_t*)dev->link.next;
  503.         KernelFree(temp);
  504.     }
  505. }
  506.  
  507. const struct pci_device_id* find_pci_device(pci_dev_t* pdev, const struct pci_device_id *idlist)
  508. {
  509.     pci_dev_t *dev;
  510.     const struct pci_device_id *ent;
  511.  
  512.     for(dev = (pci_dev_t*)devices.next;
  513.         &dev->link != &devices;
  514.         dev = (pci_dev_t*)dev->link.next)
  515.     {
  516.         if( dev->pci_dev.vendor != idlist->vendor )
  517.             continue;
  518.  
  519.         for(ent = idlist; ent->vendor != 0; ent++)
  520.         {
  521.             if(unlikely(ent->device == dev->pci_dev.device))
  522.             {
  523.                 pdev->pci_dev = dev->pci_dev;
  524.                 return  ent;
  525.             }
  526.         };
  527.     }
  528.  
  529.     return NULL;
  530. };
  531.  
  532. struct pci_dev *
  533. pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
  534. {
  535.     pci_dev_t *dev;
  536.  
  537.     dev = (pci_dev_t*)devices.next;
  538.  
  539.     if(from != NULL)
  540.     {
  541.         for(; &dev->link != &devices;
  542.             dev = (pci_dev_t*)dev->link.next)
  543.         {
  544.             if( &dev->pci_dev == from)
  545.             {
  546.                 dev = (pci_dev_t*)dev->link.next;
  547.                 break;
  548.             };
  549.         }
  550.     };
  551.  
  552.     for(; &dev->link != &devices;
  553.         dev = (pci_dev_t*)dev->link.next)
  554.     {
  555.         if((dev->pci_dev.vendor != vendor) && (vendor != PCI_ANY_ID))
  556.                 continue;
  557.  
  558.         if((dev->pci_dev.device == device || device == PCI_ANY_ID))
  559.         {
  560.             return &dev->pci_dev;
  561.         }
  562.     }
  563.     return NULL;
  564. };
  565.  
  566.  
  567. struct pci_dev * _pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
  568. {
  569.     pci_dev_t *dev;
  570.  
  571.     for(dev = (pci_dev_t*)devices.next;
  572.         &dev->link != &devices;
  573.         dev = (pci_dev_t*)dev->link.next)
  574.     {
  575.         if ( dev->pci_dev.busnr == bus && dev->pci_dev.devfn == devfn)
  576.             return &dev->pci_dev;
  577.     }
  578.     return NULL;
  579. }
  580.  
  581. struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
  582. {
  583.     pci_dev_t *dev;
  584.  
  585.     dev = (pci_dev_t*)devices.next;
  586.  
  587.     if(from != NULL)
  588.     {
  589.         for(; &dev->link != &devices;
  590.             dev = (pci_dev_t*)dev->link.next)
  591.         {
  592.             if( &dev->pci_dev == from)
  593.             {
  594.                 dev = (pci_dev_t*)dev->link.next;
  595.                 break;
  596.             };
  597.         }
  598.     };
  599.  
  600.     for(; &dev->link != &devices;
  601.         dev = (pci_dev_t*)dev->link.next)
  602.     {
  603.         if( dev->pci_dev.class == class)
  604.         {
  605.             return &dev->pci_dev;
  606.         }
  607.     }
  608.  
  609.    return NULL;
  610. }
  611.  
  612.  
  613. int pci_bus_read_config_byte (struct pci_bus *bus, u32 devfn, int pos, u8 *value)
  614. {
  615. //    raw_spin_lock_irqsave(&pci_lock, flags);
  616.     *value = PciRead8(bus->number, devfn, pos);
  617. //    raw_spin_unlock_irqrestore(&pci_lock, flags);
  618.     return 0;
  619. }
  620.  
  621. int pci_bus_read_config_word (struct pci_bus *bus, u32 devfn, int pos, u16 *value)
  622. {
  623.     if ( pos & 1)
  624.         return PCIBIOS_BAD_REGISTER_NUMBER;
  625. //    raw_spin_lock_irqsave(&pci_lock, flags);
  626.     *value = PciRead16(bus->number, devfn, pos);
  627. //    raw_spin_unlock_irqrestore(&pci_lock, flags);
  628.     return 0;
  629. }
  630.  
  631.  
  632. int pci_bus_read_config_dword (struct pci_bus *bus, u32 devfn, int pos, u32 *value)
  633. {
  634.     if ( pos & 3)
  635.         return PCIBIOS_BAD_REGISTER_NUMBER;
  636.     *value = PciRead32(bus->number, devfn, pos);
  637.     return 0;
  638. }
  639.  
  640. int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
  641. {
  642.     if ( where & 3)
  643.         return PCIBIOS_BAD_REGISTER_NUMBER;
  644.     PciWrite32(bus->number, devfn,where, val);
  645.     return 0;
  646. }
  647.