blob: 66fa9306151e1473f503158c98e3aa501f2bca2c [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;
59
60 /* temporary transmit buffer */
61 uint8_t txbuf[256];
62};
63
Jeremy Kerr672c8852019-03-01 12:18:07 +080064#define binding_to_astlpc(b) \
65 container_of(b, struct mctp_binding_astlpc, binding)
66
67#define MCTP_MAGIC 0x4d435450
68#define BMC_VER_MIN 1
69#define BMC_VER_CUR 1
70
71struct mctp_lpcmap_hdr {
72 uint32_t magic;
73
74 uint16_t bmc_ver_min;
75 uint16_t bmc_ver_cur;
76 uint16_t host_ver_min;
77 uint16_t host_ver_cur;
78 uint16_t negotiated_ver;
79 uint16_t pad0;
80
81 uint32_t rx_offset;
82 uint32_t rx_size;
83 uint32_t tx_offset;
84 uint32_t tx_size;
85} __attribute__((packed));
86
87/* layout of TX/RX areas */
88static const uint32_t rx_offset = 0x100;
89static const uint32_t rx_size = 0x100;
90static const uint32_t tx_offset = 0x200;
91static const uint32_t tx_size = 0x100;
92
Jeremy Kerr672c8852019-03-01 12:18:07 +080093#define LPC_WIN_SIZE (1 * 1024 * 1024)
94
95enum {
96 KCS_REG_DATA = 0,
97 KCS_REG_STATUS = 1,
98};
99
100#define KCS_STATUS_BMC_READY 0x80
101#define KCS_STATUS_CHANNEL_ACTIVE 0x40
102#define KCS_STATUS_IBF 0x02
103#define KCS_STATUS_OBF 0x01
104
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530105static bool lpc_direct(struct mctp_binding_astlpc *astlpc)
106{
107 return astlpc->lpc_map != NULL;
108}
109
Jeremy Kerr672c8852019-03-01 12:18:07 +0800110static int mctp_astlpc_kcs_set_status(struct mctp_binding_astlpc *astlpc,
111 uint8_t status)
112{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530113 uint8_t data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800114 int rc;
115
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800116 /* Since we're setting the status register, we want the other endpoint
117 * to be interrupted. However, some hardware may only raise a host-side
118 * interrupt on an ODR event.
119 * So, write a dummy value of 0xff to ODR, which will ensure that an
120 * interrupt is triggered, and can be ignored by the host.
121 */
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530122 data = 0xff;
123 status |= KCS_STATUS_OBF;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800124
Andrew Jefferyc84fd562020-01-30 21:18:16 +1030125 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
126 status);
127 if (rc) {
128 mctp_prwarn("KCS status write failed");
129 return -1;
130 }
131
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530132 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
133 data);
134 if (rc) {
135 mctp_prwarn("KCS dummy data write failed");
136 return -1;
137 }
138
Jeremy Kerr672c8852019-03-01 12:18:07 +0800139 return 0;
140}
141
142static int mctp_astlpc_kcs_send(struct mctp_binding_astlpc *astlpc,
143 uint8_t data)
144{
145 uint8_t status;
146 int rc;
147
148 for (;;) {
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530149 rc = astlpc->ops.kcs_read(astlpc->ops_data,
150 MCTP_ASTLPC_KCS_REG_STATUS, &status);
Andrew Jeffery1b27fe82020-01-24 16:05:11 +1030151 if (rc) {
Andrew Jeffery182204e2020-01-23 17:02:38 +1030152 mctp_prwarn("KCS status read failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800153 return -1;
154 }
155 if (!(status & KCS_STATUS_OBF))
156 break;
157 /* todo: timeout */
158 }
159
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530160 rc = astlpc->ops.kcs_write(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
161 data);
162 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800163 mctp_prwarn("KCS data write failed");
164 return -1;
165 }
166
167 return 0;
168}
169
170static int mctp_binding_astlpc_tx(struct mctp_binding *b,
171 struct mctp_pktbuf *pkt)
172{
173 struct mctp_binding_astlpc *astlpc = binding_to_astlpc(b);
174 uint32_t len;
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030175 struct mctp_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800176
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030177 hdr = mctp_pktbuf_hdr(pkt);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800178 len = mctp_pktbuf_size(pkt);
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030179
180 mctp_prdebug("%s: Transmitting %"PRIu32"-byte packet (%hhu, %hhu, 0x%hhx)",
181 __func__, len, hdr->src, hdr->dest, hdr->flags_seq_tag);
182
Jeremy Kerr672c8852019-03-01 12:18:07 +0800183 if (len > rx_size - 4) {
184 mctp_prwarn("invalid TX len 0x%x", len);
185 return -1;
186 }
187
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530188 if (lpc_direct(astlpc)) {
189 *(uint32_t *)(astlpc->lpc_map + rx_offset) = htobe32(len);
190 memcpy(astlpc->lpc_map + rx_offset + 4, mctp_pktbuf_hdr(pkt),
191 len);
192 } else {
193 uint32_t tmp = htobe32(len);
194 astlpc->ops.lpc_write(astlpc->ops_data, &tmp, rx_offset,
195 sizeof(tmp));
196 astlpc->ops.lpc_write(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
197 rx_offset + 4, len);
198 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800199
200 mctp_binding_set_tx_enabled(b, false);
201
202 mctp_astlpc_kcs_send(astlpc, 0x1);
203 return 0;
204}
205
206static void mctp_astlpc_init_channel(struct mctp_binding_astlpc *astlpc)
207{
208 /* todo: actual version negotiation */
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530209 if (lpc_direct(astlpc)) {
210 astlpc->lpc_hdr->negotiated_ver = htobe16(1);
211 } else {
212 uint16_t ver = htobe16(1);
213 astlpc->ops.lpc_write(astlpc->ops_data, &ver,
214 offsetof(struct mctp_lpcmap_hdr,
215 negotiated_ver),
216 sizeof(ver));
217 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800218 mctp_astlpc_kcs_set_status(astlpc,
219 KCS_STATUS_BMC_READY | KCS_STATUS_CHANNEL_ACTIVE |
220 KCS_STATUS_OBF);
221
222 mctp_binding_set_tx_enabled(&astlpc->binding, true);
223}
224
225static void mctp_astlpc_rx_start(struct mctp_binding_astlpc *astlpc)
226{
227 struct mctp_pktbuf *pkt;
228 uint32_t len;
229
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530230 if (lpc_direct(astlpc)) {
231 len = *(uint32_t *)(astlpc->lpc_map + tx_offset);
232 } else {
233 astlpc->ops.lpc_read(astlpc->ops_data, &len,
234 tx_offset, sizeof(len));
235 }
236 len = be32toh(len);
237
Jeremy Kerr672c8852019-03-01 12:18:07 +0800238 if (len > tx_size - 4) {
239 mctp_prwarn("invalid RX len 0x%x", len);
240 return;
241 }
242
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800243 if (len > astlpc->binding.pkt_size) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800244 mctp_prwarn("invalid RX len 0x%x", len);
245 return;
246 }
247
Jeremy Kerrdf15f7e2019-08-05 15:41:19 +0800248 pkt = mctp_pktbuf_alloc(&astlpc->binding, len);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800249 if (!pkt)
250 goto out_complete;
251
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530252 if (lpc_direct(astlpc)) {
253 memcpy(mctp_pktbuf_hdr(pkt),
254 astlpc->lpc_map + tx_offset + 4, len);
255 } else {
256 astlpc->ops.lpc_read(astlpc->ops_data, mctp_pktbuf_hdr(pkt),
257 tx_offset + 4, len);
258 }
Jeremy Kerr672c8852019-03-01 12:18:07 +0800259
260 mctp_bus_rx(&astlpc->binding, pkt);
261
262out_complete:
263 mctp_astlpc_kcs_send(astlpc, 0x2);
264}
265
266static void mctp_astlpc_tx_complete(struct mctp_binding_astlpc *astlpc)
267{
268 mctp_binding_set_tx_enabled(&astlpc->binding, true);
269}
270
271int mctp_astlpc_poll(struct mctp_binding_astlpc *astlpc)
272{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530273 uint8_t status, data;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800274 int rc;
275
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530276 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_STATUS,
277 &status);
278 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800279 mctp_prwarn("KCS read error");
280 return -1;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800281 }
282
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030283 mctp_prdebug("%s: status: 0x%hhx", __func__, status);
284
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530285 if (!(status & KCS_STATUS_IBF))
Jeremy Kerr672c8852019-03-01 12:18:07 +0800286 return 0;
287
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530288 rc = astlpc->ops.kcs_read(astlpc->ops_data, MCTP_ASTLPC_KCS_REG_DATA,
289 &data);
290 if (rc) {
291 mctp_prwarn("KCS data read error");
292 return -1;
293 }
294
Andrew Jefferyedfe3832020-02-06 11:52:11 +1030295 mctp_prdebug("%s: data: 0x%hhx", __func__, data);
296
Jeremy Kerr672c8852019-03-01 12:18:07 +0800297 switch (data) {
298 case 0x0:
299 mctp_astlpc_init_channel(astlpc);
300 break;
301 case 0x1:
302 mctp_astlpc_rx_start(astlpc);
303 break;
304 case 0x2:
305 mctp_astlpc_tx_complete(astlpc);
306 break;
Jeremy Kerr1a4b55a2019-06-24 14:22:39 +0800307 case 0xff:
308 /* reserved value for dummy data writes; do nothing */
309 break;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800310 default:
311 mctp_prwarn("unknown message 0x%x", data);
312 }
313 return 0;
314}
315
Jeremy Kerr672c8852019-03-01 12:18:07 +0800316static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
317{
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530318 struct mctp_lpcmap_hdr *hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800319 uint8_t status;
320 int rc;
321
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530322 if (lpc_direct(astlpc))
323 hdr = astlpc->lpc_hdr;
324 else
325 hdr = astlpc->priv_hdr;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800326
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530327 hdr->magic = htobe32(MCTP_MAGIC);
328 hdr->bmc_ver_min = htobe16(BMC_VER_MIN);
329 hdr->bmc_ver_cur = htobe16(BMC_VER_CUR);
330
331 hdr->rx_offset = htobe32(rx_offset);
332 hdr->rx_size = htobe32(rx_size);
333 hdr->tx_offset = htobe32(tx_offset);
334 hdr->tx_size = htobe32(tx_size);
335
336 if (!lpc_direct(astlpc))
337 astlpc->ops.lpc_write(astlpc->ops_data, hdr, 0, sizeof(*hdr));
Jeremy Kerr672c8852019-03-01 12:18:07 +0800338
339 /* set status indicating that the BMC is now active */
340 status = KCS_STATUS_BMC_READY | KCS_STATUS_OBF;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530341 rc = astlpc->ops.kcs_write(astlpc->ops_data,
342 MCTP_ASTLPC_KCS_REG_STATUS, status);
343 if (rc) {
Jeremy Kerr672c8852019-03-01 12:18:07 +0800344 mctp_prwarn("KCS write failed");
Jeremy Kerr672c8852019-03-01 12:18:07 +0800345 }
346
347 return rc;
348}
349
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800350static int mctp_binding_astlpc_start(struct mctp_binding *b)
351{
352 struct mctp_binding_astlpc *astlpc = container_of(b,
353 struct mctp_binding_astlpc, binding);
354
355 return mctp_astlpc_init_bmc(astlpc);
356}
357
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530358/* allocate and basic initialisation */
359static struct mctp_binding_astlpc *__mctp_astlpc_init(void)
360{
361 struct mctp_binding_astlpc *astlpc;
362
363 astlpc = __mctp_alloc(sizeof(*astlpc));
364 memset(astlpc, 0, sizeof(*astlpc));
365 astlpc->binding.name = "astlpc";
366 astlpc->binding.version = 1;
367 astlpc->binding.tx = mctp_binding_astlpc_tx;
Jeremy Kerr8081beb2019-09-04 12:33:00 +0800368 astlpc->binding.start = mctp_binding_astlpc_start;
Andrew Jeffery73c268e2020-01-30 10:16:09 +1030369 astlpc->binding.pkt_size = MCTP_PACKET_SIZE(MCTP_BTU);
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530370 astlpc->binding.pkt_pad = 0;
371 astlpc->lpc_map = NULL;
372
373 return astlpc;
374}
375
Jeremy Kerr3b36d172019-09-04 11:56:09 +0800376struct mctp_binding *mctp_binding_astlpc_core(struct mctp_binding_astlpc *b)
377{
378 return &b->binding;
379}
380
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530381struct mctp_binding_astlpc *mctp_astlpc_init_ops(
Andrew Jefferya0452492020-02-06 11:47:39 +1030382 const struct mctp_binding_astlpc_ops *ops,
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530383 void *ops_data, void *lpc_map)
384{
385 struct mctp_binding_astlpc *astlpc;
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530386
387 astlpc = __mctp_astlpc_init();
388 if (!astlpc)
389 return NULL;
390
391 memcpy(&astlpc->ops, ops, sizeof(astlpc->ops));
392 astlpc->ops_data = ops_data;
393 astlpc->lpc_map = lpc_map;
394
395 /* In indirect mode, we keep a separate buffer of header data.
396 * We need to sync this through the lpc_read/lpc_write ops.
397 */
398 if (!astlpc->lpc_map)
399 astlpc->priv_hdr = __mctp_alloc(sizeof(*astlpc->priv_hdr));
400
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530401 return astlpc;
402}
403
Andrew Jeffery4663f672020-03-10 23:36:24 +1030404void mctp_astlpc_destroy(struct mctp_binding_astlpc *astlpc)
405{
406 if (astlpc->priv_hdr)
407 __mctp_free(astlpc->priv_hdr);
408 __mctp_free(astlpc);
409}
410
Jeremy Kerrb214c642019-11-27 11:34:00 +0800411#ifdef MCTP_HAVE_FILEIO
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530412static int mctp_astlpc_init_fileio_lpc(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800413{
414 struct aspeed_lpc_ctrl_mapping map = {
415 .window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
416 .window_id = 0, /* There's only one */
417 .flags = 0,
418 .addr = 0,
419 .offset = 0,
420 .size = 0
421 };
422 int fd, rc;
423
424 fd = open(lpc_path, O_RDWR | O_SYNC);
425 if (fd < 0) {
426 mctp_prwarn("LPC open (%s) failed", lpc_path);
427 return -1;
428 }
429
430 rc = ioctl(fd, ASPEED_LPC_CTRL_IOCTL_GET_SIZE, &map);
431 if (rc) {
432 mctp_prwarn("LPC GET_SIZE failed");
433 close(fd);
434 return -1;
435 }
436
437 astlpc->lpc_map_base = mmap(NULL, map.size, PROT_READ | PROT_WRITE,
438 MAP_SHARED, fd, 0);
439 if (astlpc->lpc_map_base == MAP_FAILED) {
440 mctp_prwarn("LPC mmap failed");
441 rc = -1;
442 } else {
443 astlpc->lpc_map = astlpc->lpc_map_base +
444 map.size - LPC_WIN_SIZE;
445 }
446
447 close(fd);
448
449 return rc;
450}
451
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530452static int mctp_astlpc_init_fileio_kcs(struct mctp_binding_astlpc *astlpc)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800453{
454 astlpc->kcs_fd = open(kcs_path, O_RDWR);
455 if (astlpc->kcs_fd < 0)
456 return -1;
457
458 return 0;
459}
460
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530461static int __mctp_astlpc_fileio_kcs_read(void *arg,
462 enum mctp_binding_astlpc_kcs_reg reg, uint8_t *val)
463{
464 struct mctp_binding_astlpc *astlpc = arg;
465 off_t offset = reg;
466 int rc;
467
468 rc = pread(astlpc->kcs_fd, val, 1, offset);
469
470 return rc == 1 ? 0 : -1;
471}
472
473static int __mctp_astlpc_fileio_kcs_write(void *arg,
474 enum mctp_binding_astlpc_kcs_reg reg, uint8_t val)
475{
476 struct mctp_binding_astlpc *astlpc = arg;
477 off_t offset = reg;
478 int rc;
479
480 rc = pwrite(astlpc->kcs_fd, &val, 1, offset);
481
482 return rc == 1 ? 0 : -1;
483}
484
485int mctp_astlpc_get_fd(struct mctp_binding_astlpc *astlpc)
486{
487 return astlpc->kcs_fd;
488}
489
490struct mctp_binding_astlpc *mctp_astlpc_init_fileio(void)
Jeremy Kerr672c8852019-03-01 12:18:07 +0800491{
492 struct mctp_binding_astlpc *astlpc;
493 int rc;
494
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530495 astlpc = __mctp_astlpc_init();
496 if (!astlpc)
497 return NULL;
Jeremy Kerr672c8852019-03-01 12:18:07 +0800498
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530499 /* Set internal operations for kcs. We use direct accesses to the lpc
500 * map area */
501 astlpc->ops.kcs_read = __mctp_astlpc_fileio_kcs_read;
502 astlpc->ops.kcs_write = __mctp_astlpc_fileio_kcs_write;
503 astlpc->ops_data = astlpc;
504
505 rc = mctp_astlpc_init_fileio_lpc(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800506 if (rc) {
507 free(astlpc);
508 return NULL;
509 }
510
Jeremy Kerrbc53d352019-08-28 14:26:14 +0530511 rc = mctp_astlpc_init_fileio_kcs(astlpc);
Jeremy Kerr672c8852019-03-01 12:18:07 +0800512 if (rc) {
513 free(astlpc);
514 return NULL;
515 }
516
Jeremy Kerr672c8852019-03-01 12:18:07 +0800517 return astlpc;
518}
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530519#else
520struct mctp_binding_astlpc * __attribute__((const))
521 mctp_astlpc_init_fileio(void)
522{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030523 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530524 return NULL;
525}
Jeremy Kerr672c8852019-03-01 12:18:07 +0800526
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530527int __attribute__((const)) mctp_astlpc_get_fd(
528 struct mctp_binding_astlpc *astlpc __attribute__((unused)))
529{
Andrew Jeffery09e07492020-03-17 22:57:55 +1030530 mctp_prerr("Missing support for file IO");
Jeremy Kerr92a10a62019-08-28 16:55:54 +0530531 return -1;
532}
533#endif