Example #1
0
static int quantis_copyout_uint(intptr_t arg, int flags, unsigned int src)
{
  uint32_t src32;

  switch (ddi_model_convert_from(flags & FMODELS))
  {
    case DDI_MODEL_ILP32:
      src32 = src;
      if (ddi_copyout(&src32,  (void *)arg, sizeof(src32), flags) < 0)
      {
        return -1;
      }
      return 0;

    case DDI_MODEL_NONE:
      if (ddi_copyout(&src,  (void *)arg, sizeof(src), flags) < 0)
      {
        return -1;
      }
      return 0;

    default:
      return -1;
  }
}
Example #2
0
static int
sckm_copyout_ioctl_getreq(sckm_ioctl_getreq_t *driverarg, intptr_t userarg,
                          int flag)
{
#ifdef _MULTI_DATAMODEL
    switch (ddi_model_convert_from(flag & FMODELS)) {
    case DDI_MODEL_ILP32: {
        sckm_ioctl_getreq32_t driverarg32;
        driverarg32.transid = driverarg->transid;
        driverarg32.type = driverarg->type;
        driverarg32.buf = (caddr32_t)(uintptr_t)driverarg->buf;
        driverarg32.buf_len = driverarg->buf_len;
        if (ddi_copyout(&driverarg32, (caddr_t)userarg,
                        sizeof (sckm_ioctl_getreq32_t), flag)) {
            return (EFAULT);
        }
        break;
    }
    case DDI_MODEL_NONE:
        if (ddi_copyout(driverarg, (caddr_t)userarg,
                        sizeof (sckm_ioctl_getreq_t), flag)) {
            return (EFAULT);
        }
        break;
    }
#else /* ! _MULTI_DATAMODEL */
    if (ddi_copyout(driverarg, (caddr_t)userarg,
                    sizeof (sckm_ioctl_getreq_t), flag)) {
        return (EFAULT);
    }
#endif /* _MULTI_DATAMODEL */
    return (0);
}
static int
hci1394_ioctl_hbainfo(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_hbainfo_t hbainfo;
	int status;


	ASSERT(soft_state != NULL);
	ASSERT(arg != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_enter,
	    HCI1394_TNF_HAL_STACK, "");

	hbainfo.pci_vendor_id = soft_state->vendor_info.vendor_id;
	hbainfo.pci_device_id = soft_state->vendor_info.device_id;
	hbainfo.pci_revision_id = soft_state->vendor_info.revision_id;
	hbainfo.ohci_version = soft_state->vendor_info.ohci_version;
	hbainfo.ohci_vendor_id = soft_state->vendor_info.ohci_vendor_id;
	hbainfo.ohci_vregset_cnt = soft_state->vendor_info.vendor_reg_count;

	status = ddi_copyout(&hbainfo, arg, sizeof (hci1394_ioctl_hbainfo_t),
	    mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_hbainfo_co_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_hbainfo_exit,
	    HCI1394_TNF_HAL_STACK, "");

	return (0);
}
static int
hci1394_ioctl_selfid_cnt(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_selfid_cnt_t selfid_cnt;
	int status;


	ASSERT(soft_state != NULL);
	ASSERT(arg != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_enter,
	    HCI1394_TNF_HAL_STACK, "");

	selfid_cnt.count = soft_state->drvinfo.di_stats.st_selfid_count;

	status = ddi_copyout(&selfid_cnt, arg,
	    sizeof (hci1394_ioctl_selfid_cnt_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_selfid_cnt_co_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_selfid_cnt_exit,
	    HCI1394_TNF_HAL_STACK, "");

	return (0);
}
static int
hci1394_ioctl_busgen_cnt(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_busgen_cnt_t busgen_cnt;
	int status;


	ASSERT(soft_state != NULL);
	ASSERT(arg != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_enter,
	    HCI1394_TNF_HAL_STACK, "");

	busgen_cnt.count = hci1394_ohci_current_busgen(soft_state->ohci);

	status = ddi_copyout(&busgen_cnt, arg,
	    sizeof (hci1394_ioctl_busgen_cnt_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_busgen_cnt_co_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_busgen_cnt_exit,
	    HCI1394_TNF_HAL_STACK, "");

	return (0);
}
static int
hci1394_ioctl_rdreg(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_rdreg_t rdreg;
	int status;


	ASSERT(soft_state != NULL);
	ASSERT(arg != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_enter, HCI1394_TNF_HAL_STACK, "");

	status = ddi_copyin(arg, &rdreg, sizeof (hci1394_ioctl_rdreg_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_rdreg_ci_fail, HCI1394_TNF_HAL_ERROR,
		    "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	hci1394_ohci_reg_read(soft_state->ohci, rdreg.addr, &rdreg.data);

	status = ddi_copyout(&rdreg, arg, sizeof (hci1394_ioctl_rdreg_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_rdreg_c0_fail, HCI1394_TNF_HAL_ERROR,
		    "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdreg_exit, HCI1394_TNF_HAL_STACK, "");

	return (0);
}
Example #7
0
static int
zfs_ioctl_compat_put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
{
	char *packed = NULL;
	int error = 0;
	size_t size;

	VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);

#ifdef _KERNEL
	packed = kmem_alloc(size, KM_SLEEP);
	VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
	    KM_SLEEP) == 0);

	if (ddi_copyout(packed,
	    (void *)(uintptr_t)zc->zc_nvlist_dst, size, zc->zc_iflags) != 0)
		error = EFAULT;
	kmem_free(packed, size);
#else
	packed = (void *)(uintptr_t)zc->zc_nvlist_dst;
	VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
	    0) == 0);
#endif

	zc->zc_nvlist_dst_size = size;
	return (error);
}
static void
export_buffer(import_export_t *iep, int *error)
{
	int copy_err = 0;

	if (iep->ie_size == 0 || iep->ie_uaddr == NULL)
		return;

	/*
	 * If the buffer was marked for export initially, and if the
	 * hypercall completed successfully, resync the user-space buffer
	 * with our in-kernel buffer.
	 */
	if ((iep->ie_flags & IE_EXPORT) && (*error >= 0) &&
	    (ddi_copyout(iep->ie_kaddr, iep->ie_uaddr, iep->ie_size, 0) != 0))
		copy_err = -X_EFAULT;
	if (iep->ie_flags & IE_FREE) {
		kmem_free(iep->ie_kaddr, iep->ie_size);
		iep->ie_kaddr = NULL;
		iep->ie_flags = 0;
	}

	if (copy_err != 0 && *error >= 0)
		*error = copy_err;
}
Example #9
0
static int
fcoe_copyout_iocdata(intptr_t data, int mode, fcoeio_t *fcoeio, void *obuf)
{
	if (fcoeio->fcoeio_olen) {
		if (ddi_copyout(obuf,
		    (void *)(unsigned long)fcoeio->fcoeio_obuf,
		    fcoeio->fcoeio_olen, mode) != 0) {
			return (EFAULT);
		}
	}

	if (ddi_copyout(fcoeio, (void *)data, sizeof (fcoeio_t), mode) != 0) {
		return (EFAULT);
	}
	return (0);
}
RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb)
{
    int rc;
    RT_ASSERT_INTS_ON();

    rc = ddi_copyout(pvSrc, (void *)R3PtrDst, cb, 0 /*flags*/);
    if (RT_LIKELY(rc == 0))
        return VINF_SUCCESS;
    return VERR_ACCESS_DENIED;
}
/*
 * iscsi_ioctl_copyout -
 */
