Subversion Repositories Kolibri OS

Rev

Rev 1628 | 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. LIST_HEAD(pci_root_buses);
  9.  
  10. #define IO_SPACE_LIMIT 0xffff
  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.  
  27. static inline int pci_domain_nr(struct pci_bus *bus)
  28. {
  29.     struct pci_sysdata *sd = bus->sysdata;
  30.     return sd->domain;
  31. }
  32.  
  33. static struct pci_bus * pci_alloc_bus(void)
  34. {
  35.     struct pci_bus *b;
  36.  
  37.     b = kzalloc(sizeof(*b), GFP_KERNEL);
  38.     if (b) {
  39.         INIT_LIST_HEAD(&b->node);
  40.         INIT_LIST_HEAD(&b->children);
  41.         INIT_LIST_HEAD(&b->devices);
  42.         INIT_LIST_HEAD(&b->slots);
  43.         INIT_LIST_HEAD(&b->resources);
  44.     }
  45.     return b;
  46. }
  47.  
  48. struct pci_bus * pci_create_bus(int bus, struct pci_ops *ops, void *sysdata)
  49. {
  50.     int error;
  51.     struct pci_bus *b, *b2;
  52.  
  53.     b = pci_alloc_bus();
  54.     if (!b)
  55.         return NULL;
  56.  
  57.     b->sysdata = sysdata;
  58.     b->ops = ops;
  59.  
  60.     b2 = pci_find_bus(pci_domain_nr(b), bus);
  61.     if (b2) {
  62.         /* If we already got to this bus through a different bridge, ignore it */
  63.         dbgprintf("bus already known\n");
  64.         goto err_out;
  65.     }
  66.  
  67. //    down_write(&pci_bus_sem);
  68.     list_add_tail(&b->node, &pci_root_buses);
  69. //    up_write(&pci_bus_sem);
  70.  
  71.     b->number = b->secondary = bus;
  72.     b->resource[0] = &ioport_resource;
  73.     b->resource[1] = &iomem_resource;
  74.  
  75.     return b;
  76.  
  77. err_out:
  78.     kfree(b);
  79.     return NULL;
  80. }
  81.  
  82.  
  83.  
  84.  
  85.  
  86. static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
  87. {
  88.     struct pci_bus* child;
  89.     struct list_head *tmp;
  90.  
  91.     if(bus->number == busnr)
  92.         return bus;
  93.  
  94.     list_for_each(tmp, &bus->children) {
  95.         child = pci_do_find_bus(pci_bus_b(tmp), busnr);
  96.         if(child)
  97.             return child;
  98.     }
  99.     return NULL;
  100. }
  101.  
  102.  
  103. /**
  104.  * pci_find_bus - locate PCI bus from a given domain and bus number
  105.  * @domain: number of PCI domain to search
  106.  * @busnr: number of desired PCI bus
  107.  *
  108.  * Given a PCI bus number and domain number, the desired PCI bus is located
  109.  * in the global list of PCI buses.  If the bus is found, a pointer to its
  110.  * data structure is returned.  If no bus is found, %NULL is returned.
  111.  */
  112. struct pci_bus * pci_find_bus(int domain, int busnr)
  113. {
  114.     struct pci_bus *bus = NULL;
  115.     struct pci_bus *tmp_bus;
  116.  
  117.     while ((bus = pci_find_next_bus(bus)) != NULL)  {
  118.         if (pci_domain_nr(bus) != domain)
  119.             continue;
  120.         tmp_bus = pci_do_find_bus(bus, busnr);
  121.         if (tmp_bus)
  122.             return tmp_bus;
  123.     }
  124.     return NULL;
  125. }
  126.  
  127. /**
  128.  * pci_find_next_bus - begin or continue searching for a PCI bus
  129.  * @from: Previous PCI bus found, or %NULL for new search.
  130.  *
  131.  * Iterates through the list of known PCI busses.  A new search is
  132.  * initiated by passing %NULL as the @from argument.  Otherwise if
  133.  * @from is not %NULL, searches continue from next device on the
  134.  * global list.
  135.  */
  136. struct pci_bus *
  137. pci_find_next_bus(const struct pci_bus *from)
  138. {
  139.     struct list_head *n;
  140.     struct pci_bus *b = NULL;
  141.  
  142. //    WARN_ON(in_interrupt());
  143. //    down_read(&pci_bus_sem);
  144.     n = from ? from->node.next : pci_root_buses.next;
  145.     if (n != &pci_root_buses)
  146.         b = pci_bus_b(n);
  147. //    up_read(&pci_bus_sem);
  148.     return b;
  149. }
  150.  
  151.  
  152.