blob: 4014b89e87d19a2370ce83cb8e369bbb8e5e1a98 [file] [log] [blame]
Jeremy Kerr3d36ee22019-05-30 11:15:37 +08001/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
Jeremy Kerr672c8852019-03-01 12:18:07 +08002
Andrew Jeffery3286f172020-03-17 23:04:13 +10303#if HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7#if HAVE_ENDIAN_H
Jeremy Kerr92a10a62019-08-28 16:55:54 +05308#include <endian.h>
Andrew Jeffery3286f172020-03-17 23:04:13 +10309#endif
10
11#include <assert.h>
Andrew Jeffery59c6a5c2020-01-17 15:52:51 +103012#include <err.h>
Andrew Jefferyedfe3832020-02-06 11:52:11 +103013#include <inttypes.h>
Jeremy Kerr672c8852019-03-01 12:18:07 +080014#include <stdbool.h>
15#include <stdlib.h>
16#include <string.h>
Jeremy Kerr672c8852019-03-01 12:18:07 +080017
Jeremy Kerr672c8852019-03-01 12:18:07 +080018#define pr_fmt(x) "astlpc: " x
19
20#include "libmctp.h"
21#include "libmctp-alloc.h"
22#include "libmctp-log.h"
23#include "libmctp-astlpc.h"
Przemyslaw Czarnowskiff25d7e2020-03-26 11:39:37 +010024#include "container_of.h"
Jeremy Kerr672c8852019-03-01 12:18:07 +080025
Jeremy Kerrb214c642019-11-27 11:34:00 +080026#ifdef MCTP_HAVE_FILEIO
Jeremy Kerr92a10a62019-08-28 16:55:54 +053027
Jeremy Kerrc6f676d2019-12-19 09:24:06 +080028#include <unistd.h>
Jeremy Kerr92a10a62019-08-28 16:55:54 +053029#include <fcntl.h>
30#include <sys/ioctl.h>
31#include <sys/mman.h>
32#include <linux/aspeed-lpc-ctrl.h>
33
34/* kernel interface */
35static const char *kcs_path = "/dev/mctp0";
36static const char *lpc_path = "/dev/aspeed-lpc-ctrl";
37
38#endif
39
Jeremy Kerr672c8852019-03-01 12:18:07 +080040struct mctp_binding_astlpc {
41 struct mctp_binding binding;
Jeremy Kerrbc53d352019-08-28 14:26:14 +053042
Jeremy Kerr672c8852019-03-01 12:18:07 +080043 union {
44 void *lpc_map;
45 struct mctp_lpcmap_hdr *lpc_hdr;
46 };
Jeremy Kerrbc53d352019-08-28 14:26:14 +053047
48 /* direct ops data */
49 struct mctp_binding_astlpc_ops ops;
50 void *ops_data;
51 struct mctp_lpcmap_hdr *priv_hdr;
52
53 /* fileio ops data */
54 void *lpc_map_base;
Jeremy Kerr672c8852019-03-01 12:18:07 +080055 int kcs_fd;
56 uint8_t kcs_status;
57
58 bool running;
Jeremy Kerr672c8852019-03-01 12:18:07 +080059};
60
Jeremy Kerr672c8852019-03-01 12:18:07 +080061#define binding_to_astlpc(b) \
62 container_of(b, struct mctp_binding_astlpc, binding)
63
64#define MCTP_MAGIC 0x4d435450
65#define BMC_VER_MIN 1
66#define BMC_VER_CUR 1
67
68struct mctp_lpcmap_hdr {
69 uint32_t magic;
70
71 uint16_t bmc_ver_min;
72 uint16_t bmc_ver_cur;
73 uint16_t host_ver_min;
74 uint16_t host_ver_cur;
75 uint16_t negotiated_ver;
76 uint16_t pad0;
77
78 uint32_t rx_offset;
79 uint32_t rx_size;
80 uint32_t tx_offset;
81 uint32_t tx_size;
82} __attribute__((packed));
83
84/* layout of TX/RX areas */
85static const uint32_t rx_offset = 0x100;
86static const uint32_t rx_size = 0x100;
87static const uint32_t tx_offset = 0x200;
88static const uint32_t tx_size = 0x100;
89
Jeremy Kerr672c8852019-03-01 12:18:07 +080090#define LPC_WIN_SIZE (1 * 1024 * 1024)
91
92enum {
93 KCS_REG_DATA = 0,
94 KCS_REG_STATUS = 1,
95};
96
97#define KCS_STATUS_BMC_READY 0x80
98#define KCS_STATUS_CHANNEL_ACTIVE 0x40
99#define KCS_STATUS_IBF 0x02
100#define KCS_STATUS_OBF 0x01
101
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530102static bool lpc_direct(struct mctp_binding_astlpc *astlpc)
103{
104 return astlpc->lpc_map != NULL;
105}
106
Jeremy Kerr672c8852019-03-01 12:18:07 +0800107static int mctp_astlpc_kcs_set_status(struct mctp_binding_astlpc *astlpc,
108 uint8_t status)
109{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530110 uint8_t data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800111 int rc;
112
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800113 /* Since we're setting the status register, we want the other endpoint
114 * to be interrupted. However, some hardware may only raise a host-side
115 * interrupt on an ODR event.
116 * So, write a dummy value of 0xff to ODR, which will ensure that an
117 * interrupt is triggered, and can be ignored by the host.
118 */
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530119 data = 0xff;
120 status |= KCS_STATUS_OBF;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800121
Andrew Jefferyc84fd562020-01-30 21:18:16 +1030122 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
123 status);
124 if (rc) {
125 mctp_prwarn("KCS status write failed");
126 return -1;
127 }
128
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530129 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
130 data);
131 if (rc) {
132 mctp_prwarn("KCS dummy data write failed");
133 return -1;
134 }
135
Jeremy Kerr672c8852019-03-01 12:18:07 +0800136 return 0;
137}
138
139static int mctp_astlpc_kcs_send(struct mctp_binding_astlpc *astlpc,
140 uint8_t data)
141{
142 uint8_t status;
143 int rc;
144
145 for (;;) {
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530146 rc = astlpc->ops.kcs_read(astlpc->ops_data,
147 MCTP_ASTLPC_KCS_REG_STATUS, &status);
Andrew Jeffery1b27fe82020-01-24 16:05:11 +1030148 if (rc) {
Andrew Jeffery182204e2020-01-23 17:02:38 +1030149 mctp_prwarn("KCS status read failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800150 return -1;
151 }
152 if (!(status & KCS_STATUS_OBF))
153 break;
154 /* todo: timeout */
155 }
156
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530157 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
158 data);
159 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800160 mctp_prwarn("KCS data write failed");
161 return -1;
162 }
163
164 return 0;
165}
166
167static int mctp_binding_astlpc_tx(struct mctp_binding *b,
168 struct mctp_pktbuf *pkt)
169{
170 struct mctp_binding_astlpc *astlpc = binding_to_astlpc(b);
171 uint32_t len;
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030172 struct mctp_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800173
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030174 hdr = mctp_pktbuf_hdr(pkt);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800175 len = mctp_pktbuf_size(pkt);
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030176
177 mctp_prdebug("%s: Transmitting %"PRIu32"-byte packet (%hhu, %hhu, 0x%hhx)",
178 __func__, len, hdr->src, hdr->dest, hdr->flags_seq_tag);
179
Jeremy Kerr672c8852019-03-01 12:18:07 +0800180 if (len > rx_size - 4) {
181 mctp_prwarn("invalid TX len 0x%x", len);
182 return -1;
183 }
184
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530185 if (lpc_direct(astlpc)) {
186 *(uint32_t *)(astlpc->lpc_map + rx_offset) = htobe32(len);
187 memcpy(astlpc->lpc_map + rx_offset + 4, mctp_pktbuf_hdr(pkt),
188 len);
189 } else {
190 uint32_t tmp = htobe32(len);
191 astlpc->ops.lpc_write(astlpc->ops_data, &tmp, rx_offset,
192 sizeof(tmp));
193 astlpc->ops.lpc_write(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
194 rx_offset + 4, len);
195 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800196
197 mctp_binding_set_tx_enabled(b, false);
198
199 mctp_astlpc_kcs_send(astlpc, 0x1);
200 return 0;
201}
202
203static void mctp_astlpc_init_channel(struct mctp_binding_astlpc *astlpc)
204{
205 /* todo: actual version negotiation */
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530206 if (lpc_direct(astlpc)) {
207 astlpc->lpc_hdr->negotiated_ver = htobe16(1);
208 } else {
209 uint16_t ver = htobe16(1);
210 astlpc->ops.lpc_write(astlpc->ops_data, &ver,
211 offsetof(struct mctp_lpcmap_hdr,
212 negotiated_ver),
213 sizeof(ver));
214 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800215 mctp_astlpc_kcs_set_status(astlpc,
216 KCS_STATUS_BMC_READY | KCS_STATUS_CHANNEL_ACTIVE |
217 KCS_STATUS_OBF);
218
219 mctp_binding_set_tx_enabled(&astlpc->binding, true);
220}
221
222static void mctp_astlpc_rx_start(struct mctp_binding_astlpc *astlpc)
223{
224 struct mctp_pktbuf *pkt;
225 uint32_t len;
226
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530227 if (lpc_direct(astlpc)) {
228 len = *(uint32_t *)(astlpc->lpc_map + tx_offset);
229 } else {
230 astlpc->ops.lpc_read(astlpc->ops_data, &len,
231 tx_offset, sizeof(len));
232 }
233 len = be32toh(len);
234
Jeremy Kerr672c8852019-03-01 12:18:07 +0800235 if (len > tx_size - 4) {
236 mctp_prwarn("invalid RX len 0x%x", len);
237 return;
238 }
239
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800240 if (len > astlpc->binding.pkt_size) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800241 mctp_prwarn("invalid RX len 0x%x", len);
242 return;
243 }
244
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800245 pkt = mctp_pktbuf_alloc(&astlpc->binding, len);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800246 if (!pkt)
247 goto out_complete;
248
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530249 if (lpc_direct(astlpc)) {
250 memcpy(mctp_pktbuf_hdr(pkt),
251 astlpc->lpc_map + tx_offset + 4, len);
252 } else {
253 astlpc->ops.lpc_read(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
254 tx_offset + 4, len);
255 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800256
257 mctp_bus_rx(&astlpc->binding, pkt);
258
259out_complete:
260 mctp_astlpc_kcs_send(astlpc, 0x2);
261}
262
263static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
264{
265 mctp_binding_set_tx_enabled(&astlpc->binding, true);
266}
267
268int mctp_astlpc_poll(struct mctp_binding_astlpc *astlpc)
269{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530270 uint8_t status, data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800271 int rc;
272
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530273 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
274 &status);
275 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800276 mctp_prwarn("KCS read error");
277 return -1;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800278 }
279
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030280 mctp_prdebug("%s: status: 0x%hhx", __func__, status);
281
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530282 if (!(status & KCS_STATUS_IBF))
Jeremy Kerr672c8852019-03-01 12:18:07 +0800283 return 0;
284
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530285 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
286 &data);
287 if (rc) {
288 mctp_prwarn("KCS data read error");
289 return -1;
290 }
291
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030292 mctp_prdebug("%s: data: 0x%hhx", __func__, data);
293
Jeremy Kerr672c8852019-03-01 12:18:07 +0800294 switch (data) {
295 case 0x0:
296 mctp_astlpc_init_channel(astlpc);
297 break;
298 case 0x1:
299 mctp_astlpc_rx_start(astlpc);
300 break;
301 case 0x2:
302 mctp_astlpc_tx_complete(astlpc);
303 break;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800304 case 0xff:
305 /* reserved value for dummy data writes; do nothing */
306 break;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800307 default:
308 mctp_prwarn("unknown message 0x%x", data);
309 }
310 return 0;
311}
312
Jeremy Kerr672c8852019-03-01 12:18:07 +0800313static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
314{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530315 struct mctp_lpcmap_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800316 uint8_t status;
317 int rc;
318
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530319 if (lpc_direct(astlpc))
320 hdr = astlpc->lpc_hdr;
321 else
322 hdr = astlpc->priv_hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800323
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530324 hdr->magic = htobe32(MCTP_MAGIC);
325 hdr->bmc_ver_min = htobe16(BMC_VER_MIN);
326 hdr->bmc_ver_cur = htobe16(BMC_VER_CUR);
327
328 hdr->rx_offset = htobe32(rx_offset);
329 hdr->rx_size = htobe32(rx_size);
330 hdr->tx_offset = htobe32(tx_offset);
331 hdr->tx_size = htobe32(tx_size);
332
333 if (!lpc_direct(astlpc))
334 astlpc->ops.lpc_write(astlpc->ops_data, hdr, 0, sizeof(*hdr));
Jeremy Kerr672c8852019-03-01 12:18:07 +0800335
336 /* set status indicating that the BMC is now active */
337 status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530338 rc = astlpc->ops.kcs_write(astlpc->ops_data,
339 MCTP_ASTLPC_KCS_REG_STATUS, status);
340 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800341 mctp_prwarn("KCS write failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800342 }
343
344 return rc;
345}
346
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800347static int mctp_binding_astlpc_start(struct mctp_binding *b)
348{
349 struct mctp_binding_astlpc *astlpc = container_of(b,
350 struct mctp_binding_astlpc, binding);
351
352 return mctp_astlpc_init_bmc(astlpc);
353}
354
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530355/* allocate and basic initialisation */
356static struct mctp_binding_astlpc *__mctp_astlpc_init(void)
357{
358 struct mctp_binding_astlpc *astlpc;
359
360 astlpc = __mctp_alloc(sizeof(*astlpc));
361 memset(astlpc, 0, sizeof(*astlpc));
362 astlpc->binding.name = "astlpc";
363 astlpc->binding.version = 1;
364 astlpc->binding.tx = mctp_binding_astlpc_tx;
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800365 astlpc->binding.start = mctp_binding_astlpc_start;
Andrew Jeffery73c268e2020-01-30 10:16:09 +1030366 astlpc->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530367 astlpc->binding.pkt_pad = 0;
368 astlpc->lpc_map = NULL;
369
370 return astlpc;
371}
372
Jeremy Kerr3b36d172019-09-04 11:56:09 +0800373struct mctp_binding *mctp_binding_astlpc_core(struct mctp_binding_astlpc *b)
374{
375 return &b->binding;
376}
377
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530378struct mctp_binding_astlpc *mctp_astlpc_init_ops(
Andrew Jefferya0452492020-02-06 11:47:39 +1030379 const struct mctp_binding_astlpc_ops *ops,
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530380 void *ops_data, void *lpc_map)
381{
382 struct mctp_binding_astlpc *astlpc;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530383
384 astlpc = __mctp_astlpc_init();
385 if (!astlpc)
386 return NULL;
387
388 memcpy(&astlpc->ops, ops, sizeof(astlpc->ops));
389 astlpc->ops_data = ops_data;
390 astlpc->lpc_map = lpc_map;
391
392 /* In indirect mode, we keep a separate buffer of header data.
393 * We need to sync this through the lpc_read/lpc_write ops.
394 */
395 if (!astlpc->lpc_map)
396 astlpc->priv_hdr = __mctp_alloc(sizeof(*astlpc->priv_hdr));
397
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530398 return astlpc;
399}
400
Andrew Jeffery4663f672020-03-10 23:36:24 +1030401void mctp_astlpc_destroy(struct mctp_binding_astlpc *astlpc)
402{
403 if (astlpc->priv_hdr)
404 __mctp_free(astlpc->priv_hdr);
405 __mctp_free(astlpc);
406}
407
Jeremy Kerrb214c642019-11-27 11:34:00 +0800408#ifdef MCTP_HAVE_FILEIO
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530409static int mctp_astlpc_init_fileio_lpc(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800410{
411 struct aspeed_lpc_ctrl_mapping map = {
412 .window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
413 .window_id = 0, /* There's only one */
414 .flags = 0,
415 .addr = 0,
416 .offset = 0,
417 .size = 0
418 };
419 int fd, rc;
420
421 fd = open(lpc_path, O_RDWR | O_SYNC);
422 if (fd < 0) {
423 mctp_prwarn("LPC open (%s) failed", lpc_path);
424 return -1;
425 }
426
427 rc = ioctl(fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE, &map);
428 if (rc) {
429 mctp_prwarn("LPC GET_SIZE failed");
430 close(fd);
431 return -1;
432 }
433
434 astlpc->lpc_map_base = mmap(NULL, map.size, PROT_READ | PROT_WRITE,
435 MAP_SHARED, fd, 0);
436 if (astlpc->lpc_map_base == MAP_FAILED) {
437 mctp_prwarn("LPC mmap failed");
438 rc = -1;
439 } else {
440 astlpc->lpc_map = astlpc->lpc_map_base +
441 map.size - LPC_WIN_SIZE;
442 }
443
444 close(fd);
445
446 return rc;
447}
448
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530449static int mctp_astlpc_init_fileio_kcs(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800450{
451 astlpc->kcs_fd = open(kcs_path, O_RDWR);
452 if (astlpc->kcs_fd < 0)
453 return -1;
454
455 return 0;
456}
457
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530458static int __mctp_astlpc_fileio_kcs_read(void *arg,
459 enum mctp_binding_astlpc_kcs_reg reg, uint8_t *val)
460{
461 struct mctp_binding_astlpc *astlpc = arg;
462 off_t offset = reg;
463 int rc;
464
465 rc = pread(astlpc->kcs_fd, val, 1, offset);
466
467 return rc == 1 ? 0 : -1;
468}
469
470static int __mctp_astlpc_fileio_kcs_write(void *arg,
471 enum mctp_binding_astlpc_kcs_reg reg, uint8_t val)
472{
473 struct mctp_binding_astlpc *astlpc = arg;
474 off_t offset = reg;
475 int rc;
476
477 rc = pwrite(astlpc->kcs_fd, &val, 1, offset);
478
479 return rc == 1 ? 0 : -1;
480}
481
482int mctp_astlpc_get_fd(struct mctp_binding_astlpc *astlpc)
483{
484 return astlpc->kcs_fd;
485}
486
487struct mctp_binding_astlpc *mctp_astlpc_init_fileio(void)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800488{
489 struct mctp_binding_astlpc *astlpc;
490 int rc;
491
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530492 astlpc = __mctp_astlpc_init();
493 if (!astlpc)
494 return NULL;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800495
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530496 /* Set internal operations for kcs. We use direct accesses to the lpc
497 * map area */
498 astlpc->ops.kcs_read = __mctp_astlpc_fileio_kcs_read;
499 astlpc->ops.kcs_write = __mctp_astlpc_fileio_kcs_write;
500 astlpc->ops_data = astlpc;
501
502 rc = mctp_astlpc_init_fileio_lpc(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800503 if (rc) {
504 free(astlpc);
505 return NULL;
506 }
507
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530508 rc = mctp_astlpc_init_fileio_kcs(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800509 if (rc) {
510 free(astlpc);
511 return NULL;
512 }
513
Jeremy Kerr672c8852019-03-01 12:18:07 +0800514 return astlpc;
515}
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530516#else
517struct mctp_binding_astlpc * __attribute__((const))
518 mctp_astlpc_init_fileio(void)
519{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030520 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530521 return NULL;
522}
Jeremy Kerr672c8852019-03-01 12:18:07 +0800523
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530524int __attribute__((const)) mctp_astlpc_get_fd(
525 struct mctp_binding_astlpc *astlpc __attribute__((unused)))
526{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030527 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530528 return -1;
529}
530#endif