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