fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard/* Copyright 2010 QLogic Corporation */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard#pragma ident "Copyright 2010 QLogic Corporation; ql_ioctl.c"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fibre Channel Adapter (FCA) driver IOCTL source file.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ***********************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * NOTICE **
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * ALL RIGHTS RESERVED **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * * **
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ***********************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_apps.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_api.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_debug.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_init.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_ioctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_mbx.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <ql_xioctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Local Function Prototypes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_busy_notification(ql_adapter_state_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_idle_notification(ql_adapter_state_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_get_feature_bits(ql_adapter_state_t *ha, uint16_t *features);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_set_feature_bits(ql_adapter_state_t *ha, uint16_t features);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_set_nvram_adapter_defaults(ql_adapter_state_t *ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void ql_load_nvram(ql_adapter_state_t *ha, uint8_t addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t value);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_24xx_load_nvram(ql_adapter_state_t *, uint32_t, uint32_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_op(ql_adapter_state_t *, void *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_adapter_info(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_extended_logging(ql_adapter_state_t *, ql_adm_op_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_device_list(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_update_properties(ql_adapter_state_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_prop_update_int(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_loop_reset(ql_adapter_state_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_fw_dump(ql_adapter_state_t *, ql_adm_op_t *, void *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_nvram_dump(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_nvram_load(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_flash_load(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_vpd_dump(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_vpd_load(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_vpd_gettag(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int ql_adm_updfwmodule(ql_adapter_state_t *, ql_adm_op_t *, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint8_t *ql_vpd_findtag(ql_adapter_state_t *, uint8_t *, int8_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ************************************************************************ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* cb_ops functions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ************************************************************************ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_open
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opens device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_p = device pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flags = open flags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otype = open type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cred_p = credentials pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 = success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_open(dev_t *dev_p, int flags, int otyp, cred_t *cred_p)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_adapter_state_t *ha;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha = ddi_get_soft_state(ql_state, (int32_t)getminor(*dev_p));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_2(CE_CONT, "failed, no adapter\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Allow only character opens */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (otyp != OTYP_CHR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_2(CE_CONT, "(%d): failed, open type\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ADAPTER_STATE_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flags & FEXCL && ha->flags & QL_OPENED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ADAPTER_STATE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EBUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flags |= QL_OPENED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ADAPTER_STATE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, rval = %xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_close
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opens device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev_p = device pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flags = open flags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * otype = open type
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cred_p = credentials pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 = success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_close(dev_t dev, int flags, int otyp, cred_t *cred_p)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_adapter_state_t *ha;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha = ddi_get_soft_state(ql_state, (int32_t)getminor(dev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_2(CE_CONT, "failed, no adapter\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (otyp != OTYP_CHR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_2(CE_CONT, "(%d): failed, open type\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ADAPTER_STATE_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->flags &= ~QL_OPENED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ADAPTER_STATE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, rval = %xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_ioctl
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * control a character device
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev = device number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cmd = function to perform
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg = data type varies with request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode = flags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cred_p = credentials pointer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rval_p = pointer to result value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 = success
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *rval_p)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_adapter_state_t *ha;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_in_panic()) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_2(CE_CONT, "ql_ioctl: ddi_in_panic exit\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOPROTOOPT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha = ddi_get_soft_state(ql_state, (int32_t)getminor(dev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_2(CE_CONT, "failed, no adapter\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Quick clean exit for qla2x00 foapi calls which are
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not supported in qlc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cmd >= QL_FOAPI_START && cmd <= QL_FOAPI_END) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "failed, fo api not supported\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOTTY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* PWR management busy. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_busy_notification(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != FC_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_busy_notification\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENXIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_xioctl(ha, cmd, arg, mode, cred_p, rval_p);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == ENOPROTOOPT || rval == EINVAL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cmd) {
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard case QL_GET_ADAPTER_FEATURE_BITS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t bits;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_get_feature_bits(ha, &bits);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rval && ddi_copyout((void *)&bits, (void *)arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (bits), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard case QL_SET_ADAPTER_FEATURE_BITS: {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t bits;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)arg, (void *)&bits,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (bits), mode)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_set_feature_bits(ha, bits);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_SET_ADAPTER_NVRAM_DEFAULTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_set_nvram_adapter_defaults(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_UTIL_LOAD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_nv_util_load(ha, (void *)arg, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_UTIL_DUMP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_nv_util_dump(ha, (void *)arg, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_ADM_OP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_op(ha, (void *)arg, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unknown command = %d\n", cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ENOTTY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* PWR management idle. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_idle_notification(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != 0) {
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard /*
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard * Don't show failures caused by pps polling for
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard * non-existant virtual ports.
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard */
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard if (cmd != EXT_CC_VPORT_CMD) {
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard EL(ha, "failed, cmd=%d rval=%d\n", cmd, rval);
f885d00f4e3c96a769ce0228a732da31ad9d0b78Daniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_busy_notification
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Adapter busy notification.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_busy_notification(ql_adapter_state_t *ha)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ha->pm_capable) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->busy++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_busy_component(ha->dip, 0) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->busy--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "pm_busy_component failed = %xh\n", FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->power_level != PM_LEVEL_D0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_raise_power(ha->dip, 0, 1) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->busy--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_idle_notification
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Adapter idle notification.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_SUCCESS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FC_FAILURE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_idle_notification(ql_adapter_state_t *ha)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!ha->pm_capable) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pm_idle_component(ha->dip, 0) != DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "pm_idle_component failed = %xh\n", FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_FAILURE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->busy--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PM_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FC_SUCCESS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get adapter feature bits from NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_get_feature_bits(ql_adapter_state_t *ha, uint16_t *features)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte volatile uint16_t data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t nv_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t offset = offsetof(nvram_t, adapter_features);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_24258081)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Not supported for 24xx\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The offset can't be greater than max of 8 bits and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the following code breaks if the offset isn't at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2 byte boundary.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Have the most significant 3 bits represent the read operation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * followed by the 8 bits representing the offset at which we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are going to perform the read operation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset >>= 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset += start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd = (offset << 16) | NV_READ_OP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd <<= 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Select the chip and feed the command and address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < 11; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nv_cmd & BIT_31) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, NV_DATA_OUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd <<= 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *features = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < 16; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_SELECT | NV_CLOCK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data = RD16_IO_REG(ha, nvram);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *features <<= 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (data & NV_DATA_IN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *features = (uint16_t)(*features | 0x1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_SELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deselect the chip
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set adapter feature bits in NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_set_feature_bits(ql_adapter_state_t *ha, uint16_t features)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvram_t *nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t *wptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *bptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t csum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_24258081)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Not supported for 24xx\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv = kmem_zalloc(sizeof (*nv), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nv == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nv, sizeof (*nv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read off the whole NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr = (uint16_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) / 2; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *wptr = (uint16_t)ql_get_nvram_word(ha, count + start_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + (uint8_t)*wptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + (uint8_t)(*wptr >> 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the checksum is BAD then fail it right here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (csum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nv, sizeof (*nv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBADF);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->adapter_features[0] = (uint8_t)((features & 0xFF00) >> 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->adapter_features[1] = (uint8_t)(features & 0xFF);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Recompute the chesksum now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bptr = (uint8_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) - 1; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + *bptr++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(~csum + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->checksum = csum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now load the NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr = (uint16_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) / 2; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_load_nvram(ha, (uint8_t)(count + start_addr), *wptr++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read NVRAM and verify the contents
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr = (uint16_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) / 2; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_get_nvram_word(ha, count + start_addr) != *wptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + (uint8_t)*wptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + (uint8_t)(*wptr >> 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (csum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nv, sizeof (*nv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fix this function to update just feature bits and checksum in NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_set_nvram_adapter_defaults(ql_adapter_state_t *ha)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_24258081)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvram_24xx_t *nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t *longptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv = kmem_zalloc(sizeof (*nv), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nv == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->nvram_version[0] = LSB(ICB_24XX_VERSION);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->nvram_version[1] = MSB(ICB_24XX_VERSION);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->version[0] = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->max_frame_length[1] = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->execution_throttle[0] = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->login_retry_count[0] = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options_1[0] = BIT_2 | BIT_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options_1[1] = BIT_5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options_2[0] = BIT_5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options_2[1] = BIT_4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options_3[1] = BIT_6;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set default host adapter parameters
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->host_p[0] = BIT_4 | BIT_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->host_p[1] = BIT_3 | BIT_2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->reset_delay = 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->max_luns_per_target[0] = 128;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->port_down_retry_count[0] = 30;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->link_down_timeout[0] = 30;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * compute the chesksum now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte longptr = (uint32_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < (sizeof (nvram_24xx_t)/4)-1; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum += *longptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte longptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint32_t)(~csum + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_32((long)csum);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *longptr = csum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now load the NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte longptr = (uint32_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_24xx_t) / 4; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_load_nvram(ha,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)(count + start_addr), *longptr++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read NVRAM and verify the contents
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte longptr = (uint32_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_24xx_t) / 4; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_24xx_read_flash(ha, count + start_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte longptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "24xx_read_flash failed=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum += *longptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (csum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nv, sizeof (nvram_24xx_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvram_t *nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t *wptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *bptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t csum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv = kmem_zalloc(sizeof (*nv), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nv == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set default initialization control block.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->parameter_block_version = ICB_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options[0] = BIT_4 | BIT_3 | BIT_2 | BIT_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->firmware_options[1] = BIT_7 | BIT_5 | BIT_2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->max_frame_length[1] = 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->max_iocb_allocation[1] = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->execution_throttle[0] = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->login_retry_count = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->port_name[0] = 33;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->port_name[3] = 224;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->port_name[4] = 139;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->login_timeout = 4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set default host adapter parameters
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->host_p[0] = BIT_1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->host_p[1] = BIT_2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->reset_delay = 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->port_down_retry_count = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->maximum_luns_per_target[0] = 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * compute the chesksum now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bptr = (uint8_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) - 1; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + *bptr++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(~csum + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv->checksum = csum;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now load the NVRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr = (uint16_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) / 2; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_load_nvram(ha, (uint8_t)(count + start_addr),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *wptr++);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read NVRAM and verify the contents
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr = (uint16_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < sizeof (nvram_t) / 2; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_get_nvram_word(ha, count + start_addr) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *wptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + (uint8_t)*wptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte csum = (uint8_t)(csum + (uint8_t)(*wptr >> 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (csum) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EINVAL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(nv, sizeof (*nv));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_load_nvram(ql_adapter_state_t *ha, uint8_t addr, uint16_t value)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte volatile uint16_t word;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte volatile uint32_t nv_cmd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, NV_DATA_OUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (word = 0; word < 8; word++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, NV_DATA_OUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deselect the chip
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Erase Location
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd = (addr << 16) | NV_ERASE_OP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd <<= 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < 11; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nv_cmd & BIT_31) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, NV_DATA_OUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd <<= 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait for Erase to Finish
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_SELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte word = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((word & NV_DATA_IN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte word = RD16_IO_REG(ha, nvram);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Write data now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd = (addr << 16) | NV_WRITE_OP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd |= value;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd <<= 5;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < 27; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nv_cmd & BIT_31) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, NV_DATA_OUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv_cmd <<= 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wait for NVRAM to become ready
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_SELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte word = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((word & NV_DATA_IN) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte word = RD16_IO_REG(ha, nvram);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_delay();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Disable writes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, NV_DATA_OUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (count = 0; count < 10; count++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_nv_write(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Deselect the chip now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte WRT16_IO_REG(ha, nvram, NV_DESELECT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_24xx_load_nvram
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Enable NVRAM and writes a 32bit word to ISP24xx NVRAM.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * addr: NVRAM address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * value: data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql local function return status code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_24xx_load_nvram(ql_adapter_state_t *ha, uint32_t addr, uint32_t value)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Enable flash write. */
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (!(CFG_IST(ha, CFG_CTRL_8081))) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard WRT32_IO_REG(ha, ctrl_status,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Disable NVRAM write-protection. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (CFG_IST(ha, CFG_CTRL_2422)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_write_flash(ha, NVRAM_CONF_ADDR | 0x101, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard EL(ha, "unprotect_flash failed, rval=%xh\n", rval);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard return (rval);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Write to flash. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_24xx_write_flash(ha, addr, value);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Enable NVRAM write-protection. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (CFG_IST(ha, CFG_CTRL_2422)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* TODO: Check if 0x8c is correct -- sb: 0x9c ? */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_24xx_write_flash(ha, NVRAM_CONF_ADDR | 0x101, 0x8c);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_24xx_protect_flash(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Disable flash write. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if (!(CFG_IST(ha, CFG_CTRL_81XX))) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard WRT32_IO_REG(ha, ctrl_status,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard RD32_IO_REG(ha, ctrl_status) & ~ISP_FLASH_ENABLE);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_nv_util_load
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loads NVRAM from application.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp = user buffer address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_nv_util_load(ql_adapter_state_t *ha, void *bp, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t *wptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t data;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard uint32_t start_addr, *lptr, data32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nvram_t *nptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if ((nv = kmem_zalloc(ha->nvram_cache->size, KM_SLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (ddi_copyin(bp, nv, ha->nvram_cache->size, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Buffer copy failed\n");
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard kmem_free(nv, ha->nvram_cache->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* See if the buffer passed to us looks sane */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nptr = (nvram_t *)nv;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nptr->id[0] != 'I' || nptr->id[1] != 'S' || nptr->id[2] != 'P' ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nptr->id[3] != ' ') {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, buffer sanity check\n");
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard kmem_free(nv, ha->nvram_cache->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Quiesce I/O */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ql_stall_driver failed\n");
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard kmem_free(nv, ha->nvram_cache->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard kmem_free(nv, ha->nvram_cache->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Load NVRAM. */
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_258081)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GLOBAL_HW_UNLOCK();
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard start_addr &= ~ha->flash_data_addr;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard start_addr <<= 2;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if ((rval = ql_r_m_w_flash(ha, bp, ha->nvram_cache->size,
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard start_addr, mode)) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "nvram load failed, rval = %0xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GLOBAL_HW_LOCK();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (CFG_IST(ha, CFG_CTRL_2422)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lptr = (uint32_t *)nv;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard for (cnt = 0; cnt < ha->nvram_cache->size / 4; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data32 = *lptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_32(&data32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_24xx_load_nvram(ha, cnt + start_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, 24xx_load_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wptr = (uint16_t *)nv;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard for (cnt = 0; cnt < ha->nvram_cache->size / 2; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data = *wptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_16(&data);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_load_nvram(ha, (uint8_t)(cnt + start_addr), data);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard /* switch to the new one */
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard NVRAM_CACHE_LOCK(ha);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard kmem_free(ha->nvram_cache->cache, ha->nvram_cache->size);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->cache = (void *)nptr;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard NVRAM_CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_nv_util_dump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dumps NVRAM to application.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp = user buffer address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_nv_util_dump(ql_adapter_state_t *ha, void *bp, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval2, rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (ha->nvram_cache == NULL ||
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->size == NULL ||
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->cache == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard } else if (ha->nvram_cache->valid != 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard /* Quiesce I/O */
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "ql_stall_driver failed\n");
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard return (EBUSY);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard rval2 = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (rval2 != QL_SUCCESS) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "failed, ql_lock_nvram=%xh\n", rval2);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ql_restart_driver(ha);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard return (EIO);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard }
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard NVRAM_CACHE_LOCK(ha);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard rval2 = ql_get_nvram(ha, ha->nvram_cache->cache,
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard start_addr, ha->nvram_cache->size);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (rval2 != QL_SUCCESS) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard rval = rval2;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard } else {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->valid = 1;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "nvram cache now valid.");
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard }
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard NVRAM_CACHE_UNLOCK(ha);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (rval != 0) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "failed to dump nvram, rval=%x\n", rval);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard return (rval);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (ddi_copyout(ha->nvram_cache->cache, bp,
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->size, mode) != 0) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "Buffer copy failed\n");
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard return (EFAULT);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard }
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard return (0);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard}
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregardint
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregardql_get_nvram(ql_adapter_state_t *ha, void *dest_addr, uint32_t src_addr,
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard uint32_t size)
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard{
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard int rval = QL_SUCCESS;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard int cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Dump NVRAM. */
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_24258081)) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard uint32_t *lptr = (uint32_t *)dest_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard for (cnt = 0; cnt < size / 4; cnt++) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard rval = ql_24xx_read_flash(ha, src_addr++, lptr);
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (rval != QL_SUCCESS) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "read_flash failed=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EAGAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_32(lptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t data;
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard uint16_t *wptr = (uint16_t *)dest_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard for (cnt = 0; cnt < size / 2; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data = (uint16_t)ql_get_nvram_word(ha, cnt +
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard src_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_16(&data);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *wptr++ = data;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_vpd_load
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Loads VPD from application.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp = user buffer address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_vpd_load(ql_adapter_state_t *ha, void *bp, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *vpd, *vpdptr, *vbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t start_addr, vpd_size, *lptr, data32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unsupported adapter feature\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOTSUP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vpd_size = QL_24XX_VPD_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vpd = kmem_zalloc(vpd_size, KM_SLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(bp, vpd, vpd_size, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Buffer copy failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Sanity check the user supplied data via checksum */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vpdptr = ql_vpd_findtag(ha, vpd, "RV")) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "vpd RV tag missing\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vpdptr += 3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vbuf = vpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (vbuf <= vpdptr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt += *vbuf++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "mismatched checksum, cal=%xh, passed=%xh\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint8_t)cnt, (uintptr_t)vpdptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Quiesce I/O */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ql_stall_driver failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_lock_nvram(ha, &start_addr, LNF_VPD_DATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Load VPD. */
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_258081)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GLOBAL_HW_UNLOCK();
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard start_addr &= ~ha->flash_data_addr;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard start_addr <<= 2;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ql_r_m_w_flash(ha, bp, vpd_size, start_addr,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard mode)) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "vpd load error: %xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte GLOBAL_HW_LOCK();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lptr = (uint32_t *)vpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 0; cnt < vpd_size / 4; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data32 = *lptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_32(&data32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_24xx_load_nvram(ha, cnt + start_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data32);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, 24xx_load_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update the vcache */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, load\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((ha->vcache == NULL) && ((ha->vcache =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(vpd_size, KM_SLEEP)) == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc2\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (ddi_copyin(bp, ha->vcache, vpd_size, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Buffer copy2 failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ha->vcache, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->vcache = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_vpd_dump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dumps VPD to application buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp = user buffer address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_vpd_dump(ql_adapter_state_t *ha, void *bp, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *vpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t start_addr, vpd_size, *lptr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unsupported adapter feature\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EACCES);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vpd_size = QL_24XX_VPD_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->vcache != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy back the vpd cache data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(ha->vcache, bp, vpd_size, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Buffer copy failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vpd = kmem_zalloc(vpd_size, KM_SLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Quiesce I/O */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ql_stall_driver failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_lock_nvram(ha, &start_addr, LNF_VPD_DATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Dump VPD. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lptr = (uint32_t *)vpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 0; cnt < vpd_size / 4; cnt++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_24xx_read_flash(ha, start_addr++, lptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "read_flash failed=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EAGAIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LITTLE_ENDIAN_32(lptr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lptr++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_release_nvram(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(vpd, bp, vpd_size, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "Buffer copy failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpd, vpd_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->vcache = vpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte CACHE_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_vpd_findtag
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Search the passed vpd buffer for the requested VPD tag type.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * vpdbuf = Pointer to start of the buffer to search
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * op = VPD opcode to find (must be NULL terminated).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pointer to the opcode in the buffer if opcode found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NULL if opcode is not found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic uint8_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_vpd_findtag(ql_adapter_state_t *ha, uint8_t *vpdbuf, int8_t *opcode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *vpd = vpdbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *end = vpdbuf + QL_24XX_VPD_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t found = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vpdbuf == NULL || opcode == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "null parameter passed!\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (vpd < end) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check for end of vpd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vpd[0] == VPD_TAG_END) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opcode[0] == VPD_TAG_END) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte found = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte found = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check opcode */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(opcode, vpd, strlen(opcode)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* found opcode requested */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte found = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Didn't find the opcode, so calculate start of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * next tag. Depending on the current tag type,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the length field can be 1 or 2 bytes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(strncmp((char *)vpd, (char *)VPD_TAG_PRODID, 1))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vpd += (vpd[2] << 8) + vpd[1] + 3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (*vpd == VPD_TAG_LRT || *vpd == VPD_TAG_LRTC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vpd += 3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte vpd += vpd[2] +3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (found == 1 ? vpd : NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_vpd_lookup
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return the VPD data for the request VPD tag
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha = adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opcode = VPD opcode to find (must be NULL terminated).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp = Pointer to returned data buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bplen = Length of returned data buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Length of data copied into returned data buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * >0 = VPD data field (NULL terminated)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 = no data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -1 = Could not find opcode in vpd buffer / error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NB: The opcode buffer and the bp buffer *could* be the same buffer!
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint32_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_vpd_lookup(ql_adapter_state_t *ha, uint8_t *opcode, uint8_t *bp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int32_t bplen)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *vpd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *vpdbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int32_t len = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opcode == NULL || bp == NULL || bplen < 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "invalid parameter passed: opcode=%ph, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "bp=%ph, bplen=%xh\n", opcode, bp, bplen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vpdbuf = (uint8_t *)kmem_zalloc(QL_24XX_VPD_SIZE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte KM_SLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unable to allocate vpd memory\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ql_vpd_dump(ha, vpdbuf, (int)FKIOCTL)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpdbuf, QL_24XX_VPD_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unable to retrieve VPD data\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((vpd = ql_vpd_findtag(ha, vpdbuf, (int8_t *)opcode)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Found the tag
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*opcode == VPD_TAG_END || *opcode == VPD_TAG_LRT ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *opcode == VPD_TAG_LRTC) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we found it, but the tag doesn't have a data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * field.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (!(strncmp((char *)vpd, (char *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte VPD_TAG_PRODID, 1))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = vpd[2] << 8;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len += vpd[1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = vpd[2];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * make sure that the vpd len doesn't exceed the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * vpd end
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vpd+len > vpdbuf + QL_24XX_VPD_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "vpd tag len (%xh) exceeds vpd buffer "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "length\n", len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len >= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * make sure we don't exceed callers buffer space len
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (len > bplen) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = bplen-1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy the data back */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strncpy((int8_t *)bp, (int8_t *)(vpd+3), (int64_t)len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp[len] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* error -- couldn't find tag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp[0] = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (opcode[1] != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unable to find tag '%s'\n", opcode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unable to find tag '%xh'\n", opcode[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(vpdbuf, QL_24XX_VPD_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard/*
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * ql_r_m_w_flash
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * Read modify write from user space to flash.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard *
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * Input:
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * ha: adapter state pointer.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * dp: source byte pointer.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * bc: byte count.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * faddr: flash byte address.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * mode: flags.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard *
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * Returns:
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * ql local function return status code.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard *
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * Context:
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard * Kernel context.
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregardint
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregardql_r_m_w_flash(ql_adapter_state_t *ha, caddr_t dp, uint32_t bc, uint32_t faddr,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *bp;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard uint32_t xfer, bsize, saddr, ofst;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard int rval = 0;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): started, dp=%ph, faddr=%xh, bc=%xh\n",
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard ha->instance, (void *)dp, faddr, bc);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard bsize = ha->xioctl->fdesc.block_size;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard saddr = faddr & ~(bsize - 1);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard ofst = faddr & (bsize - 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((bp = kmem_zalloc(bsize, KM_SLEEP)) == NULL) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard EL(ha, "kmem_zalloc=null\n");
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard return (QL_MEMORY_ALLOC_FAILED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard while (bc) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard xfer = bc > bsize ? bsize : bc;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if (ofst + xfer > bsize) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard xfer = bsize - ofst;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): dp=%ph, saddr=%xh, bc=%xh, "
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard "ofst=%xh, xfer=%xh\n", ha->instance, (void *)dp, saddr,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard bc, ofst, xfer);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if (ofst || xfer < bsize) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard /* Dump Flash sector. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ql_dump_fcode(ha, bp, bsize, saddr)) !=
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_SUCCESS) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard EL(ha, "dump_flash status=%x\n", rval);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard break;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Set new data. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ddi_copyin(dp, (caddr_t)(bp + ofst), xfer,
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard mode)) != 0) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard EL(ha, "ddi_copyin status=%xh, dp=%ph, ofst=%xh, "
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard "xfer=%xh\n", rval, (void *)dp, ofst, xfer);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard rval = QL_FUNCTION_FAILED;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard break;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Write to flash. */
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ql_load_fcode(ha, bp, bsize, saddr)) !=
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_SUCCESS) {
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard EL(ha, "load_flash status=%x\n", rval);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard break;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard }
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard bc -= xfer;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard dp += xfer;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard saddr += bsize;
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard ofst = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(bp, bsize);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_op
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm utility operations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg: driver_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_op(ql_adapter_state_t *ha, void *arg, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_adm_op_t dop;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin(arg, &dop, sizeof (ql_adm_op_t), mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, driver_op_t ddi_copyin\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): started, cmd=%xh, buffer=%llx,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " length=%xh, option=%xh\n", ha->instance, dop.cmd, dop.buffer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop.length, dop.option);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (dop.cmd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_ADAPTER_INFO:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_adapter_info(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_EXTENDED_LOGGING:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_extended_logging(ha, &dop);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_LOOP_RESET:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_loop_reset(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_DEVICE_LIST:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_device_list(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_PROP_UPDATE_INT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_prop_update_int(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_UPDATE_PROPERTIES:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_update_properties(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_FW_DUMP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_fw_dump(ha, &dop, arg, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_NVRAM_LOAD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_nvram_load(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_NVRAM_DUMP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_nvram_dump(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_FLASH_LOAD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_flash_load(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_VPD_LOAD:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_vpd_load(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_VPD_DUMP:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_vpd_dump(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_VPD_GETTAG:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_vpd_gettag(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case QL_UPD_FWMODULE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ql_adm_updfwmodule(ha, &dop, mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "unsupported driver op cmd: %x\n", dop.cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_adapter_info
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_ADAPTER_INFO command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_adapter_info(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_adapter_info_t hba;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *dp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t length;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval, i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba.device_id = ha->device_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard dp = CFG_IST(ha, CFG_CTRL_24258081) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &ha->init_ctrl_blk.cb24.port_name[0] :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &ha->init_ctrl_blk.cb.port_name[0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(dp, hba.wwpn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba.d_id = ha->d_id.b24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->xioctl->fdesc.flash_size == 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte !(CFG_IST(ha, CFG_CTRL_2200) && !ha->subven_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ql_stall_driver failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard if ((rval = ql_setup_fcache(ha)) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ql_setup_flash failed=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval == QL_FUNCTION_TIMEOUT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Resume I/O */
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if (CFG_IST(ha, CFG_CTRL_24258081)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "isp_abort_needed for restart\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DRIVER_STALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hba.flash_size = ha->xioctl->fdesc.flash_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) strcpy(hba.driver_ver, QL_VERSION);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(hba.fw_ver, "%d.%d.%d", ha->fw_major_version,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->fw_minor_version, ha->fw_subminor_version);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(hba.fcode_ver, sizeof (hba.fcode_ver));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_getlongprop(DDI_DEV_T_ANY, ha->dip,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "version", (caddr_t)&dp, &i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte length = i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ddi_getlongprop=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (length > (uint32_t)sizeof (hba.fcode_ver)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte length = sizeof (hba.fcode_ver) - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy((void *)dp, (void *)hba.fcode_ver, length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dp, length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)&hba, (void *)(uintptr_t)dop->buffer,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dop->length, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ddi_copyout\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_extended_logging
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_EXTENDED_LOGGING command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_extended_logging(ql_adapter_state_t *ha, ql_adm_op_t *dop)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char prop_name[MAX_PROP_LENGTH];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(prop_name, "hba%d-extended-logging", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = ddi_prop_update_int(DDI_DEV_T_NONE, ha->dip, prop_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (int)dop->option);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, prop_update = %xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->option ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING) :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_loop_reset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_LOOP_RESET command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_loop_reset(ql_adapter_state_t *ha)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->task_daemon_flags & LOOP_DOWN) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_full_login_lip(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((rval = ql_full_login_lip(ha)) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_initiate_lip=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_device_list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_DEVICE_LIST command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_device_list(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_device_info_t dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_link_t *link;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_tgt_t *tq;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t index, cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev.address = 0xffffffff;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Scan port list for requested target and fill in the values */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (link = NULL, index = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte index < DEVICE_HEAD_LIST_SIZE && link == NULL; index++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (link = ha->dev[index].first; link != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte link = link->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tq = link->base_address;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!VALID_TARGET_ID(ha, tq->loop_id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cnt != dop->option) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* fill in the values */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(tq->port_name, dev.wwpn, 8);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev.address = tq->d_id.b24;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev.loop_id = tq->loop_id;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tq->flags & TQF_TAPE_DEVICE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev.type = FCT_TAPE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (tq->flags & TQF_INITIATOR_DEVICE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev.type = FCT_INITIATOR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev.type = FCT_TARGET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)&dev, (void *)(uintptr_t)dop->buffer,
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard dop->length, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ddi_copyout\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_update_properties
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_UPDATE_PROPERTIES command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_update_properties(ql_adapter_state_t *ha)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_comb_init_cb_t init_ctrl_blk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_comb_ip_init_cb_t ip_init_ctrl_blk;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Stall driver instance. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_stall_driver(ha, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Save init control blocks. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&ha->init_ctrl_blk, &init_ctrl_blk, sizeof (ql_comb_init_cb_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&ha->ip_init_ctrl_blk, &ip_init_ctrl_blk,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ql_comb_ip_init_cb_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update PCI configration. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_pci_sbus_config(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get configuration properties. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ql_nvram_config(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check for init firmware required. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(&ha->init_ctrl_blk, &init_ctrl_blk,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ql_comb_init_cb_t)) != 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcmp(&ha->ip_init_ctrl_blk, &ip_init_ctrl_blk,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (ql_comb_ip_init_cb_t)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "isp_abort_needed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->loop_down_timer = LOOP_DOWN_TIMER_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte TASK_DAEMON_LOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha->task_daemon_flags |= LOOP_DOWN | ISP_ABORT_NEEDED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte TASK_DAEMON_UNLOCK(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Update AEN queue. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ha->xioctl->flags & QL_AEN_TRACKING_ENABLE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_enqueue_aen(ha, MBA_PORT_UPDATE, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Restart driver instance. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_prop_update_int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_PROP_UPDATE_INT command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_prop_update_int(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *prop_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prop_name = kmem_zalloc(dop->length, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (prop_name == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)(uintptr_t)dop->buffer, prop_name, dop->length,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, prop_name ddi_copyin\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(prop_name, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = ddi_prop_update_int(DDI_DEV_T_NONE, ha->dip, prop_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (int)dop->option)) != DDI_PROP_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, prop_update=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(prop_name, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(prop_name, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_fw_dump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_FW_DUMP command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * udop: user space ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_fw_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, void *udop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte caddr_t dmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dop->length < ha->risc_dump_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, incorrect length=%xh, size=%xh\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->length, ha->risc_dump_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if (ha->ql_dump_state & QL_DUMP_VALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dmp = kmem_zalloc(ha->risc_dump_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dmp == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->length = (uint32_t)ql_ascii_fw_dump(ha, dmp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout((void *)dmp, (void *)(uintptr_t)dop->buffer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->length, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ddi_copyout\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dmp, ha->risc_dump_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dmp, ha->risc_dump_size);
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard ha->ql_dump_state |= QL_DUMP_UPLOADED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, no dump file\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->length = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(dop, udop, sizeof (ql_adm_op_t), mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, driver_op_t ddi_copyout\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_nvram_dump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_NVRAM_DUMP command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_nvram_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (dop->length < ha->nvram_cache->size) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "failed, length=%xh, size=%xh\n", dop->length,
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = ql_nv_util_dump(ha, (void *)(uintptr_t)dop->buffer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_nv_util_dump\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_nvram_load
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_NVRAM_LOAD command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_nvram_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard if (dop->length < ha->nvram_cache->size) {
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard EL(ha, "failed, length=%xh, size=%xh\n", dop->length,
c1fad183c9a0deeb49586645ec9baa8f3c1bc8beDaniel Beauregard ha->nvram_cache->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = ql_nv_util_load(ha, (void *)(uintptr_t)dop->buffer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_nv_util_dump\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_flash_load
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_FLASH_LOAD command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_flash_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *dp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dp = kmem_zalloc(dop->length, KM_SLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, kmem_zalloc\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ENOMEM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)(uintptr_t)dop->buffer, dp, dop->length,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ddi_copyin failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dp, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ql_stall_driver failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dp, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EBUSY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard rval = (CFG_IST(ha, CFG_CTRL_24258081) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_24xx_load_flash(ha, dp, dop->length, dop->option) :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_load_flash(ha, dp, dop->length));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_restart_driver(ha);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(dp, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rval != QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_vpd_dump
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_VPD_DUMP command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_vpd_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "hba does not support VPD\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dop->length < QL_24XX_VPD_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, length=%xh, size=%xh\n", dop->length,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_24XX_VPD_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if ((rval = ql_vpd_dump(ha, (void *)(uintptr_t)dop->buffer, mode))
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_vpd_dump\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_vpd_load
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_VPD_LOAD command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_vpd_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "hba does not support VPD\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dop->length < QL_24XX_VPD_SIZE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, length=%xh, size=%xh\n", dop->length,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_24XX_VPD_SIZE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard if ((rval = ql_vpd_load(ha, (void *)(uintptr_t)dop->buffer, mode))
16dd44c265271a75647fb0bb41109bb7c585a526Daniel Beauregard != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ql_vpd_dump\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*EMPTY*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_vpd_gettag
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_VPD_GETTAG command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_vpd_gettag(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *lbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
eb82ff87b34e625264561b2d267577cf9821dab0Daniel Beauregard if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "hba does not support VPD\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lbuf = (uint8_t *)kmem_zalloc(dop->length, KM_SLEEP)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "mem alloc failure of %xh bytes\n", dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyin((void *)(uintptr_t)dop->buffer, lbuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->length, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "ddi_copyin failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(lbuf, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EFAULT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = ql_vpd_lookup(ha, lbuf, lbuf, (int32_t)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dop->length)) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed vpd_lookup\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_copyout(lbuf, (void *)(uintptr_t)dop->buffer,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strlen((int8_t *)lbuf)+1, mode) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha, "failed, ddi_copyout\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(lbuf, dop->length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ql_adm_updfwmodule
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Performs qladm QL_UPD_FWMODULE command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ha: adapter state pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dop: ql_adm_op_t structure pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mode: flags.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Context:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kernel context.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteql_adm_updfwmodule(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int rval = DDI_SUCCESS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_link_t *link;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_adapter_state_t *ha2 = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint16_t fw_class = (uint16_t)dop->option;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* zero the firmware module reference count */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (link = ql_hba.first; link != NULL; link = link->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha2 = link->base_address;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fw_class == ha2->fw_class) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = ddi_modclose(ha2->fw_module)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DDI_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha2, "modclose rval=%xh\n", rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha2->fw_module = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* reload the f/w modules */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (link = ql_hba.first; link != NULL; link = link->next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha2 = link->base_address;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fw_class == ha2->fw_class) && (ha2->fw_class == NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((rval = (int32_t)ql_fwmodule_resolve(ha2)) !=
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte QL_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha2, "unable to load f/w module: '%x' "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "(rval=%xh)\n", ha2->fw_class, rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = EFAULT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha2, "f/w module updated: '%x'\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ha2->fw_class);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte EL(ha2, "isp abort needed (%d)\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ql_awaken_task_daemon(ha2, NULL, ISP_ABORT_NEEDED, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rval = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5dfd244acc8f144280c5bc8f69ed941185fc3cccDaniel Beauregard QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}