4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/cmn_err.h>
30 #include <sys/ddi_impldefs.h>
31 #include <sys/autoconf.h>
32 #include <sys/systm.h>
33 #include <sys/modctl.h>
35 #include <sys/sunddi.h>
36 #include <sys/sunndi.h>
37 #include <sys/ndi_impldefs.h>
38 #include <sys/promif.h>
41 #include <sys/promif.h>
43 #include <sys/obpdefs.h>
44 #include <sys/cpuvar.h>
45 #include <vm/seg_kmem.h>
46 #include <sys/prom_plat.h>
47 #include <sys/machsystm.h>
49 #include <sys/memlist.h>
52 #include <sys/sbd_ioctl.h>
54 #include <sys/sbdp_priv.h>
55 #include <sys/sbdp_mem.h>
56 #include <sys/sbdp_error.h>
57 #include <sys/serengeti.h>
59 #include <sys/sgsbbc.h> /* To get fn_t type definition */
65 uint_t sbdp_debug
= 0x0;
69 * Enable or disable dr
71 int sbdp_dr_available
= 1;
73 /* name properties for some Serengeti device nodes */
74 #define CMP_DEVNAME "cmp"
75 #define MEM_DEVNAME "memory"
76 #define CPU_DEVNAME "cpu"
77 #define IO_PCI_DEVNAME "pci"
78 #define IO_SGHSC_DEVNAME "sghsc"
79 #define IO_WCI_DEVNAME "wci"
81 static sbd_devattr_t sbdp_devattr
[] = {
82 { CMP_DEVNAME
, "cmp", SBD_COMP_CMP
},
83 { MEM_DEVNAME
, "memory-controller", SBD_COMP_MEM
},
84 { CPU_DEVNAME
, "cpu", SBD_COMP_CPU
},
85 { IO_PCI_DEVNAME
, "pci", SBD_COMP_IO
},
86 { IO_SGHSC_DEVNAME
, "sghsc", SBD_COMP_IO
},
87 { IO_WCI_DEVNAME
, "wci", SBD_COMP_IO
},
88 /* last item must be blank */
89 { NULL
, NULL
, SBD_COMP_UNKNOWN
}
93 * In the case of a busy mbox, if a status cmd comes in we return a cached
94 * copy. This cache is a link list of wnodes that contains bd structs with
95 * the appropriate info. When a new wnode is created a whole entry is added
98 sbdp_wnode_t
*first_node
= NULL
; /* first wnode. Entry to the link list */
99 int cur_num_wnodes
= 0; /* how many nodes are currently running */
101 /* Macros to access fields in the previous array */
102 #define SBDP_CT(i) sbdp_devattr[i].s_dnodetype
103 #define SBDP_DEVNAME(i) sbdp_devattr[(i)].s_devname
104 #define SBDP_OTYPE(i) sbdp_devattr[(i)].s_obp_type
109 sbdp_wnode_t
*sbdp_get_wnodep(int);
112 * Module linkage information for the kernel.
115 static struct modlmisc modlmisc
= {
120 static struct modlinkage modlinkage
= {
127 * VA area used during CPU shutdown.
129 caddr_t sbdp_shutdown_va
;
132 * Mutex to protect our inventory
134 kmutex_t sbdp_wnode_mutex
;
141 e
= mod_install(&modlinkage
);
145 sbdp_shutdown_va
= vmem_alloc(heap_arena
, PAGESIZE
, VM_SLEEP
);
146 ASSERT(sbdp_shutdown_va
!= NULL
);
147 sbdp_valp
= (uint64_t *)vmem_alloc(static_alloc_arena
,
148 sizeof (uint64_t), VM_SLEEP
);
150 mutex_init(&sbdp_wnode_mutex
, NULL
, MUTEX_DRIVER
, NULL
);
162 e
= mod_remove(&modlinkage
);
166 vmem_free(heap_arena
, sbdp_shutdown_va
, PAGESIZE
);
167 sbdp_shutdown_va
= NULL
;
168 vmem_free(static_alloc_arena
, (void *)sbdp_valp
, sizeof (uint64_t));
171 mutex_destroy(&sbdp_wnode_mutex
);
176 _info(struct modinfo
*modinfop
)
178 return (mod_info(&modlinkage
, modinfop
));
182 sbdp_get_bd_and_wnode_num(pnode_t nodeid
, int *bd
, int *wnode
)
185 static fn_t f
= "sbdp_get_bd_and_wnode_num";
186 extern int get_portid(pnode_t node
, pnode_t
*cmpp
);
188 SBDP_DBG_FUNC("%s\n", f
);
190 if (sbdp_is_node_bad(nodeid
))
193 if ((portid
= get_portid(nodeid
, NULL
)) == -1)
197 * decode the board number
199 *bd
= SG_PORTID_TO_BOARD_NUM(portid
);
200 *wnode
= SG_PORTID_TO_NODEID(portid
);
206 sbdp_get_board_num(sbdp_handle_t
*hp
, dev_info_t
*dip
)
212 static fn_t f
= "sbdp_get_board_num";
214 SBDP_DBG_FUNC("%s\n", f
);
219 nodeid
= ddi_get_nodeid(dip
);
222 * Portid has encoded the nodeid and the agent id. The top
223 * 4 bits are correspond to the wcnodeid and the lower 5 are the
225 * Each agent id represents a physical location hence we can
226 * obtain the board number
228 if (sbdp_get_bd_and_wnode_num(nodeid
, &bd
, &wnode
) < 0)
236 sbdp_get_devattr(void)
238 return (&sbdp_devattr
[0]);
242 sbdp_portid_to_cpu_unit(int cmp
, int core
)
244 return (SG_PORTID_TO_CPU_UNIT(cmp
, core
));
248 sbdp_get_unit_num(sbdp_handle_t
*hp
, dev_info_t
*dip
)
253 sbd_comp_type_t type
;
254 char dev_type
[OBP_MAXPROPNAME
];
257 static fn_t f
= "sbdp_get_unit_num";
259 SBDP_DBG_FUNC("%s\n", f
);
264 nodeid
= ddi_get_nodeid(dip
);
266 if (sbdp_is_node_bad(nodeid
))
269 if (prom_getprop(nodeid
, "device_type", (caddr_t
)dev_type
) < 0) {
270 SBDP_DBG_MISC("%s: couldn't get device_type\n", f
);
274 for (i
= 0; SBDP_CT(i
) != SBD_COMP_UNKNOWN
; i
++) {
275 if (strcmp(dev_type
, SBDP_OTYPE(i
)) != 0)
282 if ((cpuid
= sbdp_get_cpuid(hp
, dip
)) != -1) {
283 unit
= SG_CPUID_TO_CPU_UNIT(cpuid
);
294 * Check to see if this is a cpci node
295 * cpci nodes are assign unit nums of 5 for now
296 * So they don't conflict with the pci unit nums
299 if (strcmp(dev_type
, "sghsc") == 0) {
300 SBDP_DBG_MISC("it is a sghsc\n");
304 if (prom_getprop(nodeid
, "portid", (caddr_t
)&portid
) <= 0) {
305 SBDP_DBG_MISC("%s: couldn't get portid\n", f
);
309 len
= prom_getproplen(nodeid
, "reg");
311 SBDP_DBG_MISC("%s: couldn't get length\n", f
);
315 if (prom_getprop(nodeid
, "reg", (caddr_t
)regs
) < 0) {
316 SBDP_DBG_MISC("%s: couldn't get registers\n", f
);
320 if ((portid
% 2) != 0)
321 if ((regs
[0].regspec_addr_lo
& 0x700000) ==
327 if ((regs
[0].regspec_addr_lo
& 0x700000) ==
333 SBDP_DBG_MISC("unit is %d\n", unit
);
344 struct sbdp_mem_dip
{
350 sbdp_get_mem_dip(pnode_t node
, void *arg
, uint_t flags
)
352 _NOTE(ARGUNUSED(flags
))
354 struct sbdp_mem_dip
*smdp
= (struct sbdp_mem_dip
*)arg
;
357 if (node
== OBP_NONODE
|| node
== OBP_BADNODE
)
358 return (DDI_FAILURE
);
360 mem
.nodes
= smdp
->bdp
->nodes
;
361 mem
.board
= smdp
->bdp
->bd
;
362 mem
.nmem
= smdp
->bdp
->nnum
;
364 (void) sbdp_is_mem(node
, &mem
);
367 * We need to find the dip only for the first nodeid
369 if (smdp
->bdp
->nnum
== 0 && mem
.nmem
== 1) {
370 ASSERT(smdp
->dip
== NULL
);
371 smdp
->dip
= e_ddi_nodeid_to_dip(node
);
374 smdp
->bdp
->nnum
= mem
.nmem
;
376 return (DDI_SUCCESS
);
381 * Update the board info. Required after a copy rename
384 sbdp_update_bd_info(sbdp_bd_t
*bdp
)
386 attach_pkt_t apkt
, *apktp
= &apkt
;
387 struct sbdp_mem_dip smd
= {0};
388 static fn_t f
= "sbdp_update_bd_info";
390 SBDP_DBG_FUNC("%s\n", f
);
398 mutex_enter(&bdp
->bd_mutex
);
401 * we get the top nodes here. This will have a side effect of
402 * updating the present bit for cpus
404 apktp
->node
= bdp
->wnode
;
405 apktp
->board
= bdp
->bd
;
406 apktp
->num_of_nodes
= 0;
408 sbdp_walk_prom_tree(prom_rootnode(), sbdp_select_top_nodes
,
412 * We need to clear nnum since we are looking again for the
419 * If a dip is found by sbdp_get_mem_dip(), it will be
422 sbdp_walk_prom_tree(prom_rootnode(), sbdp_get_mem_dip
, &smd
);
423 if (smd
.dip
!= NULL
) {
426 hp
= kmem_zalloc(sizeof (sbdp_handle_t
), KM_SLEEP
);
427 hp
->h_board
= bdp
->bd
;
428 hp
->h_wnode
= bdp
->wnode
;
429 hp
->h_err
= kmem_zalloc(sizeof (*hp
->h_err
), KM_SLEEP
);
430 if (bdp
->ml
!= NULL
) {
431 (void) sbdp_del_memlist(hp
, bdp
->ml
);
433 bdp
->ml
= sbdp_get_memlist(hp
, (dev_info_t
*)NULL
);
435 * if the board doesn't have banks initialize them,
436 * otherwise we assume they have been updated if
439 if (bdp
->banks
== NULL
) {
440 sbdp_init_bd_banks(bdp
);
443 sbdp_print_bd_banks(bdp
);
446 if (sbdphw_get_base_physaddr(hp
, smd
.dip
, &bdp
->bpa
))
448 ddi_release_devi(smd
.dip
);
449 kmem_free(hp
->h_err
, sizeof (*hp
->h_err
));
450 kmem_free(hp
, sizeof (sbdp_handle_t
));
452 mutex_exit(&bdp
->bd_mutex
);
456 * Initialize the board struct. This remains cached. We update it
457 * every time we have a successful show_board and after a copy-rename
460 sbdp_bd_init(sbdp_bd_t
*bdp
, int bd
, int wnode
)
462 static fn_t f
= "sbdp_bd_init";
464 SBDP_DBG_FUNC("%s\n", f
);
469 SBDP_UNSET_ALL_CPUS_IN_RESET(bdp
);
471 bdp
->cpus_present
= 0;
473 sbdp_update_bd_info(bdp
);
475 mutex_init(&bdp
->bd_mutex
, NULL
, MUTEX_DRIVER
, NULL
);
476 bdp
->bd_sc
= (show_board_t
*)kmem_zalloc(sizeof (show_board_t
),
482 * This entry is going away. Clean up
485 sbdp_bd_fini(sbdp_bd_t
*bdp
)
487 static fn_t f
= "sbdp_bd_fini";
489 SBDP_DBG_FUNC("%s\n", f
);
491 sbdp_cleanup_bd(bdp
->wnode
, bdp
->bd
);
492 kmem_free(bdp
->bd_sc
, sizeof (show_board_t
));
494 mutex_destroy(&bdp
->bd_mutex
);
496 sbdp_print_all_segs();
501 * A new wnode has arrived. Initialize the struct and create
502 * the board structures.
505 sbdp_wnode_init(sbdp_wnode_t
*wnodep
, int wnode
, int boards
)
508 static fn_t f
= "sbdp_wnode_init";
510 SBDP_DBG_FUNC("%s\n", f
);
512 wnodep
->wnode
= wnode
;
513 wnodep
->nbds
= boards
;
514 wnodep
->bds
= kmem_zalloc(sizeof (sbdp_bd_t
) * boards
, KM_SLEEP
);
515 wnodep
->next
= wnodep
->prev
= NULL
;
517 for (i
= 0; i
< boards
; i
++)
518 sbdp_bd_init(&wnodep
->bds
[i
], i
, wnode
);
522 * Wnode got DRed out. Clean up all the node stuff including the boards
525 sbdp_wnode_fini(sbdp_wnode_t
*wnodep
)
529 static fn_t f
= "sbdp_wnode_fini";
531 SBDP_DBG_FUNC("%s\n", f
);
533 boards
= wnodep
->nbds
;
535 for (i
= 0; i
< boards
; i
++)
536 sbdp_bd_fini(&wnodep
->bds
[i
]);
538 kmem_free(wnodep
->bds
, sizeof (sbdp_bd_t
) * boards
);
539 wnodep
->next
= wnodep
->prev
= NULL
;
540 kmem_free(wnodep
, sizeof (sbdp_wnode_t
));
544 * Add all the necessary fields to this board's struct
547 sbdp_add_new_bd_info(int wnode
, int board
)
550 static fn_t f
= "sbdp_add_new_bd_info";
552 SBDP_DBG_FUNC("%s\n", f
);
554 cur
= sbdp_get_wnodep(wnode
);
556 SBDP_DBG_MISC("adding new board info %d\n", board
);
558 sbdp_update_bd_info(&cur
->bds
[board
]);
563 * This board has gone away. Clean the necessary fields
566 sbdp_cleanup_bd(int wnode
, int board
)
569 sbdp_handle_t handle
, *hp
;
572 static fn_t f
= "sbdp_cleanup_bd";
574 SBDP_DBG_FUNC("%s\n", f
);
576 cur
= sbdp_get_wnodep(wnode
);
578 SBDP_DBG_MISC("cleaning up bd info for bd %d\n", board
);
580 SBDP_DBG_MISC("cur is null\n");
584 bdp
= &cur
->bds
[board
];
589 mutex_enter(&bdp
->bd_mutex
);
591 for (i
= 0; i
< bdp
->nnum
; i
++)
592 bdp
->nodes
[i
] = (pnode_t
)0;
595 sbdp_fini_bd_banks(bdp
);
598 hp
->h_board
= bdp
->bd
;
599 hp
->h_wnode
= bdp
->wnode
;
601 (void) sbdp_del_memlist(hp
, bdp
->ml
);
608 sbdp_cpu_in_reset(wnode
, bdp
->bd
, SBDP_ALL_CPUS
, 0);
610 bdp
->cpus_present
= 0;
612 mutex_exit(&bdp
->bd_mutex
);
616 * Traverse the list looking for wnode. Return it when found
619 sbdp_get_wnodep(int wnode
)
623 static fn_t f
= "sbdp_get_wnodep";
625 SBDP_DBG_FUNC("%s\n", f
);
627 mutex_enter(&sbdp_wnode_mutex
);
628 for (i
= 0, cur
= first_node
; i
< cur_num_wnodes
; i
++,
630 if (cur
->wnode
== wnode
) {
631 mutex_exit(&sbdp_wnode_mutex
);
635 mutex_exit(&sbdp_wnode_mutex
);
641 * Insert this brand new node into our master list. It leaves it all
645 sbdp_insert_wnode(int wnode
, int max_boards
)
647 sbdp_wnode_t
*wnodep
;
649 static fn_t f
= "sbdp_insert_wnode";
651 SBDP_DBG_FUNC("%s\n", f
);
653 wnodep
= kmem_zalloc(sizeof (sbdp_wnode_t
), KM_SLEEP
);
655 mutex_enter(&sbdp_wnode_mutex
);
656 if (first_node
== NULL
) {
660 cur
= first_node
+ cur_num_wnodes
++;
664 mutex_exit(&sbdp_wnode_mutex
);
665 sbdp_wnode_init(wnodep
, wnode
, max_boards
);
669 * This node is gone. Remove it from the list and also clean up
672 sbdp_remove_wnode(sbdp_wnode_t
*wnodep
)
675 static fn_t f
= "sbdp_remove_wnode";
677 SBDP_DBG_FUNC("%s\n", f
);
679 if (wnodep
!= NULL
) {
680 sbdp_wnode_fini(wnodep
);
681 mutex_enter(&sbdp_wnode_mutex
);
683 if (first_node
== wnodep
)
688 cur
->next
= wnodep
->next
;
689 if (wnodep
->next
!= NULL
)
690 wnodep
->next
->prev
= cur
;
694 mutex_exit(&sbdp_wnode_mutex
);
699 * Entry point from sbd. This is called when a new node is added. We
700 * create an entry in our inventory and initialize all the stuff that will be
704 sbdp_setup_instance(caddr_t arg
)
706 ssm_sbdp_info_t
*sbdp_info
;
710 static fn_t f
= "sbdp_setup_instance";
712 SBDP_DBG_FUNC("%s\n", f
);
715 * We get this directly from ssm
717 sbdp_info
= (ssm_sbdp_info_t
*)arg
;
719 instance
= sbdp_info
->instance
;
720 wnode
= sbdp_info
->wnode
;
721 max_boards
= plat_max_boards();
723 SBDP_DBG_MISC("sbdp_setup_instance: instance %d wnode %d\n", instance
,
726 if (sbdp_get_wnodep(wnode
) == NULL
) {
728 * This node has not been instanstiated
731 sbdp_insert_wnode(wnode
, max_boards
);
734 return (DDI_SUCCESS
);
738 * Entry point from sbd. This is called when a node has been removed (or is
739 * going away. We do all the necessary cleanup
742 sbdp_teardown_instance(caddr_t arg
)
744 ssm_sbdp_info_t
*sbdp_info
;
747 sbdp_wnode_t
*wnodep
;
748 static fn_t f
= "sbdp_teardown_instance";
750 SBDP_DBG_FUNC("%s\n", f
);
753 * ssm should have set this up
755 sbdp_info
= (ssm_sbdp_info_t
*)arg
;
757 instance
= sbdp_info
->instance
;
758 wnode
= sbdp_info
->wnode
;
760 SBDP_DBG_MISC("sbdp_teardown_instance: instance %d wnode %d\n",
764 * Find this node and then remove it
766 if ((wnodep
= sbdp_get_wnodep(wnode
)) != NULL
) {
767 sbdp_remove_wnode(wnodep
);
769 return (DDI_SUCCESS
);
773 sbdp_disabled_component(sbdp_handle_t
*hp
)
783 sbdp_release_component(sbdp_handle_t
*hp
, dev_info_t
*dip
)
789 sbdp_set_err(sbd_error_t
*ep
, int ecode
, char *rsc
)
791 static fn_t f
= "sbdp_set_err";
793 SBDP_DBG_FUNC("%s\n", f
);
798 (void) strcpy((caddr_t
)(ep
->e_rsc
), (caddr_t
)rsc
);
803 * Serengeti DR passthrus are for debugging purposes only.
807 int (*handler
)(sbdp_handle_t
*, void *);
808 } sbdp_passthrus
[] = {
810 { "readmem", sbdp_passthru_readmem
},
811 { "prep-script", sbdp_passthru_prep_script
},
812 { "test-quiesce", sbdp_passthru_test_quiesce
},
813 { "inject-error", sbdp_passthru_inject_error
},
814 { "reset-error", sbdp_passthru_reset_error
},
817 /* the following line must always be last */
824 sbdp_ioctl(sbdp_handle_t
*hp
, sbdp_ioctl_arg_t
*sbdpi
)
829 sbd_ioctl_arg_t
*sbdi
= (sbd_ioctl_arg_t
*)sbdpi
->h_iap
;
831 static fn_t f
= "sbdp_ioctl";
833 SBDP_DBG_FUNC("%s\n", f
);
835 if (sbdi
->i_len
>= sizeof (buf
) ||
836 ddi_copyin(sbdi
->i_opts
, buf
, sbdi
->i_len
, sbdpi
->h_mode
)) {
837 sbdp_set_err(hp
->h_err
, ESBD_FAULT
, NULL
);
842 while (sbdp_passthrus
[i
].name
!= NULL
) {
845 len
= strlen(sbdp_passthrus
[i
].name
);
846 if (strncmp(sbdp_passthrus
[i
].name
, buf
, len
) == 0)
851 if (sbdp_passthrus
[i
].name
== NULL
) {
852 sbdp_set_err(hp
->h_err
, ESBD_INVAL
, NULL
);
855 rv
= (*sbdp_passthrus
[i
].handler
)(hp
, buf
);
856 if (rv
!= ESBD_NOERROR
) {
857 sbdp_set_err(hp
->h_err
, rv
, NULL
);
870 * Check the dnode we obtained. Need to find a better way to determine
871 * if the node has the correct starting address
874 sbdp_is_node_bad(pnode_t node
)
876 static fn_t f
= "sbdp_is_node_bad";
878 SBDP_DBG_FUNC("%s\n", f
);
880 return ((node
== OBP_NONODE
) || (node
== OBP_BADNODE
) ||
881 ((node
& 0x80000000u
) != 0x80000000u
));
885 * Retrieve the information we have on this board from
889 sbdp_get_bd_info(int wnode
, int board
)
891 sbdp_wnode_t
*wnodep
;
894 static fn_t f
= "sbdp_get_bd_info";
896 SBDP_DBG_FUNC("%s\n", f
);
898 wnodep
= sbdp_get_wnodep(wnode
);
899 max_bds
= plat_max_boards();
901 if ((wnodep
== NULL
) || ((board
< 0) && (board
> max_bds
))) {
905 bdp
= &wnodep
->bds
[board
];
908 * We might not have the complete bd info. With cheetah we
909 * cannot access the memory decode registers when then cpu is
910 * in reset. If the mem info is incomplete, then we try to gather it
913 sbdp_update_bd_info(bdp
);
919 * There are certain cases where obp marks components as failed
920 * If the status is ok the node won't have any status property. It
921 * is only there if the status is other than ok.
924 sbdp_get_comp_status(pnode_t nodeid
)
926 char status_buf
[OBP_MAXPROPNAME
];
927 static const char *status
= "status";
928 static const char *failed
= "fail";
929 static const char *disabled
= "disabled";
930 static fn_t f
= "sbdp_get_comp_status";
932 SBDP_DBG_FUNC("%s\n", f
);
934 if (sbdp_is_node_bad(nodeid
)) {
935 SBDP_DBG_STATE("node is not ok\n");
936 return (SBD_COND_UNKNOWN
);
939 if (prom_getproplen(nodeid
, (char *)status
) <= 0) {
940 SBDP_DBG_STATE("status is ok\n");
941 return (SBD_COND_OK
);
944 if (prom_getprop(nodeid
, (char *)status
, status_buf
) < 0) {
945 SBDP_DBG_STATE("status is unknown\n");
946 return (SBD_COND_UNKNOWN
);
949 if (strncmp(status_buf
, failed
, strlen(failed
)) == 0) {
950 SBDP_DBG_STATE("status of failed\n");
951 return (SBD_COND_FAILED
);
954 if (strcmp(status_buf
, disabled
) == 0) {
955 SBDP_DBG_STATE("status of unusable\n");
956 return (SBD_COND_UNUSABLE
);
959 return (SBD_COND_OK
);
963 sbdp_cpu_in_reset(int node
, int bd
, int unit
, int reset
)
967 static fn_t f
= "sbdp_cpu_in_reset";
969 SBDP_DBG_FUNC("%s\n", f
);
971 if ((unit
< -1) || (bd
< 0) || (node
< 0)) {
975 cur
= sbdp_get_wnodep(node
);
977 SBDP_DBG_MISC("marking cpu %d %s for board %d\n", unit
,
978 (reset
) ? "in reset" : "out of reset", bd
);
986 if (unit
== SBDP_ALL_CPUS
)
988 SBDP_SET_ALL_CPUS_IN_RESET(bdp
);
990 SBDP_UNSET_ALL_CPUS_IN_RESET(bdp
);
993 SBDP_SET_CPU_IN_RESET(bdp
, unit
);
995 SBDP_UNSET_CPU_IN_RESET(bdp
, unit
);
999 sbdp_set_cpu_present(int node
, int bd
, int unit
)
1003 static fn_t f
= "sbdp_set_cpu_present";
1005 SBDP_DBG_FUNC("%s\n", f
);
1007 if ((unit
< 0) || (bd
< 0) || (node
< 0)) {
1011 cur
= sbdp_get_wnodep(node
);
1016 bdp
= &cur
->bds
[bd
];
1018 SBDP_SET_CPU_PRESENT(bdp
, unit
);
1024 sbdp_is_cpu_present(int node
, int bd
, int unit
)
1028 static fn_t f
= "sbdp_is_cpu_present";
1030 SBDP_DBG_FUNC("%s\n", f
);
1032 if ((unit
< 0) || (bd
< 0) || (node
< 0)) {
1036 cur
= sbdp_get_wnodep(node
);
1041 bdp
= &cur
->bds
[bd
];
1043 return (SBDP_IS_CPU_PRESENT(bdp
, unit
));
1047 sbdp_is_cpu_in_reset(int node
, int bd
, int unit
)
1051 static fn_t f
= "sbdp_is_cpu_in_reset";
1053 SBDP_DBG_FUNC("%s\n", f
);
1055 if ((unit
< 0) || (bd
< 0) || (node
< 0)) {
1059 cur
= sbdp_get_wnodep(node
);
1065 bdp
= &cur
->bds
[bd
];
1067 return (SBDP_IS_CPU_IN_RESET(bdp
, unit
));
1073 static fn_t f
= "sbdp_dr_avail";
1075 SBDP_DBG_FUNC("%s\n", f
);
1077 if (sbdp_dr_available
)
1078 if (sg_prom_sb_dr_check() == 0)