cregit-Linux how code gets into the kernel

Release 4.11 drivers/media/usb/pvrusb2/pvrusb2-ctrl.c

/*
 *
 *
 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 */

#include "pvrusb2-ctrl.h"
#include "pvrusb2-hdw-internal.h"
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mutex.h>



static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val) { if (cptr->info->check_value) { if (!cptr->info->check_value(cptr,val)) return -ERANGE; } else if (cptr->info->type == pvr2_ctl_enum) { if (val < 0) return -ERANGE; if (val >= cptr->info->def.type_enum.count) return -ERANGE; } else { int lim; lim = cptr->info->def.type_int.min_value; if (cptr->info->get_min_value) { cptr->info->get_min_value(cptr,&lim); } if (val < lim) return -ERANGE; lim = cptr->info->def.type_int.max_value; if (cptr->info->get_max_value) { cptr->info->get_max_value(cptr,&lim); } if (val > lim) return -ERANGE; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely180100.00%2100.00%
Total180100.00%2100.00%

/* Set the given control. */
int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) { return pvr2_ctrl_set_mask_value(cptr,~0,val); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely24100.00%1100.00%
Total24100.00%1100.00%

/* Set/clear specific bits of the given control. */
int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) { int ret = 0; if (!cptr) return -EINVAL; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->set_value) { if (cptr->info->type == pvr2_ctl_bitmask) { mask &= cptr->info->def.type_bitmask.valid_bits; } else if ((cptr->info->type == pvr2_ctl_int)|| (cptr->info->type == pvr2_ctl_enum)) { ret = pvr2_ctrl_range_check(cptr,val); if (ret < 0) break; } else if (cptr->info->type != pvr2_ctl_bool) { break; } ret = cptr->info->set_value(cptr,mask,val); } else { ret = -EPERM; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely171100.00%5100.00%
Total171100.00%5100.00%

/* Get the current value of the given control. */
int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr) { int ret = 0; if (!cptr) return -EINVAL; LOCK_TAKE(cptr->hdw->big_lock); do { ret = cptr->info->get_value(cptr,valptr); } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely70100.00%1100.00%
Total70100.00%1100.00%

/* Retrieve control's type */
enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) { if (!cptr) return pvr2_ctl_int; return cptr->info->type; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely26100.00%1100.00%
Total26100.00%1100.00%

/* Retrieve control's maximum value (int type) */
int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr) { int ret = 0; if (!cptr) return 0; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->get_max_value) { cptr->info->get_max_value(cptr,&ret); } else if (cptr->info->type == pvr2_ctl_int) { ret = cptr->info->def.type_int.max_value; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely99100.00%2100.00%
Total99100.00%2100.00%

/* Retrieve control's minimum value (int type) */
int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) { int ret = 0; if (!cptr) return 0; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->get_min_value) { cptr->info->get_min_value(cptr,&ret); } else if (cptr->info->type == pvr2_ctl_int) { ret = cptr->info->def.type_int.min_value; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely99100.00%2100.00%
Total99100.00%2100.00%

/* Retrieve control's default value (any type) */
int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr) { int ret = 0; if (!cptr) return -EINVAL; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->get_def_value) { ret = cptr->info->get_def_value(cptr, valptr); } else { *valptr = cptr->info->default_value; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely92100.00%3100.00%
Total92100.00%3100.00%

/* Retrieve control's enumeration count (enum only) */
int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr) { int ret = 0; if (!cptr) return 0; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->type == pvr2_ctl_enum) { ret = cptr->info->def.type_enum.count; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely76100.00%1100.00%
Total76100.00%1100.00%

/* Retrieve control's valid mask bits (bit mask only) */
int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr) { int ret = 0; if (!cptr) return 0; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->type == pvr2_ctl_bitmask) { ret = cptr->info->def.type_bitmask.valid_bits; } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely76100.00%1100.00%
Total76100.00%1100.00%

/* Retrieve the control's name */
const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) { if (!cptr) return NULL; return cptr->info->name; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely27100.00%2100.00%
Total27100.00%2100.00%

/* Retrieve the control's desc */
const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) { if (!cptr) return NULL; return cptr->info->desc; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely27100.00%2100.00%
Total27100.00%2100.00%

/* Retrieve a control enumeration or bit mask value */
int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, char *bptr,unsigned int bmax, unsigned int *blen) { int ret = -EINVAL; if (!cptr) return 0; *blen = 0; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->type == pvr2_ctl_enum) { const char * const *names; names = cptr->info->def.type_enum.value_names; if (pvr2_ctrl_range_check(cptr,val) == 0) { if (names[val]) { *blen = scnprintf( bptr,bmax,"%s", names[val]); } else { *blen = 0; } ret = 0; } } else if (cptr->info->type == pvr2_ctl_bitmask) { const char **names; unsigned int idx; int msk; names = cptr->info->def.type_bitmask.bit_names; val &= cptr->info->def.type_bitmask.valid_bits; for (idx = 0, msk = 1; val; idx++, msk <<= 1) { if (val & msk) { *blen = scnprintf(bptr,bmax,"%s", names[idx]); ret = 0; break; } } } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely25699.61%266.67%
Hans Verkuil10.39%133.33%
Total257100.00%3100.00%

