1 /****************************************************************************
2 * fs/driver/fs_registerdriver.c
3 *
4 * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
5 * Author: Gregory Nutt <gnutt@nuttx.org>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name NuttX nor the names of its contributors may be
18 * used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ****************************************************************************/
35
36 /****************************************************************************
37 * Included Files
38 ****************************************************************************/
39
40 #include "vfs_config.h"
41 #include "sys/types.h"
42 #include "errno.h"
43 #include "fs/driver.h"
44 #include "vnode.h"
45 #include "string.h"
46 #include "path_cache.h"
47 #include "limits.h"
48
49 /****************************************************************************
50 * Public Functions
51 ****************************************************************************/
52
53 /****************************************************************************
54 * Name: register_driver
55 *
56 * Description:
57 * Register a character driver vnode the pseudo file system.
58 *
59 * Input Parameters:
60 * path - The path to the vnode to create
61 * fops - The file operations structure
62 * mode - inmode priviledges (not used)
63 * priv - Private, user data that will be associated with the vnode.
64 *
65 * Returned Value:
66 * Zero on success (with the vnode point in 'vnode'); A negated errno
67 * value is returned on a failure (all error values returned by
68 * vnode_reserve):
69 *
70 * EINVAL - 'path' is invalid for this operation
71 * EEXIST - An vnode already exists at 'path'
72 * ENOMEM - Failed to allocate in-memory resources for the operation
73 *
74 ****************************************************************************/
75
register_driver(const char * path,const struct file_operations_vfs * fops,mode_t mode,void * priv)76 int register_driver(const char *path, const struct file_operations_vfs *fops,
77 mode_t mode, void *priv)
78 {
79 struct Vnode *vnode = NULL;
80 int ret;
81
82 if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
83 {
84 return -EINVAL;
85 }
86
87 VnodeHold();
88 ret = VnodeLookup(path, &vnode, 0);
89 if (ret == 0)
90 {
91 VnodeDrop();
92 return -EEXIST;
93 }
94
95 /* Insert a dummy node -- we need to hold the vnode semaphore because we
96 * will have a momentarily bad structure.
97 */
98
99 struct drv_data *data = (struct drv_data *)zalloc(sizeof(struct drv_data));
100
101 data->ops = (void *)fops;
102 data->mode = mode;
103 data->priv = priv;
104
105 ret = VnodeLookup(path, &vnode, V_CREATE | V_DUMMY);
106 if (ret == OK)
107 {
108 /* We have it, now populate it with driver specific information.
109 * NOTE that the initial reference count on the new vnode is zero.
110 */
111 vnode->type = VNODE_TYPE_CHR;
112 vnode->data = data;
113 vnode->mode = mode;
114 vnode->fop = (struct file_operations_vfs *)fops;
115 }
116
117 VnodeDrop();
118
119 return ret;
120 }
121