Switchtec Userspace  PROJECT_NUMBER = PROJECT_NUMBER=PROJECT_NUMBER = 2.2
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 
57 void gas_mrpc_memcpy_to_gas(struct switchtec_dev *dev, void __gas *dest,
58  const void *src, size_t n)
59 {
60  struct gas_mrpc_write cmd;
61  int ret;
62 
63  cmd.gas_offset = (uint32_t)(dest - (void __gas *)dev->gas_map);
64 
65  while (n) {
66  cmd.len = n;
67  if (cmd.len > sizeof(cmd.data))
68  cmd.len = sizeof(cmd.data);
69 
70  memcpy(&cmd.data, src, cmd.len);
71 
72  ret = switchtec_cmd(dev, MRPC_GAS_WRITE, &cmd,
73  cmd.len + sizeof(cmd) - sizeof(cmd.data),
74  NULL, 0);
75  if (ret)
76  raise(SIGBUS);
77 
78  n -= cmd.len;
79  cmd.gas_offset += cmd.len;
80  }
81 }
82 
90 void gas_mrpc_memcpy_from_gas(struct switchtec_dev *dev, void *dest,
91  const void __gas *src, size_t n)
92 {
93  struct gas_mrpc_read cmd;
94  int ret;
95 
96  cmd.gas_offset = (uint32_t)(src - (void __gas *)dev->gas_map);
97 
98  while (n) {
99  cmd.len = n;
100  if (cmd.len > MRPC_MAX_DATA_LEN)
101  cmd.len = MRPC_MAX_DATA_LEN;
102 
103  ret = switchtec_cmd(dev, MRPC_GAS_READ, &cmd,
104  sizeof(cmd), dest, cmd.len);
105  if (ret)
106  raise(SIGBUS);
107 
108  n -= cmd.len;
109  dest += cmd.len;
110  }
111 }
112 
120 ssize_t gas_mrpc_write_from_gas(struct switchtec_dev *dev, int fd,
121  const void __gas *src, size_t n)
122 {
123  char buf[MRPC_MAX_DATA_LEN];
124  ssize_t ret, total = 0;
125  size_t txfr_sz;
126 
127  while (n) {
128  txfr_sz = n;
129  if (txfr_sz > sizeof(buf))
130  txfr_sz = sizeof(buf);
131 
132  gas_mrpc_memcpy_from_gas(dev, buf, src, txfr_sz);
133 
134  ret = write(fd, buf, txfr_sz);
135  if (ret < 0)
136  return ret;
137 
138  n -= ret;
139  src += ret;
140  total += ret;
141  }
142 
143  return total;
144 }
145 
void 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:90
Main Switchtec header.
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:120
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:57
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:132