1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** FileX Component */
16 /** */
17 /** Media */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define FX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "fx_api.h"
28 #include "fx_media.h"
29 #include "fx_system.h"
30
31
32 FX_CALLER_CHECKING_EXTERNS
33
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _fxe_media_open PORTABLE C */
40 /* 6.1 */
41 /* AUTHOR */
42 /* */
43 /* William E. Lamie, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This function checks for errors in the media open call. */
48 /* */
49 /* INPUT */
50 /* */
51 /* media_ptr Media control block pointer */
52 /* media_name Pointer to media name string */
53 /* media_driver Media driver entry function */
54 /* driver_info_ptr Optional information pointer */
55 /* supplied to media driver */
56 /* memory_ptr Pointer to memory used by the */
57 /* FileX for this media. */
58 /* memory_size Size of media memory - must */
59 /* at least 512 bytes and */
60 /* one sector size. */
61 /* media_control_block_size Size of FX_MEDIA structure */
62 /* */
63 /* OUTPUT */
64 /* */
65 /* FX_PTR_ERROR One or more input parameters */
66 /* are NULL */
67 /* status Actual completion status */
68 /* */
69 /* CALLS */
70 /* */
71 /* tx_thread_identify Get current thread */
72 /* tx_thread_preemption_change Disable/restore preemption */
73 /* _fx_media_open Actual media open service */
74 /* */
75 /* CALLED BY */
76 /* */
77 /* Application Code */
78 /* */
79 /* RELEASE HISTORY */
80 /* */
81 /* DATE NAME DESCRIPTION */
82 /* */
83 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
84 /* 09-30-2020 William E. Lamie Modified comment(s), */
85 /* resulting in version 6.1 */
86 /* */
87 /**************************************************************************/
_fxe_media_open(FX_MEDIA * media_ptr,CHAR * media_name,VOID (* media_driver)(FX_MEDIA *),VOID * driver_info_ptr,VOID * memory_ptr,ULONG memory_size,UINT media_control_block_size)88 UINT _fxe_media_open(FX_MEDIA *media_ptr, CHAR *media_name,
89 VOID (*media_driver)(FX_MEDIA *), VOID *driver_info_ptr,
90 VOID *memory_ptr, ULONG memory_size, UINT media_control_block_size)
91 {
92
93 UINT status;
94 ULONG temp;
95 FX_MEDIA *current_media;
96 ULONG open_count;
97
98 #ifndef FX_SINGLE_THREAD
99 TX_THREAD *current_thread;
100 UINT old_threshold;
101 #endif
102
103
104 /* Check for invalid input pointers. */
105 if ((media_ptr == FX_NULL) || (media_driver == FX_NULL) || (memory_ptr == FX_NULL) || (media_control_block_size != sizeof(FX_MEDIA)))
106 {
107 return(FX_PTR_ERROR);
108 }
109
110 /* Check for a valid caller. */
111 FX_CALLER_CHECKING_CODE
112
113 /* Check for proper size of the logical sector cache. */
114 temp = _fx_system_media_max_sector_cache;
115
116 /* Isolate the lowest set bit. */
117 temp = (temp & ((~temp) + ((ULONG) 1)));
118
119 /* If FX_MAX_SECTOR_CACHE is a power of 2, the value of temp should be unchanged. */
120 if ((temp == 1) || (temp != _fx_system_media_max_sector_cache))
121 {
122
123 /* Not a power of 2, return an error. */
124 return(FX_MEDIA_INVALID);
125 }
126
127 /* Check for proper size of the FAT cache. */
128 temp = _fx_system_media_max_fat_cache;
129
130 /* Isolate the lowest set bit. */
131 temp = (temp & ((~temp) + ((ULONG) 1)));
132
133 /* If FX_MAX_FAT_CACHE is a power of 2, the value of temp should be unchanged. */
134 if ((temp == 1) || (temp != _fx_system_media_max_fat_cache))
135 {
136
137 /* Not a power of 2, return an error. */
138 return(FX_MEDIA_INVALID);
139 }
140
141 #ifndef FX_SINGLE_THREAD
142
143 /* Pickup current thread pointer. At this point we know the current thread pointer is non-null since
144 it was checked by code in FX_CALLER_CHECKING_CODE macro. */
145 current_thread = tx_thread_identify();
146
147 /* Disable preemption temporarily. */
148 tx_thread_preemption_change(current_thread, 0, &old_threshold);
149 #endif
150
151 /* Loop to check for the media already opened. */
152 current_media = _fx_system_media_opened_ptr;
153 open_count = _fx_system_media_opened_count;
154 while (open_count--)
155 {
156
157 /* Is the new media pointer already open? */
158 if (media_ptr == current_media)
159 {
160
161 #ifndef FX_SINGLE_THREAD
162
163 /* Restore preemption. */
164 tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
165 #endif
166
167 /* Duplicate media open, return an error! */
168 return(FX_PTR_ERROR);
169 }
170
171 /* Move to next entry. */
172 current_media = current_media -> fx_media_opened_next;
173 }
174
175 #ifndef FX_SINGLE_THREAD
176
177 /* Restore preemption. */
178 tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
179 #endif
180
181 /* Call actual media open service. */
182 status = _fx_media_open(media_ptr, media_name, media_driver, driver_info_ptr,
183 memory_ptr, memory_size);
184
185 /* Return status. */
186 return(status);
187 }
188
189