fctl_private.h revision 3e5bc1d795e8c41f3680a71e3954e72d079ee46d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _FCTL_PRIVATE_H
#define _FCTL_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Stuff strictly internal to fctl that
* isn't exposed to any other modules.
*/
(x)[3] + (x)[4] + (x)[5] +\
(x)[6] + (x)[7])
#define FC_ACTION_INVALID -1
#define FC_REASON_INVALID -1
#define FC_EXPLN_INVALID -1
/*
* Internally translated and used state change values to ULPs
*/
#define FC_ULP_STATEC_DONT_CARE 0
#define FC_ULP_STATEC_ONLINE 1
#define FC_ULP_STATEC_OFFLINE 2
#define FC_ULP_STATEC_OFFLINE_TIMEOUT 3
#define FC_ULP_ADD_RETRY_COUNT 90
#define FC_MAX_TRACE_BUF_LEN 512
#define FC_NPIV_MAX_PORT 255
/*
* port_dstate values
*/
#define ULP_PORT_ATTACH 0x01
#define ULP_PORT_SUSPEND 0x02
#define ULP_PORT_POWER_DOWN 0x04
#define ULP_PORT_BUSY 0x08
#define FCTL_DISALLOW_CALLBACKS(x) (!((x) & ULP_PORT_ATTACH) ||\
((x) & ULP_PORT_BUSY))
typedef struct ulp_ports {
int port_dstate;
struct fc_local_port *port_handle;
typedef struct ulp_module {
struct ulp_module *mod_next;
typedef struct ulp_list {
typedef struct fca_port {
struct fc_local_port *port_handle;
typedef struct timed_counter {
struct timed_counter *sig;
/*
* Struct describing a remote node. A remote node is associated with one
* or more remote ports (fc_remote_port_t structs) that are all accessible
* through one local port (fc_local_port_t struct).
*
* Each fc_remote_node_t struct is also referenced by nwwn in the global
* nwwn_hash_table[] list.
*/
typedef struct fc_remote_node {
/*
* Mutex lock to protect access to all members of this struct.
* Current implementation dictates acquisition of fd_mutex before
* pd_mutex can be acquired (when both locks must be acquired).
*/
/* Node WWN for the remote node */
/*
* This is the number of (active) fc_remote_port_t structs that
* are associated with this remote node.
*/
int fd_numports;
/*
* Tracks whether this struct is "valid" or "invalid", using the
* FC_REMOTE_NODE_* values given above.
*/
int fd_flags;
/* Linked list of remote ports associated with this remote node. */
struct fc_remote_port *fd_portlistp;
/*
* Stack depth for troubleshooting (only used in debug code)
*/
#define FC_STACK_DEPTH 14
/*
* The fc_remote_port_t struct represents a remote FC port that is
* accessible via the local FC port (fc_local_port_t). Each remote
* FC port is associated with one FC local port (fc_local_port_t,
* above) and one remote FC node (fc_remote_node_t, see below).
* fc_remote_port_t structs are created and destroyed as needed to
* correspond with changing conditions out on the link.
*/
typedef struct fc_remote_port {
/*
* Ah, the infamous 'pd_mutex' that has given developers so much
* joy over the years....
* (Gotta love the original, extremely helpful comment.)
*/
/*
* Reference count of the # of logins initiated by a ULP
* (i.e., this is the # of ULPs accessing the struct). See
* fp_plogi_group() for more info.
*/
int pd_login_count;
/*
* This appears to track the login state of the remote FC port.
* Used with the PORT_DEVICE_* macros in fc_appif.h.
*/
/*
* Link pointers for the port wwn and D_ID hash lists. These point
* to the next remote port in the current hash chain.
*/
struct fc_remote_port *pd_wwn_hnext;
struct fc_remote_port *pd_did_hnext;
/*
* Link pointer for list of *all* fc_remote_port_t structs
* associated with the same fc_local_port_t struct.
*/
struct fc_remote_port *pd_port_next;
/*
* Pointer to the fc_remote_node_t struct for the remote node
* associated with the remote port.
*/
struct fc_remote_node *pd_remote_nodep;
/* port type for the remote port */
/*
* Back pointer to the fc_local_port_t struct for the local port
* associated with this remote port.
*/
struct fc_local_port *pd_port;
/*
* (Sigh) this actually doesn't have anything to do with the "type"
* of the remote port per se. It's really more an indicator of the
* changed somehow after an event has occurred on the link.
* There also seems to be some connection to the "changed map".
*
* The legal values for this are the PORT_DEVICE_* definitions
* earlier in this file.
*/
/*
* remote port. Legal values are given above.
* See also the pd_state field.
*/
/* Legal values are given above (beware of the mipselling) */
/* This is _SO_ private that even we don't use it */
/*
* This is a count of the number of references to (or holds on)
* this remote port.
*/
int pd_ref_count; /* number of references */
/*
* Re-login disable for FCP-2 error recovery. This is intended to
* help with tape devices when an RSCN or Link Reset occurs during
* a long write operations (like backup). fp's default action is
* to try to log in again, but that forces a rewind on the LUN
* and corrupts its state.
*
* The legal bit values are given below. Some specific definitions
* are as follows:
*
* PD_IN_DID_QUEUE: The fc_remote_port_t is present in the d_id
* hash list of the associated fc_local_port_t. (This
* is apparently meant to cover some races).
* PD_LOGGED_OUT: This is a directive to ignore the NORELOGIN if
* an actual logout occurred
*/
/*
* Count of the # of unsolicited LOGOs received. See the definition
* of FC_LOGO_TOLERANCE_LIMIT in fp.c.
*/
#ifdef DEBUG
int pd_w_depth; /* for WWN hash table */
int pd_d_depth; /* for D_ID hash table */
#endif
/*
* Structs for the global nwwn_hash_table[] entries.
*
* At _init() time, fctl allocates an array of fctl_nwwn_list_t structs that
* has nwwn_table_size entries. The hash_head member anchors a linked
* list of fctl_nwwn_elem_t structs that are linked via the fne_next pointer.
* Each fctl_nwwn_elem_t also contains a pointer to one fc_remote_node_t struct.
*/
typedef struct fctl_nwwn_elem fctl_nwwn_elem_t;
struct fctl_nwwn_elem {
};
typedef struct fctl_nwwn_list {
typedef struct fc_errmap {
int fc_errno;
char *fc_errname;
} fc_errmap_t;
typedef struct fc_pkt_reason {
int reason_val;
char *reason_msg;
typedef struct fc_pkt_action {
int action_val;
char *action_msg;
typedef struct fc_pkt_expln {
int expln_val;
char *expln_msg;
typedef struct fc_pkt_error {
int pkt_state;
char *pkt_msg;
/*
* Values for the fd_flags field in the fc_remote_node_t struct.
* Note, the code seems to rely on the struct initialization using
* kmem_zalloc() to set all the bits to zero, since FC_REMOTE_NODE_INVALID
* is never explicitly set anywhere.
*/
#define FC_REMOTE_NODE_INVALID 0
#define FC_REMOTE_NODE_VALID 1
/*
* Values for the pd_flags field in the fc_remote_port_t struct. These
* are used in a _lot_ of places. NOTE: these are values, not bit flags.
*/
#define PD_IDLE 0x00
#define PD_ELS_IN_PROGRESS 0x01
#define PD_ELS_MARK 0x02
/*
* Bit values for the pd_aux_flags field in the fc_remote_port_t struct.
*/
/* in the D_ID hash list of the */
/* associated fc_local_port_t. (This */
/* is apparently meant to narrow */
/* some race windows). */
#define PD_DISABLE_RELOGIN 0x02
#define PD_NEEDS_REMOVAL 0x04
/* the NORELOGIN if an actual logout */
/* occurred */
/* given to one or more ULPs. */
/*
* Values for the pd_recepient field in the fc_remote_port_t struct.
* Tries to describe where a PLOGI attempt originated.
*/
#define PD_PLOGI_INITIATOR 0
#define PD_PLOGI_RECEPIENT 1
/*
* The fc_local_port_t struct represents a local FC port. It is the softstate
* struct for each fp instance, so it comes into existence at DDI_ATTACH
* and is deleted during DDI_DETACH.
*/
typedef struct fc_local_port {
/*
* Mutex to protect certain data fields in this struct.
*/
/*
* fp_state sort of tracks the state of the link at the local port.
* The actual 'state' is kept in the lower byte, and the port speed
* is kept in the next most significant byte. The code makes
* extensive use of the FC_PORT_SPEED_MASK() and FC_PORT_STATE_MASK()
* macros to separate these two items. The current link topology
* is actually kept separately in the fp_topology field.
* The legal values for fp_state are given above.
*/
/*
* The S_ID for the local port. See fc_types.h for the fc_portid_t
* definition.
*/
/*
* Opaque reference handle for the local port device. This value
* is supplied by the FCA driver and is passed unaltered to
* various FCA driver entry point functions.
*/
/* Entry point vectors for the FCA driver at this FC port */
struct fca_tran *fp_fca_tran;
/*
* fp's homegrown "job" threading mechanism (not a Solaris DDI taskq).
*
* in a driver-private thread. One thread per fc_local_port_t struct.
* The thread is created during DDI_ATTACH for the instance.
*/
struct job_request *fp_job_head;
struct job_request *fp_job_tail;
/*
* Current port topology. Uses the FC_TOP_* values defined in
* fc_appif.h. This is used with the FC_IS_TOP_SWITCH() macro and
* is also used with the FC_TOP_EXTERNAL() macro in the ULPs.
*/
/*
* The fp_task and fp_last_task fields are used mainly in the
* fp_job_handler() function. These are used to indicate when a job
* is executing. They also allow a second job to be issued while
* the current job is still in progress, but only one level of nesting
* is permitted.
*
* The legal values for these fields are given in fp.h
*
* This should not be confused with the Solaris DDI taskq mechanism,
* altho also fp makes use of that in some places (just to keep life
* interesting).
*/
int fp_task; /* current task */
int fp_last_task; /* last task */
/*
* fp_soft_state actually tracks the progression of the fp driver
* in various code paths, particularly in attach, detach, suspend,
* resume, and state change callbacks.
*
* The values for this are defined in fc_portif.h.
*
* This is sometimes used in conjunction with the fp_statec_busy
* field (see below), but there is no direct, 1-to-1 correlation
* in how these are used together.
*/
volatile uint16_t fp_soft_state;
/*
* Software restoration bit fields for (PM)SUSPEND/(PM)RESUME (??)
* Legal values are FP_RESTORE_* in fp.h
*/
/*
* and fp_fciocmd(). See fp.h for legal values.
*/
/*
* Base pointer for hash table of fc_remote_port_t structs (remote
* ports) accessible thru the local port. The table is hashed by
* the D_ID of the remote port.
*/
struct d_id_hash *fp_did_table;
/*
* Base pointer for hash table of fc_remote_port_t structs (remote
* ports) accessible thru the local port. The table is hashed by
* the port WWN of the remote port.
*/
struct pwwn_hash *fp_pwwn_table;
struct kmem_cache *fp_pkt_cache;
int fp_out_fpcmds; /* outstanding fp_cmd # */
/*
* fp_statec_busy tracks the progression of state change
* callbacks within the fp driver. It follows unsolicited callbacks
* and things like the port startup which happens during the attach.
* The value increments when a state change is active and decrements
* when it completes.
*
* The benefit of this is that we should be processing only the
* latest state change and drop the existing one. Coalescing of
* multiple outstanding state changes is NOT performed.
*
* This is accessed in many places in the code, and also is buried
* in some macros (see fp_soft_state above).
*
* IMPORTANT: The code currently permits nested state changes,
* and there is no limitation on the allowed level of nesting.
*/
int fp_statec_busy;
int fp_port_num; /* port number */
int fp_instance; /* instance number */
/*
* Flag to indicate whether or not the ULP attach is in progress. Used
* to synchronize execution of various functions. Seems intended to
* have a value of either zero or one.
*/
int fp_ulp_attach; /* ULP attach done ? */
int fp_dev_count; /* number of devices */
int fp_ptpt_master; /* my WWN is greater */
int fp_ulp_nload; /* count of ULPs */
int fp_total_devices; /* total count */
/*
*/
int fp_els_resp_pkt_busy;
/*
* This is the "state" of the link on the local port, as reported
* by the underlying FCA driver at bind time. This uses the same
* values as fp_state above, including FC_STATE_OFFLINE, FC_STATE_LOOP,
* and FC_PORT_STATE_MASK(port->fp_bind_state).
*/
/*
* Bit field of various parameterized behaviors for the local port.
* CAUTION: there is also an fp global variable called "fp_options"
* that is used to initialize this field during DDI_ATTACH.
*/
/*
* Apparently intended to facilitate reporting the FC_HBA type
* for the local port. Legal values are in fcgs2.h. The
* fc_porttype_t typedef is in fc_types.h
*/
int fp_active_ubs; /* outstanding UBs */
/*
* CV to inform fp "job" thread that there is work to do.
* See fp_job_handler() function.
*/
/*
* Apparently intended to prevent race conditions by holding off any
* DDI_DETACHes for the local port while a ULP attach is in progress.
*/
/*
* Save up the devinfo pointers from Solaris, for performing
* pm_raise_power(), pm_busy_component(), and other DDI friends.
*/
/* This is a real Solaris DDI taskq (not the fp "job" queue) */
int fp_orphan_count; /* number of orphans */
/*
* Current PM power level of the local port device. Values
* are given in fc_portif.h
*/
int fp_pm_level; /* power level */
int fp_pm_busy; /* port busy */
int fp_pm_busy_nocomp; /* busy (no comp) */
/*
* Opaque data for CALLB_CPR_* macros used by the per-local-port
* job thread. Required for safe thread shutdown during PM operations.
*/
char fp_jindex; /* Not used */
char fp_rnid_init; /* init done */
/* T11 FC-HBA data */
int fp_npiv_portnum;
#define FC_NPIV_DISABLE 0
#define FC_NPIV_ENABLE 1
int fp_npiv_flag;
#define FC_NPIV_DELETING 1
int fp_npiv_state;
#define FC_PHY_PORT 0
#define FC_NPIV_PORT 1
int fp_npiv_type;
struct fc_local_port *fp_port_next;
struct fc_local_port *fp_port_prev;
/*
* Struct for the d_id hash table in the fc_local_port_t struct. The code
* allocates memory for an array of D_ID_HASH_TABLE_SIZE elements at
* attach time. The array pointer is saved at the fp_did_table member
* in the fc_local_port_t struct.
* Each hash chain is a singly-linked list of fc_remote_port_t
* structs, using the pd_did_hnext pointer in the fc_remote_port_t struct.
*/
struct d_id_hash {
int d_id_count; /* Count of list entries */
};
/*
* Struct for the pwwn hash table in the fc_local_port_t struct. The code
* allocates memory for an array of PWWN_HASH_TABLE_SIZE elements at
* attach time. The array pointer is saved at the fp_pwwn_table member
* in the fc_local_port_t struct.
* Each hash chain is a singly-linked list of fc_remote_port_t
* structs, using the pd_wwn_hnext pointer in the fc_remote_port_t struct.
*/
struct pwwn_hash {
int pwwn_count; /* Count of list entries */
};
/* Function prototypes */
static dev_info_t *
#ifdef __cplusplus
}
#endif
#endif /* _FCTL_PRIVATE_H */