aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/sysfs.c120
-rw-r--r--drivers/pci/pci-sysfs.c13
-rw-r--r--include/linux/sysfs.h4
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)
60struct port_attribute port_attr_##_name = __ATTR_RO(_name) 58struct port_attribute port_attr_##_name = __ATTR_RO(_name)
61 59
62struct port_table_attribute { 60struct 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
67static ssize_t port_attr_show(struct kobject *kobj, 66static 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
452static int alloc_group(struct attribute ***attr, 450static struct attribute **
453 ssize_t (*show)(struct ib_port *, 451alloc_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
494err: 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; 484err:
485 while (--i >= 0)
486 kfree(tab_attr[i]);
487 kfree(tab_attr);
488 return NULL;
504} 489}
505 490
506static int add_port(struct ib_device *device, int port_num) 491static 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
570err_free_pkey: 552err_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
578err_remove_gid: 558err_remove_gid:
579 sysfs_remove_group(&p->kobj, &p->gid_group); 559 sysfs_remove_group(&p->kobj, &p->gid_group);
580 560
581err_free_gid: 561err_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
589err_remove_pma: 567err_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;
16struct module; 16struct module;
17 17
18struct attribute { 18struct 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
24struct attribute_group { 24struct attribute_group {
25 char * name; 25 const char * name;
26 struct attribute ** attrs; 26 struct attribute ** attrs;
27}; 27};
28 28