03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
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 * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ENXS platform-specific functions
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* rmcadm driver file descriptor */
03831d35f7499c87d51205817c93e9a8d42c4baestevel * librsc receive buffer - it is used as temporary buffer to store replies
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from the remote side
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Registered boot-protocol message callback routine. This routine will be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * called whenever a boot protocol message is received.
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* lookup table to match request and response . This is in order to support */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* obsolete functions (rscp_send, rscp_recv) */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic const int rr_table_cnt = sizeof (rr_table) / sizeof (rr_table[0]);
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) */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic rsci8 unsupported_cmds[] = { DP_SET_DATE_TIME };
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int unsupported_cmds_cnt = sizeof (unsupported_cmds) /
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Protocol version number, used to determine whether ALOM will
03831d35f7499c87d51205817c93e9a8d42c4baestevel * time out on unknown commands.
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* function prototypes */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic req_resp_table_t *rsc_lookup_rr_table(req_resp_table_t *, int, rsci8);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize the generic librsc data protocol routines. basically, it
03831d35f7499c87d51205817c93e9a8d42c4baestevel * open the rmcadm (pseudo) device and initialize data
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 'erase' the rx buffer
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) memset(rsc_rx_buffer, 0, sizeof (RSC_MAX_RX_BUFFER));
03831d35f7499c87d51205817c93e9a8d42c4baestevel * open rmcadm driver
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_init: Error opening %s, error code = %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Fetch the protocol version number in use between the host
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and ALOM.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((errno = rscp_send_recv(&request, &response, 0)) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_init: sdp version number is %d\n", sdp_version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
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
03831d35f7499c87d51205817c93e9a8d42c4baestevelrscp_send_recv(rscp_msg_t *req, rscp_msg_t *resp, struct timespec *timeout)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the request is required, it should not be NULL!
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if the command is actually supported
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if not, return an error
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if this command will generate a response and if it will not,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return an error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_REQUEST_RESPONSE, &rr) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_send_recv: req. failed, status=%d errno=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
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
03831d35f7499c87d51205817c93e9a8d42c4baestevelrsc_lookup_rr_table(req_resp_table_t *rr_table, int cnt, rsci8 type)
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < cnt; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (rr_table + i);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * function to check if a message type is in the list of unsupported commands
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If so, will return 1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < unsupported_cmds_cnt; i++)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
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 return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * RSC hard reset. Returns 0 on success, non-zero on error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * functions used (exclusively) for the firmware download
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 return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This routine un-registers a boot protocol message callback.
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Call this routine to send a boot protocol message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * get the timeout value
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rr_bp_item = rsc_lookup_rr_table(rr_bp_table, rr_bp_table_cnt,
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_REQUEST_RESPONSE_BP, &rr_bp) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_send_bpmsg: BP cmd %x failed status=%d "
03831d35f7499c87d51205817c93e9a8d42c4baestevel bpmsg_reply.cmd, bpmsg_reply.dat1, bpmsg_reply.dat2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply received. call the registered callback (if any)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Write raw characters to the RSC control device. Returns 0 on success,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * non-zero on error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_SEND_SRECORD_BP, &srec_bp) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rsc_raw_write: failed. status=%d ioctl error=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply received. call the registered callback (if any)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * obsolete functions provided for backward compatibility
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 return (0);
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 * 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 * sanity check
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if the command is actually supported
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if not, return an error
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check if this command will generate a response and if it will not,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return an error.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * init rx buffer
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((rr_item = rsc_lookup_rr_table(rr_table, rr_table_cnt,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * no reply expected. so, no reply buffer needed
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (set to NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("request/response %x/%x\n", req->msg_type, resp->msg_type);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(rsc_fd, RMCADM_REQUEST_RESPONSE, &rr) < 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("rscp_send: req %x failed, status=%d errno=%d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel * reply received. get the number of bytes effectively returned
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("got reply type=%x len=%d\n", rsc_rx_resp_type, rsc_rx_resp_len);
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
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 * 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 * timeout parameter is declared for backward compatibility but it is not used.
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel * sanity check
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("read reply. type=%x, err=%d\n", msgp->type, err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel * used to free up a (received) message. no-op function
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);