Subversion Repositories Kolibri OS

Rev

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