diff options
Diffstat (limited to 'drivers/misc/thinkpad_acpi.c')
| -rw-r--r-- | drivers/misc/thinkpad_acpi.c | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index a31d00d570cb..ca6d15cdc5f0 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
| @@ -520,12 +520,8 @@ static ssize_t tpacpi_driver_debug_store(struct device_driver *drv, | |||
| 520 | const char *buf, size_t count) | 520 | const char *buf, size_t count) |
| 521 | { | 521 | { |
| 522 | unsigned long t; | 522 | unsigned long t; |
| 523 | char *endp; | ||
| 524 | 523 | ||
| 525 | t = simple_strtoul(buf, &endp, 0); | 524 | if (parse_strtoul(buf, 0xffff, &t)) |
| 526 | while (*endp && isspace(*endp)) | ||
| 527 | endp++; | ||
| 528 | if (*endp) | ||
| 529 | return -EINVAL; | 525 | return -EINVAL; |
| 530 | 526 | ||
| 531 | dbg_level = t; | 527 | dbg_level = t; |
| @@ -575,6 +571,86 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) | |||
| 575 | driver_remove_file(drv, tpacpi_driver_attributes[i]); | 571 | driver_remove_file(drv, tpacpi_driver_attributes[i]); |
| 576 | } | 572 | } |
| 577 | 573 | ||
| 574 | /************************************************************************* | ||
| 575 | * sysfs support helpers | ||
| 576 | */ | ||
| 577 | |||
| 578 | struct attribute_set_obj { | ||
| 579 | struct attribute_set s; | ||
| 580 | struct attribute *a; | ||
| 581 | } __attribute__((packed)); | ||
| 582 | |||
| 583 | static struct attribute_set *create_attr_set(unsigned int max_members, | ||
| 584 | const char* name) | ||
| 585 | { | ||
| 586 | struct attribute_set_obj *sobj; | ||
| 587 | |||
| 588 | if (max_members == 0) | ||
| 589 | return NULL; | ||
| 590 | |||
| 591 | /* Allocates space for implicit NULL at the end too */ | ||
| 592 | sobj = kzalloc(sizeof(struct attribute_set_obj) + | ||
| 593 | max_members * sizeof(struct attribute *), | ||
| 594 | GFP_KERNEL); | ||
| 595 | if (!sobj) | ||
| 596 | return NULL; | ||
| 597 | sobj->s.max_members = max_members; | ||
| 598 | sobj->s.group.attrs = &sobj->a; | ||
| 599 | sobj->s.group.name = name; | ||
| 600 | |||
| 601 | return &sobj->s; | ||
| 602 | } | ||
| 603 | |||
| 604 | /* not multi-threaded safe, use it in a single thread per set */ | ||
| 605 | static int add_to_attr_set(struct attribute_set* s, struct attribute *attr) | ||
| 606 | { | ||
| 607 | if (!s || !attr) | ||
| 608 | return -EINVAL; | ||
| 609 | |||
| 610 | if (s->members >= s->max_members) | ||
| 611 | return -ENOMEM; | ||
| 612 | |||
| 613 | s->group.attrs[s->members] = attr; | ||
| 614 | s->members++; | ||
| 615 | |||
| 616 | return 0; | ||
| 617 | } | ||
| 618 | |||
| 619 | static int add_many_to_attr_set(struct attribute_set* s, | ||
| 620 | struct attribute **attr, | ||
| 621 | unsigned int count) | ||
| 622 | { | ||
| 623 | int i, res; | ||
| 624 | |||
| 625 | for (i = 0; i < count; i++) { | ||
| 626 | res = add_to_attr_set(s, attr[i]); | ||
| 627 | if (res) | ||
| 628 | return res; | ||
| 629 | } | ||
| 630 | |||
| 631 | return 0; | ||
| 632 | } | ||
| 633 | |||
| 634 | static void delete_attr_set(struct attribute_set* s, struct kobject *kobj) | ||
| 635 | { | ||
| 636 | sysfs_remove_group(kobj, &s->group); | ||
| 637 | destroy_attr_set(s); | ||
| 638 | } | ||
| 639 | |||
| 640 | static int parse_strtoul(const char *buf, | ||
| 641 | unsigned long max, unsigned long *value) | ||
| 642 | { | ||
| 643 | char *endp; | ||
| 644 | |||
| 645 | *value = simple_strtoul(buf, &endp, 0); | ||
| 646 | while (*endp && isspace(*endp)) | ||
| 647 | endp++; | ||
| 648 | if (*endp || *value > max) | ||
| 649 | return -EINVAL; | ||
| 650 | |||
| 651 | return 0; | ||
| 652 | } | ||
| 653 | |||
| 578 | /**************************************************************************** | 654 | /**************************************************************************** |
| 579 | **************************************************************************** | 655 | **************************************************************************** |
| 580 | * | 656 | * |
