/*
* 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 2014 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SYS_SCSI_ADAPTERS_SCSI_VHCI_H
#define _SYS_SCSI_ADAPTERS_SCSI_VHCI_H
/*
* Multiplexed I/O SCSI vHCI global include
*/
#include <sys/mdi_impldefs.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
#endif /* _BIT_FIELDS_LTOH */
#ifdef _KERNEL
#ifdef UNDEFINED
#endif
/*
* HBA interface macros
*/
int vhci_do_scsi_cmd(struct scsi_pkt *);
/*PRINTFLIKE3*/
void vhci_log(int, dev_info_t *, const char *, ...);
/*
* debugging stuff
*/
#ifdef DEBUG
#ifndef VHCI_DEBUG_DEFAULT_VAL
#define VHCI_DEBUG_DEFAULT_VAL 0
#endif /* VHCI_DEBUG_DEFAULT_VAL */
extern int vhci_debug;
#else /* !DEBUG */
#endif /* !DEBUG */
}
}
/*
* When a LUN is HELD it results in new IOs being returned to the target
* driver layer with TRAN_BUSY. Should be used while performing
* operations that require prevention of any new IOs to the LUN and
* the LUN should be HELD for the duration of such operations.
* f can be VH_SLEEP or VH_NOSLEEP.
* h is set to 1 to indicate LUN was successfully HELD.
* h is set to 0 when f is VH_NOSLEEP and LUN is already HELD.
*
* Application examples:
*
* 1) SCSI-II RESERVE: HOLD LUN until it is quiesced and the load balancing
* policy is switched to NONE before proceeding with RESERVE handling.
*
* 2) Failover: HOLD LUN before initiating failover.
*
* 3) When an externally initiated failover is detected, HOLD LUN until all
* path states have been refreshed to reflect the new value.
*
*/
int sleep = (f); \
(h) = 1; \
} else { \
(h) = 0; \
} \
} else { \
(h) = 1; \
} \
sleep = (h); \
}
(vlun)->svl_transient = 0; \
}
/*
* vhci_pkt states
*/
/*
* Set the first time taskq is dispatched from scsi_start for
* a packet. To ensure vhci_scsi_start recognizes that the scsi_pkt
* is being issued from the taskq and not target driver.
*/
/*
* Set the first time failover is being triggered. To ensure
* failover won't be triggered again when the packet is being
* retried by target driver.
*/
/*
* define extended scsi cmd pkt
*/
/*
* Maximum size of SCSI cdb in SCSI command
*/
/*
* OSD specific definitions
*/
/*
* flag to determine failover support
*/
#define SCSI_BOTH_FAILOVER \
struct scsi_vhci_swarg;
typedef struct vhci_prin_readkeys {
#define VHCI_PROUT_SIZE \
typedef struct vhci_prout {
/* PGR register parameters start */
#if defined(_BIT_FIELDS_LTOH)
#else
#endif /* _BIT_FIELDS_LTOH */
/* PGR register parameters end */
/* Update VHCI_PROUT_SIZE if new fields are added here */
} vhci_prout_t;
struct vhci_pkt {
/*
* pHCI packet that does the actual work.
*/
/*
* copy of vhci_scsi_init_pkt args. Used when we invoke
* scsi_init_pkt() of the pHCI corresponding to the path that we
* bind to
*/
int vpkt_tgt_init_cdblen;
int vpkt_tgt_init_scblen;
/*
* Pointer to original struct vhci_pkt for cmd send by ssd.
* Saved when the command is being retried internally.
*/
};
typedef struct scsi_vhci_lun {
/*
* following three fields are under svl_mutex protection
*/
int svl_transient;
/*
* to prevent unnecessary failover when a device is
* is discovered across a passive path and active path
* is still comng up
*/
/*
* to keep the failover status in order to return the
* failure status to target driver when targer driver
* retries the command which originally triggered the
* failover.
*/
int svl_failover_status;
/*
*/
/*
* Failover ops and ops name selected for the lun.
*/
char *svl_fops_name;
void *svl_fops_ctpriv;
char *svl_lun_wwn;
/*
* currently active pathclass
*/
char *svl_active_pclass;
/*
* When SCSI-II reservations are active we set the following pip
* to point to the path holding the reservation. As long as
* the reservation is active this svl_resrv_pip is bound for the
* transport directly. We bypass calling mdi_select_path to return
* a pip.
* The following pip is only valid when VLUN_RESERVE_ACTIVE_FLG
* is set. This pip should not be accessed if this flag is reset.
*/
/*
* following fields are for PGR support
*/
/* external failover */
int svl_efo_update_path;
int svl_not_supported;
int svl_sector_size;
int svl_setcap_done;
/*
* This flag is used to monitor the state of SCSI-II RESERVATION on the
* lun. A SCSI-II RESERVE cmd may be accepted by the target on the inactive
* path. This would then cause a subsequent IO to cause the paths to be
* updated and be returned with a reservation conflict. By monitoring this
* flag, and sending a reset to the target when needed to clear the reservation,
* one can avoid this conflict.
*/
/*
* This flag is set when a SCSI-II RESERVE cmd is received by scsi_vhci
* and cleared when the pkt completes in vhci_intr. It ensures that the
* lun remains quiesced for the duration of this pkt. This is different
* from VHCI_HOLD_LUN as this pertains to IOs only.
*/
/*
* This flag is set to tell vhci_update_pathstates to call back
* into vhci_mpapi_update_tpg_acc_state.
*/
/*
* Various reset recovery depth.
*/
#define FALSE (0)
/*
* this is stashed away in the client private area of
* pathinfo
*/
typedef struct scsi_vhci_priv {
/*
* scsi device associated with this
* pathinfo
*/
/*
* number of outstanding commands on this
* path. Protected by svp_mutex
*/
int svp_cmds;
/*
* following is used to prevent packets completing with the
* same error reason from flooding the screen
*/
/* external failover scsi_watch token */
/* any cleanup operations for a newly found path. */
int svp_new_path;
/*
* argument to scsi_watch callback. Used for processing
* externally initiated failovers
*/
typedef struct scsi_vhci_swarg {
int svs_release_lun;
int svs_done;
/*
* scsi_vhci softstate
*
* vhci_mutex protects
* vhci_state
* and vhci_reset_notify list
*/
struct scsi_vhci {
/*
* This taskq is for general vhci operations like reservations,
* auto-failback, etc.
*/
/* Dedicate taskq to handle external failovers */
};
/*
* vHCI flags for configuration settings, defined in scsi_vhci.conf
*/
typedef enum {
/*
* structure describing operational characteristics of
* path
*/
struct scsi_path_opinfo {
int opinfo_rev;
/*
* name of pathclass. Eg. "primary", "secondary"
*/
/*
*/
/*
* the best and worst case time estimates for
* failover operation to complete
*/
/* XLF implementation */
int opinfo_xlf_capable;
};
/*
* vectors for device specific failover related operations
*/
struct scsi_failover_ops {
int sfo_rev;
/*
* failover module name, begins with "f_"
*/
char *sfo_name;
/*
* devices supported by failover module
*
* NOTE: this is an aproximation, sfo_device_probe has the final say.
*/
char **sfo_devices;
/*
* initialize the failover module
*/
void (*sfo_init)();
/*
* identify device
*/
int (*sfo_device_probe)(
struct scsi_device *sd,
struct scsi_inquiry *stdinq,
void **ctpriv);
/*
* housekeeping (free memory etc alloc'ed during probe
*/
void (*sfo_device_unprobe)(
struct scsi_device *sd,
void *ctpriv);
/*
* bring a path ONLINE (ie make it ACTIVE)
*/
int (*sfo_path_activate)(
struct scsi_device *sd,
char *pathclass,
void *ctpriv);
/*
* inverse of above
*/
int (*sfo_path_deactivate)(
struct scsi_device *sd,
char *pathclass,
void *ctpriv);
/*
* returns operational characteristics of path
*/
int (*sfo_path_get_opinfo)(
struct scsi_device *sd,
struct scsi_path_opinfo *opinfo,
void *ctpriv);
/*
* verify path is operational
*/
int (*sfo_path_ping)(
struct scsi_device *sd,
void *ctpriv);
/*
* analyze SENSE data to detect externally initiated
* failovers
*/
int (*sfo_analyze_sense)(
struct scsi_device *sd,
void *ctpriv);
/*
* return the next pathclass in order of preference
* eg. "secondary" comes after "primary"
*/
int (*sfo_pathclass_next)(
char *cur,
char **nxt,
void *ctpriv);
};
/*
* Names of (too) 'well-known' failover ops.
* NOTE: consumers of these names should look for a better way...
*/
/*
* Macro to provide plumbing for basic failover module
*/
&mod_miscops, sfo_name \
}; \
static struct modlinkage modlinkage = { \
}; \
int _init() \
{ \
return (mod_install(&modlinkage)); \
} \
int _fini() \
{ \
return (mod_remove(&modlinkage)); \
} \
{ \
} \
static int local_name##_device_probe( \
struct scsi_device *, \
struct scsi_inquiry *, void **); \
static void local_name##_device_unprobe( \
struct scsi_device *, void *); \
static int local_name##_path_activate( \
struct scsi_device *, char *, void *); \
static int local_name##_path_deactivate( \
struct scsi_device *, char *, void *); \
static int local_name##_path_get_opinfo( \
struct scsi_device *, \
struct scsi_path_opinfo *, void *); \
static int local_name##_path_ping( \
struct scsi_device *, void *); \
static int local_name##_analyze_sense( \
struct scsi_device *, \
uint8_t *, void *); \
static int local_name##_pathclass_next( \
char *, char **, void *); \
SFO_REV, \
sfo_name, \
local_name##_dev_table, \
NULL, \
local_name##_path_ping, \
}
#ifdef lint
#else /* lint */
#endif /* lint */
/*
* Return values for sfo_device_probe
*/
/* return values for sfo_analyze_sense() */
#define SCSI_SENSE_NOFAILOVER 0
/* vhci_intr action codes */
#define JUST_RETURN 0
#if defined(_SYSCALL32)
/*
* 32 bit variants of sv_path_info_prop_t and sv_path_info_t;
* To be used only in the driver and NOT applications
*/
typedef struct sv_path_info_prop32 {
typedef struct sv_path_info32 {
union {
} device;
typedef struct sv_iocdata32 {
typedef struct sv_switch_to_cntlr_iocdata32 {
#endif /* _SYSCALL32 */
#endif /* _KERNEL */
/*
* Userland (Non Kernel) definitions start here.
* Multiplexed I/O SCSI vHCI IOCTL Definitions
*/
/*
* IOCTL structure for path properties
*/
typedef struct sv_path_info_prop {
/*
* Max buffer size of getting path properties
*/
/*
* String values for "path-class" property
*/
#define PCLASS_NONPREFERRED 0
/*
* IOCTL structure for path information
*/
typedef struct sv_path_info {
union {
} device;
/*
* IOCTL argument structure
*/
typedef struct sv_iocdata {
} sv_iocdata_t;
/*
* IOCTL argument structure for switching controllers
*/
typedef struct sv_switch_to_cntlr_iocdata {
/*
* IOCTL definitions
*/
#ifdef DEBUG
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SCSI_ADAPTERS_SCSI_VHCI_H */