03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/conf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/file.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/modctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunndi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi_impldefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/obpdefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cmn_err.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/debug.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sysmacros.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/autoconf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kmem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgsbbc_mailbox.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgfrutree.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgfru_priv.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sgfru_mbox.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This driver implements the ioctls for the serengeti frutree picl plugin
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and the serengeti fruaccess library. These are all private,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * platform-dependent interfaces.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Global Variables */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baesteveluint_t sgfru_debug = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Opaque state structure pointer */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void *sgfru_statep; /* sgfru soft state hook */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the maximum amount of time this driver is prepared to wait for the mailbox
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to reply before it decides to timeout.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint sgfru_mbox_wait = SGFRU_DEFAULT_MAX_MBOX_WAIT_TIME;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Module Variables */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Driver entry points. These are located in sgfru.c so as to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * not cause a warning for the sgfru adb macro.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct cb_ops sgfru_cb_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_open, /* open */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_close, /* close */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* strategy */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* print */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* dump */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* read */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* write */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_ioctl, /* ioctl */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* devmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* mmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* segmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nochpoll, /* poll */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_prop_op, /* cb_prop_op */
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL, /* streamtab */
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_NEW | D_MP /* Driver compatibility flag */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct dev_ops sgfru_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DEVO_REV, /* devo_rev, */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, /* refcnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_getinfo_1to1, /* info */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* identify */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* probe */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_attach, /* attach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_detach, /* detach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* reset */
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sgfru_cb_ops, /* driver operations */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (struct bus_ops *)0, /* bus operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Loadable module support. This is located in sgfru.c so as to
193974072f41a843678abf5f61979c748687e66bSherry Moore * pick up the 1.8 version of sgfru.c.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelextern struct mod_ops mod_driverops;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modldrv modldrv = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel &mod_driverops, /* Type of module. This one is a pseudo driver */
193974072f41a843678abf5f61979c748687e66bSherry Moore "FRU Driver",
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sgfru_ops, /* driver ops */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modlinkage modlinkage = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MODREV_1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void *)&modldrv,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Allocate the soft state info and add the module. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = ddi_soft_state_init(&sgfru_statep,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sgfru_soft_state_t), 1)) == 0 &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (error = mod_install(&modlinkage)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_fini(&sgfru_statep);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Remove the module and free the soft state info. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = mod_remove(&modlinkage)) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_fini(&sgfru_statep);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_info(struct modinfo *modinfop)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_info(&modlinkage, modinfop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_soft_state_t *softsp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_attach";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_ATTACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance = ddi_get_instance(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel error = ddi_soft_state_zalloc(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (error != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: cannot allocate fru state "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "for inst %d.", f, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp = ddi_get_soft_state(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (softsp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_free(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: could not get state "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "structure for inst %d.", f, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp->fru_dip = dip;
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp->fru_pdip = ddi_get_parent(softsp->fru_dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp->instance = instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel error = ddi_create_minor_node(dip, SGFRU_DRV_NAME, S_IFCHR,
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance, DDI_PSEUDO, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (error == DDI_FAILURE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_free(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_report_dev(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_RESUME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_soft_state_t *softsp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_detach";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance = ddi_get_instance(dip);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp = ddi_get_soft_state(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (softsp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: could not get state "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "structure for inst %d.", f, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_DETACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_soft_state_free(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(dip, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_SUSPEND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance = getminor(*dev_p);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_soft_state_t *softsp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_open";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((error = drv_priv(cred_p)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: inst %d drv_priv failed",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp = (sgfru_soft_state_t *)ddi_get_soft_state(sgfru_statep,
03831d35f7499c87d51205817c93e9a8d42c4baestevel instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (softsp == (sgfru_soft_state_t *)NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: inst %d ddi_get_soft_state failed",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENXIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (error);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance = getminor(dev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_soft_state_t *softsp = (sgfru_soft_state_t *)
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_get_soft_state(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (softsp == (sgfru_soft_state_t *)NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENXIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function disperses the ioctls from the serengeti libpiclfruhier plugin
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and the serengeti libpiclfruaccess library to the appropriate sub-functions.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int *rval_p)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_soft_state_t *softsp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int instance = getminor(dev);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_init_arg_t init_arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_ioctl";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel softsp = ddi_get_soft_state(sgfru_statep, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (softsp == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENXIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_STATE("sgfru:%s: dev %lx cmd %d, instance %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, dev, cmd, instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel init_arg.dev = dev;
03831d35f7499c87d51205817c93e9a8d42c4baestevel init_arg.cmd = cmd;
03831d35f7499c87d51205817c93e9a8d42c4baestevel init_arg.mode = mode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel init_arg.argp = arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETSECTIONS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getsections(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETSEGMENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getsegments(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_ADDSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_addsegment(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_READRAWSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_readsegment(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_WRITERAWSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_writesegment(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETPACKETS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getpackets(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_APPENDPACKET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_appendpacket(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETPAYLOAD:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getpayload(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_UPDATEPAYLOAD:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_updatepayload(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNUMSECTIONS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNUMSEGMENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNUMPACKETS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getnum(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_DELETESEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_DELETEPACKET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_delete(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETCHILDLIST:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getchildlist(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETCHILDHANDLES:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getchildhandles(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNODEINFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_getnodeinfo(&init_arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = EINVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for private SGFRU_GETCHILDLIST ioctl.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getchildlist(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t ssize, size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t clist;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel node_t *clistp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_getchildlist";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin child_info_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &clist) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = clist.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_HANDLES)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for unpadded fru_info_t + node_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + (max_cnt * NODE_SIZE));
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_NODE("sgfru:%s: FRU_INFO_SIZE %lu NODE_SIZE %lu size %lu\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, FRU_INFO_SIZE, NODE_SIZE, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_NODE("sgfru:%s: handle %lx cnt %d buffer 0x%p\n", f,
03831d35f7499c87d51205817c93e9a8d42c4baestevel clist.fru_hdl, clist.fru_cnt, clist.frus);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &clist.fru_info))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for padded node_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ssize = (size_t)(max_cnt * sizeof (node_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel clistp = (node_t *)kmem_zalloc(ssize, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded fru_info_t + node_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_node_pad(datap, max_cnt, &clist.fru_info, clistp))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(clistp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free node_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copy out fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &clist.fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(clistp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout node_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_nodes(iargp, &clist, clistp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(clistp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free node_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(clistp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for private SGFRU_GETCHILDHANDLES ioctl.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getchildhandles(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap, tdatap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t hdls;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_info_t hinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_getchildhandles";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin handles_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &hdls) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_HANDLE("sgfru:%s: handle %lx\n", f, hdls.fru_hdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = hdls.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_HANDLES)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for child fru_hdl_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + (max_cnt * FRU_HDL_SIZE));
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_mbox(iargp->cmd, datap, size, &hdls.fru_info);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ret != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, &hinfo);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout actual fru_cnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &hinfo) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_HANDLE("sgfru:%s: count %x\n", f, hinfo.cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout fru_hdl_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_handles(iargp, &hdls, (fru_hdl_t *)tdatap) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free datap buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for private SGFRU_GETNODEINFO ioctl.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getnodeinfo(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t nodeinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel node_t node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_getnodeinfo";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin node_info_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &nodeinfo) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate unpadded buffer for node_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(NODE_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_NODE("sgfru:%s: handle %lx size 0x%lx\n", f, nodeinfo.fru_hdl, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_mbox(iargp->cmd, datap, size, &nodeinfo.fru_info);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ret != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded node_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_node_pad(datap, 0, NULL, &node))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free node_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout node_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_nodes(iargp, &nodeinfo, &node) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_NODE("sgfru:%s: handle %lx nodename %s has_children %d class %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, node.handle, node.nodename, node.has_children, node.class);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_get_sections().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getsections(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t ssize, size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t sects;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel section_t *sectp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin sections_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &sects) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = sects.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_SECTIONS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for unpadded fru_info_t + section_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + (max_cnt * SECTION_SIZE));
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &sects.fru_info))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for padded section_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ssize = (size_t)(max_cnt * sizeof (section_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel sectp = (section_t *)kmem_zalloc(ssize, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded fru_info_t + section_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_section_pad(datap, max_cnt, &sects.fru_info, sectp))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(sectp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free section_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copy out fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &sects.fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(sectp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout section_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_sections(iargp, &sects, sectp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(sectp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free section_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(sectp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_get_segments().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getsegments(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t ssize, size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t segs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel segment_t *segp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &segs) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = segs.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_SEGMENTS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate unpadded buffer for fru_info_t + segment_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + (max_cnt * SEGMENT_SIZE));
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &segs.fru_info)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for padded segment_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ssize = (size_t)(max_cnt * sizeof (segment_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel segp = (segment_t *)kmem_zalloc(ssize, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded fru_info_t + segment_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_segment_pad(datap, max_cnt, &segs.fru_info, segp))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(segp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free segment_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copy out fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &segs.fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(segp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout segment_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_segments(iargp, &segs, segp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(segp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free segment_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(segp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_addsegment(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t seg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel segment_t segment;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_hdl_t *hdlp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_addsegment";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &seg) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin segment_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_segment(iargp, &seg, &segment) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: handle %lx, max cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, seg.fru_hdl, seg.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: handle %lx, name %s, descriptor 0x%x, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "offset 0x%x, length 0x%x\n", f, segment.handle, segment.name,
193974072f41a843678abf5f61979c748687e66bSherry Moore segment.descriptor, segment.offset, segment.length);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for unpadded section_hdl_t + segment_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(SECTION_HDL_SIZE + SEGMENT_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate padded to unpadded section_hdl_t + segment_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sgfru_segment_unpad(&seg.fru_info, &segment, datap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ret = sgfru_mbox(iargp->cmd, datap, size, &seg.fru_info);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ret != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout updated section_hdl_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel hdlp = (fru_hdl_t *)(datap + sizeof (fru_hdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_handle(iargp, (void *)iargp->argp, hdlp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout new segment_hdl_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_handle(iargp, seg.frus, --hdlp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free segment_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_read_segment().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_readsegment(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap, tdatap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t segs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_info_t sinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_readsegment";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin one segments_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &segs) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = segs.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_SEGMENTSIZE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: handle %lx, max cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, segs.fru_hdl, segs.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate unpadded buffer for raw data */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + max_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &segs.fru_info)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, &sinfo);
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: handle %lx, actual cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, sinfo.hdl, sinfo.cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout actual fru_cnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &sinfo) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout raw segment data */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_buffer(iargp, &segs, tdatap) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_write_segment().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_writesegment(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap, tdatap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t segs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_writesegment";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &segs) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = segs.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_SEGMENTSIZE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: handle %lx, max cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, segs.fru_hdl, segs.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate unpadded buffer for fru_info_t + raw data */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + max_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate padded to unpadded fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_unpad(&segs.fru_info, datap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin raw segment data */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_buffer(iargp, segs.frus, max_cnt, tdatap) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &segs.fru_info)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: handle %lx, actual cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, segs.fru_hdl, segs.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout updated segment handle and actual fru_cnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &segs.fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_get_packets().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getpackets(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t ssize, size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t packs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel packet_t *packp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin packets_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &packs) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = packs.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_PACKETS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for unpadded fru_info_t + packet_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + (max_cnt * PACKET_SIZE));
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &packs.fru_info))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for padded packet_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ssize = (size_t)(max_cnt * sizeof (packet_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel packp = (packet_t *)kmem_zalloc(ssize, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded fru_info_t + packet_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_packet_pad(datap, max_cnt, &packs.fru_info, packp))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(packp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free packet_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copy out fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &packs.fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(packp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout packet_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_packets(iargp, &packs, packp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(packp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free packet_t buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(packp, ssize);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_append_packet().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_appendpacket(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap, tdatap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel append_info_t append;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_hdl_t *hdlp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t addr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin append_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_append(iargp, &append) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = append.payload_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_PAYLOADSIZE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for unpadded fru_info_t + packet_t + payload */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + PACKET_SIZE + max_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate padded to unpadded fru_info_t plus packet_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_packet_unpad(&append.payload.fru_info, &append.packet,
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin payload to the end of the unpadded buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_buffer(iargp, append.payload_data, append.payload_cnt,
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &append.payload.fru_info)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout new packet_hdl_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel hdlp = (fru_hdl_t *)datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_handle(iargp, (void *)iargp->argp, hdlp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout updated segment_hdl_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel addr = (caddr_t)(iargp->argp + sizeof (packet_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_handle(iargp, addr, ++hdlp) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_get_payload().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getpayload(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap, tdatap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t payld;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_info_t pinfo;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_getpayload";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin payload_t aka frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &payld) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_PAYLOAD("sgfru:%s: handle %lx, max cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, payld.fru_hdl, payld.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = payld.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_PAYLOADSIZE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for fru_info_t + payload */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + max_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &payld.fru_info))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate unpadded to padded fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, &pinfo);
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_PAYLOAD("sgfru:%s: handle %lx, max cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, pinfo.hdl, pinfo.cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout actual fru_cnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &pinfo) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout raw packet data, aka the payload */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_buffer(iargp, &payld, tdatap) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_update_payload().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_updatepayload(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap, tdatap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup_info_t payld;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_cnt_t max_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_updatepayload";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin frup_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_frup(iargp, &payld) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check on kmem_alloc space requirements */
03831d35f7499c87d51205817c93e9a8d42c4baestevel max_cnt = payld.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((max_cnt <= 0) || (max_cnt > MAX_PAYLOADSIZE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* allocate buffer for fru_info_t + payload */
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = (size_t)(FRU_INFO_SIZE + max_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = kmem_zalloc(size, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* translate padded to unpadded fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_unpad(&payld.fru_info, datap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin payload */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_buffer(iargp, payld.frus, max_cnt, tdatap) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_PAYLOAD("sgfru_updatepayload: handle %lx, actual cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore payld.fru_hdl, payld.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* call mailbox */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &payld.fru_info))
03831d35f7499c87d51205817c93e9a8d42c4baestevel != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free buffer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(datap, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout new packet_hdl_t and actual count */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &payld.fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_PAYLOAD("sgfru:%s: new handle %lx, cnt %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore f, payld.fru_hdl, payld.fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_get_num_[sections|segments|packets]().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_getnum(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_info_t fru_info;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_fru(iargp, &fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = sizeof (fru_cnt_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = (caddr_t)&fru_info.cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &fru_info)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for fru_delete_[segment|packet].
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_delete(const sgfru_init_arg_t *iargp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_info_t fru_info;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_delete";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyin fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyin_fru(iargp, &fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: delete handle %lx\n", f, fru_info.hdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel datap = (caddr_t)&fru_info.hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = sgfru_mbox(iargp->cmd, datap, size, &fru_info)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_SEGMENT("sgfru:%s: new parent handle %lx\n", f, fru_info.hdl);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout fru_info_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sgfru_copyout_fru(iargp, &fru_info) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Calls the sgsbbc mailbox with data, returns data and status info.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_mbox(const int cmd, char *datap, const size_t size, fru_info_t *fru)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t request, *reqp = &request;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbbc_msg_t response, *resp = &response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_hdl_t hdls[2] = {0, 0};
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru_hdl_t hdl = fru->hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_mbox";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&request, sizeof (sbbc_msg_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.type = SGFRU_MBOX;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&response, sizeof (sbbc_msg_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.type = SGFRU_MBOX;
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_MBOX("sgfru:%s: cmd 0x%x, size %lu\n", f, cmd, size);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETCHILDLIST:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETCHILDLIST;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETCHILDLIST;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETCHILDHANDLES:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETCHILDHANDLES;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETCHILDHANDLES;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNODEINFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETNODEINFO;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)&hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETNODEINFO;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNUMSECTIONS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETNUMSECTIONS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)&hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETNUMSECTIONS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNUMSEGMENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETNUMSEGMENTS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)&hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETNUMSEGMENTS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETNUMPACKETS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETNUMPACKETS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)&hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETNUMPACKETS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETSECTIONS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETSECTIONS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETSECTIONS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETSEGMENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETSEGMENTS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETSEGMENTS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETPACKETS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETPACKETS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETPACKETS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_ADDSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_ADDSEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_ADDSEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (hdls);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)&hdls;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_APPENDPACKET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_APPENDPACKET;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_APPENDPACKET;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (hdls);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)&hdls;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_DELETESEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_DELETESEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_DELETESEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)&hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_READRAWSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_READRAWSEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_READRAWSEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_WRITERAWSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_WRITERAWSEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_WRITERAWSEGMENT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_DELETEPACKET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_DELETEPACKET;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_DELETEPACKET;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (fru_hdl_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)&hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_GETPAYLOAD:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_GETPAYLOAD;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_GETPAYLOAD;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_UPDATEPAYLOAD:
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_type.sub_type = SGFRU_MBOX_UPDATEPAYLOAD;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_len = size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel reqp->msg_buf = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type.sub_type = SGFRU_MBOX_UPDATEPAYLOAD;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = sizeof (fru_info_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)fru;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = sbbc_mbox_request_response(reqp, resp, sgfru_mbox_wait);
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_MBOX("sgfru:%s: rv %d, msg_status %d\n", f, rv, resp->msg_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rv) || (resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* errors from sgsbbc */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (resp->msg_status > 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (resp->msg_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* errors from SCAPP */
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (resp->msg_status) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_COMMAND_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* internal SCAPP error */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINTR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_HARDWARE_FAILURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* seprom read/write errors */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_ILLEGAL_PARAMETER:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* illegal ioctl parameter */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_BOARD_ACCESS_DENIED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* board access denied */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EACCES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_STALE_CONTENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* stale contents */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ESTALE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_STALE_OBJECT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* stale handle */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOENT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NO_SEPROM_SPACE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* seprom lacks space */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOSPC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NO_MEMORY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* user prog. lacks space */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOMEM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SG_MBOX_STATUS_NOT_SUPPORTED:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* unsupported operation */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EIO);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * These two calls get back two handles, a new handle for the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * added segment or packet, and an updated parent handle.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_ADDSEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_APPENDPACKET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(hdls, datap, sizeof (hdls));
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* These two calls get an updated parent handle. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_DELETESEGMENT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SGFRU_DELETEPACKET:
03831d35f7499c87d51205817c93e9a8d42c4baestevel fru->hdl = hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy in one frup_info_t from user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyin_frup(const sgfru_init_arg_t *argp, frup_info_t *frup)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyin_frup";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)frup, sizeof (frup_info_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef _MULTI_DATAMODEL
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_model_convert_from(argp->mode & FMODELS) == DDI_MODEL_ILP32) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup32_info_t frup32;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&frup32, sizeof (frup32_info_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)argp->argp, (void *)&frup32,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (frup32_info_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: (32 bit) failed to copyin "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "frup32_t struct", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup->fru_hdl = frup32.fru_hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup->fru_cnt = frup32.fru_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel frup->frus = (void *)(uintptr_t)frup32.frus;
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_STATE("sgfru:%s: frus %p %x hdl %lx cnt %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, frup->frus, frup32.frus, frup->fru_hdl, frup->fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* _MULTI_DATAMODEL */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)argp->argp, (void *)frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (frup_info_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "sgfru:%s: failed to copyin frup_info_t struct", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy in one fru_info_t from user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyin_fru(const sgfru_init_arg_t *argp, fru_info_t *fru)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyin_fru";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)fru, sizeof (fru_info_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)argp->argp, (void *)fru,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (fru_info_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "sgfru:%s: failed to copyin fru_info_t struct", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy in segment_t from user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyin_segment(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel segment_t *segp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyin_segment";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)segp, sizeof (segment_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)frup->frus, (void *)segp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (segment_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "sgfru:%s: failed to copyin segment_t struct", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy in segment handle, packet and payload data from user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyin_append(const sgfru_init_arg_t *argp, append_info_t *app)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyin_append";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)app, sizeof (append_info_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef _MULTI_DATAMODEL
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_model_convert_from(argp->mode & FMODELS) == DDI_MODEL_ILP32) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel append32_info_t app32;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bzero((caddr_t)&app32, sizeof (append32_info_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)argp->argp, (void *)&app32,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (append32_info_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: (32 bit) failed to copyin "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "append32_info_t struct", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel app->packet = app32.packet;
03831d35f7499c87d51205817c93e9a8d42c4baestevel app->payload_hdl = app32.payload_hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel app->payload_cnt = app32.payload_cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel app->payload_data = (void *)(uintptr_t)app32.payload_data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_PAYLOAD("sgfru:%s:: data %p hdl %lx cnt %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel f, app->payload_data, app->payload_hdl, app->payload_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* _MULTI_DATAMODEL */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)argp->argp, (void *)app,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (append_info_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "sgfru:%s: failed to copyin append_info_t struct", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel PR_PAYLOAD("sgfru:%s: hdl %lx, cnt %d pkt hdl %lx "
193974072f41a843678abf5f61979c748687e66bSherry Moore "tag %lx\n", f, app->payload_hdl, app->payload_cnt,
193974072f41a843678abf5f61979c748687e66bSherry Moore app->packet.handle, app->packet.tag);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy in raw segment and payload data from user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyin_buffer(const sgfru_init_arg_t *argp, const caddr_t data,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const int cnt, char *buffer)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyin_buffer";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((void *)data, (void *)buffer, cnt, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyin buffer", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out one fru_info_t to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_fru(const sgfru_init_arg_t *argp, const fru_info_t *frup)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_fru";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)frup, (void *)argp->argp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (fru_info_t), argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout fru", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out one fru_hdl_t to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_handle(const sgfru_init_arg_t *argp, const void *addr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const fru_hdl_t *hdlp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_handle";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)hdlp, (void *)addr, sizeof (fru_hdl_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel argp->mode) != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout handle", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out an array of fru_hdl_t's to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_handles(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const fru_hdl_t *hdlp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_handles";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size = (size_t)(frup->fru_cnt * sizeof (fru_hdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout fru_hdl_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)hdlp, (void *)frup->frus, size, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout handles", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out one or more node_t's to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_nodes(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const node_t *nodep)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_nodes";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size = (size_t)(frup->fru_cnt * sizeof (node_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout node_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)nodep, (void *)frup->frus, size, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout nodes", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out section_t's to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_sections(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const section_t *sectp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_sections";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size = (size_t)(frup->fru_cnt * sizeof (section_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout section_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)sectp, (void *)frup->frus, size, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout sections", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out segment_t's to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_segments(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const segment_t *segp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_segments";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size = (size_t)(frup->fru_cnt * sizeof (segment_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout segment_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)segp, (void *)frup->frus, size, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout segments", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out packet_t's to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_packets(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const packet_t *packp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_packets";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size = (size_t)(frup->fru_cnt * sizeof (packet_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout packet_t's */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)packp, (void *)frup->frus, size, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout packets", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to copy out raw segment and payload data to user.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_copyout_buffer(const sgfru_init_arg_t *argp, const frup_info_t *frup,
03831d35f7499c87d51205817c93e9a8d42c4baestevel const char *buffer)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static fn_t f = "sgfru_copyout_buffer";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel size_t size = (size_t)(frup->fru_cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* copyout packet_t */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout((void *)buffer, (void *)frup->frus, size, argp->mode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel != DDI_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sgfru:%s: failed to copyout buffer", f);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to pad a Java (SCAPP) fru_info_t, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * C (Solaris). Assumes one fru_info_t.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic caddr_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_fru_pad(const caddr_t datap, fru_info_t *fru)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&fru->hdl, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&fru->cnt, FRU_CNT_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_CNT_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (tdatap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to pad a Java (SCAPP) node_t, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * C (Solaris). Assumes a fru_info_t and one or more node_t's.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_node_pad(const caddr_t datap, const int max_cnt, fru_info_t *fru,
03831d35f7499c87d51205817c93e9a8d42c4baestevel node_t *nodep)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel node_t *np;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i, cnt = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fru != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, fru);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (max_cnt < fru->cnt) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOMEM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cnt = fru->cnt;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, np = nodep; i < cnt; i++, np++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&np->handle, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&np->nodename, NODENAME_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += NODENAME_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&np->has_children, HASCHILDREN_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += HASCHILDREN_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&np->class, CLASS_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += CLASS_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (np->class == LOCATION_CLASS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&np->location_slot, SLOT_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += SLOT_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&np->location_label, LABEL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += LABEL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to pad a Java (SCAPP) section, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * C (Solaris). Assumes a fru_info_t and multiple section_t's.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_section_pad(const caddr_t datap, const int max_cnt, fru_info_t *fru,
03831d35f7499c87d51205817c93e9a8d42c4baestevel section_t *sectp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel section_t *sp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, fru);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (max_cnt < fru->cnt)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOMEM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, sp = sectp; i < fru->cnt; i++, sp++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->handle, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->offset, OFFSET_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += OFFSET_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->length, LENGTH_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += LENGTH_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->protected, PROTECTED_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += PROTECTED_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->version, VERSION_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += VERSION_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to pad a Java (SCAPP) segment, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * C (Solaris). Assumes a fru_info_t and multiple segment_t's.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_segment_pad(const caddr_t datap, const int max_cnt, fru_info_t *fru,
03831d35f7499c87d51205817c93e9a8d42c4baestevel segment_t *segp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel segment_t *sp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, fru);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (max_cnt < fru->cnt)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOMEM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, sp = segp; i < fru->cnt; i++, sp++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->handle, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->name, NAME_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += NAME_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->descriptor, DESCRIPTOR_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += DESCRIPTOR_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->offset, OFFSET_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += OFFSET_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&sp->length, LENGTH_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += LENGTH_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to pad a Java (SCAPP) packet, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * C (Solaris). Assumes a fru_info_t and multiple packet_t's.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_packet_pad(const caddr_t datap, const int max_cnt, fru_info_t *fru,
03831d35f7499c87d51205817c93e9a8d42c4baestevel packet_t *packp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel packet_t *pp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap = sgfru_fru_pad(datap, fru);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (max_cnt < fru->cnt)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOMEM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0, pp = packp; i < fru->cnt; i++, pp++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&pp->handle, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(tdatap, (caddr_t)&pp->tag, TAG_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += TAG_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to unpad a C (Solaris) fru_info_t, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Java (SCAPP). Assumes a fru_info_t.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic caddr_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_fru_unpad(const fru_info_t *fru, caddr_t datap)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&fru->hdl, tdatap, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&fru->cnt, tdatap, FRU_CNT_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_CNT_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (tdatap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to unpad a C (Solaris) segment, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Java (SCAPP). Assumes a section_hdl_t and one segment_t.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_segment_unpad(const fru_info_t *fru, const segment_t *segp,
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t datap)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&fru->hdl, tdatap, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&segp->handle, tdatap, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&segp->name, tdatap, NAME_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += NAME_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&segp->descriptor, tdatap, DESCRIPTOR_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += DESCRIPTOR_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&segp->offset, tdatap, OFFSET_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += OFFSET_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&segp->length, tdatap, LENGTH_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used to unpad a C (Solaris) packet, in preparation for sending it to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Java (SCAPP). Assumes a fru_info_t and one packet_t.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic caddr_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelsgfru_packet_unpad(const fru_info_t *fru, const packet_t *packp, caddr_t datap)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel caddr_t tdatap = datap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&fru->hdl, tdatap, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&fru->cnt, tdatap, FRU_CNT_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_CNT_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&packp->handle, tdatap, FRU_HDL_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += FRU_HDL_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy((caddr_t)&packp->tag, tdatap, TAG_SIZE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tdatap += TAG_SIZE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (tdatap);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}