root/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. show_name
  2. show_type
  3. show_min
  4. show_max
  5. show_def
  6. show_val_norm
  7. show_val_custom
  8. show_enum
  9. show_bits
  10. store_val_any
  11. store_val_norm
  12. store_val_custom
  13. pvr2_sysfs_add_control
  14. pvr2_sysfs_add_debugifc
  15. pvr2_sysfs_tear_down_debugifc
  16. pvr2_sysfs_add_controls
  17. pvr2_sysfs_tear_down_controls
  18. pvr2_sysfs_class_release
  19. pvr2_sysfs_release
  20. class_dev_destroy
  21. v4l_minor_number_show
  22. bus_info_show
  23. hdw_name_show
  24. hdw_desc_show
  25. v4l_radio_minor_number_show
  26. unit_number_show
  27. class_dev_create
  28. pvr2_sysfs_internal_check
  29. pvr2_sysfs_create
  30. pvr2_sysfs_class_create
  31. pvr2_sysfs_class_destroy
  32. debuginfo_show
  33. debugcmd_show
  34. debugcmd_store

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   5  */
   6 
   7 #include <linux/string.h>
   8 #include <linux/slab.h>
   9 #include "pvrusb2-sysfs.h"
  10 #include "pvrusb2-hdw.h"
  11 #include "pvrusb2-debug.h"
  12 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
  13 #include "pvrusb2-debugifc.h"
  14 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
  15 
  16 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
  17 
  18 struct pvr2_sysfs {
  19         struct pvr2_channel channel;
  20         struct device *class_dev;
  21 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
  22         struct pvr2_sysfs_debugifc *debugifc;
  23 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
  24         struct pvr2_sysfs_ctl_item *item_first;
  25         struct pvr2_sysfs_ctl_item *item_last;
  26         struct device_attribute attr_v4l_minor_number;
  27         struct device_attribute attr_v4l_radio_minor_number;
  28         struct device_attribute attr_unit_number;
  29         struct device_attribute attr_bus_info;
  30         struct device_attribute attr_hdw_name;
  31         struct device_attribute attr_hdw_desc;
  32         int v4l_minor_number_created_ok;
  33         int v4l_radio_minor_number_created_ok;
  34         int unit_number_created_ok;
  35         int bus_info_created_ok;
  36         int hdw_name_created_ok;
  37         int hdw_desc_created_ok;
  38 };
  39 
  40 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
  41 struct pvr2_sysfs_debugifc {
  42         struct device_attribute attr_debugcmd;
  43         struct device_attribute attr_debuginfo;
  44         int debugcmd_created_ok;
  45         int debuginfo_created_ok;
  46 };
  47 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
  48 
  49 struct pvr2_sysfs_ctl_item {
  50         struct device_attribute attr_name;
  51         struct device_attribute attr_type;
  52         struct device_attribute attr_min;
  53         struct device_attribute attr_max;
  54         struct device_attribute attr_def;
  55         struct device_attribute attr_enum;
  56         struct device_attribute attr_bits;
  57         struct device_attribute attr_val;
  58         struct device_attribute attr_custom;
  59         struct pvr2_ctrl *cptr;
  60         int ctl_id;
  61         struct pvr2_sysfs *chptr;
  62         struct pvr2_sysfs_ctl_item *item_next;
  63         struct attribute *attr_gen[8];
  64         struct attribute_group grp;
  65         int created_ok;
  66         char name[80];
  67 };
  68 
  69 struct pvr2_sysfs_class {
  70         struct class class;
  71 };
  72 
  73 static ssize_t show_name(struct device *class_dev,
  74                          struct device_attribute *attr,
  75                          char *buf)
  76 {
  77         struct pvr2_sysfs_ctl_item *cip;
  78         const char *name;
  79         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name);
  80         name = pvr2_ctrl_get_desc(cip->cptr);
  81         pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
  82                          cip->chptr, cip->ctl_id, name);
  83         if (!name) return -EINVAL;
  84         return scnprintf(buf, PAGE_SIZE, "%s\n", name);
  85 }
  86 
  87 static ssize_t show_type(struct device *class_dev,
  88                          struct device_attribute *attr,
  89                          char *buf)
  90 {
  91         struct pvr2_sysfs_ctl_item *cip;
  92         const char *name;
  93         enum pvr2_ctl_type tp;
  94         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type);
  95         tp = pvr2_ctrl_get_type(cip->cptr);
  96         switch (tp) {
  97         case pvr2_ctl_int: name = "integer"; break;
  98         case pvr2_ctl_enum: name = "enum"; break;
  99         case pvr2_ctl_bitmask: name = "bitmask"; break;
 100         case pvr2_ctl_bool: name = "boolean"; break;
 101         default: name = "?"; break;
 102         }
 103         pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
 104                          cip->chptr, cip->ctl_id, name);
 105         return scnprintf(buf, PAGE_SIZE, "%s\n", name);
 106 }
 107 
 108 static ssize_t show_min(struct device *class_dev,
 109                         struct device_attribute *attr,
 110                         char *buf)
 111 {
 112         struct pvr2_sysfs_ctl_item *cip;
 113         long val;
 114         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min);
 115         val = pvr2_ctrl_get_min(cip->cptr);
 116         pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
 117                          cip->chptr, cip->ctl_id, val);
 118         return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
 119 }
 120 
 121 static ssize_t show_max(struct device *class_dev,
 122                         struct device_attribute *attr,
 123                         char *buf)
 124 {
 125         struct pvr2_sysfs_ctl_item *cip;
 126         long val;
 127         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max);
 128         val = pvr2_ctrl_get_max(cip->cptr);
 129         pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
 130                          cip->chptr, cip->ctl_id, val);
 131         return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
 132 }
 133 
 134 static ssize_t show_def(struct device *class_dev,
 135                         struct device_attribute *attr,
 136                         char *buf)
 137 {
 138         struct pvr2_sysfs_ctl_item *cip;
 139         int val;
 140         int ret;
 141         unsigned int cnt = 0;
 142         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def);
 143         ret = pvr2_ctrl_get_def(cip->cptr, &val);
 144         if (ret < 0) return ret;
 145         ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
 146                                      buf, PAGE_SIZE - 1, &cnt);
 147         pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
 148                          cip->chptr, cip->ctl_id, cnt, buf, val);
 149         buf[cnt] = '\n';
 150         return cnt + 1;
 151 }
 152 
 153 static ssize_t show_val_norm(struct device *class_dev,
 154                              struct device_attribute *attr,
 155                              char *buf)
 156 {
 157         struct pvr2_sysfs_ctl_item *cip;
 158         int val;
 159         int ret;
 160         unsigned int cnt = 0;
 161         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
 162         ret = pvr2_ctrl_get_value(cip->cptr, &val);
 163         if (ret < 0) return ret;
 164         ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
 165                                      buf, PAGE_SIZE - 1, &cnt);
 166         pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
 167                          cip->chptr, cip->ctl_id, cnt, buf, val);
 168         buf[cnt] = '\n';
 169         return cnt+1;
 170 }
 171 
 172 static ssize_t show_val_custom(struct device *class_dev,
 173                                struct device_attribute *attr,
 174                                char *buf)
 175 {
 176         struct pvr2_sysfs_ctl_item *cip;
 177         int val;
 178         int ret;
 179         unsigned int cnt = 0;
 180         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
 181         ret = pvr2_ctrl_get_value(cip->cptr, &val);
 182         if (ret < 0) return ret;
 183         ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val,
 184                                             buf, PAGE_SIZE - 1, &cnt);
 185         pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
 186                          cip->chptr, cip->ctl_id, cnt, buf, val);
 187         buf[cnt] = '\n';
 188         return cnt+1;
 189 }
 190 
 191 static ssize_t show_enum(struct device *class_dev,
 192                          struct device_attribute *attr,
 193                          char *buf)
 194 {
 195         struct pvr2_sysfs_ctl_item *cip;
 196         long val;
 197         unsigned int bcnt, ccnt, ecnt;
 198         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum);
 199         ecnt = pvr2_ctrl_get_cnt(cip->cptr);
 200         bcnt = 0;
 201         for (val = 0; val < ecnt; val++) {
 202                 pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt,
 203                                       PAGE_SIZE - bcnt, &ccnt);
 204                 if (!ccnt) continue;
 205                 bcnt += ccnt;
 206                 if (bcnt >= PAGE_SIZE) break;
 207                 buf[bcnt] = '\n';
 208                 bcnt++;
 209         }
 210         pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
 211                          cip->chptr, cip->ctl_id);
 212         return bcnt;
 213 }
 214 
 215 static ssize_t show_bits(struct device *class_dev,
 216                          struct device_attribute *attr,
 217                          char *buf)
 218 {
 219         struct pvr2_sysfs_ctl_item *cip;
 220         int valid_bits, msk;
 221         unsigned int bcnt, ccnt;
 222         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits);
 223         valid_bits = pvr2_ctrl_get_mask(cip->cptr);
 224         bcnt = 0;
 225         for (msk = 1; valid_bits; msk <<= 1) {
 226                 if (!(msk & valid_bits)) continue;
 227                 valid_bits &= ~msk;
 228                 pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt,
 229                                       PAGE_SIZE - bcnt, &ccnt);
 230                 bcnt += ccnt;
 231                 if (bcnt >= PAGE_SIZE) break;
 232                 buf[bcnt] = '\n';
 233                 bcnt++;
 234         }
 235         pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
 236                          cip->chptr, cip->ctl_id);
 237         return bcnt;
 238 }
 239 
 240 static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl,
 241                          const char *buf,unsigned int count)
 242 {
 243         int ret;
 244         int mask,val;
 245         if (customfl) {
 246                 ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count,
 247                                                     &mask, &val);
 248         } else {
 249                 ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count,
 250                                              &mask, &val);
 251         }
 252         if (ret < 0) return ret;
 253         ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val);
 254         pvr2_hdw_commit_ctl(cip->chptr->channel.hdw);
 255         return ret;
 256 }
 257 
 258 static ssize_t store_val_norm(struct device *class_dev,
 259                               struct device_attribute *attr,
 260                               const char *buf, size_t count)
 261 {
 262         struct pvr2_sysfs_ctl_item *cip;
 263         int ret;
 264         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
 265         pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
 266                          cip->chptr, cip->ctl_id, (int)count, buf);
 267         ret = store_val_any(cip, 0, buf, count);
 268         if (!ret) ret = count;
 269         return ret;
 270 }
 271 
 272 static ssize_t store_val_custom(struct device *class_dev,
 273                                 struct device_attribute *attr,
 274                                 const char *buf, size_t count)
 275 {
 276         struct pvr2_sysfs_ctl_item *cip;
 277         int ret;
 278         cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
 279         pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
 280                          cip->chptr, cip->ctl_id, (int)count, buf);
 281         ret = store_val_any(cip, 1, buf, count);
 282         if (!ret) ret = count;
 283         return ret;
 284 }
 285 
 286 static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
 287 {
 288         struct pvr2_sysfs_ctl_item *cip;
 289         struct pvr2_ctrl *cptr;
 290         unsigned int cnt,acnt;
 291         int ret;
 292 
 293         cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
 294         if (!cptr) return;
 295 
 296         cip = kzalloc(sizeof(*cip),GFP_KERNEL);
 297         if (!cip) return;
 298         pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
 299 
 300         cip->cptr = cptr;
 301         cip->ctl_id = ctl_id;
 302 
 303         cip->chptr = sfp;
 304         cip->item_next = NULL;
 305         if (sfp->item_last) {
 306                 sfp->item_last->item_next = cip;
 307         } else {
 308                 sfp->item_first = cip;
 309         }
 310         sfp->item_last = cip;
 311 
 312         sysfs_attr_init(&cip->attr_name.attr);
 313         cip->attr_name.attr.name = "name";
 314         cip->attr_name.attr.mode = S_IRUGO;
 315         cip->attr_name.show = show_name;
 316 
 317         sysfs_attr_init(&cip->attr_type.attr);
 318         cip->attr_type.attr.name = "type";
 319         cip->attr_type.attr.mode = S_IRUGO;
 320         cip->attr_type.show = show_type;
 321 
 322         sysfs_attr_init(&cip->attr_min.attr);
 323         cip->attr_min.attr.name = "min_val";
 324         cip->attr_min.attr.mode = S_IRUGO;
 325         cip->attr_min.show = show_min;
 326 
 327         sysfs_attr_init(&cip->attr_max.attr);
 328         cip->attr_max.attr.name = "max_val";
 329         cip->attr_max.attr.mode = S_IRUGO;
 330         cip->attr_max.show = show_max;
 331 
 332         sysfs_attr_init(&cip->attr_def.attr);
 333         cip->attr_def.attr.name = "def_val";
 334         cip->attr_def.attr.mode = S_IRUGO;
 335         cip->attr_def.show = show_def;
 336 
 337         sysfs_attr_init(&cip->attr_val.attr);
 338         cip->attr_val.attr.name = "cur_val";
 339         cip->attr_val.attr.mode = S_IRUGO;
 340 
 341         sysfs_attr_init(&cip->attr_custom.attr);
 342         cip->attr_custom.attr.name = "custom_val";
 343         cip->attr_custom.attr.mode = S_IRUGO;
 344 
 345         sysfs_attr_init(&cip->attr_enum.attr);
 346         cip->attr_enum.attr.name = "enum_val";
 347         cip->attr_enum.attr.mode = S_IRUGO;
 348         cip->attr_enum.show = show_enum;
 349 
 350         sysfs_attr_init(&cip->attr_bits.attr);
 351         cip->attr_bits.attr.name = "bit_val";
 352         cip->attr_bits.attr.mode = S_IRUGO;
 353         cip->attr_bits.show = show_bits;
 354 
 355         if (pvr2_ctrl_is_writable(cptr)) {
 356                 cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
 357                 cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
 358         }
 359 
 360         acnt = 0;
 361         cip->attr_gen[acnt++] = &cip->attr_name.attr;
 362         cip->attr_gen[acnt++] = &cip->attr_type.attr;
 363         cip->attr_gen[acnt++] = &cip->attr_val.attr;
 364         cip->attr_gen[acnt++] = &cip->attr_def.attr;
 365         cip->attr_val.show = show_val_norm;
 366         cip->attr_val.store = store_val_norm;
 367         if (pvr2_ctrl_has_custom_symbols(cptr)) {
 368                 cip->attr_gen[acnt++] = &cip->attr_custom.attr;
 369                 cip->attr_custom.show = show_val_custom;
 370                 cip->attr_custom.store = store_val_custom;
 371         }
 372         switch (pvr2_ctrl_get_type(cptr)) {
 373         case pvr2_ctl_enum:
 374                 // Control is an enumeration
 375                 cip->attr_gen[acnt++] = &cip->attr_enum.attr;
 376                 break;
 377         case pvr2_ctl_int:
 378                 // Control is an integer
 379                 cip->attr_gen[acnt++] = &cip->attr_min.attr;
 380                 cip->attr_gen[acnt++] = &cip->attr_max.attr;
 381                 break;
 382         case pvr2_ctl_bitmask:
 383                 // Control is an bitmask
 384                 cip->attr_gen[acnt++] = &cip->attr_bits.attr;
 385                 break;
 386         default: break;
 387         }
 388 
 389         cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
 390                         pvr2_ctrl_get_name(cptr));
 391         cip->name[cnt] = 0;
 392         cip->grp.name = cip->name;
 393         cip->grp.attrs = cip->attr_gen;
 394 
 395         ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
 396         if (ret) {
 397                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 398                            "sysfs_create_group error: %d",
 399                            ret);
 400                 return;
 401         }
 402         cip->created_ok = !0;
 403 }
 404 
 405 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
 406 static ssize_t debuginfo_show(struct device *, struct device_attribute *,
 407                               char *);
 408 static ssize_t debugcmd_show(struct device *, struct device_attribute *,
 409                              char *);
 410 static ssize_t debugcmd_store(struct device *, struct device_attribute *,
 411                               const char *, size_t count);
 412 
 413 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
 414 {
 415         struct pvr2_sysfs_debugifc *dip;
 416         int ret;
 417 
 418         dip = kzalloc(sizeof(*dip),GFP_KERNEL);
 419         if (!dip) return;
 420         sysfs_attr_init(&dip->attr_debugcmd.attr);
 421         dip->attr_debugcmd.attr.name = "debugcmd";
 422         dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
 423         dip->attr_debugcmd.show = debugcmd_show;
 424         dip->attr_debugcmd.store = debugcmd_store;
 425         sysfs_attr_init(&dip->attr_debuginfo.attr);
 426         dip->attr_debuginfo.attr.name = "debuginfo";
 427         dip->attr_debuginfo.attr.mode = S_IRUGO;
 428         dip->attr_debuginfo.show = debuginfo_show;
 429         sfp->debugifc = dip;
 430         ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd);
 431         if (ret < 0) {
 432                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 433                            "device_create_file error: %d",
 434                            ret);
 435         } else {
 436                 dip->debugcmd_created_ok = !0;
 437         }
 438         ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo);
 439         if (ret < 0) {
 440                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 441                            "device_create_file error: %d",
 442                            ret);
 443         } else {
 444                 dip->debuginfo_created_ok = !0;
 445         }
 446 }
 447 
 448 
 449 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
 450 {
 451         if (!sfp->debugifc) return;
 452         if (sfp->debugifc->debuginfo_created_ok) {
 453                 device_remove_file(sfp->class_dev,
 454                                          &sfp->debugifc->attr_debuginfo);
 455         }
 456         if (sfp->debugifc->debugcmd_created_ok) {
 457                 device_remove_file(sfp->class_dev,
 458                                          &sfp->debugifc->attr_debugcmd);
 459         }
 460         kfree(sfp->debugifc);
 461         sfp->debugifc = NULL;
 462 }
 463 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
 464 
 465 
 466 static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
 467 {
 468         unsigned int idx,cnt;
 469         cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
 470         for (idx = 0; idx < cnt; idx++) {
 471                 pvr2_sysfs_add_control(sfp,idx);
 472         }
 473 }
 474 
 475 
 476 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
 477 {
 478         struct pvr2_sysfs_ctl_item *cip1,*cip2;
 479         for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
 480                 cip2 = cip1->item_next;
 481                 if (cip1->created_ok) {
 482                         sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
 483                 }
 484                 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
 485                 kfree(cip1);
 486         }
 487 }
 488 
 489 
 490 static void pvr2_sysfs_class_release(struct class *class)
 491 {
 492         struct pvr2_sysfs_class *clp;
 493         clp = container_of(class,struct pvr2_sysfs_class,class);
 494         pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
 495         kfree(clp);
 496 }
 497 
 498 
 499 static void pvr2_sysfs_release(struct device *class_dev)
 500 {
 501         pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
 502         kfree(class_dev);
 503 }
 504 
 505 
 506 static void class_dev_destroy(struct pvr2_sysfs *sfp)
 507 {
 508         struct device *dev;
 509         if (!sfp->class_dev) return;
 510 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
 511         pvr2_sysfs_tear_down_debugifc(sfp);
 512 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
 513         pvr2_sysfs_tear_down_controls(sfp);
 514         if (sfp->hdw_desc_created_ok) {
 515                 device_remove_file(sfp->class_dev,
 516                                    &sfp->attr_hdw_desc);
 517         }
 518         if (sfp->hdw_name_created_ok) {
 519                 device_remove_file(sfp->class_dev,
 520                                    &sfp->attr_hdw_name);
 521         }
 522         if (sfp->bus_info_created_ok) {
 523                 device_remove_file(sfp->class_dev,
 524                                          &sfp->attr_bus_info);
 525         }
 526         if (sfp->v4l_minor_number_created_ok) {
 527                 device_remove_file(sfp->class_dev,
 528                                          &sfp->attr_v4l_minor_number);
 529         }
 530         if (sfp->v4l_radio_minor_number_created_ok) {
 531                 device_remove_file(sfp->class_dev,
 532                                          &sfp->attr_v4l_radio_minor_number);
 533         }
 534         if (sfp->unit_number_created_ok) {
 535                 device_remove_file(sfp->class_dev,
 536                                          &sfp->attr_unit_number);
 537         }
 538         pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
 539         dev_set_drvdata(sfp->class_dev, NULL);
 540         dev = sfp->class_dev->parent;
 541         sfp->class_dev->parent = NULL;
 542         put_device(dev);
 543         device_unregister(sfp->class_dev);
 544         sfp->class_dev = NULL;
 545 }
 546 
 547 
 548 static ssize_t v4l_minor_number_show(struct device *class_dev,
 549                                      struct device_attribute *attr, char *buf)
 550 {
 551         struct pvr2_sysfs *sfp;
 552         sfp = dev_get_drvdata(class_dev);
 553         if (!sfp) return -EINVAL;
 554         return scnprintf(buf,PAGE_SIZE,"%d\n",
 555                          pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
 556                                                        pvr2_v4l_type_video));
 557 }
 558 
 559 
 560 static ssize_t bus_info_show(struct device *class_dev,
 561                              struct device_attribute *attr, char *buf)
 562 {
 563         struct pvr2_sysfs *sfp;
 564         sfp = dev_get_drvdata(class_dev);
 565         if (!sfp) return -EINVAL;
 566         return scnprintf(buf,PAGE_SIZE,"%s\n",
 567                          pvr2_hdw_get_bus_info(sfp->channel.hdw));
 568 }
 569 
 570 
 571 static ssize_t hdw_name_show(struct device *class_dev,
 572                              struct device_attribute *attr, char *buf)
 573 {
 574         struct pvr2_sysfs *sfp;
 575         sfp = dev_get_drvdata(class_dev);
 576         if (!sfp) return -EINVAL;
 577         return scnprintf(buf,PAGE_SIZE,"%s\n",
 578                          pvr2_hdw_get_type(sfp->channel.hdw));
 579 }
 580 
 581 
 582 static ssize_t hdw_desc_show(struct device *class_dev,
 583                              struct device_attribute *attr, char *buf)
 584 {
 585         struct pvr2_sysfs *sfp;
 586         sfp = dev_get_drvdata(class_dev);
 587         if (!sfp) return -EINVAL;
 588         return scnprintf(buf,PAGE_SIZE,"%s\n",
 589                          pvr2_hdw_get_desc(sfp->channel.hdw));
 590 }
 591 
 592 
 593 static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
 594                                            struct device_attribute *attr,
 595                                            char *buf)
 596 {
 597         struct pvr2_sysfs *sfp;
 598         sfp = dev_get_drvdata(class_dev);
 599         if (!sfp) return -EINVAL;
 600         return scnprintf(buf,PAGE_SIZE,"%d\n",
 601                          pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
 602                                                        pvr2_v4l_type_radio));
 603 }
 604 
 605 
 606 static ssize_t unit_number_show(struct device *class_dev,
 607                                 struct device_attribute *attr, char *buf)
 608 {
 609         struct pvr2_sysfs *sfp;
 610         sfp = dev_get_drvdata(class_dev);
 611         if (!sfp) return -EINVAL;
 612         return scnprintf(buf,PAGE_SIZE,"%d\n",
 613                          pvr2_hdw_get_unit_number(sfp->channel.hdw));
 614 }
 615 
 616 
 617 static void class_dev_create(struct pvr2_sysfs *sfp,
 618                              struct pvr2_sysfs_class *class_ptr)
 619 {
 620         struct usb_device *usb_dev;
 621         struct device *class_dev;
 622         int ret;
 623 
 624         usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
 625         if (!usb_dev) return;
 626         class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL);
 627         if (!class_dev) return;
 628 
 629         pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
 630 
 631         class_dev->class = &class_ptr->class;
 632 
 633         dev_set_name(class_dev, "%s",
 634                      pvr2_hdw_get_device_identifier(sfp->channel.hdw));
 635 
 636         class_dev->parent = get_device(&usb_dev->dev);
 637 
 638         sfp->class_dev = class_dev;
 639         dev_set_drvdata(class_dev, sfp);
 640         ret = device_register(class_dev);
 641         if (ret) {
 642                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 643                            "device_register failed");
 644                 put_device(class_dev);
 645                 return;
 646         }
 647 
 648         sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
 649         sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
 650         sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
 651         sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
 652         sfp->attr_v4l_minor_number.store = NULL;
 653         ret = device_create_file(sfp->class_dev,
 654                                        &sfp->attr_v4l_minor_number);
 655         if (ret < 0) {
 656                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 657                            "device_create_file error: %d",
 658                            ret);
 659         } else {
 660                 sfp->v4l_minor_number_created_ok = !0;
 661         }
 662 
 663         sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
 664         sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
 665         sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
 666         sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
 667         sfp->attr_v4l_radio_minor_number.store = NULL;
 668         ret = device_create_file(sfp->class_dev,
 669                                        &sfp->attr_v4l_radio_minor_number);
 670         if (ret < 0) {
 671                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 672                            "device_create_file error: %d",
 673                            ret);
 674         } else {
 675                 sfp->v4l_radio_minor_number_created_ok = !0;
 676         }
 677 
 678         sysfs_attr_init(&sfp->attr_unit_number.attr);
 679         sfp->attr_unit_number.attr.name = "unit_number";
 680         sfp->attr_unit_number.attr.mode = S_IRUGO;
 681         sfp->attr_unit_number.show = unit_number_show;
 682         sfp->attr_unit_number.store = NULL;
 683         ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number);
 684         if (ret < 0) {
 685                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 686                            "device_create_file error: %d",
 687                            ret);
 688         } else {
 689                 sfp->unit_number_created_ok = !0;
 690         }
 691 
 692         sysfs_attr_init(&sfp->attr_bus_info.attr);
 693         sfp->attr_bus_info.attr.name = "bus_info_str";
 694         sfp->attr_bus_info.attr.mode = S_IRUGO;
 695         sfp->attr_bus_info.show = bus_info_show;
 696         sfp->attr_bus_info.store = NULL;
 697         ret = device_create_file(sfp->class_dev,
 698                                        &sfp->attr_bus_info);
 699         if (ret < 0) {
 700                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 701                            "device_create_file error: %d",
 702                            ret);
 703         } else {
 704                 sfp->bus_info_created_ok = !0;
 705         }
 706 
 707         sysfs_attr_init(&sfp->attr_hdw_name.attr);
 708         sfp->attr_hdw_name.attr.name = "device_hardware_type";
 709         sfp->attr_hdw_name.attr.mode = S_IRUGO;
 710         sfp->attr_hdw_name.show = hdw_name_show;
 711         sfp->attr_hdw_name.store = NULL;
 712         ret = device_create_file(sfp->class_dev,
 713                                  &sfp->attr_hdw_name);
 714         if (ret < 0) {
 715                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 716                            "device_create_file error: %d",
 717                            ret);
 718         } else {
 719                 sfp->hdw_name_created_ok = !0;
 720         }
 721 
 722         sysfs_attr_init(&sfp->attr_hdw_desc.attr);
 723         sfp->attr_hdw_desc.attr.name = "device_hardware_description";
 724         sfp->attr_hdw_desc.attr.mode = S_IRUGO;
 725         sfp->attr_hdw_desc.show = hdw_desc_show;
 726         sfp->attr_hdw_desc.store = NULL;
 727         ret = device_create_file(sfp->class_dev,
 728                                  &sfp->attr_hdw_desc);
 729         if (ret < 0) {
 730                 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 731                            "device_create_file error: %d",
 732                            ret);
 733         } else {
 734                 sfp->hdw_desc_created_ok = !0;
 735         }
 736 
 737         pvr2_sysfs_add_controls(sfp);
 738 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
 739         pvr2_sysfs_add_debugifc(sfp);
 740 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
 741 }
 742 
 743 
 744 static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
 745 {
 746         struct pvr2_sysfs *sfp;
 747         sfp = container_of(chp,struct pvr2_sysfs,channel);
 748         if (!sfp->channel.mc_head->disconnect_flag) return;
 749         pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
 750         class_dev_destroy(sfp);
 751         pvr2_channel_done(&sfp->channel);
 752         kfree(sfp);
 753 }
 754 
 755 
 756 struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
 757                                      struct pvr2_sysfs_class *class_ptr)
 758 {
 759         struct pvr2_sysfs *sfp;
 760         sfp = kzalloc(sizeof(*sfp),GFP_KERNEL);
 761         if (!sfp) return sfp;
 762         pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
 763         pvr2_channel_init(&sfp->channel,mp);
 764         sfp->channel.check_func = pvr2_sysfs_internal_check;
 765 
 766         class_dev_create(sfp,class_ptr);
 767         return sfp;
 768 }
 769 
 770 
 771 
 772 struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
 773 {
 774         struct pvr2_sysfs_class *clp;
 775         clp = kzalloc(sizeof(*clp),GFP_KERNEL);
 776         if (!clp) return clp;
 777         pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
 778                          clp);
 779         clp->class.name = "pvrusb2";
 780         clp->class.class_release = pvr2_sysfs_class_release;
 781         clp->class.dev_release = pvr2_sysfs_release;
 782         if (class_register(&clp->class)) {
 783                 pvr2_sysfs_trace(
 784                         "Registration failed for pvr2_sysfs_class id=%p",clp);
 785                 kfree(clp);
 786                 clp = NULL;
 787         }
 788         return clp;
 789 }
 790 
 791 
 792 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
 793 {
 794         pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp);
 795         if (clp)
 796                 class_unregister(&clp->class);
 797 }
 798 
 799 
 800 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
 801 static ssize_t debuginfo_show(struct device *class_dev,
 802                               struct device_attribute *attr, char *buf)
 803 {
 804         struct pvr2_sysfs *sfp;
 805         sfp = dev_get_drvdata(class_dev);
 806         if (!sfp) return -EINVAL;
 807         pvr2_hdw_trigger_module_log(sfp->channel.hdw);
 808         return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
 809 }
 810 
 811 
 812 static ssize_t debugcmd_show(struct device *class_dev,
 813                              struct device_attribute *attr, char *buf)
 814 {
 815         struct pvr2_sysfs *sfp;
 816         sfp = dev_get_drvdata(class_dev);
 817         if (!sfp) return -EINVAL;
 818         return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
 819 }
 820 
 821 
 822 static ssize_t debugcmd_store(struct device *class_dev,
 823                               struct device_attribute *attr,
 824                               const char *buf, size_t count)
 825 {
 826         struct pvr2_sysfs *sfp;
 827         int ret;
 828 
 829         sfp = dev_get_drvdata(class_dev);
 830         if (!sfp) return -EINVAL;
 831 
 832         ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
 833         if (ret < 0) return ret;
 834         return count;
 835 }
 836 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */

/* [<][>][^][v][top][bottom][index][help] */