/* Return V4L ID for this control or zero if none */
int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr) { if (!cptr) return 0; return cptr->info->v4l_id; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely25100.00%1100.00%
Total25100.00%1100.00%


unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) { unsigned int flags = 0; if (cptr->info->get_v4lflags) { flags = cptr->info->get_v4lflags(cptr); } if (cptr->info->set_value) { flags &= ~V4L2_CTRL_FLAG_READ_ONLY; } else { flags |= V4L2_CTRL_FLAG_READ_ONLY; } return flags; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely63100.00%2100.00%
Total63100.00%2100.00%

/* Return true if control is writable */
int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) { if (!cptr) return 0; return cptr->info->set_value != NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely2696.30%150.00%
Al Viro13.70%150.00%
Total27100.00%2100.00%

/* Return true if control has custom symbolic representation */
int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr) { if (!cptr) return 0; if (!cptr->info->val_to_sym) return 0; if (!cptr->info->sym_to_val) return 0; return !0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely46100.00%1100.00%
Total46100.00%1100.00%

/* Convert a given mask/val to a custom symbolic value */
int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr, int mask,int val, char *buf,unsigned int maxlen, unsigned int *len) { if (!cptr) return -EINVAL; if (!cptr->info->val_to_sym) return -EINVAL; return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely71100.00%1100.00%
Total71100.00%1100.00%

/* Convert a symbolic value to a mask/value pair */
int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr, const char *buf,unsigned int len, int *maskptr,int *valptr) { if (!cptr) return -EINVAL; if (!cptr->info->sym_to_val) return -EINVAL; return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely67100.00%1100.00%
Total67100.00%1100.00%


static unsigned int gen_bitmask_string(int msk,int val,int msk_only, const char **names, char *ptr,unsigned int len) { unsigned int idx; long sm,um; int spcFl; unsigned int uc,cnt; const char *idStr; spcFl = 0; uc = 0; um = 0; for (idx = 0, sm = 1; msk; idx++, sm <<= 1) { if (sm & msk) { msk &= ~sm; idStr = names[idx]; if (idStr) { cnt = scnprintf(ptr,len,"%s%s%s", (spcFl ? " " : ""), (msk_only ? "" : ((val & sm) ? "+" : "-")), idStr); ptr += cnt; len -= cnt; uc += cnt; spcFl = !0; } else { um |= sm; } } } if (um) { if (msk_only) { cnt = scnprintf(ptr,len,"%s0x%lx", (spcFl ? " " : ""), um); ptr += cnt; len -= cnt; uc += cnt; spcFl = !0; } else if (um & val) { cnt = scnprintf(ptr,len,"%s+0x%lx", (spcFl ? " " : ""), um & val); ptr += cnt; len -= cnt; uc += cnt; spcFl = !0; } else if (um & ~val) { cnt = scnprintf(ptr,len,"%s+0x%lx", (spcFl ? " " : ""), um & ~val); ptr += cnt; len -= cnt; uc += cnt; spcFl = !0; } } return uc; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely328100.00%1100.00%
Total328100.00%1100.00%

static const char *boolNames[] = { "false", "true", "no", "yes", };
static int parse_token(const char *ptr,unsigned int len, int *valptr, const char * const *names, unsigned int namecnt) { char buf[33]; unsigned int slen; unsigned int idx; int negfl; char *p2; *valptr = 0; if (!names) namecnt = 0; for (idx = 0; idx < namecnt; idx++) { if (!names[idx]) continue; slen = strlen(names[idx]); if (slen != len) continue; if (memcmp(names[idx],ptr,slen)) continue; *valptr = idx; return 0; } negfl = 0; if ((*ptr == '-') || (*ptr == '+')) { negfl = (*ptr == '-'); ptr++; len--; } if (len >= sizeof(buf)) return -EINVAL; memcpy(buf,ptr,len); buf[len] = 0; *valptr = simple_strtol(buf,&p2,0); if (negfl) *valptr = -(*valptr); if (*p2) return -EINVAL; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely23299.57%266.67%
Hans Verkuil10.43%133.33%
Total233100.00%3100.00%


static int parse_mtoken(const char *ptr,unsigned int len, int *valptr, const char **names,int valid_bits) { char buf[33]; unsigned int slen; unsigned int idx; char *p2; int msk; *valptr = 0; for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) { if (!(msk & valid_bits)) continue; valid_bits &= ~msk; if (!names[idx]) continue; slen = strlen(names[idx]); if (slen != len) continue; if (memcmp(names[idx],ptr,slen)) continue; *valptr = msk; return 0; } if (len >= sizeof(buf)) return -EINVAL; memcpy(buf,ptr,len); buf[len] = 0; *valptr = simple_strtol(buf,&p2,0); if (*p2) return -EINVAL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely19198.96%150.00%
Roel Kluin21.04%150.00%
Total193100.00%2100.00%


static int parse_tlist(const char *ptr,unsigned int len, int *maskptr,int *valptr, const char **names,int valid_bits) { unsigned int cnt; int mask,val,kv,mode,ret; mask = 0; val = 0; ret = 0; while (len) { cnt = 0; while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; ptr += cnt; len -= cnt; mode = 0; if ((*ptr == '-') || (*ptr == '+')) { mode = (*ptr == '-') ? -1 : 1; ptr++; len--; } cnt = 0; while (cnt < len) { if (ptr[cnt] <= 32) break; if (ptr[cnt] >= 127) break; cnt++; } if (!cnt) break; if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) { ret = -EINVAL; break; } ptr += cnt; len -= cnt; switch (mode) { case 0: mask = valid_bits; val |= kv; break; case -1: mask |= kv; val &= ~kv; break; case 1: mask |= kv; val |= kv; break; default: break; } } *maskptr = mask; *valptr = val; return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely282100.00%1100.00%
Total282100.00%1100.00%

/* Convert a symbolic value to a mask/value pair */
int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, const char *ptr,unsigned int len, int *maskptr,int *valptr) { int ret = -EINVAL; unsigned int cnt; *maskptr = 0; *valptr = 0; cnt = 0; while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; len -= cnt; ptr += cnt; cnt = 0; while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) || (ptr[len-(cnt+1)] >= 127))) cnt++; len -= cnt; if (!len) return -EINVAL; LOCK_TAKE(cptr->hdw->big_lock); do { if (cptr->info->type == pvr2_ctl_int) { ret = parse_token(ptr,len,valptr,NULL,0); if (ret >= 0) { ret = pvr2_ctrl_range_check(cptr,*valptr); } *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bool) { ret = parse_token(ptr,len,valptr,boolNames, ARRAY_SIZE(boolNames)); if (ret == 1) { *valptr = *valptr ? !0 : 0; } else if (ret == 0) { *valptr = (*valptr & 1) ? !0 : 0; } *maskptr = 1; } else if (cptr->info->type == pvr2_ctl_enum) { ret = parse_token( ptr,len,valptr, cptr->info->def.type_enum.value_names, cptr->info->def.type_enum.count); if (ret >= 0) { ret = pvr2_ctrl_range_check(cptr,*valptr); } *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bitmask) { ret = parse_tlist( ptr,len,maskptr,valptr, cptr->info->def.type_bitmask.bit_names, cptr->info->def.type_bitmask.valid_bits); } } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely41598.11%685.71%
Pantelis Koukousoulas81.89%114.29%
Total423100.00%7100.00%

