Beispiel #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;
  }
}
Beispiel #2
0
/**
 * File ioctl entry point
 *
 * We have some additional work to do in the ioctl call, as we have to support
 * both 32 bit and 64 bit userland programs. Data structures from userland are
 * converted using the `ddi_model_convert_from' function.
 */
static int quantis_copyin_uint(intptr_t arg, int flags, unsigned int* dst)
{
  uint32_t tmp32;

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

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

    default:
      return -1;
  }
}
Beispiel #3
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);
}
Beispiel #4
0
static int
ippctl_copyout(
	caddr_t		arg,
	int		mode,
	char		*kbuf,
	size_t		kbuflen)
{
	ippctl_ioctl_t	iioc;
	caddr_t		ubuf;
	int		ubuflen;

	DBG0(DBG_CBOPS, "copying out ioctl structure\n");

	/*
	 * Copy in the ioctl structure from user-space, converting from 32-bit
	 * as necessary.
	 */

#ifdef	_MULTI_DATAMODEL
	switch (ddi_model_convert_from(mode & FMODELS)) {
	case DDI_MODEL_ILP32:
		{
			ippctl_ioctl32_t	iioc32;

			if (ddi_copyin(arg, (caddr_t)&iioc32,
			    sizeof (ippctl_ioctl32_t), mode) != 0)
				return (EFAULT);

			ubuf = (caddr_t)(uintptr_t)iioc32.ii32_buf;
			ubuflen = iioc32.ii32_buflen;
		}
		break;
	case DDI_MODEL_NONE:
		if (ddi_copyin(arg, (caddr_t)&iioc, sizeof (ippctl_ioctl_t),
		    mode) != 0)
			return (EFAULT);

		ubuf = iioc.ii_buf;
		ubuflen = iioc.ii_buflen;
		break;
	default:
		return (EFAULT);
	}
#else	/* _MULTI_DATAMODEL */
	if (ddi_copyin(arg, (caddr_t)&iioc, sizeof (ippctl_ioctl_t),
	    mode) != 0)
		return (EFAULT);

	ubuf = iioc.ii_buf;
	ubuflen = iioc.ii_buflen;
#endif	/* _MULTI_DATAMODEL */

	DBG1(DBG_CBOPS, "ubuf = 0x%p\n", (void *)ubuf);
	DBG1(DBG_CBOPS, "ubuflen = %d\n", ubuflen);

	/*
	 * Sanity check the data buffer details.
	 */

	if (ubuflen == 0 || ubuf == NULL)
		return (EINVAL);

	if (ubuflen < kbuflen)
		return (ENOSPC);
	if (ubuflen > MAXUBUFLEN)
		return (E2BIG);

	/*
	 * Copy out the data buffer to user space.
	 */

	DBG0(DBG_CBOPS, "copying out nvlist\n");
	if (ddi_copyout((caddr_t)kbuf, ubuf, kbuflen, mode) != 0)
		return (EFAULT);

	return (0);
}
Beispiel #5
0
static int
ippctl_copyin(
	caddr_t		arg,
	int		mode,
	char		**kbufp,
	size_t		*kbuflenp)
{
	ippctl_ioctl_t	iioc;
	caddr_t		ubuf;
	char		*kbuf;
	size_t		ubuflen;

	DBG0(DBG_CBOPS, "copying in ioctl structure\n");

	/*
	 * Copy in the ioctl structure from user-space, converting from 32-bit
	 * as necessary.
	 */

#ifdef	_MULTI_DATAMODEL
	switch (ddi_model_convert_from(mode & FMODELS)) {
	case DDI_MODEL_ILP32:
		{
			ippctl_ioctl32_t	iioc32;

			DBG0(DBG_CBOPS, "converting from 32-bit\n");

			if (ddi_copyin(arg, (caddr_t)&iioc32,
			    sizeof (ippctl_ioctl32_t), mode) != 0)
				return (EFAULT);

			ubuf = (caddr_t)(uintptr_t)iioc32.ii32_buf;
			ubuflen = (size_t)iioc32.ii32_buflen;
		}
		break;
	case DDI_MODEL_NONE:
		if (ddi_copyin(arg, (caddr_t)&iioc, sizeof (ippctl_ioctl_t),
		    mode) != 0)
			return (EFAULT);

		ubuf = iioc.ii_buf;
		ubuflen = iioc.ii_buflen;
		break;
	default:
		return (EFAULT);
	}
#else	/* _MULTI_DATAMODEL */
	if (ddi_copyin(arg, (caddr_t)&iioc, sizeof (ippctl_ioctl_t),
	    mode) != 0)
		return (EFAULT);

	ubuf = iioc.ii_buf;
	ubuflen = iioc.ii_buflen;
#endif	/* _MULTI_DATAMODEL */

	DBG1(DBG_CBOPS, "ubuf = 0x%p\n", (void *)ubuf);
	DBG1(DBG_CBOPS, "ubuflen = %lu\n", ubuflen);

	/*
	 * Sanity check the command buffer information.
	 */

	if (ubuflen == 0 || ubuf == NULL)
		return (EINVAL);
	if (ubuflen > MAXUBUFLEN)
		return (E2BIG);

	/*
	 * Allocate some memory for the command buffer and copy it in.
	 */

	kbuf = kmem_zalloc(ubuflen, KM_SLEEP);
	DBG0(DBG_CBOPS, "copying in nvlist\n");
	if (ddi_copyin(ubuf, (caddr_t)kbuf, ubuflen, mode) != 0) {
		kmem_free(kbuf, ubuflen);
		return (EFAULT);
	}

	*kbufp = kbuf;
	*kbuflenp = ubuflen;
	return (0);
}
Beispiel #6
0
/*ARGSUSED*/
static int
fm_ioctl(dev_t dev, int cmd, intptr_t data, int flag, cred_t *cred, int *rvalp)
{
	char *buf;
	int err;
	uint_t model;
	const fm_subr_t *subr;
	uint32_t vers;
	fm_ioc_data_t fid;
	nvlist_t *invl = NULL, *onvl = NULL;
#ifdef _MULTI_DATAMODEL
	fm_ioc_data32_t fid32;
#endif

	if (getminor(dev) != 0)
		return (ENXIO);

	for (subr = fm_subrs; subr->cmd != cmd; subr++)
		if (subr->cmd == -1)
			return (ENOTTY);

	if (subr->priv && (flag & FWRITE) == 0 &&
	    secpolicy_sys_config(CRED(), 0) != 0)
		return (EPERM);

	model = ddi_model_convert_from(flag & FMODELS);

	switch (model) {
#ifdef _MULTI_DATAMODEL
	case DDI_MODEL_ILP32:
		if (ddi_copyin((void *)data, &fid32,
		    sizeof (fm_ioc_data32_t), flag) != 0)
			return (EFAULT);
		fid.fid_version = fid32.fid_version;
		fid.fid_insz = fid32.fid_insz;
		fid.fid_inbuf = (caddr_t)(uintptr_t)fid32.fid_inbuf;
		fid.fid_outsz = fid32.fid_outsz;
		fid.fid_outbuf = (caddr_t)(uintptr_t)fid32.fid_outbuf;
		break;
#endif /* _MULTI_DATAMODEL */
	case DDI_MODEL_NONE:
	default:
		if (ddi_copyin((void *)data, &fid, sizeof (fm_ioc_data_t),
		    flag) != 0)
			return (EFAULT);
	}

	if (nvlist_lookup_uint32(fm_vers_nvl, subr->version, &vers) != 0 ||
	    fid.fid_version != vers)
		return (ENOTSUP);

	if (fid.fid_insz > FM_IOC_MAXBUFSZ)
		return (ENAMETOOLONG);
	if (fid.fid_outsz > FM_IOC_OUT_MAXBUFSZ)
		return (EINVAL);

	/*
	 * Copy in and unpack the input nvlist.
	 */
	if (fid.fid_insz != 0 && fid.fid_inbuf != (caddr_t)0) {
		buf = kmem_alloc(fid.fid_insz, KM_SLEEP);
		if (ddi_copyin(fid.fid_inbuf, buf, fid.fid_insz, flag) != 0) {
			kmem_free(buf, fid.fid_insz);
			return (EFAULT);
		}
		err = nvlist_unpack(buf, fid.fid_insz, &invl, KM_SLEEP);
		kmem_free(buf, fid.fid_insz);
		if (err != 0)
			return (err);
	}

	err = subr->func(cmd, invl, &onvl);

	if (invl != NULL)
		nvlist_free(invl);

	if (err != 0) {
		if (onvl != NULL)
			nvlist_free(onvl);
		return (err);
	}

	/*
	 * If the output nvlist contains any data, pack it and copyout.
	 */
	if (onvl != NULL) {
		size_t sz;

		if ((err = nvlist_size(onvl, &sz, NV_ENCODE_NATIVE)) != 0) {
			nvlist_free(onvl);
			return (err);
		}
		if (sz > fid.fid_outsz) {
			nvlist_free(onvl);
			return (ENAMETOOLONG);
		}

		buf = kmem_alloc(sz, KM_SLEEP);
		if ((err = nvlist_pack(onvl, &buf, &sz, NV_ENCODE_NATIVE,
		    KM_SLEEP)) != 0) {
			kmem_free(buf, sz);
			nvlist_free(onvl);
			return (err);
		}
		nvlist_free(onvl);
		if (ddi_copyout(buf, fid.fid_outbuf, sz, flag) != 0) {
			kmem_free(buf, sz);
			return (EFAULT);
		}
		kmem_free(buf, sz);
		fid.fid_outsz = sz;

		switch (model) {
#ifdef _MULTI_DATAMODEL
		case DDI_MODEL_ILP32:
			fid32.fid_outsz = (size32_t)fid.fid_outsz;
			if (ddi_copyout(&fid32, (void *)data,
			    sizeof (fm_ioc_data32_t), flag) != 0)
				return (EFAULT);
			break;
#endif /* _MULTI_DATAMODEL */
		case DDI_MODEL_NONE:
		default:
			if (ddi_copyout(&fid, (void *)data,
			    sizeof (fm_ioc_data_t), flag) != 0)
				return (EFAULT);
		}
	}

	return (err);
}
Beispiel #7
0
/*ARGSUSED*/
static int
rmcadm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
    int *rval_p)
{
	int				instance = getminor(dev);
	int				retval = 0;
	rmcadm_request_response_t	rr;
	rmcadm_send_srecord_bp_t	ssbp;
	rmc_comm_msg_t			rmc_req, *rmc_reqp = &rmc_req;
	rmc_comm_msg_t			rmc_resp, *rmc_respp = &rmc_resp;
	caddr_t				user_req_buf;
	caddr_t				user_data_buf;
	caddr_t				user_resp_buf;

	if (instance != 0)
		return (ENXIO);

	switch (cmd) {

	case RMCADM_REQUEST_RESPONSE:
	case RMCADM_REQUEST_RESPONSE_BP:

		/*
		 * first copy in the request_response structure
		 */
#ifdef _MULTI_DATAMODEL
		switch (ddi_model_convert_from(mode & FMODELS)) {
		case DDI_MODEL_ILP32:
		{
			/*
			 * For use when a 32 bit app makes a call into a
			 * 64 bit ioctl
			 */
			rmcadm_request_response32_t	rr32;

			if (ddi_copyin((caddr_t)arg, (caddr_t)&rr32,
			    sizeof (rr32), mode)) {
				return (EFAULT);
			}
			rr.req.msg_type = rr32.req.msg_type;
			rr.req.msg_len = rr32.req.msg_len;
			rr.req.msg_bytes = rr32.req.msg_bytes;
			rr.req.msg_buf = (caddr_t)(uintptr_t)rr32.req.msg_buf;
			rr.resp.msg_type = rr32.resp.msg_type;
			rr.resp.msg_len = rr32.resp.msg_len;
			rr.resp.msg_bytes = rr32.resp.msg_bytes;
			rr.resp.msg_buf = (caddr_t)(uintptr_t)rr32.resp.msg_buf;
			rr.wait_time = rr32.wait_time;
			break;
		}
		case DDI_MODEL_NONE:
			if (ddi_copyin((caddr_t)arg, (caddr_t)&rr,
			    sizeof (rr), mode)) {
				return (EFAULT);
			}
			break;
		}
#else /* ! _MULTI_DATAMODEL */
		if (ddi_copyin((caddr_t)arg, (caddr_t)&rr,
		    sizeof (rr), mode) != 0) {
			return (EFAULT);
		}
#endif /* _MULTI_DATAMODEL */

		/*
		 * save the user request buffer pointer
		 */
		user_req_buf = rr.req.msg_buf;

		if (user_req_buf != NULL) {
			/*
			 * copy in the request data
			 */
			rr.req.msg_buf = kmem_alloc(rr.req.msg_len, KM_SLEEP);

			if (ddi_copyin(user_req_buf, rr.req.msg_buf,
			    rr.req.msg_len, mode) != 0) {

				kmem_free(rr.req.msg_buf, rr.req.msg_len);
				rr.req.msg_buf = user_req_buf;
				return (EFAULT);
			}
		} else {
			if (rr.req.msg_len > 0)
				/*
				 * msg_len should be 0 if buffer is NULL!
				 */
				return (EINVAL);
		}

		/*
		 * save the user request buffer pointer
		 */
		user_resp_buf = rr.resp.msg_buf;
		if (user_resp_buf != NULL) {
			rr.resp.msg_buf = kmem_alloc(rr.resp.msg_len, KM_SLEEP);
		}

		/*
		 * send the request (or BP request) via the rmc_comm driver
		 */
		rmc_reqp->msg_type = rr.req.msg_type;
		rmc_reqp->msg_buf = rr.req.msg_buf;
		rmc_reqp->msg_len = rr.req.msg_len;
		rmc_reqp->msg_bytes = rr.req.msg_bytes;

		if (cmd == RMCADM_REQUEST_RESPONSE) {

			/*
			 * check if response is expected. If so, fill in
			 * the response data structure
			 */
			if (rr.resp.msg_type != DP_NULL_MSG) {

				rmc_respp->msg_type = rr.resp.msg_type;
				rmc_respp->msg_buf = rr.resp.msg_buf;
				rmc_respp->msg_len = rr.resp.msg_len;
				rmc_respp->msg_bytes = rr.resp.msg_bytes;

			} else {

				rmc_respp = (rmc_comm_msg_t *)NULL;
			}

			rr.status = rmc_comm_request_response(
				    rmc_reqp, rmc_respp, rr.wait_time);

		} else { /* RMCADM_REQUEST_RESPONSE_BP */

			/*
			 * check if a BP message is expected back. If so,
			 * fill in the response data structure
			 */
			if (rr.resp.msg_buf != NULL) {

				rmc_respp->msg_type = rr.resp.msg_type;
				rmc_respp->msg_buf = rr.resp.msg_buf;
				rmc_respp->msg_len = rr.resp.msg_len;
				rmc_respp->msg_bytes = rr.resp.msg_bytes;

			} else {

				rmc_respp = (rmc_comm_msg_t *)NULL;
			}

			rr.status = rmc_comm_request_response_bp(
				    rmc_reqp, rmc_respp, rr.wait_time);
		}

		/*
		 * if a response was expected, copy back the (actual) number
		 * of bytes of the response returned by the
		 * rmc_comm_request_response function (msg_bytes field)
		 */
		if (rmc_respp != NULL) {
			rr.resp.msg_bytes = rmc_respp->msg_bytes;
		}

		if (rr.status != RCNOERR) {

			retval = rmcadm_get_errno(rr.status);

		} else if (user_resp_buf != NULL) {
			/*
			 * copy out the user response buffer
			 */
			if (ddi_copyout(rr.resp.msg_buf, user_resp_buf,
			    rr.resp.msg_bytes, mode) != 0) {
				retval = EFAULT;
			}
		}

		/*
		 * now copy out the updated request_response structure
		 */
		if (rr.req.msg_buf)
			kmem_free(rr.req.msg_buf, rr.req.msg_len);
		if (rr.resp.msg_buf)
			kmem_free(rr.resp.msg_buf, rr.resp.msg_len);

		rr.req.msg_buf = user_req_buf;
		rr.resp.msg_buf = user_resp_buf;

#ifdef _MULTI_DATAMODEL
		switch (ddi_model_convert_from(mode & FMODELS)) {
		case DDI_MODEL_ILP32:
		{
			/*
			 * For use when a 32 bit app makes a call into a
			 * 64 bit ioctl
			 */
			rmcadm_request_response32_t	rr32;

			rr32.req.msg_type = rr.req.msg_type;
			rr32.req.msg_len = rr.req.msg_len;
			rr32.req.msg_bytes = rr.req.msg_bytes;
			rr32.req.msg_buf = (caddr32_t)(uintptr_t)rr.req.msg_buf;
			rr32.resp.msg_type = rr.resp.msg_type;
			rr32.resp.msg_len = rr.resp.msg_len;
			rr32.resp.msg_bytes = rr.resp.msg_bytes;
			rr32.resp.msg_buf =
			    (caddr32_t)(uintptr_t)rr.resp.msg_buf;
			rr32.wait_time = rr.wait_time;
			rr32.status = rr.status;
			if (ddi_copyout((caddr_t)&rr32, (caddr_t)arg,
			    sizeof (rr32), mode)) {
				return (EFAULT);
			}
			break;
		}
		case DDI_MODEL_NONE:
			if (ddi_copyout((caddr_t)&rr, (caddr_t)arg,
			    sizeof (rr), mode))
				return (EFAULT);
			break;
		}
#else /* ! _MULTI_DATAMODEL */
		if (ddi_copyout((caddr_t)&rr, (caddr_t)arg, sizeof (rr),
		    mode) != 0)
			return (EFAULT);
#endif /* _MULTI_DATAMODEL */
		break;


	case RMCADM_SEND_SRECORD_BP:

		/*
		 * first copy in the request_response structure
		 */
#ifdef _MULTI_DATAMODEL
		switch (ddi_model_convert_from(mode & FMODELS)) {
		case DDI_MODEL_ILP32:
		{
			/*
			 * For use when a 32 bit app makes a call into a
			 * 64 bit ioctl
			 */
			rmcadm_send_srecord_bp32_t	ssbp32;

			if (ddi_copyin((caddr_t)arg, (caddr_t)&ssbp32,
			    sizeof (ssbp32), mode)) {
				return (EFAULT);
			}
			ssbp.data_len = ssbp32.data_len;
			ssbp.data_buf = (caddr_t)(uintptr_t)ssbp32.data_buf;
			ssbp.resp_bp.msg_type = ssbp32.resp_bp.msg_type;
			ssbp.resp_bp.msg_len = ssbp32.resp_bp.msg_len;
			ssbp.resp_bp.msg_bytes = ssbp32.resp_bp.msg_bytes;
			ssbp.resp_bp.msg_buf =
			    (caddr_t)(uintptr_t)ssbp32.resp_bp.msg_buf;
			ssbp.wait_time = ssbp32.wait_time;
			break;
		}
		case DDI_MODEL_NONE:
			if (ddi_copyin((caddr_t)arg, (caddr_t)&ssbp,
			    sizeof (ssbp), mode))
				return (EFAULT);
			break;
		}
#else /* ! _MULTI_DATAMODEL */
		if (ddi_copyin((caddr_t)arg, (caddr_t)&ssbp,
		    sizeof (ssbp), mode) != 0)
			return (EFAULT);
#endif /* _MULTI_DATAMODEL */

		/*
		 * save the user data buffer pointer
		 */
		user_data_buf = ssbp.data_buf;

		if (user_data_buf != NULL) {
			/*
			 * copy in the srecord data
			 */
			ssbp.data_buf = kmem_alloc(ssbp.data_len, KM_SLEEP);

			if (ddi_copyin(user_data_buf, ssbp.data_buf,
			    ssbp.data_len, mode) != 0) {

				kmem_free(ssbp.data_buf, ssbp.data_len);
				ssbp.data_buf = user_data_buf;
				return (EFAULT);
			}
		} else {
			return (EINVAL);	/* request can't be NULL! */
		}

		/*
		 * save the user request buffer pointer
		 */
		user_resp_buf = ssbp.resp_bp.msg_buf;
		if (user_resp_buf != NULL) {
			ssbp.resp_bp.msg_buf =
			    kmem_alloc(ssbp.resp_bp.msg_len, KM_SLEEP);
		} else {

			kmem_free(ssbp.data_buf, ssbp.data_len);
			return (EINVAL);
		}

		/*
		 * send the srecord via the rmc_comm driver and get the reply
		 * back (BP message)
		 */

		rmc_respp->msg_type = ssbp.resp_bp.msg_type;
		rmc_respp->msg_buf = ssbp.resp_bp.msg_buf;
		rmc_respp->msg_len = ssbp.resp_bp.msg_len;
		rmc_respp->msg_bytes = ssbp.resp_bp.msg_bytes;

		ssbp.status = rmc_comm_send_srecord_bp(ssbp.data_buf,
		    ssbp.data_len, rmc_respp, ssbp.wait_time);

		/*
		 * copy back the actual size of the returned message
		 */
		ssbp.resp_bp.msg_bytes = rmc_respp->msg_bytes;

		if (ssbp.status != RCNOERR) {
			retval = rmcadm_get_errno(ssbp.status);

		} else if (user_resp_buf != NULL) {
			/*
			 * copy out the user BP response buffer
			 */
			if (ddi_copyout(ssbp.resp_bp.msg_buf, user_resp_buf,
			    ssbp.resp_bp.msg_bytes, mode) != 0) {
				retval = EFAULT;
			}
		}

		/*
		 * now copy out the updated request_response structure
		 */
		if (ssbp.data_buf)
			kmem_free(ssbp.data_buf, ssbp.data_len);
		if (ssbp.resp_bp.msg_buf)
			kmem_free(ssbp.resp_bp.msg_buf, ssbp.resp_bp.msg_len);

		ssbp.data_buf = user_data_buf;
		ssbp.resp_bp.msg_buf = user_resp_buf;

#ifdef _MULTI_DATAMODEL
		switch (ddi_model_convert_from(mode & FMODELS)) {
		case DDI_MODEL_ILP32:
		{
			/*
			 * For use when a 32 bit app makes a call into a
			 * 64 bit ioctl
			 */
			rmcadm_send_srecord_bp32_t	ssbp32;

			ssbp32.data_len = ssbp.data_len;
			ssbp32.data_buf = (caddr32_t)(uintptr_t)ssbp.data_buf;
			ssbp32.resp_bp.msg_type = ssbp.resp_bp.msg_type;
			ssbp32.resp_bp.msg_len = ssbp.resp_bp.msg_len;
			ssbp32.resp_bp.msg_bytes = ssbp.resp_bp.msg_bytes;
			ssbp32.resp_bp.msg_buf =
			    (caddr32_t)(uintptr_t)ssbp.resp_bp.msg_buf;
			ssbp32.wait_time = ssbp.wait_time;

			if (ddi_copyout((caddr_t)&ssbp32, (caddr_t)arg,
			    sizeof (ssbp32), mode)) {
				return (EFAULT);
			}
			break;
		}
		case DDI_MODEL_NONE:
			if (ddi_copyout((caddr_t)&ssbp, (caddr_t)arg,
			    sizeof (ssbp), mode))
				return (EFAULT);
			break;
		}
#else /* ! _MULTI_DATAMODEL */
		if (ddi_copyout((caddr_t)&ssbp, (caddr_t)arg, sizeof (ssbp),
		    mode) != 0)
			return (EFAULT);
#endif /* _MULTI_DATAMODEL */
		break;


	case RMCADM_RESET_SP:
		pmugpio_reset();
		retval = 0;
		break;
	default:
		retval = ENOTSUP;
		break;
	}
	return (retval);
}
static int
hci1394_ioctl_read_selfid(hci1394_state_t *soft_state, void *arg, int mode)
{
	hci1394_ioctl_read_selfid_t read_selfid;
	int status;
	uint_t offset;
	uint32_t data;
#ifdef	_MULTI_DATAMODEL
	hci1394_ioctl_readselfid32_t read_selfid32;
#endif


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

#ifdef	_MULTI_DATAMODEL
	switch (ddi_model_convert_from(mode & FMODELS)) {

		/* 32-bit app in 64-bit kernel */
	case DDI_MODEL_ILP32:
		/* copy in the 32-bit version of the args */
		status = ddi_copyin(arg, &read_selfid32,
		    sizeof (hci1394_ioctl_readselfid32_t), mode);
		if (status != 0) {
			TNF_PROBE_0(hci1394_ioctl_read_selfid_ci_fail,
			    HCI1394_TNF_HAL_ERROR, "");
			TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
			    HCI1394_TNF_HAL_STACK, "");
			return (EFAULT);
		}

		/*
		 * Use a special function to process the 32-bit user address
		 * pointer embedded in the structure we pass in arg.
		 */
		status = hci1394_ioctl_read_selfid32(soft_state,
		    &read_selfid32, mode);
		return (status);
	default:
		break;
	}
