FreeBSD/sys/kern/subr_rman.c
/*
 * Sysctl interface for scanning the resource lists.
 *
 * We take two input parameters; the index into the list of resource
 * managers, and the resource offset into the list.
 */
Sysctl interface for scanning the resource lists.
We take two input parameters; the index into the list of resource
managers, and the resource offset into the list.
Sysctl interface for scanning the resource lists . We take two input parameters ; the index into the list of resource managers and the resource offset into the list .
static int
sysctl_rman(SYSCTL_HANDLER_ARGS)
{
	int			*name = (int *)arg1;
	u_int			namelen = arg2;
	int			rman_idx, res_idx;
	struct rman		*rm;
	struct resource_i	*res;
	struct resource_i	*sres;
	struct u_rman		urm;
	struct u_resource	ures;
	int			error;
	if (namelen != 3)
		return (EINVAL);
	if (bus_data_generation_check(name[0]))
		return (EINVAL);
	rman_idx = name[1];
	res_idx = name[2];
	mtx_lock(&rman_mtx);
	TAILQ_FOREACH(rm, &rman_head, rm_link) {
		if (rman_idx-- == 0)
			break;
	}
	mtx_unlock(&rman_mtx);
	if (rm == NULL)
		return (ENOENT);
	if (res_idx == -1) {
		bzero(&urm, sizeof(urm));
		urm.rm_handle = (uintptr_t)rm;
		if (rm->rm_descr != NULL)
			strlcpy(urm.rm_descr, rm->rm_descr, RM_TEXTLEN);
		urm.rm_start = rm->rm_start;
		urm.rm_size = rm->rm_end - rm->rm_start + 1;
		urm.rm_type = rm->rm_type;
		error = SYSCTL_OUT(req, &urm, sizeof(urm));
		return (error);
	}
	mtx_lock(rm->rm_mtx);
	TAILQ_FOREACH(res, &rm->rm_list, r_link) {
		if (res->r_sharehead != NULL) {
			LIST_FOREACH(sres, res->r_sharehead, r_sharelink)
				if (res_idx-- == 0) {
					res = sres;
					goto found;
				}
		}
		else if (res_idx-- == 0)
				goto found;
	}
	mtx_unlock(rm->rm_mtx);
	return (ENOENT);
found:
	bzero(&ures, sizeof(ures));
	ures.r_handle = (uintptr_t)res;
	ures.r_parent = (uintptr_t)res->r_rm;
	ures.r_device = (uintptr_t)res->r_dev;
	if (res->r_dev != NULL) {
		if (device_get_name(res->r_dev) != NULL) {
			snprintf(ures.r_devname, RM_TEXTLEN,
			    "%s%d",
			    device_get_name(res->r_dev),
			    device_get_unit(res->r_dev));
		} else {
			strlcpy(ures.r_devname, "nomatch",
			    RM_TEXTLEN);
		}
	} else {
		ures.r_devname[0] = '\0';
	}
	ures.r_start = res->r_start;
	ures.r_size = res->r_end - res->r_start + 1;
	ures.r_flags = res->r_flags;
	mtx_unlock(rm->rm_mtx);
	error = SYSCTL_OUT(req, &ures, sizeof(ures));
	return (error);
}
static int sysctl_rman ( SYSCTL_HANDLER_ARGS ) { int * name = ( int * ) arg1 ; u_int namelen = arg2 ; int rman_idx , res_idx ; struct rman * rm ; struct resource_i * res ; struct resource_i * sres ; struct u_rman urm ; struct u_resource ures ; int error ; if ( namelen != 3 ) return ( EINVAL ) ; if ( bus_data_generation_check ( name [ 0 ] ) ) return ( EINVAL ) ; rman_idx = name [ 1 ] ; res_idx = name [ 2 ] ; mtx_lock ( & rman_mtx ) ; TAILQ_FOREACH ( rm , & rman_head , rm_link ) { if ( rman_idx -- == 0 ) break ; } mtx_unlock ( & rman_mtx ) ; if ( rm == NULL ) return ( ENOENT ) ; if ( res_idx == -1 ) { bzero ( & urm , sizeof ( urm ) ) ; urm . rm_handle = ( uintptr_t ) rm ; if ( rm -> rm_descr != NULL ) strlcpy ( urm . rm_descr , rm -> rm_descr , RM_TEXTLEN ) ; urm . rm_start = rm -> rm_start ; urm . rm_size = rm -> rm_end - rm -> rm_start + 1 ; urm . rm_type = rm -> rm_type ; error = SYSCTL_OUT ( req , & urm , sizeof ( urm ) ) ; return ( error ) ; } mtx_lock ( rm -> rm_mtx ) ; TAILQ_FOREACH ( res , & rm -> rm_list , r_link ) { if ( res -> r_sharehead != NULL ) { LIST_FOREACH ( sres , res -> r_sharehead , r_sharelink ) if ( res_idx -- == 0 ) { res = sres ; goto found ; } } else if ( res_idx -- == 0 ) goto found ; } mtx_unlock ( rm -> rm_mtx ) ; return ( ENOENT ) ; found : bzero ( & ures , sizeof ( ures ) ) ; ures . r_handle = ( uintptr_t ) res ; ures . r_parent = ( uintptr_t ) res -> r_rm ; ures . r_device = ( uintptr_t ) res -> r_dev ; if ( res -> r_dev != NULL ) { if ( device_get_name ( res -> r_dev ) != NULL ) { snprintf ( ures . r_devname , RM_TEXTLEN , " " , device_get_name ( res -> r_dev ) , device_get_unit ( res -> r_dev ) ) ; } else { strlcpy ( ures . r_devname , " " , RM_TEXTLEN ) ; } } else { ures . r_devname [ 0 ] = ' \0 ' ; } ures . r_start = res -> r_start ; ures . r_size = res -> r_end - res -> r_start + 1 ; ures . r_flags = res -> r_flags ; mtx_unlock ( rm -> rm_mtx ) ; error = SYSCTL_OUT ( req , & ures , sizeof ( ures ) ) ; return ( error ) ; }
Sysctl interface for scanning the resource lists.
Sysctl interface for scanning the resource lists .
/*
	 * Find the indexed resource manager
	 */ /*
	 * If the resource index is -1, we want details on the
	 * resource manager.
	 */ /*
	 * Find the indexed resource and return it.
	 */