4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1998-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/types.h>
34 #include <sys/sysmacros.h>
43 #include <sys/rsm/rsmndi.h>
44 #include <rsmlib_in.h>
45 #include <sys/rsm/rsm.h>
47 extern int _rsm_memseg_import_map(rsm_memseg_import_handle_t
,
53 extern int _rsm_memseg_import_unmap(rsm_memseg_import_handle_t
);
55 static rsm_ndlib_attr_t _rsm_loopback_attr
= {
56 B_TRUE
, /* mapping needed for put/get */
57 B_TRUE
/* mapping needed for putv/getv */
61 loopback_get8(rsm_memseg_import_handle_t im_memseg
, off_t off
,
66 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
68 (uint8_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
74 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
75 "loopback_get8: enter\n"));
77 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
78 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
79 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
80 if (e
!= RSM_SUCCESS
) {
85 for (i
= 0; i
< rep_cnt
; i
++) {
86 datap
[i
] = data_addr
[i
];
89 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
90 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
91 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
92 if (e
!= RSM_SUCCESS
) {
97 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
98 "loopback_get8: exit\n"));
100 return (RSM_SUCCESS
);
104 loopback_get16(rsm_memseg_import_handle_t im_memseg
, off_t off
,
109 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
110 uint16_t *data_addr
=
112 (uint16_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
118 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
119 "loopback_get16: enter\n"));
121 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
122 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
123 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
124 if (e
!= RSM_SUCCESS
) {
129 for (i
= 0; i
< rep_cnt
; i
++) {
130 datap
[i
] = data_addr
[i
];
133 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
134 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
135 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
136 if (e
!= RSM_SUCCESS
) {
141 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
142 "loopback_get16: exit\n"));
144 return (RSM_SUCCESS
);
148 loopback_get32(rsm_memseg_import_handle_t im_memseg
, off_t off
,
153 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
154 uint32_t *data_addr
=
156 (uint32_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
162 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
163 "loopback_get32: enter\n"));
165 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
166 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
167 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
168 if (e
!= RSM_SUCCESS
) {
173 for (i
= 0; i
< rep_cnt
; i
++) {
174 datap
[i
] = data_addr
[i
];
177 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
178 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
179 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
180 if (e
!= RSM_SUCCESS
) {
185 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
186 "loopback_get32: exit\n"));
188 return (RSM_SUCCESS
);
192 loopback_get64(rsm_memseg_import_handle_t im_memseg
, off_t off
,
197 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
198 uint64_t *data_addr
=
200 (uint64_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
206 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
207 "loopback_get64: enter\n"));
209 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
210 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
211 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
212 if (e
!= RSM_SUCCESS
) {
217 for (i
= 0; i
< rep_cnt
; i
++) {
218 datap
[i
] = data_addr
[i
];
221 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
222 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
223 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
224 if (e
!= RSM_SUCCESS
) {
229 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
230 "loopback_get64: exit\n"));
232 return (RSM_SUCCESS
);
236 loopback_put8(rsm_memseg_import_handle_t im_memseg
, off_t off
,
241 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
243 (uint8_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
249 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
250 "loopback_put8: enter\n"));
252 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
253 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
254 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
255 if (e
!= RSM_SUCCESS
) {
260 for (i
= 0; i
< rep_cnt
; i
++) {
261 data_addr
[i
] = datap
[i
];
264 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
265 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
266 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
267 if (e
!= RSM_SUCCESS
) {
272 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
273 "loopback_put8: exit\n"));
275 return (RSM_SUCCESS
);
279 loopback_put16(rsm_memseg_import_handle_t im_memseg
, off_t off
,
284 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
285 uint16_t *data_addr
=
287 (uint16_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
293 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
294 "loopback_put16: enter\n"));
296 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
297 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
298 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
299 if (e
!= RSM_SUCCESS
) {
304 for (i
= 0; i
< rep_cnt
; i
++) {
305 data_addr
[i
] = datap
[i
];
308 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
309 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
310 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
311 if (e
!= RSM_SUCCESS
) {
316 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
317 "loopback_put16: exit\n"));
319 return (RSM_SUCCESS
);
323 loopback_put32(rsm_memseg_import_handle_t im_memseg
, off_t off
,
328 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
329 uint32_t *data_addr
=
331 (uint32_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
337 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
338 "loopback_put32: enter\n"));
340 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
341 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
342 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
343 if (e
!= RSM_SUCCESS
) {
348 for (i
= 0; i
< rep_cnt
; i
++) {
349 data_addr
[i
] = datap
[i
];
352 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
353 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
354 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
355 if (e
!= RSM_SUCCESS
) {
360 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
361 "loopback_put32: exit\n"));
363 return (RSM_SUCCESS
);
367 loopback_put64(rsm_memseg_import_handle_t im_memseg
, off_t off
,
372 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
373 uint64_t *data_addr
=
375 (uint64_t *)&seg
->rsmseg_vaddr
[off
- seg
->rsmseg_mapoffset
];
381 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
382 "loopback_put64: enter\n"));
384 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
385 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
386 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
387 if (e
!= RSM_SUCCESS
) {
392 for (i
= 0; i
< rep_cnt
; i
++) {
393 data_addr
[i
] = datap
[i
];
396 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
397 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
398 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
399 if (e
!= RSM_SUCCESS
) {
404 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
405 "loopback_put64: exit\n"));
407 return (RSM_SUCCESS
);
411 loopback_get(rsm_memseg_import_handle_t im_memseg
, off_t offset
, void *dst_addr
,
414 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
417 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
418 "loopback_get: enter\n"));
420 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
421 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
422 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
423 if (e
!= RSM_SUCCESS
) {
428 bcopy(seg
->rsmseg_vaddr
+ offset
- seg
->rsmseg_mapoffset
, dst_addr
,
431 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
432 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
433 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
434 if (e
!= RSM_SUCCESS
) {
439 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
440 "loopback_get: exit\n"));
442 return (RSM_SUCCESS
);
447 * Move data to each component of the io vector from the remote segment
450 loopback_getv(rsm_scat_gath_t
*sg_io
)
452 rsm_iovec_t
*iovec
= sg_io
->iovec
;
453 rsmseg_handle_t
*im_seg
= (rsmseg_handle_t
*)sg_io
->remote_handle
;
456 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
457 "loopback_getv: enter\n"));
459 /* do the vector data transfer */
460 for (i
= 0; i
< sg_io
->io_request_count
; i
++) {
461 (void) bcopy(im_seg
->rsmseg_vaddr
+ iovec
->remote_offset
,
462 iovec
->local
.vaddr
+ iovec
->local_offset
,
463 iovec
->transfer_length
);
467 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
468 "loopback_getv: exit\n"));
470 sg_io
->io_residual_count
= 0;
472 return (RSM_SUCCESS
);
476 loopback_put(rsm_memseg_import_handle_t im_memseg
, off_t offset
, void *src_addr
,
479 rsmseg_handle_t
*seg
= (rsmseg_handle_t
*)im_memseg
;
482 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
483 "loopback_put: enter\n"));
485 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
486 e
= seg
->rsmseg_ops
->rsm_memseg_import_open_barrier(
487 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
488 if (e
!= RSM_SUCCESS
) {
493 bcopy(src_addr
, seg
->rsmseg_vaddr
+ offset
- seg
->rsmseg_mapoffset
,
496 if (seg
->rsmseg_barmode
== RSM_BARRIER_MODE_IMPLICIT
) {
497 e
= seg
->rsmseg_ops
->rsm_memseg_import_close_barrier(
498 (rsm_barrier_handle_t
)seg
->rsmseg_barrier
);
499 if (e
!= RSM_SUCCESS
) {
504 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
505 "loopback_put: exit\n"));
507 return (RSM_SUCCESS
);
512 * Move data from each component of the io vector to the remote segment
515 loopback_putv(rsm_scat_gath_t
*sg_io
)
517 rsm_iovec_t
*iovec
= sg_io
->iovec
;
518 rsmseg_handle_t
*im_seg
= (rsmseg_handle_t
*)sg_io
->remote_handle
;
521 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
522 "loopback_putv: enter\n"));
524 /* do the vector data transfer */
525 for (i
= 0; i
< sg_io
->io_request_count
; i
++) {
526 (void) bcopy(iovec
->local
.vaddr
+ iovec
->local_offset
,
527 im_seg
->rsmseg_vaddr
+ iovec
->remote_offset
,
528 iovec
->transfer_length
);
532 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
533 "loopback_putv: exit\n"));
535 sg_io
->io_residual_count
= 0;
537 return (RSM_SUCCESS
);
541 loopback_create_handle(rsmapi_controller_handle_t controller
,
542 rsm_localmemory_handle_t
*local_handle
,
543 caddr_t vaddr
, size_t len
)
546 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
547 "loopback_create_handle: enter\n"));
549 controller
= controller
;
552 *local_handle
= (rsm_localmemory_handle_t
)vaddr
;
554 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
555 "loopback_create_handle: exit\n"));
557 return (RSM_SUCCESS
);
561 loopback_free_handle(rsm_localmemory_handle_t handle
)
564 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
565 "loopback_free_handle: enter\n"));
569 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
570 "loopback_free_handle: exit\n"));
572 return (RSM_SUCCESS
);
577 * import side memory segment operations (barriers):
580 loopback_init_barrier(rsm_memseg_import_handle_t im_memseg
,
581 rsm_barrier_type_t type
,
582 rsm_barrier_handle_t barrier
)
585 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
586 "loopback_init_barrier: enter\n"));
588 type
= type
; im_memseg
= im_memseg
; barrier
= barrier
;
590 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
591 "loopback_init_barrier: exit\n"));
593 return (RSM_SUCCESS
);
597 loopback_open_barrier(rsm_barrier_handle_t barrier
)
600 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
601 "loopback_open_barrier: enter\n"));
605 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
606 "loopback_open_barrier: exit\n"));
608 return (RSM_SUCCESS
);
612 loopback_order_barrier(rsm_barrier_handle_t barrier
)
615 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
616 "loopback_order_barrier: enter\n"));
620 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
621 "loopback_order_barrier: exit\n"));
623 return (RSM_SUCCESS
);
627 loopback_close_barrier(rsm_barrier_handle_t barrier
)
630 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
631 "loopback_close_barrier: enter\n"));
635 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
636 "loopback_close_barrier: exit\n"));
638 return (RSM_SUCCESS
);
642 loopback_destroy_barrier(rsm_barrier_handle_t barrier
)
645 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
646 "loopback_destroy_barrier: enter\n"));
650 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
651 "loopback_destroy_barrier: exit\n"));
653 return (RSM_SUCCESS
);
657 loopback_get_lib_attr(rsm_ndlib_attr_t
**libattrp
)
660 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
661 "loopback_get_lib_attr: enter\n"));
663 *libattrp
= &_rsm_loopback_attr
;
665 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
666 "loopback_get_lib_attr: exit\n"));
668 return (RSM_SUCCESS
);
671 * If an entry is NULL, the parent will fill it out with its entry point.
674 __rsmloopback_init_ops(rsm_segops_t
*segops
)
677 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
678 "__rsmloopback_init_ops: enter\n"));
680 segops
->rsm_memseg_import_get8
= loopback_get8
;
681 segops
->rsm_memseg_import_get16
= loopback_get16
;
682 segops
->rsm_memseg_import_get32
= loopback_get32
;
683 segops
->rsm_memseg_import_get64
= loopback_get64
;
685 segops
->rsm_memseg_import_put8
= loopback_put8
;
686 segops
->rsm_memseg_import_put16
= loopback_put16
;
687 segops
->rsm_memseg_import_put32
= loopback_put32
;
688 segops
->rsm_memseg_import_put64
= loopback_put64
;
690 segops
->rsm_memseg_import_put
= loopback_put
;
691 segops
->rsm_memseg_import_get
= loopback_get
;
693 segops
->rsm_memseg_import_putv
= loopback_putv
;
694 segops
->rsm_memseg_import_getv
= loopback_getv
;
696 segops
->rsm_create_localmemory_handle
= loopback_create_handle
;
697 segops
->rsm_free_localmemory_handle
= loopback_free_handle
;
699 segops
->rsm_memseg_import_init_barrier
= loopback_init_barrier
;
700 segops
->rsm_memseg_import_open_barrier
= loopback_open_barrier
;
701 segops
->rsm_memseg_import_order_barrier
= loopback_order_barrier
;
702 segops
->rsm_memseg_import_close_barrier
= loopback_close_barrier
;
703 segops
->rsm_memseg_import_destroy_barrier
= loopback_destroy_barrier
;
705 segops
->rsm_get_lib_attr
= loopback_get_lib_attr
;
707 DBPRINTF((RSM_LIBRARY
|RSM_LOOPBACK
, RSM_DEBUG_VERBOSE
,
708 "__rsmloopback_init_ops: exit\n"));