1 /** @file
2     Device Abstraction: device creation utility functions.
3 
4     Copyright (c) 2011 - 2012, 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/MemoryAllocationLib.h>
16 
17 #include  <LibConfig.h>
18 
19 #include  <errno.h>
20 #include  <stdarg.h>
21 #include  <sys/poll.h>
22 #include  <kfile.h>
23 #include  <Device/Device.h>
24 #include  <MainData.h>
25 
26 LIST_ENTRY    daDeviceList    = INITIALIZE_LIST_HEAD_VARIABLE(daDeviceList);
27 DeviceNode   *daDefaultDevice = NULL;     ///< Device to use if nothing else found
28 DeviceNode   *daRootDevice    = NULL;     ///< Device containing the root file system
29 DeviceNode   *daCurrentDevice = NULL;     ///< Device currently being accessed
30 
31 /* Commonly used fileops
32       fnullop_*   Does nothing and returns success.
33       fbadop_*    Does nothing and returns EPERM
34 */
fnullop_fcntl(struct __filedes * filp,UINT32 Cmd,void * p3,void * p4)35 int     EFIAPI fnullop_fcntl (struct __filedes *filp, UINT32 Cmd, void *p3, void *p4)
36 { return 0; }
37 
fnullop_poll(struct __filedes * filp,short Events)38 short  EFIAPI fnullop_poll  (struct __filedes *filp, short Events)
39 {
40   return ((POLLIN | POLLRDNORM | POLLOUT) & Events);
41 }
42 
fnullop_flush(struct __filedes * filp)43 int     EFIAPI fnullop_flush (struct __filedes *filp)
44 { return 0; }
45 
fbadop_stat(struct __filedes * filp,struct stat * StatBuf,void * Buf)46 int     EFIAPI fbadop_stat   (struct __filedes *filp, struct stat *StatBuf, void *Buf)
47 {
48   errno = EPERM;
49   return -1;
50 }
51 
fbadop_ioctl(struct __filedes * filp,ULONGN Cmd,va_list argp)52 int     EFIAPI fbadop_ioctl  (struct __filedes *filp, ULONGN Cmd, va_list argp)
53 {
54   errno = EPERM;
55   return -1;
56 }
57 
fbadop_delete(struct __filedes * filp)58 int     EFIAPI fbadop_delete (struct __filedes *filp)
59 {
60   errno = EPERM;
61   return -1;
62 }
63 
fbadop_mkdir(const char * path,__mode_t perms)64 int     EFIAPI fbadop_mkdir  (const char *path, __mode_t perms)
65 {
66   errno = EPERM;
67   return -1;
68 }
69 
fbadop_rename(const char * from,const char * to)70 int     EFIAPI fbadop_rename   (const char *from, const char *to)
71 {
72   errno = EPERM;
73   return -1;
74 }
75 
fbadop_rmdir(struct __filedes * filp)76 int     EFIAPI fbadop_rmdir    (struct __filedes *filp)
77 {
78   errno = EPERM;
79   return -1;
80 }
81 
82 /** Add a new device to the device list.
83     If both DevName and DevProto are NULL, register this as the Default device.
84 
85     @param  DevName       Name of the device to add.
86     @param  DevProto      Pointer to the GUID identifying the protocol associated with this device.
87                           If DevProto is NULL, startup code will not try to find instances
88                           of this device.
89     @param  OpenFunc      Pointer to the device's Open function.
90     @param  InstanceList  Optional pointer to the device's initialized instance list.
91                           If InstanceList is NULL, the application startup code will
92                           scan for instances of the protocol identified by DevProto and
93                           populate the InstanceList in the order those protocols are found.
94     @param  NumInstance   Number of instances in InstanceList.
95     @param  Modes         Bit-mapped flags indicating operations (R, W, RW, ...) permitted to this device.
96 
97 **/
98 DeviceNode *
99 EFIAPI
__DevRegister(IN const CHAR16 * DevName,IN GUID * DevProto,IN FO_OPEN OpenFunc,IN void * InstanceList,IN int NumInstance,IN UINT32 InstanceSize,IN UINT32 Modes)100 __DevRegister(
101   IN const CHAR16          *DevName,
102   IN GUID                  *DevProto,
103   IN FO_OPEN                OpenFunc,
104   IN void                  *InstanceList,
105   IN int                    NumInstance,
106   IN UINT32                 InstanceSize,
107   IN UINT32                 Modes
108   )
109 {
110   DeviceNode         *Node;
111   GenericInstance    *GIp;
112   char               *GenPtr;
113   int                 i;
114 
115   /* Validate parameters */
116   if(((DevName == NULL) && (DevProto != NULL)) ||
117       (OpenFunc == NULL)) {
118     EFIerrno = RETURN_INVALID_PARAMETER;
119     return NULL;
120   }
121   Node = (DeviceNode *)AllocateZeroPool(sizeof(DeviceNode));
122   if(Node == NULL) {
123     EFIerrno = RETURN_OUT_OF_RESOURCES;
124     return NULL;
125   }
126 
127   Node->DevName       = DevName;
128   Node->DevProto      = DevProto;
129   Node->InstanceList  = InstanceList;
130   Node->OpenFunc      = OpenFunc;
131   Node->InstanceSize  = InstanceSize;
132   Node->NumInstances  = NumInstance;
133   Node->OpModes       = Modes;
134 
135   /* Update the Parent member of each element of the InstanceList */
136   if(InstanceList != NULL) {
137     GenPtr = InstanceList;
138 
139     for(i = 0; i < NumInstance; ++i) {    // Iterate through each element of InstanceList
140       GIp = (GenericInstance *)GenPtr;
141       GIp->Parent = Node;                     // Initializing the Parent member & InstanceNum
142       //GIp->InstanceNum = i;
143       GenPtr += InstanceSize;
144     }
145   }
146   if(DevName == NULL) {
147     if(daDefaultDevice != NULL) {
148       EFIerrno = RETURN_INVALID_PARAMETER;
149       return NULL;
150     }
151     daDefaultDevice = Node;
152   }
153   else {
154     (void) InsertTailList(&daDeviceList, &Node->DevList);
155   }
156   EFIerrno = RETURN_SUCCESS;
157   return Node;
158 }
159