No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / iscsi / dist / src / lib / osd_ops.c
blob696203b7ca805a023340bcd8e7a90796bef62723
1 /*
2 * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By downloading, copying, installing or
3 * using the software you agree to this license. If you do not agree to this license, do not download, install,
4 * copy or use the software.
6 * Intel License Agreement
8 * Copyright (c) 2002, Intel Corporation
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
12 * the following conditions are met:
14 * -Redistributions of source code must retain the above copyright notice, this list of conditions and the
15 * following disclaimer.
17 * -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
18 * following disclaimer in the documentation and/or other materials provided with the distribution.
20 * -The name of Intel Corporation may not be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Transport-independent Methods
36 #include "config.h"
39 #include "osd.h"
40 #include "iscsiutil.h"
41 #include "compat.h"
42 #include "osd_ops.h"
44 #ifdef HAVE_NETINET_IN_H
45 #include <netinet/in.h>
46 #endif
48 static int
49 extract_attribute(uint32_t page, uint32_t n, uint16_t len,
50 uint8_t * data, unsigned length, void *val)
52 int i = 0;
54 for (i = 0; i < length;) {
55 if (ISCSI_NTOHL(*(uint32_t *) (data + i)) != page) {
56 iscsi_err(__FILE__, __LINE__, "page mismatch: got 0x%x, expected 0x%x\n", ISCSI_NTOHL(*(uint32_t *) (data + i)), page);
57 return -1;
59 i += 4;
60 if (ISCSI_NTOHL(*(uint32_t *) (data + i)) != n) {
61 iscsi_err(__FILE__, __LINE__, "index mismatch\n");
62 return -1;
64 i += 4;
65 if (ISCSI_NTOHS(*(uint16_t *) (data + i)) != len) {
66 iscsi_err(__FILE__, __LINE__, "len mismatch\n");
67 return -1;
69 i += 2;
70 iscsi_trace(TRACE_DEBUG, "page 0x%x, index %u, len %u\n", page, n, len);
71 memcpy(val, data + i, len);
72 i += len;
74 iscsi_trace(TRACE_DEBUG, "parsed %i bytes\n", i);
75 return i;
79 int
80 osd_create_group(void *dev,
81 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem),
82 uint32_t * GroupID)
84 osd_args_t args;
85 #if 0
86 uint8_t get_list[8];
87 #endif
88 uint8_t get_data[14];
89 OSD_OPS_MEM mem;
91 mem.recv_data = get_data;
92 mem.recv_len = 14;
93 mem.recv_sg = 0;
95 memset(&args, 0, sizeof(osd_args_t));
96 args.opcode = 0x7F;
97 args.service_action = OSD_CREATE_GROUP;
99 #if 0
100 args.length = 8;
101 args.get_attributes_list_length = 8;
102 *((unsigned long *) get_list) = ISCSI_HTONL(0x40000001);
103 *((unsigned long *) (get_list + 4)) = ISCSI_HTONL(0x1);
104 mem.send_data = get_list;
105 mem.send_len = 8;
106 mem.send_sg = 0;
107 #else
108 args.get_attributes_page = 0x40000001;
109 mem.send_data = NULL;
110 mem.send_len = 0;
111 mem.send_sg = 0;
112 #endif
114 args.get_attributes_allocation_length = 14;
115 if (osd_exec(dev, &args, &mem) != 0) {
116 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
117 return -1;
119 if (extract_attribute(0x40000001, 0x1, 4, get_data, 14, GroupID) == -1) {
120 iscsi_err(__FILE__, __LINE__, "extract_attributes() failed\n");
121 return -1;
123 *GroupID = ISCSI_NTOHL(*GroupID);
124 iscsi_trace(TRACE_OSD, "osd_create_group() OK --> GroupID 0x%x\n", *GroupID);
126 return 0;
129 int
130 osd_create(void *dev, uint32_t GroupID,
131 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem),
132 uint64_t * UserID)
134 osd_args_t args;
135 #if 0
136 uint8_t get_list[8];
137 #endif
138 uint8_t get_data[18];
139 OSD_OPS_MEM mem;
141 mem.recv_data = get_data;
142 mem.recv_len = 18;
143 mem.recv_sg = 0;
145 memset(&args, 0, sizeof(osd_args_t));
146 args.opcode = 0x7F;
147 args.service_action = OSD_CREATE;
148 args.GroupID = GroupID;
150 #if 0
151 args.length = 8;
152 args.get_attributes_list_length = 8;
153 *((unsigned long *) get_list) = ISCSI_HTONL(0x00000001);
154 *((unsigned long *) (get_list + 4)) = ISCSI_HTONL(0x2);
155 mem.send_data = get_list;
156 mem.send_len = 8;
157 mem.send_sg = 0;
158 #else
159 args.get_attributes_page = 0x000000001;
160 mem.send_data = NULL;
161 mem.send_len = 0;
162 mem.send_sg = 0;
163 #endif
165 args.get_attributes_allocation_length = 18;
166 if (osd_exec(dev, &args, &mem) != 0) {
167 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
168 return -1;
170 if (extract_attribute(0x00000001, 0x2, 8, get_data, 18, UserID) == -1) {
171 iscsi_err(__FILE__, __LINE__, "extract_attributes() failed\n");
172 return -1;
174 *UserID = ISCSI_NTOHLL(*UserID);
175 iscsi_trace(TRACE_OSD, "osd_create(GroupID 0x%x) OK --> UserID 0x%llx\n", GroupID, *UserID);
177 return 0;
180 int
181 osd_remove_group(void *dev, uint32_t GroupID,
182 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
184 osd_args_t args;
185 OSD_OPS_MEM mem;
187 mem.send_data = NULL;
188 mem.send_len = 0;
189 mem.send_sg = 0;
190 mem.recv_data = NULL;
191 mem.recv_len = 0;
192 mem.recv_sg = 0;
194 memset(&args, 0, sizeof(osd_args_t));
195 args.opcode = 0x7F;
196 args.service_action = OSD_REMOVE_GROUP;
197 args.GroupID = GroupID;
198 if (osd_exec(dev, &args, &mem) != 0) {
199 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
200 return -1;
202 iscsi_trace(TRACE_OSD, "osd_remove_group(Group ID 0x%x) OK\n", GroupID);
204 return 0;
207 int
208 osd_remove(void *dev, uint32_t GroupID, uint64_t UserID,
209 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
211 osd_args_t args;
212 OSD_OPS_MEM mem;
214 mem.send_data = NULL;
215 mem.send_len = 0;
216 mem.send_sg = 0;
217 mem.recv_data = NULL;
218 mem.recv_len = 0;
219 mem.recv_sg = 0;
221 memset(&args, 0, sizeof(osd_args_t));
222 args.opcode = 0x7F;
223 args.service_action = OSD_REMOVE;
224 args.UserID = UserID;
225 args.GroupID = GroupID;
226 if (osd_exec(dev, &args, &mem) != 0) {
227 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
228 return -1;
230 iscsi_trace(TRACE_OSD, "osd_remove(GroupID 0x%x, UserID 0x%llx) OK\n", GroupID, UserID);
232 return 0;
235 int
236 osd_write(void *dev,
237 uint32_t GroupID, uint64_t UserID, uint64_t offset, uint64_t len, const void *send_data, int sg_len,
238 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
240 osd_args_t args;
241 OSD_OPS_MEM mem;
243 iscsi_trace(TRACE_OSD, "osd_write(GroupID 0x%x, UserID 0x%llx, Offset %llu, Len %llu)\n", GroupID, UserID, offset, len);
244 mem.send_data = send_data;
245 mem.send_len = len;
246 mem.send_sg = sg_len;
247 mem.recv_data = NULL;
248 mem.recv_len = 0;
249 mem.recv_sg = 0;
250 memset(&args, 0, sizeof(osd_args_t));
251 args.opcode = 0x7F;
252 args.service_action = OSD_WRITE;
253 args.GroupID = GroupID;
254 args.UserID = UserID;
255 args.offset = offset;
256 args.length = len;
257 if (osd_exec(dev, &args, &mem) != 0) {
258 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
259 return -1;
261 return 0;
264 int
265 osd_read(void *dev,
266 uint32_t GroupID, uint64_t UserID, uint64_t offset, uint64_t len, void *recv_data, int sg_len,
267 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
269 osd_args_t args;
270 OSD_OPS_MEM mem;
272 iscsi_trace(TRACE_OSD, "osd_read(GroupID 0x%x, UserID 0x%llx, Offset %llu, Len %llu)\n", GroupID, UserID, offset, len);
273 mem.send_data = NULL;
274 mem.send_len = 0;
275 mem.send_sg = 0;
276 mem.recv_data = recv_data;
277 mem.recv_len = len;
278 mem.recv_sg = sg_len;
279 memset(&args, 0, sizeof(osd_args_t));
280 args.opcode = 0x7F;
281 args.service_action = OSD_READ;
282 args.GroupID = GroupID;
283 args.UserID = UserID;
284 args.offset = offset;
285 args.length = len;
286 if (osd_exec(dev, &args, &mem) != 0) {
287 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
288 return -1;
290 return 0;
293 int
294 osd_set_one_attr(void *dev,
295 uint32_t GroupID, uint64_t UserID, uint32_t page, uint32_t n, uint32_t len, void *value,
296 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem))
298 osd_args_t args;
299 OSD_OPS_MEM mem;
300 uint8_t list[10];
301 #if 0
302 struct iovec sg[2];
303 #else
304 uint8_t *buffer = NULL;
305 #endif
307 iscsi_trace(TRACE_OSD, "osd_set_one_attr(GroupID 0x%x, UserID 0x%llx, Page 0x%x, Index %u, Len %u)\n",
308 GroupID, UserID, page, n, len);
309 memset(&args, 0, sizeof(osd_args_t));
310 args.opcode = 0x7F;
311 args.service_action = OSD_SET_ATTR;
312 args.GroupID = GroupID;
313 args.UserID = UserID;
314 args.length = 10 + len;
315 args.set_attributes_list_length = 10 + len;
316 *((uint32_t *) (list + 0)) = ISCSI_HTONL(page);
317 *((uint32_t *) (list + 4)) = ISCSI_HTONL(n);
318 *((uint16_t *) (list + 8)) = ISCSI_HTONS(len);
319 #if 0
320 sg[0].iov_base = list;
321 sg[0].iov_len = 10;
322 sg[1].iov_base = value;
323 sg[1].iov_len = len;
324 mem.send_data = sg;
325 mem.send_len = 10 + len;
326 mem.send_sg = 2;
327 #else
328 if ((buffer = iscsi_malloc_atomic(10 + len)) == NULL) {
329 iscsi_err(__FILE__, __LINE__, "iscsi_malloc() failed\n");
330 return -1;
332 memcpy(buffer, list, 10);
333 memcpy(buffer + 10, value, len);
334 mem.send_data = buffer;
335 mem.send_len = 10 + len;
336 mem.send_sg = 0;
337 #endif
338 mem.recv_data = NULL;
339 mem.recv_len = 0;
340 mem.recv_sg = 0;
342 if (osd_exec(dev, &args, &mem) != 0) {
343 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
344 return -1;
346 if (buffer)
347 iscsi_free_atomic(buffer);
349 return 0;
352 int
353 osd_get_one_attr(void *dev,
354 uint32_t GroupID, uint64_t UserID, uint32_t page, uint32_t n, uint32_t alloc_len,
355 int (*osd_exec) (void *dev, osd_args_t * args, OSD_OPS_MEM * mem),
356 uint16_t * len, void *value)
358 osd_args_t args;
359 OSD_OPS_MEM mem;
360 uint8_t list_out[8];
361 #if 0
362 uint8_t list_in[10];
363 struct iovec sg[2];
364 #else
365 uint8_t *buffer;
366 #endif
368 iscsi_trace(TRACE_OSD, "osd_get_one_attr(GroupID 0x%x, UserID 0x%llx, Page 0x%x, Index %u, Alloc Len %u)\n",
369 GroupID, UserID, page, n, alloc_len);
370 memset(&args, 0, sizeof(osd_args_t));
371 args.opcode = 0x7F;
372 args.service_action = OSD_GET_ATTR;
373 args.GroupID = GroupID;
374 args.UserID = UserID;
375 if (n) {
376 args.length = 8;
377 *((uint32_t *) (list_out + 0)) = ISCSI_HTONL(page);
378 *((uint32_t *) (list_out + 4)) = ISCSI_HTONL(n);
379 args.get_attributes_list_length = 8;
380 mem.send_data = list_out;
381 mem.send_len = 8;
382 mem.send_sg = 0;
383 } else {
384 iscsi_trace(TRACE_OSD, "requesting entire page or reference page\n");
385 mem.send_data = NULL;
386 mem.send_len = 0;
387 mem.send_sg = 0;
388 args.get_attributes_page = page;
390 #if 0
391 sg[0].iov_base = list_in;
392 sg[0].iov_len = 10;
393 sg[1].iov_base = value;
394 sg[1].iov_len = alloc_len;
395 mem.recv_data = sg;
396 mem.recv_len = 10 + alloc_len;
397 mem.recv_sg = 2;
398 #else
399 if ((buffer = iscsi_malloc_atomic(10 + alloc_len)) == NULL) {
400 iscsi_err(__FILE__, __LINE__, "iscsi_malloc() failed\n");
401 return -1;
403 mem.recv_data = buffer;
404 mem.recv_len = 10 + alloc_len;
405 mem.recv_sg = 0;
406 #endif
407 args.get_attributes_allocation_length = 10 + alloc_len;
408 if (osd_exec(dev, &args, &mem) != 0) {
409 iscsi_err(__FILE__, __LINE__, "osd_exec() failed\n");
410 return -1;
412 memcpy(value, buffer + 10, alloc_len);
413 if (buffer)
414 iscsi_free_atomic(buffer);
415 return 0;