Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_bus.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#include <sys/poll.h> | #include <sys/poll.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/condvar.h> | #include <sys/condvar.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <sys/random.h> | #include <sys/random.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/sbuf.h> | |||||
#include <sys/selinfo.h> | #include <sys/selinfo.h> | ||||
#include <sys/signalvar.h> | #include <sys/signalvar.h> | ||||
#include <sys/smp.h> | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/interrupt.h> | #include <sys/interrupt.h> | ||||
#include <sys/cpuset.h> | #include <sys/cpuset.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | struct device { | ||||
uint32_t devflags; /**< api level flags for device_get_flags() */ | uint32_t devflags; /**< api level flags for device_get_flags() */ | ||||
u_int flags; /**< internal device flags */ | u_int flags; /**< internal device flags */ | ||||
u_int order; /**< order from device_add_child_ordered() */ | u_int order; /**< order from device_add_child_ordered() */ | ||||
void *ivars; /**< instance variables */ | void *ivars; /**< instance variables */ | ||||
void *softc; /**< current driver's variables */ | void *softc; /**< current driver's variables */ | ||||
struct sysctl_ctx_list sysctl_ctx; /**< state for sysctl variables */ | struct sysctl_ctx_list sysctl_ctx; /**< state for sysctl variables */ | ||||
struct sysctl_oid *sysctl_tree; /**< state for sysctl variables */ | struct sysctl_oid *sysctl_tree; /**< state for sysctl variables */ | ||||
/* XXX: Temporary for testing */ | |||||
cpuset_t intr_cpus; | |||||
cpuset_t local_cpus; | |||||
}; | }; | ||||
static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures"); | static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures"); | ||||
static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc"); | static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc"); | ||||
static void devctl2_init(void); | static void devctl2_init(void); | ||||
#ifdef BUS_DEBUG | #ifdef BUS_DEBUG | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
error = SYSCTL_OUT_STR(req, value); | error = SYSCTL_OUT_STR(req, value); | ||||
if (buf != NULL) | if (buf != NULL) | ||||
free(buf, M_BUS); | free(buf, M_BUS); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | |||||
device_cpuset_handler(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
cpuset_t *set; | |||||
struct sbuf *sb; | |||||
int cpu, error, once; | |||||
set = arg1; | |||||
sb = sbuf_new_for_sysctl(NULL, NULL, 128, req); | |||||
for (once = 0, cpu = 0; cpu < CPU_SETSIZE; cpu++) { | |||||
if (CPU_ISSET(cpu, set)) { | |||||
if (once == 0) { | |||||
sbuf_printf(sb, "%d", cpu); | |||||
once = 1; | |||||
} else | |||||
sbuf_printf(sb, ",%d", cpu); | |||||
} | |||||
} | |||||
if (once == 0) | |||||
sbuf_printf(sb, "<none>"); | |||||
error = sbuf_finish(sb); | |||||
sbuf_delete(sb); | |||||
return (error); | |||||
} | |||||
static void | static void | ||||
device_sysctl_init(device_t dev) | device_sysctl_init(device_t dev) | ||||
{ | { | ||||
devclass_t dc = dev->devclass; | devclass_t dc = dev->devclass; | ||||
int domain; | int domain; | ||||
if (dev->sysctl_tree != NULL) | if (dev->sysctl_tree != NULL) | ||||
return; | return; | ||||
Show All 22 Lines | device_sysctl_init(device_t dev) | ||||
SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), | SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), | ||||
OID_AUTO, "%parent", CTLTYPE_STRING | CTLFLAG_RD, | OID_AUTO, "%parent", CTLTYPE_STRING | CTLFLAG_RD, | ||||
dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A", | dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A", | ||||
"parent device"); | "parent device"); | ||||
if (bus_get_domain(dev, &domain) == 0) | if (bus_get_domain(dev, &domain) == 0) | ||||
SYSCTL_ADD_INT(&dev->sysctl_ctx, | SYSCTL_ADD_INT(&dev->sysctl_ctx, | ||||
SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%domain", | SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%domain", | ||||
CTLFLAG_RD, NULL, domain, "NUMA domain"); | CTLFLAG_RD, NULL, domain, "NUMA domain"); | ||||
/* XXX: For testing. */ | |||||
if (bus_get_cpus(dev, INTR_CPUS, sizeof(dev->intr_cpus), | |||||
&dev->intr_cpus) == 0) | |||||
SYSCTL_ADD_PROC(&dev->sysctl_ctx, | |||||
SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%intr_cpus", | |||||
CTLTYPE_STRING | CTLFLAG_RD, &dev->intr_cpus, 0, | |||||
device_cpuset_handler, "A", "Interrupt CPUs"); | |||||
if (bus_get_cpus(dev, LOCAL_CPUS, sizeof(dev->local_cpus), | |||||
&dev->local_cpus) == 0) | |||||
SYSCTL_ADD_PROC(&dev->sysctl_ctx, | |||||
SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%local_cpus", | |||||
CTLTYPE_STRING | CTLFLAG_RD, &dev->local_cpus, 0, | |||||
device_cpuset_handler, "A", "Interrupt CPUs"); | |||||
} | } | ||||
static void | static void | ||||
device_sysctl_update(device_t dev) | device_sysctl_update(device_t dev) | ||||
{ | { | ||||
devclass_t dc = dev->devclass; | devclass_t dc = dev->devclass; | ||||
if (dev->sysctl_tree == NULL) | if (dev->sysctl_tree == NULL) | ||||
▲ Show 20 Lines • Show All 3,783 Lines • ▼ Show 20 Lines | bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq, | ||||
/* Propagate up the bus hierarchy until someone handles it. */ | /* Propagate up the bus hierarchy until someone handles it. */ | ||||
if (dev->parent) | if (dev->parent) | ||||
return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie, | return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie, | ||||
descr)); | descr)); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/** | /** | ||||
* @brief Helper function for implementing BUS_GET_CPUS(). | |||||
* | |||||
* This simple implementation of BUS_GET_CPUS() simply calls the | |||||
* BUS_GET_CPUS() method of the parent of @p dev. | |||||
*/ | |||||
int | |||||
bus_generic_get_cpus(device_t dev, device_t child, enum cpu_sets op, | |||||
size_t setsize, cpuset_t *cpuset) | |||||
{ | |||||
/* Propagate up the bus hierarchy until someone handles it. */ | |||||
if (dev->parent != NULL) | |||||
return (BUS_GET_CPUS(dev->parent, child, op, setsize, cpuset)); | |||||
return (EINVAL); | |||||
} | |||||
/** | |||||
* @brief Helper function for implementing BUS_GET_DMA_TAG(). | * @brief Helper function for implementing BUS_GET_DMA_TAG(). | ||||
* | * | ||||
* This simple implementation of BUS_GET_DMA_TAG() simply calls the | * This simple implementation of BUS_GET_DMA_TAG() simply calls the | ||||
* BUS_GET_DMA_TAG() method of the parent of @p dev. | * BUS_GET_DMA_TAG() method of the parent of @p dev. | ||||
*/ | */ | ||||
bus_dma_tag_t | bus_dma_tag_t | ||||
bus_generic_get_dma_tag(device_t dev, device_t child) | bus_generic_get_dma_tag(device_t dev, device_t child) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 493 Lines • ▼ Show 20 Lines | bus_child_location_str(device_t child, char *buf, size_t buflen) | ||||
if (parent == NULL) { | if (parent == NULL) { | ||||
*buf = '\0'; | *buf = '\0'; | ||||
return (0); | return (0); | ||||
} | } | ||||
return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen)); | return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen)); | ||||
} | } | ||||
/** | /** | ||||
* @brief Wrapper function for BUS_GET_CPUS(). | |||||
* | |||||
* This function simply calls the BUS_GET_CPUS() method of the | |||||
* parent of @p dev. | |||||
*/ | |||||
int | |||||
bus_get_cpus(device_t dev, enum cpu_sets op, size_t setsize, cpuset_t *cpuset) | |||||
{ | |||||
device_t parent; | |||||
parent = device_get_parent(dev); | |||||
if (parent == NULL) | |||||
return (EINVAL); | |||||
return (BUS_GET_CPUS(parent, dev, op, setsize, cpuset)); | |||||
} | |||||
/** | |||||
* @brief Wrapper function for BUS_GET_DMA_TAG(). | * @brief Wrapper function for BUS_GET_DMA_TAG(). | ||||
* | * | ||||
* This function simply calls the BUS_GET_DMA_TAG() method of the | * This function simply calls the BUS_GET_DMA_TAG() method of the | ||||
* parent of @p dev. | * parent of @p dev. | ||||
*/ | */ | ||||
bus_dma_tag_t | bus_dma_tag_t | ||||
bus_get_dma_tag(device_t dev) | bus_get_dma_tag(device_t dev) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
* chain. | * chain. | ||||
*/ | */ | ||||
static int | static int | ||||
root_child_present(device_t dev, device_t child) | root_child_present(device_t dev, device_t child) | ||||
{ | { | ||||
return (-1); | return (-1); | ||||
} | } | ||||
static int | |||||
root_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, | |||||
cpuset_t *cpuset) | |||||
{ | |||||
switch (op) { | |||||
case INTR_CPUS: | |||||
/* Default to returning the set of all CPUs. */ | |||||
if (setsize != sizeof(cpuset_t)) | |||||
return (EINVAL); | |||||
*cpuset = all_cpus; | |||||
return (0); | |||||
default: | |||||
return (EINVAL); | |||||
} | |||||
} | |||||
static kobj_method_t root_methods[] = { | static kobj_method_t root_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
KOBJMETHOD(device_shutdown, bus_generic_shutdown), | KOBJMETHOD(device_shutdown, bus_generic_shutdown), | ||||
KOBJMETHOD(device_suspend, bus_generic_suspend), | KOBJMETHOD(device_suspend, bus_generic_suspend), | ||||
KOBJMETHOD(device_resume, root_resume), | KOBJMETHOD(device_resume, root_resume), | ||||
/* Bus interface */ | /* Bus interface */ | ||||
KOBJMETHOD(bus_print_child, root_print_child), | KOBJMETHOD(bus_print_child, root_print_child), | ||||
KOBJMETHOD(bus_read_ivar, bus_generic_read_ivar), | KOBJMETHOD(bus_read_ivar, bus_generic_read_ivar), | ||||
KOBJMETHOD(bus_write_ivar, bus_generic_write_ivar), | KOBJMETHOD(bus_write_ivar, bus_generic_write_ivar), | ||||
KOBJMETHOD(bus_setup_intr, root_setup_intr), | KOBJMETHOD(bus_setup_intr, root_setup_intr), | ||||
KOBJMETHOD(bus_child_present, root_child_present), | KOBJMETHOD(bus_child_present, root_child_present), | ||||
KOBJMETHOD(bus_get_cpus, root_get_cpus), | |||||
KOBJMETHOD_END | KOBJMETHOD_END | ||||
}; | }; | ||||
static driver_t root_driver = { | static driver_t root_driver = { | ||||
"root", | "root", | ||||
root_methods, | root_methods, | ||||
1, /* no softc */ | 1, /* no softc */ | ||||
▲ Show 20 Lines • Show All 693 Lines • Show Last 20 Lines |