03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ENXS platform-specific functions
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdlib.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <unistd.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <string.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <assert.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <fcntl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "librsc.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* rmcadm driver file descriptor */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int rsc_fd = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * librsc receive buffer - it is used as temporary buffer to store replies
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from the remote side
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic uchar_t rsc_rx_buffer[RSC_MAX_RX_BUFFER];
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int rsc_rx_resp_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int rsc_rx_error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic rsci8 rsc_rx_resp_type = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Registered boot-protocol message callback routine. This routine will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * called whenever a boot protocol message is received.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic rscp_bpmsg_cb_t *bpmsg_cb;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* lookup table to match request and response . This is in order to support */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* obsolete functions (rscp_send, rscp_recv) */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic req_resp_table_t rr_table[] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_DATE_TIME, DP_GET_DATE_TIME_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_date_time_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_SET_DATE_TIME, DP_SET_DATE_TIME_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_set_date_time_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_EVENT_LOG, DP_GET_EVENT_LOG_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_event_log_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_MODEM_CONNECT, DP_MODEM_CONNECT_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_modem_connect_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_MODEM_DISCONNECT, DP_MODEM_DISCONNECT_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_modem_disconnect_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_SEND_ALERT, DP_SEND_ALERT_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_send_alert_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_SET_CFGVAR, DP_SET_CFGVAR_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_set_cfgvar_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_CFGVAR, DP_GET_CFGVAR_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_cfgvar_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_CFGVAR_NAME, DP_GET_CFGVAR_NAME_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_cfgvar_name_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_NETWORK_CFG, DP_GET_NETWORK_CFG_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_network_cfg_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_RSC_STATUS, DP_RSC_STATUS_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_rsc_status_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_USER_ADM, DP_USER_ADM_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_user_adm_r_t), RR_SEPROM_TIMEOUT},
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_RESET_RSC, DP_NULL_MSG,
03831d35f7499c87d51205817c93e9a8d42c4baestevel 0, 1 },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_CONSOLE_LOG, DP_GET_CONSOLE_LOG_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_console_log_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_CONFIG_LOG, DP_GET_CONFIG_LOG_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_config_log_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { DP_GET_EVENT_LOG2, DP_GET_EVENT_LOG2_R,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (dp_get_event_log2_r_t), RR_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic const int rr_table_cnt = sizeof (rr_table) / sizeof (rr_table[0]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* lookup table to get timeout value for BP cmd reply. This is in order to */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* support obsolete functions (rscp_send_bpmsg, rsc_raw_write) */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic req_resp_table_t rr_bp_table[] = {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel { BP_OBP_BOOTINIT, NULL, sizeof (bp_msg_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel RR_BOOT_INIT_TIMEOUT },
03831d35f7499c87d51205817c93e9a8d42c4baestevel { BP_OBP_RESET, NULL, sizeof (bp_msg_t),
03831d35f7499c87d51205817c93e9a8d42c4baestevel RR_BOOT_RESET_TIMEOUT }
03831d35f7499c87d51205817c93e9a8d42c4baestevel};
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic const int rr_bp_table_cnt =
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (rr_bp_table) / sizeof (rr_bp_table[0]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic rsci8 unsupported_cmds[] = { DP_SET_DATE_TIME };
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int unsupported_cmds_cnt = sizeof (unsupported_cmds) /
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (unsupported_cmds[0]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Protocol version number, used to determine whether ALOM will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * time out on unknown commands.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int sdp_version = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* function prototypes */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic req_resp_table_t *rsc_lookup_rr_table(req_resp_table_t *, int, rsci8);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int rsc_check_unsupported_cmd(rsci8);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int rsc_cmd_response_guaranteed(rsci8);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize the generic librsc data protocol routines. basically, it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * open the rmcadm (pseudo) device and initialize data
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_init(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rscp_msg_t request, response;
03831d35f7499c87d51205817c93e9a8d42c4baestevel dp_get_sdp_version_r_t version_msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 'erase' the rx buffer
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) memset(rsc_rx_buffer, 0, sizeof (RSC_MAX_RX_BUFFER));
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_type = DP_NULL_MSG;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * open rmcadm driver
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rsc_fd = open(RSC_RMCADM_DRV, O_RDWR)) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_init: Error opening %s, error code = %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel RSC_RMCADM_DRV, errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Fetch the protocol version number in use between the host
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and ALOM.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel request.type = DP_GET_SDP_VERSION;
03831d35f7499c87d51205817c93e9a8d42c4baestevel request.len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel request.data = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel response.type = DP_GET_SDP_VERSION_R;
03831d35f7499c87d51205817c93e9a8d42c4baestevel response.len = sizeof (version_msg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel response.data = (caddr_t)&version_msg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((errno = rscp_send_recv(&request, &response, 0)) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel sdp_version = version_msg.version;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_init: sdp version number is %d\n", sdp_version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * send/receive interface: this is the new interface where application
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (currently scadm, SunVTS) send a request and wait for a reply in a
03831d35f7499c87d51205817c93e9a8d42c4baestevel * single call. If a response is not required (resp=NULL), the function
03831d35f7499c87d51205817c93e9a8d42c4baestevel * will only return the status of the request (whether it has been successfully
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or not).
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_send_recv(rscp_msg_t *req, rscp_msg_t *resp, struct timespec *timeout)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_request_response_t rr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_msg_t *rr_req = &rr.req;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_msg_t *rr_resp = &rr.resp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the request is required, it should not be NULL!
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (req == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if the command is actually supported
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if not, return an error
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_check_unsupported_cmd(req->type) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if this command will generate a response and if it will not,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return an error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!rsc_cmd_response_guaranteed(req->type))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_req->msg_type = req->type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_req->msg_len = req->len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_req->msg_buf = (caddr_t)req->data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (resp != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_type = resp->type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_len = resp->len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_buf = (caddr_t)resp->data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_bytes = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_type = DP_NULL_MSG;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_resp->msg_bytes = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (timeout == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr.wait_time = RR_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr.wait_time = timeout->tv_sec * 1000 +
03831d35f7499c87d51205817c93e9a8d42c4baestevel timeout->tv_nsec / 1000000;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr.status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_REQUEST_RESPONSE, &rr) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_send_recv: req. failed, status=%d errno=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_req->msg_type, rr.status, errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * function used to look up at the request/response table. Given a request
03831d35f7499c87d51205817c93e9a8d42c4baestevel * type, will return a record which provides the following information:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * response expected and a timeout value
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic req_resp_table_t *
03831d35f7499c87d51205817c93e9a8d42c4baestevelrsc_lookup_rr_table(req_resp_table_t *rr_table, int cnt, rsci8 type)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("lookup for type %x, count %d\n", type, cnt);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < cnt; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rr_table[i].req_type == type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rr_table + i);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * function to check if a message type is in the list of unsupported commands
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If so, will return 1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelrsc_check_unsupported_cmd(rsci8 type)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < unsupported_cmds_cnt; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (unsupported_cmds[i] == type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Returns 1 if ALOM will generate a response to the given command code,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * otherwise it returns 0. If a command is not in the following list,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and the protocol version is 2 or less, then ALOM will not generate
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a response to the command. This causes the driver to time out,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and we want to avoid that situation.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int
03831d35f7499c87d51205817c93e9a8d42c4baestevelrsc_cmd_response_guaranteed(rsci8 type)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (type) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_ALARM_STATE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_CFGVAR:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_CFGVAR_NAME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_CIRCUIT_BRKS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_DATE_TIME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_DEVICE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_EVENT_LOG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_FAN_STATUS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_FRU_STATUS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_HANDLE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_HANDLE_NAME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_LED_STATE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_NETWORK_CFG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_PCMCIA_INFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_PSU_STATUS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_SDP_VERSION:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_SYSINFO:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_TEMP:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_TEMPERATURES:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_TICKCNT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_TOD_CLOCK:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_USER_WATCHDOG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_GET_VOLTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_MODEM_CONNECT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_MODEM_DATA:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_MODEM_DISCONNECT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_RESET_RSC:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_RMC_EVENTS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_RSC_STATUS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_RUN_TEST:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SEND_ALERT:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_ALARM_STATE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_CFGVAR:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_CPU_SIGNATURE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_DATE_TIME:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_DEFAULT_CFG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_HOST_WATCHDOG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_LED_STATE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_SET_USER_WATCHDOG:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_UPDATE_FLASH:
03831d35f7499c87d51205817c93e9a8d42c4baestevel case DP_USER_ADM:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (sdp_version >= SDP_RESPONDS_TO_ALL_CMDS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * RSC hard reset. Returns 0 on success, non-zero on error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrsc_nmi(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_RESET_SP, NULL) < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * functions used (exclusively) for the firmware download
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Call this routine to register a callback that will be called by the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * generic data protocol routines when a boot protocol message is
03831d35f7499c87d51205817c93e9a8d42c4baestevel * received. Only one of these routines may be registered at a time.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Note that receiving a boot protocol message has the effect of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * re-initializing the data protocol. Returns 0 on success, or non-
03831d35f7499c87d51205817c93e9a8d42c4baestevel * zero on failure.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_register_bpmsg_cb(rscp_bpmsg_cb_t *cb)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bpmsg_cb == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg_cb = cb;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EALREADY);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This routine un-registers a boot protocol message callback.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_unregister_bpmsg_cb(rscp_bpmsg_cb_t *cb)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bpmsg_cb == cb) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg_cb = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINPROGRESS);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Call this routine to send a boot protocol message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_send_bpmsg(bp_msg_t *bpmsg)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_request_response_t rr_bp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_msg_t *req_bp = &rr_bp.req;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_msg_t *resp_bp = &rr_bp.resp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_resp_table_t *rr_bp_item;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bp_msg_t bpmsg_reply;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0 || bpmsg == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * get the timeout value
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rr_bp_item = rsc_lookup_rr_table(rr_bp_table, rr_bp_table_cnt,
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg->cmd)) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_bp.wait_time = rr_bp_item->timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_bp.wait_time = RR_BP_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr_bp.status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_bp->msg_len = sizeof (bp_msg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_bp->msg_buf = (caddr_t)bpmsg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rr_bp.wait_time == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp_bp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp_bp->msg_len = sizeof (bp_msg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp_bp->msg_buf = (caddr_t)&bpmsg_reply;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("send BP cmd %x, expect reply %x/%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg->cmd, resp_bp->msg_buf, resp_bp->msg_len);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_REQUEST_RESPONSE_BP, &rr_bp) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_send_bpmsg: BP cmd %x failed status=%d "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "errno=%d\n", bpmsg->cmd, rr_bp.status, errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("got BP reply type=%x,%x,%x\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg_reply.cmd, bpmsg_reply.dat1, bpmsg_reply.dat2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply received. call the registered callback (if any)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bpmsg_cb != NULL && resp_bp->msg_buf != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg_cb(&bpmsg_reply);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Write raw characters to the RSC control device. Returns 0 on success,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * non-zero on error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrsc_raw_write(char *buf, int nbytes)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_send_srecord_bp_t srec_bp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bp_msg_t bpmsg_reply;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.data_len = (uint_t)nbytes;
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.data_buf = (caddr_t)buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.resp_bp.msg_len = sizeof (bp_msg_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.resp_bp.msg_buf = (caddr_t)&bpmsg_reply;
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.wait_time = RR_BOOT_LOAD_TIMEOUT;
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("send srecord BP len=%d\n", nbytes);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_SEND_SRECORD_BP, &srec_bp) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rsc_raw_write: failed. status=%d ioctl error=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel srec_bp.status, errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("got BP reply type=%x\n", bpmsg_reply.cmd);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply received. call the registered callback (if any)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bpmsg_cb != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg_cb(&bpmsg_reply);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * obsolete functions provided for backward compatibility
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is obsolete and it is provided for backward compatibility.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (no-op function). It was used to start up the data protocol. low-level
03831d35f7499c87d51205817c93e9a8d42c4baestevel * protocol has moved to the kernel and the rmc_comm driver is responsible
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for setting up the data protocol.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (obsolete)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_start(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is obsolete and it is provided for backward compatibility.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Previously, rscp_send() and rscp_recv() where used to send a request and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * read a reply respectively. Now, rscp_send_recv() should be used instead
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (request/response in one call).
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This is used to send a message by making an RMCADM_REQUEST_RESPONSE ioctl
03831d35f7499c87d51205817c93e9a8d42c4baestevel * call. A lookup table (rr_table) is used to find out the expected reply
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (if any) and the timeout value for a message to be sent. The reply is then
03831d35f7499c87d51205817c93e9a8d42c4baestevel * stored in a buffer (rsc_rx_buffer) to be returned by calling rscp_recv()
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_send(rscp_msg_t *msgp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_request_response_t rr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_msg_t *req = &rr.req;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rmcadm_msg_t *resp = &rr.resp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req_resp_table_t *rr_item;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sanity check
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (msgp == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if the command is actually supported
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if not, return an error
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_check_unsupported_cmd(msgp->type) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if this command will generate a response and if it will not,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return an error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!rsc_cmd_response_guaranteed(msgp->type))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * init rx buffer
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel req->msg_type = msgp->type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req->msg_len = msgp->len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel req->msg_buf = msgp->data;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rr_item = rsc_lookup_rr_table(rr_table, rr_table_cnt,
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->type)) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_type = rr_item->resp_type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rr_item->resp_type == DP_NULL_MSG) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * no reply expected. so, no reply buffer needed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (set to NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_len = RSC_MAX_RX_BUFFER;
03831d35f7499c87d51205817c93e9a8d42c4baestevel resp->msg_buf = (caddr_t)rsc_rx_buffer;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr.wait_time = rr_item->timeout;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_type = rr_item->resp_type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (ENOTSUP);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr.status = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("request/response %x/%x\n", req->msg_type, resp->msg_type);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_REQUEST_RESPONSE, &rr) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_send: req %x failed, status=%d errno=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel rr.req.msg_type, rr.status, errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_error = errno;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (errno);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply received. get the number of bytes effectively returned
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_len = resp->msg_bytes;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_type = resp->msg_type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("got reply type=%x len=%d\n", rsc_rx_resp_type, rsc_rx_resp_len);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is obsolete and it is provided for backward compatibility
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Previously, rscp_send() and rscp_recv() where used to send a request and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * read a reply repectively. Now, rscp_send_recv() should be used instead
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (request/response in one call).
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function returns the reply received when a request was previously sent
03831d35f7499c87d51205817c93e9a8d42c4baestevel * using the rscp_send() function (stored in the rsc_rx_buffer buffer). If a
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply was not received, then an error is returned.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * timeout parameter is declared for backward compatibility but it is not used.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_recv(rscp_msg_t *msgp, struct timespec *timeout)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int err = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sanity check
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (msgp == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EINVAL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_rx_error < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->type = DP_NULL_MSG;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->data = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = rsc_rx_error;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->type = rsc_rx_resp_type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->len = rsc_rx_resp_len;
03831d35f7499c87d51205817c93e9a8d42c4baestevel msgp->data = rsc_rx_buffer;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("read reply. type=%x, err=%d\n", msgp->type, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_len = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_error = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel rsc_rx_resp_type = DP_NULL_MSG;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * used to free up a (received) message. no-op function
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_free_msg(rscp_msg_t *msgp)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (rsc_fd < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (EBADF);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}