static ssize_t vloopback_read (struct file * f, char * buf, size_t count, loff_t *offset) { struct video_device *loopdev=video_devdata(f); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) priv_ptr ptr=(priv_ptr)video_get_drvdata(loopdev); #else priv_ptr ptr=(priv_ptr)loopdev->priv; #endif int nr=ptr->pipenr; unsigned long realcount=count; if (loops[nr]->zerocopy) { if (ptr->in) { if (realcount > loops[nr]->ioctllength+sizeof(unsigned long int)) realcount=loops[nr]->ioctllength+sizeof(unsigned long int); if (copy_to_user(buf , &loops[nr]->ioctlnr, sizeof(unsigned long int))) return -EFAULT; if (copy_to_user(buf+sizeof(unsigned long int) , loops[nr]->ioctldata, realcount-sizeof(unsigned long int))) return -EFAULT; if (loops[nr]->ioctlnr==0) loops[nr]->ioctlnr=-1; return realcount; } else { struct video_window vidwin; struct video_mmap vidmmap; struct video_picture vidpic; fake_ioctl(nr, VIDIOCGWIN, &vidwin); fake_ioctl(nr, VIDIOCGPICT, &vidpic); vidmmap.height=vidwin.height; vidmmap.width=vidwin.width; vidmmap.format=vidpic.palette; vidmmap.frame=0; if (fake_ioctl(nr, VIDIOCMCAPTURE, &vidmmap)) return 0; if (fake_ioctl(nr, VIDIOCSYNC, &vidmmap)) return 0; realcount=vidwin.height*vidwin.width*vidpic.depth; } } if (ptr->in) return -EINVAL; if (realcount > loops[nr]->buflength) { realcount = loops[nr]->buflength; info("Not so much data in buffer!"); } loops[nr]->pendingread = 1; wake_up(&loops[nr]->wait); if (!loops[nr]->zerocopy) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) unsigned long fw=loops[nr]->frameswrite; wait_event_interruptible(loops[nr]->wait, fw!=loops[nr]->frameswrite); #else interruptible_sleep_on(&loops[nr]->wait); #endif } loops[nr]->pendingread = 0; down(&loops[nr]->lock); if (!loops[nr]->buffer) { up(&loops[nr]->lock); return 0; } if (copy_to_user(buf, loops[nr]->buffer, realcount)) return -EFAULT; up(&loops[nr]->lock); loops[nr]->framesread++; return realcount; }
CmsRet devCtl_boardIoctl(UINT32 boardIoctl, BOARD_IOCTL_ACTION action, char *string, SINT32 strLen, SINT32 offset, void *data) { BOARD_IOCTL_PARMS ioctlParms; SINT32 boardFd = 0; SINT32 rc; CmsRet ret=CMSRET_SUCCESS; #ifdef DESKTOP_LINUX /* don't open anything, ioctl to this fd will be faked anyways */ boardFd = 77777; #else boardFd = open(BOARD_DEVICE_NAME, O_RDWR); #endif if ( boardFd != -1 ) { ioctlParms.string = string; ioctlParms.strLen = strLen; ioctlParms.offset = offset; ioctlParms.action = action; ioctlParms.buf = data; ioctlParms.result = -1; #if defined(AEI_VDSL_CUSTOMER_NCS) if(boardIoctl == BOARD_IOCTL_FLASH_WRITE && (action ==PERSISTENT)) { FILE *fp = NULL; if((fp=fopen("/var/write_psi_lock", "w")) != NULL) fclose(fp); } #endif #ifdef DESKTOP_LINUX rc = fake_ioctl(boardIoctl, &ioctlParms); #else rc = ioctl(boardFd, boardIoctl, &ioctlParms); close(boardFd); #endif #if defined(AEI_VDSL_CUSTOMER_NCS) if(boardIoctl == BOARD_IOCTL_FLASH_WRITE && (action ==PERSISTENT)) unlink("/var/write_psi_lock"); #endif /* * When reading the scratch pad, the return value indicates the count. * Check for that condition first. */ if (((boardIoctl == BOARD_IOCTL_FLASH_READ) && (action == SCRATCH_PAD)) || ((boardIoctl == BOARD_IOCTL_FLASH_LIST) && (action == SCRATCH_PAD)) || boardIoctl == BOARD_IOCTL_BOOT_IMAGE_OPERATION) { /* * The kernel will either return the number of bytes read, * or if the user provided buffer was not big enough, a * negative number indicating the number of bytes needed. * See cms_psp.h, cmsPsp_get(). */ ret = (CmsRet) ioctlParms.result; } else { if (rc < 0) { cmsLog_debug("boardIoctl=0x%x action=%d rc=%d errno=%d", boardIoctl, action, rc, errno); ret = CMSRET_INVALID_ARGUMENTS; } /* ioctl specific return data */ if (ret == CMSRET_SUCCESS) { if ((boardIoctl == BOARD_IOCTL_GET_PSI_SIZE) || (boardIoctl == BOARD_IOCTL_GET_BACKUP_PSI_SIZE) || (boardIoctl == BOARD_IOCTL_GET_SYSLOG_SIZE) || (boardIoctl == BOARD_IOCTL_GET_CHIP_ID) || (boardIoctl == BOARD_IOCTL_GET_NUM_ENET_MACS) || (boardIoctl == BOARD_IOCTL_GET_NUM_ENET_PORTS) || #if defined(AEI_VDSL_CUSTOMER_CENTURYLINK) (boardIoctl == BOARD_IOCTL_GET_POWERLED_STATUS) || (boardIoctl == BOARD_IOCTL_GET_FLASH_TOTAL) || (boardIoctl == BOARD_IOCTL_GET_FLASH_USED) || #endif (boardIoctl == BOARD_IOCTL_GET_SDRAM_SIZE) || (boardIoctl == BOARD_IOCTL_FLASH_READ && action == FLASH_SIZE)) { if (data != NULL) { *((UINT32 *)data) = (UINT32) ioctlParms.result; } } #ifdef AEI_VDSL_CUSTOMER_NCS else if(boardIoctl == BOARD_IOCTL_GET_FS_OFFSET) { if (data != NULL) { *((unsigned long *)data) = (unsigned long) ioctlParms.result; } } #endif } } } else { cmsLog_error("Unable to open device %s", BOARD_DEVICE_NAME); ret = CMSRET_INTERNAL_ERROR; } return ret; }