⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hcl.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return(0);}/* * hwgraph_vertex_get_next - this routine returns the next sibbling for the  *	device entry given in de.  If there are no more sibbling, NULL  * 	is returned in next_sibbling. * *	Currently we do not have any protection against de being deleted  *	while it's handle is being held. */inthwgraph_vertex_get_next(devfs_handle_t *next_sibbling, devfs_handle_t *de){	*next_sibbling = devfs_get_next_sibling (*de);	if (*next_sibbling != NULL)		*de = *next_sibbling;	return (0);}/* * hwgraph_vertex_destroy - Destroy the devfs entry */inthwgraph_vertex_destroy(devfs_handle_t de){	void *labelcl_info = NULL;	labelcl_info = devfs_get_info(de);	devfs_unregister(de);	if (labelcl_info)		labelcl_info_destroy((labelcl_info_t *)labelcl_info);	return(0);}/*** See if a vertex has an outgoing edge with a specified name.** Vertices in the hwgraph *implicitly* contain these edges:**	"." 	refers to "current vertex"**	".." 	refers to "connect point vertex"**	"char"	refers to current vertex (character device access)**	"block"	refers to current vertex (block device access)*//* * hwgraph_edge_add - This routines has changed from the original conext. * All it does now is to create a symbolic link from "from" to "to". *//* ARGSUSED */inthwgraph_edge_add(devfs_handle_t from, devfs_handle_t to, char *name){	char *path;	int name_start;	devfs_handle_t handle = NULL;	int rv;	path = kmalloc(1024, GFP_KERNEL);	name_start = devfs_generate_path (to, path, 1024);	/*	 * Otherwise, just create a symlink to the vertex.	 * In this case the vertex was previous created with a REAL pathname.	 */	rv = devfs_mk_symlink (from, (const char *)name, 			       DEVFS_FL_DEFAULT, (const char *)&path[name_start],			       &handle, NULL);	name_start = devfs_generate_path (handle, path, 1024);	return(rv);	}/* ARGSUSED */inthwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr){	int namelen = 0;	devfs_handle_t target_handle = NULL;	if (name == NULL)		return(-1);	if (toptr == NULL)		return(-1);	/*	 * If the name is "." just return the current devfs entry handle.	 */	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {		if (toptr) {			*toptr = from;		}	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {		/*		 * Hmmm .. should we return the connect point or parent ..		 * see in hwgraph, the concept of parent is the connectpt!		 *		 * Maybe we should see whether the connectpt is set .. if 		 * not just return the parent!		 */		target_handle = hwgraph_connectpt_get(from);		if (target_handle) {			/*			 * Just return the connect point.			 */			*toptr = target_handle;			return(0);		}		target_handle = devfs_get_parent(from);		*toptr = target_handle;	} else {		/*		 * Call devfs to get the devfs entry.		 */		namelen = (int) strlen(name);		target_handle = devfs_find_handle (from, name, 0, 0,					0, 1); /* Yes traverse symbolic links */		if (target_handle == NULL)			return(-1);		else		*toptr = target_handle;	}	return(0);}/* * hwgraph_edge_get_next - Retrieves the next sibbling given the current *	entry number "placeptr". * * 	Allow the caller to retrieve walk through the sibblings of "source"  * 	devfs_handle_t.  The implicit edges "." and ".." is returned first  * 	followed by each of the real children. * *	We may end up returning garbage if another thread perform any deletion  *	in this directory before "placeptr". * *//* ARGSUSED */inthwgraph_edge_get_next(devfs_handle_t source, char *name, devfs_handle_t *target,                              uint *placeptr){        uint which_place;	unsigned int namelen = 0;	const char *tempname = NULL;        if (placeptr == NULL)                return(-1);        which_place = *placeptr;again:        if (which_place <= HWGRAPH_RESERVED_PLACES) {                if (which_place == EDGE_PLACE_WANT_CURRENT) {			/*			 * Looking for "."			 * Return the current devfs handle.			 */                        if (name != NULL)                                strcpy(name, HWGRAPH_EDGELBL_DOT);                        if (target != NULL) {                                *target = source; 				/* XXX should incr "source" ref count here if we				 * ever implement ref counts */                        }                } else if (which_place == EDGE_PLACE_WANT_CONNECTPT) {			/*			 * Looking for the connect point or parent.			 * If the connect point is set .. it returns the connect point.			 * Otherwise, it returns the parent .. will we support 			 * connect point?			 */                        devfs_handle_t connect_point = hwgraph_connectpt_get(source);                        if (connect_point == NULL) {				/*				 * No connectpoint set .. either the User				 * explicitly NULL it or this node was not 				 * created via hcl.				 */                                which_place++;                                goto again;                        }                        if (name != NULL)                                strcpy(name, HWGRAPH_EDGELBL_DOTDOT);                        if (target != NULL)                                *target = connect_point;                } else if (which_place == EDGE_PLACE_WANT_REAL_EDGES) {			/* 			 * return first "real" entry in directory, and increment			 * placeptr.  Next time around we should have 			 * which_place > HWGRAPH_RESERVED_EDGES so we'll fall through			 * this nested if block.			 */			*target = devfs_get_first_child(source);			if (*target && name) {				tempname = devfs_get_name(*target, &namelen);				if (tempname && namelen)					strcpy(name, tempname);			}								*placeptr = which_place + 1;			return (0);                }                *placeptr = which_place+1;                return(0);        }	/*	 * walk linked list, (which_place - HWGRAPH_RESERVED_PLACES) times	 */	{		devfs_handle_t	curr;		int		i = 0;		for (curr=devfs_get_first_child(source), i= i+HWGRAPH_RESERVED_PLACES; 			curr!=NULL && i<which_place; 			curr=devfs_get_next_sibling(curr), i++)			;		*target = curr;		*placeptr = which_place + 1;		if (curr && name) {			tempname = devfs_get_name(*target, &namelen);			printk("hwgraph_edge_get_next: Component name = %s, length = %d\n", tempname, namelen);			if (tempname && namelen)				strcpy(name, tempname);		}	}	if (target == NULL)		return(-1);	else        	return(0);}/* * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc *	of the label as INFO_DESC_PRIVATE and store the info in the label. *//* ARGSUSED */inthwgraph_info_add_LBL(	devfs_handle_t de,			char *name,			arbitrary_info_t info){	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));}/* * hwgraph_info_remove_LBL - Remove the label entry for the device. *//* ARGSUSED */inthwgraph_info_remove_LBL(	devfs_handle_t de,				char *name,				arbitrary_info_t *old_info){	return(labelcl_info_remove_LBL(de, name, NULL, old_info));}/* * hwgraph_info_replace_LBL - replaces an existing label with  *	a new label info value. *//* ARGSUSED */inthwgraph_info_replace_LBL(	devfs_handle_t de,				char *name,				arbitrary_info_t info,				arbitrary_info_t *old_info){	return(labelcl_info_replace_LBL(de, name,			INFO_DESC_PRIVATE, info,			NULL, old_info));}/* * hwgraph_info_get_LBL - Get and return the info value in the label of the  * 	device. *//* ARGSUSED */inthwgraph_info_get_LBL(	devfs_handle_t de,			char *name,			arbitrary_info_t *infop){	return(labelcl_info_get_LBL(de, name, NULL, infop));}/* * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer  *	of the given label for the device.  The weird thing is that the label  *	that matches the name is return irrespective of the info_desc value! *	Do not understand why the word "exported" is used! *//* ARGSUSED */inthwgraph_info_get_exported_LBL(	devfs_handle_t de,				char *name,				int *export_info,				arbitrary_info_t *infop){	int rc;	arb_info_desc_t info_desc;	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);	if (rc == 0)		*export_info = (int)info_desc;	return(rc);}/* * hwgraph_info_get_next_LBL - Returns the next label info given the  *	current label entry in place. * *	Once again this has no locking or reference count for protection. * *//* ARGSUSED */inthwgraph_info_get_next_LBL(	devfs_handle_t de,				char *buf,				arbitrary_info_t *infop,				labelcl_info_place_t *place){	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));}/* * hwgraph_info_export_LBL - Retrieve the specified label entry and modify  *	the info_desc field with the given value in nbytes. *//* ARGSUSED */inthwgraph_info_export_LBL(devfs_handle_t de, char *name, int nbytes){	arbitrary_info_t info;	int rc;	if (nbytes == 0)		nbytes = INFO_DESC_EXPORT;	if (nbytes < 0)		return(-1);	rc = labelcl_info_get_LBL(de, name, NULL, &info);	if (rc != 0)		return(rc);	rc = labelcl_info_replace_LBL(de, name,				nbytes, info, NULL, NULL);	return(rc);}/* * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the  * label info_descr filed to INFO_DESC_PRIVATE. *//* ARGSUSED */inthwgraph_info_unexport_LBL(devfs_handle_t de, char *name){	arbitrary_info_t info;	int rc;	rc = labelcl_info_get_LBL(de, name, NULL, &info);	if (rc != 0)		return(rc);	rc = labelcl_info_replace_LBL(de, name,				INFO_DESC_PRIVATE, info, NULL, NULL);	return(rc);}/* * hwgraph_path_lookup - return the handle for the given path. * */inthwgraph_path_lookup(	devfs_handle_t start_vertex_handle,			char *lookup_path,			devfs_handle_t *vertex_handle_ptr,			char **remainder){	*vertex_handle_ptr = devfs_find_handle(start_vertex_handle,	/* start dir */					lookup_path,		/* path */					0,			/* major */					0,			/* minor */					0,			/* char | block */					1);			/* traverse symlinks */	if (*vertex_handle_ptr == NULL)		return(-1);	else		return(0);}/* * hwgraph_traverse - Find and return the devfs handle starting from de. * */graph_error_thwgraph_traverse(devfs_handle_t de, char *path, devfs_handle_t *found){	/* 	 * get the directory entry (path should end in a directory)	 */	*found = devfs_find_handle(de,	/* start dir */			    path,	/* path */			    0,		/* major */			    0,		/* minor */			    0,		/* char | block */			    1);		/* traverse symlinks */	if (*found == NULL)		return(GRAPH_NOT_FOUND);	else		return(GRAPH_SUCCESS);}/* * hwgraph_path_to_vertex - Return the devfs entry handle for the given  *	pathname .. assume traverse symlinks too!. */devfs_handle_thwgraph_path_to_vertex(char *path){	return(devfs_find_handle(NULL,	/* start dir */			path,		/* path */		    	0,		/* major */		    	0,		/* minor */		    	0,		/* char | block */		    	1));		/* traverse symlinks */}/* * hwgraph_path_to_dev - Returns the devfs_handle_t of the given path .. *	We only deal with devfs handle and not devfs_handle_t.*/devfs_handle_thwgraph_path_to_dev(char *path){	devfs_handle_t  de;	de = hwgraph_path_to_vertex(path);	return(de);}/* * hwgraph_block_device_get - return the handle of the block device file. *	The assumption here is that de is a directory.*/devfs_handle_thwgraph_block_device_get(devfs_handle_t de){	return(devfs_find_handle(de,		/* start dir */			"block",		/* path */		    	0,			/* major */		    	0,			/* minor */		    	DEVFS_SPECIAL_BLK,	/* char | block */		    	1));			/* traverse symlinks */}/* * hwgraph_char_device_get - return the handle of the char device file. *      The assumption here is that de is a directory.*/devfs_handle_thwgraph_char_device_get(devfs_handle_t de){	return(devfs_find_handle(de,		/* start dir */			"char",			/* path */		    	0,			/* major */		    	0,			/* minor */		    	DEVFS_SPECIAL_CHR,	/* char | block */		    	1));			/* traverse symlinks */}/* * hwgraph_cdevsw_get - returns the fops of the given devfs entry. */struct file_operations *hwgraph_cdevsw_get(devfs_handle_t de)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -