static int dvb_dsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct aml_dsc *dsc = file->private_data; struct aml_dvb *dvb = dsc->dvb; struct am_dsc_key key; int ret = 0, i; unsigned long flags; spin_lock_irqsave(&dvb->slock, flags); switch(cmd) { case AMDSC_IOC_SET_PID: for(i=0; i<DSC_COUNT; i++) { if(i==dsc->id) continue; if(dvb->dsc[i].used && (dvb->dsc[i].pid==arg)) { ret = -EBUSY; } } dsc->pid = arg; dsc_set_pid(dsc, dsc->pid); break; case AMDSC_IOC_SET_KEY: if (copy_from_user(&key, (void __user *)arg, sizeof(struct am_dsc_key))) { ret = -EFAULT; } else { if(key.type) memcpy(dsc->odd, key.key, 8); else memcpy(dsc->even, key.key, 8); dsc->set |= 1<<(key.type); dsc_set_key(dsc, key.type, key.key); } break; default: ret = -EINVAL; break; } spin_unlock_irqrestore(&dvb->slock, flags); return ret; }
static int dvb_dsc_release(struct inode *inode, struct file *file) { struct aml_dsc *dsc = file->private_data; struct aml_dvb *dvb = dsc->dvb; unsigned long flags; //dvb_generic_release(inode, file); spin_lock_irqsave(&dvb->slock, flags); dsc->used = 0; dsc_set_pid(dsc, 0x1fff); dsc->pid = 0x1fff; dsc->set = 0; dvb->dsc_dev->users--; spin_unlock_irqrestore(&dvb->slock, flags); return 0; }