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