in iphase.c [2754:2884]
static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
{
IA_CMDBUF ia_cmds;
IADEV *iadev;
int i, board;
u16 __user *tmps;
IF_EVENT(printk(">ia_ioctl\n");)
if (cmd != IA_CMD) {
if (!dev->phy->ioctl) return -EINVAL;
return dev->phy->ioctl(dev,cmd,arg);
}
if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT;
board = ia_cmds.status;
if ((board < 0) || (board > iadev_count))
board = 0;
board = array_index_nospec(board, iadev_count + 1);
iadev = ia_dev[board];
switch (ia_cmds.cmd) {
case MEMDUMP:
{
switch (ia_cmds.sub_cmd) {
case MEMDUMP_SEGREG:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
tmps = (u16 __user *)ia_cmds.buf;
for(i=0; i<0x80; i+=2, tmps++)
if(put_user((u16)(readl(iadev->seg_reg+i) & 0xffff), tmps)) return -EFAULT;
ia_cmds.status = 0;
ia_cmds.len = 0x80;
break;
case MEMDUMP_REASSREG:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
tmps = (u16 __user *)ia_cmds.buf;
for(i=0; i<0x80; i+=2, tmps++)
if(put_user((u16)(readl(iadev->reass_reg+i) & 0xffff), tmps)) return -EFAULT;
ia_cmds.status = 0;
ia_cmds.len = 0x80;
break;
case MEMDUMP_FFL:
{
ia_regs_t *regs_local;
ffredn_t *ffL;
rfredn_t *rfL;
if (!capable(CAP_NET_ADMIN)) return -EPERM;
regs_local = kmalloc(sizeof(*regs_local), GFP_KERNEL);
if (!regs_local) return -ENOMEM;
ffL = ®s_local->ffredn;
rfL = ®s_local->rfredn;
/* Copy real rfred registers into the local copy */
for (i=0; i<(sizeof (rfredn_t))/4; i++)
((u_int *)rfL)[i] = readl(iadev->reass_reg + i) & 0xffff;
/* Copy real ffred registers into the local copy */
for (i=0; i<(sizeof (ffredn_t))/4; i++)
((u_int *)ffL)[i] = readl(iadev->seg_reg + i) & 0xffff;
if (copy_to_user(ia_cmds.buf, regs_local,sizeof(ia_regs_t))) {
kfree(regs_local);
return -EFAULT;
}
kfree(regs_local);
printk("Board %d registers dumped\n", board);
ia_cmds.status = 0;
}
break;
case READ_REG:
{
if (!capable(CAP_NET_ADMIN)) return -EPERM;
desc_dbg(iadev);
ia_cmds.status = 0;
}
break;
case 0x6:
{
ia_cmds.status = 0;
printk("skb = 0x%p\n", skb_peek(&iadev->tx_backlog));
printk("rtn_q: 0x%p\n",ia_deque_rtn_q(&iadev->tx_return_q));
}
break;
case 0x8:
{
struct k_sonet_stats *stats;
stats = &PRIV(_ia_dev[board])->sonet_stats;
printk("section_bip: %d\n", atomic_read(&stats->section_bip));
printk("line_bip : %d\n", atomic_read(&stats->line_bip));
printk("path_bip : %d\n", atomic_read(&stats->path_bip));
printk("line_febe : %d\n", atomic_read(&stats->line_febe));
printk("path_febe : %d\n", atomic_read(&stats->path_febe));
printk("corr_hcs : %d\n", atomic_read(&stats->corr_hcs));
printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
printk("tx_cells : %d\n", atomic_read(&stats->tx_cells));
printk("rx_cells : %d\n", atomic_read(&stats->rx_cells));
}
ia_cmds.status = 0;
break;
case 0x9:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
for (i = 1; i <= iadev->num_rx_desc; i++)
free_desc(_ia_dev[board], i);
writew( ~(RX_FREEQ_EMPT | RX_EXCP_RCVD),
iadev->reass_reg+REASS_MASK_REG);
iadev->rxing = 1;
ia_cmds.status = 0;
break;
case 0xb:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
ia_frontend_intr(iadev);
break;
case 0xa:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
{
ia_cmds.status = 0;
IADebugFlag = ia_cmds.maddr;
printk("New debug option loaded\n");
}
break;
default:
ia_cmds.status = 0;
break;
}
}
break;
default:
break;
}
return 0;
}