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 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/cpuvar.h>
30 #include <sys/cpu_module.h>
32 #include <sys/sunddi.h>
33 #include <sys/param.h>
34 #include <sys/obpdefs.h>
35 #include <sys/prom_plat.h>
36 #include <sys/sgsbbc_mailbox.h>
37 #include <sys/sbd_ioctl.h>
38 #include <sys/sbdp_priv.h>
39 #include <sys/sbdp_mbox.h>
40 #include <sys/promif.h>
41 #include <sys/plat_ecc_dimm.h>
43 #define UNKNOWN "unknown"
44 #define INITL_STATUS 0xdead
46 int sbdp_mbox_wait
= 86400; /* in seconds */
47 int sbdp_shw_bd_wait
= 5; /* in seconds */
49 int sbdp_sc_err_translation(int);
50 int sbdp_poweroff_wkaround
= 1;
53 * By default, DR of non-Panther procs is not allowed into a Panther
54 * domain with large page sizes enabled. Setting this to 0 will remove
57 static int sbdp_large_page_restriction
= 1;
60 * Initialize the data structs for the common part of the pkts
63 sbdp_init_msg_pkt(sbbc_msg_t
*msg
, uint16_t sub_type
, int len
, caddr_t buf
)
65 msg
->msg_type
.type
= DR_MBOX
;
66 msg
->msg_type
.sub_type
= sub_type
;
67 msg
->msg_status
= INITL_STATUS
;
76 * Convert a showboard data structure to the board structure shared
77 * between sbd and sbdp
80 sbdp_showbd_2_sbd_stat(show_board_t
*shbp
, sbd_stat_t
*stp
, int board
)
82 static fn_t f
= "sbdp_showbd_2_sbd_stat";
84 SBDP_DBG_FUNC("%s\n", f
);
87 (void) strcpy(stp
->s_info
, shbp
->s_info
);
88 stp
->s_power
= shbp
->s_power
;
90 (void) strcpy(stp
->s_type
, shbp
->s_type
);
92 if (shbp
->s_present
== 0) {
94 * This should go away since the SC should put the unknown
95 * We leave this here so Symon and other scripts don't have
98 (void) strcpy(stp
->s_type
, UNKNOWN
);
99 stp
->s_rstate
= SBD_STAT_EMPTY
;
100 } else if (shbp
->s_claimed
== 0)
101 stp
->s_rstate
= SBD_STAT_DISCONNECTED
;
103 stp
->s_rstate
= SBD_STAT_CONNECTED
;
106 stp
->s_assigned
= shbp
->s_assigned
;
107 stp
->s_cond
= shbp
->s_cond
;
111 * Entry point from sbd. Get the status from the SC and then convert
112 * the info returned into something that sbd understands
113 * If the request times out or fails other than an illegal transaction
114 * copy the info from our inventory
117 sbdp_get_board_status(sbdp_handle_t
*hp
, sbd_stat_t
*stp
)
119 int board
= hp
->h_board
;
120 int node
= hp
->h_wnode
;
121 sbbc_msg_t request
, *reqp
= &request
;
122 sbbc_msg_t response
, *resp
= &response
;
123 info_t inform
, *informp
= &inform
;
124 show_board_t show_bd
, *shbp
= &show_bd
;
126 sbd_error_t
*sep
= hp
->h_err
;
129 static fn_t f
= "sbdp_get_board_status";
131 SBDP_DBG_FUNC("%s\n", f
);
134 * Check for options. If there are any, fail the operation
136 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
137 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
141 bdp
= sbdp_get_bd_info(node
, board
);
143 informp
->board
= board
;
144 informp
->node
= node
;
145 informp
->revision
= 0xdead;
146 len
= sizeof (info_t
);
148 sbdp_init_msg_pkt(reqp
, DR_MBOX_SHOW_BOARD
, len
, (caddr_t
)informp
);
150 bzero(shbp
, sizeof (show_board_t
));
153 shbp
->s_assigned
= -1;
154 shbp
->s_claimed
= -1;
155 shbp
->s_present
= -1;
156 len
= sizeof (show_board_t
);
158 sbdp_init_msg_pkt(resp
, DR_MBOX_SHOW_BOARD
, len
, (caddr_t
)shbp
);
160 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_shw_bd_wait
);
162 SBDP_DBG_MISC("show board completed: rv = %d\n", rv
);
165 * This domain has no access to this board. Return failure
167 if ((resp
->msg_status
== SG_MBOX_STATUS_BOARD_ACCESS_DENIED
) ||
168 (resp
->msg_status
== SG_MBOX_STATUS_ILLEGAL_SLOT
) ||
169 (resp
->msg_status
== SG_MBOX_STATUS_ILLEGAL_NODE
)) {
172 * invalidate cached copy.
176 sbdp_set_err(sep
, ESGT_GET_BOARD_STAT
, NULL
);
181 * If we get any error see if we can return a cached copy of the
182 * board info. If one exists turn the busy flag on
185 mutex_enter(&bdp
->bd_mutex
);
186 if (bdp
->valid_cp
== -1) {
187 sbdp_set_err(sep
, ESGT_GET_BOARD_STAT
,
189 mutex_exit(&bdp
->bd_mutex
);
194 * we have a valid copy. Return it and set the
195 * busy flag on so the user know this is not the most
198 bcopy(bdp
->bd_sc
, shbp
, sizeof (show_board_t
));
199 mutex_exit(&bdp
->bd_mutex
);
202 * The sbbc returns the error in both parts (i.e rv and status)
203 * so since we just took care of it reset rv
208 * revalidate our copy of the returned data
211 SBDP_DBG_MBOX("HUGE ERROR\n");
213 mutex_enter(&bdp
->bd_mutex
);
214 bcopy(shbp
, bdp
->bd_sc
, sizeof (show_board_t
));
216 mutex_exit(&bdp
->bd_mutex
);
221 SBDP_DBG_MBOX("Showboard: board\t%d\n\trevision\t%d\n\ts_cond\t%d\n\t"
222 "s_power\t%d\n\ts_assigned\t%d\n\ts_claimed\t%d\n\t"
223 "s_present\t%d\n\ts_ledstatus\t%d\n\ts_type\t%s\n\t"
225 board
, shbp
->revision
, shbp
->s_cond
, shbp
->s_power
,
226 shbp
->s_assigned
, shbp
->s_claimed
, shbp
->s_present
,
227 shbp
->s_ledstatus
, shbp
->s_type
, shbp
->s_info
);
230 * Now that we got the info run through the sbd-sbdp translator
232 sbdp_showbd_2_sbd_stat(shbp
, stp
, board
);
235 * Last add the platform options
237 SBDP_PLATFORM_OPTS(stp
->s_platopts
);
243 * Entry point from sbd. Call down to the SC to assign the board
244 * We simply return the status the SC told us
247 sbdp_assign_board(sbdp_handle_t
*hp
)
249 int board
= hp
->h_board
;
250 int node
= hp
->h_wnode
;
251 sbbc_msg_t request
, *reqp
= &request
;
252 sbbc_msg_t response
, *resp
= &response
;
254 info2_t inform
, *informp
= &inform
;
258 static fn_t f
= "sbdp_assign_board";
260 SBDP_DBG_FUNC("%s\n", f
);
264 * Check for options. If there are any, fail the operation
266 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
267 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
271 informp
->board
= board
;
272 informp
->node
= node
;
273 informp
->extra
= SBDP_ASSIGN
;
274 len
= sizeof (info2_t
);
276 sbdp_init_msg_pkt(reqp
, DR_MBOX_ASSIGN
, len
, (caddr_t
)informp
);
278 len
= sizeof (cmd_rev
);
280 sbdp_init_msg_pkt(resp
, DR_MBOX_ASSIGN
, len
, (caddr_t
)&cmd_rev
);
282 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
284 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
285 SBDP_DBG_MISC("failed to assign board: rv = %d\n", rv
);
286 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
294 * Entry point from sbd. Call down to the SC to unassign the board
295 * We simply return the status the SC told us
298 sbdp_unassign_board(sbdp_handle_t
*hp
)
300 int board
= hp
->h_board
;
301 int node
= hp
->h_wnode
;
302 sbbc_msg_t request
, *reqp
= &request
;
303 sbbc_msg_t response
, *resp
= &response
;
305 info2_t inform
, *informp
= &inform
;
309 static fn_t f
= "sbdp_unassign_board";
311 SBDP_DBG_FUNC("%s\n", f
);
315 * Check for options. If there are any, fail the operation
317 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
318 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
322 informp
->board
= board
;
323 informp
->node
= node
;
324 informp
->extra
= SBDP_UNASSIGN
;
325 len
= sizeof (info2_t
);
327 sbdp_init_msg_pkt(reqp
, DR_MBOX_ASSIGN
, len
, (caddr_t
)informp
);
329 len
= sizeof (cmd_rev
);
331 sbdp_init_msg_pkt(resp
, DR_MBOX_ASSIGN
, len
, (caddr_t
)&cmd_rev
);
333 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
335 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
336 SBDP_DBG_MISC("failed to unassign board: rv = %d\n", rv
);
337 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
345 sg_attach_board(void *arg
)
350 static fn_t f
= "sg_attach_board";
352 SBDP_DBG_FUNC("%s\n", f
);
354 hp
= (sbdp_handle_t
*)arg
;
356 cset
= cpu_ready_set
;
357 promsafe_xc_attention(cset
);
358 rv
= prom_serengeti_attach_board(hp
->h_wnode
, hp
->h_board
);
365 sg_detach_board(void *arg
)
370 static fn_t f
= "sg_detach_board";
372 SBDP_DBG_FUNC("%s\n", f
);
374 hp
= (sbdp_handle_t
*)arg
;
376 cset
= cpu_ready_set
;
377 promsafe_xc_attention(cset
);
378 rv
= prom_serengeti_detach_board(hp
->h_wnode
, hp
->h_board
);
385 * Entry point from sbd. First we call down to the SC to "attach/claim" this
386 * board. As a side effect the SC updates the pda info so obp can create the
387 * device tree. If we are successful, we ask OBP to probe the board. OBP
388 * creates new nodes on its own obp tree
389 * As an added bonus, since we don't use the inkernel prober, we need to create
390 * the dev_info nodes but just to a point where they are created but
391 * Solaris can't use them (i.e BIND)
394 sbdp_connect_board(sbdp_handle_t
*hp
)
396 sbbc_msg_t request
, *reqp
= &request
;
397 sbbc_msg_t response
, *resp
= &response
;
401 static fn_t f
= "sbdp_connect_board";
402 int panther_pages_enabled
;
404 SBDP_DBG_FUNC("%s\n", f
);
411 * Check for options. If there are any, fail the operation
413 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
414 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
419 * Currently, we pass the info in the extra data fields.
420 * This may change in the SC. We need to change it then
422 sbdp_init_msg_pkt(reqp
, DR_MBOX_CLAIM
, 0, (caddr_t
)NULL
);
423 reqp
->msg_data
[0] = node
;
424 reqp
->msg_data
[1] = board
;
426 sbdp_init_msg_pkt(resp
, DR_MBOX_CLAIM
, 0, (caddr_t
)NULL
);
428 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
430 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
431 SBDP_DBG_MISC("failed to claim board: rv = %d\n", rv
);
432 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
437 rv
= prom_tree_update(sg_attach_board
, hp
);
439 SBDP_DBG_MISC("failed to prom attach board: rv = %d\n", rv
);
440 sbdp_set_err(sep
, ESGT_PROM_ATTACH
, NULL
);
444 sbdp_init_msg_pkt(reqp
, DR_MBOX_UNCLAIM
, 0, (caddr_t
)NULL
);
445 reqp
->msg_data
[0] = node
;
446 reqp
->msg_data
[1] = board
;
448 sbdp_init_msg_pkt(resp
, DR_MBOX_UNCLAIM
, 0, (caddr_t
)NULL
);
450 (void) sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
455 SBDP_DBG_MISC("prom attach worked\n");
456 sbdp_attach_bd(node
, board
);
459 * XXX Until the Solaris large pages support heterogeneous cpu
460 * domains, DR needs to prevent the addition of non-Panther cpus
461 * to an all-Panther domain with large pages enabled.
463 panther_pages_enabled
= (page_num_pagesizes() > DEFAULT_MMU_PAGE_SIZES
);
464 if (sbdp_board_non_panther_cpus(node
, board
) > 0 &&
465 panther_pages_enabled
&& sbdp_large_page_restriction
) {
466 cmn_err(CE_WARN
, "Domain shutdown is required to add a non-"
467 "UltraSPARC-IV+ board into an all UltraSPARC-IV+ domain");
468 (void) sbdp_disconnect_board(hp
);
469 sbdp_set_err(sep
, ESGT_NOT_SUPP
, NULL
);
474 * Now that the board has been successfully attached, obtain
475 * platform-specific DIMM serial id information for the board.
477 if (SG_BOARD_IS_CPU_TYPE(board
) &&
478 plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE
)) {
479 (void) plat_request_mem_sids(board
);
486 * Entry point from sbd. Undo the connect call. We first need to remove
487 * the "dummy (i.e unusable)" nodes from solaris. We then call down to OBP
488 * to prune its tree. After all has been cleaned up from OBP and Solaris
489 * We call the SC to "detach/unclain" the board. A side effect is that the
490 * SC will clear the pda entries for this board
493 sbdp_disconnect_board(sbdp_handle_t
*hp
)
495 sbbc_msg_t request
, *reqp
= &request
;
496 sbbc_msg_t response
, *resp
= &response
;
500 static fn_t f
= "sbdp_disconnect_board";
502 SBDP_DBG_FUNC("%s\n", f
);
508 SBDP_DBG_MISC("sbdp_disconnect_board: board = %d node = %d\n",
512 * Check for options. If there are any, fail the operation
514 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
515 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
519 if (sbdp_detach_bd(node
, board
, sep
)) {
520 sbdp_attach_bd(node
, board
);
521 SBDP_DBG_ALL("failed to detach board %d\n", board
);
525 rv
= prom_tree_update(sg_detach_board
, hp
);
530 sbdp_attach_bd(node
, board
);
531 SBDP_DBG_MISC("failed to prom detach board: rv = %d\n", rv
);
532 sbdp_set_err(sep
, ESGT_PROM_DETACH
, NULL
);
536 SBDP_DBG_MISC("prom detach worked\n");
538 * Currently, we pass the info in the extra data fields.
539 * This may change in the SC. We need to change it then
541 sbdp_init_msg_pkt(reqp
, DR_MBOX_UNCLAIM
, 0, (caddr_t
)NULL
);
542 reqp
->msg_data
[0] = node
;
543 reqp
->msg_data
[1] = board
;
545 sbdp_init_msg_pkt(resp
, DR_MBOX_UNCLAIM
, 0, (caddr_t
)NULL
);
547 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
549 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
550 SBDP_DBG_MISC("failed to unclaim board: rv = %d\n", rv
);
551 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
553 /* bring back the obp tree to what it was */
554 (void) prom_tree_update(sg_attach_board
, hp
);
558 * Now that the board has been successfully detached, discard
559 * platform-specific DIMM serial id information for the board.
561 if (!rv
&& SG_BOARD_IS_CPU_TYPE(board
) &&
562 plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE
)) {
563 (void) plat_discard_mem_sids(board
);
570 * Entry point from sbd. Very simple. Just ask the SC to poweoff the board
571 * Return the status from the SC
574 sbdp_poweroff_board(sbdp_handle_t
*hp
)
576 sbbc_msg_t request
, *reqp
= &request
;
577 sbbc_msg_t response
, *resp
= &response
;
579 info2_t inform
, *informp
;
583 static fn_t f
= "sbdp_poweroff_board";
585 SBDP_DBG_FUNC("%s\n", f
);
589 * Check for options. If there are any, fail the operation
591 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
592 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
597 * Can't check for bad options here since we use this for workaround
602 informp
->board
= hp
->h_board
;
603 informp
->node
= hp
->h_wnode
;
604 informp
->extra
= SBDP_POWER_OFF
;
606 len
= sizeof (info2_t
);
607 sbdp_init_msg_pkt(reqp
, DR_MBOX_POWER
, len
, (caddr_t
)informp
);
609 len
= sizeof (cmd_rev
);
610 sbdp_init_msg_pkt(resp
, DR_MBOX_POWER
, len
, (caddr_t
)&cmd_rev
);
612 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
614 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
615 SBDP_DBG_MISC("failed to poweroff board: rv = %d\n", rv
);
616 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
624 * Entry point from sbd. Ask the SC to poweron the board
625 * Return the status from the SC
628 sbdp_poweron_board(sbdp_handle_t
*hp
)
630 sbbc_msg_t request
, *reqp
= &request
;
631 sbbc_msg_t response
, *resp
= &response
;
633 info2_t inform
, *informp
;
637 int board
= hp
->h_board
;
638 static fn_t f
= "sbdp_poweron_board";
640 SBDP_DBG_FUNC("%s\n", f
);
644 * Check for options. If there are any, fail the operation
646 if (hp
->h_opts
!= NULL
&& hp
->h_opts
->copts
!= NULL
) {
647 sbdp_set_err(sep
, ESBD_INVAL_OPT
, hp
->h_opts
->copts
);
651 if (sbdp_poweroff_wkaround
)
652 if (SG_BOARD_IS_CPU_TYPE(board
)) {
654 if ((rv
= sbdp_poweroff_board(hp
)) != 0)
659 informp
->board
= hp
->h_board
;
660 informp
->node
= hp
->h_wnode
;
661 informp
->extra
= SBDP_POWER_ON
;
663 len
= sizeof (info2_t
);
664 sbdp_init_msg_pkt(reqp
, DR_MBOX_POWER
, len
, (caddr_t
)informp
);
666 len
= sizeof (cmd_rev
);
667 sbdp_init_msg_pkt(resp
, DR_MBOX_POWER
, len
, (caddr_t
)&cmd_rev
);
669 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
671 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
672 SBDP_DBG_MISC("failed to poweron board: rv = %d\n", rv
);
673 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
681 sbdp_get_diag(sbdp_opts_t
*opts
)
684 static fn_t f
= "sbdp_get_diag";
686 SBDP_DBG_FUNC("%s\n", f
);
688 if ((opts
== NULL
) || (opts
->copts
== NULL
))
689 return (SBDP_DIAG_NVCI
);
691 if ((cptr
= strstr(opts
->copts
, "diag=")) != NULL
) {
693 * We have args and need to process them
695 cptr
+= strlen("diag=");
697 if (strncmp(cptr
, "off", sizeof ("off")) == 0) {
698 return (SBDP_DIAG_OFF
);
699 } else if (strncmp(cptr
, "init", sizeof ("init")) == 0) {
700 return (SBDP_DIAG_INIT
);
701 } else if (strncmp(cptr
, "quick", sizeof ("quick")) == 0) {
702 return (SBDP_DIAG_QUICK
);
703 } else if (strncmp(cptr
, "min", sizeof ("min")) == 0) {
704 return (SBDP_DIAG_MIN
);
705 } else if (strncmp(cptr
, "default", sizeof ("default")) == 0 ||
706 strncmp(cptr
, "max", sizeof ("max")) == 0) {
707 return (SBDP_DIAG_DEFAULT
);
708 } else if (strncmp(cptr
, "mem1", sizeof ("mem1")) == 0) {
709 return (SBDP_DIAG_MEM1
);
710 } else if (strncmp(cptr
, "mem2", sizeof ("mem2")) == 0) {
711 return (SBDP_DIAG_MEM2
);
714 SBDP_DBG_MISC("error: unrecognized arg\n");
720 * Entry point from sbd. Ask the SC to test the board. We still need to
721 * worry about the diag level. The user may have changed it
723 * NOTE: The flag field has 2 different meanings whether we are dealing
724 * with a cpu/mem board or an io board. In the case of a cpu/mem board it
725 * means retest the board to the diag level specified. In the case of an IO
726 * board, it means: Perform the necessary steps to prepare the board
727 * for the claim without running POST at the diag level specified.
730 sbdp_test_board(sbdp_handle_t
*hp
, sbdp_opts_t
*opts
)
732 int board
= hp
->h_board
;
733 int node
= hp
->h_wnode
;
734 sbbc_msg_t request
, *reqp
= &request
;
735 sbbc_msg_t response
, *resp
= &response
;
737 testb_t inform
, *informp
= &inform
;
742 static fn_t f
= "sbdp_test_board";
744 SBDP_DBG_FUNC("%s\n", f
);
748 diag
= sbdp_get_diag(opts
);
751 sbdp_set_err(sep
, ESBD_INVAL_OPT
, opts
!= NULL
?
756 SBDP_DBG_MISC("Diag level is 0x%x\n", diag
);
758 informp
->info
.board
= board
;
759 informp
->info
.node
= node
;
761 informp
->info
.extra
= diag
;
764 * Only force retest on CPU boards
766 if (SG_BOARD_IS_CPU_TYPE(board
))
770 * For CPULESS IO pass the force to the SC
772 if (hp
->h_flags
& SBDP_IOCTL_FLAG_FORCE
)
779 len
= sizeof (testb_t
);
780 sbdp_init_msg_pkt(reqp
, DR_MBOX_TEST_BD
, len
, (caddr_t
)informp
);
783 len
= sizeof (cmd_rev
);
784 sbdp_init_msg_pkt(resp
, DR_MBOX_TEST_BD
, len
, (caddr_t
)&cmd_rev
);
786 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
788 if (rv
!= 0 || (resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
789 SBDP_DBG_MISC("failed to test board: rv = %d status = %d\n",
790 rv
, resp
->msg_status
);
791 rv
= resp
->msg_status
;
792 sbdp_set_err(sep
, sbdp_sc_err_translation(resp
->msg_status
),
800 * Request the SC to update POST's memory slice table by swapping
801 * the entries for the two board numbers given
802 * This is used when performing a copy-rename operation.
805 sbdp_swap_slices(int bd1
, int bd2
)
807 sbbc_msg_t request
, *reqp
= &request
;
808 sbbc_msg_t response
, *resp
= &response
;
810 swap_slices_t inform
, *informp
= &inform
;
813 static fn_t f
= "sbdp_swap_slices";
815 SBDP_DBG_FUNC("%s\n", f
);
817 informp
->board1
= bd1
;
818 informp
->board2
= bd2
;
820 len
= sizeof (swap_slices_t
);
821 sbdp_init_msg_pkt(reqp
, DR_MBOX_SWAP_SLICES
, len
, (caddr_t
)informp
);
823 len
= sizeof (cmd_rev
);
824 sbdp_init_msg_pkt(resp
, DR_MBOX_SWAP_SLICES
, len
, (caddr_t
)&cmd_rev
);
826 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
828 if (rv
!= 0 || (resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
829 SBDP_DBG_MISC("failed to swap slices %d<->%d: rv = %d "
830 "status = %d\n", bd1
, bd2
, rv
, resp
->msg_status
);
831 rv
= sbdp_sc_err_translation(resp
->msg_status
);
838 sbdp_sc_err_translation(int error
)
841 static fn_t f
= "sbdp_sc_err_translation";
843 SBDP_DBG_FUNC("%s\n", f
);
846 case SG_MBOX_STATUS_HARDWARE_FAILURE
:
849 case SG_MBOX_STATUS_ILLEGAL_PARAMETER
:
850 case SG_MBOX_STATUS_ILLEGAL_NODE
:
851 case SG_MBOX_STATUS_ILLEGAL_SLOT
:
854 case SG_MBOX_STATUS_BOARD_ACCESS_DENIED
:
855 err
= ESGT_BD_ACCESS
;
857 case SG_MBOX_STATUS_STALE_CONTENTS
:
858 err
= ESGT_STALE_CMP
;
860 case SG_MBOX_STATUS_STALE_OBJECT
:
861 err
= ESGT_STALE_OBJ
;
863 case SG_MBOX_STATUS_NO_SEPROM_SPACE
:
864 err
= ESGT_NO_SEPROM_SPACE
;
866 case SG_MBOX_STATUS_NO_MEMORY
:
869 case SG_MBOX_STATUS_NOT_SUPPORTED
:
872 case SG_MBOX_STATUS_COMMAND_FAILURE
:
882 sbdp_stop_cpu(processorid_t cpu
)
884 sbbc_msg_t request
, *reqp
= &request
;
885 sbbc_msg_t response
, *resp
= &response
;
888 static fn_t f
= "sbdp_stop_cpu";
890 SBDP_DBG_FUNC("%s\n", f
);
892 len
= sizeof (processorid_t
);
893 sbdp_init_msg_pkt(reqp
, DR_MBOX_STOP_CPU
, len
, (caddr_t
)&cpu
);
895 sbdp_init_msg_pkt(resp
, DR_MBOX_STOP_CPU
, 0, (caddr_t
)NULL
);
897 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
899 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
900 SBDP_DBG_MISC("failed to stop cpu: rv = %d\n", rv
);
907 sbdp_start_cpu(processorid_t cpu
)
909 sbbc_msg_t request
, *reqp
= &request
;
910 sbbc_msg_t response
, *resp
= &response
;
913 static fn_t f
= "sbdp_start_cpu";
915 SBDP_DBG_FUNC("%s\n", f
);
918 sbdp_init_msg_pkt(reqp
, DR_MBOX_START_CPU
, len
, (caddr_t
)&cpu
);
920 sbdp_init_msg_pkt(resp
, DR_MBOX_START_CPU
, 0, (caddr_t
)NULL
);
922 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
924 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
925 SBDP_DBG_MISC("failed to start cpu: rv = %d\n", rv
);
932 * With the SIR implementation for CPU unconfigure, this mailbox
936 sbdp_start_cpu_pairs(processorid_t cpu
)
938 sbbc_msg_t request
, *reqp
= &request
;
939 sbbc_msg_t response
, *resp
= &response
;
942 static fn_t f
= "sbdp_start_cpu_pairs";
944 SBDP_DBG_FUNC("%s\n", f
);
947 sbdp_init_msg_pkt(reqp
, DR_MBOX_START_CPU_PAIRS
, len
, (caddr_t
)&cpu
);
949 sbdp_init_msg_pkt(resp
, DR_MBOX_START_CPU_PAIRS
, 0, (caddr_t
)NULL
);
951 rv
= sbbc_mbox_request_response(reqp
, resp
, sbdp_mbox_wait
);
953 if (rv
!= 0 || (rv
= resp
->msg_status
!= SG_MBOX_STATUS_SUCCESS
)) {
954 SBDP_DBG_MISC("failed to start cpu pair: rv = %d\n", rv
);