5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * CDDL HEADER START
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * The contents of this file are subject to the terms of the
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * Common Development and Distribution License (the "License").
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * You may not use this file except in compliance with the License.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * or http://www.opensolaris.org/os/licensing.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * See the License for the specific language governing permissions
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * and limitations under the License.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * When distributing Covered Code, include this CDDL HEADER in each
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * If applicable, add the following below this CDDL HEADER, with the
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * fields enclosed by brackets "[]" replaced with your own identifying
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * information: Portions Copyright [yyyy] [name of copyright owner]
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * CDDL HEADER END
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * Use is subject to license terms.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * ses (SCSI Generic Device) specific functions.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <libnvpair.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <stdio.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <stdlib.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <unistd.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <sys/types.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <sys/sysmacros.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <sys/queue.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <fcntl.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <string.h>
c4800545504378963d9f2eeb253f06899664f9f6jmcp#include <scsi/libscsi.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <scsi/libses.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <libintl.h> /* for gettext(3c) */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#include <fwflash/fwflash.h>
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define VIDLEN 0x08
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define PIDLEN 0x10
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define REVLEN 0x04
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define SASADDRLEN 0x10
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define PCBUFLEN 0x40
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define RQBUFLEN 0xfe
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define STATBUFLEN 0xfe
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define INQBUFLEN 0x80
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/* useful defines */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define UCODE_CHECK_STATUS 0
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define UCODE_CHECK_SUPPORTED 1
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcptypedef struct ucode_statdesc {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uint64_t us_value;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp const char *us_desc;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp boolean_t us_pending;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp boolean_t us_iserr;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp} ucode_statdesc_t;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpstatic ucode_statdesc_t ucode_statdesc_table[] = {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_NOP, "none", B_FALSE, B_FALSE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_INPROGRESS, "in progress", B_TRUE, B_FALSE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_SAVING, "saved", B_TRUE, B_FALSE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_COMPLETE_NOW, "completed (available)", B_FALSE,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_COMPLETE_AT_RESET,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "completed (need reset or power on)", B_FALSE, B_FALSE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_COMPLETE_AT_POWERON, "completed (need power on)",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE, B_FALSE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_PAGE_ERR, "page error (offset %d)",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE, B_TRUE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_IMAGE_ERR, "invalid image",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE, B_TRUE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_TIMEOUT, "download timeout",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE, B_TRUE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_INTERNAL_NEEDIMAGE,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "internal error (NEED NEW IMAGE BEFORE RESET)",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE, B_TRUE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp { SES2_DLUCODE_S_INTERNAL_SAFE,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "internal error (reset to revert to backup)",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp B_FALSE, B_TRUE },
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp};
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp#define NUCODE_STATUS \
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (sizeof (ucode_statdesc_table) / sizeof (ucode_statdesc_table[0]))
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcptypedef struct ucode_status {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uint64_t us_status;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp boolean_t us_iserr;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp boolean_t us_pending;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp char us_desc[128];
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp} ucode_status_t;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcptypedef struct ucode_wait {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uint64_t uw_prevstatus;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp boolean_t uw_pending;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ses_node_t *uw_oldnp;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp} ucode_wait_t;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcptypedef struct sam4_statdesc {
c4800545504378963d9f2eeb253f06899664f9f6jmcp int status;
c4800545504378963d9f2eeb253f06899664f9f6jmcp char *message;
c4800545504378963d9f2eeb253f06899664f9f6jmcp} sam4_statdesc_t;
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic sam4_statdesc_t sam4_status[] = {
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_GOOD, "Status: GOOD (success)" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_CHECK_CONDITION, "Status: CHECK CONDITION" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_CONDITION_MET, "Status: CONDITION MET" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_BUSY, "Status: Device is BUSY" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_RESERVATION_CONFLICT, "Status: Device is RESERVED" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_TASK_SET_FULL,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "Status: TASK SET FULL (insufficient resources in command queue" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { SAM4_STATUS_TASK_ABORTED, "Status: TASK ABORTED" },
c4800545504378963d9f2eeb253f06899664f9f6jmcp { NULL, NULL }
c4800545504378963d9f2eeb253f06899664f9f6jmcp};
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp#define NSAM4_STATUS \
c4800545504378963d9f2eeb253f06899664f9f6jmcp (sizeof (sam4_status) / sizeof (sam4_status[0]))
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpchar drivername[] = "ses\0";
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpstatic char *devprefix = "/devices";
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic char *sessuffix = ":0";
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic char *sgensuffix = ":ses";
c4800545504378963d9f2eeb253f06899664f9f6jmcp
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic ses_target_t *ses_target;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpextern di_node_t rootnode;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpextern int errno;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpextern struct fw_plugin *self;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpextern struct vrfyplugin *verifier;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpextern int fwflash_debug;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/* required functions for this plugin */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint fw_readfw(struct devicelist *device, char *filename);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint fw_writefw(struct devicelist *device);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint fw_identify(int start);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint fw_devinfo(struct devicelist *thisdev);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/* helper functions */
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChenstatic int print_updated_status(ses_node_t *np, void *arg);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpstatic int get_status(nvlist_t *props, ucode_status_t *sp);
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic int sendimg(ses_node_t *np, void *data);
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic int scsi_writebuf();
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*
c4800545504378963d9f2eeb253f06899664f9f6jmcp * We don't currently support reading firmware from a SAS
c4800545504378963d9f2eeb253f06899664f9f6jmcp * expander. If we do eventually support it, we would use
c4800545504378963d9f2eeb253f06899664f9f6jmcp * the scsi READ BUFFER command to do so.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpfw_readfw(struct devicelist *flashdev, char *filename)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "%s: not writing firmware for device %s to file %s\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname, flashdev->access_devname, filename);
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("\n\nReading of firmware images from %s-attached "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "devices is not supported\n\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_SUCCESS);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * If we're invoking fw_writefw, then flashdev is a valid,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * flashable device supporting the SES2 Download Microcode Diagnostic
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * Control page (0x0e).
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * If verifier is null, then we haven't been called following a firmware
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * image verification load operation.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * *THIS* function uses scsi SEND DIAGNOSTIC/download microcode to
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * achieve the task... if you chase down to the bottom of libses you
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * can see that too.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpfw_writefw(struct devicelist *flashdev)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen int rv = FWFLASH_FAILURE;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp nvlist_t *nvl;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ses_snap_t *snapshot;
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_node_t *targetnode;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((verifier == NULL) || (verifier->imgsize == 0) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (verifier->fwimage == NULL)) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp /* should _not_ happen */
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Firmware image has not "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "been verified.\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp nvlist_add_uint64(nvl, SES_CTL_PROP_UCODE_MODE,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp SES_DLUCODE_M_WITH_OFFS) != 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to allocate "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "space for device prop list\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp fprintf(stdout, "\n"); /* get a fresh line for progress updates */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (nvlist_add_uint64(nvl, SES_CTL_PROP_UCODE_BUFID,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp verifier->flashbuf) != 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to add buffer id "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "property, hence unable to flash device\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp goto cancel;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (nvlist_add_byte_array(nvl, SES_CTL_PROP_UCODE_DATA,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (uint8_t *)verifier->fwimage, verifier->imgsize) != 0) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_ERROR,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "%s: Out of memory for property addition\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp goto cancel;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if ((ses_target =
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ses_open(LIBSES_VERSION, flashdev->access_devname)) == NULL) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to open flashable device %s\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname, flashdev->access_devname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp goto cancel;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp snapshot = ses_snap_hold(ses_target);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((targetnode = ses_snap_primary_enclosure(snapshot)) == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to locate primary enclosure for "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "device %s\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp } else {
c4800545504378963d9f2eeb253f06899664f9f6jmcp rv = sendimg(targetnode, nvl);
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (rv == FWFLASH_SUCCESS) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Done. New image will be active "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "after the system is rebooted.\n\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp } else {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "%s: unable to flash image %s to device %s\n\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->drvname, verifier->imgfile,
c4800545504378963d9f2eeb253f06899664f9f6jmcp flashdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ses_snap_rele(snapshot);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ses_close(ses_target);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpcancel:
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp nvlist_free(nvl);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (rv);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * The fw_identify() function walks the device
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * tree trying to find devices which this plugin
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * can work with.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * The parameter "start" gives us the starting index number
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * to give the device when we add it to the fw_devices list.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp *
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp * firstdev is allocated by us and we add space as needed
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpfw_identify(int start)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp int rv = FWFLASH_FAILURE;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp di_node_t thisnode;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp struct devicelist *newdev;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp char *devpath;
c4800545504378963d9f2eeb253f06899664f9f6jmcp char *devsuffix;
c4800545504378963d9f2eeb253f06899664f9f6jmcp char *driver;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp int idx = start;
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson size_t devlength = 0;
c4800545504378963d9f2eeb253f06899664f9f6jmcp nvlist_t *props;
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_snap_t *snapshot;
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_node_t *rootnodep, *nodep;
c4800545504378963d9f2eeb253f06899664f9f6jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (strcmp(self->drvname, "sgen") == 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp devsuffix = sgensuffix;
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver = self->drvname;
c4800545504378963d9f2eeb253f06899664f9f6jmcp } else {
c4800545504378963d9f2eeb253f06899664f9f6jmcp devsuffix = sessuffix;
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver = drivername;
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp thisnode = di_drv_first_node(driver, rootnode);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (thisnode == DI_NODE_NIL) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_INFO, gettext("No %s nodes in this system\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver);
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if ((devpath = calloc(1, MAXPATHLEN + 1)) == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to allocate space "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "for a device node\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver);
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp /* we've found one, at least */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp for (; thisnode != DI_NODE_NIL; thisnode = di_drv_next_node(thisnode)) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp devpath = di_devfs_path(thisnode);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if ((newdev = calloc(1, sizeof (struct devicelist)))
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp == NULL) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: identification function unable "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "to allocate space for device entry\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp /* calloc enough for /devices + devpath + devsuffix + '\0' */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp devlength = strlen(devpath) + strlen(devprefix) +
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp strlen(devsuffix) + 2;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if ((newdev->access_devname = calloc(1, devlength)) == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to allocate "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "space for a devfs name\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(devpath);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp snprintf(newdev->access_devname, devlength,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "%s%s%s", devprefix, devpath, devsuffix);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((newdev->drvname = calloc(1, strlen(driver) + 1))
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to allocate "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "space to store a driver name\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->access_devname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp (void) strlcpy(newdev->drvname, driver,
c4800545504378963d9f2eeb253f06899664f9f6jmcp strlen(driver) + 1);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((newdev->classname = calloc(1, strlen(driver) + 1))
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to malloc "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "space for a class name\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp drivername);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->access_devname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp (void) strlcpy(newdev->classname, driver,
c4800545504378963d9f2eeb253f06899664f9f6jmcp strlen(driver) + 1);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp /*
c4800545504378963d9f2eeb253f06899664f9f6jmcp * Only alloc as much as we truly need, and DON'T forget
c4800545504378963d9f2eeb253f06899664f9f6jmcp * that libnvpair manages the memory for property lookups!
c4800545504378963d9f2eeb253f06899664f9f6jmcp * The same goes for libdevinfo properties.
c4800545504378963d9f2eeb253f06899664f9f6jmcp *
c4800545504378963d9f2eeb253f06899664f9f6jmcp * Also note that we're allocating here before we try to
c4800545504378963d9f2eeb253f06899664f9f6jmcp * ses_open() the target, because if we can't allocate
c4800545504378963d9f2eeb253f06899664f9f6jmcp * sufficient space then we might as well go home.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
c4800545504378963d9f2eeb253f06899664f9f6jmcp newdev->ident = calloc(1, VIDLEN + PIDLEN + REVLEN + 3);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha if (newdev->ident == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to malloc space for"
c4800545504378963d9f2eeb253f06899664f9f6jmcp "SCSI INQUIRY data\n"), driver);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->classname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->drvname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((ses_target =
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_open(LIBSES_VERSION, newdev->access_devname))
c4800545504378963d9f2eeb253f06899664f9f6jmcp == NULL) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("%s: Unable to open device %s\n"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver, newdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->ident);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->classname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->access_devname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp continue;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp snapshot = ses_snap_hold(ses_target);
c4800545504378963d9f2eeb253f06899664f9f6jmcp rootnodep = ses_root_node(snapshot);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp /*
c4800545504378963d9f2eeb253f06899664f9f6jmcp * If the node has no properties, or the INQUIRY properties
c4800545504378963d9f2eeb253f06899664f9f6jmcp * don't exist, this device does not comply with SES2 so we
c4800545504378963d9f2eeb253f06899664f9f6jmcp * won't touch it.
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp */
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((props = ses_node_props(rootnodep)) == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->ident);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_snap_rele(snapshot);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_close(ses_target);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->classname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->drvname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
c4800545504378963d9f2eeb253f06899664f9f6jmcp continue;
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((nvlist_lookup_string(props, SCSI_PROP_VENDOR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp &newdev->ident->vid) != 0) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (nvlist_lookup_string(props, SCSI_PROP_PRODUCT,
c4800545504378963d9f2eeb253f06899664f9f6jmcp &newdev->ident->pid) != 0) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (nvlist_lookup_string(props, SCSI_PROP_REVISION,
c4800545504378963d9f2eeb253f06899664f9f6jmcp &newdev->ident->revid) != 0)) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->ident);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_snap_rele(snapshot);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_close(ses_target);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->classname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->access_devname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->drvname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
c4800545504378963d9f2eeb253f06899664f9f6jmcp continue;
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp nodep = ses_snap_primary_enclosure(snapshot);
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((props = ses_node_props(nodep)) == NULL) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->ident);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_snap_rele(snapshot);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_close(ses_target);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev->classname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(newdev->drvname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp free(newdev);
c4800545504378963d9f2eeb253f06899664f9f6jmcp free(devpath);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp continue;
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "\nvid: %s\npid: %s\nrevid: %s\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp newdev->ident->vid,
c4800545504378963d9f2eeb253f06899664f9f6jmcp newdev->ident->pid,
c4800545504378963d9f2eeb253f06899664f9f6jmcp newdev->ident->revid);
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (nvlist_lookup_string(props, LIBSES_EN_PROP_CSN,
c4800545504378963d9f2eeb253f06899664f9f6jmcp &newdev->addresses[0]) == 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "Chassis Serial Number: %s\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp newdev->addresses[0]);
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang } else
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang logmsg(MSG_INFO,
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang "%s: no chassis-serial-number property "
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang "for device %s\n",
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang driver, newdev->access_devname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson rv = di_prop_lookup_strings(DDI_DEV_T_ANY,
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson thisnode, "target-port", &newdev->addresses[1]);
f1c2346531c82ed357422b37e6c09f7b692e0c45James C. McPherson if (rv < 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "%s: no target-port property "
c4800545504378963d9f2eeb253f06899664f9f6jmcp "for device %s\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver, newdev->access_devname);
c4800545504378963d9f2eeb253f06899664f9f6jmcp } else
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "target-port property: %s\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp newdev->addresses[1]);
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp newdev->index = idx;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ++idx;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp newdev->plugin = self;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_snap_rele(snapshot);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp TAILQ_INSERT_TAIL(fw_devices, newdev, nextdev);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (fwflash_debug != 0) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp struct devicelist *tempdev;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp TAILQ_FOREACH(tempdev, fw_devices, nextdev) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO, "%s:fw_identify:\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp driver);
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "\ttempdev @ 0x%lx\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\taccess_devname: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\tdrvname: %s\tclassname: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\tident->vid: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\tident->pid: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\tident->revid: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\tindex: %d\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\taddress[0]: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\taddress[1]: %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\t\tplugin @ 0x%lx\n\n",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp &tempdev,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp tempdev->access_devname,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp tempdev->drvname, newdev->classname,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp tempdev->ident->vid,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp tempdev->ident->pid,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp tempdev->ident->revid,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp tempdev->index,
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang (tempdev->addresses[0] ? tempdev->addresses[0] :
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang "(not supported)"),
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang (tempdev->addresses[1] ? tempdev->addresses[1] :
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang "(not supported)"),
c4800545504378963d9f2eeb253f06899664f9f6jmcp &tempdev->plugin);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp return (FWFLASH_SUCCESS);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpint
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpfw_devinfo(struct devicelist *thisdev)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp fprintf(stdout, gettext("Device[%d] %s\n Class [%s]\n"),
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp thisdev->index, thisdev->access_devname, thisdev->classname);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp fprintf(stdout,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp gettext("\tVendor : %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\tProduct : %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\tFirmware revision : %s\n"
c4800545504378963d9f2eeb253f06899664f9f6jmcp "\tChassis Serial Number : %s\n"
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "\tTarget-port identifier : %s\n"),
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp thisdev->ident->vid,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp thisdev->ident->pid,
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp thisdev->ident->revid,
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang (thisdev->addresses[0] ? thisdev->addresses[0] :
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang "(not supported)"),
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang (thisdev->addresses[1] ? thisdev->addresses[1] :
0f59e5a798136b49e7c0666181494da06bd8051epeihong huang "(not supported)"));
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp fprintf(stdout, "\n\n");
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp return (FWFLASH_SUCCESS);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*ARGSUSED*/
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpstatic int
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpget_status(nvlist_t *props, ucode_status_t *sp)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp int i;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uint64_t status, astatus;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (nvlist_lookup_uint64(props, SES_EN_PROP_UCODE, &status) != 0) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp sp->us_status = -1ULL;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) snprintf(sp->us_desc, sizeof (sp->us_desc),
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "not supported");
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (nvlist_lookup_uint64(props, SES_EN_PROP_UCODE_A,
c4800545504378963d9f2eeb253f06899664f9f6jmcp &astatus) != 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp gettext("\nError: Unable to retrieve current status\n"));
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp for (i = 0; i < NUCODE_STATUS; i++) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (ucode_statdesc_table[i].us_value == status)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp break;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp sp->us_status = status;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (i == NUCODE_STATUS) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) snprintf(sp->us_desc, sizeof (sp->us_desc),
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp "unknown (0x%02x)", (int)status);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen sp->us_iserr = sp->us_pending = B_TRUE;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp } else {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp /* LINTED */
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) snprintf(sp->us_desc, sizeof (sp->us_desc),
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ucode_statdesc_table[i].us_desc, (int)astatus);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp sp->us_iserr = ucode_statdesc_table[i].us_iserr;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp sp->us_pending = ucode_statdesc_table[i].us_pending;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_SUCCESS);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChenstatic int
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpprint_updated_status(ses_node_t *np, void *arg)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ucode_wait_t *uwp = arg;
c4800545504378963d9f2eeb253f06899664f9f6jmcp nvlist_t *props;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ucode_status_t status;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((props = ses_node_props(np)) == NULL) {
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen if (get_status(props, &status) != FWFLASH_SUCCESS)
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp if (status.us_status != uwp->uw_prevstatus)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%30s: %s\n", "status", status.us_desc);
c4800545504378963d9f2eeb253f06899664f9f6jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uwp->uw_prevstatus = status.us_status;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uwp->uw_pending = status.us_pending;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (status.us_iserr) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "libses: status.us_iserr: 0x%0x\n",
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp status.us_iserr);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen }
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_SUCCESS);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp/*ARGSUSED*/
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic int
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcpsendimg(ses_node_t *np, void *data)
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp nvlist_t *props;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp nvlist_t *arg = data;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp char *vendor, *product, *revision, *csn;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp char buf[128];
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ses_snap_t *newsnap;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp int ret;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ucode_status_t statdesc;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ucode_wait_t wait;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp uint8_t *imagedata;
c4800545504378963d9f2eeb253f06899664f9f6jmcp uint_t len;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp /* If we've been called without data, eject */
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (nvlist_lookup_byte_array(arg, SES_CTL_PROP_UCODE_DATA,
c4800545504378963d9f2eeb253f06899664f9f6jmcp &imagedata, &len) != 0) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp props = ses_node_props(np);
c4800545504378963d9f2eeb253f06899664f9f6jmcp if ((props == NULL) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (nvlist_lookup_string(props, SES_EN_PROP_VID, &vendor) != 0) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (nvlist_lookup_string(props, SES_EN_PROP_PID, &product) != 0) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (nvlist_lookup_string(props, SES_EN_PROP_REV, &revision) != 0) ||
c4800545504378963d9f2eeb253f06899664f9f6jmcp (nvlist_lookup_string(props, LIBSES_EN_PROP_CSN, &csn) != 0)) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%30s: %s\n", "vendor", vendor);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%30s: %s\n", "product", product);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%30s: %s\n", "revision", revision);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%30s: %s\n", "serial", csn);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp ret = get_status(props, &statdesc);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%30s: %s\n", "current status", statdesc.us_desc);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen if (ret != FWFLASH_SUCCESS) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) snprintf(buf, sizeof (buf), "downloading %u bytes", len);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("\n%30s: ", buf);
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp /*
c4800545504378963d9f2eeb253f06899664f9f6jmcp * If the bufferid isn't 2, then the verifier has already
87d06e46cdea545c3c673120b7211158dcfd35ccpeihong huang * OK'd the image that the user has provided.
c4800545504378963d9f2eeb253f06899664f9f6jmcp *
c4800545504378963d9f2eeb253f06899664f9f6jmcp * At present the non-"standard" images need to be flashed
c4800545504378963d9f2eeb253f06899664f9f6jmcp * using the scsi WRITE BUFFER command
c4800545504378963d9f2eeb253f06899664f9f6jmcp */
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (verifier->flashbuf != 2)
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (scsi_writebuf());
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen if (ses_node_ctl(np, SES_CTL_OP_DL_UCODE, arg) != FWFLASH_SUCCESS) {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("failed!\n");
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("%s\n", ses_errmsg());
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp } else {
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp (void) printf("ok\n");
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp }
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp wait.uw_prevstatus = -1ULL;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp wait.uw_oldnp = np;
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen if ((newsnap = ses_snap_new(ses_target)) == NULL) {
d73e86db323b2684ada2db7e3b2fe57e542703b0suha logmsg(MSG_ERROR,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "failed to update SES snapshot: %s",
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_errmsg());
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen }
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp print_updated_status(ses_snap_primary_enclosure(newsnap),
c4800545504378963d9f2eeb253f06899664f9f6jmcp &wait);
c4800545504378963d9f2eeb253f06899664f9f6jmcp ses_snap_rele(newsnap);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_SUCCESS);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha}
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcpstatic int
c4800545504378963d9f2eeb253f06899664f9f6jmcpscsi_writebuf()
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp{
c4800545504378963d9f2eeb253f06899664f9f6jmcp int ret;
d73e86db323b2684ada2db7e3b2fe57e542703b0suha int i = 0;
c4800545504378963d9f2eeb253f06899664f9f6jmcp libscsi_action_t *action;
c4800545504378963d9f2eeb253f06899664f9f6jmcp spc3_write_buffer_cdb_t *wb_cdb;
c4800545504378963d9f2eeb253f06899664f9f6jmcp libscsi_hdl_t *handle;
c4800545504378963d9f2eeb253f06899664f9f6jmcp libscsi_target_t *target;
c4800545504378963d9f2eeb253f06899664f9f6jmcp sam4_status_t samstatus;
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp target = ses_scsi_target(ses_target);
c4800545504378963d9f2eeb253f06899664f9f6jmcp handle = libscsi_get_handle(target);
c4800545504378963d9f2eeb253f06899664f9f6jmcp action = libscsi_action_alloc(handle, SPC3_CMD_WRITE_BUFFER,
c4800545504378963d9f2eeb253f06899664f9f6jmcp LIBSCSI_AF_WRITE|LIBSCSI_AF_RQSENSE,
c4800545504378963d9f2eeb253f06899664f9f6jmcp (void *)verifier->fwimage, (size_t)verifier->imgsize);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp wb_cdb = (spc3_write_buffer_cdb_t *)libscsi_action_get_cdb(action);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen
c4800545504378963d9f2eeb253f06899664f9f6jmcp wb_cdb->wbc_mode = SPC3_WB_MODE_DATA;
c4800545504378963d9f2eeb253f06899664f9f6jmcp wb_cdb->wbc_bufferid = verifier->flashbuf;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen wb_cdb->wbc_buffer_offset[0] = 0;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen wb_cdb->wbc_buffer_offset[1] = 0;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen wb_cdb->wbc_buffer_offset[2] = 0;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen wb_cdb->wbc_parameter_list_len[0] =
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen (verifier->imgsize & 0xff0000) >> 16;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen wb_cdb->wbc_parameter_list_len[1] = (verifier->imgsize & 0xff00) >> 8;
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen wb_cdb->wbc_parameter_list_len[2] = (verifier->imgsize & 0xff);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp ret = libscsi_exec(action, target);
c4800545504378963d9f2eeb253f06899664f9f6jmcp samstatus = libscsi_action_get_status(action);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp logmsg(MSG_INFO,
c4800545504378963d9f2eeb253f06899664f9f6jmcp "\nscsi_writebuffer: ret 0x%0x, samstatus 0x%0x\n",
c4800545504378963d9f2eeb253f06899664f9f6jmcp ret, samstatus);
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen if ((ret != FWFLASH_SUCCESS) || samstatus != SAM4_STATUS_GOOD) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp libscsi_action_free(action);
d65b419ea7828ceaecc8f2ed7188237add6b14dcXinChen return (FWFLASH_FAILURE);
c4800545504378963d9f2eeb253f06899664f9f6jmcp } else {
c4800545504378963d9f2eeb253f06899664f9f6jmcp (void) printf("ok\n");
d73e86db323b2684ada2db7e3b2fe57e542703b0suha }
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp for (i = 0; i < NSAM4_STATUS; i++) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (sam4_status[i].status == samstatus) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp (void) printf("%s\n", (sam4_status[i].message));
c4800545504378963d9f2eeb253f06899664f9f6jmcp break;
d73e86db323b2684ada2db7e3b2fe57e542703b0suha }
d73e86db323b2684ada2db7e3b2fe57e542703b0suha }
d73e86db323b2684ada2db7e3b2fe57e542703b0suha
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (i == NSAM4_STATUS)
c4800545504378963d9f2eeb253f06899664f9f6jmcp (void) printf("Status: UNKNOWN\n");
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp if (samstatus == SAM4_STATUS_GOOD) {
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_SUCCESS);
c4800545504378963d9f2eeb253f06899664f9f6jmcp }
c4800545504378963d9f2eeb253f06899664f9f6jmcp
c4800545504378963d9f2eeb253f06899664f9f6jmcp return (FWFLASH_FAILURE);
5a7763bf3e9db4cfe6cb523b096cb74af71e3793jmcp}