• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <linux/fs.h>
32 #include "hdf_log.h"
33 #include "hdf_io_service.h"
34 #include "osal_cdev.h"
35 #include "osal_file.h"
36 #include "osal_mem.h"
37 #include "osal_uaccess.h"
38 
39 #define HDF_LOG_TAG osal_cdev
40 
41 struct OsalCdev {
42     struct file_operations_vfs fops;
43     const struct OsalCdevOps* opsImpl;
44     const char* path;
45     void* priv;
46 };
47 
OsalCdevOpen(struct file * filep)48 int OsalCdevOpen(struct file* filep)
49 {
50     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
51     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
52     return dev->opsImpl->open(dev, filep);
53 }
54 
OsalCdevRelease(struct file * filep)55 int OsalCdevRelease(struct file* filep)
56 {
57     if (filep == NULL || filep->f_vnode == NULL) {
58         return HDF_ERR_INVALID_OBJECT;
59     }
60     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
61     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
62     return dev->opsImpl->release(dev, filep);
63 }
64 
OsalCdevRead(struct file * filep,char * buffer,size_t buflen)65 ssize_t OsalCdevRead(struct file* filep, char* buffer, size_t buflen)
66 {
67     if (filep == NULL || filep->f_vnode == NULL) {
68         return HDF_ERR_INVALID_OBJECT;
69     }
70     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
71     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
72     return dev->opsImpl->read(filep, buffer, buflen, 0);
73 }
74 
OsalCdevWrite(struct file * filep,const char * buffer,size_t buflen)75 ssize_t OsalCdevWrite(struct file* filep, const char* buffer, size_t buflen)
76 {
77     if (filep == NULL || filep->f_vnode == NULL) {
78         return HDF_ERR_INVALID_OBJECT;
79     }
80     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
81     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
82     return dev->opsImpl->write(filep, buffer, buflen, 0);
83 }
84 
OsalCdevSeek(struct file * filep,off_t offset,int whence)85 off_t OsalCdevSeek(struct file* filep, off_t offset, int whence)
86 {
87     if (filep == NULL || filep->f_vnode == NULL) {
88         return HDF_ERR_INVALID_OBJECT;
89     }
90     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
91     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
92     return dev->opsImpl->seek(filep, offset, whence);
93 }
94 
OsalCdevIoctl(struct file * filep,int cmd,unsigned long arg)95 int OsalCdevIoctl(struct file* filep, int cmd, unsigned long arg)
96 {
97     if (filep == NULL || filep->f_vnode == NULL) {
98         return HDF_ERR_INVALID_OBJECT;
99     }
100     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
101     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
102     return dev->opsImpl->ioctl(filep, cmd, arg);
103 }
104 
OsalCdevPoll(struct file * filep,poll_table * fds)105 int OsalCdevPoll(struct file* filep, poll_table* fds)
106 {
107     if (filep == NULL || filep->f_vnode == NULL) {
108         return HDF_ERR_INVALID_OBJECT;
109     }
110     struct drv_data* drvData = (struct drv_data* )filep->f_vnode->data;
111     struct OsalCdev* dev = (struct OsalCdev* )drvData->priv;
112     return dev->opsImpl->poll(filep, fds);
113 }
114 
AssignFileOps(struct file_operations_vfs * fops,const struct OsalCdevOps * src)115 static void AssignFileOps(struct file_operations_vfs* fops, const struct OsalCdevOps* src)
116 {
117     fops->seek = src->seek != NULL ? OsalCdevSeek : NULL;
118     fops->read = src->read != NULL ? OsalCdevRead : NULL;
119     fops->write = src->write != NULL ? OsalCdevWrite : NULL;
120     fops->poll = src->poll != NULL ? OsalCdevPoll : NULL;
121     fops->ioctl = src->ioctl != NULL ? OsalCdevIoctl : NULL;
122     fops->open = src->open != NULL ? OsalCdevOpen : NULL;
123     fops->close = src->release != NULL ? OsalCdevRelease : NULL;
124 }
125 
OsalAllocCdev(const struct OsalCdevOps * fops)126 struct OsalCdev* OsalAllocCdev(const struct OsalCdevOps* fops)
127 {
128     struct OsalCdev* cdev = OsalMemCalloc(sizeof(struct OsalCdev));
129     if (cdev == NULL) {
130         return NULL;
131     }
132 
133     AssignFileOps(&cdev->fops, fops);
134     cdev->opsImpl = fops;
135 
136     return cdev;
137 }
138 
OsalRegisterCdev(struct OsalCdev * cdev,const char * name,unsigned int mode,void * priv)139 int OsalRegisterCdev(struct OsalCdev* cdev, const char* name, unsigned int mode, void* priv)
140 {
141     if (cdev == NULL || name == NULL) {
142         return HDF_ERR_INVALID_PARAM;
143     }
144     HDF_LOGI("%s:register %s", __func__, name);
145     static bool devPathInitted = false;
146     if (!devPathInitted && mkdir(DEV_NODE_PATH, DEV_NODE_PATH_MODE) == 0) {
147         devPathInitted = true;
148     }
149     int ret =  register_driver(name, &cdev->fops, mode, cdev);
150     if (ret == HDF_SUCCESS) {
151         cdev->priv = priv;
152         cdev->path = name;
153     }
154     return ret;
155 }
156 
OsalUnregisterCdev(struct OsalCdev * cdev)157 void OsalUnregisterCdev(struct OsalCdev* cdev)
158 {
159     if (cdev != NULL) {
160         unregister_driver(cdev->path);
161     }
162 }
163 
OsalFreeCdev(struct OsalCdev * cdev)164 void OsalFreeCdev(struct OsalCdev* cdev)
165 {
166     if (cdev != NULL) {
167         OsalMemFree(cdev);
168     }
169 }
170 
OsalGetCdevPriv(struct OsalCdev * cdev)171 void* OsalGetCdevPriv(struct OsalCdev* cdev)
172 {
173     return cdev != NULL ? cdev->priv : NULL;
174 }
175 
OsalSetFilePriv(struct file * filep,void * priv)176 void OsalSetFilePriv(struct file* filep, void* priv)
177 {
178     if (filep != NULL) {
179         filep->f_priv = priv;
180     }
181 }
182 
OsalGetFilePriv(struct file * filep)183 void* OsalGetFilePriv(struct file* filep)
184 {
185     return filep != NULL ? filep->f_priv : NULL;
186 }
187