int
iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode)
{
	int	rtn;

	rtn = EFAULT;
	if (ddi_copyout(data, arg, size, mode) == 0) {
		rtn = 0;
	}
	kmem_free(data, size);
	return (rtn);
}
static int
hci1394_ioctl_read_selfid32(hci1394_state_t *soft_state,
    hci1394_ioctl_readselfid32_t *read_selfid, int mode)
{
	int status;
	uint_t offset;
	uint32_t data;


	ASSERT(soft_state != NULL);
	ASSERT(read_selfid != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_enter,
	    HCI1394_TNF_HAL_STACK, "");

	/*
	 * make sure we are not trying to copy more data than the selfid buffer
	 * can hold.  count is in quadlets and max_selfid_size is in bytes.
	 */
	if ((read_selfid->count * 4) > OHCI_MAX_SELFID_SIZE) {
		TNF_PROBE_0(hci1394_ioctl_read_selfid32_cnt_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EINVAL);
	}

	/*
	 * copy the selfid buffer one word at a time into the user buffer. The
	 * combination between having to do ddi_get32's (for endian reasons) and
	 * a ddi_copyout() make it easier to do it one word at a time.
	 */
	for (offset = 0; offset < read_selfid->count; offset++) {
		/* read word from selfid buffer */
		hci1394_ohci_selfid_read(soft_state->ohci, offset, &data);
		/* copy the selfid word into the user buffer */
		status = ddi_copyout(&data,
		    (void *)(uintptr_t)(read_selfid->buf + (offset * 4)),
		    4, mode);
		if (status != 0) {
			TNF_PROBE_0(hci1394_ioctl_read_selfid32_co_fail,
			    HCI1394_TNF_HAL_ERROR, "");
			TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit,
			    HCI1394_TNF_HAL_STACK, "");
			return (EFAULT);
		}
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid32_exit,
	    HCI1394_TNF_HAL_STACK, "");

	return (0);
}
Example #13
0
static void
scopyout(spcs_s_pinfo_t *kstatus, spcs_s_pinfo_t *ustatus)
{
	int mode = 0;
#ifdef UNISTAT_TRACE
	cmn_err(CE_WARN, "!scopyout entry");
#endif

	/*
	 * If tdata is in use, blow up: asynch data is not intended for ioctls.
	 * How would we ship it back? (the user hasn't given us any place to
	 * put it!)
	 */

	if (kstatus->tcount)
		cmn_err(_CELEVEL, "!SPCS: Unistat async data in ioctl status!");

	/*
	 * Gently, Bentley
	 * Have to copy all the header stuff even though there is no need for
	 * some items like the revisions. This is unavoidable without making
	 * the structure more complex or guessing about alignment and the true
	 * size of the part of the structure sitting ahead of the {i,s,t}data
	 * arrays.
	 */

	(void) ddi_copyout((void *) kstatus, (void *) ustatus,
	    sizeof (spcs_s_pinfo_t) - (sizeof (kstatus->idata) +
	    sizeof (kstatus->sdata) + sizeof (kstatus->tdata)), mode);
	(void) ddi_copyout((void *)kstatus->idata, (void *) ustatus->idata,
	    (kstatus->icount * sizeof (kstatus->idata[0])), mode);
	(void) ddi_copyout((void *)kstatus->sdata, (void *) ustatus->sdata,
	    (kstatus->scount * sizeof (kstatus->sdata[0])), mode);
	(void) ddi_copyout((void *)kstatus->tdata, (void *) ustatus->tdata,
	    (kstatus->tcount * sizeof (kstatus->tdata[0])), mode);
#ifdef UNISTAT_TRACE
	cmn_err(CE_WARN, "!scopyout exit");
#endif
}
Example #14
0
static int
get_hsp(
	void			*d,
	int			mode
)
{
	hot_spare_pool_t	*hsp;
	get_hsp_t		*ghsp;
	size_t			size;
	set_t			setno;
	int			err = 0;
	md_i_get_t		*migp = (md_i_get_t *)d;


	setno = migp->md_driver.md_setno;

	mdclrerror(&migp->mde);

	/* Scan the hot spare pool list */
	hsp = find_hot_spare_pool(setno, migp->id);
	if (hsp == NULL) {
		return (mdhsperror(&migp->mde, MDE_INVAL_HSP,
			migp->id));
	}

	size = (sizeof (ghsp->ghsp_hs_keys[0]) * (hsp->hsp_nhotspares - 1)) +
	    sizeof (get_hsp_t);

	if (migp->size == 0) {
		migp->size = (int)size;
		return (0);
	}

	if (migp->size < size)
		return (EFAULT);

	ghsp = kmem_alloc(size, KM_SLEEP);

	ghsp->ghsp_id = hsp->hsp_self_id;
	ghsp->ghsp_refcount = hsp->hsp_refcount;
	ghsp->ghsp_nhotspares = hsp->hsp_nhotspares;
	build_key_list(setno, hsp, ghsp->ghsp_hs_keys);
	if (ddi_copyout(ghsp, (caddr_t)(uintptr_t)migp->mdp, size, mode))
		err = EFAULT;
	kmem_free(ghsp, size);
	return (err);
}
static int
hci1394_ioctl_rdvreg(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_rdvreg_t rdvreg;
	int status;


	ASSERT(soft_state != NULL);
	ASSERT(arg != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_enter, HCI1394_TNF_HAL_STACK,
	    "");

	status = ddi_copyin(arg, &rdvreg, sizeof (hci1394_ioctl_rdvreg_t),
	    mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_rdvreg_ci_fail, HCI1394_TNF_HAL_ERROR,
		    "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	status = hci1394_vendor_reg_read(soft_state->vendor,
	    rdvreg.regset, rdvreg.addr, &rdvreg.data);
	if (status != DDI_SUCCESS) {
		TNF_PROBE_0(hci1394_ioctl_rdvreg_vrr_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EINVAL);
	}

	status = ddi_copyout(&rdvreg, arg, sizeof (hci1394_ioctl_rdvreg_t),
	    mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_rdvreg_co_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdvreg_exit, HCI1394_TNF_HAL_STACK, "");

	return (0);
}
Example #16
0
static int
notify_fillin_empty_ioctl(void *data, void *ioctl_in, size_t sz,
		int mode)
{

	int	err;
	md_event_ioctl_t	*ioctl = (md_event_ioctl_t *)data;


	ioctl->mdn_event = EQ_EMPTY;
	ioctl->mdn_tag = TAG_EMPTY;
	ioctl->mdn_set = MD_ALLSETS;
	ioctl->mdn_dev =  MD_ALLDEVS;
	uniqtime32(&ioctl->mdn_time);
	ioctl->mdn_user = (u_longlong_t)0;
	err = ddi_copyout(data, ioctl_in, sz, mode);
	return (err);
}
Example #17
0
/*ARGSUSED*/
static int
av1394_ioctl_arq_get_ibuf_size(av1394_inst_t *avp, void *arg, int mode)
{
	av1394_async_t	*ap = &avp->av_a;
	int		sz;
	int		ret = 0;

	AV1394_TNF_ENTER(av1394_ioctl_arq_get_ibuf_size);

	sz = av1394_getmaxq(&ap->a_rq);

	if (ddi_copyout(&sz, arg, sizeof (sz), mode) != 0) {
		ret = EFAULT;
	}

	AV1394_TNF_EXIT(av1394_ioctl_arq_get_ibuf_size);
	return (ret);
}
static int
hci1394_ioctl_rdphy(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_rdphy_t rdphy;
	int status;


	ASSERT(soft_state != NULL);
	ASSERT(arg != NULL);
	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_enter, HCI1394_TNF_HAL_STACK, "");

	status = ddi_copyin(arg, &rdphy, sizeof (hci1394_ioctl_rdphy_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_rdphy_ci_fail, HCI1394_TNF_HAL_ERROR,
		    "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	status = hci1394_ohci_phy_read(soft_state->ohci, rdphy.addr,
	    &rdphy.data);
	if (status != DDI_SUCCESS) {
		TNF_PROBE_0(hci1394_ioctl_rdphy_pr_fail, HCI1394_TNF_HAL_ERROR,
		    "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EINVAL);
	}

	status = ddi_copyout(&rdphy, arg, sizeof (hci1394_ioctl_rdphy_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_rdphy_co_fail, HCI1394_TNF_HAL_ERROR,
		    "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_rdphy_exit, HCI1394_TNF_HAL_STACK, "");

	return (0);
}
Example #19
0
File: foo.c Project: gwr/on-skel
/*ARGSUSED*/
static int
foo_ioctl(dev_t dev, int cmd, intptr_t arg, int flags,	/* model.h */
	cred_t *cr, int *rvalp)
{
	int err;

	err = 0;
	switch (cmd) {
	case FOO_IOC_GETCNT:
		atomic_inc_32(&foo_count);
		if (ddi_copyout(&foo_count, (void *)arg,
		    sizeof (foo_count), flags))
			err = EFAULT;
		break;

	default:
		err = ENOTTY;
		break;
	}

	return (err);
}
/*
 * iscsi_conn_list_get_copyout -
 */
int
iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *cl, caddr_t arg,
    int mode)
{
	size_t			alloc_len;
	int			rtn;

	ASSERT(cl != NULL);
	ASSERT(arg != NULL);

	rtn = EFAULT;
	alloc_len = sizeof (*cl);
	if (cl->cl_in_cnt != 0) {
		alloc_len += ((cl->cl_in_cnt - 1) * sizeof (iscsi_if_conn_t));
	}

	if (ddi_copyout(cl, arg, alloc_len, mode) == 0) {
		rtn = 0;
	}
	kmem_free(cl, alloc_len);
	return (rtn);
}
/*ARGSUSED*/
static int
stripe_get(void *d, int mode, IOLOCK *lock)
{
	minor_t		mnum;
	mdi_unit_t	*ui;
	ms_unit_t	*un;
	md_error_t	*mdep;
	md_i_get_t	*migp = d;


	mnum = migp->id;
	mdep = &migp->mde;

	mdclrerror(mdep);

	if ((MD_MIN2SET(mnum) >= md_nsets) || (MD_MIN2UNIT(mnum) >= md_nunits))
		return (mdmderror(mdep, MDE_INVAL_UNIT, mnum));

	if ((ui = MDI_UNIT(mnum)) == NULL) {
		return (mdmderror(mdep, MDE_UNIT_NOT_SETUP, mnum));
	}

	un = (ms_unit_t *)md_ioctl_readerlock(lock, ui);

	if (migp->size == 0) {
		migp->size = un->c.un_size;
		return (0);
	}

	if (migp->size < un->c.un_size) {
		return (EFAULT);
	}

	if (ddi_copyout(un, (void *)(uintptr_t)migp->mdp,
	    un->c.un_size, mode))
		return (EFAULT);
	return (0);
}
/*ARGSUSED*/
static int
cpuid_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rval)
{
	char areq[16];
	void *ustr;

	switch (cmd) {
	case CPUID_GET_HWCAP: {
		STRUCT_DECL(cpuid_get_hwcap, h);

		STRUCT_INIT(h, mode);
		if (ddi_copyin((void *)arg,
		    STRUCT_BUF(h), STRUCT_SIZE(h), mode))
			return (EFAULT);
		if ((ustr = STRUCT_FGETP(h, cgh_archname)) != NULL &&
		    copyinstr(ustr, areq, sizeof (areq), NULL) != 0)
			return (EFAULT);
		areq[sizeof (areq) - 1] = '\0';

		if (strcmp(areq, architecture) == 0)
			STRUCT_FSET(h, cgh_hwcap, auxv_hwcap);
#if defined(_SYSCALL32_IMPL)
		else if (strcmp(areq, architecture_32) == 0)
			STRUCT_FSET(h, cgh_hwcap, auxv_hwcap32);
#endif
		else
			STRUCT_FSET(h, cgh_hwcap, 0);
		if (ddi_copyout(STRUCT_BUF(h),
		    (void *)arg, STRUCT_SIZE(h), mode))
			return (EFAULT);
		return (0);
	}

	default:
		return (ENOTTY);
	}
}
Example #23
0
int
_nscpartsize(dev_t dev, intptr_t arg, int mode)
{
	struct nscioc_partsize partsize;
	minor_t mindev = getminor(dev);
	nsc_size_t size;
	int rc, resv;
	nsc_fd_t *fd;

	if ((fd = _nsc_minor_fd[mindev]) == 0)
		return (EIO);

	mutex_enter(_nsc_minor_slp[mindev]);

	resv = (nsc_held(fd) == 0);

	if (resv && (rc = nsc_reserve(fd, NSC_PCATCH)) != 0) {
		mutex_exit(_nsc_minor_slp[mindev]);
		return (rc);
	}

	rc = nsc_partsize(fd, &size);
	partsize.partsize = (uint64_t)size;

	if (resv)
		nsc_release(fd);

	mutex_exit(_nsc_minor_slp[mindev]);

	if (ddi_copyout((void *)&partsize, (void *)arg,
	    sizeof (partsize), mode) < 0) {
		return (EFAULT);
	}

	return (rc);
}
static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
{
    LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl Dev=%d Cmd=%d pArg=%p Mode=%d\n", Dev, Cmd, pArg));

    /*
     * Get the session from the soft state item.
     */
    vboxusbmon_state_t *pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev));
    if (!pState)
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: no state data for %d\n", getminor(Dev)));
        return EINVAL;
    }

    /*
     * Read the request wrapper. Though We don't really need wrapper struct. now
     * it's room for the future as Solaris isn't generous regarding the size.
     */
    VBOXUSBREQ ReqWrap;
    if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
        return ENOTTY;
    }

    int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
    if (RT_UNLIKELY(rc))
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
        return EINVAL;
    }

    if (ReqWrap.u32Magic != VBOXUSBMON_MAGIC)
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
        return EINVAL;
    }
    if (RT_UNLIKELY(   ReqWrap.cbData == 0
                    || ReqWrap.cbData > _1M*16))
    {
        LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
        return EINVAL;
    }

    /*
     * Read the request.
     */
    void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData);
    if (RT_UNLIKELY(!pvBuf))
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
        return ENOMEM;
    }

    rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
    if (RT_UNLIKELY(rc))
    {
        RTMemTmpFree(pvBuf);
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
        return EFAULT;
    }
    if (RT_UNLIKELY(   ReqWrap.cbData != 0
                    && !VALID_PTR(pvBuf)))
    {
        RTMemTmpFree(pvBuf);
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pvBuf invalid pointer %p\n", pvBuf));
        return EINVAL;
    }
    Log((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pid=%d.\n", (int)RTProcSelf()));

    /*
     * Process the IOCtl.
     */
    size_t cbDataReturned;
    rc = vboxUSBMonSolarisProcessIOCtl(Cmd, pState, pvBuf, ReqWrap.cbData, &cbDataReturned);
    ReqWrap.rc = rc;
    rc = 0;

    if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
        cbDataReturned = ReqWrap.cbData;
    }

    ReqWrap.cbData = cbDataReturned;

    /*
     * Copy the request back to user space.
     */
    rc = ddi_copyout(&ReqWrap, (void *)pArg, sizeof(ReqWrap), Mode);
    if (RT_LIKELY(!rc))
    {
        /*
         * Copy the payload (if any) back to user space.
         */
        if (cbDataReturned > 0)
        {
            rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
            if (RT_UNLIKELY(rc))
            {
                LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
                rc = EFAULT;
            }
        }
    }
    else
    {
        LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout(1) failed pArg=%p Cmd=%d\n", pArg, Cmd));
        rc = EFAULT;
    }

    *pVal = rc;
    RTMemTmpFree(pvBuf);
    return rc;
}
/* ARGSUSED */
static int
sdpfp_ioctl(sock_lower_handle_t handle, int cmd, intptr_t arg, int mod,
    int32_t *rval, struct cred *cr)
{
#if defined(_SYSCALL32)
	struct timeval32 tival;
#else
	struct timeval tival;
#endif
	mac_client_promisc_type_t mtype;
	datalink_id_t linkid;
	struct lifreq lifreq;
	struct ifreq ifreq;
	struct pfpsock *ps;
	mac_handle_t mh;
	timespec_t tv;
	int error;

	switch (cmd) {
	/*
	 * ioctls that work on "struct lifreq"
	 */
	case SIOCSLIFFLAGS :
	case SIOCGLIFINDEX :
	case SIOCGLIFFLAGS :
	case SIOCGLIFMTU :
		error = pfp_lifreq_getlinkid(arg, &lifreq, &linkid);
		if (error != 0)
			return (error);
		break;

	/*
	 * ioctls that work on "struct ifreq".
	 * Not all of these have a "struct lifreq" partner, for example
	 * SIOCGIFHWADDR, for the simple reason that the logical interface
	 * does not have a hardware address.
	 */
	case SIOCSIFFLAGS :
	case SIOCGIFINDEX :
	case SIOCGIFFLAGS :
	case SIOCGIFMTU :
	case SIOCGIFHWADDR :
		error = pfp_ifreq_getlinkid(arg, &ifreq, &linkid);
		if (error != 0)
			return (error);
		break;
	}

	error =  mac_open_by_linkid(linkid, &mh);
	if (error != 0)
		return (error);

	ps = (struct pfpsock *)handle;

	switch (cmd) {
	case SIOCGLIFINDEX :
		lifreq.lifr_index = linkid;
		break;

	case SIOCGIFINDEX :
		ifreq.ifr_index = linkid;
		break;

	case SIOCGIFFLAGS :
		ifreq.ifr_flags = IFF_RUNNING;
		if (ps->ps_promisc == MAC_CLIENT_PROMISC_ALL)
			ifreq.ifr_flags |= IFF_PROMISC;
		break;

	case SIOCGLIFFLAGS :
		lifreq.lifr_flags = IFF_RUNNING;
		if (ps->ps_promisc == MAC_CLIENT_PROMISC_ALL)
			lifreq.lifr_flags |= IFF_PROMISC;
		break;

	case SIOCSIFFLAGS :
		if (linkid != ps->ps_linkid) {
			error = EINVAL;
		} else {
			if ((ifreq.ifr_flags & IFF_PROMISC) != 0)
				mtype = MAC_CLIENT_PROMISC_ALL;
			else
				mtype = MAC_CLIENT_PROMISC_FILTERED;
			error = pfp_set_promisc(ps, mtype);
		}
		break;

	case SIOCSLIFFLAGS :
		if (linkid != ps->ps_linkid) {
			error = EINVAL;
		} else {
			if ((lifreq.lifr_flags & IFF_PROMISC) != 0)
				mtype = MAC_CLIENT_PROMISC_ALL;
			else
				mtype = MAC_CLIENT_PROMISC_FILTERED;
			error = pfp_set_promisc(ps, mtype);
		}
		break;

	case SIOCGIFMTU :
		mac_sdu_get(mh, NULL, &ifreq.ifr_mtu);
		break;

	case SIOCGLIFMTU :
		mac_sdu_get(mh, NULL, &lifreq.lifr_mtu);
		break;

	case SIOCGIFHWADDR :
		mac_unicast_primary_get(mh, (uint8_t *)ifreq.ifr_addr.sa_data);
		ifreq.ifr_addr.sa_family = pfp_dl_to_arphrd(mac_type(mh));
		break;

	case SIOCGSTAMP :
		(void) gethrestime(&tv);
		tival.tv_sec = (time_t)tv.tv_sec;
		tival.tv_usec = tv.tv_nsec / 1000;
		error = ddi_copyout(&tival, (void *)arg, sizeof (tival), 0);
		break;

	default :
		break;
	}

	mac_close(mh);

	if (error == 0) {
		/*
		 * Only the "GET" ioctls need to copy data back to userace.
		 */
		switch (cmd) {
		case SIOCGLIFINDEX :
		case SIOCGLIFFLAGS :
		case SIOCGLIFMTU :
			error = ddi_copyout(&lifreq, (void *)arg,
			    sizeof (lifreq), 0);
			break;

		case SIOCGIFINDEX :
		case SIOCGIFFLAGS :
		case SIOCGIFMTU :
		case SIOCGIFHWADDR :
			error = ddi_copyout(&ifreq, (void *)arg,
			    sizeof (ifreq), 0);
			break;
		default :
			break;
		}
	}

	return (error);
}
Example #26
0
int
nskernd_command(intptr_t arg, int mode, int *rvalp)
{
	struct nskernd *udata = NULL;
	uint64_t arg1, arg2;
	int rc;

	*rvalp = 0;
	rc = 0;

	udata = kmem_alloc(sizeof (*udata), KM_SLEEP);
	if (ddi_copyin((void *)arg, udata, sizeof (*udata), mode) < 0) {
		kmem_free(udata, sizeof (*udata));
		return (EFAULT);
	}

	switch (udata->command) {
	case NSKERND_START:		/* User program start */
		*rvalp = nskernd_start(udata->data1);
		break;

	case NSKERND_STOP:		/* User program requesting stop */
		mutex_enter(&nskernd_lock);
		nskernd_cleanup();
		mutex_exit(&nskernd_lock);
		break;

	case NSKERND_WAIT:
		mutex_enter(&nskernd_lock);

		bcopy(udata, &nskernd_kdata, sizeof (*udata));

		if (nskernd_ask > 0)
			cv_signal(&nskernd_ask_cv);

		nskernd_u_wait++;

		if (cv_wait_sig(&nskernd_u_cv, &nskernd_lock) != 0) {
			/*
			 * woken by cv_signal() or cv_broadcast()
			 */
			bcopy(&nskernd_kdata, udata, sizeof (*udata));
		} else {
			/*
			 * signal - the user process has blocked all
			 * signals except for SIGTERM and the
			 * uncatchables, so the process is about to die
			 * and we need to clean up.
			 */
			udata->command = NSKERND_STOP;
			udata->data1 = (uint64_t)1;	 /* cleanup done */

			nskernd_cleanup();
		}

		nskernd_u_wait--;

		mutex_exit(&nskernd_lock);

		if (ddi_copyout(udata, (void *)arg,
		    sizeof (*udata), mode) < 0) {
			rc = EFAULT;
			break;
		}

		break;

	case NSKERND_NEWLWP:
		/* save kmem by freeing the udata structure */
		arg1 = udata->data1;
		kmem_free(udata, sizeof (*udata));
		udata = NULL;
		nsc_runlwp(arg1);
		break;

	case NSKERND_LOCK:
		/* save kmem by freeing the udata structure */
		arg1 = udata->data1;
		arg2 = udata->data2;
		kmem_free(udata, sizeof (*udata));
		udata = NULL;
		nsc_lockchild(arg1, arg2);
		break;

	default:
		cmn_err(CE_WARN, "nskernd: unknown command %d", udata->command);
		rc = EINVAL;
		break;
	}

	if (udata != NULL) {
		kmem_free(udata, sizeof (*udata));
		udata = NULL;
	}

	return (rc);
}
Example #27
0
/*ARGSUSED*/
static int
ntwdt_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
	int *rvalp)
{
	int instance = getminor(dev);
	int retval = 0;
	ntwdt_state_t *ntwdt_ptr = NULL;
	ntwdt_runstate_t *ntwdt_state;
	lom_dogstate_t lom_dogstate;
	lom_dogctl_t lom_dogctl;
	uint32_t lom_dogtime;

	if ((ntwdt_ptr = getstate(instance)) == NULL) {
		return (ENXIO);
	}

	ntwdt_state = ntwdt_ptr->ntwdt_run_state;

	switch (cmd) {
	case LOMIOCDOGSTATE:
		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);
		lom_dogstate.reset_enable = ntwdt_state->ntwdt_reset_enabled;
		lom_dogstate.dog_enable = ntwdt_state->ntwdt_watchdog_enabled;
		lom_dogstate.dog_timeout = ntwdt_state->ntwdt_watchdog_timeout;
		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);

		if (ddi_copyout((caddr_t)&lom_dogstate, (caddr_t)arg,
		    sizeof (lom_dogstate_t), mode) != 0) {
			retval = EFAULT;
		}
		break;

	case LOMIOCDOGCTL:
		if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogctl,
		    sizeof (lom_dogctl_t), mode) != 0) {
			retval = EFAULT;
			break;
		}

		NTWDT_DBG(NTWDT_DBG_IOCTL, ("reset_enable: %d, and dog_enable: "
		    "%d, watchdog_timeout %d", lom_dogctl.reset_enable,
		    lom_dogctl.dog_enable,
		    ntwdt_state->ntwdt_watchdog_timeout));
		/*
		 * ignore request to enable reset while disabling watchdog.
		 */
		if (!lom_dogctl.dog_enable && lom_dogctl.reset_enable) {
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("invalid combination of "
			    "reset_enable: %d, and dog_enable: %d",
			    lom_dogctl.reset_enable,
			    lom_dogctl.dog_enable));
			retval = EINVAL;
			break;
		}

		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

		if (ntwdt_state->ntwdt_watchdog_timeout == 0) {
			/*
			 * the LOMIOCDOGTIME has never been used to setup
			 * a valid timeout.
			 */
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("timeout has not been set"
			    "watchdog_timeout: %d",
			    ntwdt_state->ntwdt_watchdog_timeout));
			retval = EINVAL;
			goto end;
		}

		/*
		 * Store the user specified state in the softstate.
		 */
		ntwdt_state->ntwdt_reset_enabled = lom_dogctl.reset_enable;
		ntwdt_state->ntwdt_watchdog_enabled = lom_dogctl.dog_enable;

		if (ntwdt_state->ntwdt_watchdog_enabled != 0) {
			/*
			 * The user wants to enable the watchdog.
			 * Arm the watchdog and start the cyclic.
			 */
			ntwdt_arm_watchdog(ntwdt_state);

			if (ntwdt_state->ntwdt_timer_running == 0) {
				ntwdt_start_timer(ntwdt_ptr);
			}

			NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is enabled"));
		} else {
			/*
			 * The user wants to disable the watchdog.
			 */
			if (ntwdt_state->ntwdt_timer_running != 0) {
				ntwdt_stop_timer(ntwdt_ptr);
			}
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT is disabled"));
		}

		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
		break;

	case LOMIOCDOGTIME:
		if (ddi_copyin((caddr_t)arg, (caddr_t)&lom_dogtime,
		    sizeof (uint32_t), mode) != 0) {
			retval = EFAULT;
			break;
		}

		NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set timeout: %d",
		    lom_dogtime));

		/*
		 * Ensure specified timeout is valid.
		 */
		if ((lom_dogtime == 0) ||
		    (lom_dogtime > (uint32_t)NTWDT_MAX_TIMEOUT)) {
			retval = EINVAL;
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("user set invalid "
			    "timeout: %d", (int)TICK_TO_MSEC(lom_dogtime)));
			break;
		}

		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

		ntwdt_state->ntwdt_watchdog_timeout = lom_dogtime;

		/*
		 * If awdt is currently running, re-arm it with the
		 * newly-specified timeout value.
		 */
		if (ntwdt_state->ntwdt_timer_running != 0) {
			ntwdt_arm_watchdog(ntwdt_state);
		}
		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
		break;

	case LOMIOCDOGPAT:
		/*
		 * Allow user to pat the watchdog timer.
		 */
		NTWDT_DBG(NTWDT_DBG_IOCTL, ("DOGPAT is invoked"));
		mutex_enter(&ntwdt_state->ntwdt_runstate_mutex);

		/*
		 * If awdt is not enabled or underlying cyclic is not
		 * running, exit.
		 */
		if (!(ntwdt_state->ntwdt_watchdog_enabled &&
		    ntwdt_state->ntwdt_timer_running)) {
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("PAT: AWDT not enabled"));
			goto end;
		}

		if (ntwdt_state->ntwdt_watchdog_expired == 0) {
			/*
			 * re-arm the awdt.
			 */
			ntwdt_arm_watchdog(ntwdt_state);
			NTWDT_DBG(NTWDT_DBG_IOCTL, ("AWDT patted, "
			    "remainning seconds: %d",
			    ntwdt_state->ntwdt_time_remaining));
		}

		mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
		break;

	default:
		retval = EINVAL;
		break;
	}
	return (retval);
