Velocity Userspace
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 
59 void 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 
94 int 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 
131 ssize_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 
gas_mrpc_write
Definition: gas_mrpc.h:33
gas_mrpc_memcpy_from_gas
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
switchtec.h
Main Switchtec header.
gas_mrpc_read
Definition: gas_mrpc.h:39
gas_mrpc_write_from_gas
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
gas_mrpc_memcpy_to_gas
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
switchtec_cmd
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