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
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
40 #include "iscsiutil.h"
44 #ifdef HAVE_NETINET_IN_H
45 #include <netinet/in.h>
49 extract_attribute(uint32_t page
, uint32_t n
, uint16_t len
,
50 uint8_t * data
, unsigned length
, void *val
)
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
);
60 if (ISCSI_NTOHL(*(uint32_t *) (data
+ i
)) != n
) {
61 iscsi_err(__FILE__
, __LINE__
, "index mismatch\n");
65 if (ISCSI_NTOHS(*(uint16_t *) (data
+ i
)) != len
) {
66 iscsi_err(__FILE__
, __LINE__
, "len mismatch\n");
70 iscsi_trace(TRACE_DEBUG
, "page 0x%x, index %u, len %u\n", page
, n
, len
);
71 memcpy(val
, data
+ i
, len
);
74 iscsi_trace(TRACE_DEBUG
, "parsed %i bytes\n", i
);
80 osd_create_group(void *dev
,
81 int (*osd_exec
) (void *dev
, osd_args_t
* args
, OSD_OPS_MEM
* mem
),
91 mem
.recv_data
= get_data
;
95 memset(&args
, 0, sizeof(osd_args_t
));
97 args
.service_action
= OSD_CREATE_GROUP
;
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
;
108 args
.get_attributes_page
= 0x40000001;
109 mem
.send_data
= NULL
;
114 args
.get_attributes_allocation_length
= 14;
115 if (osd_exec(dev
, &args
, &mem
) != 0) {
116 iscsi_err(__FILE__
, __LINE__
, "osd_exec() failed\n");
119 if (extract_attribute(0x40000001, 0x1, 4, get_data
, 14, GroupID
) == -1) {
120 iscsi_err(__FILE__
, __LINE__
, "extract_attributes() failed\n");
123 *GroupID
= ISCSI_NTOHL(*GroupID
);
124 iscsi_trace(TRACE_OSD
, "osd_create_group() OK --> GroupID 0x%x\n", *GroupID
);
130 osd_create(void *dev
, uint32_t GroupID
,
131 int (*osd_exec
) (void *dev
, osd_args_t
* args
, OSD_OPS_MEM
* mem
),
138 uint8_t get_data
[18];
141 mem
.recv_data
= get_data
;
145 memset(&args
, 0, sizeof(osd_args_t
));
147 args
.service_action
= OSD_CREATE
;
148 args
.GroupID
= GroupID
;
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
;
159 args
.get_attributes_page
= 0x000000001;
160 mem
.send_data
= NULL
;
165 args
.get_attributes_allocation_length
= 18;
166 if (osd_exec(dev
, &args
, &mem
) != 0) {
167 iscsi_err(__FILE__
, __LINE__
, "osd_exec() failed\n");
170 if (extract_attribute(0x00000001, 0x2, 8, get_data
, 18, UserID
) == -1) {
171 iscsi_err(__FILE__
, __LINE__
, "extract_attributes() failed\n");
174 *UserID
= ISCSI_NTOHLL(*UserID
);
175 iscsi_trace(TRACE_OSD
, "osd_create(GroupID 0x%x) OK --> UserID 0x%llx\n", GroupID
, *UserID
);
181 osd_remove_group(void *dev
, uint32_t GroupID
,
182 int (*osd_exec
) (void *dev
, osd_args_t
* args
, OSD_OPS_MEM
* mem
))
187 mem
.send_data
= NULL
;
190 mem
.recv_data
= NULL
;
194 memset(&args
, 0, sizeof(osd_args_t
));
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");
202 iscsi_trace(TRACE_OSD
, "osd_remove_group(Group ID 0x%x) OK\n", GroupID
);
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
))
214 mem
.send_data
= NULL
;
217 mem
.recv_data
= NULL
;
221 memset(&args
, 0, sizeof(osd_args_t
));
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");
230 iscsi_trace(TRACE_OSD
, "osd_remove(GroupID 0x%x, UserID 0x%llx) OK\n", GroupID
, UserID
);
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
))
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
;
246 mem
.send_sg
= sg_len
;
247 mem
.recv_data
= NULL
;
250 memset(&args
, 0, sizeof(osd_args_t
));
252 args
.service_action
= OSD_WRITE
;
253 args
.GroupID
= GroupID
;
254 args
.UserID
= UserID
;
255 args
.offset
= offset
;
257 if (osd_exec(dev
, &args
, &mem
) != 0) {
258 iscsi_err(__FILE__
, __LINE__
, "osd_exec() failed\n");
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
))
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
;
276 mem
.recv_data
= recv_data
;
278 mem
.recv_sg
= sg_len
;
279 memset(&args
, 0, sizeof(osd_args_t
));
281 args
.service_action
= OSD_READ
;
282 args
.GroupID
= GroupID
;
283 args
.UserID
= UserID
;
284 args
.offset
= offset
;
286 if (osd_exec(dev
, &args
, &mem
) != 0) {
287 iscsi_err(__FILE__
, __LINE__
, "osd_exec() failed\n");
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
))
304 uint8_t *buffer
= NULL
;
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
));
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
);
320 sg
[0].iov_base
= list
;
322 sg
[1].iov_base
= value
;
325 mem
.send_len
= 10 + len
;
328 if ((buffer
= iscsi_malloc_atomic(10 + len
)) == NULL
) {
329 iscsi_err(__FILE__
, __LINE__
, "iscsi_malloc() failed\n");
332 memcpy(buffer
, list
, 10);
333 memcpy(buffer
+ 10, value
, len
);
334 mem
.send_data
= buffer
;
335 mem
.send_len
= 10 + len
;
338 mem
.recv_data
= NULL
;
342 if (osd_exec(dev
, &args
, &mem
) != 0) {
343 iscsi_err(__FILE__
, __LINE__
, "osd_exec() failed\n");
347 iscsi_free_atomic(buffer
);
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
)
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
));
372 args
.service_action
= OSD_GET_ATTR
;
373 args
.GroupID
= GroupID
;
374 args
.UserID
= UserID
;
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
;
384 iscsi_trace(TRACE_OSD
, "requesting entire page or reference page\n");
385 mem
.send_data
= NULL
;
388 args
.get_attributes_page
= page
;
391 sg
[0].iov_base
= list_in
;
393 sg
[1].iov_base
= value
;
394 sg
[1].iov_len
= alloc_len
;
396 mem
.recv_len
= 10 + alloc_len
;
399 if ((buffer
= iscsi_malloc_atomic(10 + alloc_len
)) == NULL
) {
400 iscsi_err(__FILE__
, __LINE__
, "iscsi_malloc() failed\n");
403 mem
.recv_data
= buffer
;
404 mem
.recv_len
= 10 + alloc_len
;
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");
412 memcpy(value
, buffer
+ 10, alloc_len
);
414 iscsi_free_atomic(buffer
);