/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1998-2001 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern int _rsm_memseg_import_map(rsm_memseg_import_handle_t, void **, rsm_attribute_t, rsm_permission_t, off_t, size_t); extern int _rsm_memseg_import_unmap(rsm_memseg_import_handle_t); static rsm_ndlib_attr_t _rsm_loopback_attr = { B_TRUE, /* mapping needed for put/get */ B_TRUE /* mapping needed for putv/getv */ }; static int loopback_get8(rsm_memseg_import_handle_t im_memseg, off_t off, uint8_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint8_t *data_addr = (uint8_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get8: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { datap[i] = data_addr[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get8: exit\n")); return (RSM_SUCCESS); } static int loopback_get16(rsm_memseg_import_handle_t im_memseg, off_t off, uint16_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint16_t *data_addr = /* LINTED */ (uint16_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get16: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { datap[i] = data_addr[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get16: exit\n")); return (RSM_SUCCESS); } static int loopback_get32(rsm_memseg_import_handle_t im_memseg, off_t off, uint32_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint32_t *data_addr = /* LINTED */ (uint32_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get32: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { datap[i] = data_addr[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get32: exit\n")); return (RSM_SUCCESS); } static int loopback_get64(rsm_memseg_import_handle_t im_memseg, off_t off, uint64_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint64_t *data_addr = /* LINTED */ (uint64_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get64: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { datap[i] = data_addr[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get64: exit\n")); return (RSM_SUCCESS); } static int loopback_put8(rsm_memseg_import_handle_t im_memseg, off_t off, uint8_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint8_t *data_addr = (uint8_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put8: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { data_addr[i] = datap[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put8: exit\n")); return (RSM_SUCCESS); } static int loopback_put16(rsm_memseg_import_handle_t im_memseg, off_t off, uint16_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint16_t *data_addr = /* LINTED */ (uint16_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put16: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { data_addr[i] = datap[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put16: exit\n")); return (RSM_SUCCESS); } static int loopback_put32(rsm_memseg_import_handle_t im_memseg, off_t off, uint32_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint32_t *data_addr = /* LINTED */ (uint32_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put32: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { data_addr[i] = datap[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put32: exit\n")); return (RSM_SUCCESS); } static int loopback_put64(rsm_memseg_import_handle_t im_memseg, off_t off, uint64_t *datap, ulong_t rep_cnt, boolean_t swap) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; uint64_t *data_addr = /* LINTED */ (uint64_t *)&seg->rsmseg_vaddr[off - seg->rsmseg_mapoffset]; uint_t i = 0; int e; swap = swap; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put64: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } for (i = 0; i < rep_cnt; i++) { data_addr[i] = datap[i]; } if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put64: exit\n")); return (RSM_SUCCESS); } static int loopback_get(rsm_memseg_import_handle_t im_memseg, off_t offset, void *dst_addr, size_t length) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; int e; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } bcopy(seg->rsmseg_vaddr + offset - seg->rsmseg_mapoffset, dst_addr, length); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get: exit\n")); return (RSM_SUCCESS); } /* * Move data to each component of the io vector from the remote segment */ int loopback_getv(rsm_scat_gath_t *sg_io) { rsm_iovec_t *iovec = sg_io->iovec; rsmseg_handle_t *im_seg = (rsmseg_handle_t *)sg_io->remote_handle; int i; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_getv: enter\n")); /* do the vector data transfer */ for (i = 0; i < sg_io->io_request_count; i++) { (void) bcopy(im_seg->rsmseg_vaddr + iovec->remote_offset, iovec->local.vaddr + iovec->local_offset, iovec->transfer_length); iovec++; } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_getv: exit\n")); sg_io->io_residual_count = 0; return (RSM_SUCCESS); } static int loopback_put(rsm_memseg_import_handle_t im_memseg, off_t offset, void *src_addr, size_t length) { rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; int e; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put: enter\n")); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_open_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } bcopy(src_addr, seg->rsmseg_vaddr + offset - seg->rsmseg_mapoffset, length); if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { e = seg->rsmseg_ops->rsm_memseg_import_close_barrier( (rsm_barrier_handle_t)seg->rsmseg_barrier); if (e != RSM_SUCCESS) { return (e); } } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_put: exit\n")); return (RSM_SUCCESS); } /* * Move data from each component of the io vector to the remote segment */ int loopback_putv(rsm_scat_gath_t *sg_io) { rsm_iovec_t *iovec = sg_io->iovec; rsmseg_handle_t *im_seg = (rsmseg_handle_t *)sg_io->remote_handle; int i; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_putv: enter\n")); /* do the vector data transfer */ for (i = 0; i < sg_io->io_request_count; i++) { (void) bcopy(iovec->local.vaddr + iovec->local_offset, im_seg->rsmseg_vaddr + iovec->remote_offset, iovec->transfer_length); iovec++; } DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_putv: exit\n")); sg_io->io_residual_count = 0; return (RSM_SUCCESS); } static int loopback_create_handle(rsmapi_controller_handle_t controller, rsm_localmemory_handle_t *local_handle, caddr_t vaddr, size_t len) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_create_handle: enter\n")); controller = controller; len = len; *local_handle = (rsm_localmemory_handle_t)vaddr; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_create_handle: exit\n")); return (RSM_SUCCESS); } static int loopback_free_handle(rsm_localmemory_handle_t handle) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_free_handle: enter\n")); handle = handle; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_free_handle: exit\n")); return (RSM_SUCCESS); } /* * import side memory segment operations (barriers): */ static int loopback_init_barrier(rsm_memseg_import_handle_t im_memseg, rsm_barrier_type_t type, rsm_barrier_handle_t barrier) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_init_barrier: enter\n")); type = type; im_memseg = im_memseg; barrier = barrier; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_init_barrier: exit\n")); return (RSM_SUCCESS); } static int loopback_open_barrier(rsm_barrier_handle_t barrier) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_open_barrier: enter\n")); barrier = barrier; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_open_barrier: exit\n")); return (RSM_SUCCESS); } static int loopback_order_barrier(rsm_barrier_handle_t barrier) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_order_barrier: enter\n")); barrier = barrier; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_order_barrier: exit\n")); return (RSM_SUCCESS); } static int loopback_close_barrier(rsm_barrier_handle_t barrier) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_close_barrier: enter\n")); barrier = barrier; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_close_barrier: exit\n")); return (RSM_SUCCESS); } static int loopback_destroy_barrier(rsm_barrier_handle_t barrier) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_destroy_barrier: enter\n")); barrier = barrier; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_destroy_barrier: exit\n")); return (RSM_SUCCESS); } static int loopback_get_lib_attr(rsm_ndlib_attr_t **libattrp) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get_lib_attr: enter\n")); *libattrp = &_rsm_loopback_attr; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "loopback_get_lib_attr: exit\n")); return (RSM_SUCCESS); } /* * If an entry is NULL, the parent will fill it out with its entry point. */ void __rsmloopback_init_ops(rsm_segops_t *segops) { DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "__rsmloopback_init_ops: enter\n")); segops->rsm_memseg_import_get8 = loopback_get8; segops->rsm_memseg_import_get16 = loopback_get16; segops->rsm_memseg_import_get32 = loopback_get32; segops->rsm_memseg_import_get64 = loopback_get64; segops->rsm_memseg_import_put8 = loopback_put8; segops->rsm_memseg_import_put16 = loopback_put16; segops->rsm_memseg_import_put32 = loopback_put32; segops->rsm_memseg_import_put64 = loopback_put64; segops->rsm_memseg_import_put = loopback_put; segops->rsm_memseg_import_get = loopback_get; segops->rsm_memseg_import_putv = loopback_putv; segops->rsm_memseg_import_getv = loopback_getv; segops->rsm_create_localmemory_handle = loopback_create_handle; segops->rsm_free_localmemory_handle = loopback_free_handle; segops->rsm_memseg_import_init_barrier = loopback_init_barrier; segops->rsm_memseg_import_open_barrier = loopback_open_barrier; segops->rsm_memseg_import_order_barrier = loopback_order_barrier; segops->rsm_memseg_import_close_barrier = loopback_close_barrier; segops->rsm_memseg_import_destroy_barrier = loopback_destroy_barrier; segops->rsm_get_lib_attr = loopback_get_lib_attr; DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, "__rsmloopback_init_ops: exit\n")); }