📄 hcl.c
字号:
{ 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 + -