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