diff options
-rw-r--r-- | drivers/infiniband/core/sysfs.c | 120 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 13 | ||||
-rw-r--r-- | include/linux/sysfs.h | 4 |
3 files changed, 58 insertions, 79 deletions
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 3a413f72ff6d..5febd6d8b885 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -40,9 +40,7 @@ struct ib_port { | |||
40 | struct kobject kobj; | 40 | struct kobject kobj; |
41 | struct ib_device *ibdev; | 41 | struct ib_device *ibdev; |
42 | struct attribute_group gid_group; | 42 | struct attribute_group gid_group; |
43 | struct attribute **gid_attr; | ||
44 | struct attribute_group pkey_group; | 43 | struct attribute_group pkey_group; |
45 | struct attribute **pkey_attr; | ||
46 | u8 port_num; | 44 | u8 port_num; |
47 | }; | 45 | }; |
48 | 46 | ||
@@ -60,8 +58,9 @@ struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store) | |||
60 | struct port_attribute port_attr_##_name = __ATTR_RO(_name) | 58 | struct port_attribute port_attr_##_name = __ATTR_RO(_name) |
61 | 59 | ||
62 | struct port_table_attribute { | 60 | struct port_table_attribute { |
63 | struct port_attribute attr; | 61 | struct port_attribute attr; |
64 | int index; | 62 | char name[8]; |
63 | int index; | ||
65 | }; | 64 | }; |
66 | 65 | ||
67 | static ssize_t port_attr_show(struct kobject *kobj, | 66 | static ssize_t port_attr_show(struct kobject *kobj, |
@@ -398,17 +397,16 @@ static void ib_port_release(struct kobject *kobj) | |||
398 | struct attribute *a; | 397 | struct attribute *a; |
399 | int i; | 398 | int i; |
400 | 399 | ||
401 | for (i = 0; (a = p->gid_attr[i]); ++i) { | 400 | for (i = 0; (a = p->gid_group.attrs[i]); ++i) |
402 | kfree(a->name); | ||
403 | kfree(a); | 401 | kfree(a); |
404 | } | ||
405 | 402 | ||
406 | for (i = 0; (a = p->pkey_attr[i]); ++i) { | 403 | kfree(p->gid_group.attrs); |
407 | kfree(a->name); | 404 | |
405 | for (i = 0; (a = p->pkey_group.attrs[i]); ++i) | ||
408 | kfree(a); | 406 | kfree(a); |
409 | } | ||
410 | 407 | ||
411 | kfree(p->gid_attr); | 408 | kfree(p->pkey_group.attrs); |
409 | |||
412 | kfree(p); | 410 | kfree(p); |
413 | } | 411 | } |
414 | 412 | ||
@@ -449,58 +447,45 @@ static int ib_device_hotplug(struct class_device *cdev, char **envp, | |||
449 | return 0; | 447 | return 0; |
450 | } | 448 | } |
451 | 449 | ||
452 | static int alloc_group(struct attribute ***attr, | 450 | static struct attribute ** |
453 | ssize_t (*show)(struct ib_port *, | 451 | alloc_group_attrs(ssize_t (*show)(struct ib_port *, |
454 | struct port_attribute *, char *buf), | 452 | struct port_attribute *, char *buf), |
455 | int len) | 453 | int len) |
456 | { | 454 | { |
457 | struct port_table_attribute ***tab_attr = | 455 | struct attribute **tab_attr; |
458 | (struct port_table_attribute ***) attr; | 456 | struct port_table_attribute *element; |
459 | int i; | 457 | int i; |
460 | int ret; | ||
461 | |||
462 | *tab_attr = kmalloc((1 + len) * sizeof *tab_attr, GFP_KERNEL); | ||
463 | if (!*tab_attr) | ||
464 | return -ENOMEM; | ||
465 | 458 | ||
466 | memset(*tab_attr, 0, (1 + len) * sizeof *tab_attr); | 459 | tab_attr = kcalloc(1 + len, sizeof(struct attribute *), GFP_KERNEL); |
460 | if (!tab_attr) | ||
461 | return NULL; | ||
467 | 462 | ||
468 | for (i = 0; i < len; ++i) { | 463 | for (i = 0; i < len; i++) { |
469 | (*tab_attr)[i] = kmalloc(sizeof *(*tab_attr)[i], GFP_KERNEL); | 464 | element = kcalloc(1, sizeof(struct port_table_attribute), |
470 | if (!(*tab_attr)[i]) { | 465 | GFP_KERNEL); |
471 | ret = -ENOMEM; | 466 | if (!element) |
472 | goto err; | 467 | goto err; |
473 | } | ||
474 | memset((*tab_attr)[i], 0, sizeof *(*tab_attr)[i]); | ||
475 | (*tab_attr)[i]->attr.attr.name = kmalloc(8, GFP_KERNEL); | ||
476 | if (!(*tab_attr)[i]->attr.attr.name) { | ||
477 | ret = -ENOMEM; | ||
478 | goto err; | ||
479 | } | ||
480 | 468 | ||
481 | if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) { | 469 | if (snprintf(element->name, sizeof(element->name), |
482 | ret = -ENOMEM; | 470 | "%d", i) >= sizeof(element->name)) |
483 | goto err; | 471 | goto err; |
484 | } | ||
485 | 472 | ||
486 | (*tab_attr)[i]->attr.attr.mode = S_IRUGO; | 473 | element->attr.attr.name = element->name; |
487 | (*tab_attr)[i]->attr.attr.owner = THIS_MODULE; | 474 | element->attr.attr.mode = S_IRUGO; |
488 | (*tab_attr)[i]->attr.show = show; | 475 | element->attr.attr.owner = THIS_MODULE; |
489 | (*tab_attr)[i]->index = i; | 476 | element->attr.show = show; |
490 | } | 477 | element->index = i; |
491 | |||
492 | return 0; | ||
493 | 478 | ||
494 | err: | 479 | tab_attr[i] = &element->attr.attr; |
495 | for (i = 0; i < len; ++i) { | ||
496 | if ((*tab_attr)[i]) | ||
497 | kfree((*tab_attr)[i]->attr.attr.name); | ||
498 | kfree((*tab_attr)[i]); | ||
499 | } | 480 | } |
500 | 481 | ||
501 | kfree(*tab_attr); | 482 | return tab_attr; |
502 | 483 | ||
503 | return ret; | 484 | err: |
485 | while (--i >= 0) | ||
486 | kfree(tab_attr[i]); | ||
487 | kfree(tab_attr); | ||
488 | return NULL; | ||
504 | } | 489 | } |
505 | 490 | ||
506 | static int add_port(struct ib_device *device, int port_num) | 491 | static int add_port(struct ib_device *device, int port_num) |
@@ -541,23 +526,20 @@ static int add_port(struct ib_device *device, int port_num) | |||
541 | if (ret) | 526 | if (ret) |
542 | goto err_put; | 527 | goto err_put; |
543 | 528 | ||
544 | ret = alloc_group(&p->gid_attr, show_port_gid, attr.gid_tbl_len); | ||
545 | if (ret) | ||
546 | goto err_remove_pma; | ||
547 | |||
548 | p->gid_group.name = "gids"; | 529 | p->gid_group.name = "gids"; |
549 | p->gid_group.attrs = p->gid_attr; | 530 | p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len); |
531 | if (!p->gid_group.attrs) | ||
532 | goto err_remove_pma; | ||
550 | 533 | ||
551 | ret = sysfs_create_group(&p->kobj, &p->gid_group); | 534 | ret = sysfs_create_group(&p->kobj, &p->gid_group); |
552 | if (ret) | 535 | if (ret) |
553 | goto err_free_gid; | 536 | goto err_free_gid; |
554 | 537 | ||
555 | ret = alloc_group(&p->pkey_attr, show_port_pkey, attr.pkey_tbl_len); | ||
556 | if (ret) | ||
557 | goto err_remove_gid; | ||
558 | |||
559 | p->pkey_group.name = "pkeys"; | 538 | p->pkey_group.name = "pkeys"; |
560 | p->pkey_group.attrs = p->pkey_attr; | 539 | p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, |
540 | attr.pkey_tbl_len); | ||
541 | if (!p->pkey_group.attrs) | ||
542 | goto err_remove_gid; | ||
561 | 543 | ||
562 | ret = sysfs_create_group(&p->kobj, &p->pkey_group); | 544 | ret = sysfs_create_group(&p->kobj, &p->pkey_group); |
563 | if (ret) | 545 | if (ret) |
@@ -568,23 +550,19 @@ static int add_port(struct ib_device *device, int port_num) | |||
568 | return 0; | 550 | return 0; |
569 | 551 | ||
570 | err_free_pkey: | 552 | err_free_pkey: |
571 | for (i = 0; i < attr.pkey_tbl_len; ++i) { | 553 | for (i = 0; i < attr.pkey_tbl_len; ++i) |
572 | kfree(p->pkey_attr[i]->name); | 554 | kfree(p->pkey_group.attrs[i]); |
573 | kfree(p->pkey_attr[i]); | ||
574 | } | ||
575 | 555 | ||
576 | kfree(p->pkey_attr); | 556 | kfree(p->pkey_group.attrs); |
577 | 557 | ||
578 | err_remove_gid: | 558 | err_remove_gid: |
579 | sysfs_remove_group(&p->kobj, &p->gid_group); | 559 | sysfs_remove_group(&p->kobj, &p->gid_group); |
580 | 560 | ||
581 | err_free_gid: | 561 | err_free_gid: |
582 | for (i = 0; i < attr.gid_tbl_len; ++i) { | 562 | for (i = 0; i < attr.gid_tbl_len; ++i) |
583 | kfree(p->gid_attr[i]->name); | 563 | kfree(p->gid_group.attrs[i]); |
584 | kfree(p->gid_attr[i]); | ||
585 | } | ||
586 | 564 | ||
587 | kfree(p->gid_attr); | 565 | kfree(p->gid_group.attrs); |
588 | 566 | ||
589 | err_remove_pma: | 567 | err_remove_pma: |
590 | sysfs_remove_group(&p->kobj, &pma_group); | 568 | sysfs_remove_group(&p->kobj, &pma_group); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6ca0061137a6..e8aad151175f 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -339,16 +339,17 @@ pci_create_resource_files(struct pci_dev *pdev) | |||
339 | if (!pci_resource_len(pdev, i)) | 339 | if (!pci_resource_len(pdev, i)) |
340 | continue; | 340 | continue; |
341 | 341 | ||
342 | res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC); | 342 | /* allocate attribute structure, piggyback attribute name */ |
343 | res_attr = kcalloc(1, sizeof(*res_attr) + 10, GFP_ATOMIC); | ||
343 | if (res_attr) { | 344 | if (res_attr) { |
344 | memset(res_attr, 0, sizeof(*res_attr) + 10); | 345 | char *res_attr_name = (char *)(res_attr + 1); |
346 | |||
345 | pdev->res_attr[i] = res_attr; | 347 | pdev->res_attr[i] = res_attr; |
346 | /* Allocated above after the res_attr struct */ | 348 | sprintf(res_attr_name, "resource%d", i); |
347 | res_attr->attr.name = (char *)(res_attr + 1); | 349 | res_attr->attr.name = res_attr_name; |
348 | sprintf(res_attr->attr.name, "resource%d", i); | ||
349 | res_attr->size = pci_resource_len(pdev, i); | ||
350 | res_attr->attr.mode = S_IRUSR | S_IWUSR; | 350 | res_attr->attr.mode = S_IRUSR | S_IWUSR; |
351 | res_attr->attr.owner = THIS_MODULE; | 351 | res_attr->attr.owner = THIS_MODULE; |
352 | res_attr->size = pci_resource_len(pdev, i); | ||
352 | res_attr->mmap = pci_mmap_resource; | 353 | res_attr->mmap = pci_mmap_resource; |
353 | res_attr->private = &pdev->resource[i]; | 354 | res_attr->private = &pdev->resource[i]; |
354 | sysfs_create_bin_file(&pdev->dev.kobj, res_attr); | 355 | sysfs_create_bin_file(&pdev->dev.kobj, res_attr); |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 931b5aaaf380..d9cd2d31d377 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -16,13 +16,13 @@ struct kobject; | |||
16 | struct module; | 16 | struct module; |
17 | 17 | ||
18 | struct attribute { | 18 | struct attribute { |
19 | char * name; | 19 | const char * name; |
20 | struct module * owner; | 20 | struct module * owner; |
21 | mode_t mode; | 21 | mode_t mode; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | struct attribute_group { | 24 | struct attribute_group { |
25 | char * name; | 25 | const char * name; |
26 | struct attribute ** attrs; | 26 | struct attribute ** attrs; |
27 | }; | 27 | }; |
28 | 28 | ||