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