Home | History | Annotate | Download | only in Utility
      1 /** @file
      2     Device Abstraction: Search device list for a matching device.
      3 
      4     Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
      5     This program and the accompanying materials are licensed and made available under
      6     the terms and conditions of the BSD License that accompanies this distribution.
      7     The full text of the license may be found at
      8     http://opensource.org/licenses/bsd-license.php.
      9 
     10     THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11     WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 **/
     13 #include  <Uefi.h>
     14 #include  <Library/BaseLib.h>
     15 #include  <Library/BaseMemoryLib.h>
     16 
     17 #include  <LibConfig.h>
     18 
     19 #include  <errno.h>
     20 #include  <kfile.h>
     21 #include  <Device/Device.h>
     22 #include  <MainData.h>
     23 
     24 /** Find a DeviceNode matching DevName or DevProto, or both.
     25 
     26     If DevName is NULL, then the device name is not used in the search.
     27     If DevProto is NULL, then the protocol GUID is not used in the search.
     28     If both are NULL, then INVALID_PARAMETER is returned.
     29     If both DevName and DevProto are specified, then both must match.
     30     If both are specified but only one matches, then DEVICE_ERROR is returned.
     31 
     32     @param  DevName     Name of the Device Abstraction to find.
     33     @param  DevProto    GUID of the Protocol associated with the Device Abstraction.
     34     @param  Node        Pointer to the pointer to receive the found Device Node's address.
     35 
     36     @retval RETURN_SUCCESS              The desired Device Node was found.
     37     @retval RETURN_INVALID_PARAMETER    Both DevName and DevProto are NULL or Node is NULL.
     38     @retval RETURN_DEVICE_ERROR         DevName matched but DevProto did not.
     39     @retval RETURN_NOT_FOUND            The desired device was not found.
     40 **/
     41 EFI_STATUS
     42 EFIAPI
     43 __DevSearch(
     44   IN     CHAR16        *DevName,
     45   IN     GUID          *DevProto,
     46      OUT DeviceNode   **Node
     47   )
     48 {
     49   RETURN_STATUS     Status = RETURN_NOT_FOUND;
     50   DeviceNode       *WorkNode;
     51   INT32             DevMatched;
     52 
     53   if(((DevName == NULL) && (DevProto == NULL)) || (Node == NULL)) {
     54     Status = RETURN_INVALID_PARAMETER;
     55   }
     56   else {
     57     if(IsListEmpty((LIST_ENTRY *)&daDeviceList)) {
     58       Status = RETURN_NOT_FOUND;
     59     }
     60     else {
     61       /* Traverse the list of Device Nodes hunting for a match */
     62       WorkNode = (DeviceNode *)GetFirstNode((LIST_ENTRY *)&daDeviceList);
     63       do {
     64         /* Use DevMatched to keep track of the three match conditions. */
     65         DevMatched = 0;
     66         if(DevName != NULL) {
     67           ++DevMatched;
     68           if(wcsncmp(DevName, WorkNode->DevName, wcslen(WorkNode->DevName)) == 0) {
     69             ++DevMatched;
     70           }
     71         }
     72         /* At this point, DevMatched has one of the following values:
     73               0   DevName == NULL, no name comparison
     74               1   DevName did not match WorkNode's name
     75               2   DevName MATCHED
     76         */
     77         if((DevMatched != 1) && (DevProto != NULL) && (WorkNode->DevProto != NULL)) {
     78           /*  Only bother with the GUID comparison if:
     79                 * There was NOT a name mismatch
     80                 * DevProto is NOT NULL -- there is a GUID to compare
     81                 * WorkNode->DevProto is NOT NULL
     82           */
     83           if(CompareGuid(DevProto, WorkNode->DevProto)) {
     84             // GUIDs matched, we found it
     85             Status = RETURN_SUCCESS;
     86             *Node = WorkNode;
     87             break;
     88           }
     89           else {
     90             // GUIDs did not match
     91             if(DevMatched == 2) {
     92               // Name matched, GUID did not!
     93               Status = RETURN_DEVICE_ERROR;
     94               break;    // Don't try any more, we have an internal problem
     95             }
     96           }
     97         }
     98         else {
     99           if(DevMatched == 2) {
    100             // Device Name matched, GUIDs skipped
    101             Status = RETURN_SUCCESS;
    102             *Node = WorkNode;
    103             break;
    104           }
    105         }
    106         // Check the next device in the list
    107         WorkNode = (DeviceNode *)GetNextNode(&daDeviceList, (LIST_ENTRY *)WorkNode);
    108       } while(&daDeviceList != (LIST_ENTRY *)WorkNode);
    109     }
    110   }
    111   return Status;
    112 }
    113