]> git.proxmox.com Git - mirror_edk2.git/blob - OptionRomPkg/DriverHealthDxe/DriverHealthDxe.c
Fix a obvious bug for judge whether the PPB support ISA
[mirror_edk2.git] / OptionRomPkg / DriverHealthDxe / DriverHealthDxe.c
1 /** @file
2 DiskIo driver that lays on every BlockIo protocol in the system.
3 DiskIo converts a block oriented device to a byte oriented device.
4
5 Disk access may have to handle unaligned request about sector boundaries.
6 There are three cases:
7 UnderRun - The first byte is not on a sector boundary or the read request is
8 less than a sector in length.
9 Aligned - A read of N contiguous sectors.
10 OverRun - The last byte is not on a sector boundary.
11
12 Copyright (c) 2006 - 2009, Intel Corporation. <BR>
13 All rights reserved. This program and the accompanying materials
14 are licensed and made available under the terms and conditions of the BSD License
15 which accompanies this distribution. The full text of the license may be found at
16 http://opensource.org/licenses/bsd-license.php
17
18 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
19 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20
21 **/
22
23 #include "DriverHealthDxe.h"
24
25 #undef STRING_TOKEN
26 #define STRING_TOKEN(x) 0
27
28 extern EFI_GUID gEfiCallerIdGuid;
29
30 CHAR16 VariableName[] = L"Config";
31 UINTN mNumNotHealthy = 0;
32 UINT8 ControllerIndex = 0;
33
34 //
35 // Link used to store the controller health status
36 //
37 LIST_ENTRY mControllerList = {NULL, NULL};
38
39 //
40 // 0 - Healthy -> {0}
41 // 1 - Health with warning messages -> {1}
42 // 2 - Failed -> {2}
43 // 3 - Failed with error messages -> {3}
44 // 4 - RebootRequired -> {4}
45 // 5 - RebootRequired with messages -> {5}
46 // 6 - ReconnectRequired -> {6}
47 // 7 - ReconnectRequired with messages -> {7}
48 // 100..103 - RepairRequired -> {0..3}
49 // 104..107 - RepairRequired with error messages -> {0..3}
50 // 108..111 - RepairRequired with progress notifications -> {0..3}
51 // 112..115 - RepairRequired with error messages and progress notifications -> {0..3}
52 // 132..163 - RepairRequired -> {300..331}
53 // 164..195 - RepairRequired with error messages -> {300..331}
54 // 196..227 - RepairRequired with progress notifications -> {300..331}
55 // 228..259 - RepairRequired with error messages and progress notifications -> {300..331}
56 // 300..307 - ConfigRequired -> {0..7}
57 // 308..315 - ConfigRequired with error messages -> {0..7}
58 // 316..323 - ConfigRequired with forms -> {0..7}
59 // 324..331 - ConfigRequired with forms and error messages -> {0..7}
60 // 332..347 - ConfigRequired -> {100..115}
61 // 348..363 - ConfigRequired with error messages -> {100..115}
62 // 364..379 - ConfigRequired with forms -> {100.115}
63 // 380..395 - ConfigRequired with forms and error messages -> {100..115}
64
65 DEVICE_STATE mDeviceState[] = {
66 { TRUE, 308, 000, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
67 { TRUE, 309, 001, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
68 { TRUE, 310, 002, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
69 { TRUE, 311, 003, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
70 { TRUE, 312, 004, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
71 { TRUE, 313, 005, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
72 { TRUE, 314, 006, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
73 { TRUE, 315, 007, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
74
75 { TRUE, 000, 000, 0, FALSE, EfiDriverHealthStatusHealthy },
76 { TRUE, 001, 001, STRING_TOKEN (STR_HEALTHY_WARNING), FALSE, EfiDriverHealthStatusHealthy },
77
78 { TRUE, 002, 002, 0, FALSE, EfiDriverHealthStatusFailed },
79 { TRUE, 003, 003, STRING_TOKEN (STR_FAILED_ERROR), FALSE, EfiDriverHealthStatusFailed },
80
81 { FALSE, 004, 004, 0, FALSE, EfiDriverHealthStatusRebootRequired },
82 { FALSE, 005, 005, STRING_TOKEN (STR_REBOOT_REQUIRED), FALSE, EfiDriverHealthStatusRebootRequired },
83
84 { FALSE, 006, 006, 0, FALSE, EfiDriverHealthStatusReconnectRequired },
85 { FALSE, 007, 007, STRING_TOKEN (STR_RECONNECT_REQUIRED), FALSE, EfiDriverHealthStatusReconnectRequired },
86
87 { TRUE, 100, 000, 0, FALSE, EfiDriverHealthStatusRepairRequired },
88 { TRUE, 101, 001, 0, FALSE, EfiDriverHealthStatusRepairRequired },
89 { TRUE, 102, 002, 0, FALSE, EfiDriverHealthStatusRepairRequired },
90 { TRUE, 103, 003, 0, FALSE, EfiDriverHealthStatusRepairRequired },
91
92 { TRUE, 104, 000, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
93 { TRUE, 105, 001, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
94 { TRUE, 106, 002, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
95 { TRUE, 107, 003, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
96
97 { TRUE, 108, 000, 0, TRUE, EfiDriverHealthStatusRepairRequired },
98 { TRUE, 109, 001, 0, TRUE, EfiDriverHealthStatusRepairRequired },
99 { TRUE, 110, 002, 0, TRUE, EfiDriverHealthStatusRepairRequired },
100 { TRUE, 111, 003, 0, TRUE, EfiDriverHealthStatusRepairRequired },
101
102 { TRUE, 112, 000, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
103 { TRUE, 113, 001, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
104 { TRUE, 114, 002, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
105 { TRUE, 115, 003, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
106
107 { TRUE, 132, 300, 0, FALSE, EfiDriverHealthStatusRepairRequired },
108 { TRUE, 133, 301, 0, FALSE, EfiDriverHealthStatusRepairRequired },
109 { TRUE, 134, 302, 0, FALSE, EfiDriverHealthStatusRepairRequired },
110 { TRUE, 135, 303, 0, FALSE, EfiDriverHealthStatusRepairRequired },
111 { TRUE, 136, 304, 0, FALSE, EfiDriverHealthStatusRepairRequired },
112 { TRUE, 137, 305, 0, FALSE, EfiDriverHealthStatusRepairRequired },
113 { TRUE, 138, 306, 0, FALSE, EfiDriverHealthStatusRepairRequired },
114 { TRUE, 139, 307, 0, FALSE, EfiDriverHealthStatusRepairRequired },
115 { TRUE, 140, 308, 0, FALSE, EfiDriverHealthStatusRepairRequired },
116 { TRUE, 141, 309, 0, FALSE, EfiDriverHealthStatusRepairRequired },
117 { TRUE, 142, 310, 0, FALSE, EfiDriverHealthStatusRepairRequired },
118 { TRUE, 143, 311, 0, FALSE, EfiDriverHealthStatusRepairRequired },
119 { TRUE, 144, 312, 0, FALSE, EfiDriverHealthStatusRepairRequired },
120 { TRUE, 145, 313, 0, FALSE, EfiDriverHealthStatusRepairRequired },
121 { TRUE, 146, 314, 0, FALSE, EfiDriverHealthStatusRepairRequired },
122 { TRUE, 147, 315, 0, FALSE, EfiDriverHealthStatusRepairRequired },
123 { TRUE, 148, 316, 0, FALSE, EfiDriverHealthStatusRepairRequired },
124 { TRUE, 149, 317, 0, FALSE, EfiDriverHealthStatusRepairRequired },
125 { TRUE, 150, 318, 0, FALSE, EfiDriverHealthStatusRepairRequired },
126 { TRUE, 151, 319, 0, FALSE, EfiDriverHealthStatusRepairRequired },
127 { TRUE, 152, 320, 0, FALSE, EfiDriverHealthStatusRepairRequired },
128 { TRUE, 153, 321, 0, FALSE, EfiDriverHealthStatusRepairRequired },
129 { TRUE, 154, 322, 0, FALSE, EfiDriverHealthStatusRepairRequired },
130 { TRUE, 155, 323, 0, FALSE, EfiDriverHealthStatusRepairRequired },
131 { TRUE, 156, 324, 0, FALSE, EfiDriverHealthStatusRepairRequired },
132 { TRUE, 157, 325, 0, FALSE, EfiDriverHealthStatusRepairRequired },
133 { TRUE, 158, 326, 0, FALSE, EfiDriverHealthStatusRepairRequired },
134 { TRUE, 159, 327, 0, FALSE, EfiDriverHealthStatusRepairRequired },
135 { TRUE, 160, 328, 0, FALSE, EfiDriverHealthStatusRepairRequired },
136 { TRUE, 161, 329, 0, FALSE, EfiDriverHealthStatusRepairRequired },
137 { TRUE, 162, 330, 0, FALSE, EfiDriverHealthStatusRepairRequired },
138 { TRUE, 163, 331, 0, FALSE, EfiDriverHealthStatusRepairRequired },
139
140 { TRUE, 164, 300, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
141 { TRUE, 165, 301, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
142 { TRUE, 166, 302, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
143 { TRUE, 167, 303, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
144 { TRUE, 168, 304, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
145 { TRUE, 169, 305, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
146 { TRUE, 170, 306, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
147 { TRUE, 171, 307, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
148 { TRUE, 172, 308, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
149 { TRUE, 173, 309, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
150 { TRUE, 174, 310, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
151 { TRUE, 175, 311, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
152 { TRUE, 176, 312, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
153 { TRUE, 177, 313, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
154 { TRUE, 178, 314, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
155 { TRUE, 179, 315, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
156 { TRUE, 180, 316, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
157 { TRUE, 181, 317, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
158 { TRUE, 182, 318, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
159 { TRUE, 183, 319, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
160 { TRUE, 184, 320, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
161 { TRUE, 185, 321, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
162 { TRUE, 186, 322, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
163 { TRUE, 187, 323, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
164 { TRUE, 188, 324, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
165 { TRUE, 189, 325, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
166 { TRUE, 190, 326, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
167 { TRUE, 191, 327, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
168 { TRUE, 192, 328, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
169 { TRUE, 193, 329, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
170 { TRUE, 194, 330, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
171 { TRUE, 195, 331, STRING_TOKEN (STR_REPAIR_REQUIRED), FALSE, EfiDriverHealthStatusRepairRequired },
172
173 { TRUE, 196, 300, 0, TRUE, EfiDriverHealthStatusRepairRequired },
174 { TRUE, 197, 301, 0, TRUE, EfiDriverHealthStatusRepairRequired },
175 { TRUE, 198, 302, 0, TRUE, EfiDriverHealthStatusRepairRequired },
176 { TRUE, 199, 303, 0, TRUE, EfiDriverHealthStatusRepairRequired },
177 { TRUE, 200, 304, 0, TRUE, EfiDriverHealthStatusRepairRequired },
178 { TRUE, 201, 305, 0, TRUE, EfiDriverHealthStatusRepairRequired },
179 { TRUE, 202, 306, 0, TRUE, EfiDriverHealthStatusRepairRequired },
180 { TRUE, 203, 307, 0, TRUE, EfiDriverHealthStatusRepairRequired },
181 { TRUE, 204, 308, 0, TRUE, EfiDriverHealthStatusRepairRequired },
182 { TRUE, 205, 309, 0, TRUE, EfiDriverHealthStatusRepairRequired },
183 { TRUE, 206, 310, 0, TRUE, EfiDriverHealthStatusRepairRequired },
184 { TRUE, 207, 311, 0, TRUE, EfiDriverHealthStatusRepairRequired },
185 { TRUE, 208, 312, 0, TRUE, EfiDriverHealthStatusRepairRequired },
186 { TRUE, 209, 313, 0, TRUE, EfiDriverHealthStatusRepairRequired },
187 { TRUE, 210, 314, 0, TRUE, EfiDriverHealthStatusRepairRequired },
188 { TRUE, 211, 315, 0, TRUE, EfiDriverHealthStatusRepairRequired },
189 { TRUE, 212, 316, 0, TRUE, EfiDriverHealthStatusRepairRequired },
190 { TRUE, 213, 317, 0, TRUE, EfiDriverHealthStatusRepairRequired },
191 { TRUE, 214, 318, 0, TRUE, EfiDriverHealthStatusRepairRequired },
192 { TRUE, 215, 319, 0, TRUE, EfiDriverHealthStatusRepairRequired },
193 { TRUE, 216, 320, 0, TRUE, EfiDriverHealthStatusRepairRequired },
194 { TRUE, 217, 321, 0, TRUE, EfiDriverHealthStatusRepairRequired },
195 { TRUE, 218, 322, 0, TRUE, EfiDriverHealthStatusRepairRequired },
196 { TRUE, 219, 323, 0, TRUE, EfiDriverHealthStatusRepairRequired },
197 { TRUE, 220, 324, 0, TRUE, EfiDriverHealthStatusRepairRequired },
198 { TRUE, 221, 325, 0, TRUE, EfiDriverHealthStatusRepairRequired },
199 { TRUE, 222, 326, 0, TRUE, EfiDriverHealthStatusRepairRequired },
200 { TRUE, 223, 327, 0, TRUE, EfiDriverHealthStatusRepairRequired },
201 { TRUE, 224, 328, 0, TRUE, EfiDriverHealthStatusRepairRequired },
202 { TRUE, 225, 329, 0, TRUE, EfiDriverHealthStatusRepairRequired },
203 { TRUE, 226, 330, 0, TRUE, EfiDriverHealthStatusRepairRequired },
204 { TRUE, 227, 331, 0, TRUE, EfiDriverHealthStatusRepairRequired },
205
206 { TRUE, 228, 300, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
207 { TRUE, 229, 301, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
208 { TRUE, 230, 302, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
209 { TRUE, 231, 303, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
210 { TRUE, 232, 304, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
211 { TRUE, 233, 305, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
212 { TRUE, 234, 306, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
213 { TRUE, 235, 307, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
214 { TRUE, 236, 308, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
215 { TRUE, 237, 309, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
216 { TRUE, 238, 310, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
217 { TRUE, 239, 311, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
218 { TRUE, 240, 312, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
219 { TRUE, 241, 313, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
220 { TRUE, 242, 314, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
221 { TRUE, 243, 315, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
222 { TRUE, 244, 316, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
223 { TRUE, 245, 317, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
224 { TRUE, 246, 318, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
225 { TRUE, 247, 319, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
226 { TRUE, 248, 320, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
227 { TRUE, 249, 321, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
228 { TRUE, 250, 322, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
229 { TRUE, 251, 323, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
230 { TRUE, 252, 324, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
231 { TRUE, 253, 325, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
232 { TRUE, 254, 326, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
233 { TRUE, 255, 327, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
234 { TRUE, 256, 328, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
235 { TRUE, 257, 329, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
236 { TRUE, 258, 330, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
237 { TRUE, 259, 331, STRING_TOKEN (STR_REPAIR_REQUIRED), TRUE, EfiDriverHealthStatusRepairRequired },
238
239 { TRUE, 300, 000, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
240 { TRUE, 301, 001, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
241 { TRUE, 302, 002, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
242 { TRUE, 303, 003, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
243 { TRUE, 304, 004, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
244 { TRUE, 305, 005, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
245 { TRUE, 306, 006, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
246 { TRUE, 307, 007, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
247
248 { TRUE, 308, 000, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
249 { TRUE, 309, 001, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
250 { TRUE, 310, 002, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
251 { TRUE, 311, 003, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
252 { TRUE, 312, 004, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
253 { TRUE, 313, 005, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
254 { TRUE, 314, 006, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
255 { TRUE, 315, 007, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
256
257 { TRUE, 316, 000, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
258 { TRUE, 317, 001, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
259 { TRUE, 318, 002, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
260 { TRUE, 319, 003, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
261 { TRUE, 320, 004, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
262 { TRUE, 321, 005, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
263 { TRUE, 322, 006, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
264 { TRUE, 323, 007, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
265
266 { TRUE, 324, 000, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
267 { TRUE, 325, 001, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
268 { TRUE, 326, 002, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
269 { TRUE, 327, 003, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
270 { TRUE, 328, 004, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
271 { TRUE, 329, 005, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
272 { TRUE, 330, 006, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
273 { TRUE, 331, 007, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
274
275 { TRUE, 332, 100, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
276 { TRUE, 333, 101, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
277 { TRUE, 334, 102, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
278 { TRUE, 335, 103, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
279 { TRUE, 336, 104, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
280 { TRUE, 337, 105, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
281 { TRUE, 338, 106, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
282 { TRUE, 339, 107, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
283 { TRUE, 340, 108, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
284 { TRUE, 341, 109, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
285 { TRUE, 342, 110, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
286 { TRUE, 343, 111, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
287 { TRUE, 344, 112, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
288 { TRUE, 345, 113, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
289 { TRUE, 346, 114, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
290 { TRUE, 347, 115, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
291
292 { TRUE, 348, 100, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
293 { TRUE, 349, 101, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
294 { TRUE, 350, 102, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
295 { TRUE, 351, 103, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
296 { TRUE, 352, 104, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
297 { TRUE, 353, 105, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
298 { TRUE, 354, 106, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
299 { TRUE, 355, 107, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
300 { TRUE, 356, 108, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
301 { TRUE, 357, 109, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
302 { TRUE, 358, 110, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
303 { TRUE, 359, 111, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
304 { TRUE, 360, 112, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
305 { TRUE, 361, 113, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
306 { TRUE, 362, 114, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
307 { TRUE, 363, 115, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
308
309 { TRUE, 364, 100, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
310 { TRUE, 365, 101, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
311 { TRUE, 366, 102, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
312 { TRUE, 367, 103, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
313 { TRUE, 368, 104, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
314 { TRUE, 369, 105, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
315 { TRUE, 370, 106, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
316 { TRUE, 371, 107, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
317 { TRUE, 372, 108, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
318 { TRUE, 373, 109, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
319 { TRUE, 374, 110, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
320 { TRUE, 375, 111, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
321 { TRUE, 376, 112, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
322 { TRUE, 377, 113, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
323 { TRUE, 378, 114, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
324 { TRUE, 379, 115, 0, FALSE, EfiDriverHealthStatusConfigurationRequired },
325
326 { TRUE, 380, 100, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
327 { TRUE, 381, 101, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
328 { TRUE, 382, 102, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
329 { TRUE, 383, 103, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
330 { TRUE, 384, 104, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
331 { TRUE, 385, 105, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
332 { TRUE, 386, 106, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
333 { TRUE, 387, 107, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
334 { TRUE, 388, 108, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
335 { TRUE, 389, 109, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
336 { TRUE, 390, 110, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
337 { TRUE, 391, 111, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
338 { TRUE, 392, 112, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
339 { TRUE, 393, 113, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
340 { TRUE, 394, 114, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
341 { TRUE, 395, 115, STRING_TOKEN (STR_CONFIG_WARNING), FALSE, EfiDriverHealthStatusConfigurationRequired },
342
343 { TRUE, 999, 999, 0, FALSE }
344 };
345
346 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePathDiskIoDummy = {
347 {
348 {
349 HARDWARE_DEVICE_PATH,
350 HW_VENDOR_DP,
351 {
352 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
353 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
354 }
355 },
356 //
357 // {C153B68E-EBFC-488e-B110-662867745BBE}
358 //
359 { 0xc153b68e, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0xbe} }
360 },
361 {
362 END_DEVICE_PATH_TYPE,
363 END_ENTIRE_DEVICE_PATH_SUBTYPE,
364 {
365 (UINT8) (END_DEVICE_PATH_LENGTH),
366 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
367 }
368 }
369 };
370
371 EFI_HII_HANDLE mHiiHandle = NULL;
372
373 EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBinding = {
374 DiskIoDriverBindingSupported,
375 DiskIoDriverBindingStart,
376 DiskIoDriverBindingStop,
377 0xaa,
378 NULL,
379 NULL
380 };
381
382 EFI_DRIVER_HEALTH_PROTOCOL gDiskIoDriverHealth = {
383 DiskIoDriverHealthGetHealthStatus,
384 DiskIoDriverHealthRepair
385 };
386 //
387 // Template for DiskIo private data structure.
388 // The pointer to BlockIo protocol interface is assigned dynamically.
389 //
390 DISK_IO_PRIVATE_DATA gDiskIoPrivateDataTemplate = {
391 DISK_IO_PRIVATE_DATA_SIGNATURE,
392 {
393 EFI_DISK_IO_PROTOCOL_REVISION,
394 DiskIoReadDisk,
395 DiskIoWriteDisk
396 },
397 NULL,
398 NULL, // Handle
399 NULL, // Consumed Protocol
400 NULL,
401 //
402 // Produced Protocol
403 //
404 {
405 DummyExtractConfig,
406 DummyRouteConfig,
407 DummyDriverCallback
408 },
409 //
410 // NVdata
411 //
412 { 0x0 },
413 //
414 // Controller Name
415 //
416 NULL,
417 //
418 // Controller Index
419 //
420 0
421 };
422
423 DEVICE_STATE *
424 GetDeviceState (
425 UINTN DeviceStateNumber
426 )
427 {
428 UINTN Index;
429
430 for (Index = 0; mDeviceState[Index].CurrentState != 999 && mDeviceState[Index].CurrentState != DeviceStateNumber; Index++);
431 ASSERT (mDeviceState[Index].CurrentState != 999);
432
433 return &mDeviceState[Index];
434 }
435
436
437 /**
438 Test to see if this driver supports ControllerHandle.
439
440 @param This Protocol instance pointer.
441 @param ControllerHandle Handle of device to test
442 @param RemainingDevicePath Optional parameter use to pick a specific child
443 device to start.
444
445 @retval EFI_SUCCESS This driver supports this device
446 @retval EFI_ALREADY_STARTED This driver is already running on this device
447 @retval other This driver does not support this device
448
449 **/
450 EFI_STATUS
451 EFIAPI
452 DiskIoDriverBindingSupported (
453 IN EFI_DRIVER_BINDING_PROTOCOL *This,
454 IN EFI_HANDLE ControllerHandle,
455 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
456 )
457 {
458 EFI_STATUS Status;
459 EFI_BLOCK_IO_PROTOCOL *BlockIo;
460
461 //
462 // Open the IO Abstraction(s) needed to perform the supported test.
463 //
464 Status = gBS->OpenProtocol (
465 ControllerHandle,
466 &gEfiBlockIoProtocolGuid,
467 (VOID **) &BlockIo,
468 This->DriverBindingHandle,
469 ControllerHandle,
470 EFI_OPEN_PROTOCOL_BY_DRIVER
471 );
472 if (EFI_ERROR (Status)) {
473 return Status;
474 }
475
476 //
477 // Close the I/O Abstraction(s) used to perform the supported test.
478 //
479 gBS->CloseProtocol (
480 ControllerHandle,
481 &gEfiBlockIoProtocolGuid,
482 This->DriverBindingHandle,
483 ControllerHandle
484 );
485 return EFI_SUCCESS;
486 }
487
488
489 /**
490 Start this driver on ControllerHandle by opening a Block IO protocol and
491 installing a Disk IO protocol on ControllerHandle.
492
493 @param This Protocol instance pointer.
494 @param ControllerHandle Handle of device to bind driver to
495 @param RemainingDevicePath Optional parameter use to pick a specific child
496 device to start.
497
498 @retval EFI_SUCCESS This driver is added to ControllerHandle
499 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
500 @retval other This driver does not support this device
501
502 **/
503 EFI_STATUS
504 EFIAPI
505 DiskIoDriverBindingStart (
506 IN EFI_DRIVER_BINDING_PROTOCOL *This,
507 IN EFI_HANDLE ControllerHandle,
508 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
509 )
510 {
511 EFI_STATUS Status;
512 DISK_IO_PRIVATE_DATA *Private;
513 DEVICE_STATE *DeviceState;
514 UINTN DataSize;
515 UINT32 StartCount;
516 CONTROLLER_STATE *ControllerState;
517
518 Private = NULL;
519 ControllerState = NULL;
520
521 //
522 // Connect to the Block IO interface on ControllerHandle.
523 //
524 Status = gBS->OpenProtocol (
525 ControllerHandle,
526 &gEfiBlockIoProtocolGuid,
527 (VOID **) &gDiskIoPrivateDataTemplate.BlockIo,
528 This->DriverBindingHandle,
529 ControllerHandle,
530 EFI_OPEN_PROTOCOL_BY_DRIVER
531 );
532 if (EFI_ERROR (Status)) {
533 return Status;
534 }
535
536 //
537 // Initialize the Disk IO device instance.
538 //
539 Private = AllocateCopyPool (sizeof (DISK_IO_PRIVATE_DATA), &gDiskIoPrivateDataTemplate);
540 if (Private == NULL) {
541 Status = EFI_OUT_OF_RESOURCES;
542 goto ErrorExit;
543 }
544
545 //
546 // Begin Driver Health Protocol Support
547 //
548 DataSize = sizeof (StartCount);
549 Status = gRT->GetVariable (
550 L"StartCount",
551 &gEfiCallerIdGuid,
552 NULL,
553 &DataSize,
554 &StartCount
555 );
556 if (EFI_ERROR (Status)) {
557 //
558 // If the configuration can not be read, then set the default config value of 0
559 //
560 StartCount = 0;
561 }
562
563 ControllerIndex++;
564
565 DeviceState = GetDeviceState (mDeviceState[StartCount].CurrentState);
566 ASSERT (DeviceState != NULL);
567
568 ControllerState = AllocateZeroPool (sizeof (CONTROLLER_STATE));
569 if (ControllerState == NULL) {
570 return EFI_OUT_OF_RESOURCES;
571 }
572
573 ControllerState->ControllerHandle = ControllerHandle;
574 ControllerState->Signature = DISK_IO_CONTROLLER_STATE_SIGNATURE;
575 ControllerState->DeviceStateNum = DeviceState->CurrentState;
576 ControllerState->ChildHandle = NULL;
577 ControllerState->ControllerIndex = ControllerIndex;
578
579 InsertTailList (&mControllerList, &ControllerState->Link);
580
581 if (DeviceState->HealthStatus != EfiDriverHealthStatusHealthy || DeviceState->StringId != 0) {
582 mNumNotHealthy++;
583 }
584
585 StartCount++;
586 while (!mDeviceState[StartCount].StartState) {
587 if (mDeviceState[StartCount].CurrentState == 999) {
588 StartCount = 0;
589 } else {
590 StartCount++;
591 }
592 }
593 if (mDeviceState[StartCount].CurrentState == 999) {
594 StartCount = 0;
595 }
596
597 Status = gRT->SetVariable (
598 L"StartCount",
599 &gEfiCallerIdGuid,
600 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
601 sizeof (StartCount),
602 &StartCount
603 );
604 ASSERT_EFI_ERROR (Status);
605
606 if (DeviceState->HealthStatus == EfiDriverHealthStatusConfigurationRequired) {
607 Private->NVdata.ConfigGood = 0;
608 } else {
609 Private->NVdata.ConfigGood = 1;
610 }
611 Status = gRT->SetVariable (
612 L"Config",
613 &gEfiCallerIdGuid,
614 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
615 sizeof (Private->NVdata.ConfigGood),
616 &Private->NVdata.ConfigGood
617 );
618 ASSERT_EFI_ERROR (Status);
619
620 //
621 // End Driver Health Protocol Support
622 //
623
624 //
625 // Install protocol interfaces for the Disk IO device.
626 //
627 Status = gBS->InstallProtocolInterface (
628 &ControllerHandle,
629 &gEfiDiskIoProtocolGuid,
630 EFI_NATIVE_INTERFACE,
631 &Private->DiskIo
632 );
633
634 Private->ControllerIndex = ControllerIndex;
635 AddName (Private);
636
637 ErrorExit:
638 if (EFI_ERROR (Status)) {
639
640 if (Private != NULL) {
641 FreeUnicodeStringTable (Private->ControllerNameTable);
642 FreePool (Private);
643 }
644
645 gBS->CloseProtocol (
646 ControllerHandle,
647 &gEfiBlockIoProtocolGuid,
648 This->DriverBindingHandle,
649 ControllerHandle
650 );
651 }
652
653 return Status;
654 }
655
656
657 /**
658 Stop this driver on ControllerHandle by removing Disk IO protocol and closing
659 the Block IO protocol on ControllerHandle.
660
661 @param This Protocol instance pointer.
662 @param ControllerHandle Handle of device to stop driver on
663 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
664 children is zero stop the entire bus driver.
665 @param ChildHandleBuffer List of Child Handles to Stop.
666
667 @retval EFI_SUCCESS This driver is removed ControllerHandle
668 @retval other This driver was not removed from this device
669
670 **/
671 EFI_STATUS
672 EFIAPI
673 DiskIoDriverBindingStop (
674 IN EFI_DRIVER_BINDING_PROTOCOL *This,
675 IN EFI_HANDLE ControllerHandle,
676 IN UINTN NumberOfChildren,
677 IN EFI_HANDLE *ChildHandleBuffer
678 )
679 {
680 EFI_STATUS Status;
681 EFI_DISK_IO_PROTOCOL *DiskIo;
682 DISK_IO_PRIVATE_DATA *Private;
683 DEVICE_STATE *DeviceState;
684 CONTROLLER_STATE *ControllerState;
685 LIST_ENTRY *Link;
686
687 ControllerState = NULL;
688 DeviceState = NULL;
689
690 //
691 // Get our context back.
692 //
693 Status = gBS->OpenProtocol (
694 ControllerHandle,
695 &gEfiDiskIoProtocolGuid,
696 (VOID **) &DiskIo,
697 This->DriverBindingHandle,
698 ControllerHandle,
699 EFI_OPEN_PROTOCOL_GET_PROTOCOL
700 );
701 if (EFI_ERROR (Status)) {
702 return EFI_UNSUPPORTED;
703 }
704
705 Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);
706
707 Status = gBS->UninstallProtocolInterface (
708 ControllerHandle,
709 &gEfiDiskIoProtocolGuid,
710 &Private->DiskIo
711 );
712 if (!EFI_ERROR (Status)) {
713
714 Status = gBS->CloseProtocol (
715 ControllerHandle,
716 &gEfiBlockIoProtocolGuid,
717 This->DriverBindingHandle,
718 ControllerHandle
719 );
720 //
721 // Get the Controller State from global list
722 //
723 Link = GetFirstNode (&mControllerList);
724
725 while (!IsNull (&mControllerList, Link)) {
726 ControllerState = DISK_IO_CONTROLLER_STATE_FROM_LINK (Link);
727
728 if (ControllerState->ControllerHandle == ControllerHandle) {
729 DeviceState = GetDeviceState (ControllerState->DeviceStateNum);
730 break;
731 }
732 Link = GetNextNode (&mControllerList, Link);
733 }
734
735 ASSERT (DeviceState != NULL);
736
737 if (DeviceState->HealthStatus != EfiDriverHealthStatusHealthy || DeviceState->StringId != 0) {
738 mNumNotHealthy--;
739 }
740
741 RemoveEntryList (Link);
742
743 if (ControllerState != NULL) {
744 FreePool (ControllerState);
745 }
746 }
747
748 if (!EFI_ERROR (Status)) {
749 FreeUnicodeStringTable (Private->ControllerNameTable);
750 FreePool (Private);
751 }
752
753 ControllerIndex = 0;
754 return Status;
755 }
756
757
758
759 /**
760 Read BufferSize bytes from Offset into Buffer.
761 Reads may support reads that are not aligned on
762 sector boundaries. There are three cases:
763 UnderRun - The first byte is not on a sector boundary or the read request is
764 less than a sector in length.
765 Aligned - A read of N contiguous sectors.
766 OverRun - The last byte is not on a sector boundary.
767
768 @param This Protocol instance pointer.
769 @param MediaId Id of the media, changes every time the media is replaced.
770 @param Offset The starting byte offset to read from
771 @param BufferSize Size of Buffer
772 @param Buffer Buffer containing read data
773
774 @retval EFI_SUCCESS The data was read correctly from the device.
775 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
776 @retval EFI_NO_MEDIA There is no media in the device.
777 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
778 @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not
779 valid for the device.
780
781 **/
782 EFI_STATUS
783 EFIAPI
784 DiskIoReadDisk (
785 IN EFI_DISK_IO_PROTOCOL *This,
786 IN UINT32 MediaId,
787 IN UINT64 Offset,
788 IN UINTN BufferSize,
789 OUT VOID *Buffer
790 )
791 {
792 EFI_STATUS Status;
793 DISK_IO_PRIVATE_DATA *Private;
794 EFI_BLOCK_IO_PROTOCOL *BlockIo;
795 EFI_BLOCK_IO_MEDIA *Media;
796 UINT32 BlockSize;
797 UINT64 Lba;
798 UINT64 OverRunLba;
799 UINT32 UnderRun;
800 UINT32 OverRun;
801 BOOLEAN TransactionComplete;
802 UINTN WorkingBufferSize;
803 UINT8 *WorkingBuffer;
804 UINTN Length;
805 UINT8 *Data;
806 UINT8 *PreData;
807 UINTN IsBufferAligned;
808 UINTN DataBufferSize;
809 BOOLEAN LastRead;
810
811 Private = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
812
813 BlockIo = Private->BlockIo;
814 Media = BlockIo->Media;
815 BlockSize = Media->BlockSize;
816
817 if (Media->MediaId != MediaId) {
818 return EFI_MEDIA_CHANGED;
819 }
820
821 WorkingBuffer = Buffer;
822 WorkingBufferSize = BufferSize;
823
824 //
825 // Allocate a temporary buffer for operation
826 //
827 DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
828
829 if (Media->IoAlign > 1) {
830 PreData = AllocatePool (DataBufferSize + Media->IoAlign);
831 Data = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
832 } else {
833 PreData = AllocatePool (DataBufferSize);
834 Data = PreData;
835 }
836
837 if (PreData == NULL) {
838 return EFI_OUT_OF_RESOURCES;
839 }
840
841 Lba = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
842
843 Length = BlockSize - UnderRun;
844 TransactionComplete = FALSE;
845
846 Status = EFI_SUCCESS;
847 if (UnderRun != 0) {
848 //
849 // Offset starts in the middle of an Lba, so read the entire block.
850 //
851 Status = BlockIo->ReadBlocks (
852 BlockIo,
853 MediaId,
854 Lba,
855 BlockSize,
856 Data
857 );
858
859 if (EFI_ERROR (Status)) {
860 goto Done;
861 }
862
863 if (Length > BufferSize) {
864 Length = BufferSize;
865 TransactionComplete = TRUE;
866 }
867
868 CopyMem (WorkingBuffer, Data + UnderRun, Length);
869
870 WorkingBuffer += Length;
871
872 WorkingBufferSize -= Length;
873 if (WorkingBufferSize == 0) {
874 goto Done;
875 }
876
877 Lba += 1;
878 }
879
880 OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
881
882 if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
883 //
884 // If the DiskIo maps directly to a BlockIo device do the read.
885 //
886 if (OverRun != 0) {
887 WorkingBufferSize -= OverRun;
888 }
889 //
890 // Check buffer alignment
891 //
892 IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
893
894 if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
895 //
896 // Alignment is satisfied, so read them together
897 //
898 Status = BlockIo->ReadBlocks (
899 BlockIo,
900 MediaId,
901 Lba,
902 WorkingBufferSize,
903 WorkingBuffer
904 );
905
906 if (EFI_ERROR (Status)) {
907 goto Done;
908 }
909
910 WorkingBuffer += WorkingBufferSize;
911
912 } else {
913 //
914 // Use the allocated buffer instead of the original buffer
915 // to avoid alignment issue.
916 // Here, the allocated buffer (8-byte align) can satisfy the alignment
917 //
918 LastRead = FALSE;
919 do {
920 if (WorkingBufferSize <= DataBufferSize) {
921 //
922 // It is the last calling to readblocks in this loop
923 //
924 DataBufferSize = WorkingBufferSize;
925 LastRead = TRUE;
926 }
927
928 Status = BlockIo->ReadBlocks (
929 BlockIo,
930 MediaId,
931 Lba,
932 DataBufferSize,
933 Data
934 );
935 if (EFI_ERROR (Status)) {
936 goto Done;
937 }
938
939 CopyMem (WorkingBuffer, Data, DataBufferSize);
940 WorkingBufferSize -= DataBufferSize;
941 WorkingBuffer += DataBufferSize;
942 Lba += DATA_BUFFER_BLOCK_NUM;
943 } while (!LastRead);
944 }
945 }
946
947 if (!TransactionComplete && OverRun != 0) {
948 //
949 // Last read is not a complete block.
950 //
951 Status = BlockIo->ReadBlocks (
952 BlockIo,
953 MediaId,
954 OverRunLba,
955 BlockSize,
956 Data
957 );
958
959 if (EFI_ERROR (Status)) {
960 goto Done;
961 }
962
963 CopyMem (WorkingBuffer, Data, OverRun);
964 }
965
966 Done:
967 if (PreData != NULL) {
968 FreePool (PreData);
969 }
970
971 return Status;
972 }
973
974
975 /**
976 Writes BufferSize bytes from Buffer into Offset.
977 Writes may require a read modify write to support writes that are not
978 aligned on sector boundaries. There are three cases:
979 UnderRun - The first byte is not on a sector boundary or the write request
980 is less than a sector in length. Read modify write is required.
981 Aligned - A write of N contiguous sectors.
982 OverRun - The last byte is not on a sector boundary. Read modified write
983 required.
984
985 @param This Protocol instance pointer.
986 @param MediaId Id of the media, changes every time the media is replaced.
987 @param Offset The starting byte offset to read from
988 @param BufferSize Size of Buffer
989 @param Buffer Buffer containing read data
990
991 @retval EFI_SUCCESS The data was written correctly to the device.
992 @retval EFI_WRITE_PROTECTED The device can not be written to.
993 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
994 @retval EFI_NO_MEDIA There is no media in the device.
995 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
996 @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not
997 valid for the device.
998
999 **/
1000 EFI_STATUS
1001 EFIAPI
1002 DiskIoWriteDisk (
1003 IN EFI_DISK_IO_PROTOCOL *This,
1004 IN UINT32 MediaId,
1005 IN UINT64 Offset,
1006 IN UINTN BufferSize,
1007 IN VOID *Buffer
1008 )
1009 {
1010 EFI_STATUS Status;
1011 DISK_IO_PRIVATE_DATA *Private;
1012 EFI_BLOCK_IO_PROTOCOL *BlockIo;
1013 EFI_BLOCK_IO_MEDIA *Media;
1014 UINT32 BlockSize;
1015 UINT64 Lba;
1016 UINT64 OverRunLba;
1017 UINT32 UnderRun;
1018 UINT32 OverRun;
1019 BOOLEAN TransactionComplete;
1020 UINTN WorkingBufferSize;
1021 UINT8 *WorkingBuffer;
1022 UINTN Length;
1023 UINT8 *Data;
1024 UINT8 *PreData;
1025 UINTN IsBufferAligned;
1026 UINTN DataBufferSize;
1027 BOOLEAN LastWrite;
1028
1029 Private = DISK_IO_PRIVATE_DATA_FROM_THIS (This);
1030
1031 BlockIo = Private->BlockIo;
1032 Media = BlockIo->Media;
1033 BlockSize = Media->BlockSize;
1034
1035 if (Media->ReadOnly) {
1036 return EFI_WRITE_PROTECTED;
1037 }
1038
1039 if (Media->MediaId != MediaId) {
1040 return EFI_MEDIA_CHANGED;
1041 }
1042
1043 DataBufferSize = BlockSize * DATA_BUFFER_BLOCK_NUM;
1044
1045 if (Media->IoAlign > 1) {
1046 PreData = AllocatePool (DataBufferSize + Media->IoAlign);
1047 Data = PreData - ((UINTN) PreData & (Media->IoAlign - 1)) + Media->IoAlign;
1048 } else {
1049 PreData = AllocatePool (DataBufferSize);
1050 Data = PreData;
1051 }
1052
1053 if (PreData == NULL) {
1054 return EFI_OUT_OF_RESOURCES;
1055 }
1056
1057 WorkingBuffer = Buffer;
1058 WorkingBufferSize = BufferSize;
1059
1060 Lba = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
1061
1062 Length = BlockSize - UnderRun;
1063 TransactionComplete = FALSE;
1064
1065 Status = EFI_SUCCESS;
1066 if (UnderRun != 0) {
1067 //
1068 // Offset starts in the middle of an Lba, so do read modify write.
1069 //
1070 Status = BlockIo->ReadBlocks (
1071 BlockIo,
1072 MediaId,
1073 Lba,
1074 BlockSize,
1075 Data
1076 );
1077
1078 if (EFI_ERROR (Status)) {
1079 goto Done;
1080 }
1081
1082 if (Length > BufferSize) {
1083 Length = BufferSize;
1084 TransactionComplete = TRUE;
1085 }
1086
1087 CopyMem (Data + UnderRun, WorkingBuffer, Length);
1088
1089 Status = BlockIo->WriteBlocks (
1090 BlockIo,
1091 MediaId,
1092 Lba,
1093 BlockSize,
1094 Data
1095 );
1096 if (EFI_ERROR (Status)) {
1097 goto Done;
1098 }
1099
1100 WorkingBuffer += Length;
1101 WorkingBufferSize -= Length;
1102 if (WorkingBufferSize == 0) {
1103 goto Done;
1104 }
1105
1106 Lba += 1;
1107 }
1108
1109 OverRunLba = Lba + DivU64x32Remainder (WorkingBufferSize, BlockSize, &OverRun);
1110
1111 if (!TransactionComplete && WorkingBufferSize >= BlockSize) {
1112 //
1113 // If the DiskIo maps directly to a BlockIo device do the write.
1114 //
1115 if (OverRun != 0) {
1116 WorkingBufferSize -= OverRun;
1117 }
1118 //
1119 // Check buffer alignment
1120 //
1121 IsBufferAligned = (UINTN) WorkingBuffer & (UINTN) (Media->IoAlign - 1);
1122
1123 if (Media->IoAlign <= 1 || IsBufferAligned == 0) {
1124 //
1125 // Alignment is satisfied, so write them together
1126 //
1127 Status = BlockIo->WriteBlocks (
1128 BlockIo,
1129 MediaId,
1130 Lba,
1131 WorkingBufferSize,
1132 WorkingBuffer
1133 );
1134
1135 if (EFI_ERROR (Status)) {
1136 goto Done;
1137 }
1138
1139 WorkingBuffer += WorkingBufferSize;
1140
1141 } else {
1142 //
1143 // The buffer parameter is not aligned with the request
1144 // So use the allocated instead.
1145 // It can fit almost all the cases.
1146 //
1147 LastWrite = FALSE;
1148 do {
1149 if (WorkingBufferSize <= DataBufferSize) {
1150 //
1151 // It is the last calling to writeblocks in this loop
1152 //
1153 DataBufferSize = WorkingBufferSize;
1154 LastWrite = TRUE;
1155 }
1156
1157 CopyMem (Data, WorkingBuffer, DataBufferSize);
1158 Status = BlockIo->WriteBlocks (
1159 BlockIo,
1160 MediaId,
1161 Lba,
1162 DataBufferSize,
1163 Data
1164 );
1165 if (EFI_ERROR (Status)) {
1166 goto Done;
1167 }
1168
1169 WorkingBufferSize -= DataBufferSize;
1170 WorkingBuffer += DataBufferSize;
1171 Lba += DATA_BUFFER_BLOCK_NUM;
1172 } while (!LastWrite);
1173 }
1174 }
1175
1176 if (!TransactionComplete && OverRun != 0) {
1177 //
1178 // Last bit is not a complete block, so do a read modify write.
1179 //
1180 Status = BlockIo->ReadBlocks (
1181 BlockIo,
1182 MediaId,
1183 OverRunLba,
1184 BlockSize,
1185 Data
1186 );
1187
1188 if (EFI_ERROR (Status)) {
1189 goto Done;
1190 }
1191
1192 CopyMem (Data, WorkingBuffer, OverRun);
1193
1194 Status = BlockIo->WriteBlocks (
1195 BlockIo,
1196 MediaId,
1197 OverRunLba,
1198 BlockSize,
1199 Data
1200 );
1201 if (EFI_ERROR (Status)) {
1202 goto Done;
1203 }
1204 }
1205
1206 Done:
1207 if (PreData != NULL) {
1208 FreePool (PreData);
1209 }
1210
1211 return Status;
1212 }
1213
1214
1215 /**
1216 Retrieves the health status of a controller in the platform. This function can also
1217 optionally return warning messages, error messages, and a set of HII Forms that may
1218 be repair a controller that is not proper configured.
1219
1220 @param This A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1221
1222 @param ControllerHandle The handle of the controller to retrieve the health status
1223 on. This is an optional parameter that may be NULL. If
1224 this parameter is NULL, then the value of ChildHandle is
1225 ignored, and the combined health status of all the devices
1226 that the driver is managing is returned.
1227
1228 @param ChildHandle The handle of the child controller to retrieve the health
1229 status on. This is an optional parameter that may be NULL.
1230 This parameter is ignored of ControllerHandle is NULL. It
1231 will be NULL for device drivers. It will also be NULL for
1232 bus drivers when an attempt is made to collect the health
1233 status of the bus controller. If will not be NULL when an
1234 attempt is made to collect the health status for a child
1235 controller produced by the driver.
1236
1237 @param HealthStatus A pointer to the health status that is returned by this
1238 function. This is an optional parameter that may be NULL.
1239 This parameter is ignored of ControllerHandle is NULL.
1240 The health status for the controller specified by
1241 ControllerHandle and ChildHandle is returned.
1242
1243 @param MessageList A pointer to an array of warning or error messages associated
1244 with the controller specified by ControllerHandle and
1245 ChildHandle. This is an optional parameter that may be NULL.
1246 MessageList is allocated by this function with the EFI Boot
1247 Service AllocatePool(), and it is the caller's responsibility
1248 to free MessageList with the EFI Boot Service FreePool().
1249 Each message is specified by tuple of an EFI_HII_HANDLE and
1250 an EFI_STRING_ID. The array of messages is terminated by tuple
1251 containing a EFI_HII_HANDLE with a value of NULL. The
1252 EFI_HII_STRING_PROTOCOL.GetString() function can be used to
1253 retrieve the warning or error message as a Null-terminated
1254 Unicode string in a specific language. Messages may be
1255 returned for any of the HealthStatus values except
1256 EfiDriverHealthStatusReconnectRequired and
1257 EfiDriverHealthStatusRebootRequired.
1258
1259 @param FormHiiHandle A pointer to the HII handle for an HII form associated with the
1260 controller specified by ControllerHandle and ChildHandle.
1261 This is an optional parameter that may be NULL. An HII form
1262 is specified by a combination of an EFI_HII_HANDLE and an
1263 EFI_GUID that identifies the Form Set GUID. The
1264 EFI_FORM_BROWSER2_PROTOCOL.SendForm() function can be used
1265 to display and allow the user to make configuration changes
1266 to the HII Form. An HII form may only be returned with a
1267 HealthStatus value of EfiDriverHealthStatusConfigurationRequired.
1268
1269 @retval EFI_SUCCESS ControllerHandle is NULL, and all the controllers
1270 managed by this driver specified by This have a health
1271 status of EfiDriverHealthStatusHealthy with no warning
1272 messages to be returned. The ChildHandle, HealthStatus,
1273 MessageList, and FormList parameters are ignored.
1274
1275 @retval EFI_DEVICE_ERROR ControllerHandle is NULL, and one or more of the
1276 controllers managed by this driver specified by This
1277 do not have a health status of EfiDriverHealthStatusHealthy.
1278 The ChildHandle, HealthStatus, MessageList, and
1279 FormList parameters are ignored.
1280
1281 @retval EFI_DEVICE_ERROR ControllerHandle is NULL, and one or more of the
1282 controllers managed by this driver specified by This
1283 have one or more warning and/or error messages.
1284 The ChildHandle, HealthStatus, MessageList, and
1285 FormList parameters are ignored.
1286
1287 @retval EFI_SUCCESS ControllerHandle is not NULL and the health status
1288 of the controller specified by ControllerHandle and
1289 ChildHandle was returned in HealthStatus. A list
1290 of warning and error messages may be optionally
1291 returned in MessageList, and a list of HII Forms
1292 may be optionally returned in FormList.
1293
1294 @retval EFI_UNSUPPORTED ControllerHandle is not NULL, and the controller
1295 specified by ControllerHandle and ChildHandle is not
1296 currently being managed by the driver specified by This.
1297
1298 @retval EFI_INVALID_PARAMETER HealthStatus is NULL.
1299
1300 @retval EFI_OUT_OF_RESOURCES MessageList is not NULL, and there are not enough
1301 resource available to allocate memory for MessageList.
1302
1303 **/
1304 EFI_STATUS
1305 DiskIoDriverHealthGetHealthStatus (
1306 IN EFI_DRIVER_HEALTH_PROTOCOL *This,
1307 IN EFI_HANDLE ControllerHandle OPTIONAL,
1308 IN EFI_HANDLE ChildHandle OPTIONAL,
1309 OUT EFI_DRIVER_HEALTH_STATUS *HealthStatus,
1310 OUT EFI_DRIVER_HEALTH_HII_MESSAGE **MessageList OPTIONAL,
1311 OUT EFI_HII_HANDLE *FormHiiHandle OPTIONAL
1312 )
1313 {
1314 EFI_STATUS Status;
1315 EFI_DISK_IO_PROTOCOL *DiskIo;
1316 DISK_IO_PRIVATE_DATA *Private;
1317 DEVICE_STATE *DeviceState;
1318 CONTROLLER_STATE *ControllerState;
1319 LIST_ENTRY *Link;
1320 UINTN BufferSize;
1321
1322 ControllerState = NULL;
1323 DeviceState = NULL;
1324
1325 if (HealthStatus == NULL) {
1326 return EFI_INVALID_PARAMETER;
1327 }
1328
1329 if (ControllerHandle == NULL) {
1330 *HealthStatus = EfiDriverHealthStatusHealthy;
1331 if (mNumNotHealthy != 0) {
1332 *HealthStatus = EfiDriverHealthStatusFailed;
1333 }
1334 return EFI_SUCCESS;
1335 }
1336
1337 //
1338 // This is a device driver, so ChildHandle must be NULL.
1339 //
1340 if (ChildHandle != NULL) {
1341 return EFI_UNSUPPORTED;
1342 }
1343 //
1344 // Make sure this driver is currently managing ControllerHandle
1345 //
1346 Status = EfiTestManagedDevice (
1347 ControllerHandle,
1348 gDiskIoDriverBinding.DriverBindingHandle,
1349 &gEfiBlockIoProtocolGuid
1350 );
1351 if (EFI_ERROR (Status)) {
1352 return Status;
1353 }
1354
1355 if (HealthStatus == NULL) {
1356 return EFI_INVALID_PARAMETER;
1357 }
1358 Status = gBS->HandleProtocol (ControllerHandle, &gEfiDiskIoProtocolGuid, (VOID **) &DiskIo);
1359 if (EFI_ERROR (Status)) {
1360 return EFI_UNSUPPORTED;
1361 }
1362
1363 if (HealthStatus == NULL) {
1364 return EFI_INVALID_PARAMETER;
1365 }
1366
1367 Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);
1368
1369
1370 //
1371 // Get the Controller State from global list
1372 //
1373 Link = GetFirstNode (&mControllerList);
1374
1375 while (!IsNull (&mControllerList, Link)) {
1376 ControllerState = DISK_IO_CONTROLLER_STATE_FROM_LINK (Link);
1377
1378 if (ControllerState->ControllerHandle == ControllerHandle) {
1379 DeviceState = GetDeviceState (ControllerState->DeviceStateNum);
1380 break;
1381 }
1382 Link = GetNextNode (&mControllerList, Link);
1383 }
1384
1385 ASSERT (DeviceState != NULL);
1386
1387 if (DeviceState->HealthStatus == EfiDriverHealthStatusConfigurationRequired) {
1388
1389 //
1390 // Read the configuration for this device
1391 //
1392 BufferSize = sizeof (Private->NVdata.ConfigGood);
1393 Status = gRT->GetVariable (
1394 L"Config",
1395 &gEfiCallerIdGuid,
1396 NULL,
1397 &BufferSize,
1398 &Private->NVdata.ConfigGood
1399 );
1400 ASSERT_EFI_ERROR (Status);
1401
1402 //
1403 // If the config value is 1, then the configuration is valid and the state machine can move to the next state
1404 // Otherwise, the state machine returns ConfigurationRequired again
1405 //
1406 if (Private->NVdata.ConfigGood == ControllerState->ControllerIndex) {
1407 if (DeviceState->HealthStatus != EfiDriverHealthStatusHealthy || DeviceState->StringId != 0) {
1408 mNumNotHealthy--;
1409 }
1410
1411 ControllerState->DeviceStateNum = DeviceState->NextState;
1412
1413 DeviceState = GetDeviceState (ControllerState->DeviceStateNum);
1414 ASSERT (DeviceState != NULL);
1415
1416 if (DeviceState->HealthStatus != EfiDriverHealthStatusHealthy) {
1417 mNumNotHealthy++;
1418 }
1419 }
1420 }
1421
1422 *HealthStatus = DeviceState->HealthStatus;
1423
1424 if (MessageList != NULL) {
1425 *MessageList = NULL;
1426 if (DeviceState->StringId != 0) {
1427 *MessageList = AllocateZeroPool (sizeof(EFI_DRIVER_HEALTH_HII_MESSAGE) * 2);
1428 if (*MessageList == NULL) {
1429 return EFI_UNSUPPORTED;
1430 }
1431 (*MessageList)[0].HiiHandle = mHiiHandle;
1432 (*MessageList)[0].StringId = DeviceState->StringId;
1433 } else {
1434 *MessageList = AllocateZeroPool (sizeof(EFI_DRIVER_HEALTH_HII_MESSAGE) * 1);
1435 if (*MessageList == NULL) {
1436 return EFI_UNSUPPORTED;
1437 }
1438 }
1439 }
1440 if (FormHiiHandle != NULL) {
1441 *FormHiiHandle = mHiiHandle;
1442 }
1443
1444 if (DeviceState->HealthStatus == EfiDriverHealthStatusConfigurationRequired) {
1445 Private->NVdata.ConfigGood = 0;
1446 Status = gRT->SetVariable (
1447 L"Config",
1448 &gEfiCallerIdGuid,
1449 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1450 sizeof (Private->NVdata.ConfigGood),
1451 &Private->NVdata.ConfigGood
1452 );
1453 ASSERT_EFI_ERROR (Status);
1454 }
1455
1456 return EFI_SUCCESS;
1457 }
1458
1459 /**
1460 Performs a repair operation on a controller in the platform. This function can
1461 optionally report repair progress information back to the platform.
1462
1463 @param This A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1464 @param ControllerHandle The handle of the controller to repair.
1465 @param ChildHandle The handle of the child controller to repair. This is
1466 an optional parameter that may be NULL. It will be NULL
1467 for device drivers. It will also be NULL for bus
1468 drivers when an attempt is made to repair a bus controller.
1469 If will not be NULL when an attempt is made to repair a
1470 child controller produced by the driver.
1471 @param RepairNotify A notification function that may be used by a driver to
1472 report the progress of the repair operation. This is
1473 an optional parameter that may be NULL.
1474
1475
1476 @retval EFI_SUCCESS An attempt to repair the controller specified by
1477 ControllerHandle and ChildHandle was performed.
1478 The result of the repair operation can be
1479 determined by calling GetHealthStatus().
1480 @retval EFI_UNSUPPORTED The driver specified by This is not currently
1481 managing the controller specified by ControllerHandle
1482 and ChildHandle.
1483 @retval EFI_OUT_OF_RESOURCES There are not enough resources to perform the
1484 repair operation.
1485
1486 */
1487 EFI_STATUS
1488 DiskIoDriverHealthRepair (
1489 IN EFI_DRIVER_HEALTH_PROTOCOL *This,
1490 IN EFI_HANDLE ControllerHandle,
1491 IN EFI_HANDLE ChildHandle OPTIONAL,
1492 IN EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY RepairNotify OPTIONAL
1493 )
1494 {
1495 EFI_STATUS Status;
1496 UINTN Index;
1497 DEVICE_STATE *DeviceState;
1498 CONTROLLER_STATE *ControllerState;
1499 LIST_ENTRY *Link;
1500 EFI_DISK_IO_PROTOCOL *DiskIo;
1501 DISK_IO_PRIVATE_DATA *Private;
1502
1503 Index = 0;
1504 ControllerState = NULL;
1505 DeviceState = NULL;
1506 //
1507 // This is a device driver, so ChildHandle must be NULL.
1508 //
1509 if (ChildHandle != NULL) {
1510 return EFI_UNSUPPORTED;
1511 }
1512 //
1513 // Make sure this driver is currently managing ControllerHandle
1514 //
1515 Status = EfiTestManagedDevice (
1516 ControllerHandle,
1517 gDiskIoDriverBinding.DriverBindingHandle,
1518 &gEfiBlockIoProtocolGuid
1519 );
1520 if (EFI_ERROR (Status)) {
1521 return Status;
1522 }
1523
1524 Status = gBS->HandleProtocol (ControllerHandle, &gEfiDiskIoProtocolGuid, (VOID **) &DiskIo);
1525 if (EFI_ERROR (Status)) {
1526 return EFI_UNSUPPORTED;
1527 }
1528
1529 Private = DISK_IO_PRIVATE_DATA_FROM_THIS (DiskIo);
1530
1531 Link = GetFirstNode (&mControllerList);
1532
1533 while (!IsNull (&mControllerList, Link)) {
1534 ControllerState = DISK_IO_CONTROLLER_STATE_FROM_LINK (Link);
1535
1536 if (ControllerState->ControllerHandle == ControllerHandle) {
1537 DeviceState = GetDeviceState (ControllerState->DeviceStateNum);
1538 break;
1539 }
1540 Link = GetNextNode (&mControllerList, Link);
1541 }
1542
1543 ASSERT (DeviceState != NULL);
1544 //
1545 // Check to see if the controller has already been repaired
1546 //
1547 if (DeviceState->HealthStatus != EfiDriverHealthStatusRepairRequired) {
1548 return EFI_SUCCESS;
1549 }
1550
1551 if (DeviceState->RepairNotify) {
1552 do {
1553 RepairNotify(Index, 10);
1554 Index++;
1555 } while ((gBS->Stall(100000) == EFI_SUCCESS) && (Index < 10));
1556 }
1557
1558 if (DeviceState->HealthStatus != EfiDriverHealthStatusHealthy || DeviceState->StringId != 0) {
1559 mNumNotHealthy--;
1560 }
1561
1562 //
1563 // Repair success, go to next state
1564 //
1565 ControllerState->DeviceStateNum = DeviceState->NextState;
1566
1567 DeviceState = GetDeviceState (ControllerState->DeviceStateNum);
1568 ASSERT (DeviceState != NULL);
1569
1570 if (DeviceState->HealthStatus != EfiDriverHealthStatusHealthy || DeviceState->StringId != 0) {
1571 mNumNotHealthy++;
1572 }
1573
1574 if (DeviceState->HealthStatus == EfiDriverHealthStatusConfigurationRequired) {
1575 Private->NVdata.ConfigGood = 0;
1576 Status = gRT->SetVariable (
1577 L"Config",
1578 &gEfiCallerIdGuid,
1579 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1580 sizeof (Private->NVdata.ConfigGood),
1581 &Private->NVdata.ConfigGood
1582 );
1583 ASSERT_EFI_ERROR (Status);
1584 }
1585
1586 return EFI_SUCCESS;
1587 }
1588
1589 /**
1590 The user Entry Point for module DiskIo. The user code starts with this function.
1591
1592 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1593 @param[in] SystemTable A pointer to the EFI System Table.
1594
1595 @retval EFI_SUCCESS The entry point is executed successfully.
1596 @retval other Some error occurs when executing this entry point.
1597
1598 **/
1599 EFI_STATUS
1600 EFIAPI
1601 InitializeDiskIo (
1602 IN EFI_HANDLE ImageHandle,
1603 IN EFI_SYSTEM_TABLE *SystemTable
1604 )
1605 {
1606 EFI_STATUS Status;
1607 //
1608 // Install driver model protocol(s).
1609 //
1610 Status = EfiLibInstallDriverBindingComponentName2 (
1611 ImageHandle,
1612 SystemTable,
1613 &gDiskIoDriverBinding,
1614 ImageHandle,
1615 &gDiskIoComponentName,
1616 &gDiskIoComponentName2
1617 );
1618
1619 ASSERT_EFI_ERROR (Status);
1620
1621 Status = gBS->InstallProtocolInterface (
1622 &ImageHandle,
1623 &gEfiDriverHealthProtocolGuid,
1624 EFI_NATIVE_INTERFACE,
1625 &gDiskIoDriverHealth
1626 );
1627 ASSERT_EFI_ERROR (Status);
1628
1629 InitializeListHead (&mControllerList);
1630
1631 gDiskIoPrivateDataTemplate.Handle = ImageHandle;
1632 Status = DiskIoConfigFormInit ();
1633
1634 ASSERT_EFI_ERROR (Status);
1635
1636 return Status;
1637 }
1638
1639 /**
1640 Initialize the serial configuration form.
1641
1642 @retval EFI_SUCCESS The serial configuration form is initialized.
1643 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1644 @retval Others Other errors as indicated.
1645 **/
1646 EFI_STATUS
1647 DiskIoConfigFormInit (
1648 VOID
1649 )
1650 {
1651 EFI_STATUS Status;
1652
1653 //
1654 // Locate Hii Database protocol
1655 //
1656 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&gDiskIoPrivateDataTemplate.HiiDatabase);
1657 if (EFI_ERROR (Status)) {
1658 return Status;
1659 }
1660
1661 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&gDiskIoPrivateDataTemplate.HiiConfigRouting);
1662 if (EFI_ERROR (Status)) {
1663 return Status;
1664 }
1665
1666 //
1667 // Install Device Path Protocol and Config Access protocol to driver handle
1668 //
1669 Status = gBS->InstallMultipleProtocolInterfaces (
1670 &gDiskIoPrivateDataTemplate.Handle,
1671 &gEfiDevicePathProtocolGuid, &mHiiVendorDevicePathDiskIoDummy,
1672 &gEfiHiiConfigAccessProtocolGuid, &gDiskIoPrivateDataTemplate.ConfigAccess,
1673 NULL
1674 );
1675 if (EFI_ERROR (Status)) {
1676 return Status;
1677 }
1678
1679 //
1680 // Publish our HII data
1681 //
1682 mHiiHandle = HiiAddPackages (
1683 &gEfiCallerIdGuid,
1684 gDiskIoPrivateDataTemplate.Handle,
1685 DriverHealthDxeStrings,
1686 DriverHealthVfrBin,
1687 NULL
1688 );
1689 if (mHiiHandle == NULL) {
1690 return EFI_OUT_OF_RESOURCES;
1691 }
1692
1693 return EFI_SUCCESS;
1694 }
1695 /**
1696 This function processes the results of changes in configuration.
1697
1698 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1699 @param Action Specifies the type of action taken by the browser.
1700 @param QuestionId A unique value which is sent to the original
1701 exporting driver so that it can identify the type
1702 of data to expect.
1703 @param Type The type of value for the question.
1704 @param Value A pointer to the data being sent to the original
1705 exporting driver.
1706 @param ActionRequest On return, points to the action requested by the
1707 callback function.
1708
1709 @retval EFI_SUCCESS The callback successfully handled the action.
1710 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1711 variable and its data.
1712 @retval EFI_DEVICE_ERROR The variable could not be saved.
1713 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1714 callback.
1715
1716 **/
1717 EFI_STATUS
1718 EFIAPI
1719 DummyDriverCallback (
1720 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1721 IN EFI_BROWSER_ACTION Action,
1722 IN EFI_QUESTION_ID QuestionId,
1723 IN UINT8 Type,
1724 IN EFI_IFR_TYPE_VALUE *Value,
1725 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1726 )
1727 {
1728
1729 DISK_IO_NV_DATA *IfrNvData;
1730
1731 //
1732 // Retrieve uncommitted data from Browser
1733 //
1734
1735 IfrNvData = AllocateZeroPool (sizeof (DISK_IO_NV_DATA));
1736 ASSERT (IfrNvData != NULL);
1737
1738 if (!HiiGetBrowserData (&gEfiCallerIdGuid, VariableName, sizeof (DISK_IO_NV_DATA), (UINT8 *) IfrNvData)) {
1739 FreePool (IfrNvData);
1740 return EFI_NOT_FOUND;
1741 }
1742
1743 if ((Value == NULL) || (ActionRequest == NULL)) {
1744 return EFI_INVALID_PARAMETER;
1745 }
1746
1747 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
1748
1749
1750 return EFI_SUCCESS;
1751 }
1752
1753 /**
1754 This function allows a caller to extract the current configuration for one
1755 or more named elements from the target driver.
1756
1757 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1758 @param Request A null-terminated Unicode string in
1759 <ConfigRequest> format.
1760 @param Progress On return, points to a character in the Request
1761 string. Points to the string's null terminator if
1762 request was successful. Points to the most recent
1763 '&' before the first failing name/value pair (or
1764 the beginning of the string if the failure is in
1765 the first name/value pair) if the request was not
1766 successful.
1767 @param Results A null-terminated Unicode string in
1768 <ConfigAltResp> format which has all values filled
1769 in for the names in the Request string. String to
1770 be allocated by the called function.
1771
1772 @retval EFI_SUCCESS The Results is filled with the requested values.
1773 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
1774 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
1775 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1776 driver.
1777
1778 **/
1779 EFI_STATUS
1780 EFIAPI
1781 DummyExtractConfig (
1782 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1783 IN CONST EFI_STRING Request,
1784 OUT EFI_STRING *Progress,
1785 OUT EFI_STRING *Results
1786 )
1787 {
1788 EFI_STATUS Status;
1789 UINTN BufferSize;
1790 DISK_IO_PRIVATE_DATA *PrivateData;
1791 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1792 EFI_STRING ConfigRequest;
1793 EFI_STRING ConfigRequestHdr;
1794 UINTN Size;
1795
1796 if (Progress == NULL || Results == NULL || Request == NULL) {
1797 return EFI_INVALID_PARAMETER;
1798 }
1799 //
1800 // Initialize the local variables.
1801 //
1802 ConfigRequestHdr = NULL;
1803 ConfigRequest = NULL;
1804 Size = 0;
1805 *Progress = Request;
1806
1807 PrivateData = DISK_IO_PRIVATE_DATA_FROM_CONFIG_ACCESS(This);
1808 HiiConfigRouting = PrivateData->HiiConfigRouting;
1809
1810 //
1811 // Get Buffer Storage data from EFI variable.
1812 // Try to get the current setting from variable.
1813 //
1814 BufferSize = sizeof (DISK_IO_NV_DATA);
1815 Status = gRT->GetVariable (
1816 VariableName,
1817 &gEfiCallerIdGuid,
1818 NULL,
1819 &BufferSize,
1820 &PrivateData->NVdata
1821 );
1822 if (EFI_ERROR (Status)) {
1823 return EFI_NOT_FOUND;
1824 }
1825
1826 if (Request == NULL) {
1827 //
1828 // Request is set to NULL, construct full request string.
1829 //
1830
1831 //
1832 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1833 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1834 //
1835 ConfigRequestHdr = HiiConstructConfigHdr (&gEfiCallerIdGuid, VariableName, PrivateData->Handle);
1836 Size = (StrLen (ConfigRequest) + 32 + 1) * sizeof (CHAR16);
1837 ConfigRequest = AllocateZeroPool (Size);
1838 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
1839 FreePool (ConfigRequestHdr);
1840 } else {
1841 //
1842 // Check routing data in <ConfigHdr>.
1843 // Note: if only one Storage is used, then this checking could be skipped.
1844 //
1845 if (!HiiIsConfigHdrMatch (Request, &gEfiCallerIdGuid, VariableName)) {
1846 return EFI_NOT_FOUND;
1847 }
1848 ConfigRequest = Request;
1849 }
1850
1851 //
1852 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1853 //
1854 Status = HiiConfigRouting->BlockToConfig (
1855 HiiConfigRouting,
1856 ConfigRequest,
1857 (UINT8 *) &PrivateData->NVdata,
1858 BufferSize,
1859 Results,
1860 Progress
1861 );
1862
1863 if (Request == NULL) {
1864 FreePool (ConfigRequest);
1865 *Progress = NULL;
1866 }
1867
1868 return Status;
1869 }
1870
1871 /**
1872 This function processes the results of changes in configuration.
1873
1874 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1875 @param Configuration A null-terminated Unicode string in <ConfigResp>
1876 format.
1877 @param Progress A pointer to a string filled in with the offset of
1878 the most recent '&' before the first failing
1879 name/value pair (or the beginning of the string if
1880 the failure is in the first name/value pair) or
1881 the terminating NULL if all was successful.
1882
1883 @retval EFI_SUCCESS The Results is processed successfully.
1884 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1885 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1886 driver.
1887
1888 **/
1889 EFI_STATUS
1890 EFIAPI
1891 DummyRouteConfig (
1892 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1893 IN CONST EFI_STRING Configuration,
1894 OUT EFI_STRING *Progress
1895 )
1896 {
1897 EFI_STATUS Status;
1898 UINTN BufferSize;
1899 DISK_IO_PRIVATE_DATA *PrivateData;
1900 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1901
1902 if (Configuration == NULL || Progress == NULL) {
1903 return EFI_INVALID_PARAMETER;
1904 }
1905
1906
1907 PrivateData = DISK_IO_PRIVATE_DATA_FROM_CONFIG_ACCESS (This);
1908 HiiConfigRouting = PrivateData->HiiConfigRouting;
1909 *Progress = Configuration;
1910
1911 //
1912 // Check routing data in <ConfigHdr>.
1913 // Note: if only one Storage is used, then this checking could be skipped.
1914 //
1915 if (!HiiIsConfigHdrMatch (Configuration, &gEfiCallerIdGuid, VariableName)) {
1916 return EFI_NOT_FOUND;
1917 }
1918
1919 //
1920 // Get Buffer Storage data from EFI variable
1921 //
1922 BufferSize = sizeof (DISK_IO_NV_DATA);
1923 Status = gRT->GetVariable (
1924 VariableName,
1925 &gEfiCallerIdGuid,
1926 NULL,
1927 &BufferSize,
1928 &PrivateData->NVdata
1929 );
1930 if (EFI_ERROR (Status)) {
1931 return Status;
1932 }
1933
1934 //
1935 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1936 //
1937 BufferSize = sizeof (DISK_IO_NV_DATA);
1938 Status = HiiConfigRouting->ConfigToBlock (
1939 HiiConfigRouting,
1940 Configuration,
1941 (UINT8 *) &PrivateData->NVdata,
1942 &BufferSize,
1943 Progress
1944 );
1945 if (EFI_ERROR (Status)) {
1946 return Status;
1947 }
1948
1949 //
1950 // Store Buffer Storage back to EFI variable
1951 //
1952 Status = gRT->SetVariable(
1953 VariableName,
1954 &gEfiCallerIdGuid,
1955 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1956 sizeof (DISK_IO_NV_DATA),
1957 &PrivateData->NVdata
1958 );
1959
1960 return Status;
1961 }