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 <linux/vmalloc.h>
15 #include <asm/uv/bios.h>
16 #include <asm/uv/uv.h>
17 #include <asm/uv/uv_hub.h>
18 #include <asm/uv/uv_geo.h>
20 #define INVALID_CNODE -1
22 struct kobject
*sgi_uv_kobj
;
23 static struct kset
*uv_pcibus_kset
;
24 static struct kset
*uv_hubs_kset
;
25 static struct uv_bios_hub_info
*hub_buf
;
26 static struct uv_bios_port_info
**port_buf
;
27 static struct uv_hub
**uv_hubs
;
28 static struct uv_pci_top_obj
**uv_pci_objs
;
29 static int num_pci_lines
;
30 static int num_cnodes
;
31 static int *prev_obj_to_cnode
;
32 static int uv_bios_obj_cnt
;
33 static signed short uv_master_nasid
= -1;
34 static void *uv_biosheap
;
36 static const char *uv_type_string(void)
40 else if (is_uv4a_hub())
42 else if (is_uv4_hub())
44 else if (is_uv3_hub())
46 else if (is_uv2_hub())
48 else if (uv_get_hubless_system())
54 static int ordinal_to_nasid(int ordinal
)
56 if (ordinal
< num_cnodes
&& ordinal
>= 0)
57 return UV_PNODE_TO_NASID(uv_blade_to_pnode(ordinal
));
62 static union geoid_u
cnode_to_geoid(int cnode
)
66 uv_bios_get_geoinfo(ordinal_to_nasid(cnode
), (u64
)sizeof(union geoid_u
), (u64
*)&geoid
);
70 static int location_to_bpos(char *location
, int *rack
, int *slot
, int *blade
)
75 if (sscanf(location
, "%c%03d%c%02d%c%2d%c%d",
76 &r
, rack
, &type
, slot
, &b
, &idb
, &h
, &idh
) != 8)
78 *blade
= idb
* 2 + idh
;
83 static int cache_obj_to_cnode(struct uv_bios_hub_info
*obj
)
87 int obj_rack
, obj_slot
, obj_blade
;
88 int rack
, slot
, blade
;
90 if (!obj
->f
.fields
.this_part
&& !obj
->f
.fields
.is_shared
)
93 if (location_to_bpos(obj
->location
, &obj_rack
, &obj_slot
, &obj_blade
))
96 for (cnode
= 0; cnode
< num_cnodes
; cnode
++) {
97 geoid
= cnode_to_geoid(cnode
);
98 rack
= geo_rack(geoid
);
99 slot
= geo_slot(geoid
);
100 blade
= geo_blade(geoid
);
101 if (obj_rack
== rack
&& obj_slot
== slot
&& obj_blade
== blade
)
102 prev_obj_to_cnode
[obj
->id
] = cnode
;
108 static int get_obj_to_cnode(int obj_id
)
110 return prev_obj_to_cnode
[obj_id
];
115 struct uv_bios_hub_info
*hub_info
;
116 struct uv_port
**ports
;
119 #define to_uv_hub(kobj_ptr) container_of(kobj_ptr, struct uv_hub, kobj)
121 static ssize_t
hub_name_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
123 return sysfs_emit(buf
, "%s\n", hub_info
->name
);
126 static ssize_t
hub_location_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
128 return sysfs_emit(buf
, "%s\n", hub_info
->location
);
131 static ssize_t
hub_partition_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
133 return sysfs_emit(buf
, "%d\n", hub_info
->f
.fields
.this_part
);
136 static ssize_t
hub_shared_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
138 return sysfs_emit(buf
, "%d\n", hub_info
->f
.fields
.is_shared
);
140 static ssize_t
hub_nasid_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
142 int cnode
= get_obj_to_cnode(hub_info
->id
);
144 return sysfs_emit(buf
, "%d\n", ordinal_to_nasid(cnode
));
146 static ssize_t
hub_cnode_show(struct uv_bios_hub_info
*hub_info
, char *buf
)
148 return sysfs_emit(buf
, "%d\n", get_obj_to_cnode(hub_info
->id
));
151 struct hub_sysfs_entry
{
152 struct attribute attr
;
153 ssize_t (*show
)(struct uv_bios_hub_info
*hub_info
, char *buf
);
154 ssize_t (*store
)(struct uv_bios_hub_info
*hub_info
, const char *buf
, size_t sz
);
157 static struct hub_sysfs_entry name_attribute
=
158 __ATTR(name
, 0444, hub_name_show
, NULL
);
159 static struct hub_sysfs_entry location_attribute
=
160 __ATTR(location
, 0444, hub_location_show
, NULL
);
161 static struct hub_sysfs_entry partition_attribute
=
162 __ATTR(this_partition
, 0444, hub_partition_show
, NULL
);
163 static struct hub_sysfs_entry shared_attribute
=
164 __ATTR(shared
, 0444, hub_shared_show
, NULL
);
165 static struct hub_sysfs_entry nasid_attribute
=
166 __ATTR(nasid
, 0444, hub_nasid_show
, NULL
);
167 static struct hub_sysfs_entry cnode_attribute
=
168 __ATTR(cnode
, 0444, hub_cnode_show
, NULL
);
170 static struct attribute
*uv_hub_attrs
[] = {
171 &name_attribute
.attr
,
172 &location_attribute
.attr
,
173 &partition_attribute
.attr
,
174 &shared_attribute
.attr
,
175 &nasid_attribute
.attr
,
176 &cnode_attribute
.attr
,
179 ATTRIBUTE_GROUPS(uv_hub
);
181 static void hub_release(struct kobject
*kobj
)
183 struct uv_hub
*hub
= to_uv_hub(kobj
);
188 static ssize_t
hub_type_show(struct kobject
*kobj
, struct attribute
*attr
,
191 struct uv_hub
*hub
= to_uv_hub(kobj
);
192 struct uv_bios_hub_info
*bios_hub_info
= hub
->hub_info
;
193 struct hub_sysfs_entry
*entry
;
195 entry
= container_of(attr
, struct hub_sysfs_entry
, attr
);
200 return entry
->show(bios_hub_info
, buf
);
203 static const struct sysfs_ops hub_sysfs_ops
= {
204 .show
= hub_type_show
,
207 static const struct kobj_type hub_attr_type
= {
208 .release
= hub_release
,
209 .sysfs_ops
= &hub_sysfs_ops
,
210 .default_groups
= uv_hub_groups
,
213 static int uv_hubs_init(void)
219 prev_obj_to_cnode
= kmalloc_array(uv_bios_obj_cnt
, sizeof(*prev_obj_to_cnode
),
221 if (!prev_obj_to_cnode
)
224 for (i
= 0; i
< uv_bios_obj_cnt
; i
++)
225 prev_obj_to_cnode
[i
] = INVALID_CNODE
;
227 uv_hubs_kset
= kset_create_and_add("hubs", NULL
, sgi_uv_kobj
);
232 sz
= uv_bios_obj_cnt
* sizeof(*hub_buf
);
233 hub_buf
= kzalloc(sz
, GFP_KERNEL
);
239 biosr
= uv_bios_enum_objs((u64
)uv_master_nasid
, sz
, (u64
*)hub_buf
);
245 uv_hubs
= kcalloc(uv_bios_obj_cnt
, sizeof(*uv_hubs
), GFP_KERNEL
);
251 for (i
= 0; i
< uv_bios_obj_cnt
; i
++) {
252 uv_hubs
[i
] = kzalloc(sizeof(*uv_hubs
[i
]), GFP_KERNEL
);
259 uv_hubs
[i
]->hub_info
= &hub_buf
[i
];
260 cache_obj_to_cnode(uv_hubs
[i
]->hub_info
);
262 uv_hubs
[i
]->kobj
.kset
= uv_hubs_kset
;
264 ret
= kobject_init_and_add(&uv_hubs
[i
]->kobj
, &hub_attr_type
,
265 NULL
, "hub_%u", hub_buf
[i
].id
);
268 kobject_uevent(&uv_hubs
[i
]->kobj
, KOBJ_ADD
);
274 kobject_put(&uv_hubs
[i
]->kobj
);
279 kset_unregister(uv_hubs_kset
);
281 kfree(prev_obj_to_cnode
);
286 static void uv_hubs_exit(void)
290 for (i
= 0; i
< uv_bios_obj_cnt
; i
++)
291 kobject_put(&uv_hubs
[i
]->kobj
);
295 kset_unregister(uv_hubs_kset
);
296 kfree(prev_obj_to_cnode
);
301 struct uv_bios_port_info
*port_info
;
304 #define to_uv_port(kobj_ptr) container_of(kobj_ptr, struct uv_port, kobj)
306 static ssize_t
uv_port_conn_hub_show(struct uv_bios_port_info
*port
, char *buf
)
308 return sysfs_emit(buf
, "%d\n", port
->conn_id
);
311 static ssize_t
uv_port_conn_port_show(struct uv_bios_port_info
*port
, char *buf
)
313 return sysfs_emit(buf
, "%d\n", port
->conn_port
);
316 struct uv_port_sysfs_entry
{
317 struct attribute attr
;
318 ssize_t (*show
)(struct uv_bios_port_info
*port_info
, char *buf
);
319 ssize_t (*store
)(struct uv_bios_port_info
*port_info
, const char *buf
, size_t size
);
322 static struct uv_port_sysfs_entry uv_port_conn_hub_attribute
=
323 __ATTR(conn_hub
, 0444, uv_port_conn_hub_show
, NULL
);
324 static struct uv_port_sysfs_entry uv_port_conn_port_attribute
=
325 __ATTR(conn_port
, 0444, uv_port_conn_port_show
, NULL
);
327 static struct attribute
*uv_port_attrs
[] = {
328 &uv_port_conn_hub_attribute
.attr
,
329 &uv_port_conn_port_attribute
.attr
,
332 ATTRIBUTE_GROUPS(uv_port
);
334 static void uv_port_release(struct kobject
*kobj
)
336 struct uv_port
*port
= to_uv_port(kobj
);
341 static ssize_t
uv_port_type_show(struct kobject
*kobj
, struct attribute
*attr
,
344 struct uv_port
*port
= to_uv_port(kobj
);
345 struct uv_bios_port_info
*port_info
= port
->port_info
;
346 struct uv_port_sysfs_entry
*entry
;
348 entry
= container_of(attr
, struct uv_port_sysfs_entry
, attr
);
353 return entry
->show(port_info
, buf
);
356 static const struct sysfs_ops uv_port_sysfs_ops
= {
357 .show
= uv_port_type_show
,
360 static const struct kobj_type uv_port_attr_type
= {
361 .release
= uv_port_release
,
362 .sysfs_ops
= &uv_port_sysfs_ops
,
363 .default_groups
= uv_port_groups
,
366 static int uv_ports_init(void)
369 int j
= 0, k
= 0, ret
, sz
;
371 port_buf
= kcalloc(uv_bios_obj_cnt
, sizeof(*port_buf
), GFP_KERNEL
);
375 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
376 sz
= hub_buf
[j
].ports
* sizeof(*port_buf
[j
]);
377 port_buf
[j
] = kzalloc(sz
, GFP_KERNEL
);
383 biosr
= uv_bios_enum_ports((u64
)uv_master_nasid
, (u64
)hub_buf
[j
].id
, sz
,
390 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
391 uv_hubs
[j
]->ports
= kcalloc(hub_buf
[j
].ports
,
392 sizeof(*uv_hubs
[j
]->ports
), GFP_KERNEL
);
393 if (!uv_hubs
[j
]->ports
) {
399 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
400 for (k
= 0; k
< hub_buf
[j
].ports
; k
++) {
401 uv_hubs
[j
]->ports
[k
] = kzalloc(sizeof(*uv_hubs
[j
]->ports
[k
]), GFP_KERNEL
);
402 if (!uv_hubs
[j
]->ports
[k
]) {
407 uv_hubs
[j
]->ports
[k
]->port_info
= &port_buf
[j
][k
];
408 ret
= kobject_init_and_add(&uv_hubs
[j
]->ports
[k
]->kobj
, &uv_port_attr_type
,
409 &uv_hubs
[j
]->kobj
, "port_%d", port_buf
[j
][k
].port
);
412 kobject_uevent(&uv_hubs
[j
]->ports
[k
]->kobj
, KOBJ_ADD
);
418 for (; j
>= 0; j
--) {
420 kobject_put(&uv_hubs
[j
]->ports
[k
]->kobj
);
422 k
= hub_buf
[j
-1].ports
- 1;
424 j
= uv_bios_obj_cnt
- 1;
427 kfree(uv_hubs
[j
]->ports
);
428 j
= uv_bios_obj_cnt
- 1;
436 static void uv_ports_exit(void)
440 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
441 for (k
= hub_buf
[j
].ports
- 1; k
>= 0; k
--)
442 kobject_put(&uv_hubs
[j
]->ports
[k
]->kobj
);
444 for (j
= 0; j
< uv_bios_obj_cnt
; j
++) {
445 kfree(uv_hubs
[j
]->ports
);
451 struct uv_pci_top_obj
{
460 #define to_uv_pci_top_obj(kobj_ptr) container_of(kobj_ptr, struct uv_pci_top_obj, kobj)
462 static ssize_t
uv_pci_type_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
464 return sysfs_emit(buf
, "%s\n", top_obj
->type
);
467 static ssize_t
uv_pci_location_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
469 return sysfs_emit(buf
, "%s\n", top_obj
->location
);
472 static ssize_t
uv_pci_iio_stack_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
474 return sysfs_emit(buf
, "%d\n", top_obj
->iio_stack
);
477 static ssize_t
uv_pci_ppb_addr_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
479 return sysfs_emit(buf
, "%s\n", top_obj
->ppb_addr
);
482 static ssize_t
uv_pci_slot_show(struct uv_pci_top_obj
*top_obj
, char *buf
)
484 return sysfs_emit(buf
, "%d\n", top_obj
->slot
);
487 struct uv_pci_top_sysfs_entry
{
488 struct attribute attr
;
489 ssize_t (*show
)(struct uv_pci_top_obj
*top_obj
, char *buf
);
490 ssize_t (*store
)(struct uv_pci_top_obj
*top_obj
, const char *buf
, size_t size
);
493 static struct uv_pci_top_sysfs_entry uv_pci_type_attribute
=
494 __ATTR(type
, 0444, uv_pci_type_show
, NULL
);
495 static struct uv_pci_top_sysfs_entry uv_pci_location_attribute
=
496 __ATTR(location
, 0444, uv_pci_location_show
, NULL
);
497 static struct uv_pci_top_sysfs_entry uv_pci_iio_stack_attribute
=
498 __ATTR(iio_stack
, 0444, uv_pci_iio_stack_show
, NULL
);
499 static struct uv_pci_top_sysfs_entry uv_pci_ppb_addr_attribute
=
500 __ATTR(ppb_addr
, 0444, uv_pci_ppb_addr_show
, NULL
);
501 static struct uv_pci_top_sysfs_entry uv_pci_slot_attribute
=
502 __ATTR(slot
, 0444, uv_pci_slot_show
, NULL
);
504 static void uv_pci_top_release(struct kobject
*kobj
)
506 struct uv_pci_top_obj
*top_obj
= to_uv_pci_top_obj(kobj
);
508 kfree(top_obj
->type
);
509 kfree(top_obj
->location
);
510 kfree(top_obj
->ppb_addr
);
514 static ssize_t
pci_top_type_show(struct kobject
*kobj
,
515 struct attribute
*attr
, char *buf
)
517 struct uv_pci_top_obj
*top_obj
= to_uv_pci_top_obj(kobj
);
518 struct uv_pci_top_sysfs_entry
*entry
;
520 entry
= container_of(attr
, struct uv_pci_top_sysfs_entry
, attr
);
525 return entry
->show(top_obj
, buf
);
528 static const struct sysfs_ops uv_pci_top_sysfs_ops
= {
529 .show
= pci_top_type_show
,
532 static const struct kobj_type uv_pci_top_attr_type
= {
533 .release
= uv_pci_top_release
,
534 .sysfs_ops
= &uv_pci_top_sysfs_ops
,
537 static int init_pci_top_obj(struct uv_pci_top_obj
*top_obj
, char *line
)
540 char type
[11], location
[14], ppb_addr
[15];
542 unsigned int tmp_match
[2];
544 // Minimum line length
545 if (strlen(line
) < 36)
548 //Line must match format "pcibus %4x:%2x" to be valid
549 str_cnt
= sscanf(line
, "pcibus %4x:%2x", &tmp_match
[0], &tmp_match
[1]);
553 /* Connect pcibus to segment:bus number with '_'
554 * to concatenate name tokens.
555 * pcibus 0000:00 ... -> pcibus_0000:00 ...
559 /* Null terminate after the concatencated name tokens
560 * to produce kobj name string.
564 // Use start to index after name tokens string for remainder of line info.
567 top_obj
->iio_stack
= -1;
570 /* r001i01b00h0 BASE IO (IIO Stack 0)
571 * r001i01b00h1 PCIe IO (IIO Stack 1)
572 * r001i01b03h1 PCIe SLOT
573 * r001i01b00h0 NODE IO
575 * (IIO Stack #) may not be present.
577 if (start
[0] == 'r') {
578 str_cnt
= sscanf(start
, "%13s %10[^(] %*s %*s %d)",
579 location
, type
, &top_obj
->iio_stack
);
582 top_obj
->type
= kstrdup(type
, GFP_KERNEL
);
585 top_obj
->location
= kstrdup(location
, GFP_KERNEL
);
586 if (!top_obj
->location
) {
587 kfree(top_obj
->type
);
591 /* PPB at 0000:80:00.00 (slot 3)
592 * (slot #) may not be present.
594 else if (start
[0] == 'P') {
595 str_cnt
= sscanf(start
, "%10s %*s %14s %*s %d)",
596 type
, ppb_addr
, &top_obj
->slot
);
599 top_obj
->type
= kstrdup(type
, GFP_KERNEL
);
602 top_obj
->ppb_addr
= kstrdup(ppb_addr
, GFP_KERNEL
);
603 if (!top_obj
->ppb_addr
) {
604 kfree(top_obj
->type
);
610 top_obj
->kobj
.kset
= uv_pcibus_kset
;
612 ret
= kobject_init_and_add(&top_obj
->kobj
, &uv_pci_top_attr_type
, NULL
, "%s", line
);
617 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_type_attribute
.attr
);
621 if (top_obj
->location
) {
622 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_location_attribute
.attr
);
626 if (top_obj
->iio_stack
>= 0) {
627 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_iio_stack_attribute
.attr
);
631 if (top_obj
->ppb_addr
) {
632 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_ppb_addr_attribute
.attr
);
636 if (top_obj
->slot
>= 0) {
637 ret
= sysfs_create_file(&top_obj
->kobj
, &uv_pci_slot_attribute
.attr
);
642 kobject_uevent(&top_obj
->kobj
, KOBJ_ADD
);
646 kobject_put(&top_obj
->kobj
);
650 static int pci_topology_init(void)
652 char *pci_top_str
, *start
, *found
, *count
;
658 uv_pcibus_kset
= kset_create_and_add("pcibuses", NULL
, sgi_uv_kobj
);
662 for (sz
= PAGE_SIZE
; sz
< 16 * PAGE_SIZE
; sz
+= PAGE_SIZE
) {
663 pci_top_str
= kmalloc(sz
, GFP_KERNEL
);
666 goto err_pci_top_str
;
668 biosr
= uv_bios_get_pci_topology((u64
)sz
, (u64
*)pci_top_str
);
669 if (biosr
== BIOS_STATUS_SUCCESS
) {
670 len
= strnlen(pci_top_str
, sz
);
671 for (count
= pci_top_str
; count
< pci_top_str
+ len
; count
++) {
677 uv_pci_objs
= kcalloc(num_pci_lines
,
678 sizeof(*uv_pci_objs
), GFP_KERNEL
);
682 goto err_pci_top_str
;
685 while ((found
= strsep(&start
, "\n")) != NULL
) {
686 uv_pci_objs
[k
] = kzalloc(sizeof(*uv_pci_objs
[k
]), GFP_KERNEL
);
687 if (!uv_pci_objs
[k
]) {
691 ret
= init_pci_top_obj(uv_pci_objs
[k
], found
);
695 if (k
== num_pci_lines
)
700 if (biosr
== BIOS_STATUS_SUCCESS
|| biosr
== BIOS_STATUS_UNIMPLEMENTED
)
708 kobject_put(&uv_pci_objs
[k
]->kobj
);
712 kset_unregister(uv_pcibus_kset
);
716 static void pci_topology_exit(void)
720 for (k
= 0; k
< num_pci_lines
; k
++)
721 kobject_put(&uv_pci_objs
[k
]->kobj
);
722 kset_unregister(uv_pcibus_kset
);
726 static ssize_t
partition_id_show(struct kobject
*kobj
,
727 struct kobj_attribute
*attr
, char *buf
)
729 return sysfs_emit(buf
, "%ld\n", sn_partition_id
);
732 static ssize_t
coherence_id_show(struct kobject
*kobj
,
733 struct kobj_attribute
*attr
, char *buf
)
735 return sysfs_emit(buf
, "%ld\n", sn_coherency_id
);
738 static ssize_t
uv_type_show(struct kobject
*kobj
,
739 struct kobj_attribute
*attr
, char *buf
)
741 return sysfs_emit(buf
, "%s\n", uv_type_string());
744 static ssize_t
uv_archtype_show(struct kobject
*kobj
,
745 struct kobj_attribute
*attr
, char *buf
)
747 return uv_get_archtype(buf
, PAGE_SIZE
);
750 static ssize_t
uv_hub_type_show(struct kobject
*kobj
,
751 struct kobj_attribute
*attr
, char *buf
)
753 return sysfs_emit(buf
, "0x%x\n", uv_hub_type());
756 static ssize_t
uv_hubless_show(struct kobject
*kobj
,
757 struct kobj_attribute
*attr
, char *buf
)
759 return sysfs_emit(buf
, "0x%x\n", uv_get_hubless_system());
762 static struct kobj_attribute partition_id_attr
=
763 __ATTR(partition_id
, 0444, partition_id_show
, NULL
);
764 static struct kobj_attribute coherence_id_attr
=
765 __ATTR(coherence_id
, 0444, coherence_id_show
, NULL
);
766 static struct kobj_attribute uv_type_attr
=
767 __ATTR(uv_type
, 0444, uv_type_show
, NULL
);
768 static struct kobj_attribute uv_archtype_attr
=
769 __ATTR(archtype
, 0444, uv_archtype_show
, NULL
);
770 static struct kobj_attribute uv_hub_type_attr
=
771 __ATTR(hub_type
, 0444, uv_hub_type_show
, NULL
);
772 static struct kobj_attribute uv_hubless_attr
=
773 __ATTR(hubless
, 0444, uv_hubless_show
, NULL
);
775 static struct attribute
*base_attrs
[] = {
776 &partition_id_attr
.attr
,
777 &coherence_id_attr
.attr
,
779 &uv_archtype_attr
.attr
,
780 &uv_hub_type_attr
.attr
,
784 static const struct attribute_group base_attr_group
= {
788 static int initial_bios_setup(void)
793 biosr
= uv_bios_get_master_nasid((u64
)sizeof(uv_master_nasid
), (u64
*)&uv_master_nasid
);
797 biosr
= uv_bios_get_heapsize((u64
)uv_master_nasid
, (u64
)sizeof(u64
), &v
);
801 uv_biosheap
= vmalloc(v
);
805 biosr
= uv_bios_install_heap((u64
)uv_master_nasid
, v
, (u64
*)uv_biosheap
);
811 biosr
= uv_bios_obj_count((u64
)uv_master_nasid
, sizeof(u64
), &v
);
816 uv_bios_obj_cnt
= (int)v
;
821 static struct attribute
*hubless_base_attrs
[] = {
822 &partition_id_attr
.attr
,
824 &uv_archtype_attr
.attr
,
825 &uv_hubless_attr
.attr
,
829 static const struct attribute_group hubless_base_attr_group
= {
830 .attrs
= hubless_base_attrs
834 static int __init
uv_sysfs_hubless_init(void)
838 ret
= sysfs_create_group(sgi_uv_kobj
, &hubless_base_attr_group
);
840 pr_warn("sysfs_create_group hubless_base_attr_group failed\n");
841 kobject_put(sgi_uv_kobj
);
846 static int __init
uv_sysfs_init(void)
850 if (!is_uv_system() && !uv_get_hubless_system())
853 num_cnodes
= uv_num_possible_blades();
856 sgi_uv_kobj
= kobject_create_and_add("sgi_uv", firmware_kobj
);
858 pr_warn("kobject_create_and_add sgi_uv failed\n");
862 if (uv_get_hubless_system())
863 return uv_sysfs_hubless_init();
865 ret
= sysfs_create_group(sgi_uv_kobj
, &base_attr_group
);
867 pr_warn("sysfs_create_group base_attr_group failed\n");
868 goto err_create_group
;
871 ret
= initial_bios_setup();
875 ret
= uv_hubs_init();
879 ret
= uv_ports_init();
883 ret
= pci_topology_init();
896 sysfs_remove_group(sgi_uv_kobj
, &base_attr_group
);
898 kobject_put(sgi_uv_kobj
);
902 static void __exit
uv_sysfs_hubless_exit(void)
904 sysfs_remove_group(sgi_uv_kobj
, &hubless_base_attr_group
);
905 kobject_put(sgi_uv_kobj
);
908 static void __exit
uv_sysfs_exit(void)
910 if (!is_uv_system()) {
911 if (uv_get_hubless_system())
912 uv_sysfs_hubless_exit();
920 sysfs_remove_group(sgi_uv_kobj
, &base_attr_group
);
921 kobject_put(sgi_uv_kobj
);
925 device_initcall(uv_sysfs_init
);
927 module_init(uv_sysfs_init
);
929 module_exit(uv_sysfs_exit
);
931 MODULE_AUTHOR("Hewlett Packard Enterprise");
932 MODULE_DESCRIPTION("Sysfs structure for HPE UV systems");
933 MODULE_LICENSE("GPL");