in ipmi/ipmi_devintf.c [294:616]
static long ipmi_ioctl(struct file *file,
unsigned int cmd,
unsigned long data)
{
int rv = -EINVAL;
struct ipmi_file_private *priv = file->private_data;
void __user *arg = (void __user *)data;
switch (cmd)
{
case IPMICTL_SEND_COMMAND:
{
struct ipmi_req req;
int retries;
unsigned int retry_time_ms;
if (copy_from_user(&req, arg, sizeof(req))) {
rv = -EFAULT;
break;
}
mutex_lock(&priv->recv_mutex);
retries = priv->default_retries;
retry_time_ms = priv->default_retry_time_ms;
mutex_unlock(&priv->recv_mutex);
rv = handle_send_req(priv->user, &req, retries, retry_time_ms);
break;
}
case IPMICTL_SEND_COMMAND_SETTIME:
{
struct ipmi_req_settime req;
if (copy_from_user(&req, arg, sizeof(req))) {
rv = -EFAULT;
break;
}
rv = handle_send_req(priv->user,
&req.req,
req.retries,
req.retry_time_ms);
break;
}
case IPMICTL_RECEIVE_MSG:
case IPMICTL_RECEIVE_MSG_TRUNC:
{
struct ipmi_recv rsp;
if (copy_from_user(&rsp, arg, sizeof(rsp)))
rv = -EFAULT;
else
rv = handle_recv(priv, cmd == IPMICTL_RECEIVE_MSG_TRUNC,
&rsp, copyout_recv, arg);
break;
}
case IPMICTL_REGISTER_FOR_CMD:
{
struct ipmi_cmdspec val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
IPMI_CHAN_ALL);
break;
}
case IPMICTL_UNREGISTER_FOR_CMD:
{
struct ipmi_cmdspec val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
IPMI_CHAN_ALL);
break;
}
case IPMICTL_REGISTER_FOR_CMD_CHANS:
{
struct ipmi_cmdspec_chans val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
val.chans);
break;
}
case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
{
struct ipmi_cmdspec_chans val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
val.chans);
break;
}
case IPMICTL_SET_GETS_EVENTS_CMD:
{
int val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_set_gets_events(priv->user, val);
break;
}
/* The next four are legacy, not per-channel. */
case IPMICTL_SET_MY_ADDRESS_CMD:
{
unsigned int val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_set_my_address(priv->user, 0, val);
break;
}
case IPMICTL_GET_MY_ADDRESS_CMD:
{
unsigned int val;
unsigned char rval;
rv = ipmi_get_my_address(priv->user, 0, &rval);
if (rv)
break;
val = rval;
if (copy_to_user(arg, &val, sizeof(val))) {
rv = -EFAULT;
break;
}
break;
}
case IPMICTL_SET_MY_LUN_CMD:
{
unsigned int val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_set_my_LUN(priv->user, 0, val);
break;
}
case IPMICTL_GET_MY_LUN_CMD:
{
unsigned int val;
unsigned char rval;
rv = ipmi_get_my_LUN(priv->user, 0, &rval);
if (rv)
break;
val = rval;
if (copy_to_user(arg, &val, sizeof(val))) {
rv = -EFAULT;
break;
}
break;
}
case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:
{
struct ipmi_channel_lun_address_set val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
return ipmi_set_my_address(priv->user, val.channel, val.value);
}
case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD:
{
struct ipmi_channel_lun_address_set val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_get_my_address(priv->user, val.channel, &val.value);
if (rv)
break;
if (copy_to_user(arg, &val, sizeof(val))) {
rv = -EFAULT;
break;
}
break;
}
case IPMICTL_SET_MY_CHANNEL_LUN_CMD:
{
struct ipmi_channel_lun_address_set val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);
break;
}
case IPMICTL_GET_MY_CHANNEL_LUN_CMD:
{
struct ipmi_channel_lun_address_set val;
if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);
if (rv)
break;
if (copy_to_user(arg, &val, sizeof(val))) {
rv = -EFAULT;
break;
}
break;
}
case IPMICTL_SET_TIMING_PARMS_CMD:
{
struct ipmi_timing_parms parms;
if (copy_from_user(&parms, arg, sizeof(parms))) {
rv = -EFAULT;
break;
}
mutex_lock(&priv->recv_mutex);
priv->default_retries = parms.retries;
priv->default_retry_time_ms = parms.retry_time_ms;
mutex_unlock(&priv->recv_mutex);
rv = 0;
break;
}
case IPMICTL_GET_TIMING_PARMS_CMD:
{
struct ipmi_timing_parms parms;
mutex_lock(&priv->recv_mutex);
parms.retries = priv->default_retries;
parms.retry_time_ms = priv->default_retry_time_ms;
mutex_unlock(&priv->recv_mutex);
if (copy_to_user(arg, &parms, sizeof(parms))) {
rv = -EFAULT;
break;
}
rv = 0;
break;
}
case IPMICTL_GET_MAINTENANCE_MODE_CMD:
{
int mode;
mode = ipmi_get_maintenance_mode(priv->user);
if (copy_to_user(arg, &mode, sizeof(mode))) {
rv = -EFAULT;
break;
}
rv = 0;
break;
}
case IPMICTL_SET_MAINTENANCE_MODE_CMD:
{
int mode;
if (copy_from_user(&mode, arg, sizeof(mode))) {
rv = -EFAULT;
break;
}
rv = ipmi_set_maintenance_mode(priv->user, mode);
break;
}
default:
rv = -ENOTTY;
break;
}
return rv;
}