1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "nv-linux.h"
25
26 extern int NVreg_ImexChannelCount;
27
nv_caps_imex_open(struct inode * inode,struct file * file)28 static int nv_caps_imex_open(struct inode *inode, struct file *file)
29 {
30 return 0;
31 }
32
nv_caps_imex_release(struct inode * inode,struct file * file)33 static int nv_caps_imex_release(struct inode *inode, struct file *file)
34 {
35 return 0;
36 }
37
38 static struct file_operations g_nv_caps_imex_fops =
39 {
40 .owner = THIS_MODULE,
41 .open = nv_caps_imex_open,
42 .release = nv_caps_imex_release
43 };
44
45 struct
46 {
47 NvBool initialized;
48 struct cdev cdev;
49 dev_t devno;
50 } g_nv_caps_imex;
51
nv_caps_imex_channel_get(int fd)52 int NV_API_CALL nv_caps_imex_channel_get(int fd)
53 {
54 #if NV_FILESYSTEM_ACCESS_AVAILABLE
55 struct file *file;
56 struct inode *inode;
57 int channel = -1;
58
59 file = fget(fd);
60 if (file == NULL)
61 {
62 return channel;
63 }
64
65 inode = NV_FILE_INODE(file);
66 if (inode == NULL)
67 {
68 goto out;
69 }
70
71 /* Make sure the fd belongs to the nv-caps-imex-drv */
72 if (file->f_op != &g_nv_caps_imex_fops)
73 {
74 goto out;
75 }
76
77 /* minor number is same as channel */
78 channel = MINOR(inode->i_rdev);
79
80 out:
81 fput(file);
82
83 return channel;
84 #else
85 return -1;
86 #endif
87 }
88
nv_caps_imex_channel_count(void)89 int NV_API_CALL nv_caps_imex_channel_count(void)
90 {
91 return NVreg_ImexChannelCount;
92 }
93
nv_caps_imex_init(void)94 int NV_API_CALL nv_caps_imex_init(void)
95 {
96 int rc;
97
98 if (g_nv_caps_imex.initialized)
99 {
100 nv_printf(NV_DBG_ERRORS, "nv-caps-imex is already initialized.\n");
101 return -EBUSY;
102 }
103
104 if (NVreg_ImexChannelCount == 0)
105 {
106 nv_printf(NV_DBG_INFO, "nv-caps-imex is disabled.\n");
107 return 0;
108 }
109
110 rc = alloc_chrdev_region(&g_nv_caps_imex.devno, 0,
111 NVreg_ImexChannelCount,
112 "nvidia-caps-imex-channels");
113 if (rc < 0)
114 {
115 nv_printf(NV_DBG_ERRORS, "nv-caps-imex failed to create cdev.\n");
116 return rc;
117 }
118
119 cdev_init(&g_nv_caps_imex.cdev, &g_nv_caps_imex_fops);
120
121 g_nv_caps_imex.cdev.owner = THIS_MODULE;
122
123 rc = cdev_add(&g_nv_caps_imex.cdev, g_nv_caps_imex.devno,
124 NVreg_ImexChannelCount);
125 if (rc < 0)
126 {
127 nv_printf(NV_DBG_ERRORS, "nv-caps-imex failed to add cdev.\n");
128 goto cdev_add_fail;
129 }
130
131 g_nv_caps_imex.initialized = NV_TRUE;
132
133 return 0;
134
135 cdev_add_fail:
136 unregister_chrdev_region(g_nv_caps_imex.devno, NVreg_ImexChannelCount);
137
138 return rc;
139 }
140
nv_caps_imex_exit(void)141 void NV_API_CALL nv_caps_imex_exit(void)
142 {
143 if (!g_nv_caps_imex.initialized)
144 {
145 return;
146 }
147
148 cdev_del(&g_nv_caps_imex.cdev);
149
150 unregister_chrdev_region(g_nv_caps_imex.devno, NVreg_ImexChannelCount);
151
152 g_nv_caps_imex.initialized = NV_FALSE;
153 }
154