in clients/hsi_char.c [525:577]
static long hsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct hsc_channel *channel = file->private_data;
unsigned int state;
struct hsc_rx_config rxc;
struct hsc_tx_config txc;
long ret = 0;
switch (cmd) {
case HSC_RESET:
hsi_flush(channel->cl);
break;
case HSC_SET_PM:
if (copy_from_user(&state, (void __user *)arg, sizeof(state)))
return -EFAULT;
if (state == HSC_PM_DISABLE) {
if (test_and_set_bit(HSC_CH_WLINE, &channel->flags))
return -EINVAL;
ret = hsi_start_tx(channel->cl);
} else if (state == HSC_PM_ENABLE) {
if (!test_and_clear_bit(HSC_CH_WLINE, &channel->flags))
return -EINVAL;
ret = hsi_stop_tx(channel->cl);
} else {
ret = -EINVAL;
}
break;
case HSC_SEND_BREAK:
return hsc_break_send(channel->cl);
case HSC_SET_RX:
if (copy_from_user(&rxc, (void __user *)arg, sizeof(rxc)))
return -EFAULT;
return hsc_rx_set(channel->cl, &rxc);
case HSC_GET_RX:
hsc_rx_get(channel->cl, &rxc);
if (copy_to_user((void __user *)arg, &rxc, sizeof(rxc)))
return -EFAULT;
break;
case HSC_SET_TX:
if (copy_from_user(&txc, (void __user *)arg, sizeof(txc)))
return -EFAULT;
return hsc_tx_set(channel->cl, &txc);
case HSC_GET_TX:
hsc_tx_get(channel->cl, &txc);
if (copy_to_user((void __user *)arg, &txc, sizeof(txc)))
return -EFAULT;
break;
default:
return -ENOIOCTLCMD;
}
return ret;
}