static int ia_ioctl()

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 = &regs_local->ffredn;
	     rfL = &regs_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;  
}