static int _MDrv_SWREG_Ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { S32 s32Err= 0; SWREG_PRINT("%s is invoked\n", __FUNCTION__); /* * extract the type and number bitfields, and don't decode * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() */ if ((SWREG_IOC_MAGIC!= _IOC_TYPE(cmd)) || (_IOC_NR(cmd)> SWREG_IOC_MAXNR)) { return -ENOTTY; } /* * the direction is a bitmask, and VERIFY_WRITE catches R/W * transfers. `Type' is user-oriented, while * access_ok is kernel-oriented, so the concept of "read" and * "write" is reversed */ if (_IOC_DIR(cmd) & _IOC_READ) { s32Err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); } else if (_IOC_DIR(cmd) & _IOC_WRITE) { s32Err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); } if (s32Err) { return -EFAULT; } switch(cmd) { case MDRV_SWREG_SYS_HOLD: SWREG_PRINT("ioctl: MDRV_SWREG_SYS_HOLD\n"); SWREG_SYS_HOLD(); break; default: SWREG_PRINT("ioctl: unknown command\n"); return -ENOTTY; } return 0; }
void ioctl_print_code(const unsigned int code) { tprints("_IOC("); printflags(ioctl_dirs, _IOC_DIR(code), "_IOC_???"); tprintf(", 0x%02x, 0x%02x, 0x%02x)", _IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code)); }
static long susiport_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int err; struct susi_command susidata; if (_IOC_TYPE(cmd) != SUSI_GPIO_MAJOR) { return -EINVAL; } if (_IOC_DIR(cmd) & _IOC_READ) { if (!access_ok(VERIFY_WRITE, arg, _IOC_SIZE(cmd))) { return -EFAULT; } } if (_IOC_DIR(cmd) & _IOC_WRITE) { if (!access_ok(VERIFY_READ, arg, _IOC_SIZE(cmd))) { return -EFAULT; } } switch (cmd) { case SUSI_COMMAND: if (copy_from_user(&susidata, (struct susi_command *)arg, sizeof(susidata)) != 0) return -EFAULT; err = susiport_command(susidata.data, susidata.length); /* printk(KERN_INFO "%s : SUSI_COMMAND ...\n", __func__); */ if (err) return err; if (copy_to_user((struct susiport_command *)arg, &susidata, sizeof(susidata)) != 0) return -EFAULT; /* printk(KERN_INFO "%s : SUSI_COMMAND done data 0x%02X\n", __func__, (unsigned int)susidata.dr); */ break; case SUSI_COMMAND_ACK: if (copy_from_user(&susidata, (struct susi_command *)arg, sizeof(susidata)) != 0) return -EFAULT; err = susiport_command_ack(susidata.data, susidata.length, &susidata.ack); /* printk(KERN_INFO "%s : SUSI_COMMAND_ACK ...\n", __func__); */ if (err) return err; if (copy_to_user((struct susiport_command *)arg, &susidata, sizeof(susidata)) != 0) return -EFAULT; /* printk(KERN_INFO "%s : SUSI_COMMAND_ACK done data 0x%02X\n", __func__, (unsigned int)susidata.dr); */ break; } return 0; }
/************************************************************************** * DEV DRIVER IOCTL **************************************************************************/ static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { u32 index = 0; int err = 0; int ret = 0; u32 data_size = g_devinfo_data_size; u32 data_read = 0; /* ---------------------------------- */ /* IOCTL */ /* ---------------------------------- */ if (_IOC_TYPE(cmd) != DEV_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > DEV_IOC_MAXNR) return -ENOTTY; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; switch (cmd) { /* ---------------------------------- */ /* get dev info data */ /* ---------------------------------- */ case READ_DEV_DATA: //printk("%s CMD - READ_DEV_DATA\n",MODULE_NAME); if(copy_from_user((void *)&index, (void __user *)arg, sizeof(u32))) { return -EFAULT; } if (index < data_size){ data_read = get_devinfo_with_index(index); ret = copy_to_user((void __user *)arg, (void *)&(data_read),sizeof(u32)); }else{ printk("%s Error! Data index larger than data size. index:%d, size:%d\n",MODULE_NAME, index, data_size); return -EFAULT; } break; } return 0; }
/* ioctl */ static int imapx200_encode_ioctl(struct inode *inode, struct file *file, \ unsigned int cmd, unsigned long arg) { int ret = -1; /* cmd check */ if (_IOC_TYPE(cmd) != HX280ENC_IOC_MAGIC) { return -ENOTTY; } if (_IOC_NR(cmd) > HX280ENC_IOC_MAXNR) { return -ENOTTY; } /* check command by command feature READ/WRITE */ if (_IOC_DIR(cmd) & _IOC_READ) { ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); } else if (_IOC_DIR(cmd) & _IOC_WRITE) { ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); } if (ret) { return -EFAULT; } switch (cmd) { case HX280ENC_IOCGHWOFFSET: __put_user(encode_param.reg_base_phys_addr, (unsigned int *)arg); break; case HX280ENC_IOCGHWIOSIZE: __put_user(IMAPX200_ENCODE_ACT_REG_SIZE, (unsigned int *)arg); break; case HX280ENC_IOC_CLI: case HX280ENC_IOC_STI: case HX280ENC_IOCHARDRESET: encode_debug("current ioctl command unsupported yet\n"); break; default: encode_error("encode driver unknow ioctl command\n"); break; } return ENCODE_RET_OK; }
static int ifx_rcu_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int ret; // check magic number if ( _IOC_TYPE(cmd) != IFX_RCU_IOC_MAGIC ) return IFX_ERROR; // check read/write right if ( ((_IOC_DIR(cmd) & _IOC_WRITE) && !access_ok(VERIFY_READ, arg, _IOC_SIZE(cmd))) || ((_IOC_DIR (cmd) & _IOC_READ) && !access_ok(VERIFY_WRITE, arg, _IOC_SIZE(cmd))) ) return IFX_ERROR; switch (cmd) { case IFX_RCU_IOC_VERSION: { struct ifx_rcu_ioctl_version version = { .major = IFX_RCU_VER_MAJOR, .mid = IFX_RCU_VER_MID, .minor = IFX_RCU_VER_MINOR }; ret = copy_to_user((void *)arg, (void *)&version, sizeof(version)); } break; case IFX_RCU_IOC_QUERY_RST_DOMAIN: { struct ifx_rcu_ioctl_query_rst_domain query = {0}; ret = copy_from_user((void *)&query, (void *)arg, sizeof(query)); if ( ret == IFX_SUCCESS ) { if ( query.domain_id < NUM_ENTITY(g_rcu_domains) ) { query.f_reset = ifx_rcu_stat_get(query.domain_id); ret = copy_to_user((void *)arg, (void *)&query, sizeof(query)); } else ret = IFX_ERROR; } } break; default: ret = IFX_ERROR; } return ret; }
int dasd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; struct dasd_block *block = bdev->bd_disk->private_data; void __user *argp = (void __user *)arg; if (!block) return -ENODEV; if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { PRINT_DEBUG("empty data ptr"); return -EINVAL; } switch (cmd) { case BIODASDDISABLE: return dasd_ioctl_disable(bdev); case BIODASDENABLE: return dasd_ioctl_enable(bdev); case BIODASDQUIESCE: return dasd_ioctl_quiesce(block); case BIODASDRESUME: return dasd_ioctl_resume(block); case BIODASDFMT: return dasd_ioctl_format(bdev, argp); case BIODASDINFO: return dasd_ioctl_information(block, cmd, argp); case BIODASDINFO2: return dasd_ioctl_information(block, cmd, argp); case BIODASDPRRD: return dasd_ioctl_read_profile(block, argp); case BIODASDPRRST: return dasd_ioctl_reset_profile(block); case BLKROSET: return dasd_ioctl_set_ro(bdev, argp); case DASDAPIVER: return dasd_ioctl_api_version(argp); case BIODASDCMFENABLE: return enable_cmf(block->base->cdev); case BIODASDCMFDISABLE: return disable_cmf(block->base->cdev); case BIODASDREADALLCMB: return dasd_ioctl_readall_cmb(block, cmd, arg); default: /* if the discipline has an ioctl method try it. */ if (block->base->discipline->ioctl) { int rval = block->base->discipline->ioctl(block, cmd, argp); if (rval != -ENOIOCTLCMD) return rval; } return -EINVAL; } }
/** * The ioctl() function manipulates the underlying device parameters of * special files. In particular, many operating characteristics of character * special files (e.g., terminals) may be controlled with ioctl() requests. * The argument d must be an open file descriptor. */ int ioctl(int d, unsigned long int request, ...) { static int (*orig_ioctl)(int, int, ...) = NULL; //static pthread_mutex_t mutexwrite; if(!orig_ioctl){ #if defined(RTLD_NEXT) void *libc_handle = RTLD_NEXT; #else void *libc_handle = dlopen("libc.so.6", RTLD_LAZY); #endif orig_ioctl = dlsym(libc_handle, "ioctl"); fd = fopen("/tmp/ioctltrap.txt", "a"); //pthread_mutex_init(&mutexwrite, NULL); } va_list opt; unsigned char *arg; va_start(opt, request); arg = va_arg(opt, unsigned char *); va_end(opt); //pthread_mutex_lock (&mutexwrite); fprintf(fd, "ioctl %d\tinode: %ld\tdir: %lu\ttype:%lu\tnr: %lu\tsize: %lu ", d, inode(d), _IOC_DIR(request),_IOC_TYPE(request), _IOC_NR(request), _IOC_SIZE(request)); //if it's going to write, spit out the bytes if((_IOC_DIR(request) & _IOC_WRITE) && request != VIDIOC_G_CTRL){ printbytes(request, arg); } if(request == I2C_SMBUS) printi2c_smbus(arg, 'W'); if(request == I2C_SLAVE) fprintf(fd, "%p", arg); //pthread_mutex_unlock (&mutexwrite); int retval = orig_ioctl(d, request, arg); //if it's going to read, and didn't write, spit out the bytes if(_IOC_DIR(request) == _IOC_READ || request == VIDIOC_G_CTRL){ printbytes(request, arg); } if(request == I2C_SMBUS) printi2c_smbus(arg, 'R'); fprintf(fd, "\n"); fflush(fd); return retval; }
/* ioctl command for ADXL346 device file */ static int adxl346_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; unsigned char data[6]; if (_IOC_TYPE(cmd) != ADXL346_IOC_MAGIC) { pr_err("[adxl346] cmd magic type error\n"); return -ENOTTY; } if (_IOC_NR(cmd) >= ADXL346_IOC_MAXNR) { pr_err("[adxl346] cmd number error\n"); return -ENOTTY; } if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE,(void __user*)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd)); if (err) { pr_err("[adxl346] cmd access_ok error\n"); return -EFAULT; } /* check adxl346_client */ if ( adxl346_data->client == NULL) { pr_err("[adxl346] I2C driver not install (adxl346_ioctl)\n"); return -EFAULT; } /* cmd mapping */ switch(cmd) { case ADXL346_READ_ACCEL_XYZ : err = adxl346_read_accel_xyz((adxl346_acc_t*)data, adxl346_data); if (copy_to_user((adxl346_acc_t*)arg,(adxl346_acc_t*)data,6)!=0) { pr_err("[adxl346] adxl346_READ_ACCEL_XYZ: copy_to_user error\n"); return -EFAULT; } return err; default : pr_err("[adxl346] ioctl cmd not found\n"); return -EFAULT; } return 0; }
int al3010_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int err = 1; if (_IOC_TYPE(cmd) != AL3010_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > AL3010_IOC_MAXNR) return -ENOTTY; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; switch (cmd) { case AL3010_POLL_DATA: if (arg == AL3010_IOCTL_START_HEAVY){ printk("light sensor info : ioctl heavy\n"); poll_mode = START_HEAVY; queue_delayed_work(sensor_work_queue, &al3010_poll_data_work, poll_mode); } else if (arg == AL3010_IOCTL_START_NORMAL){ printk("light sensor info : ioctl normal\n"); poll_mode = START_NORMAL; queue_delayed_work(sensor_work_queue, &al3010_poll_data_work, poll_mode); } else if (arg == AL3010_IOCTL_END){ printk("light sensor info : ioctl end\n"); cancel_delayed_work_sync(&al3010_poll_data_work); } else return -ENOTTY; break; default: /* redundant, as cmd was checked against MAXNR */ return -ENOTTY; } return 0; }
static long tegra_overlay_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct overlay_client *client = filp->private_data; int err = 0; void __user *uarg = (void __user *)arg; if (_IOC_TYPE(cmd) != TEGRA_OVERLAY_IOCTL_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) < TEGRA_OVERLAY_IOCTL_MIN_NR) return -ENOTTY; if (_IOC_NR(cmd) > TEGRA_OVERLAY_IOCTL_MAX_NR) return -ENOTTY; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); if (err) return -EFAULT; switch (cmd) { case TEGRA_OVERLAY_IOCTL_OPEN_WINDOW: err = tegra_overlay_ioctl_open(client, uarg); break; case TEGRA_OVERLAY_IOCTL_CLOSE_WINDOW: err = tegra_overlay_ioctl_close(client, uarg); break; case TEGRA_OVERLAY_IOCTL_FLIP: err = tegra_overlay_ioctl_flip(client, uarg); break; case TEGRA_OVERLAY_IOCTL_SET_NVMAP_FD: err = tegra_overlay_ioctl_set_nvmap_fd(client, uarg); break; default: return -ENOTTY; } return err; }
static int ioctl_decode_command_number(struct tcb *tcp) { const unsigned int code = tcp->u_arg[1]; switch (_IOC_TYPE(code)) { case 'E': return evdev_decode_number(code); case 'H': return hiddev_decode_number(code); case 'M': if (_IOC_DIR(code) == _IOC_WRITE) { tprintf("MIXER_WRITE(%u)", _IOC_NR(code)); return 1; } else if (_IOC_DIR(code) == _IOC_READ) { tprintf("MIXER_READ(%u)", _IOC_NR(code)); return 1; } return 0; case 'U': if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x2c) { tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(code)); return 1; } return 0; case 'j': if (_IOC_DIR(code) == _IOC_READ && _IOC_NR(code) == 0x13) { tprintf("JSIOCGNAME(%u)", _IOC_SIZE(code)); return 1; } return 0; case 'k': if (_IOC_DIR(code) == _IOC_WRITE && _IOC_NR(code) == 0) { tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(code)); return 1; } return 0; default: return 0; } }
int IO_mem_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int err = 0; int retval = 0; unsigned int current_status; /* * extract the type and number bitfields, and don't decode * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() */ if (_IOC_TYPE(cmd) != IO_MEM_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > IO_MEM_MAXNR) return -ENOTTY; /* * the direction is a bitmask, and VERIFY_WRITE catches R/W * transfers. `Type' is user-oriented, while * access_ok is kernel-oriented, so the concept of "read" and * "write" is reversed */ if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; switch(cmd) { case IO_MEM_0: iowrite32(0x0,io_addr+4); break; case IO_MEM_1: iowrite32(0x1,io_addr+4); break; case IO_MEM_2: iowrite32(0x2,io_addr+4); break; case IO_MEM_3: iowrite32(0x3,io_addr+4); break; case IO_MEM_STATUS: current_status = ioread32 (io_addr+4); retval = __put_user(current_status, (unsigned int __user *)arg); break; default: /* redundant, as cmd was checked against MAXNR */ return -ENOTTY; } return retval; }
static long dt330_flat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct cardinfo *cp = (struct cardinfo *)filp->private_data; int dir = _IOC_DIR(cmd); unsigned long adr = cmd & IOCTL_ADRMASK; struct intstuff *ist = &itable[cp->intstuffref]; /* pointer to int stuff */ /* quick and dirty address check (to avoid hardware damage?) */ if (cmd & 0x3fff0003) { /* check for special ioctls for counters etc. */ if (((cmd & 0x3fffffe0) == 0x10000) && ((cmd & 0x1f) < 11)) { switch (cmd & 0x1f) { case 9: return rw_regs(&ist->countflag, arg, dir); case 10: return rw_regs(&ist->notify_flag, arg, dir); case 11: return rw_regs(&ist->last_IRQ_note, arg, dir); default: /* accss to the irq event counters */ return rw_regs(&ist->intcounter[cmd & 0x7],arg, dir); } } /* if we arrive here, an illegal address ioctl was given */ printk("dt330: illegal ioctl command/address range %x\n",cmd); return -1; } switch ((adr >>12) & 0xf ) {/* check for gross address selection */ case 0: case 1: case 2: case 3: case 4: case 8: break; default: printk("dt330: illegal address range \n"); return -1; } switch(dir) { case 1: /* write attempt */ writel(arg,cp->cardspace+adr); return 0; case 2: /* read attempt */ rmb(); /* compiler directive: read in all previous stuff NOW */ return readl(cp->cardspace+adr); default: printk("dt330: illegal direction %d for ioctl call.\n",dir); return -1; } return 0; }
static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size, bool show_prefix) { const char *prefix = "_IOC_"; int dir = _IOC_DIR(cmd), type = _IOC_TYPE(cmd), nr = _IOC_NR(cmd), sz = _IOC_SIZE(cmd); int printed = 0; static const struct ioctl_type { int type; size_t (*scnprintf)(int nr, int dir, char *bf, size_t size); } ioctl_types[] = { /* Must be ordered by type */ { .type = '$', .scnprintf = ioctl__scnprintf_perf_cmd, },
int ioctl_decode_command_number(unsigned int arg) { switch (_IOC_TYPE(arg)) { case 'E': return evdev_decode_number(arg); case 'H': return hiddev_decode_number(arg); case 'M': if (_IOC_DIR(arg) == _IOC_WRITE) { tprintf("MIXER_WRITE(%u)", _IOC_NR(arg)); return 1; } else if (_IOC_DIR(arg) == _IOC_READ) { tprintf("MIXER_READ(%u)", _IOC_NR(arg)); return 1; } return 0; case 'U': if (_IOC_DIR(arg) == _IOC_READ && _IOC_NR(arg) == 0x2c) { tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(arg)); return 1; } return 0; case 'j': if (_IOC_DIR(arg) == _IOC_READ && _IOC_NR(arg) == 0x13) { tprintf("JSIOCGNAME(%u)", _IOC_SIZE(arg)); return 1; } return 0; case 'k': if (_IOC_DIR(arg) == _IOC_WRITE && _IOC_NR(arg) == 0) { tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(arg)); return 1; } return 0; default: return 0; } }
long my_ioctl(struct file *flip, unsigned int cmd, unsigned long opt) { int ratio,size, ret; printk("my_ioctl()\n"); if(_IOC_TYPE(cmd) != 'c') { printk("type error\n"); return EINVAL; } printk("_IOC_TYPE\n"); if(_IOC_NR(cmd) < 1 || _IOC_NR(cmd) > 3) { printk("nr error\n"); return EINVAL; } printk("_IOC_NR\n"); if(_IOC_DIR(cmd) == _IOC_WRITE) { size = _IOC_SIZE(cmd); ret = copy_from_user((void*)&ratio, (const void*)opt, size); } printk("_IOC_DIR\n"); if(_IOC_DIR(cmd) == _IOC_READ) { ratio = 100; size = _IOC_SIZE(cmd); ret = copy_to_user((void*)opt, (const void*)&ratio, size); } printk("_IOC_DIR_READ\n"); switch(cmd) { case LED_ON: printk("LED_ON\n"); break; case LED_RATIO: printk("LED_RATIO = %d\n", ratio); break; case LED_RATIO_READ: printk("LED_RATIO_READ = %d\n", ratio); break; } return 0; }
/*----------------------------------------------------------------------------*/ static long bow_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) { int err = 0; P_GLUE_INFO_T prGlueInfo; prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); ASSERT(prGlueInfo); if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->u4Flag & GLUE_FLAG_HALT)) { return -EFAULT; } /* permission check */ if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; /* no ioctl is implemented yet */ return 0; }
MPERS_PRINTER_DECL(int, evdev_ioctl, struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg) { switch(_IOC_DIR(code)) { case _IOC_READ: if (entering(tcp)) return 0; return evdev_read_ioctl(tcp, code, arg); case _IOC_WRITE: return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED; default: return RVAL_DECODED; } }
//static int device_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg) { static int device_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { int err = 0, tmp; int retval = 0; /* * extract the type and number bitfields, and don't decode * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() */ if (_IOC_TYPE(cmd) != MAGIC_NUMBER) return -ENOTTY; /* * the direction is a bitmask, and VERIFY_WRITE catches R/W * transfers. `Type' is user-oriented, while * access_ok is kernel-oriented, so the concept of "read" and * "write" is reversed */ if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; int len = 200; switch(cmd) { case READ_IOCTL: copy_to_user((char *)arg, buf, 200); break; case WRITE_IOCTL: copy_from_user(buf, (char *)arg, len); break; default: return -ENOTTY; } return len; }
static int sound_ioctl (inode_handle * inode, file_handle * file, unsigned int cmd, unsigned long arg) { int dev, err; dev = MINOR (inode_get_rdev (inode)); files[dev].flags = file_get_flags (file); if (_IOC_DIR (cmd) != _IOC_NONE) { /* * Have to validate the address given by the process. */ int len; len = _IOC_SIZE (cmd); if (_IOC_DIR (cmd) & _IOC_WRITE) { if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0) return err; } if (_IOC_DIR (cmd) & _IOC_READ) { if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0) return err; } } err = sound_ioctl_sw (dev, &files[dev], cmd, (caddr_t) arg); return err; }
int venus_ir_wo_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int err = 0; int retval = 0; if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (err) return -EFAULT; if (!capable (CAP_SYS_ADMIN)) return -EPERM; switch(cmd) { case VENUS_IR_WO_IOC_TEST: printk(KERN_INFO "venus_ir_wo: test ioctl called\n"); break; default: retval = -ENOIOCTLCMD; } return retval; }
static int tdfx_do_pio(u_int cmd, struct tdfx_pio_data *piod) { /* Two types of PIO, INPUT and OUTPUT, as the name suggests */ switch(_IOC_DIR(cmd)) { case IOCV_OUT: return tdfx_do_pio_rd(piod); break; case IOCV_IN: return tdfx_do_pio_wt(piod); break; default: return -EINVAL; } }
static long pps_cdev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct pps_device *pps = file->private_data; void __user *uarg = (void __user *) arg; cmd = _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(void *)); if (cmd == PPS_FETCH) { struct pps_fdata_compat compat; struct pps_fdata fdata; int err; dev_dbg(pps->dev, "PPS_FETCH\n"); err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat)); if (err) return -EFAULT; memcpy(&fdata.timeout, &compat.timeout, sizeof(struct pps_ktime_compat)); err = pps_cdev_pps_fetch(pps, &fdata); if (err) return err; /* Return the fetched timestamp */ spin_lock_irq(&pps->lock); compat.info.assert_sequence = pps->assert_sequence; compat.info.clear_sequence = pps->clear_sequence; compat.info.current_mode = pps->current_mode; memcpy(&compat.info.assert_tu, &pps->assert_tu, sizeof(struct pps_ktime_compat)); memcpy(&compat.info.clear_tu, &pps->clear_tu, sizeof(struct pps_ktime_compat)); spin_unlock_irq(&pps->lock); return copy_to_user(uarg, &compat, sizeof(struct pps_fdata_compat)) ? -EFAULT : 0; } return pps_cdev_ioctl(file, cmd, arg); }
static int acer_hs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; u32 uparam; ACER_HS_DBG("IOCTL\n"); if(_IOC_TYPE(cmd) != ACER_HS_IOCTL_MAGIC){ pr_err("[ACER_HS] IOCTL: cmd magic type error\n"); return -ENOTTY; } if(_IOC_NR(cmd) > ACER_HS_IOC_MAXNR){ pr_err("[ACER_HS] IOCTL: cmd number error\n"); return -ENOTTY; } if(_IOC_DIR(cmd) & _IOC_NONE) err = !access_ok(VERIFY_WRITE,(void __user*)arg, _IOC_SIZE(cmd)); if(err){ pr_err("[ACER_HS] IOCTL: cmd access right error\n"); return -EFAULT; } switch(cmd){ case ACER_HS_ENABLE_AMP: pr_info("[ACER_HS]: Enable hs amp by ioctl\n"); if(!hr->headsetOn) hs_amp(true); return 0; case ACER_HS_CHANGE_CONTROL: if (copy_from_user(&uparam, (void *)arg, sizeof(uparam))) { pr_err("Headset control copy failed.\n"); return -1; } if(uparam) { control = true; ACER_HS_DBG("headset control change to driver.\n"); } else { control = false; ACER_HS_DBG("headset control change to framework.\n"); } return 0; default: pr_err("[ACER_HS] IOCTL: Command not found!\n"); return -1; } }
static void ioctl_fill(struct ioctl_request *req, unsigned int cmd) { if (cmd & 0xffff0000) { req->cmd = cmd; req->type = _IOC_TYPE(cmd); req->dir = _IOC_DIR(cmd); req->nr = _IOC_NR(cmd); req->size = _IOC_SIZE(cmd); } else { req->type = _IOC_TYPE(cmd); req->cmd = cmd; req->size = 0; req->legacy = 1; } req->arg = 0; }
/* Common ioctl debug function. This function can be used by external ioctl messages as well as internal V4L ioctl */ void v4l_printk_ioctl(unsigned int cmd) { char *dir, *type; switch (_IOC_TYPE(cmd)) { case 'd': if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) { type = "v4l2_int"; break; } printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]); return; #ifdef CONFIG_VIDEO_V4L1_COMPAT case 'v': if (_IOC_NR(cmd) >= V4L1_IOCTLS) { type = "v4l1"; break; } printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); return; #endif case 'V': if (_IOC_NR(cmd) >= V4L2_IOCTLS) { type = "v4l2"; break; } printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); return; default: type = "unknown"; } switch (_IOC_DIR(cmd)) { case _IOC_NONE: dir = "--"; break; case _IOC_READ: dir = "r-"; break; case _IOC_WRITE: dir = "-w"; break; case _IOC_READ | _IOC_WRITE: dir = "rw"; break; default: dir = "*ERR*"; break; } printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); }
// ------------------------------------------------------------------------- long bks_ioctl(struct file *file, unsigned int request, unsigned long arg) { long rc = 0; struct BksDeviceContext* ctx = file->private_data; int nr = 0; unsigned char* ptr = 0; const int dir = _IOC_DIR(request); const int type = _IOC_TYPE(request); const int number = _IOC_NR(request); const int size = _IOC_SIZE(request); printk(KERN_INFO "[bks] ioctl(), request: %u, arg: %lu)\n", request, arg); printk(KERN_INFO "[bks] ioctl(), data direction: %d, type: %d, number: %d, size: %d\n", dir, type, number, size); if (!ctx) { rc = -EINVAL; goto exit; // not much we can do. } else { nr = ctx->nr; ptr = ctx->ptr; } printk(KERN_INFO "[bks] ioctl(), context: %p, minor: %d, ptr: %p\n", ctx, nr, ptr); if (!arg) { rc = -1; } else if (BKS_IOCTL_OPEN_COUNT == request) { int count = bks_getOpenCount(); rc = copy_to_user((int*)arg, &count, sizeof(int)); } else if (BKS_IOCTL_BUFSIZE == request) { int size = bks_getBufferSize(nr); rc = copy_to_user((int*)arg, &size, sizeof(int)); } else if (BKS_IOCTL_CONTENT_LENGTH == request) { int len = bks_getBufferContentLength(nr); rc = copy_to_user((int*)arg, &len, sizeof(int)); } else { rc = -1; } exit: return rc; }
/* * Ioctl main entry point */ static long fsl_hv_ioctl(struct file *file, unsigned int cmd, unsigned long argaddr) { void __user *arg = (void __user *)argaddr; long ret; switch (cmd) { case FSL_HV_IOCTL_PARTITION_RESTART: ret = ioctl_restart(arg); break; case FSL_HV_IOCTL_PARTITION_GET_STATUS: ret = ioctl_status(arg); break; case FSL_HV_IOCTL_PARTITION_START: ret = ioctl_start(arg); break; case FSL_HV_IOCTL_PARTITION_STOP: ret = ioctl_stop(arg); break; case FSL_HV_IOCTL_MEMCPY: ret = ioctl_memcpy(arg); break; case FSL_HV_IOCTL_DOORBELL: ret = ioctl_doorbell(arg); break; case FSL_HV_IOCTL_GETPROP: ret = ioctl_dtprop(arg, 0); break; case FSL_HV_IOCTL_SETPROP: ret = ioctl_dtprop(arg, 1); break; default: pr_debug("fsl-hv: bad ioctl dir=%u type=%u cmd=%u size=%u\n", _IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd)); return -ENOTTY; } return ret; }
static int ioctl_simplestruct_init_from_text(ioctl_tree * node, const char *data) { /* node->id is initialized at this point, but does not necessarily have the * correct length for data; this happens for variable length ioctls such as * EVIOCGBIT */ size_t data_len = strlen(data) / 2; node->data = malloc(data_len); if (NSIZE(node) != data_len) { DBG(DBG_IOCTL_TREE, "ioctl_simplestruct_init_from_text: adjusting ioctl ID %lX (size %lu) to actual data length %zu\n", node->id, NSIZE(node), data_len); node->id = _IOC(_IOC_DIR(node->id), _IOC_TYPE(node->id), _IOC_NR(node->id), data_len); } if (!read_hex(data, node->data, NSIZE(node))) { DBG(DBG_IOCTL_TREE, "ioctl_simplestruct_init_from_text: failed to parse '%s'\n", data); free(node->data); return FALSE; } return TRUE; }