1 /**@file
2 
3 Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 Module Name:
13 
14   DriverDiagnostics.c
15 
16 Abstract:
17 
18 **/
19 
20 #include "EmuBlockIo.h"
21 
22 //
23 // EFI Driver Diagnostics Functions
24 //
25 EFI_STATUS
26 EFIAPI
27 EmuBlockIoDriverDiagnosticsRunDiagnostics (
28   IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,
29   IN  EFI_HANDLE                                    ControllerHandle,
30   IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,
31   IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,
32   IN  CHAR8                                         *Language,
33   OUT EFI_GUID                                      **ErrorType,
34   OUT UINTN                                         *BufferSize,
35   OUT CHAR16                                        **Buffer
36   );
37 
38 //
39 // EFI Driver Diagnostics Protocol
40 //
41 EFI_DRIVER_DIAGNOSTICS_PROTOCOL gEmuBlockIoDriverDiagnostics = {
42   EmuBlockIoDriverDiagnosticsRunDiagnostics,
43   "eng"
44 };
45 
46 //
47 // EFI Driver Diagnostics 2 Protocol
48 //
49 GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gEmuBlockIoDriverDiagnostics2 = {
50   (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) EmuBlockIoDriverDiagnosticsRunDiagnostics,
51   "en"
52 };
53 
54 EFI_STATUS
55 EFIAPI
EmuBlockIoDriverDiagnosticsRunDiagnostics(IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_HANDLE ChildHandle OPTIONAL,IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,IN CHAR8 * Language,OUT EFI_GUID ** ErrorType,OUT UINTN * BufferSize,OUT CHAR16 ** Buffer)56 EmuBlockIoDriverDiagnosticsRunDiagnostics (
57   IN  EFI_DRIVER_DIAGNOSTICS_PROTOCOL               *This,
58   IN  EFI_HANDLE                                    ControllerHandle,
59   IN  EFI_HANDLE                                    ChildHandle  OPTIONAL,
60   IN  EFI_DRIVER_DIAGNOSTIC_TYPE                    DiagnosticType,
61   IN  CHAR8                                         *Language,
62   OUT EFI_GUID                                      **ErrorType,
63   OUT UINTN                                         *BufferSize,
64   OUT CHAR16                                        **Buffer
65   )
66 /*++
67 
68   Routine Description:
69     Runs diagnostics on a controller.
70 
71   Arguments:
72     This             - A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance.
73     ControllerHandle - The handle of the controller to run diagnostics on.
74     ChildHandle      - The handle of the child controller to run diagnostics on
75                        This is an optional parameter that may be NULL.  It will
76                        be NULL for device drivers.  It will also be NULL for a
77                        bus drivers that wish to run diagnostics on the bus
78                        controller.  It will not be NULL for a bus driver that
79                        wishes to run diagnostics on one of its child controllers.
80     DiagnosticType   - Indicates type of diagnostics to perform on the controller
81                        specified by ControllerHandle and ChildHandle.   See
82                        "Related Definitions" for the list of supported types.
83     Language         - A pointer to a three character ISO 639-2 language
84                        identifier or a Null-terminated ASCII string array indicating
85                        the language.  This is the language in which the optional
86                        error message should be returned in Buffer, and it must
87                        match one of the languages specified in SupportedLanguages.
88                        The number of languages supported by a driver is up to
89                        the driver writer.
90     ErrorType        - A GUID that defines the format of the data returned in
91                        Buffer.
92     BufferSize       - The size, in bytes, of the data returned in Buffer.
93     Buffer           - A buffer that contains a Null-terminated Unicode string
94                        plus some additional data whose format is defined by
95                        ErrorType.  Buffer is allocated by this function with
96                        AllocatePool(), and it is the caller's responsibility
97                        to free it with a call to FreePool().
98 
99   Returns:
100     EFI_SUCCESS           - The controller specified by ControllerHandle and
101                             ChildHandle passed the diagnostic.
102     EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
103     EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
104                             EFI_HANDLE.
105     EFI_INVALID_PARAMETER - Language is NULL.
106     EFI_INVALID_PARAMETER - ErrorType is NULL.
107     EFI_INVALID_PARAMETER - BufferType is NULL.
108     EFI_INVALID_PARAMETER - Buffer is NULL.
109     EFI_UNSUPPORTED       - The driver specified by This does not support
110                             running diagnostics for the controller specified
111                             by ControllerHandle and ChildHandle.
112     EFI_UNSUPPORTED       - The driver specified by This does not support the
113                             type of diagnostic specified by DiagnosticType.
114     EFI_UNSUPPORTED       - The driver specified by This does not support the
115                             language specified by Language.
116     EFI_OUT_OF_RESOURCES  - There are not enough resources available to complete
117                             the diagnostics.
118     EFI_OUT_OF_RESOURCES  - There are not enough resources available to return
119                             the status information in ErrorType, BufferSize,
120                             and Buffer.
121     EFI_DEVICE_ERROR      - The controller specified by ControllerHandle and
122                             ChildHandle did not pass the diagnostic.
123 
124 --*/
125 {
126   EFI_STATUS            Status;
127   EFI_BLOCK_IO_PROTOCOL *BlockIo;
128   CHAR8                 *SupportedLanguages;
129   BOOLEAN               Iso639Language;
130   BOOLEAN               Found;
131   UINTN                 Index;
132 
133   if (Language         == NULL ||
134       ErrorType        == NULL ||
135       Buffer           == NULL ||
136       ControllerHandle == NULL ||
137       BufferSize       == NULL) {
138 
139     return EFI_INVALID_PARAMETER;
140   }
141 
142   SupportedLanguages = This->SupportedLanguages;
143   Iso639Language = (BOOLEAN)(This == &gEmuBlockIoDriverDiagnostics);
144   //
145   // Make sure Language is in the set of Supported Languages
146   //
147   Found = FALSE;
148   while (*SupportedLanguages != 0) {
149     if (Iso639Language) {
150       if (CompareMem (Language, SupportedLanguages, 3) == 0) {
151         Found = TRUE;
152       break;
153     }
154       SupportedLanguages += 3;
155     } else {
156       for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);
157       if ((AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) && (Language[Index] == 0)) {
158         Found = TRUE;
159         break;
160   }
161       SupportedLanguages += Index;
162       for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);
163     }
164   }
165   //
166   // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED
167   //
168   if (!Found) {
169     return EFI_UNSUPPORTED;
170   }
171 
172   *ErrorType  = NULL;
173   *BufferSize = 0;
174   if (DiagnosticType != EfiDriverDiagnosticTypeStandard) {
175     *ErrorType  = &gEfiBlockIoProtocolGuid;
176     *BufferSize = 0x60;
177     Buffer = AllocatePool ((UINTN) (*BufferSize));
178     CopyMem (*Buffer, L"Windows Block I/O Driver Diagnostics Failed\n", *BufferSize);
179     return EFI_DEVICE_ERROR;
180   }
181 
182   //
183   // This is a device driver, so ChildHandle must be NULL.
184   //
185   if (ChildHandle != NULL) {
186     return EFI_UNSUPPORTED;
187   }
188 
189   //
190   // Validate controller handle
191   //
192   Status = gBS->OpenProtocol (
193                   ControllerHandle,
194                   &gEmuIoThunkProtocolGuid,
195                   (VOID **)&BlockIo,
196                   gEmuBlockIoDriverBinding.DriverBindingHandle,
197                   ControllerHandle,
198                   EFI_OPEN_PROTOCOL_BY_DRIVER
199                   );
200 
201   if (!EFI_ERROR (Status)) {
202     gBS->CloseProtocol (
203           ControllerHandle,
204           &gEmuIoThunkProtocolGuid,
205           gEmuBlockIoDriverBinding.DriverBindingHandle,
206           ControllerHandle
207           );
208 
209     return EFI_UNSUPPORTED;
210   }
211 
212   if (Status == EFI_UNSUPPORTED) {
213     return Status;
214   } else if (Status != EFI_ALREADY_STARTED) {
215     return EFI_INVALID_PARAMETER;
216   }
217 
218   return EFI_SUCCESS;
219 }
220