cfga_sata.c revision d3080269c400bce011f72255205cee37b5b04079
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CDDL HEADER START
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The contents of this file are subject to the terms of the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Common Development and Distribution License (the "License").
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * You may not use this file except in compliance with the License.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * See the License for the specific language governing permissions
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and limitations under the License.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * When distributing Covered Code, include this CDDL HEADER in each
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If applicable, add the following below this CDDL HEADER, with the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * fields enclosed by brackets "[]" replaced with your own identifying
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * information: Portions Copyright [yyyy] [name of copyright owner]
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CDDL HEADER END
724365f7556fc4201fdb11766ebc6bd918523130sethg * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Use is subject to license terms.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#pragma ident "%Z%%M% %I% %E% SMI"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This file contains the entry points to the plug-in as defined in the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * config_admin(3X) man page.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Set the version number for the cfgadm library's use.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* SATA specific help messages */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic char *sata_help[] = {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "SATA specific commands:\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -c [configure|unconfigure|disconnect|connect] ap_id "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "[ap_id...]\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -x sata_reset_port ap_id [ap_id...]\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -x sata_reset_device ap_id [ap_id...]\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -x sata_reset_all ap_id\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -x sata_port_deactivate ap_id [ap_id...]\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -x sata_port_activate ap_id [ap_id...]\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -x sata_port_self_test ap_id [ap_id...]\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " cfgadm -t ap_id\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "\tunknown command or option:\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}; /* End help messages */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Messages.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_OK */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_NACK */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_DEVICE_UNCONFIGURED */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_OK, "Device unconfigured prior to disconnect" },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_UNKNOWN / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_LIB_ERROR, "Unknown message; internal error" },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_INTERNAL_ERROR / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_DATA_ERROR / CFGA_DATA_ERROR -> "Data error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_OPTIONS / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_ERROR, "Hardware specific option not supported" },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_HWOPNOTSUPP / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_ERROR, "Hardware specific operation not supported" },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_DYNAMIC_AP /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_LIB_ERROR -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_AP / CFGA_APID_NOEXIST -> "Attachment point not found" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_PORT / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_LIB_ERROR, "Cannot determine sata port number for " },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_DEVCTL / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Cannot allocate devctl handle " },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_DEV_CONFIGURE /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_ERROR -> "Hardware specific failure"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_DEV_UNCONFIGURE /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_ERROR -> "Hardware specific failure"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_DISCONNECTED
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_INVAL -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_NOT_CONNECTED
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_INVAL -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_NOT_CONFIGURED /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_INVAL -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_ALREADY_CONNECTED /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_INVAL -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_ALREADY_CONFIGURED /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_INVAL -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_INVALID_DEVNAME /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_INVAL -> "Configuration operation invalid"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_OPEN / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_IOCTL / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_BUSY /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SYSTEM_BUSY -> "System is busy, try again"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_ALLOC_FAIL / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_OPNOTSUPP /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_OPNOTSUPP -> "Configuration operation not supported"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_DEVLINK / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_LIB_ERROR, "Could not find /dev/cfg link for " },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_STATE / CFGA_LIB_ERROR -> "Library error" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_LIB_ERROR, "Internal error: Unrecognized ap state" },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_PRIV / CFGA_PRIV -> "Insufficient privileges" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_NVLIST / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_ZEROLEN / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf { CVT, CFGA_ERROR, "Internal error (zerolength string)" },
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_RCM_HANDLE / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_RCM_ONLINE /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SYSTEM_BUSY -> "System is busy, try again"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SATA_RCM_OFFLINE /
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CFGA_SYSTEM_BUSY -> "System is busy, try again"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* CFGA_SATA_RCM_INFO / CFGA_ERROR -> "Hardware specific failure" */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf}; /* End error messages */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfverify_params(const char *ap_id, const char *options, char **errstring);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsetup_for_devctl_cmd(const char *ap_id, devctl_hdl_t *devctl_hdl,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfdo_control_ioctl(const char *ap_id, sata_cfga_apctl_t subcommand, uint_t arg,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfcleanup_after_devctl_cmd(devctl_hdl_t devctl_hdl, nvlist_t *user_nvlist);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic char *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* Utilities */
724365f7556fc4201fdb11766ebc6bd918523130sethgphyspath_to_devlink(const char *basedir, const char *node_path,
724365f7556fc4201fdb11766ebc6bd918523130sethg * Using libdevinfo for this is overkill and kills performance
724365f7556fc4201fdb11766ebc6bd918523130sethg * when multiple consumers of libcfgadm are executing
724365f7556fc4201fdb11766ebc6bd918523130sethg * concurrently.
724365f7556fc4201fdb11766ebc6bd918523130sethg sizeof (struct dirent);
724365f7556fc4201fdb11766ebc6bd918523130sethg while (!found && (err = readdir_r(dp, dep, &newdep)) == 0 &&
724365f7556fc4201fdb11766ebc6bd918523130sethg * realpath() is too darn slow, so fake
724365f7556fc4201fdb11766ebc6bd918523130sethg * it, by using what we know about /dev
724365f7556fc4201fdb11766ebc6bd918523130sethg * links: they are always of the form:
724365f7556fc4201fdb11766ebc6bd918523130sethg * <"../">+/devices/<path>
724365f7556fc4201fdb11766ebc6bd918523130sethg p--; /* back up to get a slash */
724365f7556fc4201fdb11766ebc6bd918523130sethg if (err != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Given the index into a table (msgcvt_t) of messages, get the message
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * string, converting it to the proper locale if necessary.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOTE: Indexes are defined in cfga_sata.h
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic const char *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfget_msg(uint_t msg_index, msgcvt_t *msg_tbl, uint_t tbl_size)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocates and creates a message string (in *ret_str),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * by concatenating all the (char *) args together, in order.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Last arg MUST be NULL.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *ret_str = (char *)realloc(*ret_str, total_len + len + 1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We're screwed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Error message handling.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For the rv passed in, looks up the corresponding error message string(s),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * internationalized if necessary, and concatenates it into a new
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * memory buffer, and points *errstring to it.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note not all rvs will result in an error message return, as not all
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * error conditions warrant a SATA-specific error message - for those
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * conditions the cfgadm generic messages are sufficient.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Some messages may display ap_id or errno, which is why they are passed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Generate the appropriate SATA-specific error message(s) (if any).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (rv) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Special case - do nothing. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* These messages require no additional strings passed. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* hardware-specific help needed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf set_msg(errstring, sata_help[HELP_PORT_ACTIVATE], NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf set_msg(errstring, sata_help[HELP_PORT_DEACTIVATE], NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf set_msg(errstring, sata_help[HELP_PORT_SELF_TEST], NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf set_msg(errstring, sata_help[HELP_CNTRL_SELF_TEST], NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* These messages also print ap_id. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf set_msg(errstring, ERR_STR(rv), "ap_id: ", ap_id, "", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* These messages also print errno. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* These messages also apid and errno. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf set_msg(errstring, ERR_STR(CFGA_SATA_INTERNAL_ERROR), NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } /* end switch */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Determine the proper error code to send back to the cfgadm library.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Entry points
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* cfgadm entry point */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *options,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All sub-commands which can change state of device require
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * root privileges.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (geteuid() != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = verify_params(ap_id, options, errstring)) != CFGA_SATA_OK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Disallow dynamic AP name component */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Try for some time as SATA hotplug thread
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * takes a while to create the path then
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * eventually give up.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Strip off AP name dynamic component, if present */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "cfga_change_state: get device path failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = sata_rcm_offline(ap_id, errstring, devpath, flags))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ret != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Strip off AP name dynamic component, if present */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port originally with device attached and was
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * unconfigured already, the devicepath for the sd will be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * removed. sata_get_devicepath in this case is not necessary.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* only call rcm_offline if the state was CONFIGURED */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "cfga_change_state: get path failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Disconnect"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ret != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "devctl_ap_unconfigure failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The current policy is that if unconfigure
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * failed, do not continue with disconnect.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If the port needs to be forced into the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * disconnect (shutdown) state,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the -x sata_port_poweroff command should be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * used instead of -c disconnect
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Disconnect"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ret != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Disallow dynamic AP name component */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ret != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* cfgadm entry point */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *func,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *options,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = verify_params(ap_id, NULL, errstring)) != CFGA_SATA_OK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All subcommands which can change state of device require
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * root privileges.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (geteuid() != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = setup_for_devctl_cmd(ap_id, &hdl, &list, 0)) !=
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We do not care here about dynamic AP name component */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rv = do_control_ioctl(ap_id, SATA_CFGA_RESET_PORT, NULL,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Reset device function requires device to be connected
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rv = do_control_ioctl(ap_id, SATA_CFGA_RESET_DEVICE, NULL,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rv = do_control_ioctl(ap_id, SATA_CFGA_PORT_DEACTIVATE, NULL,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf " %s%s\n%s",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unrecognized operation request */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* cfgadm entry point */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *options,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Should call ioctl for self test - phase 2 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf minorpath = di_devfs_minor_path(di_minor_next(node, DI_MINOR_NIL));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The dynamic component buffer returned by this function has to be freed!
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Get target node path
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) printf("cfga_list_ext: cannot locate target device\n");
724365f7556fc4201fdb11766ebc6bd918523130sethg * Using libdevinfo for this is overkill and kills
724365f7556fc4201fdb11766ebc6bd918523130sethg * performance when many consumers are using libcfgadm
724365f7556fc4201fdb11766ebc6bd918523130sethg * concurrently.
724365f7556fc4201fdb11766ebc6bd918523130sethg * deplen is large enough to fit the largest path-
724365f7556fc4201fdb11766ebc6bd918523130sethg * struct dirent includes one byte (the terminator)
724365f7556fc4201fdb11766ebc6bd918523130sethg * so we don't add 1 to the calculation here.
724365f7556fc4201fdb11766ebc6bd918523130sethg sizeof (struct dirent);
724365f7556fc4201fdb11766ebc6bd918523130sethg * If there was an error, or we didn't exit the loop
724365f7556fc4201fdb11766ebc6bd918523130sethg * by finding a block or character device, bail out.
724365f7556fc4201fdb11766ebc6bd918523130sethg * Look for links to the physical path in /dev/dsk,
724365f7556fc4201fdb11766ebc6bd918523130sethg * since we ONLY looked for BLOCK devices above.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* postprocess and copy logical name here */
545e5dad7996785cfebf226c5ef410c1b154740fsethg * For disks, remove partition/slice info
545e5dad7996785cfebf226c5ef410c1b154740fsethg /* cXtYdZ[(s[0..15])|(p[0..X])] */
545e5dad7996785cfebf226c5ef410c1b154740fsethg p++; /* Skip the 'd' */
545e5dad7996785cfebf226c5ef410c1b154740fsethg while (*p != 0 && isdigit(*p))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* cfgadm entry point */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/*ARGSUSED*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *options,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *listopts,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = verify_params(ap_id, options, errstring)) != CFGA_SATA_OK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We do not care here about dynamic AP name component */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Get ap status */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = setup_for_devctl_cmd(ap_id, &devctl_hdl, &user_nvlist,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* will call dc_cmd to send IOCTL to kernel */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Create cfga_list_data_t struct.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (cfga_list_data_t *)malloc(sizeof (**ap_id_list))) == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Rest of the code fills in the cfga_list_data_t struct.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Get /dev/cfg path to corresponding to the physical ap_id */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Remember ap_id_log must be freed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (rv != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Get logical ap_id corresponding to the physical */
20e7b521b938d6074a4b93c9c2f69c6281a26e3asethg if (ap_id_log == NULL || strstr(ap_id_log, CFGA_DEV_DIR) == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Strip off /dev/cfg/ */ ap_id_log + strlen(CFGA_DEV_DIR)+ 1,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (*ap_id_list)->ap_class[0] = '\0'; /* Filled by libcfgadm */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (*ap_id_list)->ap_busy = devctl_ap_state.ap_in_transition;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (*ap_id_list)->ap_status_time = devctl_ap_state.ap_last_change;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fill in the 'Information' field for the -v option
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Model (MOD:)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = do_control_ioctl(ap_id, SATA_CFGA_GET_MODEL_INFO,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "SATA_CFGA_GET_MODULE_INFO ioctl failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* drop leading and trailing spaces */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fill in the 'Information' field for the -v option
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Firmware revision (FREV:)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "SATA_CFGA_GET_REVFIRMWARE_INFO ioctl failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* drop leading and trailing spaces */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fill in the 'Information' field for the -v option
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Serial Number (SN:)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "SATA_CFGA_GET_SERIALNUMBER_INFO ioctl failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* drop leading and trailing spaces */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Fill in ap_type which is collected from HBA driver */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* call do_control_ioctl TBD */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = do_control_ioctl(ap_id, SATA_CFGA_GET_AP_TYPE, NULL,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "SATA_CFGA_GET_AP_TYPE ioctl failed\n");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((*ap_id_list)->ap_o_state == CFGA_STAT_CONFIGURED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This is the case where we need to generate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a dynamic component of the ap_id, i.e. device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Change it when port multiplier is supported */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This routine accepts a string adn prints it using
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the message print routine argument.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* cfgadm entry point */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* ARGSUSED */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfcfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cfga_msg(msgp, dgettext(TEXT_DOMAIN, sata_help[HELP_UNKNOWN]));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cfga_msg(msgp, dgettext(TEXT_DOMAIN, sata_help[HELP_HEADER]));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Ensure the ap_id passed is in the correct (physical ap_id) form:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * where xx is a one or two-digit number.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note the library always calls the plugin with a physical ap_id.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (strspn(l_ap_id, "0123456789.") != strlen(l_ap_id)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Bad characters in the ap_id */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* ap_id has 1..2 or more than 2 dots */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Verify the params passed in are valid.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *options,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Strip dynamic AP name component if it is present. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Takes a validated ap_id and extracts the port number.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For now, we do not support port multiplier port .
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint32_t pmport = 0; /* port multiplier not supported yet */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int pmport_qual = 0; /* port multiplier not supported yet */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf port_nbr_str = strrchr(ap_id, (int)*MINOR_SEP) + strlen(MINOR_SEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((temp = strrchr(ap_id, (int)*PORT_SEPARATOR)) != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *port = cport + (pmport << SATA_CFGA_PMPORT_SHIFT) + pmport_qual;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Pair of routines to set up for/clean up after a devctl_ap_* lib call.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfcleanup_after_devctl_cmd(devctl_hdl_t devctl_hdl, nvlist_t *user_nvlist)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_id,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Get a devctl handle to pass to the devctl_ap_XXX functions */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((*devctl_hdl = devctl_ap_acquire((char *)lap_id, oflag)) == NULL) {
724365f7556fc4201fdb11766ebc6bd918523130sethg "setup_for_devctl_cmd: devctl_ap_acquire failed: %s\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Set up nvlist to pass the port number down to the driver */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (nvlist_alloc(user_nvlistp, NV_UNIQUE_NAME_TYPE, NULL) != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Get port id, for Port Multiplier port, things could be a little bit
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * complicated because of "port.port" format in ap_id, thus for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port multiplier port, port number should be coded as 32bit int
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * with the sig 16 bit as sata channel number, least 16 bit as
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the port number of sata port multiplier port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = get_port_num(lap_id, &port)) != CFGA_SATA_OK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "setup_for_devctl_cmd: get_port_num, errno: %d\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Creates an int32_t entry */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (nvlist_add_int32(*user_nvlistp, PORT, port) == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) cleanup_after_devctl_cmd(*devctl_hdl, *user_nvlistp);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (devctl_ap_getstate(hdl, list, &devctl_ap_state) == -1) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) printf("devctl_ap_getstate failed, errno: %d\n", errno);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Given a subcommand to the DEVCTL_AP_CONTROL ioctl, rquest the size of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the data to be returned, allocate a buffer, then get the data.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns *descrp (which must be freed) and size.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note SATA_DESCR_TYPE_STRING returns an ASCII NULL-terminated string,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * not a string descr.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfdo_control_ioctl(const char *ap_id, sata_cfga_apctl_t subcommand, uint_t arg,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rv = get_port_num(ap_id, &port)) != CFGA_SATA_OK) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (void) printf("do_control_ioctl: open failed: errno:%d\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Find out how large a buf we need to get the data.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note the ioctls only accept/return a 32-bit int for a get_size
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to avoid 32/64 and BE/LE issues.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Execute IOCTL */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic char *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rv = do_control_ioctl(ap_id, SATA_CFGA_GET_DEVICE_PATH, NULL,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return ((char *)NULL);