Switchtec Userspace PROJECT_NUMBER = 3.1
gas_mrpc.c
1/*
2 * Microsemi Switchtec(tm) PCIe Management Library
3 * Copyright (c) 2017, Microsemi Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#include "switchtec/gas_mrpc.h"
26#include "switchtec/switchtec.h"
27#include "switchtec_priv.h"
28
29#include <string.h>
30#include <signal.h>
31#include <unistd.h>
32
33#define GAS_MRPC_MEMCPY_MAX 512
34
59void gas_mrpc_memcpy_to_gas(struct switchtec_dev *dev, void __gas *dest,
60 const void *src, size_t n)
61{
62 struct gas_mrpc_write cmd;
63 int ret;
64 uint32_t len;
65 uint32_t offset = (uint32_t)(dest - (void __gas *)dev->gas_map);
66
67 while (n) {
68 len = n;
69 if (len > sizeof(cmd.data))
70 len = sizeof(cmd.data);
71 cmd.len = htole32(len);
72 cmd.gas_offset = htole32(offset);
73 memcpy(&cmd.data, src, len);
74
75 ret = switchtec_cmd(dev, MRPC_GAS_WRITE, &cmd,
76 len + sizeof(cmd) - sizeof(cmd.data),
77 NULL, 0);
78 if (ret)
79 raise(SIGBUS);
80
81 n -= len;
82 offset += len;
83 }
84}
85
94int gas_mrpc_memcpy_from_gas(struct switchtec_dev *dev, void *dest,
95 const void __gas *src, size_t n)
96{
97 struct gas_mrpc_read cmd;
98 int ret;
99 uint32_t len;
100
101 cmd.gas_offset = htole32((uint32_t)(src - (void __gas *)dev->gas_map));
102
103 while (n) {
104 len = n;
105 if (len > GAS_MRPC_MEMCPY_MAX)
106 len = GAS_MRPC_MEMCPY_MAX;
107 cmd.len = htole32(len);
108
109 ret = switchtec_cmd(dev, MRPC_GAS_READ, &cmd,
110 sizeof(cmd), dest, len);
111 if (ret) {
112 memset(dest, 0xff, n);
113 return ret;
114 }
115
116 n -= len;
117 dest += len;
118 cmd.gas_offset += len;
119 }
120
121 return 0;
122}
123
131ssize_t gas_mrpc_write_from_gas(struct switchtec_dev *dev, int fd,
132 const void __gas *src, size_t n)
133{
134 char buf[MRPC_MAX_DATA_LEN];
135 ssize_t ret, total = 0;
136 size_t txfr_sz;
137
138 while (n) {
139 txfr_sz = n;
140 if (txfr_sz > sizeof(buf))
141 txfr_sz = sizeof(buf);
142
143 gas_mrpc_memcpy_from_gas(dev, buf, src, txfr_sz);
144
145 ret = write(fd, buf, txfr_sz);
146 if (ret < 0)
147 return ret;
148
149 n -= ret;
150 src += ret;
151 total += ret;
152 }
153
154 return total;
155}
156
int switchtec_cmd(struct switchtec_dev *dev, uint32_t cmd, const void *payload, size_t payload_len, void *resp, size_t resp_len)
Execute an MRPC command.
Definition: platform.c:164
void gas_mrpc_memcpy_to_gas(struct switchtec_dev *dev, void __gas *dest, const void *src, size_t n)
Copy data to the GAS using MRPC commands.
Definition: gas_mrpc.c:59
int gas_mrpc_memcpy_from_gas(struct switchtec_dev *dev, void *dest, const void __gas *src, size_t n)
Copy data from the GAS using MRPC commands.
Definition: gas_mrpc.c:94
ssize_t gas_mrpc_write_from_gas(struct switchtec_dev *dev, int fd, const void __gas *src, size_t n)
Call write() with data from the GAS using an MRPC command.
Definition: gas_mrpc.c:131
Main Switchtec header.