1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * This file supports the /sys/firmware/sgi_uv topology tree on HPE UV.
5 * Copyright (c) 2020 Hewlett Packard Enterprise. All Rights Reserved.
6 * Copyright (c) Justin Ernst
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/device.h>
12 #include <linux/slab.h>
13 #include <linux/kobject.h>
14 #include <asm/uv/bios.h>
15 #include <asm/uv/uv.h>
16 #include <asm/uv/uv_hub.h>
17 #include <asm/uv/uv_geo.h>
19 #define INVALID_CNODE -1
21 struct kobject
*sgi_uv_kobj
;
22 static struct kset
*uv_pcibus_kset
;
23 static struct kset
*uv_hubs_kset
;
24 static struct uv_bios_hub_info
*hub_buf
;
25 static struct uv_bios_port_info
**port_buf
;
26 static struct uv_hub
**uv_hubs
;
27 static struct uv_pci_top_obj
**uv_pci_objs
;
28 static int num_pci_lines
;
29 static int num_cnodes
;
30 static int *prev_obj_to_cnode
;
31 static int uv_bios_obj_cnt
;
32 static signed short uv_master_nasid
= -1;
33 static void *uv_biosheap
;
35 static const char *uv_type_string(void)
39 else if (is_uv4a_hub())
41 else if (is_uv4_hub())
43 else if (is_uv3_hub())
45 else if (is_uv2_hub())
47 else if (uv_get_hubless_system())
53 static int ordinal_to_nasid(int ordinal
)
55 if (ordinal
< num_cnodes
&& ordinal
>= 0)
56 return UV_PNODE_TO_NASID(uv_blade_to_pnode(ordinal
));
61 static union geoid_u
cnode_to_geoid(int cnode
)
65 uv_bios_get_geoinfo(ordinal_to_nasid(cnode
), (u64
)sizeof(union geoid_u
), (u64
*)&geoid
);
69 static int location_to_bpos(char *location
, int *rack
, int *slot
, int *blade
)
74 if (sscanf(location
, "%c%03d%c%02d%c%2d%c%d",
75 &r
, rack
, &type
, slot
, &b
, &idb
, &h
, &idh
) != 8)
77 *blade
= idb
* 2 + idh
;
82 static int cache_obj_to_cnode(struct uv_bios_hub_info
*obj
)
86 int obj_rack
, obj_slot
, obj_blade
;
87 int rack
, slot
, blade
;
89 if (!obj
->f
.fields
.this_part
&& !obj
->f
.fields
.is_shared
)
92 if (location_to_bpos(obj
->location
, &obj_rack
, &obj_slot
, &obj_blade
))
95 for (cnode
= 0; cnode
< num_cnodes
; cnode
++) {
96 geoid
= cnode_to_geoid(cnode
);
97 rack
= geo_rack(geoid
);
98 slot
= geo_slot(geoid
);
99 blade
= geo_blade(geoid
);
100 if (obj_rack
== rack
&& obj_slot
== slot
&& obj_blade
== blade
)
101 prev_obj_to_cnode
[obj
->id
] = cnode
;
107 static int get_obj_to_cnode(int obj_id
)
109 return prev_obj_to_cnode
[obj_id
];
114 struct uv_bios_hub_info
*hub_info
;
115 struct uv_port
**ports
;
118 #define to_uv_hub(kobj_ptr) container_of(kobj_ptr, struct uv_hub, kobj)
120 static ssize_t
hub_name_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
122 return scnprintf(buf
, PAGE_SIZE
, "%s\n", hub_info
->name
);
125 static ssize_t
hub_location_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
127 return scnprintf(buf
, PAGE_SIZE
, "%s\n", hub_info
->location
);
130 static ssize_t
hub_partition_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
132 return sprintf(buf
, "%d\n", hub_info
->f
.fields
.this_part
);
135 static ssize_t
hub_shared_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
137 return sprintf(buf
, "%d\n", hub_info
->f
.fields
.is_shared
);
139 static ssize_t
hub_nasid_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
141 int cnode
= get_obj_to_cnode(hub_info
->id
);
143 return sprintf(buf
, "%d\n", ordinal_to_nasid(cnode
));
145 static ssize_t
hub_cnode_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
147 return sprintf(buf
, "%d\n", get_obj_to_cnode(hub_info
->id
));
150 struct hub_sysfs_entry
{
151 struct attribute attr
;
152 ssize_t (*show
)(struct uv_bios_hub_info
*hub_info
, char *buf
);
153 ssize_t (*store
)(struct uv_bios_hub_info
*hub_info
, const char *buf
, size_t sz
);
156 static struct hub_sysfs_entry name_attribute
=
157 __ATTR(name
, 0444, hub_name_show
, NULL
);
158 static struct hub_sysfs_entry location_attribute
=
159 __ATTR(location
, 0444, hub_location_show
, NULL
);
160 static struct hub_sysfs_entry partition_attribute
=
161 __ATTR(this_partition
, 0444, hub_partition_show
, NULL
);
162 static struct hub_sysfs_entry shared_attribute
=
163 __ATTR(shared
, 0444, hub_shared_show
, NULL
);
164 static struct hub_sysfs_entry nasid_attribute
=
165 __ATTR(nasid
, 0444, hub_nasid_show
, NULL
);
166 static struct hub_sysfs_entry cnode_attribute
=
167 __ATTR(cnode
, 0444, hub_cnode_show
, NULL
);
169 static struct attribute
*uv_hub_attrs
[] = {
170 &name_attribute
.attr
,
171 &location_attribute
.attr
,
172 &partition_attribute
.attr
,
173 &shared_attribute
.attr
,
174 &nasid_attribute
.attr
,
175 &cnode_attribute
.attr
,
179 static void hub_release(struct kobject
*kobj
)
181 struct uv_hub
*hub
= to_uv_hub(kobj
);
186 static ssize_t
hub_type_show(struct kobject
*kobj
, struct attribute
*attr
,
189 struct uv_hub
*hub
= to_uv_hub(kobj
);
190 struct uv_bios_hub_info
*bios_hub_info
= hub
->hub_info
;
191 struct hub_sysfs_entry
*entry
;
193 entry
= container_of(attr
, struct hub_sysfs_entry
, attr
);
198 return entry
->show(bios_hub_info
, buf
);
201 static const struct sysfs_ops hub_sysfs_ops
= {
202 .show
= hub_type_show
,
205 static struct kobj_type hub_attr_type
= {
206 .release
= hub_release
,
207 .sysfs_ops
= &hub_sysfs_ops
,
208 .default_attrs
= uv_hub_attrs
,
211 static int uv_hubs_init(void)
217 prev_obj_to_cnode
= kmalloc_array(uv_bios_obj_cnt
, sizeof(*prev_obj_to_cnode
),
219 if (!prev_obj_to_cnode
)
222 for (i
= 0; i
< uv_bios_obj_cnt
; i
++)
223 prev_obj_to_cnode
[i
] = INVALID_CNODE
;
225 uv_hubs_kset
= kset_create_and_add("hubs", NULL
, sgi_uv_kobj
);
230 sz
= uv_bios_obj_cnt
* sizeof(*hub_buf
);
231 hub_buf
= kzalloc(sz
, GFP_KERNEL
);
237 biosr
= uv_bios_enum_objs((u64
)uv_master_nasid
, sz
, (u64
*)hub_buf
);
243 uv_hubs
= kcalloc(uv_bios_obj_cnt
, sizeof(*uv_hubs
), GFP_KERNEL
);
249 for (i
= 0; i
< uv_bios_obj_cnt
; i
++) {
250 uv_hubs
[i
] = kzalloc(sizeof(*uv_hubs
[i
]), GFP_KERNEL
);
257 uv_hubs
[i
]->hub_info
= &hub_buf
[i
];
258 cache_obj_to_cnode(uv_hubs
[i
]->hub_info
);
260 uv_hubs
[i
]->kobj
.kset
= uv_hubs_kset
;
262 ret
= kobject_init_and_add(&uv_hubs
[i
]->kobj
, &hub_attr_type
,
263 NULL
, "hub_%u", hub_buf
[i
].id
);
266 kobject_uevent(&uv_hubs
[i
]->kobj
, KOBJ_ADD
);
272 kobject_put(&uv_hubs
[i
]->kobj
);
277 kset_unregister(uv_hubs_kset
);
279 kfree(prev_obj_to_cnode
);
284 static void uv_hubs_exit(void)
288 for (i
= 0; i
< uv_bios_obj_cnt
; i
++)
289 kobject_put(&uv_hubs
[i
]->kobj
);
293 kset_unregister(uv_hubs_kset
);
294 kfree(prev_obj_to_cnode
);
299 struct uv_bios_port_info
*port_info
;
302 #define to_uv_port(kobj_ptr) container_of(kobj_ptr, struct uv_port, kobj)
304 static ssize_t
uv_port_conn_hub_show(struct uv_bios_port_info
*port
, char *buf
)
306 return sprintf(buf
, "%d\n", port
->conn_id
);
309 static ssize_t
uv_port_conn_port_show(struct uv_bios_port_info
*port
, char *buf
)
311 return sprintf(buf
, "%d\n", port
->conn_port
);
314 struct uv_port_sysfs_entry
{
315 struct attribute attr
;
316 ssize_t (*show
)(struct uv_bios_port_info
*port_info
, char *buf
);
317 ssize_t (*store
)(struct uv_bios_port_info
*port_info
, const char *buf
, size_t size
);
320 static struct uv_port_sysfs_entry uv_port_conn_hub_attribute
=
321 __ATTR(conn_hub
, 0444, uv_port_conn_hub_show
, NULL
);
322 static struct uv_port_sysfs_entry uv_port_conn_port_attribute
=
323 __ATTR(conn_port
, 0444, uv_port_conn_port_show
, NULL
);
325 static struct attribute
*uv_port_attrs
[] = {
326 &uv_port_conn_hub_attribute
.attr
,
327 &uv_port_conn_port_attribute
.attr
,
331 static void uv_port_release(struct kobject
*kobj
)
333 struct uv_port
*port
= to_uv_port(kobj
);
338 static ssize_t
uv_port_type_show(struct kobject
*kobj
, struct attribute
*attr
,
341 struct uv_port
*port
= to_uv_port(kobj
);
342 struct uv_bios_port_info
*port_info
= port
->port_info
;
343 struct uv_port_sysfs_entry
*entry
;
345 entry
= container_of(attr
, struct uv_port_sysfs_entry
, attr
);
350 return entry
->show(port_info
, buf
);
353 static const struct sysfs_ops uv_port_sysfs_ops
= {
354 .show
= uv_port_type_show
,
357 static struct kobj_type uv_port_attr_type
= {
358 .release
= uv_port_release
,
359 .sysfs_ops
= &uv_port_sysfs_ops
,
360 .default_attrs
= uv_port_attrs
,
363 static int uv_ports_init(void)
366 int j
= 0, k
= 0, ret
, sz
;
368 port_buf
= kcalloc(uv_bios_obj_cnt
, sizeof(*port_buf
), GFP_KERNEL
);
372 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
373 sz
= hub_buf
[j
].ports
* sizeof(*port_buf
[j
]);
374 port_buf
[j
] = kzalloc(sz
, GFP_KERNEL
);
380 biosr
= uv_bios_enum_ports((u64
)uv_master_nasid
, (u64
)hub_buf
[j
].id
, sz
,
387 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
388 uv_hubs
[j
]->ports
= kcalloc(hub_buf
[j
].ports
,
389 sizeof(*uv_hubs
[j
]->ports
), GFP_KERNEL
);
390 if (!uv_hubs
[j
]->ports
) {
396 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
397 for (k
= 0; k
< hub_buf
[j
].ports
; k
++) {
398 uv_hubs
[j
]->ports
[k
] = kzalloc(sizeof(*uv_hubs
[j
]->ports
[k
]), GFP_KERNEL
);
399 if (!uv_hubs
[j
]->ports
[k
]) {
404 uv_hubs
[j
]->ports
[k
]->port_info
= &port_buf
[j
][k
];
405 ret
= kobject_init_and_add(&uv_hubs
[j
]->ports
[k
]->kobj
, &uv_port_attr_type
,
406 &uv_hubs
[j
]->kobj
, "port_%d", port_buf
[j
][k
].port
);
409 kobject_uevent(&uv_hubs
[j
]->ports
[k
]->kobj
, KOBJ_ADD
);
415 for (; j
>= 0; j
--) {
417 kobject_put(&uv_hubs
[j
]->ports
[k
]->kobj
);
419 k
= hub_buf
[j
-1].ports
- 1;
421 j
= uv_bios_obj_cnt
- 1;
424 kfree(uv_hubs
[j
]->ports
);
425 j
= uv_bios_obj_cnt
- 1;
433 static void uv_ports_exit(void)
437 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
438 for (k
= hub_buf
[j
].ports
- 1; k
>= 0; k
--)
439 kobject_put(&uv_hubs
[j
]->ports
[k
]->kobj
);
441 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
442 kfree(uv_hubs
[j
]->ports
);
448 struct uv_pci_top_obj
{
457 #define to_uv_pci_top_obj(kobj_ptr) container_of(kobj_ptr, struct uv_pci_top_obj, kobj)
459 static ssize_t
uv_pci_type_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
461 return scnprintf(buf
, PAGE_SIZE
, "%s\n", top_obj
->type
);
464 static ssize_t
uv_pci_location_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
466 return scnprintf(buf
, PAGE_SIZE
, "%s\n", top_obj
->location
);
469 static ssize_t
uv_pci_iio_stack_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
471 return sprintf(buf
, "%d\n", top_obj
->iio_stack
);
474 static ssize_t
uv_pci_ppb_addr_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
476 return scnprintf(buf
, PAGE_SIZE
, "%s\n", top_obj
->ppb_addr
);
479 static ssize_t
uv_pci_slot_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
481 return sprintf(buf
, "%d\n", top_obj
->slot
);
484 struct uv_pci_top_sysfs_entry
{
485 struct attribute attr
;
486 ssize_t (*show
)(struct uv_pci_top_obj
*top_obj
, char *buf
);
487 ssize_t (*store
)(struct uv_pci_top_obj
*top_obj
, const char *buf
, size_t size
);
490 static struct uv_pci_top_sysfs_entry uv_pci_type_attribute
=
491 __ATTR(type
, 0444, uv_pci_type_show
, NULL
);
492 static struct uv_pci_top_sysfs_entry uv_pci_location_attribute
=
493 __ATTR(location
, 0444, uv_pci_location_show
, NULL
);
494 static struct uv_pci_top_sysfs_entry uv_pci_iio_stack_attribute
=
495 __ATTR(iio_stack
, 0444, uv_pci_iio_stack_show
, NULL
);
496 static struct uv_pci_top_sysfs_entry uv_pci_ppb_addr_attribute
=
497 __ATTR(ppb_addr
, 0444, uv_pci_ppb_addr_show
, NULL
);
498 static struct uv_pci_top_sysfs_entry uv_pci_slot_attribute
=
499 __ATTR(slot
, 0444, uv_pci_slot_show
, NULL
);
501 static void uv_pci_top_release(struct kobject
*kobj
)
503 struct uv_pci_top_obj
*top_obj
= to_uv_pci_top_obj(kobj
);
505 kfree(top_obj
->type
);
506 kfree(top_obj
->location
);
507 kfree(top_obj
->ppb_addr
);
511 static ssize_t
pci_top_type_show(struct kobject
*kobj
,
512 struct attribute
*attr
, char *buf
)
514 struct uv_pci_top_obj
*top_obj
= to_uv_pci_top_obj(kobj
);
515 struct uv_pci_top_sysfs_entry
*entry
;
517 entry
= container_of(attr
, struct uv_pci_top_sysfs_entry
, attr
);
522 return entry
->show(top_obj
, buf
);
525 static const struct sysfs_ops uv_pci_top_sysfs_ops
= {
526 .show
= pci_top_type_show
,
529 static struct kobj_type uv_pci_top_attr_type
= {
530 .release
= uv_pci_top_release
,
531 .sysfs_ops
= &uv_pci_top_sysfs_ops
,
534 static int init_pci_top_obj(struct uv_pci_top_obj
*top_obj
, char *line
)
537 char type
[11], location
[14], ppb_addr
[15];
539 unsigned int tmp_match
[2];
541 // Minimum line length
542 if (strlen(line
) < 36)
545 //Line must match format "pcibus %4x:%2x" to be valid
546 str_cnt
= sscanf(line
, "pcibus %4x:%2x", &tmp_match
[0], &tmp_match
[1]);
550 /* Connect pcibus to segment:bus number with '_'
551 * to concatenate name tokens.
552 * pcibus 0000:00 ... -> pcibus_0000:00 ...
556 /* Null terminate after the concatencated name tokens
557 * to produce kobj name string.
561 // Use start to index after name tokens string for remainder of line info.
564 top_obj
->iio_stack
= -1;
567 /* r001i01b00h0 BASE IO (IIO Stack 0)
568 * r001i01b00h1 PCIe IO (IIO Stack 1)
569 * r001i01b03h1 PCIe SLOT
570 * r001i01b00h0 NODE IO
572 * (IIO Stack #) may not be present.
574 if (start
[0] == 'r') {
575 str_cnt
= sscanf(start
, "%13s %10[^(] %*s %*s %d)",
576 location
, type
, &top_obj
->iio_stack
);
579 top_obj
->type
= kstrdup(type
, GFP_KERNEL
);
582 top_obj
->location
= kstrdup(location
, GFP_KERNEL
);
583 if (!top_obj
->location
) {
584 kfree(top_obj
->type
);
588 /* PPB at 0000:80:00.00 (slot 3)
589 * (slot #) may not be present.
591 else if (start
[0] == 'P') {
592 str_cnt
= sscanf(start
, "%10s %*s %14s %*s %d)",
593 type
, ppb_addr
, &top_obj
->slot
);
596 top_obj
->type
= kstrdup(type
, GFP_KERNEL
);
599 top_obj
->ppb_addr
= kstrdup(ppb_addr
, GFP_KERNEL
);
600 if (!top_obj
->ppb_addr
) {
601 kfree(top_obj
->type
);
607 top_obj
->kobj
.kset
= uv_pcibus_kset
;
609 ret
= kobject_init_and_add(&top_obj
->kobj
, &uv_pci_top_attr_type
, NULL
, "%s", line
);
614 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_type_attribute
.attr
);
618 if (top_obj
->location
) {
619 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_location_attribute
.attr
);
623 if (top_obj
->iio_stack
>= 0) {
624 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_iio_stack_attribute
.attr
);
628 if (top_obj
->ppb_addr
) {
629 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_ppb_addr_attribute
.attr
);
633 if (top_obj
->slot
>= 0) {
634 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_slot_attribute
.attr
);
639 kobject_uevent(&top_obj
->kobj
, KOBJ_ADD
);
643 kobject_put(&top_obj
->kobj
);
647 static int pci_topology_init(void)
649 char *pci_top_str
, *start
, *found
, *count
;
655 uv_pcibus_kset
= kset_create_and_add("pcibuses", NULL
, sgi_uv_kobj
);
659 for (sz
= PAGE_SIZE
; sz
< 16 * PAGE_SIZE
; sz
+= PAGE_SIZE
) {
660 pci_top_str
= kmalloc(sz
, GFP_KERNEL
);
663 goto err_pci_top_str
;
665 biosr
= uv_bios_get_pci_topology((u64
)sz
, (u64
*)pci_top_str
);
666 if (biosr
== BIOS_STATUS_SUCCESS
) {
667 len
= strnlen(pci_top_str
, sz
);
668 for (count
= pci_top_str
; count
< pci_top_str
+ len
; count
++) {
674 uv_pci_objs
= kcalloc(num_pci_lines
,
675 sizeof(*uv_pci_objs
), GFP_KERNEL
);
679 goto err_pci_top_str
;
682 while ((found
= strsep(&start
, "\n")) != NULL
) {
683 uv_pci_objs
[k
] = kzalloc(sizeof(*uv_pci_objs
[k
]), GFP_KERNEL
);
684 if (!uv_pci_objs
[k
]) {
688 ret
= init_pci_top_obj(uv_pci_objs
[k
], found
);
692 if (k
== num_pci_lines
)
697 if (biosr
== BIOS_STATUS_SUCCESS
|| biosr
== BIOS_STATUS_UNIMPLEMENTED
)
705 kobject_put(&uv_pci_objs
[k
]->kobj
);
709 kset_unregister(uv_pcibus_kset
);
713 static void pci_topology_exit(void)
717 for (k
= 0; k
< num_pci_lines
; k
++)
718 kobject_put(&uv_pci_objs
[k
]->kobj
);
719 kset_unregister(uv_pcibus_kset
);
723 static ssize_t
partition_id_show(struct kobject
*kobj
,
724 struct kobj_attribute
*attr
, char *buf
)
726 return sprintf(buf
, "%ld\n", sn_partition_id
);
729 static ssize_t
coherence_id_show(struct kobject
*kobj
,
730 struct kobj_attribute
*attr
, char *buf
)
732 return sprintf(buf
, "%ld\n", sn_coherency_id
);
735 static ssize_t
uv_type_show(struct kobject
*kobj
,
736 struct kobj_attribute
*attr
, char *buf
)
738 return scnprintf(buf
, PAGE_SIZE
, "%s\n", uv_type_string());
741 static ssize_t
uv_archtype_show(struct kobject
*kobj
,
742 struct kobj_attribute
*attr
, char *buf
)
744 return uv_get_archtype(buf
, PAGE_SIZE
);
747 static ssize_t
uv_hub_type_show(struct kobject
*kobj
,
748 struct kobj_attribute
*attr
, char *buf
)
750 return scnprintf(buf
, PAGE_SIZE
, "0x%x\n", uv_hub_type());
753 static ssize_t
uv_hubless_show(struct kobject
*kobj
,
754 struct kobj_attribute
*attr
, char *buf
)
756 return scnprintf(buf
, PAGE_SIZE
, "0x%x\n", uv_get_hubless_system());
759 static struct kobj_attribute partition_id_attr
=
760 __ATTR(partition_id
, 0444, partition_id_show
, NULL
);
761 static struct kobj_attribute coherence_id_attr
=
762 __ATTR(coherence_id
, 0444, coherence_id_show
, NULL
);
763 static struct kobj_attribute uv_type_attr
=
764 __ATTR(uv_type
, 0444, uv_type_show
, NULL
);
765 static struct kobj_attribute uv_archtype_attr
=
766 __ATTR(archtype
, 0444, uv_archtype_show
, NULL
);
767 static struct kobj_attribute uv_hub_type_attr
=
768 __ATTR(hub_type
, 0444, uv_hub_type_show
, NULL
);
769 static struct kobj_attribute uv_hubless_attr
=
770 __ATTR(hubless
, 0444, uv_hubless_show
, NULL
);
772 static struct attribute
*base_attrs
[] = {
773 &partition_id_attr
.attr
,
774 &coherence_id_attr
.attr
,
776 &uv_archtype_attr
.attr
,
777 &uv_hub_type_attr
.attr
,
781 static struct attribute_group base_attr_group
= {
785 static int initial_bios_setup(void)
790 biosr
= uv_bios_get_master_nasid((u64
)sizeof(uv_master_nasid
), (u64
*)&uv_master_nasid
);
794 biosr
= uv_bios_get_heapsize((u64
)uv_master_nasid
, (u64
)sizeof(u64
), &v
);
798 uv_biosheap
= vmalloc(v
);
802 biosr
= uv_bios_install_heap((u64
)uv_master_nasid
, v
, (u64
*)uv_biosheap
);
808 biosr
= uv_bios_obj_count((u64
)uv_master_nasid
, sizeof(u64
), &v
);
813 uv_bios_obj_cnt
= (int)v
;
818 static struct attribute
*hubless_base_attrs
[] = {
819 &partition_id_attr
.attr
,
821 &uv_archtype_attr
.attr
,
822 &uv_hubless_attr
.attr
,
826 static struct attribute_group hubless_base_attr_group
= {
827 .attrs
= hubless_base_attrs
831 static int __init
uv_sysfs_hubless_init(void)
835 ret
= sysfs_create_group(sgi_uv_kobj
, &hubless_base_attr_group
);
837 pr_warn("sysfs_create_group hubless_base_attr_group failed\n");
838 kobject_put(sgi_uv_kobj
);
843 static int __init
uv_sysfs_init(void)
847 if (!is_uv_system() && !uv_get_hubless_system())
850 num_cnodes
= uv_num_possible_blades();
853 sgi_uv_kobj
= kobject_create_and_add("sgi_uv", firmware_kobj
);
855 pr_warn("kobject_create_and_add sgi_uv failed\n");
859 if (uv_get_hubless_system())
860 return uv_sysfs_hubless_init();
862 ret
= sysfs_create_group(sgi_uv_kobj
, &base_attr_group
);
864 pr_warn("sysfs_create_group base_attr_group failed\n");
865 goto err_create_group
;
868 ret
= initial_bios_setup();
872 ret
= uv_hubs_init();
876 ret
= uv_ports_init();
880 ret
= pci_topology_init();
893 sysfs_remove_group(sgi_uv_kobj
, &base_attr_group
);
895 kobject_put(sgi_uv_kobj
);
899 static void __exit
uv_sysfs_hubless_exit(void)
901 sysfs_remove_group(sgi_uv_kobj
, &hubless_base_attr_group
);
902 kobject_put(sgi_uv_kobj
);
905 static void __exit
uv_sysfs_exit(void)
907 if (!is_uv_system()) {
908 if (uv_get_hubless_system())
909 uv_sysfs_hubless_exit();
917 sysfs_remove_group(sgi_uv_kobj
, &base_attr_group
);
918 kobject_put(sgi_uv_kobj
);
922 device_initcall(uv_sysfs_init
);
924 module_init(uv_sysfs_init
);
926 module_exit(uv_sysfs_exit
);
928 MODULE_AUTHOR("Hewlett Packard Enterprise");
929 MODULE_LICENSE("GPL");