void MBXSyncSrv_MMapGetFullMapDataHandler(IMG_VOID *pvData)
{
	IMG_PVOID pvKVBase;
	IMG_UINT32 ui32BaseBytes;
	IMG_UINT32 ui32Offset;
	PVR_MMAP_TYPE eMapType;
	MBXUserDataForMMapGetFullMapData infoFromUser;
	
	COPY_FROM_USER((void*)&infoFromUser, pvData, sizeof(MBXUserDataForMMapGetFullMapData));

	infoFromUser.err = PVRMMapGetFullMapData(
								infoFromUser.pvKVAddr,
								infoFromUser.ui32Bytes,
								&pvKVBase,
								&ui32BaseBytes,
								&ui32Offset,
								&eMapType);

	infoFromUser.pvKVBase = pvKVBase;
	infoFromUser.ui32BaseBytes = ui32BaseBytes;
	infoFromUser.ui32Offset = ui32Offset;
	infoFromUser.eMapType = eMapType;

	COPY_TO_USER(pvData,(void*)&infoFromUser, sizeof(MBXUserDataForMMapGetFullMapData));
}
void MBXSyncSrv_HostWriteHWRegHandler(IMG_VOID *pvData)
{
	MBXUserDataForHostHWReg infoFromUser;
	COPY_FROM_USER((void*)&infoFromUser, pvData, sizeof(MBXUserDataForHostHWReg));

	writel(infoFromUser.value, infoFromUser.pBaseAddr + infoFromUser.offset);
	mb();
}
void MBXSyncSrv_HostReadHWRegHandler(IMG_VOID *pvData)
{
	MBXUserDataForHostHWReg infoFromUser;
	
	COPY_FROM_USER((void*)&infoFromUser, pvData, sizeof(MBXUserDataForHostHWReg));

	infoFromUser.value = readl(infoFromUser.pBaseAddr+infoFromUser.offset);
	
	COPY_TO_USER(pvData,(void*)&infoFromUser, sizeof(MBXUserDataForHostHWReg));
}
long msm_irqrouter_subdev_ioctl(struct v4l2_subdev *sd,
	unsigned int cmd, void *arg)
{
	struct irqrouter_ctrl_type *irqrouter_ctrl = v4l2_get_subdevdata(sd);
	struct msm_camera_irq_cfg *irq_cfg;
	struct intr_table_entry irq_req;
	int rc = 0;

	/* Handle all IRQ Router Subdev IOCTLs here.
	 * Userspace sends the composite irq configuration.
	 * IRQ Router subdev then configures the registers to group
	 * together individual core hw irqs into a composite IRQ
	 * to the MSM IRQ controller. It also registers them with
	 * the irq manager in the camera server. */
	switch (cmd) {
	case MSM_IRQROUTER_CFG_COMPIRQ:
		COPY_FROM_USER(rc, &irq_cfg, (void __user *)arg,
			sizeof(struct msm_camera_irq_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		if (!irq_cfg ||
			(irq_cfg->irq_idx < CAMERA_SS_IRQ_0) ||
			(irq_cfg->irq_idx >= CAMERA_SS_IRQ_MAX)) {
			pr_err("%s Invalid input", __func__);
			return -EINVAL;
		} else {
			irq_req.cam_hw_mask      = irq_cfg->cam_hw_mask;
			irq_req.irq_idx          = irq_cfg->irq_idx;
			irq_req.irq_num          =
			irqrouter_ctrl->def_hw_irqmap[irq_cfg->irq_idx].irq_num;
			irq_req.is_composite     = 1;
			irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
			irq_req.num_hwcore       = irq_cfg->num_hwcore;
			irq_req.data             = NULL;
			rc = msm_cam_server_request_irq(&irq_req);
			if (rc < 0) {
				pr_err("%s Error requesting comp irq %d ",
					__func__, irq_req.irq_idx);
				return rc;
			}
			irqrouter_ctrl->def_hw_irqmap
				[irq_cfg->irq_idx].is_composite = 1;
		}
		break;
	default:
		pr_err("%s Invalid cmd %d ", __func__, cmd);
		break;
	}

	return rc;
}
Esempio n. 5
0
static int find_code_size(unsigned char* ud)
{
  int size=0;

  while (1) {
    unsigned char c;
    COPY_FROM_USER(&c,ud+size+2,1);
    switch(c) {
    case 0xa0: size+=4; break;
    case 0xe0: size+=6; break;
    case 0x90: size+=4; break;
    case 0xd0: size+=6; break;
    case 0x80: size+=6; break;
    case 0xc0: size+=8; break;
    default: return size;
    }
    size+=2;
  }
}
Esempio n. 6
0
int uae_handle_fault(struct pt_regs *regs, unsigned long error_code,
		     unsigned long address)
{
  error_code=5;
  if (current==fpf.task && 
      address==fpf.addr &&
      fpf.handler &&
      (error_code&1) &&  /* protection fault, rather than page fault */
      (error_code&4)) {  /* In user mode */
    /* Do it */
    unsigned long x;
    fpf_eip=regs->eip;
    if (COPY_FROM_USER(&x,(const void*)(fpf_eip+6), sizeof(x)))
      return 0;
    regs->eip=x;
    return 1;
  }
  return 0;
}
Esempio n. 7
0
static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd,
				struct msm_cam_media_controller *mctl)
{
	int rc = 0;

	switch (vpe_cmd->cmd_type) {
	case VPE_CMD_RESET:
		rc = vpe_reset();
		break;

	case VPE_CMD_OPERATION_MODE_CFG: {
		struct msm_vpe_op_mode_cfg op_mode_cfg;
		if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_op_mode_cfg));
			rc = -EINVAL;
			break;
		}
		COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value,
			sizeof(op_mode_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&op_mode_cfg;
		rc = vpe_operation_config(vpe_cmd->value);
		break;
		}

	case VPE_CMD_INPUT_PLANE_CFG: {
		struct msm_vpe_input_plane_cfg input_cfg;
		if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) {
			pr_err("%s: mismatch cmd = %d, len = %d, expected = %d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_input_plane_cfg));
			rc = -EINVAL;
			break;
		}
		COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value,
			sizeof(input_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&input_cfg;
		vpe_input_plane_config(vpe_cmd->value);
		break;
		}

	case VPE_CMD_OUTPUT_PLANE_CFG: {
		struct msm_vpe_output_plane_cfg output_cfg;
		if (sizeof(struct msm_vpe_output_plane_cfg) !=
			vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_output_plane_cfg));
				rc = -EINVAL;
				break;
		}
		COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value,
			sizeof(output_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&output_cfg;
		vpe_output_plane_config(vpe_cmd->value);
		break;
		}

	case VPE_CMD_SCALE_CFG_TYPE:{
		struct msm_vpe_scaler_cfg scaler_cfg;
		if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_scaler_cfg));
			rc = -EINVAL;
			break;
		}
		COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value,
			sizeof(scaler_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&scaler_cfg;
		vpe_update_scale_coef(vpe_cmd->value);
		break;
		}

	case VPE_CMD_ZOOM: {
		struct msm_mctl_pp_frame_info *zoom;
		zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info),
				GFP_ATOMIC);
		if (!zoom) {
			pr_err("%s Not enough memory ", __func__);
			rc = -ENOMEM;
			break;
		}

		if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) {
			pr_err("%s: size mismatch id=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(zoom->pp_frame_cmd));
			rc = -EINVAL;
			kfree(zoom);
			break;
		}
		COPY_FROM_USER(rc, &zoom->pp_frame_cmd,
			(void __user *)vpe_cmd->value,
			sizeof(zoom->pp_frame_cmd));
		if (rc) {
			ERR_COPY_FROM_USER();
			kfree(zoom);
			break;
		}

		zoom->user_cmd = vpe_cmd->cmd_type;
		zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev);
		D("%s: cookie=0x%x,action=0x%x,path=0x%x",
			__func__, zoom->pp_frame_cmd.cookie,
			zoom->pp_frame_cmd.vpe_output_action,
			zoom->pp_frame_cmd.path);

		D("%s Mapping Source frame ", __func__);
		zoom->src_frame.frame = zoom->pp_frame_cmd.src_frame;
		rc = msm_mctl_map_user_frame(&zoom->src_frame,
			zoom->p_mctl->client, mctl->domain_num);
		if (rc < 0) {
			pr_err("%s Error mapping source buffer rc = %d",
				__func__, rc);
			kfree(zoom);
			break;
		}

		D("%s Mapping Destination frame ", __func__);
		zoom->dest_frame.frame = zoom->pp_frame_cmd.dest_frame;
		rc = msm_mctl_map_user_frame(&zoom->dest_frame,
			zoom->p_mctl->client, mctl->domain_num);
		if (rc < 0) {
			pr_err("%s Error mapping dest buffer rc = %d",
				__func__, rc);
			msm_mctl_unmap_user_frame(&zoom->src_frame,
				zoom->p_mctl->client, mctl->domain_num);
			kfree(zoom);
			break;
		}

		rc = msm_vpe_do_pp(zoom);
		break;
		}

	case VPE_CMD_ENABLE: {
		struct msm_vpe_clock_rate clk_rate;
		int turbo_mode;
		if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_clock_rate));
			rc = -EINVAL;
			break;
		}
		if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value,
			sizeof(struct msm_vpe_clock_rate))) {
			pr_err("%s:clk_rate copy failed", __func__);
			return -EFAULT;
		}
		turbo_mode = (int)clk_rate.rate;
		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE, mctl) :
				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE, mctl);
		break;
		}

	case VPE_CMD_DISABLE:
