/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/rmc_comm_dp.h>
#include <sys/rmc_comm_dp_boot.h>
#include <sys/rmc_comm_drvintf.h>
#include <sys/rmc_comm.h>
#include <sys/machsystm.h>
/*
* functions local to this driver.
*/
void **resultp);
/*
* Driver entry points
*/
rmcadm_open, /* open */
rmcadm_close, /* close */
nodev, /* strategy() */
nodev, /* print() */
nodev, /* dump() */
nodev, /* read() */
nodev, /* write() */
rmcadm_ioctl, /* ioctl() */
nodev, /* devmap() */
nodev, /* mmap() */
ddi_segmap, /* segmap() */
nochpoll, /* poll() */
ddi_prop_op, /* prop_op() */
NULL, /* cb_str */
};
0, /* ref count */
rmcadm_getinfo, /* getinfo() */
nulldev, /* identify() */
nulldev, /* probe() */
rmcadm_attach, /* attach() */
rmcadm_detach, /* detach */
nodev, /* reset */
&rmcadm_cb_ops, /* pointer to cb_ops structure */
nulldev, /* power() */
ddi_quiesce_not_needed, /* quiesce */
};
/*
* Loadable module support.
*/
extern struct mod_ops mod_driverops;
&mod_driverops, /* Type of module. This is a driver */
"rmcadm control driver", /* Name of the module */
&rmcadm_ops /* pointer to the dev_ops structure */
};
&modldrv,
};
extern void pmugpio_reset();
/*
* Utilities...
*/
/*
* to return the errno from the rmc_comm error status
*/
int
{
/* errors from RMC */
switch (status) {
case RCENOSOFTSTATE:
break;
case RCENODATALINK:
/* data protocol not available (down) */
break;
case RCENOMEM:
/* memory problems */
break;
case RCECANTRESEND:
/* resend failed */
break;
case RCEMAXRETRIES:
/* reply not received - retries exceeded */
break;
case RCETIMEOUT:
/* reply not received - command has timed out */
break;
case RCEINVCMD:
/* data protocol cmd not supported */
break;
case RCEINVARG:
/* invalid argument(s) */
break;
case RCEGENERIC:
/* generic error */
break;
default:
break;
}
return (retval);
}
int
_init(void)
{
int error = 0;
return (error);
}
int
{
}
int
_fini(void)
{
int error = 0;
if (error)
return (error);
return (error);
}
/* ARGSUSED */
static int
{
switch (cmd) {
case DDI_INFO_DEVT2DEVINFO:
if ((m != 0) || (rmcadm_dip == NULL)) {
return (DDI_FAILURE);
}
*resultp = rmcadm_dip;
return (DDI_SUCCESS);
case DDI_INFO_DEVT2INSTANCE:
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
}
static int
{
int instance;
int err;
switch (cmd) {
case DDI_ATTACH:
/*
* only allow one instance
*/
if (instance != 0)
return (DDI_FAILURE);
if (err != DDI_SUCCESS)
return (DDI_FAILURE);
/*
* Register with rmc_comm to prevent it being detached
*/
err = rmc_comm_register();
if (err != DDI_SUCCESS) {
return (DDI_FAILURE);
}
/* Remember the dev info */
rmcadm_dip = dip;
return (DDI_SUCCESS);
case DDI_RESUME:
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
}
static int
{
int instance;
switch (cmd) {
case DDI_DETACH:
if (instance != 0)
return (DDI_FAILURE);
rmcadm_dip = NULL;
return (DDI_SUCCESS);
case DDI_SUSPEND:
return (DDI_SUCCESS);
default:
return (DDI_FAILURE);
}
}
/*ARGSUSED*/
static int
{
int error = 0;
if (instance != 0)
return (ENXIO);
instance);
return (error);
}
return (error);
}
/*ARGSUSED*/
static int
{
return (DDI_SUCCESS);
}
/*ARGSUSED*/
static int
int *rval_p)
{
int retval = 0;
if (instance != 0)
return (ENXIO);
switch (cmd) {
case RMCADM_REQUEST_RESPONSE:
/*
* first copy in the request_response structure
*/
#ifdef _MULTI_DATAMODEL
case DDI_MODEL_ILP32:
{
/*
* For use when a 32 bit app makes a call into a
* 64 bit ioctl
*/
return (EFAULT);
}
break;
}
case DDI_MODEL_NONE:
return (EFAULT);
}
break;
}
#else /* ! _MULTI_DATAMODEL */
return (EFAULT);
}
#endif /* _MULTI_DATAMODEL */
/*
* save the user request buffer pointer
*/
if (user_req_buf != NULL) {
/*
* copy in the request data
*/
return (EFAULT);
}
} else {
/*
* msg_len should be 0 if buffer is NULL!
*/
return (EINVAL);
}
/*
* save the user request buffer pointer
*/
if (user_resp_buf != NULL) {
}
/*
* send the request (or BP request) via the rmc_comm driver
*/
if (cmd == RMCADM_REQUEST_RESPONSE) {
/*
* check if response is expected. If so, fill in
* the response data structure
*/
} else {
}
} else { /* RMCADM_REQUEST_RESPONSE_BP */
/*
* check if a BP message is expected back. If so,
* fill in the response data structure
*/
} else {
}
}
/*
* 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)
*/
}
} else if (user_resp_buf != NULL) {
/*
* copy out the user response buffer
*/
}
}
/*
* now copy out the updated request_response structure
*/
#ifdef _MULTI_DATAMODEL
case DDI_MODEL_ILP32:
{
/*
* For use when a 32 bit app makes a call into a
* 64 bit ioctl
*/
return (EFAULT);
}
break;
}
case DDI_MODEL_NONE:
return (EFAULT);
break;
}
#else /* ! _MULTI_DATAMODEL */
mode) != 0)
return (EFAULT);
#endif /* _MULTI_DATAMODEL */
break;
case RMCADM_SEND_SRECORD_BP:
/*
* first copy in the request_response structure
*/
#ifdef _MULTI_DATAMODEL
case DDI_MODEL_ILP32:
{
/*
* For use when a 32 bit app makes a call into a
* 64 bit ioctl
*/
return (EFAULT);
}
break;
}
case DDI_MODEL_NONE:
return (EFAULT);
break;
}
#else /* ! _MULTI_DATAMODEL */
return (EFAULT);
#endif /* _MULTI_DATAMODEL */
/*
* save the user data buffer pointer
*/
if (user_data_buf != NULL) {
/*
* copy in the srecord data
*/
return (EFAULT);
}
} else {
return (EINVAL); /* request can't be NULL! */
}
/*
* save the user request buffer pointer
*/
if (user_resp_buf != NULL) {
} else {
return (EINVAL);
}
/*
* send the srecord via the rmc_comm driver and get the reply
* back (BP message)
*/
/*
* copy back the actual size of the returned message
*/
} else if (user_resp_buf != NULL) {
/*
* copy out the user BP response buffer
*/
}
}
/*
* now copy out the updated request_response structure
*/
#ifdef _MULTI_DATAMODEL
case DDI_MODEL_ILP32:
{
/*
* For use when a 32 bit app makes a call into a
* 64 bit ioctl
*/
return (EFAULT);
}
break;
}
case DDI_MODEL_NONE:
return (EFAULT);
break;
}
#else /* ! _MULTI_DATAMODEL */
mode) != 0)
return (EFAULT);
#endif /* _MULTI_DATAMODEL */
break;
case RMCADM_RESET_SP:
retval = 0;
break;
default:
break;
}
return (retval);
}