1 /* This FileX test concentrates on the Fault-Tolerant log recover operation.  */
2 /*
3 For FAT 12, 16, 32, one cluster size is 1024 bytes;
4 
5         1024         1024          1024       1024          1024         1024
6     |------------|------------|-----------|------------|------------|------------|
7     |  TEST.TXT  |  TEST1.TXT | TEST2.TXT |            |            |            |
8     |------------|------------|-----------|------------|------------|------------|
9          28           1000         19
10 
11 Check recover fat operation:
12 Step1: Format and open the media;
13 Step2: Enable fault tolerant feature;
14 Step3: Write 28 bytes into TEST.TXT;
15 Step4: Write 1000 bytes into TEST1.TXT;
16 Step5: Write 19 bytes into TEST2.TXT;
17 Step6: Create new thread to continue to write 2048 data into TEST1.TXT(greater than one cluster):
18 Step7: Terminate the new thread to simulate poweroff when write the data between undo log generated and redo log not generated.
19 Step8: Create new thread and enable fault tolerant feature to recover the data(undo operation);
20 Step9: Terminate the new thread to simulate poweroff when recover the FAT table;
21 Step10: Open the media and enable fault tolerant feature to recover the data(undo operation);
22 Step11: Check the test files.
23 */
24 
25 #ifndef FX_STANDALONE_ENABLE
26 #include   "tx_api.h"
27 #else
28 #define    _GNU_SOURCE
29 #define    _DEFAULT_SOURCE
30 #include   <pthread.h>
31 #include   <unistd.h>
32 #endif
33 #include   "fx_api.h"
34 #include   "fx_system.h"
35 #include   "fx_fault_tolerant.h"
36 #include   <stdio.h>
37 #include   "fx_ram_driver_test.h"
38 extern void    test_control_return(UINT status);
39 void    filex_fault_tolerant_log_recover_fat_test_application_define(void *first_unused_memory);
40 
41 #if defined (FX_ENABLE_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT_DATA)
42 
43 #define     DEMO_STACK_SIZE         4096
44 #define CACHE_SIZE                  2048
45 #define FAULT_TOLERANT_SIZE         FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
46 
47 
48 /* Define the ThreadX and FileX object control blocks...  */
49 
50 #ifndef FX_STANDALONE_ENABLE
51 static TX_THREAD                ftest_0;
52 static TX_THREAD                ftest_1;
53 static TX_THREAD                ftest_2;
54 #else
55 static pthread_t                ptid1;
56 static pthread_t                ptid2;
57 #endif
58 static FX_MEDIA                 ram_disk;
59 static FX_FILE                  my_file;
60 static UCHAR                    *pointer;
61 
62 /* Define the counters used in the test application...  */
63 
64 #ifndef FX_STANDALONE_ENABLE
65 static UCHAR                    *cache_buffer;
66 static UCHAR                    *fault_tolerant_buffer;
67 static UCHAR                    *thread_1_buffer;
68 static UCHAR                    *thread_2_buffer;
69 #else
70 static UCHAR                    cache_buffer[CACHE_SIZE];
71 static UCHAR                    fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
72 #endif
73 static UINT                     error_couter = 0;
74 static UINT                     fat_write_interrupt_1 = FX_FALSE;
75 static UINT                     fat_write_interrupt_2 = FX_FALSE;
76 static UINT                     fat_updated_flag = FX_FALSE;
77 static UINT                     write_index;
78 static UINT                     i;
79 static CHAR                     write_buffer[2048];
80 static UINT                     write_buffer_size = 2048;
81 static CHAR                     read_buffer[4096];
82 static UINT                     read_buffer_size = 4096;
83 static UCHAR                    data_buffer[4096];
84 
85 #define TEST_COUNT              3            /* FAT12, 16, 32.  */
86 
87 /* Define thread prototypes.  */
88 
89 static void    ftest_0_entry(ULONG thread_input);
90 #ifndef FX_STANDALONE_ENABLE
91 static void    ftest_1_entry(ULONG thread_input);
92 static void    ftest_2_entry(ULONG thread_input);
93 #else
94 static void   * ftest_1_entry(void * thread_input);
95 static void   * ftest_2_entry(void * thread_input);
96 #endif
97 extern void    _fx_ram_driver(FX_MEDIA *media_ptr);
98 extern void    test_control_return(UINT status);
99 extern UINT    _filex_fault_tolerant_log_check(FX_MEDIA *media_ptr);
100 extern UINT    (*driver_write_callback)(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
101 static UINT    my_driver_write_1(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
102 static UINT    my_driver_write_2(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
103 
104 
105 
106 /* Define what the initial system looks like.  */
107 
108 #ifdef CTEST
test_application_define(void * first_unused_memory)109 void test_application_define(void *first_unused_memory)
110 #else
111 void    filex_fault_tolerant_log_recover_fat_test_application_define(void *first_unused_memory)
112 #endif
113 {
114 
115 
116 #ifndef FX_STANDALONE_ENABLE
117     /* Setup the working pointer.  */
118     pointer =  (UCHAR *) first_unused_memory;
119 
120     /* Create the main thread.  */
121 
122     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
123             pointer, DEMO_STACK_SIZE,
124             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
125 
126     pointer =  pointer + DEMO_STACK_SIZE;
127 
128     /* Setup memory for the RAM disk and the sector cache.  */
129     cache_buffer =  pointer;
130     pointer += CACHE_SIZE;
131     fault_tolerant_buffer = pointer;
132     pointer += FAULT_TOLERANT_SIZE;
133     thread_1_buffer = pointer;
134     pointer += DEMO_STACK_SIZE;
135     thread_2_buffer = pointer;
136     pointer += DEMO_STACK_SIZE;
137 #endif
138 
139     /* Initialize the FileX system.  */
140     fx_system_initialize();
141 #ifdef FX_STANDALONE_ENABLE
142     ftest_0_entry(0);
143 #endif
144 }
145 
146 
147 
148 /* Define the test threads.  */
149 
ftest_0_entry(ULONG thread_input)150 static void    ftest_0_entry(ULONG thread_input)
151 {
152 
153 UINT        status;
154 ULONG       actual;
155 
156     FX_PARAMETER_NOT_USED(thread_input);
157 
158     /* Print out some test information banners.  */
159     printf("FileX Test:   Fault Tolerant Log Recover FAT Test....................");
160 
161     /* Random genearte the write data.  */
162     for (write_index = 0; write_index < write_buffer_size; write_index ++)
163         write_buffer[write_index] = (CHAR)rand();
164 
165     /* Loop to test FAT 12, 16, 32.   */
166     for (i = 0; i < TEST_COUNT; i ++)
167     {
168         if (i == 0)
169         {
170             /* Format the media with FAT12.  This needs to be done before opening it!  */
171             status =  fx_media_format(&ram_disk,
172                                      _fx_ram_driver,         // Driver entry
173                                      ram_disk_memory_large,  // RAM disk memory pointer
174                                      cache_buffer,           // Media buffer pointer
175                                      CACHE_SIZE,             // Media buffer size
176                                      "MY_RAM_DISK",          // Volume Name
177                                      1,                      // Number of FATs
178                                      32,                     // Directory Entries
179                                      0,                      // Hidden sectors
180                                      256,                    // Total sectors
181                                      256,                    // Sector size
182                                      8,                      // Sectors per cluster
183                                      1,                      // Heads
184                                      1);                     // Sectors per track
185         }
186         else if (i == 1)
187         {
188             /* Format the media with FAT16.  This needs to be done before opening it!  */
189             status =  fx_media_format(&ram_disk,
190                                      _fx_ram_driver,         // Driver entry
191                                      ram_disk_memory_large,  // RAM disk memory pointer
192                                      cache_buffer,           // Media buffer pointer
193                                      CACHE_SIZE,             // Media buffer size
194                                      "MY_RAM_DISK",          // Volume Name
195                                      1,                      // Number of FATs
196                                      32,                     // Directory Entries
197                                      0,                      // Hidden sectors
198                                      4200 * 8,               // Total sectors
199                                      256,                    // Sector size
200                                      8,                      // Sectors per cluster
201                                      1,                      // Heads
202                                      1);                     // Sectors per track
203         }
204         else if (i == 2)
205         {
206             /* Format the media with FAT32.  This needs to be done before opening it!  */
207             status =  fx_media_format(&ram_disk,
208                                      _fx_ram_driver,         // Driver entry
209                                      ram_disk_memory_large,  // RAM disk memory pointer
210                                      cache_buffer,           // Media buffer pointer
211                                      CACHE_SIZE,             // Media buffer size
212                                      "MY_RAM_DISK",          // Volume Name
213                                      1,                      // Number of FATs
214                                      32,                     // Directory Entries
215                                      0,                      // Hidden sectors
216                                      70000 * 8,              // Total sectors
217                                      256,                    // Sector size
218                                      8,                      // Sectors per cluster
219                                      1,                      // Heads
220                                      1);                     // Sectors per track
221         }
222         return_if_fail( status == FX_SUCCESS);
223 
224         /* Open the ram_disk.  */
225         status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
226         return_if_fail( status == FX_SUCCESS);
227 
228         /* Enable the Fault-tolerant feature.  */
229         status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
230         return_if_fail( status == FX_SUCCESS);
231 
232         /* Create a file called TEST.TXT in the root directory.  */
233         status =  fx_file_create(&ram_disk, "TEST.TXT");
234         return_if_fail( status == FX_SUCCESS);
235 
236         /* Open the test file.  */
237         status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
238         return_if_fail( status == FX_SUCCESS);
239 
240         /* Write a string to the test file.  */
241         status =  fx_file_write(&my_file, " ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 28);
242         return_if_fail( status == FX_SUCCESS);
243 
244         /* Seek to the beginning of the test file.  */
245         status =  fx_file_seek(&my_file, 0);
246         return_if_fail( status == FX_SUCCESS);
247 
248         /* Clean the buffer.  */
249         memset(read_buffer, 0, read_buffer_size);
250 
251         /* Read the bytes of the test file.  */
252         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
253         return_if_fail( (status == FX_SUCCESS) && (actual == 28));
254 
255         /* Close the test file.  */
256         status =  fx_file_close(&my_file);
257         return_if_fail( status == FX_SUCCESS);
258 
259         /* Create a file called TEST1.TXT in the root directory.  */
260         status =  fx_file_create(&ram_disk, "TEST1.TXT");
261         return_if_fail( status == FX_SUCCESS);
262 
263         /* Open the test file.  */
264         status =  fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
265         return_if_fail( status == FX_SUCCESS);
266 
267         /* Write a string to the test file.  */
268         status =  fx_file_write(&my_file, (void *) write_buffer, 1000);
269         return_if_fail( status == FX_SUCCESS);
270 
271         /* Seek to the beginning of the test file.  */
272         status =  fx_file_seek(&my_file, 0);
273         return_if_fail( status == FX_SUCCESS);
274 
275         /* Clean the buffer.  */
276         memset(read_buffer, 0, read_buffer_size);
277 
278         /* Read the bytes of the test file.  */
279         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
280         return_if_fail( (status == FX_SUCCESS) && (actual == 1000));
281 
282         /* Close the test file.  */
283         status =  fx_file_close(&my_file);
284         return_if_fail( status == FX_SUCCESS);
285 
286         /* Create a file called TEST2.TXT in the root directory.  */
287         status =  fx_file_create(&ram_disk, "TEST2.TXT");
288         return_if_fail( status == FX_SUCCESS);
289 
290         /* Open the test file.  */
291         status =  fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
292         return_if_fail( status == FX_SUCCESS);
293 
294         /* Write a string to the test file.  */
295         status =  fx_file_write(&my_file, " EXPRESSLOGIC_TEST\n", 19);
296         return_if_fail( status == FX_SUCCESS);
297 
298         /* Seek to the beginning of the test file.  */
299         status =  fx_file_seek(&my_file, 0);
300         return_if_fail( status == FX_SUCCESS);
301 
302         /* Clean the buffer.  */
303         memset(read_buffer, 0, read_buffer_size);
304 
305         /* Read the bytes of the test file.  */
306         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
307         return_if_fail( (status == FX_SUCCESS) && (actual == 19));
308 
309         /* Close the test file.  */
310         status =  fx_file_close(&my_file);
311         return_if_fail( status == FX_SUCCESS);
312 
313         /* Create the new thread.  */
314 #ifndef FX_STANDALONE_ENABLE
315         tx_thread_create(&ftest_1, "thread 1", ftest_1_entry, 0,
316                         thread_1_buffer, DEMO_STACK_SIZE,
317                         4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
318 #endif
319 
320         /* directory_write_interrupt */
321         fat_write_interrupt_1 = FX_FALSE;
322 
323         /* Let the other thread run.  */
324 #ifndef FX_STANDALONE_ENABLE
325         tx_thread_relinquish();
326 #else
327         pthread_create(&ptid1, NULL, &ftest_1_entry, NULL);
328         usleep(10);
329         pthread_join(ptid1,NULL);
330 #endif
331 
332         /* Delete the thread.  */
333 #ifndef FX_STANDALONE_ENABLE
334         tx_thread_delete(&ftest_1);
335 
336         /* Create the new thread.  */
337         tx_thread_create(&ftest_2, "thread 2", ftest_2_entry, 0,
338                         thread_2_buffer, DEMO_STACK_SIZE,
339                         4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
340 #else
341         pthread_cancel(ptid1);
342 #endif
343         /* directory_write_interrupt */
344         fat_write_interrupt_2 = FX_FALSE;
345 
346         /* Let the other thread run.  */
347 #ifndef FX_STANDALONE_ENABLE
348         tx_thread_relinquish();
349 #else
350         pthread_create(&ptid2, NULL, &ftest_2_entry, NULL);
351         usleep(10);
352         pthread_join(ptid2,NULL);
353 #endif
354 
355         /* Recover the log again.  */
356 
357         /* Open the ram_disk.  */
358         status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
359         return_if_fail( status == FX_SUCCESS);
360 
361         /* Enable the Fault-tolerant feature to recover the media.  */
362         status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
363         return_if_fail( status == FX_SUCCESS);
364 
365         /* Open the test file.  */
366         status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
367         return_if_fail( status == FX_SUCCESS);
368 
369         /* Seek to the beginning of the test file.  */
370         status =  fx_file_seek(&my_file, 0);
371         return_if_fail( status == FX_SUCCESS);
372 
373         /* Clean the buffer.  */
374         memset(read_buffer, 0, read_buffer_size);
375 
376         /* Read the bytes of the test file.  */
377         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
378         return_if_fail( (status == FX_SUCCESS) && (actual == 28) && (memcmp(read_buffer, " ABCDEFGHIJKLNMOPQRSTUVWXYZ\n", actual)));
379 
380         /* Close the test file.  */
381         status =  fx_file_close(&my_file);
382         return_if_fail( status == FX_SUCCESS);
383 
384         /* Open the test file.  */
385         status =  fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
386         return_if_fail( status == FX_SUCCESS);
387 
388         /* Seek to the beginning of the test file.  */
389         status =  fx_file_seek(&my_file, 0);
390         return_if_fail( status == FX_SUCCESS);
391 
392         /* Clean the buffer.  */
393         memset(read_buffer, 0, read_buffer_size);
394 
395         /* Read the bytes of the test file.  */
396         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
397         return_if_fail((status == FX_SUCCESS) && (actual == 1000) && !(memcmp(read_buffer, write_buffer, actual)));
398 
399         /* Close the test file.  */
400         status =  fx_file_close(&my_file);
401         return_if_fail( status == FX_SUCCESS);
402 
403         /* Open the test file.  */
404         status =  fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
405         return_if_fail( status == FX_SUCCESS);
406 
407         /* Seek to the beginning of the test file.  */
408         status =  fx_file_seek(&my_file, 0);
409         return_if_fail( status == FX_SUCCESS);
410 
411         /* Clean the buffer.  */
412         memset(read_buffer, 0, read_buffer_size);
413 
414         /* Read the bytes of the test file.  */
415         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
416         return_if_fail((status == FX_SUCCESS) && (actual == 19) && !(memcmp(read_buffer, " EXPRESSLOGIC_TEST\n", actual)));
417 
418         /* Close the test file.  */
419         status =  fx_file_close(&my_file);
420         return_if_fail( status == FX_SUCCESS);
421 
422         /* Close the media.  */
423         status =  fx_media_close(&ram_disk);
424         return_if_fail((status == FX_SUCCESS) && (fat_write_interrupt_1 == FX_TRUE) && (fat_write_interrupt_2 == FX_TRUE) && !(error_couter));
425 
426         /* Delete the thread.  */
427 #ifndef FX_STANDALONE_ENABLE
428         tx_thread_delete(&ftest_2);
429 #else
430         pthread_cancel(ptid2);
431 #endif
432     }
433 
434     /* Output successful.  */
435     printf("SUCCESS!\n");
436     test_control_return(0);
437 }
438 
439 /* Define the test threads.  */
440 
441 #ifndef FX_STANDALONE_ENABLE
ftest_1_entry(ULONG thread_input)442 static void    ftest_1_entry(ULONG thread_input)
443 #else
444  void  *  ftest_1_entry(void * thread_input)
445 #endif
446 {
447 
448 #ifdef FX_STANDALONE_ENABLE
449     UINT oldtype;
450     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
451     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
452 #endif
453 
454     UINT        status;
455 
456     FX_PARAMETER_NOT_USED(thread_input);
457 
458     /* Set the callback function to simulate poweoff operation when write FAT entry.  */
459     driver_write_callback = my_driver_write_1;
460 
461     /* Open the test file.  */
462     status =  fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
463 
464     /* Check the file open status.  */
465     if (status != FX_SUCCESS)
466     {
467         error_couter ++;
468 #ifndef FX_STANDALONE_ENABLE
469         return;
470 #else
471         return NULL;
472 #endif
473     }
474 
475     /* Write 1024 bytes to the file, then update the FAT table.  (bytes should be greate than one cluster).  */
476     {
477         fx_file_write(&my_file, (void *) (write_buffer + 1000), 2048);
478     }
479 }
480 
481 #ifndef FX_STANDALONE_ENABLE
ftest_2_entry(ULONG thread_input)482 static void    ftest_2_entry(ULONG thread_input)
483 #else
484 static void  *  ftest_2_entry(void * thread_input)
485 #endif
486 {
487 
488 #ifdef FX_STANDALONE_ENABLE
489     UINT oldtype;
490     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
491     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
492 #endif
493 
494     UINT        status;
495 
496     FX_PARAMETER_NOT_USED(thread_input);
497 
498     /* Open the ram_disk.  */
499     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
500 
501     /* Check the status.  */
502     if (status != FX_SUCCESS)
503     {
504 
505         error_couter ++;
506 #ifndef FX_STANDALONE_ENABLE
507         return;
508 #else
509         return NULL;
510 #endif
511     }
512 
513     /* Set the callback function to simulate poweoff operation when recover the FAT entry.  */
514     driver_write_callback = my_driver_write_2;
515 
516     /* Enable the Fault-tolerant feature to recover the media.  */
517     fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
518 }
519 
my_driver_write_1(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)520 static UINT my_driver_write_1(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
521 {
522 
523     FX_PARAMETER_NOT_USED(block_ptr);
524 
525     /* Interrupt the FAT write operation.  */
526     if ((sector_type == FX_FAT_SECTOR) && (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_UNDO_DONE) &&
527         (!(_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_DONE)))
528     {
529 
530         /* Updated the fat flag.  */
531         fat_updated_flag = FX_TRUE;
532     }
533 
534     /* Interrupt the redo write operation after updated the fat table.  */
535     if ((fat_updated_flag == FX_TRUE) && (sector_type == FX_DATA_SECTOR) &&
536         (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_UPDATING))
537     {
538 
539         /* Set the write interrupt operation.  */
540         *operation_ptr = FX_OP_WRITE_INTERRUPT;
541 
542         /* Update the flag.  */
543         fat_write_interrupt_1 = FX_TRUE;
544 
545         /* Clean the callback function.  */
546         driver_write_callback = FX_NULL;
547 
548         /* Delete the media protection structure if FX_SINGLE_THREAD is not
549         defined.  */
550 #ifndef FX_SINGLE_THREAD
551 #ifndef FX_DONT_CREATE_MUTEX
552 
553         /* Note that the protection is never released. The mutex delete
554         service will handle all threads waiting access to this media
555         control block.  */
556         tx_mutex_delete(&(media_ptr -> fx_media_protect));
557 #endif
558 #endif
559 
560         /* Clean the media data.  */
561         _fx_system_media_opened_ptr = FX_NULL;
562         _fx_system_media_opened_count = 0;
563 
564         /* Clean the media.  */
565         memset(media_ptr, 0, sizeof(FX_MEDIA));
566 
567         /* Simulate poweroff.  */
568         /* First terminate the thread to ensure it is ready for deletion.  */
569 #ifndef FX_STANDALONE_ENABLE
570         tx_thread_terminate(&ftest_1);
571 #else
572         pthread_cancel(ptid1);
573 #endif
574     }
575 
576     /* Return.  */
577     return FX_SUCCESS;
578 }
579 
my_driver_write_2(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)580 static UINT my_driver_write_2(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
581 {
582 
583     FX_PARAMETER_NOT_USED(block_ptr);
584 
585     /* Interrupt the FAT write operation.  */
586     if (sector_type == FX_FAT_SECTOR)
587     {
588 
589         /* Set the write interrupt operation.  */
590         *operation_ptr = FX_OP_WRITE_INTERRUPT;
591 
592         /* Update the flag.  */
593         fat_write_interrupt_2 = FX_TRUE;
594 
595         /* Clean the callback function.  */
596         driver_write_callback = FX_NULL;
597 
598         /* Delete the media protection structure if FX_SINGLE_THREAD is not
599         defined.  */
600 #ifndef FX_SINGLE_THREAD
601 #ifndef FX_DONT_CREATE_MUTEX
602 
603         /* Note that the protection is never released. The mutex delete
604         service will handle all threads waiting access to this media
605         control block.  */
606         tx_mutex_delete(&(media_ptr -> fx_media_protect));
607 #endif
608 #endif
609 
610         /* Clean the media data.  */
611         _fx_system_media_opened_ptr = FX_NULL;
612         _fx_system_media_opened_count = 0;
613 
614         /* Clean the media.  */
615         memset(media_ptr, 0, sizeof(FX_MEDIA));
616 
617         /* Simulate poweroff.  */
618         /* First terminate the thread to ensure it is ready for deletion.  */
619 #ifndef FX_STANDALONE_ENABLE
620         tx_thread_terminate(&ftest_2);
621 #else
622         pthread_cancel(ptid2);
623 #endif
624     }
625 
626     /* Return.  */
627     return FX_SUCCESS;
628 }
629 
630 #else
631 
632 #ifdef CTEST
test_application_define(void * first_unused_memory)633 void test_application_define(void *first_unused_memory)
634 #else
635 void    filex_fault_tolerant_log_recover_fat_test_application_define(void *first_unused_memory)
636 #endif
637 {
638 
639     FX_PARAMETER_NOT_USED(first_unused_memory);
640 
641     /* Print out some test information banners.  */
642     printf("FileX Test:   Fault Tolerant Log Recover FAT Test....................N/A\n");
643 
644     test_control_return(255);
645 }
646 #endif
647 
648