pmcs_def.h revision 8f514e743bde41fe7e0ca48510a6d4c40ca51c23
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * CDDL HEADER START
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * The contents of this file are subject to the terms of the
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Common Development and Distribution License (the "License").
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * You may not use this file except in compliance with the License.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * or http://www.opensolaris.org/os/licensing.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * See the License for the specific language governing permissions
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * and limitations under the License.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * CDDL HEADER END
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#ifndef _PMCS_DEF_H
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define _PMCS_DEF_H
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#ifdef __cplusplus
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoreextern "C" {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#endif
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef enum {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore NOTHING, /* nothing connected here */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore SATA, /* SATA connection */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore SAS, /* direct or indirect SAS connection */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore EXPANDER, /* connection to an expander */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore NEW /* Brand new device (pending state) */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore} pmcs_dtype_t;
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * This structure defines a PHY device that represents what we
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * are connected to.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * The eight real physical PHYs that are in the PMC8X6G are represented
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * as an array of eight of these structures which define what these
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * real PHYs are connected to.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * Depending upon what is actually connected to each PHY, the
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * type set will define what we're connected to. If it is
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * a direct SATA connection, the phy will describe a SATA endpoint
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * If it is a direct SAS connection, it will describe a SAS
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * endpoint.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * If it is an EXPANDER, this will describe the edge of an expander.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * As we perform discovery on what is in an EXPANDER we define an
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * additional list of phys that represent what the Expander is connected to.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_HW_MIN_LINK_RATE SAS_LINK_RATE_1_5GBIT
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_HW_MAX_LINK_RATE SAS_LINK_RATE_6GBIT
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_INVALID_DEVICE_ID 0xffffffff
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_PHY_INVALID_PORT_ID 0xf
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_PM_MAX_NAMELEN 16
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_MAX_REENUMERATE 2 /* Maximum re-enumeration attempts */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Number of usecs to wait after last noted activate/deactivate callback
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * before possibly restarting discovery
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_REDISCOVERY_DELAY (5 * MICROSEC)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amorestruct pmcs_phy {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_phy_t *sibling; /* sibling phy */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_phy_t *parent; /* parent phy */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_phy_t *children; /* head of list of children */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_phy_t *dead_next; /* dead PHY list link */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore list_node_t list_node; /* list element */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t device_id; /* PMC8X6G device handle */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ncphy : 8, /* # of contained phys for expander */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hw_event_ack : 24; /* XXX: first level phy event acked */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t phynum; /* phy number on parent expander */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t width; /* how many phys wide */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t ds_recovery_retries; /* # error retry attempts */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t ds_prev_good_recoveries; /* # successful recoveries */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore clock_t prev_recovery; /* previous successful recovery */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore clock_t last_good_recovery; /* oldest successful recovery */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore /* within PMCS_MAX_DS_RECOVERY_TIME time frame */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_dtype_t dtype; /* current dtype of the phy */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_dtype_t pend_dtype; /* new dtype (pending change) */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore level : 8, /* level in expander tree */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore tolerates_sas2 : 1, /* tolerates SAS2 SMP */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore spinup_hold : 1, /* spinup hold needs releasing */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore atdt : 3, /* attached device type */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore portid : 4, /* PMC8X6G port context */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore link_rate : 4, /* current supported speeds */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore valid_device_id : 1, /* device id is valid */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore abort_sent : 1, /* we've sent an abort */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore abort_pending : 1, /* we have an abort pending */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore need_rl_ext : 1, /* need SATA RL_EXT recocvery */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore subsidiary : 1, /* this is part of a wide phy */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore configured : 1, /* is configured */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore dead : 1, /* dead */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore changed : 1, /* this phy is changing */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore reenumerate : 1, /* attempt re-enumeration */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore deregister_wait : 1; /* phy waiting to get deregistered */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore clock_t config_stop; /* When config attempts will stop */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hrtime_t abort_all_start;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore kcondvar_t abort_all_cv; /* Wait for ABORT_ALL completion */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore kmutex_t phy_lock;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore volatile uint32_t ref_count; /* Targets & work on this PHY */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t enum_attempts; /* # of enumeration attempts */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t sas_address[8]; /* SAS address for this PHY */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore struct {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore prog_min_rate :4,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hw_min_rate :4,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore prog_max_rate :4,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hw_max_rate :4,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore reserved :16;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore } state;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char path[32]; /* path name for this phy */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_hw_t *pwp; /* back ptr to hba struct */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_iport_t *iport; /* back ptr to the iport handle */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_iport_t *last_iport; /* last iport this PHY was on */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_xscsi_t *target; /* back ptr to current target */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore kstat_t *phy_stats; /* kstats for this phy */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore /*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Attached port phy mask and target port phymask. With 16 bytes
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * we can represent a phymask for anything with up to 64 ports
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint64_t att_port_pm; /* att port pm for this PHY */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint64_t att_port_pm_tmp; /* Temp area for wide-ports */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char att_port_pm_str[PMCS_PM_MAX_NAMELEN + 1];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint64_t tgt_port_pm; /* tgt port pm for this PHY */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint64_t tgt_port_pm_tmp; /* Temp area for wide-ports */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char tgt_port_pm_str[PMCS_PM_MAX_NAMELEN + 1];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore smp_routing_attr_t routing_attr; /* Routing attr. from discover resp. */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore smp_routing_attr_t routing_method; /* Actual routing method used. */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore smp_report_general_resp_t rg_resp; /* Response to REPORT_GENERAL */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore smp_discover_resp_t disc_resp; /* Response to DISCOVER */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore};
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/* maximum number of ds recovery retries (ds_recovery_retries) */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_MAX_DS_RECOVERY_RETRIES 10
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/* max time allowed for successful recovery */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_MAX_DS_RECOVERY_TIME (60 * 1000000) /* 60 seconds */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/* ds recovery on same same phy is not allowed within this interval */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_DS_RECOVERY_INTERVAL (1000000) /* 1 second */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Inbound and Outbound Queue Related Definitions.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * The PMC8X6G has a programmable number of inbound and outbound circular
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * queues for use in message passing between the host and the PMC8X6G
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * (up to 64 queues for the Rev C Chip). This driver does not use all
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * possible queues.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Each Queue is given 4K of consistent memory and we set a 64 byte size for
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * the queue entry size (this gives us 256 queue entries per queue).
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * This allocation then continues up a further PMCS_SCRATCH_SIZE bytes
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * that the driver uses as a temporary scratch area for things like
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * SMP discovery.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * This control area looks like this:
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * Offset What
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * ------------------------------------------------
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 0 IQ 0 Consumer Index
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 4 IQ 1 Consumer Index
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 8..255 ...
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 252..255 IQ 63 Consumer Index
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 256 OQ 0 Producer Index
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 260 OQ 1 Producer Index
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 264..259 ....
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 508..511 OQ 63 Producer Index
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * 512..512+PMCS_SCRATCH_SIZE-1 Scratch area.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore */
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore#define IQCI_BASE_OFFSET 0
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore#define IQ_OFFSET(qnum) (IQCI_BASE_OFFSET + (qnum << 2))
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore#define OQPI_BASE_OFFSET 256
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore#define OQ_OFFSET(qnum) (OQPI_BASE_OFFSET + (qnum << 2))
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore/*
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * Work related structures. Each one of these structures is paired
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * with *any* command that is fed to the PMC8X6G via one of the
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * Inbound Queues. The work structure has a tag to compare with
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * the message that comes back out of an Outbound Queue. The
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * work structure also points to the phy which this command is
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * tied to. It also has a pointer a callback function (if defined).
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * See that TAG Architecture below for the various kinds of
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * dispositions of a work structure.
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore */
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore/*
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * Work Structure States
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore *
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * NIL -> READY
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * READY -> NIL
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * READY -> ONCHIP
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * ONCHIP -> INTR
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * INTR -> READY
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * INTR -> NIL
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * INTR -> ABORTED
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * INTR -> TIMED_OUT
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * ABORTED -> NIL
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * TIMED_OUT -> NIL
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore */
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amoretypedef enum {
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_NIL = 0,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_READY,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_ONCHIP,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_INTR,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_IOCOMPQ,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_ABORTED,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore PMCS_WORK_STATE_TIMED_OUT
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore} pmcs_work_state_t;
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amorestruct pmcwork {
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore STAILQ_ENTRY(pmcwork) next;
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore kmutex_t lock;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore kcondvar_t sleep_cv;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore void *ptr; /* linkage or callback function */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore void *arg; /* command specific data */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_phy_t *phy; /* phy who owns this command */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_xscsi_t *xp; /* Back pointer to xscsi struct */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore volatile uint32_t htag; /* tag for this structure */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t abt_htag; /* Tag of command to be aborted */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore timer : 27,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore onwire : 1,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore dead : 1,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore state : 3;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hrtime_t start; /* timestamp start */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t ssp_event; /* ssp event */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_dtype_t dtype; /* stash, incase phy gets cleared */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore void *last_ptr;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore void *last_arg;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_phy_t *last_phy;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_xscsi_t *last_xp;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t last_htag;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_work_state_t last_state;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hrtime_t finish;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore};
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_REC_EVENT 0xffffffff /* event recovery */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * This structure defines a PMC-Sierra defined firmware header.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#pragma pack(4)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef struct {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char vendor_id[8];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t product_id;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t hwrev;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t destination_partition;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t reserved0;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t fwrev[4];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t firmware_length;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t crc;
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore uint32_t start_address;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t data[];
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore} pmcs_fw_hdr_t;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#pragma pack()
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Offlevel work as a bit pattern.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore#define PMCS_WORK_DISCOVER 0
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_ABORT_HANDLE 3
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_SPINUP_RELEASE 4
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_SAS_HW_ACK 5
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_SATA_RUN 6
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_RUN_QUEUES 7
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_ADD_DMA_CHUNKS 8
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_DS_ERR_RECOVERY 9
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_SSP_EVT_RECOVERY 10
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_DEREGISTER_DEV 11
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_DUMP_REGS 12
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * The actual values as they appear in work_flags
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_DISCOVER (1 << 0)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_ABORT_HANDLE (1 << 3)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_SPINUP_RELEASE (1 << 4)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_SAS_HW_ACK (1 << 5)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_SATA_RUN (1 << 6)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_RUN_QUEUES (1 << 7)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_ADD_DMA_CHUNKS (1 << 8)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_DS_ERR_RECOVERY (1 << 9)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_SSP_EVT_RECOVERY (1 << 10)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_DEREGISTER_DEV (1 << 11)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_WORK_FLAG_DUMP_REGS (1 << 12)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * This structure is used by this function to test MPI (and interrupts)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * after MPI has been started to make sure it's working reliably.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef struct {
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore uint32_t signature;
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore uint32_t count;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t *ptr;
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore} echo_test_t;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define ECHO_SIGNATURE 0xbebebeef
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Tag Architecture. The PMC has 32 bit tags for MPI messages.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * We use this tag this way.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * bits what
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * ------------------------
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * 31 done bit
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * 30 non-io cmd bit
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * 29..28 tag type
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * 27..12 rolling serial number
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * 11..0 index into work area to get pmcwork structure
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * A tag type of NONE means that nobody is waiting on any results,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * so the interrupt code frees the work structure that has this
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * tag.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * A tag type of CBACK means that the the interrupt handler
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * takes the tag 'arg' in the work structure to be a callback
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * function pointer (see pmcs_cb_t). The callee is responsible
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * for freeing the work structure that has this tag.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore *
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * A tag type of WAIT means that the issuer of the work needs
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * be woken up from interrupt level when the command completes
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * (or times out). If work structure tag 'arg' is non-null,
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * up to 2*PMCS_QENTRY_SIZE bits of data from the Outbound Queue
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * entry may be copied to the area pointed to by 'arg'. This
af145792def4317aeeb9d20f7772b32a35a0161fGarrett D'Amore * allows issuers to get directly at the results of the command
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * they issed. The synchronization point for the issuer and the
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * interrupt code for command done notification is the setting
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * of the 'DONE' bit in the tag as stored in the work structure.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE_FREE 0
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE_NONE 1
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE_CBACK 2
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE_WAIT 3
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE_SHIFT 28
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_SERNO_SHIFT 12
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_INDEX_SHIFT 0
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE_MASK 0x30000000
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_NONIO_CMD 0x40000000
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_DONE 0x80000000
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_SERNO_MASK 0x0ffff000
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_INDEX_MASK 0x00000fff
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_TYPE(x) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((x) & PMCS_TAG_TYPE_MASK) >> PMCS_TAG_TYPE_SHIFT)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_SERNO(x) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((x) & PMCS_TAG_SERNO_MASK) >> PMCS_TAG_SERNO_SHIFT)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_INDEX(x) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((x) & PMCS_TAG_INDEX_MASK) >> PMCS_TAG_INDEX_SHIFT)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TAG_FREE 0
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_COMMAND_DONE(x) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((x)->htag == PMCS_TAG_FREE) || (((x)->htag & PMCS_TAG_DONE) != 0))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_COMMAND_ACTIVE(x) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ((x)->htag != PMCS_TAG_FREE && (x)->state == PMCS_WORK_STATE_ONCHIP)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Miscellaneous Definitions
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define CLEAN_MESSAGE(m, x) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore int _j = x; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore while (_j < PMCS_MSG_SIZE) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore m[_j++] = 0; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore } \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore}
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define COPY_MESSAGE(t, f, a) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore int _j; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore for (_j = 0; _j < a; _j++) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore t[_j] = f[_j]; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore } \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore while (_j < PMCS_MSG_SIZE) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore t[_j++] = 0; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore } \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore}
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_PHY_ADDRESSABLE(pp) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ((pp)->level == 0 && (pp)->dtype == SATA && \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ((pp)->sas_address[0] >> 4) != 5)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define RESTART_DISCOVERY(pwp) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ASSERT(!mutex_owned(&pwp->config_lock)); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore mutex_enter(&pwp->config_lock); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pwp->config_changed = B_TRUE; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore mutex_exit(&pwp->config_lock); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define RESTART_DISCOVERY_LOCKED(pwp) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ASSERT(mutex_owned(&pwp->config_lock)); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pwp->config_changed = B_TRUE; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PHY_CHANGED(pwp, p) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, p, NULL, "%s changed in " \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore "%s line %d", p->path, __func__, __LINE__); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore p->changed = 1; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore p->enum_attempts = 0
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PHY_CHANGED_AT_LOCATION(pwp, p, func, line) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, p, NULL, "%s changed in " \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore "%s line %d", p->path, func, line); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore p->changed = 1; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore p->enum_attempts = 0
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PHY_TYPE(pptr) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((pptr)->dtype == NOTHING)? "NOTHING" : \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((pptr)->dtype == SATA)? "SATA" : \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (((pptr)->dtype == SAS)? "SAS" : "EXPANDER")))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define IS_ROOT_PHY(pptr) (pptr->parent == NULL)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_HIPRI(pwp, oq, c) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (pwp->hipri_queue & (1 << PMCS_IQ_OTHER)) ? \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (PMCS_IOMB_HIPRI | PMCS_IOMB_IN_SAS(oq, c)) : \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (PMCS_IOMB_IN_SAS(oq, c))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define SCHEDULE_WORK(hwp, wrk) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (void) atomic_set_long_excl(&hwp->work_flags, wrk)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Check to see if the requested work bit is set. Either way, the bit will
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * be cleared upon return.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WORK_SCHEDULED(hwp, wrk) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (atomic_clear_long_excl(&hwp->work_flags, wrk) == 0)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Check to see if the requested work bit is set. The value will not be
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * changed in this case. The atomic_xx_nv operations can be quite expensive
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * so this should not be used in non-DEBUG code.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WORK_IS_SCHEDULED(hwp, wrk) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ((atomic_and_ulong_nv(&hwp->work_flags, (ulong_t)-1) & (1 << wrk)) != 0)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WAIT_FOR(p, t, r) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore clock_t _lb = ddi_get_lbolt(); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore r = 0; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore while (!PMCS_COMMAND_DONE(p)) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore clock_t _ret = cv_timedwait(&p->sleep_cv, \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore &p->lock, _lb + drv_usectohz(t * 1000)); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore if (!PMCS_COMMAND_DONE(p) && _ret < 0) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore r = 1; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore break; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore } \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore }
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Signal the next I/O completion thread to start running.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_CQ_RUN_LOCKED(hwp) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore if (!STAILQ_EMPTY(&hwp->cq) || hwp->iocomp_cb_head) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_cq_thr_info_t *cqti; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore cqti = &hwp->cq_info.cq_thr_info \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore [hwp->cq_info.cq_next_disp_thr]; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hwp->cq_info.cq_next_disp_thr++; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore if (hwp->cq_info.cq_next_disp_thr == \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hwp->cq_info.cq_threads) { \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore hwp->cq_info.cq_next_disp_thr = 0; \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore } \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore mutex_enter(&cqti->cq_thr_lock); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore cv_signal(&cqti->cq_cv); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore mutex_exit(&cqti->cq_thr_lock); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore }
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_CQ_RUN(hwp) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore mutex_enter(&hwp->cq_lock); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore PMCS_CQ_RUN_LOCKED(hwp); \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore mutex_exit(&hwp->cq_lock);
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Watchdog/SCSA timer definitions
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/* usecs to SCSA watchdog ticks */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define US2WT(x) (x)/10
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * More misc
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE0(x) (((x) >> 0) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE1(x) (((x) >> 8) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE2(x) (((x) >> 16) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE3(x) (((x) >> 24) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE4(x) (((x) >> 32) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE5(x) (((x) >> 40) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE6(x) (((x) >> 48) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define BYTE7(x) (((x) >> 56) & 0xff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WORD0(x) (((x) >> 0) & 0xffff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WORD1(x) (((x) >> 16) & 0xffff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WORD2(x) (((x) >> 32) & 0xffff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define WORD3(x) (((x) >> 48) & 0xffff)
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define DWORD0(x) ((uint32_t)(x))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define DWORD1(x) ((uint32_t)(((uint64_t)x) >> 32))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define SAS_ADDR_FMT "0x%02x%02x%02x%02x%02x%02x%02x%02x"
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define SAS_ADDR_PRT(x) x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_VALID_LINK_RATE(r) \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ((r == SAS_LINK_RATE_1_5GBIT) || (r == SAS_LINK_RATE_3GBIT) || \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore (r == SAS_LINK_RATE_6GBIT))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * This is here to avoid inclusion of <sys/ctype.h> which is not lint clean.
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define HEXDIGIT(x) (((x) >= '0' && (x) <= '9') || \
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define NSECS_PER_SEC 1000000000UL
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef void (*pmcs_cb_t) (pmcs_hw_t *, pmcwork_t *, uint32_t *);
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Defines and structure used for tracing/logging information
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TBUF_ELEM_SIZE 120
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TBUF_NUM_ELEMS_DEF 100000
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_TBUF_UA_MAX_SIZE 32
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef struct {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore /* Target-specific data */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint16_t target_num;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char target_ua[PMCS_TBUF_UA_MAX_SIZE];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore /* PHY-specific data */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint8_t phy_sas_address[8];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char phy_path[32];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore pmcs_dtype_t phy_dtype;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore /* Log data */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore timespec_t timestamp;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint64_t fw_timestamp;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore char buf[PMCS_TBUF_ELEM_SIZE];
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore} pmcs_tbuf_t;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Firmware event log header format
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef struct pmcs_fw_event_hdr_s {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_signature;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_entry_start_offset;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_rsvd1;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_buf_size;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_rsvd2;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_oldest_idx;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_latest_idx;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t fw_el_entry_size;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore} pmcs_fw_event_hdr_t;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Firmware event log entry format
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amoretypedef struct pmcs_fw_event_entry_s {
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t num_words : 3,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore reserved : 25,
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore severity: 4;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t ts_upper;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t ts_lower;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t seq_num;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t logw0;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t logw1;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t logw2;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore uint32_t logw3;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore} pmcs_fw_event_entry_t;
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_FWLOG_TIMER_DIV 8 /* fw timer has 8ns granularity */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_FWLOG_AAP1_SIG 0x1234AAAA
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_FWLOG_IOP_SIG 0x5678CCCC
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore/*
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore * Receptacle information
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_NUM_RECEPTACLES 2
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_RECEPT_LABEL_0 "SAS0"
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_RECEPT_LABEL_1 "SAS1"
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_RECEPT_PM_0 "f0"
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#define PMCS_RECEPT_PM_1 "f"
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#ifdef __cplusplus
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore}
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#endif
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore#endif /* _PMCS_DEF_H */
08045defdf65ee890fef6e20510a093a17feb8feGarrett D'Amore