25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or http://www.opensolaris.org/os/licensing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Use is subject to license terms.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * OPL IPSec Key Management Driver.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This driver runs on a OPL Domain. It processes requests received
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * from the OPL Service Processor (SP) via mailbox message. It passes
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * these requests to the sckmd daemon by means of an /ioctl interface.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Requests received from the SP consist of IPsec security associations
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * (SAs) needed to secure the communication between SC and Domain daemons
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * communicating using DSCP.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/types.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/cmn_err.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/kmem.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/errno.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/file.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/open.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/stat.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/conf.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/ddi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/cmn_err.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sunddi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sunndi.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/ddi_impldefs.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/ndi_impldefs.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/modctl.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/disp.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/note.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/byteorder.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sdt.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/scfd/scfdscpif.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/oplkm_msg.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sckm_io.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/oplkm.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define OKM_NODENAME "oplkmdrv" /* Node name */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define OKM_TARGET_ID 0 /* Target ID */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define OKM_SM_TOUT 5000 /* small timeout (5msec) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define OKM_LG_TOUT 50000 /* large timeout (50msec) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define OKM_MB_TOUT 10000000 /* Mailbox timeout (10sec) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokms_t okms_global; /* Global instance structure */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jluint32_t okm_debug = DBG_WARN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prototypes for the module related functions.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_open(dev_t *devp, int flag, int otyp, struct cred *cred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_close(dev_t dev, int flag, int otyp, struct cred *cred);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_ioctl(dev_t dev, int cmd, intptr_t data, int flag,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cred_t *cred, int *rvalp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prototypes for the internal functions.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_get_req(okms_t *okmsp, sckm_ioctl_getreq_t *ireqp,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl intptr_t data, int flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_process_req(okms_t *okmsp, okm_req_hdr_t *reqp, uint32_t len,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_getreq_t *ireqp, intptr_t data, int flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_process_status(okms_t *okmsp, sckm_ioctl_status_t *ireply);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid okm_event_handler(scf_event_t event, void *arg);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint okm_send_reply(okms_t *okmsp, uint32_t transid, uint32_t status,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint32_t sadb_err, uint32_t sadb_ver);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint block_until_ready(okms_t *okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int okm_copyin_ioctl_getreq(intptr_t userarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_getreq_t *driverarg, int flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int okm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl intptr_t userarg, int flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void okm_cleanup(okms_t *okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int okm_mbox_init(okms_t *okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void okm_mbox_fini(okms_t *okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic clock_t okm_timeout_val(int error);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct cb_ops okm_cb_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_open, /* open */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_close, /* close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* strategy */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* print */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* dump */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* read */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* write */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_ioctl, /* ioctl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* devmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* mmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* segmap */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nochpoll, /* poll */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_prop_op, /* prop_op */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0, /* streamtab */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl D_NEW | D_MP /* Driver compatibility flag */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct dev_ops okm_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DEVO_REV, /* devo_rev, */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0, /* refcnt */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_info, /* get_dev_info */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* identify */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nulldev, /* probe */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_attach, /* attach */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_detach, /* detach */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nodev, /* reset */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okm_cb_ops, /* driver operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct bus_ops *)0, /* no bus operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct modldrv modldrv = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "OPL Key Management Driver",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okm_ops,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstruct modlinkage modlinkage = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl MODREV_1,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &modldrv,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * _init - Module's init routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_init(void)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ret = mod_install(&modlinkage)) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "mod_install failed, error = %d", ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * _fini - Module's fini routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_fini(void)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ret = mod_remove(&modlinkage)) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * _info - Module's info routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_info(struct modinfo *modinfop)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (mod_info(&modlinkage, modinfop));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_attach - Module's attach routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Initializes the modules state structure and create
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the minor device node.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okms_t *okmsp = &okms_global;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance = ddi_get_instance(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Only one instance is supported. */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (instance != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cmd != DDI_ATTACH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_dip = dip;
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam okmsp->km_major = ddi_driver_major(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_inst = instance;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Get an interrupt block cookie corresponding to the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * interrupt priority of the event handler.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Assert that the event priority is not redefined to
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * some other priority.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* LINTED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(SCF_EVENT_PRI == DDI_SOFTINT_LOW);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_get_soft_iblock_cookie(dip, SCF_EVENT_PRI,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okmsp->km_ibcookie) != DDI_SUCCESS) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "ddi_get_soft_iblock_cookie failed.");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_init(&okmsp->km_lock, NULL, MUTEX_DRIVER,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void *)okmsp->km_ibcookie);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_clean |= OKM_CLEAN_LOCK;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_init(&okmsp->km_wait, NULL, CV_DRIVER, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_clean |= OKM_CLEAN_CV;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * set clean_node ahead as remove_node has to be called even
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * if create node fails.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_clean |= OKM_CLEAN_NODE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_create_minor_node(dip, OKM_NODENAME, S_IFCHR,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl instance, NULL, NULL) == DDI_FAILURE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "Device node creation failed");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_cleanup(okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_set_driver_private(dip, (caddr_t)okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_report_dev(dip);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_detach - Module's detach routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Cleans up the module's state structures and any other
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * relevant data.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okms_t *okmsp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cmd != DDI_DETACH) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((okmsp = ddi_get_driver_private(dip)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Check if the mailbox is still in use.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_state & OKM_MB_INITED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "Detach failure: Mailbox in use");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_FAILURE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_cleanup(okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_set_driver_private(dip, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (DDI_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_info - Module's info routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* ARGSUSED */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel okms_t *okmsp = &okms_global;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor_t minor;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret = DDI_FAILURE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (infocmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_INFO_DEVT2DEVINFO:
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel /*
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel * We have the case here where the minor number
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel * is the same as the instance number. So, just
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel * make sure we have the right minor node in our
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel * global state. If we don't, set the result to NULL.
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor = getminor((dev_t)arg);
6074f19f4f7fc46d66216416827712a7511abffbZach Kissel if (okmsp->km_inst != minor) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *result = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *result = okmsp->km_dip;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = DDI_SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_INFO_DEVT2INSTANCE:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl minor = getminor((dev_t)arg);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *result = (void *)(uintptr_t)minor;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = DDI_SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_open - Device open routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Initializes the mailbox and waits until the mailbox
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * gets connected. Only one open at a time is supported.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_open(dev_t *devp, int flag, int otyp, struct cred *cred)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okms_t *okmsp = &okms_global;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_open: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_state & OKM_OPENED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Only one open supported */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_open: already opened\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBUSY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state |= OKM_OPENED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = block_until_ready(okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state &= ~OKM_OPENED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_open: ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * block_until_ready - Function to wait until the mailbox is ready to use.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: It initializes the mailbox and waits for the mailbox
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * state to transition to connected.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlblock_until_ready(okms_t *okmsp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("block_until_ready: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(MUTEX_HELD(&okmsp->km_lock));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_state & OKM_MB_DISC) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("block_until_ready: closing the mailbox\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_mbox_fini(okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_state & OKM_MB_CONN) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("block_until_ready: mailbox connected\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize mailbox.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ret = okm_mbox_init(okmsp)) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("block_until_ready: mailbox init failed ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("block_until_ready: ret=%d", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_close - Device close routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Closes the mailbox.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_close(dev_t dev, int flag, int otyp, struct cred *cred)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okms_t *okmsp = &okms_global;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_close: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Close the lower layer first */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_mbox_fini(okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_ioctl - Device ioctl routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Processes ioctls from the daemon.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_ioctl(dev_t dev, int cmd, intptr_t data, int flag, cred_t *cred, int *rvalp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okms_t *okmsp = &okms_global;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_getreq_t ireq;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_status_t istatus;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_GETREQ:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_ioctl: GETREQ\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okm_copyin_ioctl_getreq(data, &ireq, flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = okm_get_req(okmsp, &ireq, data, flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_ioctl: GETREQ ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STATUS:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_ioctl: STATUS\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyin((caddr_t)data, &istatus,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_status_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = okm_process_status(okmsp, &istatus);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_ioctl: STATUS ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_ioctl: UNKNOWN ioctl\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = EINVAL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_get_req - Get a request from the mailbox.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: It blocks until a message is received, then processes
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the message and returns it to the requestor.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_get_req(okms_t *okmsp, sckm_ioctl_getreq_t *ireqp, intptr_t data, int flag)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_req_hdr_t *reqp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl caddr_t msgbuf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint32_t len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_getreq: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ret = block_until_ready(okmsp)) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_getreq: failed ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_reqp != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_getreq: req cached\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp = okmsp->km_reqp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl len = okmsp->km_reqlen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqlen = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jlretry:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (OKM_MBOX_READY(okmsp) &&
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ((ret = scf_mb_canget(okmsp->km_target,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_key, &len)) != 0)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret != ENOMSG) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_getreq: Unknown "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "mbox failure=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_getreq: waiting for mesg\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cv_wait_sig(&okmsp->km_wait,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okmsp->km_lock) <= 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_getreq:interrupted\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINTR);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!OKM_MBOX_READY(okmsp)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_getreq: mailbox not ready\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(len != 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl msgbuf = kmem_alloc(len, KM_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_sg_rcv.msc_dptr = msgbuf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_sg_rcv.msc_len = len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_getreq: getmsg\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = scf_mb_getmsg(okmsp->km_target, okmsp->km_key, len, 1,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okmsp->km_sg_rcv, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret == ENOMSG || ret == EMSGSIZE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(msgbuf, len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_getreq: nomsg ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl goto retry;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (ret != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(msgbuf, len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_getreq: Unknown mbox failure=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* check message length */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (len < sizeof (okm_req_hdr_t)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* protocol error, drop message */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(msgbuf, len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_getreq: Bad message\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBADMSG);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp = (okm_req_hdr_t *)msgbuf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp->krq_version = ntohl(reqp->krq_version);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp->krq_transid = ntohl(reqp->krq_transid);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp->krq_cmd = ntohl(reqp->krq_cmd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp->krq_reserved = ntohl(reqp->krq_reserved);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* check version of the message received */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (reqp->krq_version != OKM_PROTOCOL_VERSION) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) okm_send_reply(okmsp, reqp->krq_transid,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OKM_ERR_VERSION, 0, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(msgbuf, len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_getreq: Unknown version=%d\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp->krq_version));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBADMSG);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* process message */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = okm_process_req(okmsp, reqp, len, ireqp, data, flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_reqp == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The message is not saved, so free the buffer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(reqp, len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_getreq: ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_process_req - Process the request.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Validate the request and then give the request to the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * daemon.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_process_req(okms_t *okmsp, okm_req_hdr_t *reqp, uint32_t len,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_getreq_t *ireqp, intptr_t data, int flag)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *req_datap = (void *)(((char *)reqp) + sizeof (okm_req_hdr_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int sadb_msglen = len - sizeof (okm_req_hdr_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_req: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DUMP_REQ(reqp, len);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (reqp->krq_cmd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case OKM_MSG_SADB:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* sanity check request */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (sadb_msglen <= 0) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) okm_send_reply(okmsp, reqp->krq_transid,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl OKM_ERR_SADB_MSG, 0, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN, ("okm_process_req: bad message\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBADMSG);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Save the message, prior to giving it to the daemon.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqp = reqp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqlen = len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ireqp->buf_len < len) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_process_req: not enough space\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ENOSPC);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ireqp->transid = reqp->krq_transid;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ireqp->type = SCKM_IOCTL_REQ_SADB;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyout(req_datap, ireqp->buf, sadb_msglen, flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_process_req: copyout failed\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ireqp->buf_len = sadb_msglen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okm_copyout_ioctl_getreq(ireqp, data, flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_process_req: copyout failed\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "Unknown cmd 0x%x received", reqp->krq_cmd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Received an unknown command, send corresponding
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * error message.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) okm_send_reply(okmsp, reqp->krq_transid,
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki OKM_ERR_BAD_CMD, 0, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EBADMSG);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_req: ret=0\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_process_status - Process the status from the daemon.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Processes the status received from the daemon and sends
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * corresponding message to the SP.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_process_status(okms_t *okmsp, sckm_ioctl_status_t *ireply)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint32_t status;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint32_t sadb_msg_errno = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint32_t sadb_msg_version = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_req_hdr_t *reqp = okmsp->km_reqp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ret = block_until_ready(okmsp)) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_process_status: Unknown failure=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* fail if no status is expected, or if it does not match */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!okmsp->km_reqp || (reqp->krq_transid != ireply->transid)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_process_status: req/transid mismatch\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINVAL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (ireply->status) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_SUCCESS:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: SUCCESS\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_SUCCESS;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_ERR_PFKEY:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: PFKEY ERROR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_SADB_PFKEY;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sadb_msg_errno = ireply->sadb_msg_errno;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_ERR_REQ:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: REQ ERROR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_DAEMON;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_ERR_VERSION:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: SADB VERSION ERROR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_SADB_VERSION;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sadb_msg_version = ireply->sadb_msg_version;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_ERR_TIMEOUT:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: TIMEOUT ERR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_SADB_TIMEOUT;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_ERR_OTHER:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: OTHER ERR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_DAEMON;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCKM_IOCTL_STAT_ERR_SADB_TYPE:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: SADB TYPE ERR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_SADB_BAD_TYPE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "SCKM daemon returned invalid status %d\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ireply->status);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl status = OKM_ERR_DAEMON;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = okm_send_reply(okmsp, ireply->transid, status,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sadb_msg_errno, sadb_msg_version);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Clean up the cached request now.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(okmsp->km_reqp, okmsp->km_reqlen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqlen = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_process_status: ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_copyin_ioctl_getreq - copy-in the ioctl request from the daemon.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_copyin_ioctl_getreq(intptr_t userarg, sckm_ioctl_getreq_t *driverarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int flag)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef _MULTI_DATAMODEL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (ddi_model_convert_from(flag & FMODELS)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_MODEL_ILP32: {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_getreq32_t driverarg32;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyin((caddr_t)userarg, &driverarg32,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_getreq32_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg->transid = driverarg32.transid;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg->type = driverarg32.type;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg->buf = (caddr_t)(uintptr_t)driverarg32.buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg->buf_len = driverarg32.buf_len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_MODEL_NONE: {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyin((caddr_t)userarg, &driverarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_getreq_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#else /* ! _MULTI_DATAMODEL */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyin((caddr_t)userarg, &driverarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_getreq_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif /* _MULTI_DATAMODEL */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_copyout_ioctl_getreq - copy-out the request to the daemon.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, intptr_t userarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int flag)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef _MULTI_DATAMODEL
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (ddi_model_convert_from(flag & FMODELS)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_MODEL_ILP32: {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sckm_ioctl_getreq32_t driverarg32;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg32.transid = driverarg->transid;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg32.type = driverarg->type;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg32.buf = (caddr32_t)(uintptr_t)driverarg->buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl driverarg32.buf_len = driverarg->buf_len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyout(&driverarg32, (caddr_t)userarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_getreq32_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case DDI_MODEL_NONE:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyout(driverarg, (caddr_t)userarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_getreq_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#else /* ! _MULTI_DATAMODEL */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ddi_copyout(driverarg, (caddr_t)userarg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (sckm_ioctl_getreq_t), flag)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EFAULT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif /* _MULTI_DATAMODEL */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_cleanup - Cleanup routine.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_cleanup(okms_t *okmsp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(okmsp != NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_clean & OKM_CLEAN_NODE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_remove_minor_node(okmsp->km_dip, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_clean & OKM_CLEAN_LOCK)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_destroy(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_clean & OKM_CLEAN_CV)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_destroy(&okmsp->km_wait);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_reqp != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl kmem_free(okmsp->km_reqp, okmsp->km_reqlen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqp = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_reqlen = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ddi_set_driver_private(okmsp->km_dip, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_mbox_init - Mailbox specific initialization.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_mbox_init(okms_t *okmsp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl clock_t tout;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(MUTEX_HELD(&okmsp->km_lock));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_target = OKM_TARGET_ID;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_key = DKMD_KEY;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state &= ~OKM_MB_INITED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Iterate until mailbox gets connected */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (!(okmsp->km_state & OKM_MB_CONN)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_mbox_init: calling mb_init\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = scf_mb_init(okmsp->km_target, okmsp->km_key,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_event_handler, (void *)okmsp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_mbox_init: mb_init ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram if (ret != 0) {
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram DPRINTF(DBG_MBOX,
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram ("okm_mbox_init: failed ret =%d\n", ret));
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram DTRACE_PROBE1(okm_mbox_fail, int, ret);
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state |= OKM_MB_INITED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Block until the mailbox is ready to communicate. */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (!(okmsp->km_state &
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (OKM_MB_CONN | OKM_MB_DISC))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cv_wait_sig(&okmsp->km_wait,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okmsp->km_lock) <= 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* interrupted */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = EINTR;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram if ((ret != 0) || (okmsp->km_state & OKM_MB_DISC)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram if (okmsp->km_state & OKM_MB_INITED) {
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram (void) scf_mb_fini(okmsp->km_target,
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram okmsp->km_key);
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram }
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram if (okmsp->km_state & OKM_MB_DISC) {
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram DPRINTF(DBG_WARN,
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram ("okm_mbox_init: mbox DISC_ERROR\n"));
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram DTRACE_PROBE1(okm_mbox_fail,
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram int, OKM_MB_DISC);
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram okmsp->km_state &= ~(OKM_MB_INITED | OKM_MB_DISC |
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram OKM_MB_CONN);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram if (ret == EINTR) {
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram return (ret);
030f3a8fd60560aa3c096f68447cd7ea31457e6araghuram }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If there was failure, then wait for
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * OKM_MB_TOUT secs and retry again.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_mbox_init: waiting...\n"));
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni tout = drv_usectohz(OKM_MB_TOUT);
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni ret = cv_reltimedwait_sig(&okmsp->km_wait,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &okmsp->km_lock, tout, TR_CLOCK_TICK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* if interrupted, return immediately. */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_mbox_init: interrupted\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EINTR);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = scf_mb_ctrl(okmsp->km_target, okmsp->km_key,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl SCF_MBOP_MAXMSGSIZE, &okmsp->km_maxsz);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The max msg size should be at least the size of reply
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * we need to send.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ret == 0) && (okmsp->km_maxsz < sizeof (okm_rep_hdr_t))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "Max message size expected >= %ld "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "but found %d\n", sizeof (okm_rep_hdr_t), okmsp->km_maxsz);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = EIO;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state &= ~OKM_MB_INITED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) scf_mb_fini(okmsp->km_target, okmsp->km_key);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_mbox_init: mb_init ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_mbox_fini - Mailbox de-initialization.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_mbox_fini(okms_t *okmsp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(MUTEX_HELD(&okmsp->km_lock));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (okmsp->km_state & OKM_MB_INITED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_mbox_fini: calling mb_fini\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = scf_mb_fini(okmsp->km_target, okmsp->km_key);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_mbox_fini: mb_fini ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Failed to close the Mailbox error=%d", ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state &= ~(OKM_MB_INITED | OKM_MB_CONN | OKM_MB_DISC);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_event_handler - Mailbox event handler.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Description: Implements a state machine to handle all the mailbox
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * events. For each event, it sets the appropriate state
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * flag and wakes up the threads waiting for that event.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_event_handler(scf_event_t event, void *arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okms_t *okmsp = (okms_t *)arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_event_handler: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(okmsp != NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_enter(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!(okmsp->km_state & OKM_MB_INITED)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Ignore all events if the state flag indicates that the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * mailbox not initialized, this may happen during the close.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_event_handler: event=0x%X - mailbox not inited \n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl event));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (event) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCF_MB_CONN_OK:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_event_handler: Event CONN_OK\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Now the mailbox is ready to use, lets wake up
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * any one waiting for this event.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state |= OKM_MB_CONN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_broadcast(&okmsp->km_wait);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCF_MB_MSG_DATA:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_event_handler: Event MSG_DATA\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * A message is available in the mailbox,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * wakeup if any one is ready to read the message.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (OKM_MBOX_READY(okmsp)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_broadcast(&okmsp->km_wait);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCF_MB_SPACE:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_event_handler: Event MB_SPACE\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Now the mailbox is ready to transmit, lets
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * wakeup if any one is waiting to write.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (OKM_MBOX_READY(okmsp)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_broadcast(&okmsp->km_wait);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case SCF_MB_DISC_ERROR:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_event_handler: Event DISC_ERROR\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state &= ~OKM_MB_CONN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_state |= OKM_MB_DISC;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cv_broadcast(&okmsp->km_wait);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cmn_err(CE_WARN, "Unexpected event received\n");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mutex_exit(&okmsp->km_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_send_reply - Send a mailbox reply message.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_send_reply(okms_t *okmsp, uint32_t transid,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint32_t status, uint32_t sadb_err, uint32_t sadb_ver)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okm_rep_hdr_t reply;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int ret = EIO;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_send_reply: called\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(MUTEX_HELD(&okmsp->km_lock));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reply.krp_version = htonl(OKM_PROTOCOL_VERSION);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reply.krp_transid = htonl(transid);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reply.krp_status = htonl(status);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reply.krp_sadb_errno = htonl(sadb_err);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reply.krp_sadb_version = htonl(sadb_ver);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_sg_tx.msc_dptr = (caddr_t)&reply;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl okmsp->km_sg_tx.msc_len = sizeof (reply);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DUMP_REPLY(&reply);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (OKM_MBOX_READY(okmsp)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_send_reply: sending reply\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = scf_mb_putmsg(okmsp->km_target, okmsp->km_key,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (reply), 1, &okmsp->km_sg_tx, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_MBOX, ("okm_send_reply: putmsg ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (ret == EBUSY || ret == ENOSPC) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* mailbox is busy, poll/retry */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cv_timedwait_sig(&okmsp->km_wait,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &okmsp->km_lock, okm_timeout_val(ret)) == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* interrupted */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ret = EINTR;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ("okm_send_reply: interrupted\n"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DPRINTF(DBG_DRV, ("okm_send_reply: ret=%d\n", ret));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ret);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * okm_timeout_val -- Return appropriate timeout value.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * A small timeout value is returned for EBUSY as the mailbox busy
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * condition may go away sooner and we are expected to poll.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * A larger timeout value is returned for ENOSPC case, as the condition
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * depends on the peer to release buffer space.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * NOTE: there will also be an event(SCF_MB_SPACE) but a timeout is
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * used for reliability purposes.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic clock_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_timeout_val(int error)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl clock_t tval;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ASSERT(error == EBUSY || error == ENOSPC);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (error == EBUSY) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl tval = OKM_SM_TOUT;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl tval = OKM_LG_TOUT;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (drv_usectohz(tval));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#ifdef DEBUG
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_print_req(okm_req_hdr_t *reqp, uint32_t len)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint8_t *datap = (uint8_t *)(((char *)reqp) + sizeof (okm_req_hdr_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int msglen = len - sizeof (okm_req_hdr_t);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int i, j;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define BYTES_PER_LINE 20
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char bytestr[BYTES_PER_LINE * 3 + 1];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!(okm_debug & DBG_MESG))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl printf("OKM: Request ver=%d transid=%d cmd=%s\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl reqp->krq_version, reqp->krq_transid,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ((reqp->krq_cmd == OKM_MSG_SADB) ? "MSG_SADB" : "UNKNOWN"));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = 0; i < msglen; ) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (j = 0; (j < BYTES_PER_LINE) && (i < msglen); j++, i++) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) sprintf(&bytestr[j * 3], "%02X ", datap[i]);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (j != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl printf("\t%s\n", bytestr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jlokm_print_rep(okm_rep_hdr_t *repp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!(okm_debug & DBG_MESG))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl printf("OKM: Reply Ver=%d Transid=%d Status=%d ",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl repp->krp_version, repp->krp_transid, repp->krp_status);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl printf("Sadb_errno=%d Sadb_ver=%d\n", repp->krp_sadb_errno,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl repp->krp_sadb_version);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#endif