Subversion Repositories Kolibri OS

Rev

Rev 1628 | 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.  
  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. #if 0
  266.  
  267. u32 pci_probe = 0;
  268.  
  269. #define PCI_NOASSIGN_ROMS   0x80000
  270. #define PCI_NOASSIGN_BARS   0x200000
  271.  
  272. static void pcibios_fixup_device_resources(struct pci_dev *dev)
  273. {
  274.     struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
  275.     struct resource *bar_r;
  276.     int bar;
  277.  
  278.     if (pci_probe & PCI_NOASSIGN_BARS) {
  279.         /*
  280.         * If the BIOS did not assign the BAR, zero out the
  281.         * resource so the kernel doesn't attmept to assign
  282.         * it later on in pci_assign_unassigned_resources
  283.         */
  284.         for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
  285.             bar_r = &dev->resource[bar];
  286.             if (bar_r->start == 0 && bar_r->end != 0) {
  287.                 bar_r->flags = 0;
  288.                 bar_r->end = 0;
  289.             }
  290.         }
  291.     }
  292.  
  293.     if (pci_probe & PCI_NOASSIGN_ROMS) {
  294.         if (rom_r->parent)
  295.             return;
  296.         if (rom_r->start) {
  297.             /* we deal with BIOS assigned ROM later */
  298.             return;
  299.         }
  300.         rom_r->start = rom_r->end = rom_r->flags = 0;
  301.     }
  302. }
  303.  
  304. /*
  305.  *  Called after each bus is probed, but before its children
  306.  *  are examined.
  307.  */
  308.  
  309. void pcibios_fixup_bus(struct pci_bus *b)
  310. {
  311.     struct pci_dev *dev;
  312.  
  313.     /* root bus? */
  314. //    if (!b->parent)
  315. //        x86_pci_root_bus_res_quirks(b);
  316.     pci_read_bridge_bases(b);
  317.     list_for_each_entry(dev, &b->devices, bus_list)
  318.         pcibios_fixup_device_resources(dev);
  319. }
  320.  
  321. #endif
  322.