end:
	mutex_exit(&ntwdt_state->ntwdt_runstate_mutex);
	return (retval);
}
/**
 * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions.
 *
 * @returns Solaris errno.
 *
 * @param   pSession    The session.
 * @param   Cmd         The IOCtl command.
 * @param   Mode        Information bitfield (for specifying ownership of data)
 * @param   iArg        User space address of the request buffer.
 */
static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode, intptr_t iArg)
{
    int         rc;
    uint32_t    cbBuf = 0;
    union
    {
        SUPREQHDR   Hdr;
        uint8_t     abBuf[64];
    }           StackBuf;
    PSUPREQHDR  pHdr;


    /*
     * Read the header.
     */
    if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr)))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr)));
        return EINVAL;
    }
    rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode);
    if (RT_UNLIKELY(rc))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc));
        return EFAULT;
    }
    if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd));
        return EINVAL;
    }
    cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut);
    if (RT_UNLIKELY(    StackBuf.Hdr.cbIn < sizeof(StackBuf.Hdr)
                    ||  StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr)
                    ||  cbBuf > _1M*16))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd));
        return EINVAL;
    }

    /*
     * Buffer the request.
     */
    if (cbBuf <= sizeof(StackBuf))
        pHdr = &StackBuf.Hdr;
    else
    {
        pHdr = RTMemTmpAlloc(cbBuf);
        if (RT_UNLIKELY(!pHdr))
        {
            LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd));
            return ENOMEM;
        }
    }
    rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode);
    if (RT_UNLIKELY(rc))
    {
        LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc));
        if (pHdr != &StackBuf.Hdr)
            RTMemFree(pHdr);
        return EFAULT;
    }

    /*
     * Process the IOCtl.
     */
    rc = supdrvIOCtl(iCmd, &g_DevExt, pSession, pHdr, cbBuf);

    /*
     * Copy ioctl data and output buffer back to user space.
     */
    if (RT_LIKELY(!rc))
    {
        uint32_t cbOut = pHdr->cbOut;
        if (RT_UNLIKELY(cbOut > cbBuf))
        {
            LogRel(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd));
            cbOut = cbBuf;
        }
        rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode);
        if (RT_UNLIKELY(rc != 0))
        {
            /* this is really bad */
            LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc));
            rc = EFAULT;
        }
    }
    else
        rc = EINVAL;

    if (pHdr != &StackBuf.Hdr)
        RTMemTmpFree(pHdr);
    return rc;
}
Example #29
0
/*
 * Perform register accesses on the nexus device itself.
 */
