Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_bus.c
| Show First 20 Lines • Show All 3,127 Lines • ▼ Show 20 Lines | |||||
| * @brief Helper function for implementing BUS_RELEASE_RESOURCE() | * @brief Helper function for implementing BUS_RELEASE_RESOURCE() | ||||
| * | * | ||||
| * Implement BUS_RELEASE_RESOURCE() using a resource list. Normally | * Implement BUS_RELEASE_RESOURCE() using a resource list. Normally | ||||
| * used with resource_list_alloc(). | * used with resource_list_alloc(). | ||||
| * | * | ||||
| * @param rl the resource list which was allocated from | * @param rl the resource list which was allocated from | ||||
| * @param bus the parent device of @p child | * @param bus the parent device of @p child | ||||
| * @param child the device which is requesting a release | * @param child the device which is requesting a release | ||||
| * @param type the type of resource to release | |||||
| * @param rid the resource identifier | |||||
| * @param res the resource to release | * @param res the resource to release | ||||
| * | * | ||||
| * @retval 0 success | * @retval 0 success | ||||
| * @retval non-zero a standard unix error code indicating what | * @retval non-zero a standard unix error code indicating what | ||||
| * error condition prevented the operation | * error condition prevented the operation | ||||
| */ | */ | ||||
| int | int | ||||
| resource_list_release(struct resource_list *rl, device_t bus, device_t child, | resource_list_release(struct resource_list *rl, device_t bus, device_t child, | ||||
| int type, int rid, struct resource *res) | struct resource *res) | ||||
| { | { | ||||
| struct resource_list_entry *rle = NULL; | struct resource_list_entry *rle = NULL; | ||||
| int passthrough = (device_get_parent(child) != bus); | int passthrough = (device_get_parent(child) != bus); | ||||
| int error; | int error; | ||||
| if (passthrough) { | if (passthrough) { | ||||
| return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child, | return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child, | ||||
| type, rid, res)); | res)); | ||||
| } | } | ||||
| rle = resource_list_find(rl, type, rid); | rle = resource_list_find(rl, rman_get_type(res), rman_get_rid(res)); | ||||
| if (!rle) | if (!rle) | ||||
| panic("resource_list_release: can't find resource"); | panic("resource_list_release: can't find resource"); | ||||
| if (!rle->res) | if (!rle->res) | ||||
| panic("resource_list_release: resource entry is not busy"); | panic("resource_list_release: resource entry is not busy"); | ||||
| if (rle->flags & RLE_RESERVED) { | if (rle->flags & RLE_RESERVED) { | ||||
| if (rle->flags & RLE_ALLOCATED) { | if (rle->flags & RLE_ALLOCATED) { | ||||
| if (rman_get_flags(res) & RF_ACTIVE) { | if (rman_get_flags(res) & RF_ACTIVE) { | ||||
| error = bus_deactivate_resource(child, type, | error = bus_deactivate_resource(child, res); | ||||
| rid, res); | |||||
| if (error) | if (error) | ||||
| return (error); | return (error); | ||||
| } | } | ||||
| rle->flags &= ~RLE_ALLOCATED; | rle->flags &= ~RLE_ALLOCATED; | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| return (EINVAL); | return (EINVAL); | ||||
| } | } | ||||
| error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, | error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, res); | ||||
| type, rid, res); | |||||
| if (error) | if (error) | ||||
| return (error); | return (error); | ||||
| rle->res = NULL; | rle->res = NULL; | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| /** | /** | ||||
| Show All 23 Lines | STAILQ_FOREACH(rle, rl, link) { | ||||
| if (rle->type != type) | if (rle->type != type) | ||||
| continue; | continue; | ||||
| if (rle->res == NULL) | if (rle->res == NULL) | ||||
| continue; | continue; | ||||
| if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == | if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == | ||||
| RLE_RESERVED) | RLE_RESERVED) | ||||
| continue; | continue; | ||||
| retval = EBUSY; | retval = EBUSY; | ||||
| error = resource_list_release(rl, bus, child, type, | error = resource_list_release(rl, bus, child, rle->res); | ||||
| rman_get_rid(rle->res), rle->res); | |||||
| if (error != 0) | if (error != 0) | ||||
| device_printf(bus, | device_printf(bus, | ||||
| "Failed to release active resource: %d\n", error); | "Failed to release active resource: %d\n", error); | ||||
| } | } | ||||
| return (retval); | return (retval); | ||||
| } | } | ||||
| /** | /** | ||||
| Show All 27 Lines | resource_list_unreserve(struct resource_list *rl, device_t bus, device_t child, | ||||
| if (!rle) | if (!rle) | ||||
| panic("resource_list_unreserve: can't find resource"); | panic("resource_list_unreserve: can't find resource"); | ||||
| if (!(rle->flags & RLE_RESERVED)) | if (!(rle->flags & RLE_RESERVED)) | ||||
| return (EINVAL); | return (EINVAL); | ||||
| if (rle->flags & RLE_ALLOCATED) | if (rle->flags & RLE_ALLOCATED) | ||||
| return (EBUSY); | return (EBUSY); | ||||
| rle->flags &= ~RLE_RESERVED; | rle->flags &= ~RLE_RESERVED; | ||||
| return (resource_list_release(rl, bus, child, type, rid, rle->res)); | return (resource_list_release(rl, bus, child, rle->res)); | ||||
| } | } | ||||
| /** | /** | ||||
| * @brief Print a description of resources in a resource list | * @brief Print a description of resources in a resource list | ||||
| * | * | ||||
| * Print all resources of a specified type, for use in BUS_PRINT_CHILD(). | * Print all resources of a specified type, for use in BUS_PRINT_CHILD(). | ||||
| * The name is printed if at least one resource of the given type is available. | * The name is printed if at least one resource of the given type is available. | ||||
| * The format is used to print resource start and end. | * The format is used to print resource start and end. | ||||
| ▲ Show 20 Lines • Show All 651 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). | * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). | ||||
| * | * | ||||
| * This simple implementation of BUS_RELEASE_RESOURCE() simply calls the | * This simple implementation of BUS_RELEASE_RESOURCE() simply calls the | ||||
| * BUS_RELEASE_RESOURCE() method of the parent of @p dev. | * BUS_RELEASE_RESOURCE() method of the parent of @p dev. | ||||
| */ | */ | ||||
| int | int | ||||
| bus_generic_release_resource(device_t dev, device_t child, int type, int rid, | bus_generic_release_resource(device_t dev, device_t child, struct resource *r) | ||||
| struct resource *r) | |||||
| { | { | ||||
| /* 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_RELEASE_RESOURCE(dev->parent, child, type, rid, | return (BUS_RELEASE_RESOURCE(dev->parent, child, r)); | ||||
| r)); | |||||
| return (EINVAL); | return (EINVAL); | ||||
| } | } | ||||
| /** | /** | ||||
| * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE(). | * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE(). | ||||
| * | * | ||||
| * This simple implementation of BUS_ACTIVATE_RESOURCE() simply calls the | * This simple implementation of BUS_ACTIVATE_RESOURCE() simply calls the | ||||
| * BUS_ACTIVATE_RESOURCE() method of the parent of @p dev. | * BUS_ACTIVATE_RESOURCE() method of the parent of @p dev. | ||||
| ▲ Show 20 Lines • Show All 229 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). | * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). | ||||
| * | * | ||||
| * This implementation of BUS_RELEASE_RESOURCE() uses the | * This implementation of BUS_RELEASE_RESOURCE() uses the | ||||
| * resource_list_release() function to do most of the work. It calls | * resource_list_release() function to do most of the work. It calls | ||||
| * BUS_GET_RESOURCE_LIST() to find a suitable resource list. | * BUS_GET_RESOURCE_LIST() to find a suitable resource list. | ||||
| */ | */ | ||||
| int | int | ||||
| bus_generic_rl_release_resource(device_t dev, device_t child, int type, | bus_generic_rl_release_resource(device_t dev, device_t child, | ||||
| int rid, struct resource *r) | struct resource *r) | ||||
| { | { | ||||
| struct resource_list * rl = NULL; | struct resource_list * rl = NULL; | ||||
| if (device_get_parent(child) != dev) | if (device_get_parent(child) != dev) | ||||
| return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, | return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, r)); | ||||
| type, rid, r)); | |||||
| rl = BUS_GET_RESOURCE_LIST(dev, child); | rl = BUS_GET_RESOURCE_LIST(dev, child); | ||||
| if (!rl) | if (!rl) | ||||
| return (EINVAL); | return (EINVAL); | ||||
| return (resource_list_release(rl, dev, child, type, rid, r)); | return (resource_list_release(rl, dev, child, r)); | ||||
| } | } | ||||
| /** | /** | ||||
| * @brief Helper function for implementing BUS_ALLOC_RESOURCE(). | * @brief Helper function for implementing BUS_ALLOC_RESOURCE(). | ||||
| * | * | ||||
| * This implementation of BUS_ALLOC_RESOURCE() uses the | * This implementation of BUS_ALLOC_RESOURCE() uses the | ||||
| * resource_list_alloc() function to do most of the work. It calls | * resource_list_alloc() function to do most of the work. It calls | ||||
| * BUS_GET_RESOURCE_LIST() to find a suitable resource list. | * BUS_GET_RESOURCE_LIST() to find a suitable resource list. | ||||
| ▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). | * @brief Helper function for implementing BUS_RELEASE_RESOURCE(). | ||||
| * | * | ||||
| * This implementation of BUS_RELEASE_RESOURCE() releases resources | * This implementation of BUS_RELEASE_RESOURCE() releases resources | ||||
| * allocated by bus_generic_rman_alloc_resource. | * allocated by bus_generic_rman_alloc_resource. | ||||
| */ | */ | ||||
| int | int | ||||
| bus_generic_rman_release_resource(device_t dev, device_t child, int type, | bus_generic_rman_release_resource(device_t dev, device_t child, | ||||
| int rid, struct resource *r) | struct resource *r) | ||||
| { | { | ||||
| #ifdef INVARIANTS | #ifdef INVARIANTS | ||||
| struct rman *rm; | struct rman *rm; | ||||
| #endif | #endif | ||||
| int error; | int error; | ||||
| #ifdef INVARIANTS | #ifdef INVARIANTS | ||||
| rm = BUS_GET_RMAN(dev, type, rman_get_flags(r)); | rm = BUS_GET_RMAN(dev, rman_get_type(r), rman_get_flags(r)); | ||||
| KASSERT(rman_is_region_manager(r, rm), | KASSERT(rman_is_region_manager(r, rm), | ||||
| ("%s: rman %p doesn't match for resource %p", __func__, rm, r)); | ("%s: rman %p doesn't match for resource %p", __func__, rm, r)); | ||||
| #endif | #endif | ||||
| if (rman_get_flags(r) & RF_ACTIVE) { | if (rman_get_flags(r) & RF_ACTIVE) { | ||||
| error = bus_deactivate_resource(child, type, rid, r); | error = bus_deactivate_resource(child, r); | ||||
| if (error != 0) | if (error != 0) | ||||
| return (error); | return (error); | ||||
| } | } | ||||
| return (rman_release_resource(r)); | return (rman_release_resource(r)); | ||||
| } | } | ||||
| /** | /** | ||||
| * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE(). | * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE(). | ||||
| ▲ Show 20 Lines • Show All 337 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * @brief Wrapper function for BUS_RELEASE_RESOURCE(). | * @brief Wrapper function for BUS_RELEASE_RESOURCE(). | ||||
| * | * | ||||
| * This function simply calls the BUS_RELEASE_RESOURCE() method of the | * This function simply calls the BUS_RELEASE_RESOURCE() method of the | ||||
| * parent of @p dev. | * parent of @p dev. | ||||
| */ | */ | ||||
| int | int | ||||
| bus_release_resource(device_t dev, int type, int rid, struct resource *r) | bus_release_resource(device_t dev, struct resource *r) | ||||
| { | { | ||||
| int rv; | int rv; | ||||
| if (dev->parent == NULL) | if (dev->parent == NULL) | ||||
| return (EINVAL); | return (EINVAL); | ||||
| rv = BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r); | rv = BUS_RELEASE_RESOURCE(dev->parent, dev, r); | ||||
| return (rv); | return (rv); | ||||
| } | } | ||||
| int | int | ||||
| bus_release_resource_new(device_t dev, struct resource *r) | bus_release_resource_old(device_t dev, int type, int rid, struct resource *r) | ||||
| { | { | ||||
| return (bus_release_resource(dev, rman_get_type(r), rman_get_rid(r), | return (bus_release_resource(dev, r)); | ||||
| r)); | |||||
| } | } | ||||
| /** | /** | ||||
| * @brief Wrapper function for BUS_SETUP_INTR(). | * @brief Wrapper function for BUS_SETUP_INTR(). | ||||
| * | * | ||||
| * This function simply calls the BUS_SETUP_INTR() method of the | * This function simply calls the BUS_SETUP_INTR() method of the | ||||
| * parent of @p dev. | * parent of @p dev. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 1,428 Lines • Show Last 20 Lines | |||||