#ifdef CONFIG_PANTECH_CAMERA
		if (vpe_ctrl->pp_frame_info) {
			pr_err("%s : vpe_ctrl->pp_frame_info = %p ", __func__, vpe_ctrl->pp_frame_info);
			msm_mctl_unmap_user_frame(&vpe_ctrl->pp_frame_info->src_frame,
				vpe_ctrl->pp_frame_info->p_mctl->client, mctl->domain_num);
			msm_mctl_unmap_user_frame(&vpe_ctrl->pp_frame_info->dest_frame,
				vpe_ctrl->pp_frame_info->p_mctl->client, mctl->domain_num);
			kfree(vpe_ctrl->pp_frame_info);
			vpe_ctrl->pp_frame_info = NULL;			
		}
#endif
		rc = vpe_disable(mctl);
		break;

	default:
		break;
	}

	return rc;
}
static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd)
{
	int rc = 0;

	switch (vpe_cmd->cmd_type) {
	case VPE_CMD_RESET:
		rc = vpe_reset();
		break;

	case VPE_CMD_OPERATION_MODE_CFG: {
		struct msm_vpe_op_mode_cfg op_mode_cfg;
		if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_op_mode_cfg));
			rc = -EINVAL;
			break;
		}
		COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value,
			sizeof(op_mode_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&op_mode_cfg;
		rc = vpe_operation_config(vpe_cmd->value);
		break;
		}

	case VPE_CMD_INPUT_PLANE_CFG: {
		struct msm_vpe_input_plane_cfg input_cfg;
		if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) {
			pr_err("%s: mismatch cmd = %d, len = %d, expected = %d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_input_plane_cfg));
			rc = -EINVAL;
			break;
		}
		COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value,
			sizeof(input_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&input_cfg;
		vpe_input_plane_config(vpe_cmd->value);
		break;
		}

	case VPE_CMD_OUTPUT_PLANE_CFG: {
		struct msm_vpe_output_plane_cfg output_cfg;
		if (sizeof(struct msm_vpe_output_plane_cfg) !=
			vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_output_plane_cfg));
				rc = -EINVAL;
				break;
		}
		COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value,
			sizeof(output_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&output_cfg;
		vpe_output_plane_config(vpe_cmd->value);
		break;
		}

	case VPE_CMD_SCALE_CFG_TYPE:{
		struct msm_vpe_scaler_cfg scaler_cfg;
		if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_scaler_cfg));
			rc = -EINVAL;
			break;
		}
		COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value,
			sizeof(scaler_cfg));
		if (rc) {
			ERR_COPY_FROM_USER();
			break;
		}

		vpe_cmd->value = (void *)&scaler_cfg;
		vpe_update_scale_coef(vpe_cmd->value);
		break;
		}

	case VPE_CMD_ZOOM: {
		struct msm_mctl_pp_frame_info *zoom;
		zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info),
				GFP_ATOMIC);
		if (!zoom) {
			pr_err("%s Not enough memory ", __func__);
			rc = -ENOMEM;
			break;
		}

		if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) {
			pr_err("%s: size mismatch id=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(zoom->pp_frame_cmd));
			rc = -EINVAL;
			kfree(zoom);
			break;
		}
		COPY_FROM_USER(rc, &zoom->pp_frame_cmd,
			(void __user *)vpe_cmd->value,
			sizeof(zoom->pp_frame_cmd));
		if (rc) {
			ERR_COPY_FROM_USER();
			kfree(zoom);
			break;
		}

		zoom->user_cmd = vpe_cmd->cmd_type;
		zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev);
		D("%s: src=0x%x, dest=0x%x,cookie=0x%x,action=0x%x,path=0x%x",
			__func__, zoom->pp_frame_cmd.src_buf_handle,
			zoom->pp_frame_cmd.dest_buf_handle,
			zoom->pp_frame_cmd.cookie,
			zoom->pp_frame_cmd.vpe_output_action,
			zoom->pp_frame_cmd.path);
		rc = msm_mctl_pp_get_vpe_buf_info(zoom);
		if (rc < 0) {
			pr_err("%s Error getting buffer info from mctl rc = %d",
				__func__, rc);
			kfree(zoom);
			break;
		}
		rc = msm_vpe_do_pp(zoom);
		kfree(zoom);
		break;
		}

	case VPE_CMD_ENABLE: {
		struct msm_vpe_clock_rate clk_rate;
		int turbo_mode;
		if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) {
			pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d",
				__func__, vpe_cmd->cmd_type, vpe_cmd->length,
				sizeof(struct msm_vpe_clock_rate));
			rc = -EINVAL;
			break;
		}
		if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value,
			sizeof(struct msm_vpe_clock_rate))) {
			pr_err("%s:clk_rate copy failed", __func__);
			return -EFAULT;
		}
		turbo_mode = (int)clk_rate.rate;
		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE) :
				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE);
		break;
		}

	case VPE_CMD_DISABLE:
		rc = vpe_disable();
		break;

	default:
		break;
	}

	return rc;
}
Esempio n. 9
0
static int pcicommand(pcidata* x)
{
  struct pci_dev* sh=(struct pci_dev*)x->starthandle;

  switch(x->command) {
  case CMD_FIND_SLOT:
    x->handle=(unsigned long)pci_find_slot(x->busnum,
					   PCI_DEVFN(x->devnum,x->funnum));
    return 0;
  case CMD_FIND_SUBSYS:
    x->handle=(unsigned long)pci_find_subsys(x->vendor,
					     x->device,
					     x->subsys_vendor,
					     x->subsys_device,
					     sh);
    return 0;
  case CMD_FIND_DEVICE:
    x->handle=(unsigned long)pci_find_device(x->vendor,
					     x->device,
					     sh);
    return 0;
  case CMD_FIND_CLASS:
    x->handle=(unsigned long)pci_find_class(x->class,
					    sh);
    return 0;
  case CMD_FIND_CAPAB:
    x->cappos=pci_find_capability(sh,
				  x->capability);
    return 0;
  case CMD_SET_POWER:
    x->oldpowerstate=pci_set_power_state(sh,
					 x->powerstate);
    return 0;
  case CMD_ENABLE:
    x->result=pci_enable_device(sh);
    return 0;
  case CMD_DISABLE:
    pci_disable_device(sh);
    return 0;
  case CMD_RELEASE:
    release_device(sh,0);
    return 0;
  case CMD_REQUEST:
    {
      char* name;
      
      if (x->res_name) {
	int len;
	char c;
	int i;

	len=0;
	while (!COPY_FROM_USER(&c, x->res_name+len,1)) {
	  if (!c)
	    break;
	  len++;
	}
	name=kmalloc(len+1,GFP_KERNEL);
	for (i=0;i<len;i++) {
	  name[i]=0;
	  COPY_FROM_USER(name+i, x->res_name+i,1);
	}
	name[i]=0;
      }
      else {
	name=kmalloc(22,GFP_KERNEL);
	strcpy(name,"amithlon pci system");
      }

      x->result=pci_request_regions(sh,name);
      if (!x->result) { /* Successful */
	pci_list* n=kmalloc(sizeof(pci_list),GFP_KERNEL);
	n->dev=sh;
	if (x->releasecode) {
	  int size=find_code_size(x->releasecode);
	  n->releasecode=kmalloc(size,GFP_KERNEL);
	  COPY_FROM_USER(n->releasecode,x->releasecode,size);
	}
	else 
	  n->releasecode=NULL;
	n->name=name;
	n->next=devlist;
	n->prev_p=&devlist;
	if (devlist)
	  devlist->prev_p=&(n->next);
	devlist=n;
      }
      else {
	kfree(name);
      }
    }
    return 0;
    
  case CMD_READBYTE:
    x->confdata=0;
    x->result=pci_read_config_byte(sh,
				   x->offset,
				   (u8*)&(x->confdata));
    return 0;

  case CMD_READWORD:
    x->confdata=0;
    x->result=pci_read_config_word(sh,
				   x->offset,
				   (u16*)&(x->confdata));
    return 0;
  case CMD_READLONG:
    x->confdata=0;
    x->result=pci_read_config_dword(sh,
				    x->offset,
				    (u32*)&(x->confdata));
    return 0;
  case CMD_WRITEBYTE:
    x->result=pci_write_config_byte(sh,
				    x->offset,
				    (u8)(x->confdata));
    return 0;
  case CMD_WRITEWORD:
    x->result=pci_write_config_word(sh,
				    x->offset,
				    (u16)(x->confdata));
    return 0;
  case CMD_WRITELONG:
    x->result=pci_write_config_dword(sh,
				     x->offset,
				     (u32)(x->confdata));
    return 0;
    
  case CMD_GETBASE:
    x->start=sh->resource[x->basenum].start;
    x->end=sh->resource[x->basenum].end;
    x->flags=sh->resource[x->basenum].flags;
    return 0;

  case CMD_GETINFO:
    x->irq=sh->irq;
    x->devnum=PCI_SLOT(sh->devfn);
    x->funnum=PCI_FUNC(sh->devfn);
    x->busnum=sh->bus->number;
    return 0;

  case CMD_GETNAME:
    {
      int len=0;
      do {  
	if (COPY_TO_USER((void*)(x->res_name+len),(void*)(sh->name+len),1))
	  return -EFAULT;
      } while (sh->name[len++]);
    }
    return 0;
  default:
    return -EINVAL;
  }
}
Esempio n. 10
0
/* n_hdlc_tty_write()
 * 
 * 	write a single frame of data to device
 * 	
 * Arguments:	tty	pointer to associated tty device instance data
 * 		file	pointer to file object data
 * 		data	pointer to transmit data (one frame)
 * 		count	size of transmit frame in bytes
 * 		
 * Return Value:	number of bytes written (or error code)
 */