int
pxtool_bus_reg_ops(dev_info_t *dip, void *arg, int cmd, int mode)
{

	pcitool_reg_t		prg;
	size_t			size;
	px_t			*px_p = DIP_TO_STATE(dip);
	boolean_t		is_write = B_FALSE;
	uint32_t		rval = 0;

	if (cmd == PCITOOL_NEXUS_SET_REG)
		is_write = B_TRUE;

	DBG(DBG_TOOLS, dip, "pxtool_bus_reg_ops set/get reg\n");

	/* Read data from userland. */
	if (ddi_copyin(arg, &prg, sizeof (pcitool_reg_t),
	    mode) != DDI_SUCCESS) {
		DBG(DBG_TOOLS, dip, "Error reading arguments\n");
		return (EFAULT);
	}

	size = PCITOOL_ACC_ATTR_SIZE(prg.acc_attr);

	DBG(DBG_TOOLS, dip, "raw bus:0x%x, dev:0x%x, func:0x%x\n",
	    prg.bus_no, prg.dev_no, prg.func_no);
	DBG(DBG_TOOLS, dip, "barnum:0x%x, offset:0x%" PRIx64 ", acc:0x%x\n",
	    prg.barnum, prg.offset, prg.acc_attr);
	DBG(DBG_TOOLS, dip, "data:0x%" PRIx64 ", phys_addr:0x%" PRIx64 "\n",
	    prg.data, prg.phys_addr);

	/*
	 * If bank num == ff, base phys addr passed in from userland.
	 *
	 * Normal bank specification is invalid, as there is no OBP property to
	 * back it up.
	 */
	if (prg.barnum != PCITOOL_BASE) {
		prg.status = PCITOOL_OUT_OF_RANGE;
		rval = EINVAL;
		goto done;
	}

	/* Allow only size of 8-bytes. */
	if (size != sizeof (uint64_t)) {
		prg.status = PCITOOL_INVALID_SIZE;
		rval = EINVAL;
		goto done;
	}

	/* Alignment checking. */
	if (!IS_P2ALIGNED(prg.offset, size)) {
		DBG(DBG_TOOLS, dip, "not aligned.\n");
		prg.status = PCITOOL_NOT_ALIGNED;
		rval = EINVAL;
		goto done;
	}

	prg.phys_addr += prg.offset;

	/*
	 * Only the hypervisor can access nexus registers.  As a result, there
	 * can be no error recovery in the OS.  If there is an error, the
	 * system will go down, but with a trap type 7f.  The OS cannot
	 * intervene with this kind of trap.
	 */

	/* Access device.  prg.status is modified. */
	rval = pxtool_phys_access(px_p, prg.phys_addr, &prg.data,
	    PCITOOL_ACC_IS_BIG_ENDIAN(prg.acc_attr), is_write);
done:
	prg.drvr_version = PCITOOL_VERSION;
	if (ddi_copyout(&prg, arg, sizeof (pcitool_reg_t),
	    mode) != DDI_SUCCESS) {
		DBG(DBG_TOOLS, dip, "Copyout failed.\n");
		return (EFAULT);
	}

	return (rval);
}
static int
do_gfx_ioctl(int cmd, intptr_t data, int mode, struct vgatext_softc *softc)
{
	static char kernel_only[] =
	    "gfxp_vgatext_ioctl: %s is a kernel only ioctl";
	int err;
	int kd_mode;

	switch (cmd) {
	case KDSETMODE:
		return (vgatext_kdsetmode(softc, (int)data));

	case KDGETMODE:
		kd_mode = softc->mode;
		if (ddi_copyout(&kd_mode, (void *)data, sizeof (int), mode))
			return (EFAULT);
		break;

	case VIS_DEVINIT:

		if (!(mode & FKIOCTL)) {
			cmn_err(CE_CONT, kernel_only, "VIS_DEVINIT");
			return (ENXIO);
		}

		err = vgatext_devinit(softc, (struct vis_devinit *)data);
		if (err != 0) {
			cmn_err(CE_WARN,
			    "gfxp_vgatext_ioctl:  could not"
			    " initialize console");
			return (err);
		}
		break;

	case VIS_CONSCOPY:	/* move */
	{
		struct vis_conscopy pma;

		if (ddi_copyin((void *)data, &pma,
		    sizeof (struct vis_conscopy), mode))
			return (EFAULT);

		vgatext_cons_copy(softc, &pma);
		break;
	}

	case VIS_CONSDISPLAY:	/* display */
	{
		struct vis_consdisplay display_request;

		if (ddi_copyin((void *)data, &display_request,
		    sizeof (display_request), mode))
			return (EFAULT);

		vgatext_cons_display(softc, &display_request);
		break;
	}

	case VIS_CONSCURSOR:
	{
		struct vis_conscursor cursor_request;

		if (ddi_copyin((void *)data, &cursor_request,
		    sizeof (cursor_request), mode))
			return (EFAULT);

		vgatext_cons_cursor(softc, &cursor_request);

		if (cursor_request.action == VIS_GET_CURSOR &&
		    ddi_copyout(&cursor_request, (void *)data,
		    sizeof (cursor_request), mode))
			return (EFAULT);
		break;
	}

	case VIS_GETCMAP:
	case VIS_PUTCMAP:
	case FBIOPUTCMAP:
	case FBIOGETCMAP:
		/*
		 * At the moment, text mode is not considered to have
		 * a color map.
		 */
		return (EINVAL);

	case FBIOGATTR:
		if (copyout(&vgatext_attr, (void *)data,
		    sizeof (struct fbgattr)))
			return (EFAULT);
		break;

	case FBIOGTYPE:
		if (copyout(&vgatext_attr.fbtype, (void *)data,
		    sizeof (struct fbtype)))
			return (EFAULT);
		break;

	default:
		return (ENXIO);
	}
	return (0);
}