1 /****************************************************************************
2 * fs/driver/fs_registerdriver.c
3 *
4 * Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved.
5 * Based on NuttX originally from nuttx source (nuttx/fs/ and nuttx/drivers/)
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ****************************************************************************/
20
21 /****************************************************************************
22 * Included Files
23 ****************************************************************************/
24
25 #include "vfs_config.h"
26 #include "sys/types.h"
27 #include "errno.h"
28 #include "fs/driver.h"
29 #include "vnode.h"
30 #include "string.h"
31 #include "path_cache.h"
32 #include "limits.h"
33
34 /****************************************************************************
35 * Public Functions
36 ****************************************************************************/
37
38 /****************************************************************************
39 * Name: register_driver
40 *
41 * Description:
42 * Register a character driver vnode the pseudo file system.
43 *
44 * Input Parameters:
45 * path - The path to the vnode to create
46 * fops - The file operations structure
47 * mode - inmode priviledges (not used)
48 * priv - Private, user data that will be associated with the vnode.
49 *
50 * Returned Value:
51 * Zero on success (with the vnode point in 'vnode'); A negated errno
52 * value is returned on a failure (all error values returned by
53 * vnode_reserve):
54 *
55 * EINVAL - 'path' is invalid for this operation
56 * EEXIST - An vnode already exists at 'path'
57 * ENOMEM - Failed to allocate in-memory resources for the operation
58 *
59 ****************************************************************************/
60
register_driver(const char * path,const struct file_operations_vfs * fops,mode_t mode,void * priv)61 int register_driver(const char *path, const struct file_operations_vfs *fops,
62 mode_t mode, void *priv)
63 {
64 struct Vnode *vnode = NULL;
65 int ret;
66
67 if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
68 {
69 return -EINVAL;
70 }
71
72 VnodeHold();
73 ret = VnodeLookup(path, &vnode, 0);
74 if (ret == 0)
75 {
76 VnodeDrop();
77 return -EEXIST;
78 }
79
80 /* Insert a dummy node -- we need to hold the vnode semaphore because we
81 * will have a momentarily bad structure.
82 */
83
84 struct drv_data *data = (struct drv_data *)zalloc(sizeof(struct drv_data));
85
86 data->ops = (void *)fops;
87 data->mode = mode;
88 data->priv = priv;
89
90 ret = VnodeLookup(path, &vnode, V_CREATE | V_DUMMY);
91 if (ret == OK)
92 {
93 /* We have it, now populate it with driver specific information.
94 * NOTE that the initial reference count on the new vnode is zero.
95 */
96 vnode->type = VNODE_TYPE_CHR;
97 vnode->data = data;
98 vnode->mode = mode;
99 vnode->fop = (struct file_operations_vfs *)fops;
100 }
101
102 VnodeDrop();
103
104 return ret;
105 }
106