#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/cpuvar.h>
#include <sys/cpu_module.h>
#include <sys/kmem.h>
#include <sys/sunddi.h>
#include <sys/param.h>
#include <sys/obpdefs.h>
#include <sys/prom_plat.h>
#include <sys/sgsbbc_mailbox.h>
#include <sys/sbd_ioctl.h>
#include <sys/sbdp_priv.h>
#include <sys/sbdp_mbox.h>
#include <sys/promif.h>
#include <sys/plat_ecc_dimm.h>
#define UNKNOWN "unknown"
#define INITL_STATUS 0xdead
int sbdp_mbox_wait = 86400;
int sbdp_shw_bd_wait = 5;
int sbdp_sc_err_translation(int);
int sbdp_poweroff_wkaround = 1;
static int sbdp_large_page_restriction = 1;
void
sbdp_init_msg_pkt(sbbc_msg_t *msg, uint16_t sub_type, int len, caddr_t buf)
{
msg->msg_type.type = DR_MBOX;
msg->msg_type.sub_type = sub_type;
msg->msg_status = INITL_STATUS;
msg->msg_len = len;
msg->msg_buf = buf;
msg->msg_data[0] = 0;
msg->msg_data[1] = 0;
}
void
sbdp_showbd_2_sbd_stat(show_board_t *shbp, sbd_stat_t *stp, int board)
{
static fn_t f = "sbdp_showbd_2_sbd_stat";
SBDP_DBG_FUNC("%s\n", f);
stp->s_board = board;
(void) strcpy(stp->s_info, shbp->s_info);
stp->s_power = shbp->s_power;
(void) strcpy(stp->s_type, shbp->s_type);
if (shbp->s_present == 0) {
(void) strcpy(stp->s_type, UNKNOWN);
stp->s_rstate = SBD_STAT_EMPTY;
} else if (shbp->s_claimed == 0)
stp->s_rstate = SBD_STAT_DISCONNECTED;
else
stp->s_rstate = SBD_STAT_CONNECTED;
stp->s_assigned = shbp->s_assigned;
stp->s_cond = shbp->s_cond;
}
int
sbdp_get_board_status(sbdp_handle_t *hp, sbd_stat_t *stp)
{
int board = hp->h_board;
int node = hp->h_wnode;
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
info_t inform, *informp = &inform;
show_board_t show_bd, *shbp = &show_bd;
int rv = 0;
sbd_error_t *sep = hp->h_err;
int len;
sbdp_bd_t *bdp;
static fn_t f = "sbdp_get_board_status";
SBDP_DBG_FUNC("%s\n", f);
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
bdp = sbdp_get_bd_info(node, board);
informp->board = board;
informp->node = node;
informp->revision = 0xdead;
len = sizeof (info_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_SHOW_BOARD, len, (caddr_t)informp);
bzero(shbp, sizeof (show_board_t));
shbp->s_cond = -1;
shbp->s_power = -1;
shbp->s_assigned = -1;
shbp->s_claimed = -1;
shbp->s_present = -1;
len = sizeof (show_board_t);
sbdp_init_msg_pkt(resp, DR_MBOX_SHOW_BOARD, len, (caddr_t)shbp);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_shw_bd_wait);
SBDP_DBG_MISC("show board completed: rv = %d\n", rv);
if ((resp->msg_status == SG_MBOX_STATUS_BOARD_ACCESS_DENIED) ||
(resp->msg_status == SG_MBOX_STATUS_ILLEGAL_SLOT) ||
(resp->msg_status == SG_MBOX_STATUS_ILLEGAL_NODE)) {
bdp->valid_cp = -1;
sbdp_set_err(sep, ESGT_GET_BOARD_STAT, NULL);
return (EIO);
}
if (rv != 0) {
mutex_enter(&bdp->bd_mutex);
if (bdp->valid_cp == -1) {
sbdp_set_err(sep, ESGT_GET_BOARD_STAT,
NULL);
mutex_exit(&bdp->bd_mutex);
return (EIO);
}
bcopy(bdp->bd_sc, shbp, sizeof (show_board_t));
mutex_exit(&bdp->bd_mutex);
stp->s_busy = 1;
rv = 0;
} else {
if (bdp == NULL) {
SBDP_DBG_MBOX("HUGE ERROR\n");
} else {
mutex_enter(&bdp->bd_mutex);
bcopy(shbp, bdp->bd_sc, sizeof (show_board_t));
bdp->valid_cp = 1;
mutex_exit(&bdp->bd_mutex);
}
}
SBDP_DBG_MBOX("Showboard: board\t%d\n\trevision\t%d\n\ts_cond\t%d\n\t"
"s_power\t%d\n\ts_assigned\t%d\n\ts_claimed\t%d\n\t"
"s_present\t%d\n\ts_ledstatus\t%d\n\ts_type\t%s\n\t"
"s_info\t%s\n",
board, shbp->revision, shbp->s_cond, shbp->s_power,
shbp->s_assigned, shbp->s_claimed, shbp->s_present,
shbp->s_ledstatus, shbp->s_type, shbp->s_info);
sbdp_showbd_2_sbd_stat(shbp, stp, board);
SBDP_PLATFORM_OPTS(stp->s_platopts);
return (rv);
}
int
sbdp_assign_board(sbdp_handle_t *hp)
{
int board = hp->h_board;
int node = hp->h_wnode;
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int cmd_rev = -1;
info2_t inform, *informp = &inform;
int rv = 0;
sbd_error_t *sep;
int len;
static fn_t f = "sbdp_assign_board";
SBDP_DBG_FUNC("%s\n", f);
sep = hp->h_err;
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
informp->board = board;
informp->node = node;
informp->extra = SBDP_ASSIGN;
len = sizeof (info2_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_ASSIGN, len, (caddr_t)informp);
len = sizeof (cmd_rev);
sbdp_init_msg_pkt(resp, DR_MBOX_ASSIGN, len, (caddr_t)&cmd_rev);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to assign board: rv = %d\n", rv);
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
}
return (rv);
}
int
sbdp_unassign_board(sbdp_handle_t *hp)
{
int board = hp->h_board;
int node = hp->h_wnode;
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int cmd_rev = -1;
info2_t inform, *informp = &inform;
int rv = 0;
sbd_error_t *sep;
int len;
static fn_t f = "sbdp_unassign_board";
SBDP_DBG_FUNC("%s\n", f);
sep = hp->h_err;
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
informp->board = board;
informp->node = node;
informp->extra = SBDP_UNASSIGN;
len = sizeof (info2_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_ASSIGN, len, (caddr_t)informp);
len = sizeof (cmd_rev);
sbdp_init_msg_pkt(resp, DR_MBOX_ASSIGN, len, (caddr_t)&cmd_rev);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to unassign board: rv = %d\n", rv);
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
}
return (rv);
}
static int
sg_attach_board(void *arg)
{
sbdp_handle_t *hp;
cpuset_t cset;
int rv;
static fn_t f = "sg_attach_board";
SBDP_DBG_FUNC("%s\n", f);
hp = (sbdp_handle_t *)arg;
cset = cpu_ready_set;
promsafe_xc_attention(cset);
rv = prom_serengeti_attach_board(hp->h_wnode, hp->h_board);
xc_dismissed(cset);
return (rv);
}
static int
sg_detach_board(void *arg)
{
sbdp_handle_t *hp;
cpuset_t cset;
int rv;
static fn_t f = "sg_detach_board";
SBDP_DBG_FUNC("%s\n", f);
hp = (sbdp_handle_t *)arg;
cset = cpu_ready_set;
promsafe_xc_attention(cset);
rv = prom_serengeti_detach_board(hp->h_wnode, hp->h_board);
xc_dismissed(cset);
return (rv);
}
int
sbdp_connect_board(sbdp_handle_t *hp)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int rv = 0;
int board, node;
sbd_error_t *sep;
static fn_t f = "sbdp_connect_board";
int panther_pages_enabled;
SBDP_DBG_FUNC("%s\n", f);
board = hp->h_board;
node = hp->h_wnode;
sep = hp->h_err;
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
sbdp_init_msg_pkt(reqp, DR_MBOX_CLAIM, 0, (caddr_t)NULL);
reqp->msg_data[0] = node;
reqp->msg_data[1] = board;
sbdp_init_msg_pkt(resp, DR_MBOX_CLAIM, 0, (caddr_t)NULL);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to claim board: rv = %d\n", rv);
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
return (rv);
}
rv = prom_tree_update(sg_attach_board, hp);
if (rv != 0) {
SBDP_DBG_MISC("failed to prom attach board: rv = %d\n", rv);
sbdp_set_err(sep, ESGT_PROM_ATTACH, NULL);
sbdp_init_msg_pkt(reqp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
reqp->msg_data[0] = node;
reqp->msg_data[1] = board;
sbdp_init_msg_pkt(resp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
(void) sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
return (rv);
}
SBDP_DBG_MISC("prom attach worked\n");
sbdp_attach_bd(node, board);
panther_pages_enabled = (page_num_pagesizes() > DEFAULT_MMU_PAGE_SIZES);
if (sbdp_board_non_panther_cpus(node, board) > 0 &&
panther_pages_enabled && sbdp_large_page_restriction) {
cmn_err(CE_WARN, "Domain shutdown is required to add a non-"
"UltraSPARC-IV+ board into an all UltraSPARC-IV+ domain");
(void) sbdp_disconnect_board(hp);
sbdp_set_err(sep, ESGT_NOT_SUPP, NULL);
return (-1);
}
if (SG_BOARD_IS_CPU_TYPE(board) &&
plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE)) {
(void) plat_request_mem_sids(board);
}
return (rv);
}
int
sbdp_disconnect_board(sbdp_handle_t *hp)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int rv = 0;
int board, node;
sbd_error_t *sep;
static fn_t f = "sbdp_disconnect_board";
SBDP_DBG_FUNC("%s\n", f);
board = hp->h_board;
node = hp->h_wnode;
sep = hp->h_err;
SBDP_DBG_MISC("sbdp_disconnect_board: board = %d node = %d\n",
board, node);
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
if (sbdp_detach_bd(node, board, sep)) {
sbdp_attach_bd(node, board);
SBDP_DBG_ALL("failed to detach board %d\n", board);
return (-1);
}
rv = prom_tree_update(sg_detach_board, hp);
if (rv == -1) {
sbdp_attach_bd(node, board);
SBDP_DBG_MISC("failed to prom detach board: rv = %d\n", rv);
sbdp_set_err(sep, ESGT_PROM_DETACH, NULL);
return (rv);
}
SBDP_DBG_MISC("prom detach worked\n");
sbdp_init_msg_pkt(reqp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
reqp->msg_data[0] = node;
reqp->msg_data[1] = board;
sbdp_init_msg_pkt(resp, DR_MBOX_UNCLAIM, 0, (caddr_t)NULL);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to unclaim board: rv = %d\n", rv);
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
(void) prom_tree_update(sg_attach_board, hp);
}
if (!rv && SG_BOARD_IS_CPU_TYPE(board) &&
plat_ecc_capability_sc_get(PLAT_ECC_DIMM_SID_MESSAGE)) {
(void) plat_discard_mem_sids(board);
}
return (rv);
}
int
sbdp_poweroff_board(sbdp_handle_t *hp)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int cmd_rev = -1;
info2_t inform, *informp;
int rv = 0;
sbd_error_t *sep;
int len;
static fn_t f = "sbdp_poweroff_board";
SBDP_DBG_FUNC("%s\n", f);
sep = hp->h_err;
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
informp = &inform;
informp->board = hp->h_board;
informp->node = hp->h_wnode;
informp->extra = SBDP_POWER_OFF;
len = sizeof (info2_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_POWER, len, (caddr_t)informp);
len = sizeof (cmd_rev);
sbdp_init_msg_pkt(resp, DR_MBOX_POWER, len, (caddr_t)&cmd_rev);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to poweroff board: rv = %d\n", rv);
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
}
return (rv);
}
int
sbdp_poweron_board(sbdp_handle_t *hp)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int cmd_rev = -1;
info2_t inform, *informp;
int rv = 0;
sbd_error_t *sep;
int len;
int board = hp->h_board;
static fn_t f = "sbdp_poweron_board";
SBDP_DBG_FUNC("%s\n", f);
sep = hp->h_err;
if (hp->h_opts != NULL && hp->h_opts->copts != NULL) {
sbdp_set_err(sep, ESBD_INVAL_OPT, hp->h_opts->copts);
return (-1);
}
if (sbdp_poweroff_wkaround)
if (SG_BOARD_IS_CPU_TYPE(board)) {
if ((rv = sbdp_poweroff_board(hp)) != 0)
return (rv);
}
informp = &inform;
informp->board = hp->h_board;
informp->node = hp->h_wnode;
informp->extra = SBDP_POWER_ON;
len = sizeof (info2_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_POWER, len, (caddr_t)informp);
len = sizeof (cmd_rev);
sbdp_init_msg_pkt(resp, DR_MBOX_POWER, len, (caddr_t)&cmd_rev);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to poweron board: rv = %d\n", rv);
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
}
return (rv);
}
int
sbdp_get_diag(sbdp_opts_t *opts)
{
char *cptr;
static fn_t f = "sbdp_get_diag";
SBDP_DBG_FUNC("%s\n", f);
if ((opts == NULL) || (opts->copts == NULL))
return (SBDP_DIAG_NVCI);
if ((cptr = strstr(opts->copts, "diag=")) != NULL) {
cptr += strlen("diag=");
if (strncmp(cptr, "off", sizeof ("off")) == 0) {
return (SBDP_DIAG_OFF);
} else if (strncmp(cptr, "init", sizeof ("init")) == 0) {
return (SBDP_DIAG_INIT);
} else if (strncmp(cptr, "quick", sizeof ("quick")) == 0) {
return (SBDP_DIAG_QUICK);
} else if (strncmp(cptr, "min", sizeof ("min")) == 0) {
return (SBDP_DIAG_MIN);
} else if (strncmp(cptr, "default", sizeof ("default")) == 0 ||
strncmp(cptr, "max", sizeof ("max")) == 0) {
return (SBDP_DIAG_DEFAULT);
} else if (strncmp(cptr, "mem1", sizeof ("mem1")) == 0) {
return (SBDP_DIAG_MEM1);
} else if (strncmp(cptr, "mem2", sizeof ("mem2")) == 0) {
return (SBDP_DIAG_MEM2);
}
}
SBDP_DBG_MISC("error: unrecognized arg\n");
return (-1);
}
int
sbdp_test_board(sbdp_handle_t *hp, sbdp_opts_t *opts)
{
int board = hp->h_board;
int node = hp->h_wnode;
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int cmd_rev = -1;
testb_t inform, *informp = &inform;
int rv = 0;
sbd_error_t *sep;
int diag;
int len;
static fn_t f = "sbdp_test_board";
SBDP_DBG_FUNC("%s\n", f);
sep = hp->h_err;
diag = sbdp_get_diag(opts);
if (diag == -1) {
sbdp_set_err(sep, ESBD_INVAL_OPT, opts != NULL ?
opts->copts : NULL);
return (-1);
}
SBDP_DBG_MISC("Diag level is 0x%x\n", diag);
informp->info.board = board;
informp->info.node = node;
informp->info.extra = diag;
if (SG_BOARD_IS_CPU_TYPE(board))
informp->flag = 1;
else {
if (hp->h_flags & SBDP_IOCTL_FLAG_FORCE)
informp->flag = 1;
else
informp->flag = 0;
}
len = sizeof (testb_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_TEST_BD, len, (caddr_t)informp);
len = sizeof (cmd_rev);
sbdp_init_msg_pkt(resp, DR_MBOX_TEST_BD, len, (caddr_t)&cmd_rev);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to test board: rv = %d status = %d\n",
rv, resp->msg_status);
rv = resp->msg_status;
sbdp_set_err(sep, sbdp_sc_err_translation(resp->msg_status),
NULL);
}
return (rv);
}
int
sbdp_swap_slices(int bd1, int bd2)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int cmd_rev = -1;
swap_slices_t inform, *informp = &inform;
int rv;
int len;
static fn_t f = "sbdp_swap_slices";
SBDP_DBG_FUNC("%s\n", f);
informp->board1 = bd1;
informp->board2 = bd2;
len = sizeof (swap_slices_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_SWAP_SLICES, len, (caddr_t)informp);
len = sizeof (cmd_rev);
sbdp_init_msg_pkt(resp, DR_MBOX_SWAP_SLICES, len, (caddr_t)&cmd_rev);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to swap slices %d<->%d: rv = %d "
"status = %d\n", bd1, bd2, rv, resp->msg_status);
rv = sbdp_sc_err_translation(resp->msg_status);
}
return (rv);
}
int
sbdp_sc_err_translation(int error)
{
int err;
static fn_t f = "sbdp_sc_err_translation";
SBDP_DBG_FUNC("%s\n", f);
switch (error) {
case SG_MBOX_STATUS_HARDWARE_FAILURE:
err = ESGT_HW_FAIL;
break;
case SG_MBOX_STATUS_ILLEGAL_PARAMETER:
case SG_MBOX_STATUS_ILLEGAL_NODE:
case SG_MBOX_STATUS_ILLEGAL_SLOT:
err = ESGT_INVAL;
break;
case SG_MBOX_STATUS_BOARD_ACCESS_DENIED:
err = ESGT_BD_ACCESS;
break;
case SG_MBOX_STATUS_STALE_CONTENTS:
err = ESGT_STALE_CMP;
break;
case SG_MBOX_STATUS_STALE_OBJECT:
err = ESGT_STALE_OBJ;
break;
case SG_MBOX_STATUS_NO_SEPROM_SPACE:
err = ESGT_NO_SEPROM_SPACE;
break;
case SG_MBOX_STATUS_NO_MEMORY:
err = ESGT_NO_MEM;
break;
case SG_MBOX_STATUS_NOT_SUPPORTED:
err = ESGT_NOT_SUPP;
break;
case SG_MBOX_STATUS_COMMAND_FAILURE:
default:
err = ESGT_INTERNAL;
break;
}
return (err);
}
int
sbdp_stop_cpu(processorid_t cpu)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int rv = 0;
int len;
static fn_t f = "sbdp_stop_cpu";
SBDP_DBG_FUNC("%s\n", f);
len = sizeof (processorid_t);
sbdp_init_msg_pkt(reqp, DR_MBOX_STOP_CPU, len, (caddr_t)&cpu);
sbdp_init_msg_pkt(resp, DR_MBOX_STOP_CPU, 0, (caddr_t)NULL);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to stop cpu: rv = %d\n", rv);
}
return (rv);
}
int
sbdp_start_cpu(processorid_t cpu)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int rv = 0;
int len;
static fn_t f = "sbdp_start_cpu";
SBDP_DBG_FUNC("%s\n", f);
len = sizeof (cpu);
sbdp_init_msg_pkt(reqp, DR_MBOX_START_CPU, len, (caddr_t)&cpu);
sbdp_init_msg_pkt(resp, DR_MBOX_START_CPU, 0, (caddr_t)NULL);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to start cpu: rv = %d\n", rv);
}
return (rv);
}
int
sbdp_start_cpu_pairs(processorid_t cpu)
{
sbbc_msg_t request, *reqp = &request;
sbbc_msg_t response, *resp = &response;
int rv = 0;
int len;
static fn_t f = "sbdp_start_cpu_pairs";
SBDP_DBG_FUNC("%s\n", f);
len = sizeof (cpu);
sbdp_init_msg_pkt(reqp, DR_MBOX_START_CPU_PAIRS, len, (caddr_t)&cpu);
sbdp_init_msg_pkt(resp, DR_MBOX_START_CPU_PAIRS, 0, (caddr_t)NULL);
rv = sbbc_mbox_request_response(reqp, resp, sbdp_mbox_wait);
if (rv != 0 || (rv = resp->msg_status != SG_MBOX_STATUS_SUCCESS)) {
SBDP_DBG_MISC("failed to start cpu pair: rv = %d\n", rv);
}
return (rv);
}