Subversion Repositories Kolibri OS

Rev

Rev 1631 | Rev 2187 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <ddk.h>
  3. #include <linux/errno.h>
  4. #include <mutex.h>
  5. #include <pci.h>
  6. #include <syscall.h>
  7.  
  8.  
  9. #define IO_SPACE_LIMIT          0xffff
  10. #define PCIBIOS_SUCCESSFUL      0x00
  11.  
  12. struct resource ioport_resource = {
  13.     .name   = "PCI IO",
  14.     .start  = 0,
  15.     .end    = IO_SPACE_LIMIT,
  16.     .flags  = IORESOURCE_IO,
  17. };
  18.  
  19. struct resource iomem_resource = {
  20.     .name   = "PCI mem",
  21.     .start  = 0,
  22.     .end    = -1,
  23.     .flags  = IORESOURCE_MEM,
  24. };
  25.  
  26. #define PCI_FIND_CAP_TTL    48
  27.  
  28. static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
  29.                    u8 pos, int cap, int *ttl)
  30. {
  31.     u8 id;
  32.  
  33.     while ((*ttl)--) {
  34.         pci_bus_read_config_byte(bus, devfn, pos, &pos);
  35.         if (pos < 0x40)
  36.             break;
  37.         pos &= ~3;
  38.         pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
  39.                      &id);
  40.         if (id == 0xff)
  41.             break;
  42.         if (id == cap)
  43.             return pos;
  44.         pos += PCI_CAP_LIST_NEXT;
  45.     }
  46.     return 0;
  47. }
  48.  
  49. static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
  50.                    u8 pos, int cap)
  51. {
  52.     int ttl = PCI_FIND_CAP_TTL;
  53.  
  54.     return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
  55. }
  56. static int __pci_bus_find_cap_start(struct pci_bus *bus,
  57.                     unsigned int devfn, u8 hdr_type)
  58. {
  59.     u16 status;
  60.  
  61.     pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
  62.     if (!(status & PCI_STATUS_CAP_LIST))
  63.         return 0;
  64.  
  65.     switch (hdr_type) {
  66.     case PCI_HEADER_TYPE_NORMAL:
  67.     case PCI_HEADER_TYPE_BRIDGE:
  68.         return PCI_CAPABILITY_LIST;
  69.     case PCI_HEADER_TYPE_CARDBUS:
  70.         return PCI_CB_CAPABILITY_LIST;
  71.     default:
  72.         return 0;
  73.     }
  74.  
  75.     return 0;
  76. }
  77.  
  78.  
  79. /**
  80.  * pci_find_capability - query for devices' capabilities
  81.  * @dev: PCI device to query
  82.  * @cap: capability code
  83.  *
  84.  * Tell if a device supports a given PCI capability.
  85.  * Returns the address of the requested capability structure within the
  86.  * device's PCI configuration space or 0 in case the device does not
  87.  * support it.  Possible values for @cap:
  88.  *
  89.  *  %PCI_CAP_ID_PM           Power Management
  90.  *  %PCI_CAP_ID_AGP          Accelerated Graphics Port
  91.  *  %PCI_CAP_ID_VPD          Vital Product Data
  92.  *  %PCI_CAP_ID_SLOTID       Slot Identification
  93.  *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
  94.  *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap
  95.  *  %PCI_CAP_ID_PCIX         PCI-X
  96.  *  %PCI_CAP_ID_EXP          PCI Express
  97.  */
  98. int pci_find_capability(struct pci_dev *dev, int cap)
  99. {
  100.     int pos;
  101.  
  102.     pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
  103.     if (pos)
  104.         pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
  105.  
  106.     return pos;
  107. }
  108.  
  109.  
  110. static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
  111. {
  112.     struct pci_bus* child;
  113.     struct list_head *tmp;
  114.  
  115.     if(bus->number == busnr)
  116.         return bus;
  117.  
  118.     list_for_each(tmp, &bus->children) {
  119.         child = pci_do_find_bus(pci_bus_b(tmp), busnr);
  120.         if(child)
  121.             return child;
  122.     }
  123.     return NULL;
  124. }
  125.  
  126.  
  127. /**
  128.  * pci_find_bus - locate PCI bus from a given domain and bus number
  129.  * @domain: number of PCI domain to search
  130.  * @busnr: number of desired PCI bus
  131.  *
  132.  * Given a PCI bus number and domain number, the desired PCI bus is located
  133.  * in the global list of PCI buses.  If the bus is found, a pointer to its
  134.  * data structure is returned.  If no bus is found, %NULL is returned.
  135.  */
  136. struct pci_bus * pci_find_bus(int domain, int busnr)
  137. {
  138.     struct pci_bus *bus = NULL;
  139.     struct pci_bus *tmp_bus;
  140.  
  141.     while ((bus = pci_find_next_bus(bus)) != NULL)  {
  142.         if (pci_domain_nr(bus) != domain)
  143.             continue;
  144.         tmp_bus = pci_do_find_bus(bus, busnr);
  145.         if (tmp_bus)
  146.             return tmp_bus;
  147.     }
  148.     return NULL;
  149. }
  150.  
  151. /**
  152.  * pci_find_next_bus - begin or continue searching for a PCI bus
  153.  * @from: Previous PCI bus found, or %NULL for new search.
  154.  *
  155.  * Iterates through the list of known PCI busses.  A new search is
  156.  * initiated by passing %NULL as the @from argument.  Otherwise if
  157.  * @from is not %NULL, searches continue from next device on the
  158.  * global list.
  159.  */
  160. struct pci_bus *
  161. pci_find_next_bus(const struct pci_bus *from)
  162. {
  163.     struct list_head *n;
  164.     struct pci_bus *b = NULL;
  165.  
  166. //    WARN_ON(in_interrupt());
  167. //    down_read(&pci_bus_sem);
  168.     n = from ? from->node.next : pci_root_buses.next;
  169.     if (n != &pci_root_buses)
  170.         b = pci_bus_b(n);
  171. //    up_read(&pci_bus_sem);
  172.     return b;
  173. }
  174.  
  175.  
  176. /**
  177.  * pci_get_slot - locate PCI device for a given PCI slot
  178.  * @bus: PCI bus on which desired PCI device resides
  179.  * @devfn: encodes number of PCI slot in which the desired PCI
  180.  * device resides and the logical device number within that slot
  181.  * in case of multi-function devices.
  182.  *
  183.  * Given a PCI bus and slot/function number, the desired PCI device
  184.  * is located in the list of PCI devices.
  185.  * If the device is found, its reference count is increased and this
  186.  * function returns a pointer to its data structure.  The caller must
  187.  * decrement the reference count by calling pci_dev_put().
  188.  * If no device is found, %NULL is returned.
  189.  */
  190. struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
  191. {
  192.     struct list_head *tmp;
  193.     struct pci_dev *dev;
  194.  
  195. //    WARN_ON(in_interrupt());
  196. //    down_read(&pci_bus_sem);
  197.  
  198.     list_for_each(tmp, &bus->devices) {
  199.         dev = pci_dev_b(tmp);
  200.         if (dev->devfn == devfn)
  201.             goto out;
  202.     }
  203.  
  204.     dev = NULL;
  205.  out:
  206. //    pci_dev_get(dev);
  207. //    up_read(&pci_bus_sem);
  208.     return dev;
  209. }
  210.  
  211.  
  212.  
  213.  
  214. /**
  215.  * pci_find_ext_capability - Find an extended capability
  216.  * @dev: PCI device to query
  217.  * @cap: capability code
  218.  *
  219.  * Returns the address of the requested extended capability structure
  220.  * within the device's PCI configuration space or 0 if the device does
  221.  * not support it.  Possible values for @cap:
  222.  *
  223.  *  %PCI_EXT_CAP_ID_ERR     Advanced Error Reporting
  224.  *  %PCI_EXT_CAP_ID_VC      Virtual Channel
  225.  *  %PCI_EXT_CAP_ID_DSN     Device Serial Number
  226.  *  %PCI_EXT_CAP_ID_PWR     Power Budgeting
  227.  */
  228. int pci_find_ext_capability(struct pci_dev *dev, int cap)
  229. {
  230.     u32 header;
  231.     int ttl;
  232.     int pos = PCI_CFG_SPACE_SIZE;
  233.  
  234.     /* minimum 8 bytes per capability */
  235.     ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
  236.  
  237.     if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
  238.         return 0;
  239.  
  240.     if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
  241.         return 0;
  242.  
  243.     /*
  244.      * If we have no capabilities, this is indicated by cap ID,
  245.      * cap version and next pointer all being 0.
  246.      */
  247.     if (header == 0)
  248.         return 0;
  249.  
  250.     while (ttl-- > 0) {
  251.         if (PCI_EXT_CAP_ID(header) == cap)
  252.             return pos;
  253.  
  254.         pos = PCI_EXT_CAP_NEXT(header);
  255.         if (pos < PCI_CFG_SPACE_SIZE)
  256.             break;
  257.  
  258.         if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
  259.             break;
  260.     }
  261.  
  262.     return 0;
  263. }
  264.  
  265.  
  266. /**
  267.  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  268.  * @dev: the PCI device
  269.  * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
  270.  *
  271.  * Perform INTx swizzling for a device behind one level of bridge.  This is
  272.  * required by section 9.1 of the PCI-to-PCI bridge specification for devices
  273.  * behind bridges on add-in cards.  For devices with ARI enabled, the slot
  274.  * number is always 0 (see the Implementation Note in section 2.2.8.1 of
  275.  * the PCI Express Base Specification, Revision 2.1)
  276.  */
  277. u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin)
  278. {
  279.     int slot;
  280.  
  281.  //   if (pci_ari_enabled(dev->bus))
  282.  //       slot = 0;
  283.  //   else
  284.         slot = PCI_SLOT(dev->devfn);
  285.  
  286.     return (((pin - 1) + slot) % 4) + 1;
  287. }
  288.  
  289.  
  290. #if 0
  291.  
  292. u32 pci_probe = 0;
  293.  
  294. #define PCI_NOASSIGN_ROMS   0x80000
  295. #define PCI_NOASSIGN_BARS   0x200000
  296.  
  297. static void pcibios_fixup_device_resources(struct pci_dev *dev)
  298. {
  299.     struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
  300.     struct resource *bar_r;
  301.     int bar;
  302.  
  303.     if (pci_probe & PCI_NOASSIGN_BARS) {
  304.         /*
  305.         * If the BIOS did not assign the BAR, zero out the
  306.         * resource so the kernel doesn't attmept to assign
  307.         * it later on in pci_assign_unassigned_resources
  308.         */
  309.         for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
  310.             bar_r = &dev->resource[bar];
  311.             if (bar_r->start == 0 && bar_r->end != 0) {
  312.                 bar_r->flags = 0;
  313.                 bar_r->end = 0;
  314.             }
  315.         }
  316.     }
  317.  
  318.     if (pci_probe & PCI_NOASSIGN_ROMS) {
  319.         if (rom_r->parent)
  320.             return;
  321.         if (rom_r->start) {
  322.             /* we deal with BIOS assigned ROM later */
  323.             return;
  324.         }
  325.         rom_r->start = rom_r->end = rom_r->flags = 0;
  326.     }
  327. }
  328.  
  329. /*
  330.  *  Called after each bus is probed, but before its children
  331.  *  are examined.
  332.  */
  333.  
  334. void pcibios_fixup_bus(struct pci_bus *b)
  335. {
  336.     struct pci_dev *dev;
  337.  
  338.     /* root bus? */
  339. //    if (!b->parent)
  340. //        x86_pci_root_bus_res_quirks(b);
  341.     pci_read_bridge_bases(b);
  342.     list_for_each_entry(dev, &b->devices, bus_list)
  343.         pcibios_fixup_device_resources(dev);
  344. }
  345.  
  346. #endif
  347.