static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
	const __u8 * data, rw_count_t count)
{
	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
	int error = 0;
	DECLARE_WAITQUEUE(wait, current);
	N_HDLC_BUF *tbuf;

	if (debuglevel >= DEBUG_LEVEL_INFO)	
		printk("%s(%d)n_hdlc_tty_write() called count=%d\n",
			__FILE__,__LINE__,count);
		
	/* Verify pointers */
	if (!n_hdlc)
		return -EIO;

	if (n_hdlc->magic != HDLC_MAGIC)
		return -EIO;

	/* verify frame size */
	if (count > maxframe ) {
		if (debuglevel & DEBUG_LEVEL_INFO)
			printk (KERN_WARNING
				"n_hdlc_tty_write: truncating user packet "
				"from %lu to %d\n", (unsigned long) count,
				maxframe );
		count = maxframe;
	}
	
	add_wait_queue(&n_hdlc->write_wait, &wait);
	set_current_state(TASK_INTERRUPTIBLE);
	
	/* Allocate transmit buffer */
	/* sleep until transmit buffer available */		
	while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
		schedule();
			
		n_hdlc = tty2n_hdlc (tty);
		if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
		    tty != n_hdlc->tty) {
			printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
			error = -EIO;
			break;
		}
			
		if (signal_pending(current)) {
			error = -EINTR;
			break;
		}
	}

	set_current_state(TASK_RUNNING);
	remove_wait_queue(&n_hdlc->write_wait, &wait);

	if (!error) {		
		/* Retrieve the user's buffer */
		COPY_FROM_USER (error, tbuf->buf, data, count);
		if (error) {
			/* return tx buffer to free list */
			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
		} else {
			/* Send the data */
			tbuf->count = error = count;
			n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
			n_hdlc_send_frames(n_hdlc,tty);
		}
	}

	return error;
	
}	/* end of n_hdlc_tty_write() */
long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
			unsigned int cmd, void *arg)
{
	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
	int rc = 0;

	CPP_DBG("%s: %d\n", __func__, __LINE__);
	mutex_lock(&cpp_dev->mutex);
	CPP_DBG("%s cmd: %d\n", __func__, cmd);
	switch (cmd) {
	case VIDIOC_MSM_CPP_CFG: {
		struct msm_queue_cmd *frame_qcmd;
		struct msm_cpp_frame_info_t *new_frame =
			kzalloc(sizeof(struct msm_cpp_frame_info_t),
					GFP_KERNEL);
		if (!new_frame) {
			pr_err("%s Insufficient memory. return", __func__);
			mutex_unlock(&cpp_dev->mutex);
			return -ENOMEM;
		}

		COPY_FROM_USER(rc, new_frame,
			       (void __user *)ioctl_ptr->ioctl_ptr,
			       sizeof(struct msm_cpp_frame_info_t));
		if (rc) {
			ERR_COPY_FROM_USER();
			kfree(new_frame);
			mutex_unlock(&cpp_dev->mutex);
			return -EINVAL;
		}

		frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
		if (!frame_qcmd) {
			pr_err("%s Insufficient memory. return", __func__);
			kfree(new_frame);
			mutex_unlock(&cpp_dev->mutex);
			return -ENOMEM;
		}

		atomic_set(&frame_qcmd->on_heap, 1);
		frame_qcmd->command = new_frame;
		if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) {
			msm_enqueue(&cpp_dev->realtime_q,
						&frame_qcmd->list_frame);
		} else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) {
			msm_enqueue(&cpp_dev->offline_q,
						&frame_qcmd->list_frame);
		} else {
			pr_err("%s: Invalid frame type\n", __func__);
			kfree(new_frame);
			kfree(frame_qcmd);
			mutex_unlock(&cpp_dev->mutex);
			return -EINVAL;
		}
		break;
	}
	case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: {
		struct msm_device_queue *queue = &cpp_dev->eventData_q;
		struct msm_queue_cmd *event_qcmd;
		struct msm_cpp_frame_info_t *process_frame;
		event_qcmd = msm_dequeue(queue, list_eventdata);
		process_frame = event_qcmd->command;
		CPP_DBG("fid %d\n", process_frame->frame_id);
		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
				process_frame,
				sizeof(struct msm_cpp_frame_info_t))) {
					mutex_unlock(&cpp_dev->mutex);
					return -EINVAL;
		}
		kfree(process_frame);
		kfree(event_qcmd);
		break;
	}
	}
	mutex_unlock(&cpp_dev->mutex);
	CPP_DBG("%s: %d\n", __func__, __LINE__);
	return 0;
}