1 /* Implements FX driver entry if FX_MEDIA not integrated in UX Host Class Storage. */
2
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8
9 #include "fx_api.h"
10
11 #include "ux_device_class_storage.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_stack.h"
14 #include "ux_host_class_storage.h"
15
16 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
17
18
19 VOID _ux_host_class_storage_driver_entry(FX_MEDIA *media);
20
21 VOID _ux_host_class_storage_media_insert(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG format_open);
22 VOID _ux_host_class_storage_media_remove(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
23
24 FX_MEDIA *_ux_host_class_storage_driver_medias(void);
25 FX_MEDIA *_ux_host_class_storage_driver_media(INT i);
26 UCHAR *_ux_host_class_storage_driver_media_memory(INT i);
27 INT _ux_host_class_storage_driver_media_index(FX_MEDIA *media);
28
29 INT _ux_host_class_storage_media_index(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
30 FX_MEDIA *_ux_host_class_storage_media_fx_media(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
31 UCHAR *_ux_host_class_storage_media_fx_media_memory(UX_HOST_CLASS_STORAGE_MEDIA *storage_media);
32
33 static FX_MEDIA medias[UX_HOST_CLASS_STORAGE_MAX_MEDIA];
34 static UCHAR medias_memories[UX_HOST_CLASS_STORAGE_MAX_MEDIA][UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE];
35 static VOID (*_ux_host_class_storage_media_read_write_notify)(UINT, UINT,
36 UX_HOST_CLASS_STORAGE *, ULONG, ULONG, UCHAR*) = UX_NULL;
37
_ux_host_class_storage_driver_read_write_notify(VOID (* func)(UINT,UINT,UX_HOST_CLASS_STORAGE *,ULONG,ULONG,UCHAR *))38 VOID _ux_host_class_storage_driver_read_write_notify(
39 VOID (*func)(UINT, UINT, UX_HOST_CLASS_STORAGE *, ULONG, ULONG, UCHAR*))
40 {
41 _ux_host_class_storage_media_read_write_notify = func;
42 }
43
_ux_host_class_storage_driver_medias(void)44 FX_MEDIA *_ux_host_class_storage_driver_medias(void)
45 {
46 return(medias);
47 }
48
_ux_host_class_storage_driver_media(INT i)49 FX_MEDIA *_ux_host_class_storage_driver_media(INT i)
50 {
51 return(&medias[i]);
52 }
53
_ux_host_class_storage_driver_media_memory(INT i)54 UCHAR *_ux_host_class_storage_driver_media_memory(INT i)
55 {
56 return(medias_memories[i]);
57 }
58
_ux_host_class_storage_driver_media_index(FX_MEDIA * media)59 INT _ux_host_class_storage_driver_media_index(FX_MEDIA *media)
60 {
61
62 INT media_index;
63
64
65 if (media < medias)
66 return(-1);
67 media_index = (INT)(media - medias);
68 if (media_index >= UX_HOST_CLASS_STORAGE_MAX_MEDIA)
69 return(-1);
70 return(media_index);
71 }
72
_ux_host_class_storage_media_index(UX_HOST_CLASS_STORAGE_MEDIA * storage_media)73 INT _ux_host_class_storage_media_index(UX_HOST_CLASS_STORAGE_MEDIA *storage_media)
74 {
75 UX_HOST_CLASS_STORAGE *storage;
76 UX_HOST_CLASS *class_inst;
77 UX_HOST_CLASS_STORAGE_MEDIA *storage_medias;
78 if (storage_media == UX_NULL)
79 return(-1);
80 if (storage_media -> ux_host_class_storage_media_storage == UX_NULL)
81 return(-1);
82 storage = storage_media -> ux_host_class_storage_media_storage;
83 if (storage == UX_NULL)
84 return(-1);
85 class_inst = storage -> ux_host_class_storage_class;
86 if (class_inst == UX_NULL)
87 return(-1);
88 storage_medias = (UX_HOST_CLASS_STORAGE_MEDIA *)class_inst -> ux_host_class_media;
89 if (storage_media < storage_medias)
90 return(-1);
91 return((INT)(storage_media - storage_medias));
92 }
93
_ux_host_class_storage_media_fx_media(UX_HOST_CLASS_STORAGE_MEDIA * storage_media)94 FX_MEDIA *_ux_host_class_storage_media_fx_media(UX_HOST_CLASS_STORAGE_MEDIA *storage_media)
95 {
96 INT media_index = _ux_host_class_storage_media_index(storage_media);
97 if (media_index < 0)
98 return(UX_NULL);
99 return(&medias[media_index]);
100 }
_ux_host_class_storage_media_fx_media_memory(UX_HOST_CLASS_STORAGE_MEDIA * storage_media)101 UCHAR *_ux_host_class_storage_media_fx_media_memory(UX_HOST_CLASS_STORAGE_MEDIA *storage_media)
102 {
103 INT media_index = _ux_host_class_storage_media_index(storage_media);
104 if (media_index < 0)
105 return(UX_NULL);
106 return(medias_memories[media_index]);
107 }
108
_ux_host_class_storage_media_insert(UX_HOST_CLASS_STORAGE_MEDIA * storage_media,ULONG format_open)109 VOID _ux_host_class_storage_media_insert(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG format_open)
110 {
111 INT media_index = _ux_host_class_storage_media_index(storage_media);
112 UINT rc = 0;
113 if (media_index < 0)
114 {
115 return;
116 }
117 medias[media_index].fx_media_driver_info = storage_media;
118 /* Format. */
119 if (format_open > 1)
120 {
121 rc = fx_media_format(&medias[media_index],
122 _ux_host_class_storage_driver_entry,
123 storage_media,
124 medias_memories[media_index], UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE,
125 "USB DISK", 2, 512, 0,
126 storage_media -> ux_host_class_storage_media_number_sectors,
127 storage_media -> ux_host_class_storage_media_sector_size,
128 4,
129 1, 1);
130 if (rc != UX_SUCCESS)
131 {
132 printf("%s:%d media_format error 0x%x\n", __FILE__, __LINE__, rc);
133 }
134 }
135 /* Open. */
136 if (format_open > 0 && rc == 0)
137 {
138 /* Open the media. */
139 rc = fx_media_open(&medias[media_index], UX_HOST_CLASS_STORAGE_MEDIA_NAME,
140 _ux_host_class_storage_driver_entry,
141 storage_media,
142 medias_memories[media_index],
143 UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE);
144 if (rc != UX_SUCCESS)
145 {
146 printf("%s:%d media_open error 0x%x\n", __FILE__, __LINE__, rc);
147 }
148 }
149 if (rc)
150 {
151 /* Inserted but not ready. */
152 medias[media_index].fx_media_id = 0;
153 }
154 else
155 {
156 }
157 }
158
_ux_host_class_storage_media_remove(UX_HOST_CLASS_STORAGE_MEDIA * storage_media)159 VOID _ux_host_class_storage_media_remove(UX_HOST_CLASS_STORAGE_MEDIA *storage_media)
160 {
161 INT media_index = _ux_host_class_storage_media_index(storage_media);
162 UINT rc = 0;
163
164 if (media_index < 0)
165 {
166 return;
167 }
168 if (medias[media_index].fx_media_driver_info == storage_media)
169 {
170 rc = fx_media_close(&medias[media_index]);
171 medias[media_index].fx_media_id = 0; /* Keeping compatible with integrated FX_MEDIA. */
172 medias[media_index].fx_media_driver_info = UX_NULL;
173 if (rc != UX_SUCCESS)
174 {
175 printf("%s:%d media_close error %x\n", __FILE__, __LINE__, rc);
176 }
177 }
178 }
179
_ux_host_class_storage_driver_entry(FX_MEDIA * media)180 VOID _ux_host_class_storage_driver_entry(FX_MEDIA *media)
181 {
182
183 UINT status;
184 UX_HOST_CLASS_STORAGE *storage;
185 UX_HOST_CLASS_STORAGE_MEDIA *storage_media;
186
187
188 /* Get the pointer to the storage media instance. */
189 storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *) media -> fx_media_driver_info;
190
191 /* Get storage instance. */
192 storage = storage_media -> ux_host_class_storage_media_storage;
193
194 /* Ensure the instance is valid. */
195 if ((storage -> ux_host_class_storage_state != UX_HOST_CLASS_INSTANCE_LIVE) &&
196 (storage -> ux_host_class_storage_state != UX_HOST_CLASS_INSTANCE_MOUNTING))
197 {
198
199 /* Class instance is invalid. Return an error! */
200 media -> fx_media_driver_status = FX_PTR_ERROR;
201 return;
202 }
203
204 /* Protect Thread reentry to this instance and select media LUN for further access. */
205 status = _ux_host_class_storage_media_lock(storage_media, UX_WAIT_FOREVER);
206 if (status != UX_SUCCESS)
207 {
208 printf("%s:%d lock fail 0x%x!\n", __FILE__, __LINE__, status);
209 media -> fx_media_driver_status = FX_IO_ERROR;
210 return;
211 }
212
213 /* Look at the request specified by the FileX caller. */
214 switch (media -> fx_media_driver_request)
215 {
216
217 case FX_DRIVER_READ:
218
219 /* Read one or more sectors. */
220 status = _ux_host_class_storage_media_read(storage, media -> fx_media_driver_logical_sector,
221 media -> fx_media_driver_sectors, media -> fx_media_driver_buffer);
222 if (_ux_host_class_storage_media_read_write_notify)
223 _ux_host_class_storage_media_read_write_notify(FX_DRIVER_READ, status,
224 storage,
225 media -> fx_media_driver_logical_sector,
226 media -> fx_media_driver_sectors,
227 media -> fx_media_driver_buffer);
228
229 /* Check completion status. */
230 if (status == UX_SUCCESS)
231 media -> fx_media_driver_status = FX_SUCCESS;
232 else
233 media -> fx_media_driver_status = _ux_host_class_storage_sense_code_translate(storage, status);
234 break;
235
236
237 case FX_DRIVER_WRITE:
238
239 /* Write one or more sectors. */
240 status = _ux_host_class_storage_media_write(storage, media -> fx_media_driver_logical_sector,
241 media -> fx_media_driver_sectors, media -> fx_media_driver_buffer);
242 if (_ux_host_class_storage_media_read_write_notify)
243 _ux_host_class_storage_media_read_write_notify(FX_DRIVER_WRITE, status,
244 storage,
245 media -> fx_media_driver_logical_sector,
246 media -> fx_media_driver_sectors,
247 media -> fx_media_driver_buffer);
248
249 /* Check completion status. */
250 if (status == UX_SUCCESS)
251 media -> fx_media_driver_status = FX_SUCCESS;
252 else
253 media -> fx_media_driver_status = _ux_host_class_storage_sense_code_translate(storage,status);
254 break;
255
256
257 case FX_DRIVER_FLUSH:
258
259 /* Nothing to do. Just return a good status! */
260 media -> fx_media_driver_status = FX_SUCCESS;
261 break;
262
263 case FX_DRIVER_ABORT:
264
265 /* Nothing to do. Just return a good status! */
266 media -> fx_media_driver_status = FX_SUCCESS;
267 break;
268
269 case FX_DRIVER_INIT:
270
271 /* Check for media protection. We must do this operation here because FileX clears all the
272 media fields before init. */
273 if (storage -> ux_host_class_storage_write_protected_media == UX_TRUE)
274
275 /* The media is Write Protected. We tell FileX. */
276 media -> fx_media_driver_write_protect = UX_TRUE;
277
278 /* This function always succeeds. */
279 media -> fx_media_driver_status = FX_SUCCESS;
280 break;
281
282
283 case FX_DRIVER_UNINIT:
284
285 /* Nothing to do. Just return a good status! */
286 media -> fx_media_driver_status = FX_SUCCESS;
287 break;
288
289
290 case FX_DRIVER_BOOT_READ:
291
292 /* Read the media boot sector. */
293 status = _ux_host_class_storage_media_read(storage, 0, 1,
294 media -> fx_media_driver_buffer);
295 if (_ux_host_class_storage_media_read_write_notify)
296 _ux_host_class_storage_media_read_write_notify(FX_DRIVER_READ, status,
297 storage, 0, 1,
298 media -> fx_media_driver_buffer);
299
300 /* Check completion status. */
301 if (status == UX_SUCCESS)
302 media -> fx_media_driver_status = FX_SUCCESS;
303 else
304 media -> fx_media_driver_status = _ux_host_class_storage_sense_code_translate(storage,status);
305 break;
306
307
308 case FX_DRIVER_BOOT_WRITE:
309
310 /* Write the boot sector. */
311 status = _ux_host_class_storage_media_write(storage, 0, 1,
312 media -> fx_media_driver_buffer);
313 if (_ux_host_class_storage_media_read_write_notify)
314 _ux_host_class_storage_media_read_write_notify(FX_DRIVER_WRITE, status,
315 storage, 0, 1,
316 media -> fx_media_driver_buffer);
317
318 /* Check completion status. */
319 if (status == UX_SUCCESS)
320 media -> fx_media_driver_status = FX_SUCCESS;
321 else
322 media -> fx_media_driver_status = _ux_host_class_storage_sense_code_translate(storage, status);
323 break;
324
325
326 default:
327
328 /* Invalid request from FileX */
329 media -> fx_media_driver_status = FX_IO_ERROR;
330 break;
331 }
332
333 /* Unprotect thread reentry to this instance. */
334 _ux_host_class_storage_media_unlock(storage_media);
335 }
336 #endif
337