OSDN Git Service

dp-*: fix some wrong size_t vs ssize_t usage.
[android-x86/external-efivar.git] / src / dp-acpi.c
1 /*
2  * libefivar - library for the manipulation of EFI variables
3  * Copyright 2012-2015 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2.1 of the
8  * License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include <errno.h>
22 #include <inttypes.h>
23 #include <stddef.h>
24
25 #include <efivar.h>
26 #include "dp.h"
27
28 static ssize_t
29 _format_acpi_adr(char *buf, size_t size, const_efidp dp)
30 {
31         ssize_t o = 0;
32         o += format(buf, size, o, "AcpiAdr(");
33         o += format_array(buf, size, o, "0x%"PRIx32,
34                           typeof(dp->acpi_adr.adr[0]),
35                           dp->acpi_adr.adr,
36                           (efidp_node_size(dp)-4)/sizeof (dp->acpi_adr.adr[0]));
37         o += format(buf, size, o, ")");
38         return o;
39 }
40 #define format_acpi_adr(buf, size, off, dp) \
41         _format_acpi_adr(((buf)+(off)), ((size)?((size)-(off)):0), (dp))
42
43
44 ssize_t
45 _format_acpi_dn(char *buf, size_t size, const_efidp dp)
46 {
47         ssize_t off = 0;
48         const char *hidstr = NULL;
49         size_t hidlen = 0;
50         const char *uidstr = NULL;
51         size_t uidlen = 0;
52         const char *cidstr = NULL;
53         size_t cidlen = 0;
54
55         if (dp->subtype == EFIDP_ACPI_ADR)
56                 return format_acpi_adr(buf, size, off, dp);
57
58         if (dp->subtype != EFIDP_ACPI_HID_EX && dp->subtype != EFIDP_ACPI_HID) {
59                 off += format(buf, size, off, "AcpiPath(%d,", dp->subtype);
60                 off += format_hex(buf, size, off, (uint8_t *)dp+4,
61                                   (efidp_node_size(dp)-4) / 2);
62                 off += format(buf, size, off, ")");
63                 return off;
64         }
65
66         if (dp->subtype == EFIDP_ACPI_HID_EX) {
67                 ssize_t limit = efidp_node_size(dp)
68                                 - offsetof(efidp_acpi_hid_ex, hidstr);
69
70                 hidstr = dp->acpi_hid_ex.hidstr;
71                 hidlen = strnlen(hidstr, limit);
72                 limit -= hidlen + 1;
73
74                 uidstr = hidstr + hidlen + 1;
75                 uidlen = strnlen(uidstr, limit);
76                 limit -= uidlen + 1;
77
78                 cidstr = uidstr + uidlen + 1;
79                 cidlen = strnlen(cidstr, limit);
80                 limit -= cidlen + 1;
81
82                 if (uidstr) {
83                         switch (dp->acpi_hid.hid) {
84                         case EFIDP_ACPI_PCI_ROOT_HID:
85                                 off += format(buf, size, off, "PciRoot(%s)",
86                                               uidstr);
87                                 return off;
88                         case EFIDP_ACPI_PCIE_ROOT_HID:
89                                 off += format(buf, size, off, "PcieRoot(%s)",
90                                               uidstr);
91                                 return off;
92                         }
93                 }
94         }
95
96         switch (dp->acpi_hid.hid) {
97         case EFIDP_ACPI_PCI_ROOT_HID:
98                 off += format(buf, size, off, "PciRoot(0x%"PRIx32")",
99                               dp->acpi_hid.uid);
100                 return off;
101         case EFIDP_ACPI_PCIE_ROOT_HID:
102                 off += format(buf, size, off, "PcieRoot(0x%"PRIx32")",
103                               dp->acpi_hid.uid);
104                 return off;
105         case EFIDP_ACPI_FLOPPY_HID:
106                 off += format(buf, size, off, "Floppy(0x%"PRIx32")",
107                               dp->acpi_hid.uid);
108                 return off;
109         case EFIDP_ACPI_KEYBOARD_HID:
110                 off += format(buf, size, off, "Keyboard(0x%"PRIx32")",
111                               dp->acpi_hid.uid);
112                 return off;
113         case EFIDP_ACPI_SERIAL_HID:
114                 off += format(buf, size, off, "Serial(0x%"PRIx32")",
115                               dp->acpi_hid.uid);
116                 return off;
117         default:
118                 switch (dp->subtype) {
119                 case EFIDP_ACPI_HID_EX:
120                         if (!hidstr && !cidstr &&
121                                         (uidstr || dp->acpi_hid_ex.uid)){
122                                 off += format(buf, size, off,
123                                               "AcpiExp(0x%"PRIx32",0x%"PRIx32",",
124                                               dp->acpi_hid_ex.hid,
125                                               dp->acpi_hid_ex.cid);
126                                 if (uidstr)
127                                         off += format(buf, size, off, "%s)",
128                                                       uidstr);
129                                 else
130                                         off += format(buf, size, off,
131                                                       "0x%"PRIx32")",
132                                                       dp->acpi_hid.uid);
133                                 return off;
134                         }
135                         off += format(buf, size, off, "AcpiEx(");
136                         if (hidstr)
137                                 off += format(buf, size, off, "%s,", hidstr);
138                         else
139                                 off += format(buf, size, off, "0x%"PRIx32",",
140                                               dp->acpi_hid.hid);
141                         if (cidstr)
142                                 off += format(buf, size, off, "%s,", cidstr);
143                         else
144                                 off += format(buf, size, off, "0x%"PRIx32",",
145                                               dp->acpi_hid_ex.cid);
146
147                         if (uidstr)
148                                 off += format(buf, size, off, "%s)", uidstr);
149                         else
150                                 off += format(buf, size, off, "0x%"PRIx32")",
151                                               dp->acpi_hid.uid);
152                         return off;
153                 case EFIDP_ACPI_HID:
154                         off += format(buf, size, off,
155                                       "Acpi(0x%"PRIx32",0x%"PRIx32")",
156                                       dp->acpi_hid.hid, dp->acpi_hid.uid);
157                         return off;
158                 }
159         }
160
161         return off;
162 }
163
164 ssize_t
165 __attribute__((__visibility__ ("default")))
166 efidp_make_acpi_hid(uint8_t *buf, ssize_t size, uint32_t hid, uint32_t uid)
167 {
168         efidp_acpi_hid *acpi_hid = (efidp_acpi_hid *)buf;
169         ssize_t req = sizeof (*acpi_hid);
170         ssize_t sz;
171
172         sz = efidp_make_generic(buf, size, EFIDP_ACPI_TYPE, EFIDP_ACPI_HID,
173                                 sizeof (*acpi_hid));
174         if (size && sz == req) {
175                 acpi_hid->uid = uid;
176                 acpi_hid->hid = hid;
177         }
178
179         return sz;
180 }
181
182 ssize_t
183 __attribute__((__visibility__ ("default")))
184 __attribute__((__nonnull__ (6,7,8)))
185 efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size,
186                        uint32_t hid, uint32_t uid, uint32_t cid,
187                        char *hidstr, char *uidstr, char *cidstr)
188 {
189         efidp_acpi_hid_ex *acpi_hid = (efidp_acpi_hid_ex *)buf;
190         ssize_t req;
191         ssize_t sz;
192
193         req = sizeof (*acpi_hid) + 3 +
194                 strlen(hidstr) + strlen(uidstr) + strlen(cidstr);
195         sz = efidp_make_generic(buf, size, EFIDP_ACPI_TYPE, EFIDP_ACPI_HID_EX,
196                                 req);
197         if (size && sz == req) {
198                 acpi_hid->uid = uid;
199                 acpi_hid->hid = hid;
200                 acpi_hid->cid = cid;
201                 char *next = (char *)buf+offsetof(efidp_acpi_hid_ex, hidstr);
202                 strcpy(next, hidstr);
203                 next += strlen(hidstr) + 1;
204                 strcpy(next, uidstr);
205                 next += strlen(uidstr) + 1;
206                 strcpy(next, cidstr);
207         }
208
209         return sz;
210 }