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

📄 hcl.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	return(devfs_get_ops(de));}/* * hwgraph_bdevsw_get - returns the fops of the given devfs entry.*/struct file_operations *hwgraph_bdevsw_get(devfs_handle_t de){	return(devfs_get_ops(de));}/*** Inventory is now associated with a vertex in the graph.  For items that** belong in the inventory but have no vertex ** (e.g. old non-graph-aware drivers), we create a bogus vertex under the ** INFO_LBL_INVENT name.**** For historical reasons, we prevent exact duplicate entries from being added** to a single vertex.*//* * hwgraph_inventory_add - Adds an inventory entry into de. */inthwgraph_inventory_add(	devfs_handle_t de,			int class,			int type,			major_t controller,			minor_t unit,			int state){	inventory_t *pinv = NULL, *old_pinv = NULL, *last_pinv = NULL;	int rv;	/*	 * Add our inventory data to the list of inventory data	 * associated with this vertex.	 */again:	/* GRAPH_LOCK_UPDATE(&invent_lock); */	rv = labelcl_info_get_LBL(de,			INFO_LBL_INVENT,			NULL, (arbitrary_info_t *)&old_pinv);	if ((rv != LABELCL_SUCCESS) && (rv != LABELCL_NOT_FOUND))		goto failure;	/*	 * Seek to end of inventory items associated with this	 * vertex.  Along the way, make sure we're not duplicating	 * an inventory item (for compatibility with old add_to_inventory)	 */	for (;old_pinv; last_pinv = old_pinv, old_pinv = old_pinv->inv_next) {		if ((int)class != -1 && old_pinv->inv_class != class)			continue;		if ((int)type != -1 && old_pinv->inv_type != type)			continue;		if ((int)state != -1 && old_pinv->inv_state != state)			continue;		if ((int)controller != -1		    && old_pinv->inv_controller != controller)			continue;		if ((int)unit != -1 && old_pinv->inv_unit != unit)			continue;		/* exact duplicate of previously-added inventory item */		rv = LABELCL_DUP;		goto failure;	}	/* Not a duplicate, so we know that we need to add something. */	if (pinv == NULL) {		/* Release lock while we wait for memory. */		/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */		pinv = (inventory_t *)kmalloc(sizeof(inventory_t), GFP_KERNEL);		replace_in_inventory(pinv, class, type, controller, unit, state);		goto again;	}	pinv->inv_next = NULL;	if (last_pinv) {		last_pinv->inv_next = pinv;	} else {		rv = labelcl_info_add_LBL(de, INFO_LBL_INVENT, 			sizeof(inventory_t), (arbitrary_info_t)pinv);		if (!rv)			goto failure;	}	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */	return(0);failure:	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */	if (pinv)		kfree(pinv);	return(rv);}/* * hwgraph_inventory_remove - Removes an inventory entry. * *	Remove an inventory item associated with a vertex.   It is the caller's *	responsibility to make sure that there are no races between removing *	inventory from a vertex and simultaneously removing that vertex.*/inthwgraph_inventory_remove(	devfs_handle_t de,				int class,				int type,				major_t controller,				minor_t unit,				int state){	inventory_t *pinv = NULL, *last_pinv = NULL, *next_pinv = NULL;	labelcl_error_t rv;	/*	 * We never remove stuff from ".invent" ..	 */	if (!de)		return (-1);	/*	 * Remove our inventory data to the list of inventory data	 * associated with this vertex.	 */	/* GRAPH_LOCK_UPDATE(&invent_lock); */	rv = labelcl_info_get_LBL(de,			INFO_LBL_INVENT,			NULL, (arbitrary_info_t *)&pinv);	if (rv != LABELCL_SUCCESS)		goto failure;	/*	 * Search through inventory items associated with this	 * vertex, looking for a match.	 */	for (;pinv; pinv = next_pinv) {		next_pinv = pinv->inv_next;		if(((int)class == -1 || pinv->inv_class == class) &&		   ((int)type == -1 || pinv->inv_type == type) &&		   ((int)state == -1 || pinv->inv_state == state) &&		   ((int)controller == -1 || pinv->inv_controller == controller) &&		   ((int)unit == -1 || pinv->inv_unit == unit)) {			/* Found a matching inventory item. Remove it. */			if (last_pinv) {				last_pinv->inv_next = pinv->inv_next;			} else {				rv = hwgraph_info_replace_LBL(de, INFO_LBL_INVENT, (arbitrary_info_t)pinv->inv_next, NULL);				if (rv != LABELCL_SUCCESS)					goto failure;			}			pinv->inv_next = NULL; /* sanity */			kfree(pinv);		} else			last_pinv = pinv;	}	if (last_pinv == NULL) {		rv = hwgraph_info_remove_LBL(de, INFO_LBL_INVENT, NULL);		if (rv != LABELCL_SUCCESS)			goto failure;	}	rv = LABELCL_SUCCESS;failure:	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */	return(rv);}/* * hwgraph_inventory_get_next - Get next inventory item associated with the  *	specified vertex. * *	No locking is really needed.  We don't yet have the ability *	to remove inventory items, and new items are always added to *	the end of a vertex' inventory list. * * 	However, a devfs entry can be removed!*/inthwgraph_inventory_get_next(devfs_handle_t de, invplace_t *place, inventory_t **ppinv){	inventory_t *pinv;	labelcl_error_t rv;	if (de == NULL)		return(LABELCL_BAD_PARAM);	if (place->invplace_vhdl == NULL) {		place->invplace_vhdl = de;		place->invplace_inv = NULL;	}	if (de != place->invplace_vhdl)		return(LABELCL_BAD_PARAM);	if (place->invplace_inv == NULL) {		/* Just starting on this vertex */		rv = labelcl_info_get_LBL(de, INFO_LBL_INVENT,						NULL, (arbitrary_info_t *)&pinv);		if (rv != LABELCL_SUCCESS)			return(LABELCL_NOT_FOUND);	} else {		/* Advance to next item on this vertex */		pinv = place->invplace_inv->inv_next;	}	place->invplace_inv = pinv;	*ppinv = pinv;	return(LABELCL_SUCCESS);}/* * hwgraph_controller_num_get - Returns the controller number in the inventory  *	entry. */inthwgraph_controller_num_get(devfs_handle_t device){	inventory_t *pinv;	invplace_t invplace = { NULL, NULL, NULL };	int val = -1;	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {		val = (pinv->inv_class == INV_NETWORK)? pinv->inv_unit: pinv->inv_controller;	}#ifdef DEBUG	/*	 * It does not make any sense to call this on vertexes with multiple	 * inventory structs chained together	 */	if ( device_inventory_get_next(device, &invplace) != NULL ) {		printk("Should panic here ... !\n");#endif	return (val);	}/* * hwgraph_controller_num_set - Sets the controller number in the inventory  *	entry. */voidhwgraph_controller_num_set(devfs_handle_t device, int contr_num){	inventory_t *pinv;	invplace_t invplace = { NULL, NULL, NULL };	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {		if (pinv->inv_class == INV_NETWORK)			pinv->inv_unit = contr_num;		else {			if (pinv->inv_class == INV_FCNODE)				pinv = device_inventory_get_next(device, &invplace);			if (pinv != NULL)				pinv->inv_controller = contr_num;		}	}#ifdef DEBUG	/*	 * It does not make any sense to call this on vertexes with multiple	 * inventory structs chained together	 */	if(pinv != NULL)		ASSERT(device_inventory_get_next(device, &invplace) == NULL);#endif}/* * Find the canonical name for a given vertex by walking back through * connectpt's until we hit the hwgraph root vertex (or until we run * out of buffer space or until something goes wrong). * *	COMPATIBILITY FUNCTIONALITY * Walks back through 'parents', not necessarily the same as connectpts. * * Need to resolve the fact that devfs does not return the path from  * "/" but rather it just stops right before /dev .. */inthwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen){	char *locbuf;	int   pos;	if (buflen < 1)		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */	locbuf = kmalloc(buflen, GFP_KERNEL);	pos = devfs_generate_path(vhdl, locbuf, buflen);	if (pos < 0) {		kfree(locbuf);		return pos;	}	strcpy(buf, &locbuf[pos]);	kfree(locbuf);	return 0;}/*** vertex_to_name converts a vertex into a canonical name by walking** back through connect points until we hit the hwgraph root (or until** we run out of buffer space).**** Usually returns a pointer to the original buffer, filled in as** appropriate.  If the buffer is too small to hold the entire name,** or if anything goes wrong while determining the name, vertex_to_name** returns "UnknownDevice".*/#define DEVNAME_UNKNOWN "UnknownDevice"char *vertex_to_name(devfs_handle_t vhdl, char *buf, uint buflen){	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)		return(buf);	else		return(DEVNAME_UNKNOWN);}#ifdef IRIX/*** Return the compact node id of the node that ultimately "owns" the specified** vertex.  In order to do this, we walk back through masters and connect points** until we reach a vertex that represents a node.*/cnodeid_tmaster_node_get(devfs_handle_t vhdl){	cnodeid_t cnodeid;	devfs_handle_t master;	for (;;) {		cnodeid = nodevertex_to_cnodeid(vhdl);		if (cnodeid != CNODEID_NONE)			return(cnodeid);		master = device_master_get(vhdl);		/* Check for exceptional cases */		if (master == vhdl) {			/* Since we got a reference to the "master" thru			 * device_master_get() we should decrement			 * its reference count by 1			 */			hwgraph_vertex_unref(master);			return(CNODEID_NONE);		}		if (master == GRAPH_VERTEX_NONE) {			master = hwgraph_connectpt_get(vhdl);			if ((master == GRAPH_VERTEX_NONE) ||			    (master == vhdl)) {				if (master == vhdl)					/* Since we got a reference to the					 * "master" thru					 * hwgraph_connectpt_get() we should					 * decrement its reference count by 1					 */					hwgraph_vertex_unref(master);				return(CNODEID_NONE);			}		}				vhdl = master;		/* Decrement the reference to "master" which was got		 * either thru device_master_get() or hwgraph_connectpt_get()		 * above.		 */		hwgraph_vertex_unref(master);	}}/* * Using the canonical path name to get hold of the desired vertex handle will * not work on multi-hub sn0 nodes. Hence, we use the following (slightly * convoluted) algorithm. * * - Start at the vertex corresponding to the driver (provided as input parameter) * - Loop till you reach a vertex which has EDGE_LBL_MEMORY *    - If EDGE_LBL_CONN exists, follow that up. *      else if EDGE_LBL_MASTER exists, follow that up. *      else follow EDGE_LBL_DOTDOT up. * * * We should be at desired hub/heart vertex now * * - Follow EDGE_LBL_CONN to the widget vertex. * * - return vertex handle of this widget. */devfs_handle_tmem_vhdl_get(devfs_handle_t drv_vhdl){devfs_handle_t cur_vhdl, cur_upper_vhdl;devfs_handle_t tmp_mem_vhdl, mem_vhdl;graph_error_t loop_rv;  /* Initializations */  cur_vhdl = drv_vhdl;  loop_rv = ~GRAPH_SUCCESS;  /* Loop till current vertex has EDGE_LBL_MEMORY */  while (loop_rv != GRAPH_SUCCESS) {    if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &cur_upper_vhdl)) == GRAPH_SUCCESS) {    } else if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_MASTER, &cur_upper_vhdl)) == GRAPH_SUCCESS) {      } else { /* Follow HWGRAPH_EDGELBL_DOTDOT up */           (void) hwgraph_edge_get(cur_vhdl, HWGRAPH_EDGELBL_DOTDOT, &cur_upper_vhdl);        }    cur_vhdl = cur_upper_vhdl;#if DEBUG && HWG_DEBUG    printf("Current vhdl %d \n", cur_vhdl);#endif /* DEBUG */    loop_rv = hwgraph_edge_get(cur_vhdl, EDGE_LBL_MEMORY, &tmp_mem_vhdl);  }  /* We should be at desired hub/heart vertex now */  if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &mem_vhdl)) != GRAPH_SUCCESS)    return (GRAPH_VERTEX_NONE);  return (mem_vhdl);}#endif /* IRIX *//*** Add a char device -- if the driver supports it -- at a specified vertex.*/graph_error_thwgraph_char_device_add(        devfs_handle_t from,                                char *path,                                char *prefix,                                devfs_handle_t *devhdl){	devfs_handle_t xx = NULL;	printk("FIXME: hwgraph_char_device_add() called. Use hwgraph_register.\n");	*devhdl = xx;	// Must set devhdl	return(GRAPH_SUCCESS);}graph_error_thwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr){	printk("FIXME: hwgraph_edge_remove\n");	return(GRAPH_ILLEGAL_REQUEST);}graph_error_thwgraph_vertex_unref(devfs_handle_t vhdl){	printk("FIXME: hwgraph_vertex_unref\n");	return(GRAPH_ILLEGAL_REQUEST);}EXPORT_SYMBOL(hwgraph_mk_dir);EXPORT_SYMBOL(hwgraph_path_add);EXPORT_SYMBOL(hwgraph_char_device_add);EXPORT_SYMBOL(hwgraph_register);EXPORT_SYMBOL(hwgraph_vertex_destroy);EXPORT_SYMBOL(hwgraph_fastinfo_get);EXPORT_SYMBOL(hwgraph_edge_get);EXPORT_SYMBOL(hwgraph_fastinfo_set);EXPORT_SYMBOL(hwgraph_connectpt_set);EXPORT_SYMBOL(hwgraph_connectpt_get);EXPORT_SYMBOL(hwgraph_edge_get_next);EXPORT_SYMBOL(hwgraph_info_add_LBL);EXPORT_SYMBOL(hwgraph_info_remove_LBL);EXPORT_SYMBOL(hwgraph_info_replace_LBL);EXPORT_SYMBOL(hwgraph_info_get_LBL);EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);EXPORT_SYMBOL(hwgraph_info_get_next_LBL);EXPORT_SYMBOL(hwgraph_info_export_LBL);EXPORT_SYMBOL(hwgraph_info_unexport_LBL);EXPORT_SYMBOL(hwgraph_path_lookup);EXPORT_SYMBOL(hwgraph_traverse);EXPORT_SYMBOL(hwgraph_path_to_vertex);EXPORT_SYMBOL(hwgraph_path_to_dev);EXPORT_SYMBOL(hwgraph_block_device_get);EXPORT_SYMBOL(hwgraph_char_device_get);EXPORT_SYMBOL(hwgraph_cdevsw_get);EXPORT_SYMBOL(hwgraph_bdevsw_get);EXPORT_SYMBOL(hwgraph_vertex_name_get);

⌨️ 快捷键说明

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