#endif

	/*
	 * if we got here, we either are a 64-bit app in a 64-bit kernel or a
	 * 32-bit app in a 32-bit kernel
	 */

	/* copy in the args. We don't need to do any special conversions */
	status = ddi_copyin(arg, &read_selfid,
	    sizeof (hci1394_ioctl_read_selfid_t), mode);
	if (status != 0) {
		TNF_PROBE_0(hci1394_ioctl_read_selfid_ci_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
		    HCI1394_TNF_HAL_STACK, "");
		return (EFAULT);
	}

	/*
	 * 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_selfid_cnt_fail,
		    HCI1394_TNF_HAL_ERROR, "");
		TNF_PROBE_0_DEBUG(hci1394_ioctl_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, &read_selfid.buf[offset], 4, mode);
		if (status != 0) {
			TNF_PROBE_0(hci1394_ioctl_read_selfid_co_fail,
			    HCI1394_TNF_HAL_ERROR, "");
			TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
			    HCI1394_TNF_HAL_STACK, "");
			return (EFAULT);
		}
	}

	TNF_PROBE_0_DEBUG(hci1394_ioctl_read_selfid_exit,
	    HCI1394_TNF_HAL_STACK, "");

	return (0);
}
Beispiel #9
0
static int
iiioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *crp, int *rvp)
{
	int rc;
	int ilp32;

	ilp32 = (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32);


	switch (cmd) {
	case DSWIOC_WAIT:
		rc = _ii_wait(arg, ilp32, rvp);
		break;

	case DSWIOC_RESET:
		rc = _ii_reset(arg, ilp32, rvp);
		break;

	case DSWIOC_VERSION:
		rc = _ii_version(arg, ilp32, rvp);
		break;

	case DSWIOC_ENABLE:
		rc = _ii_config(arg, ilp32, rvp, 0);
		break;

	case DSWIOC_RESUME:
		rc = _ii_config(arg, ilp32, rvp, II_EXISTING);
		break;

	case DSWIOC_DISABLE:
		rc = _ii_disable(arg, ilp32, rvp);
		break;

	case DSWIOC_SUSPEND:
		rc = _ii_suspend(arg, ilp32, rvp);
		break;

	case DSWIOC_ACOPY:
		rc = _ii_acopy(arg, ilp32, rvp);
		break;

	case DSWIOC_COPY:
		rc = _ii_copy(arg, ilp32, rvp);
		break;

	case DSWIOC_SHUTDOWN:
		rc = _ii_shutdown(arg, rvp);
		break;

	case DSWIOC_STAT:
		rc = _ii_stat(arg, ilp32, rvp);
		break;

	case DSWIOC_BITMAP:
		rc = _ii_bitmap(arg, ilp32, rvp);
		break;

	case DSWIOC_SEGMENT:
		rc = _ii_segment(arg, ilp32, rvp);
		break;

	case DSWIOC_ABORT:
		rc = _ii_abort(arg, ilp32, rvp);
		break;

	case DSWIOC_OFFLINE:
		rc = _ii_offline(arg, ilp32, rvp);
		break;

	case DSWIOC_LIST:
		rc = _ii_list(arg, ilp32, rvp);
		break;

	case DSWIOC_LISTLEN:
	case DSWIOC_OLISTLEN:
		rc = _ii_listlen(cmd, ilp32, rvp);
		break;

	case DSWIOC_EXPORT:
		rc = _ii_export(arg, ilp32, rvp);
		break;

	case DSWIOC_IMPORT:
		rc = _ii_config(arg, ilp32, rvp, II_IMPORT);
		break;

	case DSWIOC_JOIN:
		rc = _ii_join(arg, ilp32, rvp);
		break;

	case DSWIOC_COPYP:
		rc = _ii_copyparm(arg, ilp32, rvp);
		break;

	case DSWIOC_OCREAT:
		rc = _ii_ocreate(arg, ilp32, rvp);
		break;

	case DSWIOC_OATTACH:
		rc = _ii_oattach(arg, ilp32, rvp);
		break;

	case DSWIOC_ODETACH:
		rc = _ii_odetach(arg, ilp32, rvp);
		break;

	case DSWIOC_OLIST:
		rc = _ii_olist(arg, ilp32, rvp);
		break;

	case DSWIOC_OSTAT:
		rc = _ii_ostat(arg, ilp32, rvp, FALSE);
		break;

	case DSWIOC_OSTAT2:
		rc = _ii_ostat(arg, ilp32, rvp, TRUE);
		break;

	case DSWIOC_SBITSSET:
	case DSWIOC_CBITSSET:
		rc = _ii_bitsset(arg, ilp32, cmd, rvp);
		break;

	case DSWIOC_CLIST:
		rc = _ii_gc_list(arg, ilp32, rvp, &_ii_cluster_mutex,
		    _ii_cluster_top);
		break;

	case DSWIOC_GLIST:
		rc = _ii_gc_list(arg, ilp32, rvp, &_ii_group_mutex,
		    _ii_group_top);
		break;

	case DSWIOC_MOVEGRP:
		rc = _ii_move_grp(arg, ilp32, rvp);
		break;

	case DSWIOC_CHANGETAG:
		rc = _ii_change_tag(arg, ilp32, rvp);
		break;

	default:
		rc = EINVAL;
		break;
	}

	return (rc);
}