/* Convert a given mask/val to a symbolic value */
int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, int mask,int val, char *buf,unsigned int maxlen, unsigned int *len) { int ret = -EINVAL; *len = 0; if (cptr->info->type == pvr2_ctl_int) { *len = scnprintf(buf,maxlen,"%d",val); ret = 0; } else if (cptr->info->type == pvr2_ctl_bool) { *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); ret = 0; } else if (cptr->info->type == pvr2_ctl_enum) { const char * const *names; names = cptr->info->def.type_enum.value_names; if ((val >= 0) && (val < cptr->info->def.type_enum.count)) { if (names[val]) { *len = scnprintf( buf,maxlen,"%s", names[val]); } else { *len = 0; } ret = 0; } } else if (cptr->info->type == pvr2_ctl_bitmask) { *len = gen_bitmask_string( val & mask & cptr->info->def.type_bitmask.valid_bits, ~0,!0, cptr->info->def.type_bitmask.bit_names, buf,maxlen); } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely25499.61%266.67%
Hans Verkuil10.39%133.33%
Total255100.00%3100.00%

/* Convert a given mask/val to a symbolic value */
int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr, int mask,int val, char *buf,unsigned int maxlen, unsigned int *len) { int ret; LOCK_TAKE(cptr->hdw->big_lock); do { ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val, buf,maxlen,len); } while(0); LOCK_GIVE(cptr->hdw->big_lock); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Mike Isely78100.00%1100.00%
Total78100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Mike Isely335399.55%1168.75%
Pantelis Koukousoulas80.24%16.25%
Hans Verkuil30.09%16.25%
Roel Kluin20.06%16.25%
Al Viro10.03%16.25%
Sakari Ailus10.03%16.25%
Total3368100.00%16100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.