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/*
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Starcat IPSec Key Management Driver.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This driver runs on a Starcat Domain. It processes requests received
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from the System Controller (SC) from IOSRAM, passes these requests
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to the sckmd daemon by means of an open/close/ioctl interface, and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sends corresponding status information back to the SC.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Requests received from the SC consist of IPsec security associations
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (SAs) needed to secure the communication between SC and Domain daemons
03831d35f7499c87d51205817c93e9a8d42c4baestevel * communicating using the Management Network (MAN).
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cmn_err.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/kmem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/file.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/open.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/conf.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/cmn_err.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunddi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sunndi.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ddi_impldefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/ndi_impldefs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/modctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/disp.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/async.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/mboxsc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sckm_msg.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sckm_io.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/taskq.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/note.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uint_t sckm_debug_flags = 0x0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG0(f, s) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG1(f, s, a) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s, a)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG2(f, s, a, b) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s, a, b)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG3(f, s, a, b, c) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s, a, b, c)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG4(f, s, a, b, c, d) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s, a, b, c, d)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG5(f, s, a, b, c, d, e) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s, a, b, c, d, e)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG6(f, s, a, b, c, d, e, ff) if ((f)& sckm_debug_flags) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_CONT, s, a, b, c, d, e, ff)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#else
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG0(f, s)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG1(f, s, a)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG2(f, s, a, b)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG3(f, s, a, b, c)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG4(f, s, a, b, c, d)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG5(f, s, a, b, c, d, e)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEBUG6(f, s, a, b, c, d, e, ff)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* DEBUG */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define D_INIT 0x00000001 /* _init/_fini/_info */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define D_ATTACH 0x00000002 /* attach/detach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define D_OPEN 0x00000008 /* open/close */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define D_IOCTL 0x00010000 /* ioctl */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define D_TASK 0x00100000 /* mailbox task processing */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define D_CALLBACK 0x00200000 /* mailbox callback */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sckm_open(dev_t *, int, int, struct cred *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sckm_close(dev_t, int, int, struct cred *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sckm_ioctl(dev_t, int, intptr_t, int, struct cred *, int *);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct cb_ops sckm_cb_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_open, /* open */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_close, /* close */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* strategy */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* print */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* dump */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* read */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* write */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_ioctl, /* ioctl */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* devmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* mmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* segmap */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nochpoll, /* poll */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_prop_op, /* prop_op */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, /* streamtab */
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_NEW | D_MP /* Driver compatibility flag */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sckm_attach(dev_info_t *, ddi_attach_cmd_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sckm_detach(dev_info_t *, ddi_detach_cmd_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sckm_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct dev_ops sckm_ops = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel DEVO_REV, /* devo_rev, */
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, /* refcnt */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_info, /* get_dev_info */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* identify */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nulldev, /* probe */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_attach, /* attach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_detach, /* detach */
03831d35f7499c87d51205817c93e9a8d42c4baestevel nodev, /* reset */
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sckm_cb_ops, /* driver operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore (struct bus_ops *)0, /* no bus operations */
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_needed, /* quiesce */
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modldrv modldrv = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Key Management Driver",
03831d35f7499c87d51205817c93e9a8d42c4baestevel &sckm_ops,
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic struct modlinkage modlinkage = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel MODREV_1,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &modldrv,
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Private definitions.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DEF_GETMSG_TIMEOUT 60 /* in seconds */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_DAEMON_TIMEOUT 4000000 /* in microseconds */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define SCKM_NUM_TASKQ 2 /* # of task queue entries */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For processing mailbox layer events.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t sckm_task_mutex;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t sckm_taskq_ptr_mutex;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic clock_t sckm_getmsg_timeout = SCKM_DEF_GETMSG_TIMEOUT*1000;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic taskq_t *sckm_taskq = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sckm_mbox_req_hdr_t *req_data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sckm_mbox_rep_hdr_t *rep_data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * For synchronization with key management daemon.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kmutex_t sckm_umutex;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kcondvar_t sckm_udata_cv; /* daemon waits on data */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic kcondvar_t sckm_cons_cv; /* wait for daemon to consume data */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic boolean_t sckm_udata_req = B_FALSE; /* data available for daemon */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sckm_ioctl_getreq_t sckm_udata; /* request for daemon */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic sckm_ioctl_status_t sckm_udata_status; /* status from daemon */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Other misc private variables.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic dev_info_t *sckm_devi = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic boolean_t sckm_oflag = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Private functions prototypes.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void sckm_mbox_callback(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void sckm_mbox_task(void *arg);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void sckm_process_msg(uint32_t cmd, uint64_t transid,
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t len, sckm_mbox_req_hdr_t *req_data,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_mbox_rep_hdr_t *rep_data);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel mboxsc_timeout_range_t timeout_range;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_INIT, "in _init");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize outgoing mailbox (KDSC)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = mboxsc_init(KEY_KDSC, MBOXSC_MBOX_OUT, NULL)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "failed initializing outgoing mailbox "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "(%d)", ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize incoming mailbox (SCKD)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = mboxsc_init(KEY_SCKD, MBOXSC_MBOX_IN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_mbox_callback)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "failed initializing incoming mailbox "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "(%d)\n", ret);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_KDSC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = mboxsc_ctrl(KEY_SCKD, MBOXSC_CMD_GETMSG_TIMEOUT_RANGE,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void *)&timeout_range)) != 0) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_SCKD);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_KDSC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_getmsg_timeout < timeout_range.min_timeout) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_getmsg_timeout = timeout_range.min_timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "resetting getmsg timeout to %lx",
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_getmsg_timeout);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_getmsg_timeout > timeout_range.max_timeout) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_getmsg_timeout = timeout_range.max_timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "resetting getmsg timeout to %lx",
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_getmsg_timeout);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = mod_install(&modlinkage)) != 0) {
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_KDSC);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_SCKD);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize variables needed for synchronization with daemon.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.buf = kmem_alloc(SCKM_SCKD_MAXDATA, KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_data = (sckm_mbox_req_hdr_t *)kmem_alloc(SCKM_SCKD_MAXDATA,
03831d35f7499c87d51205817c93e9a8d42c4baestevel KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data = (sckm_mbox_rep_hdr_t *)kmem_alloc(SCKM_KDSC_MAXDATA,
03831d35f7499c87d51205817c93e9a8d42c4baestevel KM_SLEEP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((sckm_udata.buf == NULL) || (req_data == NULL) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (rep_data == NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "not enough memory during _init");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* free what was successfully allocated */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_udata.buf != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(sckm_udata.buf, SCKM_SCKD_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (req_data != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(req_data, SCKM_SCKD_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rep_data != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(rep_data, SCKM_KDSC_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.buf = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* uninitialize mailboxes, remove module, and return error */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_KDSC);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_SCKD);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mod_remove(&modlinkage);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_init(&sckm_udata_cv, NULL, CV_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_init(&sckm_cons_cv, NULL, CV_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&sckm_umutex, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Create mutex for task processing, protection of taskq
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pointer, and create taskq.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&sckm_task_mutex, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_init(&sckm_taskq_ptr_mutex, NULL, MUTEX_DRIVER, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_taskq = taskq_create("sckm_taskq", 1, minclsyspri,
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_NUM_TASKQ, SCKM_NUM_TASKQ, TASKQ_PREPOPULATE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_INIT, "out _init ret=%d\n", ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_fini(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int ret;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_INIT, "in _fini");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((ret = mod_remove(&modlinkage)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Wait for scheduled tasks to complete, then destroy task queue.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_taskq_ptr_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_taskq != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel taskq_destroy(sckm_taskq);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_taskq = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_taskq_ptr_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Terminate incoming and outgoing IOSRAM mailboxes
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_KDSC);
07d06da50d310a325b457d6330165aebab1e0064Surya Prakki (void) mboxsc_fini(KEY_SCKD);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Destroy module synchronization objects and free memory
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&sckm_taskq_ptr_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_destroy(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_destroy(&sckm_cons_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_udata.buf != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(sckm_udata.buf, SCKM_SCKD_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.buf = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rep_data != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(rep_data, SCKM_KDSC_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (req_data != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel kmem_free(req_data, SCKM_SCKD_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ret);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevel_info(struct modinfo *modinfop)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_INIT, "in _info");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (mod_info(&modlinkage, modinfop));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_ATTACH, "in sckm_attach, cmd=%d", cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_ATTACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_ATTACH, "sckm_attach: DDI_ATTACH");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_create_minor_node(devi, "sckmdrv", S_IFCHR,
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, NULL, NULL) == DDI_FAILURE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "ddi_create_minor_node failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(devi, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_devi = devi;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_SUSPEND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_ATTACH, "sckm_attach: DDI_SUSPEND");
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sckm_attach: bad cmd %d\n", cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_ATTACH, "out sckm_attach (DDI_SUCCESS)");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_ATTACH, "in sckm_detach, cmd=%d", cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_DETACH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_ATTACH, "sckm_detach: DDI_DETACH");
03831d35f7499c87d51205817c93e9a8d42c4baestevel ddi_remove_minor_node(devi, NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_SUSPEND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_ATTACH, "sckm_detach: DDI_DETACH");
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sckm_detach: bad cmd %d\n", cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_ATTACH, "out sckm_detach (DDI_SUCCESS)");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (DDI_SUCCESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel void **result)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_ATTACH, "in sckm_info, infocmd=%d", infocmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (infocmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_INFO_DEVT2DEVINFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *result = (void *)sckm_devi;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_INFO_DEVT2INSTANCE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel *result = (void *)0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel rv = DDI_FAILURE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_ATTACH, "out sckm_info, rv=%d", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_open(dev_t *devp, int flag, int otyp, struct cred *cred)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_OPEN, "in sckm_open");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check credentials of calling process */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (drv_priv(cred)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_OPEN, "sckm_open: attempt by non-root proc");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EPERM);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* enforce exclusive access */
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_oflag == B_TRUE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_OPEN, "sckm_open: already open");
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBUSY);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_oflag = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_OPEN, "sckm_open: succcess");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_close(dev_t dev, int flag, int otyp, struct cred *cred)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_OPEN, "in sckm_close");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_oflag = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_copyin_ioctl_getreq(intptr_t userarg, sckm_ioctl_getreq_t *driverarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int flag)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef _MULTI_DATAMODEL
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (ddi_model_convert_from(flag & FMODELS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_MODEL_ILP32: {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_ioctl_getreq32_t driverarg32;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)userarg, &driverarg32,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_getreq32_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg->transid = driverarg32.transid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg->type = driverarg32.type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg->buf = (caddr_t)(uintptr_t)driverarg32.buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg->buf_len = driverarg32.buf_len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_MODEL_NONE: {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)userarg, &driverarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_getreq_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#else /* ! _MULTI_DATAMODEL */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)userarg, &driverarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_getreq_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* _MULTI_DATAMODEL */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, intptr_t userarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int flag)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef _MULTI_DATAMODEL
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (ddi_model_convert_from(flag & FMODELS)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_MODEL_ILP32: {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_ioctl_getreq32_t driverarg32;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg32.transid = driverarg->transid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg32.type = driverarg->type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg32.buf = (caddr32_t)(uintptr_t)driverarg->buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel driverarg32.buf_len = driverarg->buf_len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout(&driverarg32, (caddr_t)userarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_getreq32_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DDI_MODEL_NONE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout(driverarg, (caddr_t)userarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_getreq_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#else /* ! _MULTI_DATAMODEL */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout(driverarg, (caddr_t)userarg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_getreq_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif /* _MULTI_DATAMODEL */
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_ioctl(dev_t dev, int cmd, intptr_t data, int flag,
03831d35f7499c87d51205817c93e9a8d42c4baestevel cred_t *cred, int *rvalp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rval = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_IOCTL, "in sckm_ioctl");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_GETREQ: {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_ioctl_getreq_t arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: got SCKM_IOCTL_GETREQ");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_copyin_ioctl_getreq(data, &arg, flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* sanity check argument */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (arg.buf_len < SCKM_SCKD_MAXDATA) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG2(D_IOCTL, "sckm_ioctl: usr buffer too "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "small (%d < %d)", arg.buf_len, SCKM_SCKD_MAXDATA);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOSPC);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* wait for request from SC */
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (!sckm_udata_req) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: waiting for msg");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (cv_wait_sig(&sckm_udata_cv, &sckm_umutex) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINTR);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_IOCTL, "sckm_ioctl: msg available "
193974072f41a843678abf5f61979c748687e66bSherry Moore "transid = 0x%lx", sckm_udata.transid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel arg.transid = sckm_udata.transid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel arg.type = sckm_udata.type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyout(sckm_udata.buf, arg.buf,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.buf_len, flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel arg.buf_len = sckm_udata.buf_len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_copyout_ioctl_getreq(&arg, data, flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STATUS: {
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_ioctl_status_t arg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: got SCKM_IOCTL_STATUS");
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ddi_copyin((caddr_t)data, &arg,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (sckm_ioctl_status_t), flag)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "sckm_ioctl: ddi_copyin failed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EFAULT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG3(D_IOCTL, "sckm_ioctl: arg transid=0x%lx, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "status=%d, sadb_msg_errno=%d", arg.transid, arg.status,
03831d35f7499c87d51205817c93e9a8d42c4baestevel arg.sadb_msg_errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* fail if no status is expected, or if it does not match */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!sckm_udata_req || sckm_udata.transid != arg.transid) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* update status information for event handler */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(&arg, &sckm_udata_status, sizeof (sckm_ioctl_status_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* signal event handler that request has been processed */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: signaling event handler"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " that data has been processed");
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_signal(&sckm_cons_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata_req = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_IOCTL, "sckm_ioctl: unknown command");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rval = EINVAL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_IOCTL, "out sckm_ioctl, rval=%d", rval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sckm_mbox_callback
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Callback routine registered with the IOSRAM mailbox protocol driver.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Invoked when a message is received on the mailbox.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_mbox_callback(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_CALLBACK, "in sckm_mbox_callback()");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_taskq_ptr_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sckm_taskq == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_taskq_ptr_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!taskq_dispatch(sckm_taskq, sckm_mbox_task, NULL, KM_NOSLEEP)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Too many tasks already pending. Do not queue a new
03831d35f7499c87d51205817c93e9a8d42c4baestevel * request.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_CALLBACK, "failed dispatching task");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_taskq_ptr_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_CALLBACK, "out sckm_mbox_callback()");
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sckm_mbox_task
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Dispatched on taskq from the IOSRAM mailbox callback
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sckm_mbox_callback when a message is received on the incoming
03831d35f7499c87d51205817c93e9a8d42c4baestevel * mailbox.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_mbox_task(void *ignored)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel _NOTE(ARGUNUSED(ignored))
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t type, cmd, length;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t transid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rval;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "in sckm_mbox_task\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (req_data == NULL || rep_data == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "sckm_mbox_task: no buffers");
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get mailbox message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel type = MBOXSC_MSG_REQUEST;
03831d35f7499c87d51205817c93e9a8d42c4baestevel length = SCKM_SCKD_MAXDATA;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmd = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel transid = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "sckm_mbox_task: "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "calling mboxsc_getmsg()\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rval = mboxsc_getmsg(KEY_SCKD, &type, &cmd, &transid,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &length, req_data, sckm_getmsg_timeout);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rval != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "mboxsc_getmsg() failed (%d)\n", rval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG4(D_TASK, "sckm_mbox_task: "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "type=0x%x cmd=0x%x length=%d transid=0x%lx\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel type, cmd, length, transid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check message length */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (length < sizeof (sckm_mbox_req_hdr_t)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* protocol error, drop message */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG2(D_TASK, "received short "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "message of length %d, min %lu",
03831d35f7499c87d51205817c93e9a8d42c4baestevel length, sizeof (sckm_mbox_req_hdr_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* check version of message received */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (req_data->sckm_version != SCKM_PROTOCOL_VERSION) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG2(D_TASK, "received protocol "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "version %d, expected %d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_data->sckm_version, SCKM_PROTOCOL_VERSION);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Send reply with SCKM_SADB_ERR_VERSION error
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so that SC can adopt correct protocol version
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for this domain.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rval = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rval != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "mboxsc_putmsg() failed (%d)\n", rval);
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* process message */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_process_msg(cmd, transid, length,
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_data, rep_data);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_task_mutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sckm_process_msg
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Process a message received from the SC. Invoked by sckm_event_task().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baestevelsckm_process_msg(uint32_t cmd, uint64_t transid,
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t len, sckm_mbox_req_hdr_t *req_data,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_mbox_rep_hdr_t *rep_data)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int rv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_enter(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (cmd) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_MSG_SADB: {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int sadb_msglen;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sadb_msglen = len-sizeof (sckm_mbox_req_hdr_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "received SCKM_MSG_SADB len=%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel sadb_msglen);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* sanity check request */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (len-sizeof (sckm_mbox_req_hdr_t) <= 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "bad SADB message, "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "zero length");
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * SADB message is too short, send corresponding
03831d35f7499c87d51205817c93e9a8d42c4baestevel * error message to SC.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_SADB_MSG;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rv = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "mboxsc_putmsg() failed (%d)\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* initialize request for daemon */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.transid = transid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.type = SCKM_IOCTL_REQ_SADB;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata.buf_len = len-sizeof (sckm_mbox_req_hdr_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bcopy(req_data+1, sckm_udata.buf, sckm_udata.buf_len);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "unknown cmd %x received from SC", cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Received unknown command from SC. Send corresponding
03831d35f7499c87d51205817c93e9a8d42c4baestevel * error message to SC.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_BAD_CMD;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rv = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "sckm_mbox_task: "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "mboxsc_putmsg() failed (%d)\n", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * At this point, we know that the request is valid, so pass
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the request to the daemon.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "waking up daemon");
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata_req = B_TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel cv_signal(&sckm_udata_cv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* wait for daemon to process request */
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni if (cv_reltimedwait(&sckm_cons_cv, &sckm_umutex,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni drv_usectohz(SCKM_DAEMON_TIMEOUT), TR_CLOCK_TICK) == -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Daemon did not process the data, report this
03831d35f7499c87d51205817c93e9a8d42c4baestevel * error to the SC.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "daemon timeout!!");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_DAEMON;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Daemon processed data, return status to SC */
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "daemon processed data");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sckm_version = SCKM_PROTOCOL_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (sckm_udata_status.status) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_SUCCESS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "daemon returned success");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_SUCCESS;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_ERR_PFKEY:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "daemon returned PF_KEY "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "error, errno=%d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata_status.sadb_msg_errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_SADB_PFKEY;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sadb_msg_errno =
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata_status.sadb_msg_errno;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_ERR_REQ:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "daemon returned "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "bad request");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_DAEMON;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_ERR_VERSION:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "PF_KEY version not "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "supported");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_SADB_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->sadb_msg_version =
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata_status.sadb_msg_version;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_ERR_TIMEOUT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "no response received "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "from key engine");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_SADB_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_ERR_OTHER:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "daemon encountered "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "an error");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_DAEMON;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case SCKM_IOCTL_STAT_ERR_SADB_TYPE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "daemon returned bad "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SADB message type");
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_SADB_BAD_TYPE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmn_err(CE_WARN, "SCKM daemon returned "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "invalid status %d", sckm_udata_status.status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data->status = SCKM_ERR_DAEMON;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* send reply back to SC */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rv = mboxsc_putmsg(KEY_KDSC, MBOXSC_MSG_REPLY,
03831d35f7499c87d51205817c93e9a8d42c4baestevel cmd, &transid, sizeof (sckm_mbox_rep_hdr_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel rep_data, MBOXSC_PUTMSG_DEF_TIMEOUT)) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG1(D_TASK, "failed sending reply to SC (%d)", rv);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel SCKM_DEBUG0(D_TASK, "reply sent to SC");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sckm_udata_req = B_FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mutex_exit(&sckm_umutex);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}