blob: a5a3a820661b7cde2687de05211f4f8bd5785486 [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
Andrew Jefferyb93b6112020-06-05 14:13:44 +0930240 assert(astlpc->binding.pkt_size >= 0);
241 if (len > (uint32_t)astlpc->binding.pkt_size) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800242 mctp_prwarn("invalid RX len 0x%x", len);
243 return;
244 }
245
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800246 pkt = mctp_pktbuf_alloc(&astlpc->binding, len);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800247 if (!pkt)
248 goto out_complete;
249
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530250 if (lpc_direct(astlpc)) {
251 memcpy(mctp_pktbuf_hdr(pkt),
252 astlpc->lpc_map + tx_offset + 4, len);
253 } else {
254 astlpc->ops.lpc_read(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
255 tx_offset + 4, len);
256 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800257
258 mctp_bus_rx(&astlpc->binding, pkt);
259
260out_complete:
261 mctp_astlpc_kcs_send(astlpc, 0x2);
262}
263
264static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
265{
266 mctp_binding_set_tx_enabled(&astlpc->binding, true);
267}
268
269int mctp_astlpc_poll(struct mctp_binding_astlpc *astlpc)
270{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530271 uint8_t status, data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800272 int rc;
273
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530274 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
275 &status);
276 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800277 mctp_prwarn("KCS read error");
278 return -1;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800279 }
280
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030281 mctp_prdebug("%s: status: 0x%hhx", __func__, status);
282
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530283 if (!(status & KCS_STATUS_IBF))
Jeremy Kerr672c8852019-03-01 12:18:07 +0800284 return 0;
285
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530286 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
287 &data);
288 if (rc) {
289 mctp_prwarn("KCS data read error");
290 return -1;
291 }
292
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030293 mctp_prdebug("%s: data: 0x%hhx", __func__, data);
294
Jeremy Kerr672c8852019-03-01 12:18:07 +0800295 switch (data) {
296 case 0x0:
297 mctp_astlpc_init_channel(astlpc);
298 break;
299 case 0x1:
300 mctp_astlpc_rx_start(astlpc);
301 break;
302 case 0x2:
303 mctp_astlpc_tx_complete(astlpc);
304 break;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800305 case 0xff:
306 /* reserved value for dummy data writes; do nothing */
307 break;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800308 default:
309 mctp_prwarn("unknown message 0x%x", data);
310 }
311 return 0;
312}
313
Jeremy Kerr672c8852019-03-01 12:18:07 +0800314static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
315{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530316 struct mctp_lpcmap_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800317 uint8_t status;
318 int rc;
319
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530320 if (lpc_direct(astlpc))
321 hdr = astlpc->lpc_hdr;
322 else
323 hdr = astlpc->priv_hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800324
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530325 hdr->magic = htobe32(MCTP_MAGIC);
326 hdr->bmc_ver_min = htobe16(BMC_VER_MIN);
327 hdr->bmc_ver_cur = htobe16(BMC_VER_CUR);
328
329 hdr->rx_offset = htobe32(rx_offset);
330 hdr->rx_size = htobe32(rx_size);
331 hdr->tx_offset = htobe32(tx_offset);
332 hdr->tx_size = htobe32(tx_size);
333
334 if (!lpc_direct(astlpc))
335 astlpc->ops.lpc_write(astlpc->ops_data, hdr, 0, sizeof(*hdr));
Jeremy Kerr672c8852019-03-01 12:18:07 +0800336
337 /* set status indicating that the BMC is now active */
338 status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530339 rc = astlpc->ops.kcs_write(astlpc->ops_data,
340 MCTP_ASTLPC_KCS_REG_STATUS, status);
341 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800342 mctp_prwarn("KCS write failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800343 }
344
345 return rc;
346}
347
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800348static int mctp_binding_astlpc_start(struct mctp_binding *b)
349{
350 struct mctp_binding_astlpc *astlpc = container_of(b,
351 struct mctp_binding_astlpc, binding);
352
353 return mctp_astlpc_init_bmc(astlpc);
354}
355
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530356/* allocate and basic initialisation */
357static struct mctp_binding_astlpc *__mctp_astlpc_init(void)
358{
359 struct mctp_binding_astlpc *astlpc;
360
361 astlpc = __mctp_alloc(sizeof(*astlpc));
362 memset(astlpc, 0, sizeof(*astlpc));
363 astlpc->binding.name = "astlpc";
364 astlpc->binding.version = 1;
365 astlpc->binding.tx = mctp_binding_astlpc_tx;
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800366 astlpc->binding.start = mctp_binding_astlpc_start;
Andrew Jeffery73c268e2020-01-30 10:16:09 +1030367 astlpc->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530368 astlpc->binding.pkt_pad = 0;
369 astlpc->lpc_map = NULL;
370
371 return astlpc;
372}
373
Jeremy Kerr3b36d172019-09-04 11:56:09 +0800374struct mctp_binding *mctp_binding_astlpc_core(struct mctp_binding_astlpc *b)
375{
376 return &b->binding;
377}
378
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530379struct mctp_binding_astlpc *mctp_astlpc_init_ops(
Andrew Jefferya0452492020-02-06 11:47:39 +1030380 const struct mctp_binding_astlpc_ops *ops,
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530381 void *ops_data, void *lpc_map)
382{
383 struct mctp_binding_astlpc *astlpc;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530384
385 astlpc = __mctp_astlpc_init();
386 if (!astlpc)
387 return NULL;
388
389 memcpy(&astlpc->ops, ops, sizeof(astlpc->ops));
390 astlpc->ops_data = ops_data;
391 astlpc->lpc_map = lpc_map;
392
393 /* In indirect mode, we keep a separate buffer of header data.
394 * We need to sync this through the lpc_read/lpc_write ops.
395 */
396 if (!astlpc->lpc_map)
397 astlpc->priv_hdr = __mctp_alloc(sizeof(*astlpc->priv_hdr));
398
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530399 return astlpc;
400}
401
Andrew Jeffery4663f672020-03-10 23:36:24 +1030402void mctp_astlpc_destroy(struct mctp_binding_astlpc *astlpc)
403{
404 if (astlpc->priv_hdr)
405 __mctp_free(astlpc->priv_hdr);
406 __mctp_free(astlpc);
407}
408
Jeremy Kerrb214c642019-11-27 11:34:00 +0800409#ifdef MCTP_HAVE_FILEIO
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530410static int mctp_astlpc_init_fileio_lpc(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800411{
412 struct aspeed_lpc_ctrl_mapping map = {
413 .window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
414 .window_id = 0, /* There's only one */
415 .flags = 0,
416 .addr = 0,
417 .offset = 0,
418 .size = 0
419 };
420 int fd, rc;
421
422 fd = open(lpc_path, O_RDWR | O_SYNC);
423 if (fd < 0) {
424 mctp_prwarn("LPC open (%s) failed", lpc_path);
425 return -1;
426 }
427
428 rc = ioctl(fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE, &map);
429 if (rc) {
430 mctp_prwarn("LPC GET_SIZE failed");
431 close(fd);
432 return -1;
433 }
434
435 astlpc->lpc_map_base = mmap(NULL, map.size, PROT_READ | PROT_WRITE,
436 MAP_SHARED, fd, 0);
437 if (astlpc->lpc_map_base == MAP_FAILED) {
438 mctp_prwarn("LPC mmap failed");
439 rc = -1;
440 } else {
441 astlpc->lpc_map = astlpc->lpc_map_base +
442 map.size - LPC_WIN_SIZE;
443 }
444
445 close(fd);
446
447 return rc;
448}
449
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530450static int mctp_astlpc_init_fileio_kcs(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800451{
452 astlpc->kcs_fd = open(kcs_path, O_RDWR);
453 if (astlpc->kcs_fd < 0)
454 return -1;
455
456 return 0;
457}
458
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530459static int __mctp_astlpc_fileio_kcs_read(void *arg,
460 enum mctp_binding_astlpc_kcs_reg reg, uint8_t *val)
461{
462 struct mctp_binding_astlpc *astlpc = arg;
463 off_t offset = reg;
464 int rc;
465
466 rc = pread(astlpc->kcs_fd, val, 1, offset);
467
468 return rc == 1 ? 0 : -1;
469}
470
471static int __mctp_astlpc_fileio_kcs_write(void *arg,
472 enum mctp_binding_astlpc_kcs_reg reg, uint8_t val)
473{
474 struct mctp_binding_astlpc *astlpc = arg;
475 off_t offset = reg;
476 int rc;
477
478 rc = pwrite(astlpc->kcs_fd, &val, 1, offset);
479
480 return rc == 1 ? 0 : -1;
481}
482
483int mctp_astlpc_get_fd(struct mctp_binding_astlpc *astlpc)
484{
485 return astlpc->kcs_fd;
486}
487
488struct mctp_binding_astlpc *mctp_astlpc_init_fileio(void)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800489{
490 struct mctp_binding_astlpc *astlpc;
491 int rc;
492
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530493 astlpc = __mctp_astlpc_init();
494 if (!astlpc)
495 return NULL;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800496
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530497 /* Set internal operations for kcs. We use direct accesses to the lpc
498 * map area */
499 astlpc->ops.kcs_read = __mctp_astlpc_fileio_kcs_read;
500 astlpc->ops.kcs_write = __mctp_astlpc_fileio_kcs_write;
501 astlpc->ops_data = astlpc;
502
503 rc = mctp_astlpc_init_fileio_lpc(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800504 if (rc) {
505 free(astlpc);
506 return NULL;
507 }
508
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530509 rc = mctp_astlpc_init_fileio_kcs(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800510 if (rc) {
511 free(astlpc);
512 return NULL;
513 }
514
Jeremy Kerr672c8852019-03-01 12:18:07 +0800515 return astlpc;
516}
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530517#else
518struct mctp_binding_astlpc * __attribute__((const))
519 mctp_astlpc_init_fileio(void)
520{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030521 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530522 return NULL;
523}
Jeremy Kerr672c8852019-03-01 12:18:07 +0800524
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530525int __attribute__((const)) mctp_astlpc_get_fd(
526 struct mctp_binding_astlpc *astlpc __attribute__((unused)))
527{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030528 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530529 return -1;
530}
531#endif