Indentation fix, cleanup.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / term / efi / serial.c
blobc0911ad7b8a9acc49bdf6736fd18e24f3236a35f
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2006,2007,2008,2012 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/disk.h>
20 #include <grub/partition.h>
21 #include <grub/mm.h>
22 #include <grub/types.h>
23 #include <grub/misc.h>
24 #include <grub/err.h>
25 #include <grub/term.h>
26 #include <grub/efi/api.h>
27 #include <grub/efi/efi.h>
28 #include <grub/efi/disk.h>
29 #include <grub/serial.h>
30 #include <grub/types.h>
31 #include <grub/i18n.h>
33 /* GUID. */
34 static grub_efi_guid_t serial_io_guid = GRUB_EFI_SERIAL_IO_GUID;
36 static void
37 do_real_config (struct grub_serial_port *port)
39 grub_efi_status_t status = GRUB_EFI_SUCCESS;
40 const grub_efi_parity_type_t parities[] = {
41 [GRUB_SERIAL_PARITY_NONE] = GRUB_EFI_SERIAL_NO_PARITY,
42 [GRUB_SERIAL_PARITY_ODD] = GRUB_EFI_SERIAL_ODD_PARITY,
43 [GRUB_SERIAL_PARITY_EVEN] = GRUB_EFI_SERIAL_EVEN_PARITY
45 const grub_efi_stop_bits_t stop_bits[] = {
46 [GRUB_SERIAL_STOP_BITS_1] = GRUB_EFI_SERIAL_1_STOP_BIT,
47 [GRUB_SERIAL_STOP_BITS_1_5] = GRUB_EFI_SERIAL_1_5_STOP_BITS,
48 [GRUB_SERIAL_STOP_BITS_2] = GRUB_EFI_SERIAL_2_STOP_BITS,
51 if (port->configured)
52 return;
54 status = efi_call_7 (port->interface->set_attributes, port->interface,
55 port->config.speed,
56 0, 0, parities[port->config.parity],
57 port->config.word_len,
58 stop_bits[port->config.stop_bits]);
59 if (status != GRUB_EFI_SUCCESS)
60 port->broken = 1;
62 status = efi_call_2 (port->interface->set_control_bits, port->interface,
63 port->config.rtscts ? 0x4002 : 0x2);
65 port->configured = 1;
68 /* Fetch a key. */
69 static int
70 serial_hw_fetch (struct grub_serial_port *port)
72 grub_efi_uintn_t bufsize = 1;
73 char c;
74 grub_efi_status_t status = GRUB_EFI_SUCCESS;
75 do_real_config (port);
76 if (port->broken)
77 return -1;
79 status = efi_call_3 (port->interface->read, port->interface, &bufsize, &c);
80 if (status != GRUB_EFI_SUCCESS || bufsize == 0)
81 return -1;
83 return c;
86 /* Put a character. */
87 static void
88 serial_hw_put (struct grub_serial_port *port, const int c)
90 grub_efi_uintn_t bufsize = 1;
91 char c0 = c;
93 do_real_config (port);
95 if (port->broken)
96 return;
98 efi_call_3 (port->interface->write, port->interface, &bufsize, &c0);
101 /* Initialize a serial device. PORT is the port number for a serial device.
102 SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
103 19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
104 for the device. Likewise, PARITY is the type of the parity and
105 STOP_BIT_LEN is the length of the stop bit. The possible values for
106 WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
107 macros. */
108 static grub_err_t
109 serial_hw_configure (struct grub_serial_port *port,
110 struct grub_serial_config *config)
112 if (config->parity != GRUB_SERIAL_PARITY_NONE
113 && config->parity != GRUB_SERIAL_PARITY_ODD
114 && config->parity != GRUB_SERIAL_PARITY_EVEN)
115 return grub_error (GRUB_ERR_BAD_ARGUMENT,
116 N_("unsupported serial port parity"));
118 if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1
119 && config->stop_bits != GRUB_SERIAL_STOP_BITS_1_5
120 && config->stop_bits != GRUB_SERIAL_STOP_BITS_2)
121 return grub_error (GRUB_ERR_BAD_ARGUMENT,
122 N_("unsupported serial port stop bits number"));
124 if (config->word_len < 5 || config->word_len > 8)
125 return grub_error (GRUB_ERR_BAD_ARGUMENT,
126 N_("unsupported serial port word length"));
128 port->config = *config;
129 port->configured = 0;
131 /* FIXME: should check if the serial terminal was found. */
133 return GRUB_ERR_NONE;
136 struct grub_serial_driver grub_efiserial_driver =
138 .configure = serial_hw_configure,
139 .fetch = serial_hw_fetch,
140 .put = serial_hw_put
143 void
144 grub_efiserial_init (void)
146 grub_efi_uintn_t num_handles;
147 grub_efi_handle_t *handles;
148 grub_efi_handle_t *handle;
149 int num_serial = 0;
150 grub_err_t err;
152 /* Find handles which support the disk io interface. */
153 handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &serial_io_guid,
154 0, &num_handles);
155 if (! handles)
156 return;
158 /* Make a linked list of devices. */
159 for (handle = handles; num_handles--; handle++)
161 struct grub_serial_port *port;
162 struct grub_efi_serial_io_interface *sio;
164 sio = grub_efi_open_protocol (*handle, &serial_io_guid,
165 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
166 if (! sio)
167 /* This should not happen... Why? */
168 continue;
170 port = grub_zalloc (sizeof (*port));
171 if (!port)
172 return;
174 port->name = grub_malloc (sizeof ("efiXXXXXXXXXXXXXXXXXXXX"));
175 if (!port->name)
176 return;
177 grub_snprintf (port->name, sizeof ("efiXXXXXXXXXXXXXXXXXXXX"),
178 "efi%d", num_serial++);
180 port->driver = &grub_efiserial_driver;
181 port->interface = sio;
182 err = grub_serial_config_defaults (port);
183 if (err)
184 grub_print_error ();
186 grub_serial_register (port);
189 grub_free (handles);
191 return;