1 /** @file
2     "Terminal" Control functions for Interactive IO.
3 
4     Copyright (c) 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.
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/BaseMemoryLib.h>
15 
16 #include  <LibConfig.h>
17 
18 #include  <errno.h>
19 #include  <sys/termios.h>
20 #include  <Device/IIO.h>
21 #include  <MainData.h>
22 
23 /** Get input baud rate.
24 
25     Extracts the input baud rate from the termios structure pointed to by the
26     pTermios argument.
27 
28     @param[in]  pTermios  A pointer to the termios structure from which to extract
29                           the input baud rate.
30 
31     @return The value of the input speed is returned exactly as it is contained
32             in the termios structure, without interpretation.
33 **/
34 speed_t
cfgetispeed(const struct termios * pTermios)35 cfgetispeed (
36   const struct termios *pTermios
37   )
38 {
39   return pTermios->c_ispeed;
40 }
41 
42 /** Get output baud rate.
43 
44     Extracts the output baud rate from the termios structure pointed to by the
45     pTermios argument.
46 
47     @param[in]  pTermios  A pointer to the termios structure from which to extract
48                           the output baud rate.
49 
50     @return The value of the output speed is returned exactly as it is contained
51             in the termios structure, without interpretation.
52 **/
53 speed_t
cfgetospeed(const struct termios * pTermios)54 cfgetospeed (
55   const struct termios *pTermios
56   )
57 {
58   return pTermios->c_ospeed;
59 }
60 
61 /** Set input baud rate.
62 
63     Replaces the input baud rate, in the termios structure pointed to by the
64     pTermios argument, with the value of NewSpeed.
65 
66     @param[out]   pTermios  A pointer to the termios structure into which to set
67                             the input baud rate.
68     @param[in]    NewSpeed  The new input baud rate.
69 
70     @retval 0     The operation completed successfully.
71     @retval -1    An error occured and errno is set to indicate the error.
72                     * EINVAL - The value of NewSpeed is outside the range of
73                       possible speed values as specified in <sys/termios.h>.
74 **/
75 int
cfsetispeed(struct termios * pTermios,speed_t NewSpeed)76 cfsetispeed (
77   struct termios *pTermios,
78   speed_t         NewSpeed
79   )
80 {
81   int RetVal;
82 
83   if(NewSpeed < B921600) {
84     pTermios->c_ispeed = NewSpeed;
85     RetVal = 0;
86   }
87   else {
88     RetVal = -1;
89     errno = EINVAL;
90   }
91   return RetVal;
92 }
93 
94 /** Set output baud rate.
95 
96     Replaces the output baud rate, in the termios structure pointed to by the
97     pTermios argument, with the value of NewSpeed.
98 
99     @param[out]   pTermios  A pointer to the termios structure into which to set
100                             the output baud rate.
101     @param[in]    NewSpeed  The new output baud rate.
102 
103     @retval 0     The operation completed successfully.
104     @retval -1    An error occured and errno is set to indicate the error.
105                     * EINVAL - The value of NewSpeed is outside the range of
106                       possible speed values as specified in <sys/termios.h>.
107 **/
108 int
cfsetospeed(struct termios * pTermios,speed_t NewSpeed)109 cfsetospeed (
110   struct termios *pTermios,
111   speed_t         NewSpeed
112   )
113 {
114   int RetVal;
115 
116   if(NewSpeed < B921600) {
117     pTermios->c_ospeed = NewSpeed;
118     RetVal = 0;
119   }
120   else {
121     RetVal = -1;
122     errno = EINVAL;
123   }
124   return RetVal;
125 }
126 
127 /** Get the parameters associated with an interactive IO device.
128 
129     Get the parameters associated with the device referred to by
130     fd and store them into the termios structure referenced by pTermios.
131 
132     @param[in]    fd        The file descriptor for an open interactive IO device.
133     @param[out]   pTermios  A pointer to a termios structure into which to store
134                             attributes of the interactive IO device.
135 
136     @retval 0     The operation completed successfully.
137     @retval -1    An error occured and errno is set to indicate the error.
138                     * EBADF - The fd argument is not a valid file descriptor.
139                     * ENOTTY - The file associated with fd is not an interactive IO device.
140 **/
141 int
tcgetattr(int fd,struct termios * pTermios)142 tcgetattr (
143   int             fd,
144   struct termios *pTermios
145   )
146 {
147   cIIO             *IIO;
148   int               RetVal;
149   struct __filedes *filp;
150   struct termios   *Termio;
151 
152   RetVal = 0;
153   if(ValidateFD( fd, VALID_OPEN)) {
154     filp = &gMD->fdarray[fd];
155 
156     if((filp->f_iflags & _S_ITTY) != 0) {
157       // fd is for a TTY or "Interactive IO" device
158       IIO = (cIIO *)filp->devdata;
159       Termio = &IIO->Termio;
160       (void)CopyMem((void *)pTermios, (const void *)Termio, sizeof(struct termios));
161     }
162     else {
163       errno   = ENOTTY;
164       RetVal  = -1;
165     }
166   }
167   else {
168     errno   = EBADF;
169     RetVal  = -1;
170   }
171   return RetVal;
172 }
173 
174 /** Set the parameters associated with an interactive IO device.
175 
176     Set the parameters associated with the device referred to by
177     fd to the values in the termios structure referenced by pTermios.
178 
179     Behavior is modified by the value of the OptAct parameter:
180       * TCSANOW: The change shall occur immediately.
181       * TCSADRAIN: The change shall occur after all output written to fd is
182         transmitted. This action should be used when changing parameters which
183         affect output.
184       * TCSAFLUSH: The change shall occur after all output written to fd is
185         transmitted, and all input so far received but not read shall be
186         discarded before the change is made.
187 
188     @param[in]  fd        The file descriptor for an open interactive IO device.
189     @param[in]  OptAct    Currently has no effect.
190     @param[in]  pTermios  A pointer to a termios structure into which to retrieve
191                           attributes to set in the interactive IO device.
192 
193     @retval 0     The operation completed successfully.
194     @retval -1    An error occured and errno is set to indicate the error.
195                     * EBADF - The fd argument is not a valid file descriptor.
196                     * ENOTTY - The file associated with fd is not an interactive IO device.
197 **/
198 int
tcsetattr(int fd,int OptAct,const struct termios * pTermios)199 tcsetattr (
200   int                   fd,
201   int                   OptAct,   // Currently ignored
202   const struct termios *pTermios
203   )
204 {
205   cIIO             *IIO;
206   int               RetVal;
207   struct __filedes *filp;
208   struct termios   *Termio;
209 
210   RetVal = 0;
211   if(ValidateFD( fd, VALID_OPEN)) {
212     filp = &gMD->fdarray[fd];
213 
214     if((filp->f_iflags & _S_ITTY) != 0) {
215       // fd is for a TTY or "Interactive IO" device
216       IIO = (cIIO *)filp->devdata;
217       Termio = &IIO->Termio;
218       (void)CopyMem((void *)Termio, (const void *)pTermios, sizeof(struct termios));
219     }
220     else {
221       errno   = ENOTTY;
222       RetVal  = -1;
223     }
224   }
225   else {
226     errno   = EBADF;
227     RetVal  = -1;
228   }
229   return RetVal;
230 }
231 
232 /** Transmit pending output.
233 
234     Function is not yet implemented for UEFI.
235 
236     @param[in]  fd        Ignored
237 
238     @retval -1    This function is not yet supported.  errno is set to ENOTSUP.
239 **/
240 int
tcdrain(int fd)241 tcdrain (int fd)
242 {
243   errno = ENOTSUP;
244   return -1;
245 }
246 
247 /** Suspend or restart the transmission or reception of data.
248 
249     This function will suspend or resume transmission or reception of data on
250     the file referred to by fd, depending on the value of Action.
251 
252     Function is not yet implemented for UEFI.
253 
254     @param[in]  fd        Ignored
255     @param[in]  Action    Ignored
256 
257     @retval -1    This function is not yet supported.  errno is set to ENOTSUP.
258 **/
259 int
tcflow(int fd,int Action)260 tcflow (
261   int fd,
262   int Action)
263 {
264   errno = ENOTSUP;
265   return -1;
266 }
267 
268 /** Discard non-transmitted output data, non-read input data, or both.
269 
270     Function is not yet implemented for UEFI.
271 
272     @param[in]  fd              Ignored
273     @param[in]  QueueSelector   Ignored
274 
275     @retval -1    This function is not yet supported.  errno is set to ENOTSUP.
276 **/
277 int
tcflush(int fd,int QueueSelector)278 tcflush (
279   int fd,
280   int QueueSelector)
281 {
282   errno = ENOTSUP;
283   return -1;
284 }
285 
286