ddk: fix strcpy
devman: scan pci root bus git-svn-id: svn://kolibrios.org@1627 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
151
drivers/devman/pci/pci.c
Normal file
151
drivers/devman/pci/pci.c
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
#include <ddk.h>
|
||||
#include <linux/errno.h>
|
||||
#include <mutex.h>
|
||||
#include <pci.h>
|
||||
#include <syscall.h>
|
||||
|
||||
LIST_HEAD(pci_root_buses);
|
||||
|
||||
#define IO_SPACE_LIMIT 0xffff
|
||||
|
||||
struct resource ioport_resource = {
|
||||
.name = "PCI IO",
|
||||
.start = 0,
|
||||
.end = IO_SPACE_LIMIT,
|
||||
.flags = IORESOURCE_IO,
|
||||
};
|
||||
|
||||
struct resource iomem_resource = {
|
||||
.name = "PCI mem",
|
||||
.start = 0,
|
||||
.end = -1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
|
||||
static inline int pci_domain_nr(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_sysdata *sd = bus->sysdata;
|
||||
return sd->domain;
|
||||
}
|
||||
|
||||
static struct pci_bus * pci_alloc_bus(void)
|
||||
{
|
||||
struct pci_bus *b;
|
||||
|
||||
b = kzalloc(sizeof(*b), GFP_KERNEL);
|
||||
if (b) {
|
||||
INIT_LIST_HEAD(&b->node);
|
||||
INIT_LIST_HEAD(&b->children);
|
||||
INIT_LIST_HEAD(&b->devices);
|
||||
INIT_LIST_HEAD(&b->slots);
|
||||
INIT_LIST_HEAD(&b->resources);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
struct pci_bus * pci_create_bus(int bus, struct pci_ops *ops, void *sysdata)
|
||||
{
|
||||
int error;
|
||||
struct pci_bus *b, *b2;
|
||||
|
||||
b = pci_alloc_bus();
|
||||
if (!b)
|
||||
return NULL;
|
||||
|
||||
b->sysdata = sysdata;
|
||||
b->ops = ops;
|
||||
|
||||
b2 = pci_find_bus(pci_domain_nr(b), bus);
|
||||
if (b2) {
|
||||
/* If we already got to this bus through a different bridge, ignore it */
|
||||
dbgprintf("bus already known\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
// down_write(&pci_bus_sem);
|
||||
list_add_tail(&b->node, &pci_root_buses);
|
||||
// up_write(&pci_bus_sem);
|
||||
|
||||
b->number = b->secondary = bus;
|
||||
b->resource[0] = &ioport_resource;
|
||||
b->resource[1] = &iomem_resource;
|
||||
|
||||
return b;
|
||||
|
||||
err_out:
|
||||
kfree(b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
|
||||
{
|
||||
struct pci_bus* child;
|
||||
struct list_head *tmp;
|
||||
|
||||
if(bus->number == busnr)
|
||||
return bus;
|
||||
|
||||
list_for_each(tmp, &bus->children) {
|
||||
child = pci_do_find_bus(pci_bus_b(tmp), busnr);
|
||||
if(child)
|
||||
return child;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pci_find_bus - locate PCI bus from a given domain and bus number
|
||||
* @domain: number of PCI domain to search
|
||||
* @busnr: number of desired PCI bus
|
||||
*
|
||||
* Given a PCI bus number and domain number, the desired PCI bus is located
|
||||
* in the global list of PCI buses. If the bus is found, a pointer to its
|
||||
* data structure is returned. If no bus is found, %NULL is returned.
|
||||
*/
|
||||
struct pci_bus * pci_find_bus(int domain, int busnr)
|
||||
{
|
||||
struct pci_bus *bus = NULL;
|
||||
struct pci_bus *tmp_bus;
|
||||
|
||||
while ((bus = pci_find_next_bus(bus)) != NULL) {
|
||||
if (pci_domain_nr(bus) != domain)
|
||||
continue;
|
||||
tmp_bus = pci_do_find_bus(bus, busnr);
|
||||
if (tmp_bus)
|
||||
return tmp_bus;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_find_next_bus - begin or continue searching for a PCI bus
|
||||
* @from: Previous PCI bus found, or %NULL for new search.
|
||||
*
|
||||
* Iterates through the list of known PCI busses. A new search is
|
||||
* initiated by passing %NULL as the @from argument. Otherwise if
|
||||
* @from is not %NULL, searches continue from next device on the
|
||||
* global list.
|
||||
*/
|
||||
struct pci_bus *
|
||||
pci_find_next_bus(const struct pci_bus *from)
|
||||
{
|
||||
struct list_head *n;
|
||||
struct pci_bus *b = NULL;
|
||||
|
||||
// WARN_ON(in_interrupt());
|
||||
// down_read(&pci_bus_sem);
|
||||
n = from ? from->node.next : pci_root_buses.next;
|
||||
if (n != &pci_root_buses)
|
||||
b = pci_bus_b(n);
|
||||
// up_read(&pci_bus_sem);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user