blob: f8cf42e55b208647f211c9930cdd8dc36ef30b19 [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"
24
Jeremy Kerrb214c642019-11-27 11:34:00 +080025#ifdef MCTP_HAVE_FILEIO
Jeremy Kerr92a10a62019-08-28 16:55:54 +053026
Jeremy Kerrc6f676d2019-12-19 09:24:06 +080027#include <unistd.h>
Jeremy Kerr92a10a62019-08-28 16:55:54 +053028#include <fcntl.h>
29#include <sys/ioctl.h>
30#include <sys/mman.h>
31#include <linux/aspeed-lpc-ctrl.h>
32
33/* kernel interface */
34static const char *kcs_path = "/dev/mctp0";
35static const char *lpc_path = "/dev/aspeed-lpc-ctrl";
36
37#endif
38
Jeremy Kerr672c8852019-03-01 12:18:07 +080039struct mctp_binding_astlpc {
40 struct mctp_binding binding;
Jeremy Kerrbc53d352019-08-28 14:26:14 +053041
Jeremy Kerr672c8852019-03-01 12:18:07 +080042 union {
43 void *lpc_map;
44 struct mctp_lpcmap_hdr *lpc_hdr;
45 };
Jeremy Kerrbc53d352019-08-28 14:26:14 +053046
47 /* direct ops data */
48 struct mctp_binding_astlpc_ops ops;
49 void *ops_data;
50 struct mctp_lpcmap_hdr *priv_hdr;
51
52 /* fileio ops data */
53 void *lpc_map_base;
Jeremy Kerr672c8852019-03-01 12:18:07 +080054 int kcs_fd;
55 uint8_t kcs_status;
56
57 bool running;
58
59 /* temporary transmit buffer */
60 uint8_t txbuf[256];
61};
62
63#ifndef container_of
64#define container_of(ptr, type, member) \
Andrew Jeffery1e0af042020-01-10 15:58:28 +103065 (type *)((char *)(ptr) - (char *)&((type *)0)->member)
Jeremy Kerr672c8852019-03-01 12:18:07 +080066#endif
67
68#define binding_to_astlpc(b) \
69 container_of(b, struct mctp_binding_astlpc, binding)
70
71#define MCTP_MAGIC 0x4d435450
72#define BMC_VER_MIN 1
73#define BMC_VER_CUR 1
74
75struct mctp_lpcmap_hdr {
76 uint32_t magic;
77
78 uint16_t bmc_ver_min;
79 uint16_t bmc_ver_cur;
80 uint16_t host_ver_min;
81 uint16_t host_ver_cur;
82 uint16_t negotiated_ver;
83 uint16_t pad0;
84
85 uint32_t rx_offset;
86 uint32_t rx_size;
87 uint32_t tx_offset;
88 uint32_t tx_size;
89} __attribute__((packed));
90
91/* layout of TX/RX areas */
92static const uint32_t rx_offset = 0x100;
93static const uint32_t rx_size = 0x100;
94static const uint32_t tx_offset = 0x200;
95static const uint32_t tx_size = 0x100;
96
Jeremy Kerr672c8852019-03-01 12:18:07 +080097#define LPC_WIN_SIZE (1 * 1024 * 1024)
98
99enum {
100 KCS_REG_DATA = 0,
101 KCS_REG_STATUS = 1,
102};
103
104#define KCS_STATUS_BMC_READY 0x80
105#define KCS_STATUS_CHANNEL_ACTIVE 0x40
106#define KCS_STATUS_IBF 0x02
107#define KCS_STATUS_OBF 0x01
108
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530109static bool lpc_direct(struct mctp_binding_astlpc *astlpc)
110{
111 return astlpc->lpc_map != NULL;
112}
113
Jeremy Kerr672c8852019-03-01 12:18:07 +0800114static int mctp_astlpc_kcs_set_status(struct mctp_binding_astlpc *astlpc,
115 uint8_t status)
116{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530117 uint8_t data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800118 int rc;
119
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800120 /* Since we're setting the status register, we want the other endpoint
121 * to be interrupted. However, some hardware may only raise a host-side
122 * interrupt on an ODR event.
123 * So, write a dummy value of 0xff to ODR, which will ensure that an
124 * interrupt is triggered, and can be ignored by the host.
125 */
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530126 data = 0xff;
127 status |= KCS_STATUS_OBF;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800128
Andrew Jefferyc84fd562020-01-30 21:18:16 +1030129 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
130 status);
131 if (rc) {
132 mctp_prwarn("KCS status write failed");
133 return -1;
134 }
135
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530136 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
137 data);
138 if (rc) {
139 mctp_prwarn("KCS dummy data write failed");
140 return -1;
141 }
142
Jeremy Kerr672c8852019-03-01 12:18:07 +0800143 return 0;
144}
145
146static int mctp_astlpc_kcs_send(struct mctp_binding_astlpc *astlpc,
147 uint8_t data)
148{
149 uint8_t status;
150 int rc;
151
152 for (;;) {
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530153 rc = astlpc->ops.kcs_read(astlpc->ops_data,
154 MCTP_ASTLPC_KCS_REG_STATUS, &status);
Andrew Jeffery1b27fe82020-01-24 16:05:11 +1030155 if (rc) {
Andrew Jeffery182204e2020-01-23 17:02:38 +1030156 mctp_prwarn("KCS status read failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800157 return -1;
158 }
159 if (!(status & KCS_STATUS_OBF))
160 break;
161 /* todo: timeout */
162 }
163
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530164 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
165 data);
166 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800167 mctp_prwarn("KCS data write failed");
168 return -1;
169 }
170
171 return 0;
172}
173
174static int mctp_binding_astlpc_tx(struct mctp_binding *b,
175 struct mctp_pktbuf *pkt)
176{
177 struct mctp_binding_astlpc *astlpc = binding_to_astlpc(b);
178 uint32_t len;
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030179 struct mctp_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800180
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030181 hdr = mctp_pktbuf_hdr(pkt);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800182 len = mctp_pktbuf_size(pkt);
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030183
184 mctp_prdebug("%s: Transmitting %"PRIu32"-byte packet (%hhu, %hhu, 0x%hhx)",
185 __func__, len, hdr->src, hdr->dest, hdr->flags_seq_tag);
186
Jeremy Kerr672c8852019-03-01 12:18:07 +0800187 if (len > rx_size - 4) {
188 mctp_prwarn("invalid TX len 0x%x", len);
189 return -1;
190 }
191
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530192 if (lpc_direct(astlpc)) {
193 *(uint32_t *)(astlpc->lpc_map + rx_offset) = htobe32(len);
194 memcpy(astlpc->lpc_map + rx_offset + 4, mctp_pktbuf_hdr(pkt),
195 len);
196 } else {
197 uint32_t tmp = htobe32(len);
198 astlpc->ops.lpc_write(astlpc->ops_data, &tmp, rx_offset,
199 sizeof(tmp));
200 astlpc->ops.lpc_write(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
201 rx_offset + 4, len);
202 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800203
204 mctp_binding_set_tx_enabled(b, false);
205
206 mctp_astlpc_kcs_send(astlpc, 0x1);
207 return 0;
208}
209
210static void mctp_astlpc_init_channel(struct mctp_binding_astlpc *astlpc)
211{
212 /* todo: actual version negotiation */
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530213 if (lpc_direct(astlpc)) {
214 astlpc->lpc_hdr->negotiated_ver = htobe16(1);
215 } else {
216 uint16_t ver = htobe16(1);
217 astlpc->ops.lpc_write(astlpc->ops_data, &ver,
218 offsetof(struct mctp_lpcmap_hdr,
219 negotiated_ver),
220 sizeof(ver));
221 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800222 mctp_astlpc_kcs_set_status(astlpc,
223 KCS_STATUS_BMC_READY | KCS_STATUS_CHANNEL_ACTIVE |
224 KCS_STATUS_OBF);
225
226 mctp_binding_set_tx_enabled(&astlpc->binding, true);
227}
228
229static void mctp_astlpc_rx_start(struct mctp_binding_astlpc *astlpc)
230{
231 struct mctp_pktbuf *pkt;
232 uint32_t len;
233
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530234 if (lpc_direct(astlpc)) {
235 len = *(uint32_t *)(astlpc->lpc_map + tx_offset);
236 } else {
237 astlpc->ops.lpc_read(astlpc->ops_data, &len,
238 tx_offset, sizeof(len));
239 }
240 len = be32toh(len);
241
Jeremy Kerr672c8852019-03-01 12:18:07 +0800242 if (len > tx_size - 4) {
243 mctp_prwarn("invalid RX len 0x%x", len);
244 return;
245 }
246
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800247 if (len > astlpc->binding.pkt_size) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800248 mctp_prwarn("invalid RX len 0x%x", len);
249 return;
250 }
251
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800252 pkt = mctp_pktbuf_alloc(&astlpc->binding, len);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800253 if (!pkt)
254 goto out_complete;
255
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530256 if (lpc_direct(astlpc)) {
257 memcpy(mctp_pktbuf_hdr(pkt),
258 astlpc->lpc_map + tx_offset + 4, len);
259 } else {
260 astlpc->ops.lpc_read(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
261 tx_offset + 4, len);
262 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800263
264 mctp_bus_rx(&astlpc->binding, pkt);
265
266out_complete:
267 mctp_astlpc_kcs_send(astlpc, 0x2);
268}
269
270static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
271{
272 mctp_binding_set_tx_enabled(&astlpc->binding, true);
273}
274
275int mctp_astlpc_poll(struct mctp_binding_astlpc *astlpc)
276{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530277 uint8_t status, data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800278 int rc;
279
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530280 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
281 &status);
282 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800283 mctp_prwarn("KCS read error");
284 return -1;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800285 }
286
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030287 mctp_prdebug("%s: status: 0x%hhx", __func__, status);
288
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530289 if (!(status & KCS_STATUS_IBF))
Jeremy Kerr672c8852019-03-01 12:18:07 +0800290 return 0;
291
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530292 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
293 &data);
294 if (rc) {
295 mctp_prwarn("KCS data read error");
296 return -1;
297 }
298
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030299 mctp_prdebug("%s: data: 0x%hhx", __func__, data);
300
Jeremy Kerr672c8852019-03-01 12:18:07 +0800301 switch (data) {
302 case 0x0:
303 mctp_astlpc_init_channel(astlpc);
304 break;
305 case 0x1:
306 mctp_astlpc_rx_start(astlpc);
307 break;
308 case 0x2:
309 mctp_astlpc_tx_complete(astlpc);
310 break;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800311 case 0xff:
312 /* reserved value for dummy data writes; do nothing */
313 break;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800314 default:
315 mctp_prwarn("unknown message 0x%x", data);
316 }
317 return 0;
318}
319
Jeremy Kerr672c8852019-03-01 12:18:07 +0800320static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
321{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530322 struct mctp_lpcmap_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800323 uint8_t status;
324 int rc;
325
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530326 if (lpc_direct(astlpc))
327 hdr = astlpc->lpc_hdr;
328 else
329 hdr = astlpc->priv_hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800330
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530331 hdr->magic = htobe32(MCTP_MAGIC);
332 hdr->bmc_ver_min = htobe16(BMC_VER_MIN);
333 hdr->bmc_ver_cur = htobe16(BMC_VER_CUR);
334
335 hdr->rx_offset = htobe32(rx_offset);
336 hdr->rx_size = htobe32(rx_size);
337 hdr->tx_offset = htobe32(tx_offset);
338 hdr->tx_size = htobe32(tx_size);
339
340 if (!lpc_direct(astlpc))
341 astlpc->ops.lpc_write(astlpc->ops_data, hdr, 0, sizeof(*hdr));
Jeremy Kerr672c8852019-03-01 12:18:07 +0800342
343 /* set status indicating that the BMC is now active */
344 status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530345 rc = astlpc->ops.kcs_write(astlpc->ops_data,
346 MCTP_ASTLPC_KCS_REG_STATUS, status);
347 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800348 mctp_prwarn("KCS write failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800349 }
350
351 return rc;
352}
353
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800354static int mctp_binding_astlpc_start(struct mctp_binding *b)
355{
356 struct mctp_binding_astlpc *astlpc = container_of(b,
357 struct mctp_binding_astlpc, binding);
358
359 return mctp_astlpc_init_bmc(astlpc);
360}
361
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530362/* allocate and basic initialisation */
363static struct mctp_binding_astlpc *__mctp_astlpc_init(void)
364{
365 struct mctp_binding_astlpc *astlpc;
366
367 astlpc = __mctp_alloc(sizeof(*astlpc));
368 memset(astlpc, 0, sizeof(*astlpc));
369 astlpc->binding.name = "astlpc";
370 astlpc->binding.version = 1;
371 astlpc->binding.tx = mctp_binding_astlpc_tx;
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800372 astlpc->binding.start = mctp_binding_astlpc_start;
Andrew Jeffery73c268e2020-01-30 10:16:09 +1030373 astlpc->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530374 astlpc->binding.pkt_pad = 0;
375 astlpc->lpc_map = NULL;
376
377 return astlpc;
378}
379
Jeremy Kerr3b36d172019-09-04 11:56:09 +0800380struct mctp_binding *mctp_binding_astlpc_core(struct mctp_binding_astlpc *b)
381{
382 return &b->binding;
383}
384
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530385struct mctp_binding_astlpc *mctp_astlpc_init_ops(
Andrew Jefferya0452492020-02-06 11:47:39 +1030386 const struct mctp_binding_astlpc_ops *ops,
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530387 void *ops_data, void *lpc_map)
388{
389 struct mctp_binding_astlpc *astlpc;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530390
391 astlpc = __mctp_astlpc_init();
392 if (!astlpc)
393 return NULL;
394
395 memcpy(&astlpc->ops, ops, sizeof(astlpc->ops));
396 astlpc->ops_data = ops_data;
397 astlpc->lpc_map = lpc_map;
398
399 /* In indirect mode, we keep a separate buffer of header data.
400 * We need to sync this through the lpc_read/lpc_write ops.
401 */
402 if (!astlpc->lpc_map)
403 astlpc->priv_hdr = __mctp_alloc(sizeof(*astlpc->priv_hdr));
404
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530405 return astlpc;
406}
407
Andrew Jeffery4663f672020-03-10 23:36:24 +1030408void mctp_astlpc_destroy(struct mctp_binding_astlpc *astlpc)
409{
410 if (astlpc->priv_hdr)
411 __mctp_free(astlpc->priv_hdr);
412 __mctp_free(astlpc);
413}
414
Jeremy Kerrb214c642019-11-27 11:34:00 +0800415#ifdef MCTP_HAVE_FILEIO
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530416static int mctp_astlpc_init_fileio_lpc(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800417{
418 struct aspeed_lpc_ctrl_mapping map = {
419 .window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
420 .window_id = 0, /* There's only one */
421 .flags = 0,
422 .addr = 0,
423 .offset = 0,
424 .size = 0
425 };
426 int fd, rc;
427
428 fd = open(lpc_path, O_RDWR | O_SYNC);
429 if (fd < 0) {
430 mctp_prwarn("LPC open (%s) failed", lpc_path);
431 return -1;
432 }
433
434 rc = ioctl(fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE, &map);
435 if (rc) {
436 mctp_prwarn("LPC GET_SIZE failed");
437 close(fd);
438 return -1;
439 }
440
441 astlpc->lpc_map_base = mmap(NULL, map.size, PROT_READ | PROT_WRITE,
442 MAP_SHARED, fd, 0);
443 if (astlpc->lpc_map_base == MAP_FAILED) {
444 mctp_prwarn("LPC mmap failed");
445 rc = -1;
446 } else {
447 astlpc->lpc_map = astlpc->lpc_map_base +
448 map.size - LPC_WIN_SIZE;
449 }
450
451 close(fd);
452
453 return rc;
454}
455
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530456static int mctp_astlpc_init_fileio_kcs(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800457{
458 astlpc->kcs_fd = open(kcs_path, O_RDWR);
459 if (astlpc->kcs_fd < 0)
460 return -1;
461
462 return 0;
463}
464
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530465static int __mctp_astlpc_fileio_kcs_read(void *arg,
466 enum mctp_binding_astlpc_kcs_reg reg, uint8_t *val)
467{
468 struct mctp_binding_astlpc *astlpc = arg;
469 off_t offset = reg;
470 int rc;
471
472 rc = pread(astlpc->kcs_fd, val, 1, offset);
473
474 return rc == 1 ? 0 : -1;
475}
476
477static int __mctp_astlpc_fileio_kcs_write(void *arg,
478 enum mctp_binding_astlpc_kcs_reg reg, uint8_t val)
479{
480 struct mctp_binding_astlpc *astlpc = arg;
481 off_t offset = reg;
482 int rc;
483
484 rc = pwrite(astlpc->kcs_fd, &val, 1, offset);
485
486 return rc == 1 ? 0 : -1;
487}
488
489int mctp_astlpc_get_fd(struct mctp_binding_astlpc *astlpc)
490{
491 return astlpc->kcs_fd;
492}
493
494struct mctp_binding_astlpc *mctp_astlpc_init_fileio(void)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800495{
496 struct mctp_binding_astlpc *astlpc;
497 int rc;
498
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530499 astlpc = __mctp_astlpc_init();
500 if (!astlpc)
501 return NULL;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800502
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530503 /* Set internal operations for kcs. We use direct accesses to the lpc
504 * map area */
505 astlpc->ops.kcs_read = __mctp_astlpc_fileio_kcs_read;
506 astlpc->ops.kcs_write = __mctp_astlpc_fileio_kcs_write;
507 astlpc->ops_data = astlpc;
508
509 rc = mctp_astlpc_init_fileio_lpc(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800510 if (rc) {
511 free(astlpc);
512 return NULL;
513 }
514
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530515 rc = mctp_astlpc_init_fileio_kcs(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800516 if (rc) {
517 free(astlpc);
518 return NULL;
519 }
520
Jeremy Kerr672c8852019-03-01 12:18:07 +0800521 return astlpc;
522}
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530523#else
524struct mctp_binding_astlpc * __attribute__((const))
525 mctp_astlpc_init_fileio(void)
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 NULL;
529}
Jeremy Kerr672c8852019-03-01 12:18:07 +0800530
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530531int __attribute__((const)) mctp_astlpc_get_fd(
532 struct mctp_binding_astlpc *astlpc __attribute__((unused)))
533{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030534 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530535 return -1;
536}
537#endif