• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved.
3  * Description: LiteOS USB Driver Device Mass Protocol About Memory Media.
4  * Author: huangjieliang
5  * Create: 2019-11-26
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  * conditions and the following disclaimer.
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  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14  * to endorse or promote products derived from this software without specific prior written
15  * permission.
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29  * Notice of Export Control Law
30  * ===============================================
31  * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32  * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33  * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34  * applicable export control laws and regulations.
35  * --------------------------------------------------------------------------- */
36 
37 #include <disk.h>
38 #include <driver.h>
39 #include "gadget/f_mass_storage_ram.h"
40 #include "user_copy.h"
41 
42 #ifdef __cplusplus
43 #if __cplusplus
44 extern "C" {
45 #endif /* __cplusplus */
46 #endif /* __cplusplus */
47 
48 #define SECTOR_SIZE   512
49 #define RAM_DEV_NAME  "/dev/uram"
50 
51 struct ram_storage_sc
52 {
53   uint8_t *start_addr;
54   uint32_t len;
55   uint32_t sector_size;
56 };
57 
ram_open(struct inode * filep)58 static int ram_open(struct inode *filep)
59 {
60   (void)filep;
61   return 0;
62 }
63 
ram_close(struct inode * filep)64 static int ram_close(struct inode *filep)
65 {
66   (void)filep;
67   return 0;
68 }
69 
ram_read(struct inode * ram_inode,uint8_t * buffer,uint64_t start_sector,uint32_t nsectors)70 static ssize_t ram_read(struct inode *ram_inode, uint8_t *buffer,
71                         uint64_t start_sector, uint32_t nsectors)
72 {
73   errno_t status;
74   struct ram_storage_sc *sc = ram_inode->i_private;
75   uint32_t sector_size      = sc->sector_size;
76   uint8_t *start_addr       = sc->start_addr;
77 
78   if (start_sector + nsectors > sc->len / sector_size)
79     {
80       usb_err("start_sector = %llu, nsectors = %u\n", start_sector, nsectors);
81       return -1;
82     }
83 
84   status = usbd_copy_to_user(buffer, nsectors * sector_size, start_addr +
85                              start_sector * sector_size, nsectors * sector_size);
86   if(status != EOK)
87     {
88       return -1;
89     }
90 
91   return (ssize_t)nsectors;
92 }
93 
ram_write(struct inode * ram_inode,const uint8_t * buffer,uint64_t start_sector,uint32_t nsectors)94 static ssize_t ram_write(struct inode *ram_inode, const uint8_t *buffer,
95                          uint64_t start_sector, uint32_t nsectors)
96 {
97   errno_t status;
98   struct ram_storage_sc *sc = ram_inode->i_private;
99   uint32_t sector_size      = sc->sector_size;
100   uint8_t *start_addr       = sc->start_addr;
101 
102   if (start_sector + nsectors > sc->len / sector_size)
103     {
104       usb_err("start_sector = %llu, nsectors = %u\n", start_sector, nsectors);
105       return -1;
106     }
107 
108   status = usbd_copy_from_user(start_addr + start_sector * sector_size,
109                                nsectors * sector_size, buffer, nsectors * sector_size);
110   if(status != EOK)
111     {
112       return -1;
113     }
114 
115   return (ssize_t)nsectors;
116 }
117 
ram_geometry(struct inode * ram_inode,struct geometry * ram_geometry)118 static int ram_geometry(struct inode *ram_inode, struct geometry *ram_geometry)
119 {
120   struct ram_storage_sc *sc;
121 
122   if (ram_geometry == NULL)
123     {
124       return -1;
125     }
126 
127   sc = ram_inode->i_private;
128   ram_geometry->geo_nsectors   = sc->len / sc->sector_size;
129   ram_geometry->geo_sectorsize = sc->sector_size;
130 
131   return 0;
132 }
133 
ram_ioctl(struct inode * ram_inode,int cmd,unsigned long arg)134 static int ram_ioctl(struct inode *ram_inode, int cmd, unsigned long arg)
135 {
136   (void)ram_inode;
137   (void)cmd;
138   (void)arg;
139   return 0;
140 }
141 
142 const static struct block_operations g_ram_dev_ops =
143 {
144   .open  = ram_open,
145   .close = ram_close,
146   .read  = ram_read,
147   .write = ram_write,
148   .geometry = ram_geometry,
149   .ioctl    = ram_ioctl,
150   .unlink   = NULL
151 };
152 
ram_mass_storage_init(void)153 int ram_mass_storage_init(void)
154 {
155   void *fat32_part_buf;
156   struct ram_storage_sc *sc;
157   int32_t disk_id;
158   int fd = -1;
159   ssize_t ret;
160 
161   sc = malloc(sizeof(struct ram_storage_sc));
162   if (sc == NULL)
163     {
164       return -1;
165     }
166   (void)memset_s(sc, sizeof(struct ram_storage_sc), 0, sizeof(struct ram_storage_sc));
167 
168   /* Request a memory block to store the fat32 partition, the length is 2M. */
169 
170   fat32_part_buf = memalign(SECTOR_SIZE, FAT_PART_SIZE);
171   if (fat32_part_buf == NULL)
172     {
173       free(sc);
174       return -1;
175     }
176 
177   fd = open(FAT_PART_IMAGE_PATH, O_RDONLY, 0);
178   if (fd < 0)
179     {
180       usb_err("open file failed!\n");
181       goto error;
182     }
183 
184   /* Copy Fat32 partition from flash to memory */
185 
186   ret = read(fd, fat32_part_buf, FAT_PART_SIZE);
187   if (ret != FAT_PART_SIZE)
188     {
189       usb_err("read bytes is too small, ret = %d\n", ret);
190       (void)close(fd);
191       goto error;
192     }
193   (void)close(fd);
194 
195   sc->start_addr  = (uint8_t *)fat32_part_buf;
196   sc->sector_size = SECTOR_SIZE;
197   sc->len         = FAT_PART_SIZE;
198 
199   /* Register the fat32 partition device node (/dev/uramp0). */
200 
201   disk_id = los_alloc_diskid_byname(RAM_DEV_NAME);
202   OsSetUsbStatus((uint32_t)disk_id);
203   ret = los_disk_init(RAM_DEV_NAME, &g_ram_dev_ops, (void *)sc, disk_id, NULL);
204   if (ret)
205     {
206       usb_err("los_disk_init fail!\n");
207       goto error;
208     }
209 
210   return 0;
211 error:
212   free(sc);
213   free(fat32_part_buf);
214   return -1;
215 }
216 
ram_mass_storage_deinit(void)217 int ram_mass_storage_deinit(void)
218 {
219   struct ram_storage_sc *sc;
220   struct inode *inode;
221   char *fullpath = NULL;
222   int32_t disk_id;
223   int ret;
224 
225   ret = vfs_normalize_path(NULL, RAM_DEV_NAME, &fullpath);
226   if (ret < 0)
227     {
228       return -1;
229     }
230 
231   inode = inode_find(fullpath, NULL);
232   if (inode == NULL)
233     {
234       free(fullpath);
235       return -1;
236     }
237   sc = inode->i_private;
238   inode_release(inode);
239   free(fullpath);
240 
241   disk_id = los_get_diskid_byname(RAM_DEV_NAME);
242   (void)los_disk_deinit(disk_id);
243   OsClearUsbStatus((uint32_t)disk_id);
244 
245   if (sc != NULL)
246     {
247       free(sc->start_addr);
248       sc->start_addr = NULL;
249       free(sc);
250     }
251 
252   return 0;
253 }
254 
255 #ifdef __cplusplus
256 #if __cplusplus
257 }
258 #endif /* __cplusplus */
259 #endif /* __cplusplus */
260