source: azure_iot_hub_riscv/trunk/asp_baseplatform/usb/mscdiskio.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.6 KB
Line 
1/*
2 * TOPPERS/ASP/FMP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015-2017 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
11 * によって公表されている GNU General Public License の Version 2 に記
12 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
13 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 *
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
34 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
35 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 *
37 * @(#) $Id$
38 */
39
40/*
41 * MSC専用ストレージ関数をサポートする
42 * 擬似的なストレージ関数郡であり、標準ライブラリィと分けての使用が望ましい。
43 * 1. msc_init この関数郡の初期化関数(bssがゼロ設定の場合この関数は不要)
44 * 2. msc_sense MSCのセンスを行う
45 * 3. msc_diskstatus MSCのステータス取得:なし
46 * 4. msc_diskread MSCの読み込み:なし
47 * 5. msc_diskwrite MSCの書き込み:なし
48 * 6. msc_iocil MSCのIO制御:なし
49 *
50 */
51
52#include "kernel_impl.h"
53#include <stdlib.h>
54#include <string.h>
55#include <t_syslog.h>
56#include <t_stdlib.h>
57#include "fcntl.h"
58#include "device.h"
59#include "storagedevice.h"
60#include "ff.h"
61#include "diskio.h"
62#include "usb_otg.h"
63#include "mscdiskio.h"
64#include "tusbh_msc.h"
65
66static int msc_sense(void *psdev, bool_t on);
67static int msc_diskstatus(void *psdev);
68static int msc_diskread(void *pif, BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount);
69static int msc_diskwrite(void *pif, const BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount);
70static int msc_diskioctl(void *pif, BYTE Func, void* Buffer);
71
72static const StorageDeviceFunc_t fatfsMscDeviceFunc = {
73 msc_sense,
74 msc_diskstatus,
75 msc_diskstatus,
76 (int(*)())msc_diskread,
77 (int(*)())msc_diskwrite,
78 (int(*)())msc_diskioctl
79};
80
81static MSC_Unit_t MSCLUNInfo;
82static FATFS ActiveFatFsObj __attribute__ ((aligned (32)));
83
84/*
85 * FatFs用SDカードファイルドライバの初期化
86 */
87#if MSC_DEVNO == 0
88void sd_init(intptr_t exinf)
89#else
90void msc_init(intptr_t exinf)
91#endif
92{
93 StorageDevice_t *psdev;
94
95 SDMSetupDevice(MSC_DEVNO, &psdev);
96 psdev->pdevf = (StorageDeviceFunc_t *)&fatfsMscDeviceFunc;
97 psdev->pdevff = (StorageDeviceFileFunc_t *)&fatfsSDeviceFileFunc;
98 psdev->_sdev_secsize = 512;
99 psdev->_sdev_port = MSC_PORTID;
100#ifdef SDEV_INSWAIT_TIME
101 psdev->_sdev_inswait = SDEV_INSWAIT_TIME;
102#else
103 psdev->_sdev_inswait = 0;
104#endif
105 psdev->_sdev_attribute |= SDEV_INSERTCHK|SDEV_CHKREMOVE;
106 psdev->_sdev_local[0] = &ActiveFatFsObj;
107 psdev->_sdev_local[1] = NULL;
108}
109
110/*
111 * MSCセンス関数
112 */
113static int msc_sense(void *pif, BOOL on)
114{
115 StorageDevice_t *psdev = pif;
116 TUSBH_Handle_t *husbh;
117 TUSBH_ERCODE status;
118 bool_t exist;
119 char pdrv;
120 int result = FR_DISK_ERR;
121
122 pdrv = psdev->_sdev_port - MSC_PORTID;
123 husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
124 if(husbh == NULL)
125 exist = 0;
126 else
127 exist = tusbhMscUnitIsReady(husbh, pdrv);
128 if(on && !exist){
129 f_mount(psdev->_sdev_devno, 0);
130 psdev->_sdev_attribute &= ~SDEV_DEVERROR;
131 return TRUE;
132 }
133 else if(!on && exist){
134 psdev->_sdev_instimer += SENSE_TIME;
135 status = tusbhMscGetLUNInfo(husbh, pdrv, &MSCLUNInfo);
136 if(status != TUSBH_E_OK)
137 psdev->_sdev_attribute |= SDEV_DEVERROR;
138 else
139 psdev->_sdev_maxsec = MSCLUNInfo.num_block;
140 if((psdev->_sdev_attribute & SDEV_DEVERROR) == 0)
141 result = f_mount(psdev->_sdev_devno, &ActiveFatFsObj);
142 if(result != FR_OK)
143 psdev->_sdev_attribute |= SDEV_DEVERROR;
144 else
145 psdev->_sdev_local[0] = &ActiveFatFsObj;
146#if 1
147 syslog_3(LOG_NOTICE, "## attr[%04x] max(%d) result(%d) ##", psdev->_sdev_attribute, psdev->_sdev_maxsec, result);
148#endif
149 return TRUE;
150 }
151 else
152 return FALSE;
153}
154
155/*
156 * FatFs用MSCステータス関数
157 */
158static int msc_diskstatus(void *pif)
159{
160 TUSBH_Handle_t *husbh;
161 StorageDevice_t *psdev = pif;
162
163 if(psdev == NULL)
164 return STA_NODISK;
165 husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
166 if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || husbh == NULL)
167 return STA_NOINIT;
168 else
169 return 0;
170}
171
172/*
173 * FatFs用MSC読み込み関数
174 */
175static int msc_diskread(void *pif, BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount)
176{
177 StorageDevice_t *psdev = pif;
178 USB_OTG_Handle_t *husb;
179 TUSBH_Handle_t *husbh;
180 TUSBH_ERCODE status;
181 char pdrv;
182 int retry = 0;
183 uint8_t *buff = NULL;
184 unsigned int align = ((unsigned int)Buffer) & 3;
185 BYTE *buffer = (BYTE *)Buffer;
186
187 husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
188 husb = (USB_OTG_Handle_t *)husbh->pSysData;
189 pdrv = psdev->_sdev_port - MSC_PORTID;
190 if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || husbh == NULL)
191 return RES_ERROR;
192 if(align != 0 && husb->Init.dma_enable == 1){
193 uint32_t *addr = malloc_cache(psdev->_sdev_secsize*SectorCount);
194 if(addr != NULL){
195 buff = buffer;
196 buffer = (BYTE *)addr;
197 }
198 }
199 do{
200 status = tusbhMscRead(husbh, pdrv, SectorNumber, (uint8_t *)buffer, SectorCount);
201 if(status == TUSBH_E_SYS)
202 break;
203 retry++;
204 }while(status != TUSBH_E_OK && retry < RETRY_COUNT);
205 if(buff != NULL){
206 tusbmemcpy(buff, buffer, psdev->_sdev_secsize*SectorCount);
207 free_cache(buffer);
208 }
209 if(status == TUSBH_E_OK)
210 return RES_OK;
211 else if(status == TUSBH_E_SYS)
212 psdev->_sdev_attribute |= SDEV_DEVERROR;
213 return RES_ERROR;
214}
215
216/*
217 * FatFs用MSC書き込み関数
218 */
219static int msc_diskwrite(void *pif, const BYTE *Buffer, DWORD SectorNumber, BYTE SectorCount)
220{
221 StorageDevice_t *psdev = pif;
222 USB_OTG_Handle_t *husb;
223 TUSBH_Handle_t *husbh;
224 TUSBH_ERCODE status;
225 char pdrv;
226 int retry = 0;
227 uint8_t *buff = NULL;
228 unsigned int align = ((unsigned int)Buffer) & 3;
229 BYTE *buffer = (BYTE *)Buffer;
230
231 husbh = (TUSBH_Handle_t *)psdev->_sdev_local[1];
232 husb = (USB_OTG_Handle_t *)husbh->pSysData;
233 pdrv = psdev->_sdev_port - MSC_PORTID;
234 if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY || husbh == NULL)
235 return RES_ERROR;
236 if(align != 0 && husb->Init.dma_enable == 1){
237 uint32_t *addr = malloc_cache(psdev->_sdev_secsize*SectorCount);
238 if(addr != NULL){
239 buff = (uint8_t *)buffer;
240 buffer = (BYTE *)addr;
241 tusbmemcpy(buffer, buff, psdev->_sdev_secsize*SectorCount);
242 }
243 }
244 do{
245 status = tusbhMscWrite(husbh, pdrv, SectorNumber, (uint8_t *)buffer, SectorCount);
246 if(status == TUSBH_E_SYS)
247 break;
248 retry++;
249 }while(status != TUSBH_E_OK && retry < RETRY_COUNT);
250 if(buff != NULL)
251 free_cache(buffer);
252 if(status == TUSBH_E_OK)
253 return RES_OK;
254 else if(status == TUSBH_E_SYS)
255 psdev->_sdev_attribute |= SDEV_DEVERROR;
256 return RES_ERROR;
257}
258
259
260/*
261 * FatFs用MSC-DISKIO制御関数
262 */
263static int msc_diskioctl(void *pif, BYTE Func, void* Buffer)
264{
265 StorageDevice_t *psdev = (StorageDevice_t *)pif;
266 DRESULT result;
267
268 if(psdev == NULL)
269 return RES_ERROR;
270 if((psdev->_sdev_attribute & (SDEV_EMPLOY|SDEV_NOTUSE)) != SDEV_EMPLOY)
271 return RES_ERROR;
272 switch(Func){
273 case CTRL_SYNC:
274 result = RES_OK; /* no action */
275 break;
276 case GET_SECTOR_COUNT:
277 *((DWORD *)Buffer) = psdev->_sdev_maxsec;
278 syslog_2(LOG_NOTICE, "ioctl notuse (%d)(%d) ", (int)Func, psdev->_sdev_maxsec);
279 result = RES_OK;
280 break;
281 case GET_BLOCK_SIZE:
282 *((DWORD *)Buffer) = 135; /* ERASE_BLK */
283 syslog_1(LOG_NOTICE, "call disk_ioctl(GET_BLOCK_SIZE, %08x)", (int)(*((DWORD *)Buffer)));
284 result = RES_OK;
285 break;
286 default:
287 syslog_2(LOG_NOTICE, "call disk_ioctl(%d, %08x)", (int)psdev->_sdev_devno, (int)Buffer);
288 slp_tsk();
289 result = RES_PARERR;
290 break;
291 }
292 return result;
293}
294
Note: See TracBrowser for help on using the repository browser.