• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "uart_dev_sample.h"
10 #include "fs/fs.h"
11 #include "securec.h"
12 #include "user_copy.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15 #include "uart_pl011_sample.h"
16 
17 #define HDF_LOG_TAG uart_dev_sample
18 #define HDF_UART_FS_MODE 0660
19 
UartSampleDevOpen(struct file * filep)20 static int32_t UartSampleDevOpen(struct file *filep)
21 {
22     struct UartHost *host = NULL;
23 
24     if (filep == NULL || filep->f_vnode == NULL) {
25         return HDF_ERR_INVALID_PARAM;
26     }
27     struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
28     host = (struct UartHost *)drv->priv;
29     if (host == NULL) {
30         HDF_LOGE("%s: host is NULL", __func__);
31         return HDF_ERR_INVALID_PARAM;
32     }
33     HDF_LOGI("%s: open uart%d success", __func__, host->num);
34     return HDF_SUCCESS;
35 }
UartSampleRelease(struct file * filep)36 static int32_t UartSampleRelease(struct file *filep)
37 {
38     struct UartHost *host = NULL;
39 
40     if (filep == NULL || filep->f_vnode == NULL) {
41         return HDF_ERR_INVALID_PARAM;
42     }
43     struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
44     host = (struct UartHost *)drv->priv;
45     if (host == NULL) {
46         HDF_LOGE("%s: host is NULL", __func__);
47         return HDF_ERR_INVALID_PARAM;
48     }
49     HDF_LOGI("%s: close uart%d success", __func__, host->num);
50     return HDF_SUCCESS;
51 }
52 
UartSampleRead(struct file * filep,char * buf,size_t count)53 static ssize_t UartSampleRead(struct file *filep, char *buf, size_t count)
54 {
55     int32_t ret;
56     uint8_t *tmpBuf = NULL;
57     struct UartHost *host = NULL;
58 
59     if (filep == NULL || filep->f_vnode == NULL) {
60         return HDF_ERR_INVALID_PARAM;
61     }
62     struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
63     host = (struct UartHost *)drv->priv;
64 
65     if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)buf, count)) {
66         tmpBuf = (uint8_t *)OsalMemCalloc(count);
67         if (tmpBuf == NULL) {
68             HDF_LOGE("%s: OsalMemCalloc error", __func__);
69             return HDF_ERR_MALLOC_FAIL;
70         }
71         ret = UartHostRead(host, tmpBuf, count);
72         if (ret == HDF_SUCCESS) {
73             ret = LOS_ArchCopyToUser(buf, tmpBuf, count);
74         }
75         OsalMemFree(tmpBuf);
76         return ret;
77     } else {
78         return UartHostRead(host, (uint8_t *)buf, count);
79     }
80 }
81 
UartSampleWrite(struct file * filep,const char * buf,size_t count)82 static ssize_t UartSampleWrite(struct file *filep, const char *buf, size_t count)
83 {
84     int32_t ret;
85     uint8_t *tmpBuf = NULL;
86     struct UartHost *host = NULL;
87 
88     if (filep == NULL || filep->f_vnode == NULL) {
89         return HDF_ERR_INVALID_PARAM;
90     }
91     struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
92     host = (struct UartHost *)drv->priv;
93 
94     if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)buf, count)) {
95         tmpBuf = (uint8_t *)OsalMemCalloc(count);
96         if (tmpBuf == NULL) {
97             HDF_LOGE("%s: OsalMemCalloc error", __func__);
98             return HDF_ERR_MALLOC_FAIL;
99         }
100         ret = LOS_ArchCopyFromUser(tmpBuf, buf, count);
101         if (ret != LOS_OK) {
102             OsalMemFree(tmpBuf);
103             return ret;
104         }
105         ret = UartHostWrite(host, tmpBuf, count);
106         OsalMemFree(tmpBuf);
107         return ret;
108     } else {
109         return UartHostWrite(host, (uint8_t *)buf, count);
110     }
111 }
112 
UartSampleDevIoctl(struct file * filep,int32_t cmd,unsigned long arg)113 static int32_t UartSampleDevIoctl(struct file *filep, int32_t cmd, unsigned long arg)
114 {
115     int32_t ret;
116     struct UartHost *host = NULL;
117     if (filep == NULL || filep->f_vnode == NULL) {
118         return HDF_ERR_INVALID_PARAM;
119     }
120     struct drv_data *drv = (struct drv_data *)filep->f_vnode->data;
121     host = (struct UartHost *)drv->priv;
122     if (host->priv == NULL) {
123         return HDF_ERR_INVALID_PARAM;
124     }
125 
126     ret = HDF_FAILURE;
127     switch (cmd) {
128         case UART_CFG_BAUDRATE:
129             ret = UartHostSetBaud(host, arg);
130             break;
131         default:
132             HDF_LOGE("%s cmd %d not support", __func__, cmd);
133             ret = HDF_ERR_NOT_SUPPORT;
134             break;
135     }
136     return ret;
137 }
138 
139 const struct file_operations_vfs g_uartSampleDevFops = {
140     .open   = UartSampleDevOpen,
141     .close  = UartSampleRelease,
142     .read   = UartSampleRead,
143     .write  = UartSampleWrite,
144     .ioctl  = UartSampleDevIoctl,
145 };
146 
147 #define MAX_DEV_NAME_SIZE 32
AddRemoveUartDev(struct UartHost * host,bool add)148 static void AddRemoveUartDev(struct UartHost *host, bool add)
149 {
150     int32_t ret;
151     char *devName = NULL;
152 
153     if (host == NULL || host->priv == NULL) {
154         HDF_LOGW("%s: invalid parameter", __func__);
155         return;
156     }
157     devName = (char *)OsalMemCalloc(sizeof(char) * (MAX_DEV_NAME_SIZE + 1));
158     if (devName == NULL) {
159         HDF_LOGE("%s: OsalMemCalloc error", __func__);
160         return;
161     }
162     ret = snprintf_s(devName, MAX_DEV_NAME_SIZE + 1, MAX_DEV_NAME_SIZE, "/dev/uartdev-%d", host->num);
163     if (ret < 0) {
164         HDF_LOGE("%s: snprintf_s failed", __func__);
165         OsalMemFree(devName);
166         return;
167     }
168     if (add) {
169         if (register_driver(devName, &g_uartSampleDevFops, HDF_UART_FS_MODE, host)) {
170             HDF_LOGE("%s: gen /dev/uartdev-%d fail!", __func__, host->num);
171             OsalMemFree(devName);
172             return;
173         }
174     } else {
175         if (unregister_driver(devName)) {
176             HDF_LOGE("%s: remove /dev/uartdev-%d fail!", __func__, host->num);
177             OsalMemFree(devName);
178             return;
179         }
180     }
181     OsalMemFree(devName);
182 }
183 
AddUartDevice(struct UartHost * host)184 void AddUartDevice(struct UartHost *host)
185 {
186     AddRemoveUartDev(host, true);
187 }
188 
RemoveUartDevice(struct UartHost * host)189 void RemoveUartDevice(struct UartHost *host)
190 {
191     AddRemoveUartDev(host, false);
192 }
193