2002 lines
71 KiB
C
2002 lines
71 KiB
C
/***************************************************************************
|
|
* Copyright 2004 - 2009 VMware, Inc. All rights reserved.
|
|
***************************************************************************/
|
|
|
|
/*
|
|
* @VMKAPIMOD_LICENSE@
|
|
*/
|
|
|
|
/*
|
|
***********************************************************************
|
|
* MPP */ /**
|
|
* \addtogroup Storage
|
|
* @{
|
|
* \defgroup MPP Multi-Pathing Plugin Interfaces
|
|
* @{
|
|
***********************************************************************
|
|
*/
|
|
|
|
#ifndef _VMKAPI_MPP_H_
|
|
#define _VMKAPI_MPP_H_
|
|
|
|
/** \cond never */
|
|
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
|
|
#error This vmkapi file should never be included directly but only via vmkapi.h
|
|
#endif
|
|
/** \endcond never */
|
|
|
|
#include "base/vmkapi_heap.h"
|
|
#include "base/vmkapi_memory.h"
|
|
#include "base/vmkapi_status.h"
|
|
#include "base/vmkapi_types.h"
|
|
#include "base/vmkapi_const.h"
|
|
#include "base/vmkapi_revision.h"
|
|
#include "scsi/vmkapi_scsi.h"
|
|
#include "scsi/vmkapi_scsi_mgmt_types.h"
|
|
#include "scsi/vmkapi_scsi_ext.h"
|
|
#include "scsi/vmkapi_scsi_const.h"
|
|
#include "scsi/vmkapi_scsi_types.h"
|
|
#include "mpp/vmkapi_mpp_types.h"
|
|
|
|
/** \cond never */
|
|
#define VMK_SCSI_REVISION_MAJOR 1
|
|
#define VMK_SCSI_REVISION_MINOR 0
|
|
#define VMK_SCSI_REVISION_UPDATE 0
|
|
#define VMK_SCSI_REVISION_PATCH_LEVEL 0
|
|
|
|
#define VMK_SCSI_REVISION VMK_REVISION_NUMBER(VMK_SCSI)
|
|
/** \endcond never */
|
|
|
|
/** \brief Max length of vendor name string including terminating nul. */
|
|
#define VMK_SCSI_VENDOR_NAME_LENGTH (VMK_SCSI_INQUIRY_VENDOR_LENGTH + 1)
|
|
|
|
//** \brief Max length of model name string including terminating nul. */
|
|
#define VMK_SCSI_MODEL_NAME_LENGTH (VMK_SCSI_INQUIRY_MODEL_LENGTH + 1)
|
|
|
|
/** \brief Default name used for unregistered devices */
|
|
#define VMK_SCSI_UNREGISTERED_DEV_NAME "Unregistered Device"
|
|
|
|
/**
|
|
* \brief Choices for probe rate for vmk_ScsiSetDeviceProbeRate.
|
|
*/
|
|
typedef enum {
|
|
/** \brief For normal operation (once/5 Sec.) */
|
|
VMK_SCSI_PROBE_RATE_DEFAULT = 1,
|
|
/** \brief Selected when the device is in APD (once/Sec.) */
|
|
VMK_SCSI_PROBE_RATE_FAST = 2
|
|
} vmk_ScsiDeviceProbeRate;
|
|
|
|
/**
|
|
* \brief Flags defined for vmk_ScsiSetDeviceProbeRate
|
|
*/
|
|
typedef enum {
|
|
/** \brief Revert to VMK_SCSI_PROBE_RATE_DEFAULT after next probe. */
|
|
VMK_SCSI_ONE_PROBE_ONLY = 0x00000001
|
|
} vmk_ScsiSetDeviceProbeRateOption;
|
|
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetCachedPathStandardUID -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the cached NAA, EUI, IQN, or TIO UID for physical path.
|
|
*
|
|
* The function returns the cached UID saved with the path as recorded
|
|
* during the last rescan (since rescans will cause UIDs of all paths
|
|
* to be verified). Success may be returned even if the path to the
|
|
* device is not working. Plugins can use this API function in the
|
|
* plugin's \em pathClaim entrypoint.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to obtain cached UID for.
|
|
* \param[out] uid Obtained UID on success.
|
|
*
|
|
* \retval VMK_BAD_PARAM The passed in path or uid was null.
|
|
* \retval VMK_FAILURE The path does not have a standard UID.
|
|
* \retval VMK_OK Otherwise.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetCachedPathStandardUID(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiUid *uid);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiReadPathStandardUID -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Read the NAA, EUI, IQN, or TIO UID for physical path from
|
|
* the device.
|
|
*
|
|
* This function reads the UID from the SCSI device logical unit
|
|
* that the path refers to and will return failure if the path is
|
|
* not working. This API function is useful to check whether the UID
|
|
* for a given path has changed; for example, in the plugin's
|
|
* \em pathProbe entrypoint.
|
|
*
|
|
* \note This will regenerate the UID saved with the path.
|
|
* \note This is a blocking call.
|
|
*
|
|
* \param[in] path Path to acquire standard UID for.
|
|
* \param[out] uid Obtained UID on success.
|
|
*
|
|
* \retval VMK_OK The UID was successfully obtained.
|
|
* \retval VMK_BAD_PARAM The passed in path or uid was null.
|
|
* \retval Other Failed to obtain the UID.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiReadPathStandardUID(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiUid *uid);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiVerifyPathUID -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Re-read path standard or legacy UID and verify that
|
|
* it did not change.
|
|
*
|
|
* This function will reread the standard path UID from the device and
|
|
* compare it against the cached UID obtained during the last rescan.
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \param[in] path Path to check UID for.
|
|
* \param[out] uid UID read from disk.
|
|
*
|
|
* \retval VMK_OK UID was generated and did not change.
|
|
* \retval VMK_UID_CHANGED New UID was detected.
|
|
* \retval VMK_NO_CONNECT Path connectivity has failed.
|
|
* \retval VMK_BAD_PARAM vmkPath or uid is NULL.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiVerifyPathUID(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiUid *uid);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiComputeUidFromEvpd83 -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get NAA, EUI, IQN, or TIO UID for physical device using
|
|
* caller supplied inquiry evpd page 0x83 data.
|
|
*
|
|
* This function will compute the UID from the passed in evpd83Buf.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The size of the \em evpd83Buf has to to be at least as big as
|
|
* indicated by its 16-bit page length field.
|
|
*
|
|
* \param[in] vmkPath Path to acquire inquiry evpd page 0x83.
|
|
* \param[in] evpd83Buf Buffer to store evpd page 0x83 data.
|
|
* \param[out] uid UID.
|
|
*
|
|
* \retval VMK_OK UID was generated and did not change.
|
|
* \retval VMK_FAILURE No usable UID type (NAA/EUI/IQN/T10)
|
|
* was found in the passed buffer.
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus
|
|
vmk_ScsiComputeUidFromEvpd83(
|
|
vmk_ScsiPath *vmkPath,
|
|
vmk_uint8 *evpd83Buf,
|
|
vmk_ScsiUid *uid);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathTransportUID -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get Path Transport UID for the physical path.
|
|
*
|
|
* This function will obtain a pair of UIDs - one UID for the HBA
|
|
* endpoint and one for the target endpoint of the path. The UID is
|
|
* transport dependent - for FC each endpoint will be of the form
|
|
* WWNN:WWPN and for other transports each endpoint will be whatever
|
|
* unique identifier is used in place for traditional target IDs
|
|
* (e.g. for iSCSI each endpoint will be an IQN).
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to acquire transport uids for.
|
|
* \param[out] uid Obtained UIDs on success.
|
|
*
|
|
* \retval VMK_OK UID successfully obtained.
|
|
* \retval VMK_BAD_PARAM Either path or uid is NULL.
|
|
* \retval VMK_NOT_FOUND The UIDs could not be obtained.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetPathTransportUID(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiPathUid *uid);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiUIDsAreEqual -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief compare two uids and return true if they are equal.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] uid1 First UID to compare.
|
|
* \param[in] uid2 Second UID to compare.
|
|
*
|
|
* \retval VMK_TRUE The UIDs are equal.
|
|
* \retval VMK_FALSE The UIDs are not equal.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_Bool vmk_ScsiUIDsAreEqual(
|
|
vmk_ScsiUid *uid1,
|
|
vmk_ScsiUid *uid2);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiAllocateDevice -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Allocate a logical storage device data structure.
|
|
*
|
|
* This function will allocate space for a vmk_ScsiDevice structure.
|
|
* Obtaining this structure also ensure that the call to register
|
|
* the device will not fail due to max. number of devices already
|
|
* registered. Since the success of this call takes up a slot for a
|
|
* registered SCSI device it is important that such allocations are
|
|
* not left around idle, but are either fully registered or freed
|
|
* again as soon as possible through vmk_ScsiFreeDevice().
|
|
*
|
|
* \see vmk_ScsiFreeDevice().
|
|
*
|
|
* \see vmk_ScsiRegisterDevice().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note The call also allocates and initializes various associated
|
|
* VMkernel private data structures.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \post The obtained device MUST be freed through vmk_ScsiFreeDevice().
|
|
*
|
|
* \param[in] plugin Plugin allocating the device.
|
|
*
|
|
* \return Pointer to vmk_ScsiDevice or NULL if allocation fails or
|
|
* if max. number of SCSI devices are already registered.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiDevice *vmk_ScsiAllocateDevice(
|
|
vmk_ScsiPlugin *plugin);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiRegisterDevice -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Add a logical storage device.
|
|
*
|
|
* This function will attempt to register a logical SCSI device with
|
|
* the VMkernel. There must be at least one UID passed in and precisely
|
|
* one of the UIDs must have \em VMK_SCSI_UID_FLAG_PRIMARY set in its
|
|
* \em uid->idFlags. The \em device->ops field must point to a structure
|
|
* filled with at least the \em startCommand, \em taskMgmt, \em open,
|
|
* \em close, \em probe, \em getInquiry, \em issueDumpCmd,
|
|
* \em isPseudoDevice and \em u.mpDeviceOps.getPathnames function
|
|
* pointers.
|
|
*
|
|
* \see vmk_ScsiDeviceUIDAdd().
|
|
* vmk_ScsiUnregisterDevice().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note The plugin will be pinned (unable to unload) until the device
|
|
* has been unregistered again
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \pre The caller MUST have obtained the passed vmk_ScsiDevice
|
|
* through a call to vmk_ScsiAllocatedevice().
|
|
* \pre The device MUST be ready to accept I/O when the call is made.
|
|
*
|
|
* \param[in] device Device to register.
|
|
* \param[in] uid Pointer to an array of numUids uids
|
|
* to register for this device.
|
|
* \param[in] numUids Number of UIDs in the **uid list.
|
|
*
|
|
* \retval VMK_OK Device successfully registered.
|
|
* \retval VMK_BAD_PARAM The value of numUids is less than 1,
|
|
* there is not exactly one uid marked
|
|
* with the VMK_SCSI_UID_FLAG_PRIMARY,
|
|
* the device->ops are not specified
|
|
* correctly, or same as
|
|
* vmk_ScsiDeviceUIDAdd().
|
|
* \retval VMK_NOT_SUPPORTED The plugin controlling the device
|
|
* is not marked as
|
|
* VMK_SCSI_PLUIGN_TYPE_MULTIPATHING
|
|
* or same as vmk_ScsiDeviceUIDAdd().
|
|
* \retval VMK_NOT_FOUND No paths are specified for the device.
|
|
* \retval VMK_EXISTS Same as vmk_ScsiDeviceUIDAdd().
|
|
* \retval VMK_DUPLIATE_UID Same as vmk_ScsiDeviceUIDAdd().
|
|
* \retval VMK_TOO_MANY_ELEMENTS Same as vmk_ScsiDeviceUIDAdd().
|
|
* \retval VMK_FAILURE Could not determine the legacy UID
|
|
* for the device.
|
|
* \retval VMK_NO_CONNECT A path to the device is in the
|
|
* process of being removed.
|
|
* \retval VMK_TIMEOUT I/O command did not complete within
|
|
* the timeout time due to a transient
|
|
* errors.
|
|
* \retval VMK_ABORTED I/O command did not complete and
|
|
* was aborted.
|
|
* \retval VMK_BUSY I/O command did not complete because
|
|
* the device was busy or there was a
|
|
* race to register/unregister the same
|
|
* device with another thread.
|
|
* \retval VMK_RESERVATION_CONFLICT I/O command did not complete due
|
|
* to a SCSI reservation on the device.
|
|
* \retval VMK_STORAGE_RETRY_OPERATION I/O command did not complete
|
|
* due to a transient error.
|
|
* \retval VMK_HBA_ERROR I/O command did not complete due
|
|
* to an HBA or driver error.
|
|
* \retval VMK_IO_ERROR I/O command did not complete due
|
|
* to an unknown error.
|
|
* \retval VMK_NOT_SUPPORTED I/O command did not complete due
|
|
* to an unspecified error.
|
|
* \retval VMK_MEDIUM_NOT_FOUND I/O command did not complete on a
|
|
* removeable media device and media
|
|
* is not present.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiRegisterDevice(
|
|
vmk_ScsiDevice *device,
|
|
vmk_ScsiUid **uid,
|
|
vmk_int32 numUids);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiUnregisterDevice -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Remove a logical storage device.
|
|
*
|
|
* This function will wait for outstanding Task Management operations
|
|
* on the device to drain before finally unregistering the device.
|
|
* If the device is open by any world the call will fail.
|
|
*
|
|
* \see vmk_ScsiRegisterDevice().
|
|
* \see vmkScsiFreeDevice().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note The caller should not hold any semaphores.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \pre The device MUST have been successfully registered with a call
|
|
* to vmk_ScsiRegisterDevice().
|
|
*
|
|
* \param[in] device Device to unregister.
|
|
*
|
|
* \retval VMK_OK Device successfully unregistered.
|
|
* \retval VMK_BUSY Device not unregistered as the device
|
|
* was busy.
|
|
* \retval VMK_BAD_PARAM Device has already been unregistered.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiUnregisterDevice(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiFreeDevice -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Free the storage associated with a logical storage device.
|
|
*
|
|
* This function will undo the work of vmk_ScsiAllocateDevice() and
|
|
* will both free the structure and also clean up some associated
|
|
* VMkernel internal structures. Among this is the freeing of the
|
|
* device "slot" that will limit the total number of allocated devices.
|
|
* It is therefore important that this function is used to free the
|
|
* vmk_ScsiDevice structure allocated through vmk_ScsiAllocateDevice().
|
|
*
|
|
* \see vmk_ScsiUnregisterDevice().
|
|
* \see vmk_ScsiAllocateDevice().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \pre The device MUST have been unregistered (or never registered).
|
|
*
|
|
* \param[in] device Device to free.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiFreeDevice(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSetDeviceState-- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Set current device state.
|
|
*
|
|
* This function allows a plugin to set the state of a device. The
|
|
* intent of this call is to allow the user to see the state of a
|
|
* device through the UI or CLI.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note No actions are currently taken by the PSA on changes to the
|
|
* device state. However this could change in a future release
|
|
* to add some events to notify upper layers (or VOB notifications)
|
|
* of device state changes. Decisions on whether to issue I/Os
|
|
* to the devices are NOT made on the basis of the device state.
|
|
*
|
|
* \param[in] device Device whose state should be set.
|
|
* \param[in] state The new state of the device.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiSetDeviceState(
|
|
vmk_ScsiDevice *device,
|
|
vmk_ScsiDeviceState state);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiDeviceStateToString -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Convert a device state into a human readable text string.
|
|
*
|
|
* \see vmk_ScsiSetDeviceState().
|
|
* \see vmk_ScsiGetDeviceState().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] state Device state to convert to string.
|
|
*
|
|
* \return String with human readable representation of device state.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
const char *vmk_ScsiDeviceStateToString(
|
|
vmk_ScsiDeviceState state);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetDeviceState -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the current device state.
|
|
*
|
|
* \see vmk_ScsiSetDeviceState().
|
|
* \see vmk_ScsiDeviceStateToString().
|
|
*
|
|
* \note The purpose of having a common device state is to show
|
|
* consistent information to the user. Plugins may have command
|
|
* line tools that display among other things the plugin device
|
|
* state. The recommendation is to use vmk_ScsiGetDeviceState()
|
|
* and vmk_ScsiDeviceStateToString() to return consistent
|
|
* information.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] device Device whose state to acquire.
|
|
*
|
|
* \return Device's state
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiDeviceState vmk_ScsiGetDeviceState(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetDeviceClass -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the current device class.
|
|
*
|
|
* This function returns the device class of the device, which is
|
|
* mostly according to the SCSI spec, but a few unsupported types
|
|
* have been "overloaded" - VMK_IDE_CLASS_CDROM is a synonym for
|
|
* VMK_SCSI_CLASS_ASCA and VMK_IDE_CLASS_OTHER is a synonym for
|
|
* VMK_SCSI_CLASS_ASCB.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] device Device whose class to acquire.
|
|
*
|
|
* \return Integer representing device class
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiDeviceClass vmk_ScsiGetDeviceClass(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetDeviceNumBlocks -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Return the number of blocks as reported by Read Capacity.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] device Device whose # of blocks to acquire.
|
|
*
|
|
* \return The number of blocks.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_uint64 vmk_ScsiGetDeviceNumBlocks(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetDeviceBlockSize -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Return the block size as reported by Read Capacity.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] device Device whose block size to acquire.
|
|
*
|
|
* \return The block size used by the device.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_uint32 vmk_ScsiGetDeviceBlockSize(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetDeviceMaxQDepth -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Return the maximum number of I/Os queueable to the MPP by
|
|
* the framework.
|
|
*
|
|
* This function will get the queue depth of the logical device
|
|
* registered with the PSA layer and will be the maximum number of
|
|
* I/Os that is allowed to be outstanding to the logical device's
|
|
* owning MP plugin.
|
|
*
|
|
* \see vmk_ScsiSetDeviceMaxQDepth().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This is \b not the maximum queue depth on the physical device.
|
|
* \note You may see less I/Os queued on the logical device even when
|
|
* multiple VMs are very busy on a VMFS volume. This is due to
|
|
* the throttling mechanism in ESX that ensure fairness.
|
|
*
|
|
* \param[in] device Device to acquire max. queue depth for.
|
|
*
|
|
* \return Device's queue depth.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_uint16 vmk_ScsiGetDeviceMaxQDepth(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSetDeviceMaxQDepth -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Set the maximum number of I/Os queuable to the MPP by
|
|
* the framework.
|
|
*
|
|
* This function will set the queue depth of the logical device
|
|
* registered with the PSA layer. It will be the maximum number of
|
|
* I/Os that is allowed to be outstanding on the logical device.
|
|
* A MPP plugin can use this to increase the number of I/Os if it
|
|
* needs to distribute them on many paths (load balancing).
|
|
*
|
|
* \see vmk_ScsiGetDeviceMaxQDepth().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This is \b not the maximum queue depth on the physical device.
|
|
* \note You may see less I/Os queued on the logical device even when
|
|
* multiple VMs are very busy on a VMFS volume. This is due to
|
|
* the throttling mechanism in ESX that ensure fairness.
|
|
*
|
|
* \param[in] device Device whose max queueing depth to set.
|
|
* \param[out] qDepth Depth to set.
|
|
*
|
|
* \retval VMK_OK The queue depth was successfully changed.
|
|
* \retval VMK_BAD_PARAM The qDepth parameter value was 0.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiSetDeviceMaxQDepth(
|
|
vmk_ScsiDevice *device,
|
|
vmk_uint16 qDepth);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSetDeviceProbeRate -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Set a device's periodic path state update rate.
|
|
*
|
|
* This function can select one of two probe rates for a logical device.
|
|
* The fast probe rate would normally be requested in case of path
|
|
* failures to quickly get an update of how many paths are affected.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The device should be probed at least as frequently as specified
|
|
* but may be probed more frequently than specified.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \param[in] vmkDevice Targeted device.
|
|
* \param[in] newProbeRate New probe rate ("DEFAULT" or "FAST").
|
|
* \param[in] flags Specifies any options, such as
|
|
* VMK_SCSI_ONE_PROBE_ONLY.
|
|
*
|
|
* \retval VMK_OK Probe rate set successfully.
|
|
* \retval VMK_BAD_PARAM A new probe rate other than
|
|
* VMK_SCSI_PROBE_RATE_DEFAULT or VMK_SCSI_PROBE_RATE_FAST
|
|
* was requested.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiSetDeviceProbeRate(
|
|
vmk_ScsiDevice *vmkDevice,
|
|
vmk_ScsiDeviceProbeRate newProbeRate,
|
|
vmk_uint32 flags);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSwitchDeviceProbeRate -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Set a device's periodic path state update rate and
|
|
* return the current probe rate settings.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The device should be probed at least as frequently as
|
|
* specified but may be probed more frequently than specified.
|
|
*
|
|
* \param[in] vmkDevice Targeted device.
|
|
* \param[in] newProbeRate New probe rate
|
|
* ("DEFAULT" or "FAST").
|
|
* \param[in] flags Options if any
|
|
* (i.e. VMK_SCSI_ONE_PROBE_ONLY).
|
|
* \param[out] currentProbeRate Probe rate prior to this call.
|
|
* \param[out] currentProbeRateFlags Probe flags prior to this call.
|
|
*
|
|
* \retval VMK_OK Probe rate set successfully.
|
|
* \retval VMK_BAD_PARAM A new probe rate other than
|
|
* VMK_SCSI_PROBE_RATE_DEFAULT or VMK_SCSI_PROBE_RATE_FAST
|
|
* was requested.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiSwitchDeviceProbeRate(
|
|
vmk_ScsiDevice *vmkDevice,
|
|
vmk_ScsiDeviceProbeRate newProbeRate,
|
|
vmk_ScsiSetDeviceProbeRateOption flags,
|
|
vmk_ScsiDeviceProbeRate *currentProbeRate,
|
|
vmk_ScsiSetDeviceProbeRateOption *currentProbeRateFlags);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetDeviceName -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the logical device's name.
|
|
*
|
|
* This function can be used to provide a consistent device name
|
|
* among logs from PSA and MP plugins.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] device Device to acquire name for.
|
|
*
|
|
* \return The name of the device as a human readable string.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
const char *vmk_ScsiGetDeviceName(
|
|
vmk_ScsiDevice *device);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiDeviceUIDAdd -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Add a UID to a device.
|
|
*
|
|
* Valid UIDs (vmk_ScsiUid.id) are nul-terminated C strings that
|
|
* may contain only the following characters:
|
|
* - '0' through '9'
|
|
* - 'a' through 'z'
|
|
* - 'A' through 'Z'
|
|
* - '_', ':', ',', '.'
|
|
*
|
|
* Valid UIDs should be persistent across power cycles, HBA
|
|
* reordering, and SAN reconfiguration. Additionally, a valid UID
|
|
* should be the same on all ESX hosts that can access the same
|
|
* physical storage. This function can only be called on a registered
|
|
* device. Only one UID of type Primary ID is permitted.
|
|
*
|
|
* \note This function can only be called for registered devices.
|
|
* \note This is a non-blocking call.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \param[in] vmkDevice Device to add uid to.
|
|
* \param[in] uidToAdd UID to add to device.
|
|
*
|
|
* \retval VMK_OK The UID was successfully added.
|
|
* \retval VMK_EXISTS The UID matches the uid of a
|
|
* different device.
|
|
* \retval VMK_BAD_PARAM The UID has invalid flags or is
|
|
* composed of disallowed characters.
|
|
* \retval VMK_DUPLICATE_UID The UID to be added to the device is
|
|
* already associated with the device.
|
|
* \retval VMK_TOO_MANY_ELEMENTS UID to be added is a primary UID and
|
|
* the device already has a primary UID.
|
|
* \retval VMK_NOT_SUPPORTED The specified device is unregistered.
|
|
* \retval VMK_NAME_TOO_LONG UID is too long (>128 bytes).
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiDeviceUIDAdd(
|
|
vmk_ScsiDevice *vmkDevice,
|
|
vmk_ScsiUid *uidToAdd);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiDeviceUIDRemove -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Remove a UID from a device.
|
|
*
|
|
* \see vmk_ScsiDeviceUIDAdd().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \param[in] device Device to remove UID from.
|
|
* \param[in] uidToRemove UID to remove from device.
|
|
*
|
|
* \retval VMK_OK The UID was successfully removed.
|
|
* \retval VMK_READ_ONLY The UID is the primary uid or a legacy UID
|
|
* for a device and cannot be removed.
|
|
* \retval VMK_NOT_FOUND The UID is not associated with the device.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiDeviceUIDRemove(
|
|
vmk_ScsiDevice *device,
|
|
vmk_ScsiUid *uidToRemove);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathState-- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Return current path state.
|
|
*
|
|
* This function returns the current path state. It does not block
|
|
* nor does it acquire another spin lock. So it is safe to call it
|
|
* while holding a spin lock without having to worry about blocking
|
|
* or lock ranking issues.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to get state for.
|
|
*
|
|
* \return The state of the path.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiPathState
|
|
vmk_ScsiGetPathState(vmk_ScsiPath *path);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSetPathState-- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Set PSA framework current path state.
|
|
*
|
|
* This function may only be called by the MP Plugin that is
|
|
* managing the path. Other callers wishing to change a path's
|
|
* state should instead use vmk_ScsiSetPluginPathState(). This
|
|
* function exists so that an MP Plugin may notify the PSA
|
|
* framework of a path state change. vmk_ScsiSetPluginPathState()
|
|
* exists so that other callers can notify the MP Plugin of a
|
|
* path state change (with the expectation that the MP Plugin will
|
|
* duly call vmk_ScsiSetPathState() after doing any internal
|
|
* bookkeeping).
|
|
*
|
|
* \see vmk_ScsiGetPathState().
|
|
* \see vmk_ScsiSetPluginPathState().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] plugin Plugin that owns the path.
|
|
* \param[in] path Path to set state on.
|
|
* \param[in] state State to set.
|
|
*
|
|
* \retval VMK_OK The path state was successfully set.
|
|
* \retval VMK_NO_PERMISSION The plugin is not the owner of the path.
|
|
* \retval VMK_BAD_PARAM The path state was invalid.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiSetPathState(
|
|
vmk_ScsiPlugin *plugin,
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiPathState state);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSetPluginPathState-- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Set MP Plugin current path state.
|
|
*
|
|
* This function may only be called by non-MP Plugin callers. An
|
|
* MP Plugin wishing to change a path's state should instead use
|
|
* vmk_ScsiSetPathState(). This function exists so that
|
|
* non-MP Plugin callers can notify a plugin of a path state
|
|
* change. vmk_ScsiSetPluginState() exists so that an MP Plugin
|
|
* can notify the PSA framework of a path state change, with the
|
|
* expectation that the MP Plugin will duly call
|
|
* vmk_ScsiSetPathState() after its internal bookkeeping as a
|
|
* of vmk_ScsiSetPluginPathState(). The path state change is
|
|
* limited to admistrative change only to enable a disabled path
|
|
* and vice versa.
|
|
*
|
|
* \see vmk_ScsiSetPathState().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note Only VMK_SCSI_PATH_STATE_{ON/OFF} are allowed.
|
|
*
|
|
* \param[in] path Path to set state on.
|
|
* \param[in] state State to set.
|
|
*
|
|
* \retval VMK_OK Path state was successfully set.
|
|
* \retval VMK_BAD_PARAM Invalid path state was passed.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiSetPluginPathState(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiPathState state);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiPathStateToString-- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get a text string describing the current path state.
|
|
*
|
|
* \see vmk_ScsiGetPathState().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] state State to convert to string.
|
|
*
|
|
* \return Human-readable string describing the path state or
|
|
* "Unknown path state" in case an invalid path state is passed.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
const char *vmk_ScsiPathStateToString(
|
|
vmk_ScsiPathState state);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathLUN -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get path LUN.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to acquire logical unit number.
|
|
*
|
|
* \return LUN for the given path.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_int32 vmk_ScsiGetPathLUN(
|
|
vmk_ScsiPath *path);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathTarget -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get path target.
|
|
*
|
|
* \note This is the target ID as returned from the driver layer and
|
|
* in case of FC/iSCSI this is thus a logical mapping of the
|
|
* real target ID (which is a WWNN or IQN).
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to acquire target id for.
|
|
*
|
|
* \return Target ID for the given path.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_int32 vmk_ScsiGetPathTarget(
|
|
vmk_ScsiPath *path);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathChannel -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get path Channel.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to acquire channel number.
|
|
*
|
|
* \return Channel number for the given path.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_int32 vmk_ScsiGetPathChannel(
|
|
vmk_ScsiPath *path);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathAdapter -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get path's Adapter name.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] path Path to acquire adapter name for.
|
|
*
|
|
* \return Adapter name for the given path.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
const char *vmk_ScsiGetPathAdapter(
|
|
vmk_ScsiPath *path);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetAdapterTransport -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the adapter transport name.
|
|
*
|
|
* Get the adapter transport type (fc/iscsi/..) as a printable string.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] adapName Adapter to acquire transport from.
|
|
* \param[out] transport Transport buffer.
|
|
* \param[in] transportLength Size of transport buffer.
|
|
*
|
|
* \retval VMK_OK Successfully obtained transport type.
|
|
* \retval VMK_NOT_FOUND The passed adapter could not be found.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetAdapterTransport(
|
|
const char *adapName,
|
|
char *transport,
|
|
vmk_uint32 transportLength);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetAdapterPendingCmdInfo -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the queued and active cmd counts for the adapter.
|
|
*
|
|
* Get the number of active and queued commands on the given adapter.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This information is only a snapshot of the values and they
|
|
* may even have changed as the function returns.
|
|
*
|
|
* \param[in] adapterName Adapter name.
|
|
* \param[out] ioCmdCounts If this pointer is non-NULL the memory
|
|
* specified will be filled in with a
|
|
* snapshot of the adapter active / queued
|
|
* command count structure
|
|
* \em vmk_ScsiIOCmdCounts.
|
|
* \param[out] queueDepthPtr If the pointer is non-NULL the memory
|
|
* specified will be filled in with a
|
|
* snapshot of the adapter maximum queue
|
|
* depth.
|
|
*
|
|
* \retval VMK_OK Successfully obtained the pending cmd. info.
|
|
* \retval VMK_NOT_FOUND The passed adapter could not be found.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetAdapterPendingCmdInfo(
|
|
const char *adapterName,
|
|
vmk_ScsiIOCmdCounts *ioCmdCounts,
|
|
vmk_int32 *queueDepthPtr);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathInquiry -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the path's cached inquiry data.
|
|
*
|
|
* This function is used to obtain a copy of cached inquiry data for
|
|
* a path. The call can fail if the data has not yet been obtained.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note \em inqBuf may be NULL in which case only \em *pageLen is
|
|
* returned. This can be used to find the right buffer size up
|
|
* front and see whether the data is available at all.
|
|
*
|
|
* \param[in] path Scsi path from which we are retrieving
|
|
* inquiry data.
|
|
* \param[out] inqBuf Buffer to which inquiry data will be copied.
|
|
* \param[in] inqBufLen Size of the inquiry buffer in bytes.
|
|
* \param[in] vmkScsiPage Page type for the inquiry data to be
|
|
* copied into the inquiry buffer.
|
|
* \param[out] pageLen Optional actual page length based on page
|
|
* header.
|
|
*
|
|
* \retval VMK_OK Successfully obtained the inquiry data.
|
|
* \retval VMK_NOT_SUPPORTED The data was not yet available or the
|
|
* page type was invalid.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetPathInquiry(
|
|
vmk_ScsiPath *path,
|
|
vmk_uint8 *inqBuf,
|
|
vmk_uint32 inqBufLen,
|
|
vmk_ScsiInqType vmkScsiPage,
|
|
vmk_uint32 *pageLen);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathVendor -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the path's vendor from its cached inquiry data.
|
|
*
|
|
* This function will retrieve the vendor string from the cached
|
|
* inquiry data.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The passed string buffer must have space for at least
|
|
* VMK_SCSI_VENDOR_NAME_LENGTH characters.
|
|
*
|
|
* \param[in] path SCSI path from which we are retrieving inq
|
|
* vendor.
|
|
* \param[out] vendor Buffer to which inquiry vendor will be copied.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiGetPathVendor(
|
|
vmk_ScsiPath *path,
|
|
char vendor[VMK_SCSI_VENDOR_NAME_LENGTH]);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathModel -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the path's model from its cached inquiry data.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The passed string buffer must have space for at least
|
|
* VMK_SCSI_MODEL_NAME_LENGTH characters.
|
|
*
|
|
* \param[in] path Scsi path from which we are retrieving inquiry
|
|
* model.
|
|
* \param[out] model Buffer to which inquiry model will be copied.
|
|
*
|
|
* \return Human readable string with the inquiry data's model.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiGetPathModel(
|
|
vmk_ScsiPath *path,
|
|
char model[VMK_SCSI_MODEL_NAME_LENGTH]);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathName -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the current path name.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The obtained string should never be modified/freed.
|
|
*
|
|
* \param[in] path Path whose name to acquire.
|
|
*
|
|
* \return Human readable string with the path's name.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
const char *vmk_ScsiGetPathName(
|
|
vmk_ScsiPath *path);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathInfo -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the path's adapter/channel/target/lun info.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] vmkPath Path to get info for.
|
|
* \param[out] adapterName Adapter name for the given path.
|
|
* \param[in] adapterNameSize Size of adapterName array in bytes.
|
|
* \param[out] channel Channel of the given path.
|
|
* \param[out] target Target id of the given path.
|
|
* \param[out] lun LUN id of the given path.
|
|
*
|
|
* \retval VMK_OK The path info was successfully obtained.
|
|
* \retval VMK_BAD_PARAM One of the input parameter(s) was NULL.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetPathInfo(
|
|
vmk_ScsiPath *vmkPath,
|
|
char *adapterName,
|
|
int adapterNameSize,
|
|
vmk_uint32 *channel,
|
|
vmk_uint32 *target,
|
|
vmk_uint32 *lun);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPathPendingCmdInfo -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the queued and active cmd counts for the path.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This information is only a snapshot.
|
|
*
|
|
* \param[in] vmkPath Path to get info for.
|
|
* \param[out] ioCmdCounts If this is non-NULL the memory specified
|
|
* will be filled in with a snapshot of the
|
|
* path active / queued command count
|
|
* structure vmk_ScsiIOCmdCounts.
|
|
* \param[out] queueDepthPtr If this is is non-NULL the memory specified
|
|
* will be filled in with a snapshot of the
|
|
* path's maximum queue depth.
|
|
*
|
|
* \retval VMK_OK Successfully obtained the pending cmd. info.
|
|
* \retval VMK_BAD_PARAM The path was invalid or NULL.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiGetPathPendingCmdInfo(
|
|
vmk_ScsiPath *vmkPath,
|
|
vmk_ScsiIOCmdCounts *ioCmdCounts,
|
|
vmk_int32 *queueDepthPtr);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssuePathTaskMgmt-- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Issue a task management command on the specified path.
|
|
*
|
|
* This function issues a task management command to abort/reset one
|
|
* or more outstanding I/Os. While a virtual reset will reset only
|
|
* commands for the given world a device/LUN reset will reset all I/O
|
|
* on the path. An abort is targeting a single I/O though that I/O may
|
|
* have been split into several smaller ones and can thus cause several
|
|
* I/Os to be aborted in the driver layer.
|
|
*
|
|
* Note that any I/Os aborted by the call will complete asynchronously
|
|
* and may not have completed when the call returns. The abort/reset is
|
|
* thus only meant as a mean to speed up completion of I/Os - normally
|
|
* by returning the I/O with an error (aborted/reset status).
|
|
*
|
|
* The \em taskMgmt structure is obtained from a prior call to
|
|
* vmk_ScsiInitTaskMgmt().
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \param[in] path Path to issue task mgmt on.
|
|
* \param[in] taskMgmt Task management request to issue.
|
|
*
|
|
* \retval VMK_OK Task management call was successfull. This
|
|
* does \em not mean that everything will
|
|
* complete since there are natural races in the
|
|
* stack so retry the operation if things don't
|
|
* complete soon after this (in a second or two).
|
|
* \retval VMK_BAD_PARAM The task management type in the passed
|
|
* taskMgmt struct is invalid.
|
|
* \retval VMK_NO_MEMORY Memory needed to issue the command could
|
|
* not be allocated.
|
|
* \retval VMK_FAILURE Could not abort/reset for other reason,
|
|
* but the operation can be retried.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiIssuePathTaskMgmt(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiTaskMgmt *taskMgmt);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiCreateCommand -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Allocate and initialize a SCSI command.
|
|
*
|
|
* For performance reasons, this routine will initialize only
|
|
* some of the fields of the vmk_ScsiCommand (lba, lbc,
|
|
* dataDirection, cdb, cdblen will NOT be initialized).
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The command must be freed using vmk_ScsiDestroyCommand().
|
|
*
|
|
* \return a pointer to vmk_ScsiCommand or NULL if allocation failed.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiCommand *vmk_ScsiCreateCommand(void);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiDestroyCommand -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Free a SCSI command.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \pre The supplied command must have been allocated via
|
|
* vmk_ScsiCreateCommand() or one of the utility
|
|
* vmk_ScsiCreateXXXCommand() functions.
|
|
* command->sgArray must be NULL. (the implication is that if
|
|
* this field was previously set, caller has vmk_SgFree()'d it).
|
|
*
|
|
* \param[in] command Command to destroy.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiDestroyCommand(vmk_ScsiCommand *command);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiCreateInqCommand -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Allocate and initialize a SCSI inquiry command.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The command must be freed using vmk_ScsiDestroyCommand().
|
|
*
|
|
* \return a pointer to vmk_ScsiCommand or NULL if allocation failed.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiCommand *
|
|
vmk_ScsiCreateInqCommand(
|
|
vmk_Bool evpd,
|
|
vmk_uint8 evpdPage,
|
|
vmk_uint32 minLen,
|
|
vmk_uint32 maxLen);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiCreateTURCommand -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Allocate and initialize a SCSI test unit ready command.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note The command must be freed using vmk_ScsiDestroyCommand().
|
|
*
|
|
* \return a pointer to vmk_ScsiCommand or NULL if allocation failed.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiCommand *vmk_ScsiCreateTURCommand(void);
|
|
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetNextDeviceCommand -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Get the next command for a logical device from the IO
|
|
* scheduler.
|
|
*
|
|
* This function is meant to be used from within an MPP in its
|
|
* \em startCommand entry point. This should be called in a loop since
|
|
* the scheduler will automatically stop when enough I/O has been
|
|
* queued (e.g. the PSA queues may still hold I/Os, but due to max.
|
|
* device queue depth or throttling no more I/Os will be issued).
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \pre The caller should not hold any spinlocks.
|
|
* \pre The caller should have acquired any needed resources that need
|
|
* to be tied to the I/O up front as I/Os cannot be returned to
|
|
* the device queue again.
|
|
*
|
|
* \param[in] vmkDev Device for which to get the next command.
|
|
*
|
|
* \return Pointer to a SCSI command or NULL if there are no more
|
|
* commands to send at this time.
|
|
* In that case, SCSI will invoke the plugin's \em start() entry
|
|
* point again when the scheduler wants to issue I/Os again.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiCommand *vmk_ScsiGetNextDeviceCommand(vmk_ScsiDevice *vmkDev);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiDeviceFlushAPDCommands -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Scan the device's scheduling queues for commands tagged with
|
|
* VMK_SCSI_COMMAND_FLAGS_NO_CONNECT_IF_APD and complete them
|
|
* with NO_CONNECT now.
|
|
*
|
|
* \param[in] vmkDev The target SCSI device
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiDeviceFlushAPDCommands(vmk_ScsiDevice *vmkDev);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssueAsyncPathCommand -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Issue a command on the specified path.
|
|
*
|
|
* This function issues a SCSI command on a specific path. The command
|
|
* will complete asynchronously at a later point using the command's
|
|
* \em done() completion callback.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \pre The caller should not hold any spinlocks.
|
|
*
|
|
* \param[in] path Path to issue command to.
|
|
* \param[in] command Command to issue on path.
|
|
*
|
|
* \retval VMK_OK Successfully issued the command.
|
|
* \retval VMK_NO_CONNECT Path is in process of being removed.
|
|
* \retval VMK_NO_MEMORY Unable to allocate memory for additional
|
|
* resources to be associated with command.
|
|
* \retval VMK_TIMEOUT The command had a timeout set and the
|
|
* timeout time had already been passed when
|
|
* the command was to be issued.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiIssueAsyncPathCommand(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiCommand *command);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssueSyncPathCommand -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Issue a synchronous command on the specified path.
|
|
*
|
|
* This function issues a command on a specific path and waits for
|
|
* the command to complete before returning.
|
|
*
|
|
* \see vmk_ScsiIssueSyncPathCommandWithData().
|
|
* \see vmk_ScsiIssueSyncPathCommandWithRetries().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note The call specifies the buffer to use for data transfer (if
|
|
* needed) using \em command->sgArray.
|
|
* \note The calling world sleeps until the command completes.
|
|
*
|
|
* \pre The caller should not hold any spinlock.
|
|
*
|
|
* \param[in] path Path to issue command to.
|
|
* \param[in] command Command to issue on path.
|
|
*
|
|
* \retval VMK_OK The command was issued successfully and
|
|
* the command's status is valid.
|
|
* \retval VMK_NO_CONNECT Path is in process of being removed
|
|
* \retval VMK_NO_MEMORY Unable to allocate memory for additional
|
|
* resources associated with command.
|
|
* \retval VMK_TIMEOUT The command had a timeout set and was
|
|
* already timed when it was to be issued.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiIssueSyncPathCommand(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiCommand *command);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssueSyncPathCommandWithData -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Issue a synchronous command on the specified path.
|
|
*
|
|
* This function issues a command on a specific path and waits for
|
|
* the command to complete before returning. The caller can specify the
|
|
* buffer to use for data transfer using the \em data and \em dataLen
|
|
* parameters. The passed data buffer is used to create an sgArray
|
|
* for the command, so the \em command->sgArray must be NULL.
|
|
*
|
|
* \see vmk_ScsiIssueSyncPathCommand().
|
|
* \see vmk_ScsiIssueSyncPathCommandWithRetries().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note The calling world sleeps until the command completes.
|
|
*
|
|
* \pre The caller should not hold any spinlock.
|
|
* \pre The \em command->sgArray must be NULL.
|
|
*
|
|
* \param[in] path Path to issue command to.
|
|
* \param[in] command Command to issue on path.
|
|
* \param[in,out] data Data buffer.
|
|
* \param[in] dataLen Length of data buffer.
|
|
*
|
|
* \retval VMK_OK The command was issued successfully and
|
|
* the command's status is valid.
|
|
* \retval VMK_NO_CONNECT Path is in process of being removed.
|
|
* \retval VMK_NO_MEMORY Unable to allocate memory for additional
|
|
* resources associated with command.
|
|
* \retval VMK_TIMEOUT The command had a timeout set and was
|
|
* already timed when it was to be issued.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiIssueSyncPathCommandWithData(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiCommand *command,
|
|
void *data,
|
|
vmk_uint32 dataLen);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssueSyncPathCommandWithRetries -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Issue a synchronous command on the specified path.
|
|
*
|
|
* This function issues a command on a specific path and waits for
|
|
* the command to complete before returning. The caller can specify
|
|
* the buffer to use for any data transfer using either the data and
|
|
* dataLen parameters or \em scsiCmd->sgArray, but not both.
|
|
*
|
|
* The issued command can complete with the errors listed below in
|
|
* the completionStatus parameter.
|
|
* - VMK_MEDIUM_NOT_FOUND the device returned a medium not
|
|
present error.
|
|
* - VMK_TIMEOUT the command timed out.
|
|
* - VMK_ABORTED the command was aborted.
|
|
* - VMK_NO_CONNECT the path is not connected.
|
|
* - VMK_HBA_ERROR the device driver returned an non-retriable
|
|
* error like data underrun.
|
|
*
|
|
* The issued command can also complete with the transient errors
|
|
* listed below.
|
|
*
|
|
* Before these errors are returned in the completionStatus
|
|
* parameter, the command will be retried a number of times.
|
|
* - VMK_RESERVATION_CONFLICT the device is reserved.
|
|
* - VMK_BUSY the device returned a busy status.
|
|
* - VMK_NO_MEMORY the system is out of memory.
|
|
* - VMK_STORAGE_RETRY_OPERATION the command failed with:
|
|
* - A check condition of power on/reset or unit attention.
|
|
* - A check condition with a sense key of aborted cmd.
|
|
* - A check condition with a sense key of not ready/becoming
|
|
* ready.
|
|
* - A host error status of retry.
|
|
* - The cmd was specified with a timeout value and it was
|
|
* terminated with an abort/reset prior to the expiration of
|
|
* the timeout value.
|
|
*
|
|
* \see vmk_ScsiIssueSyncPathCommand().
|
|
* \see vmk_ScsiIssueSyncPathCommandWithData().
|
|
*
|
|
* \note This is a blocking call.
|
|
* \note The calling world sleeps until the command completes.
|
|
*
|
|
* \param[in] path The path the cmd is to be issued to.
|
|
* \param[in] command Command to be issued.
|
|
* \param[in] data Read/write data associated with
|
|
* the command.
|
|
* \param[in] dataLen Length of the read/write data
|
|
* associated with the command.
|
|
* \param[out] completionStatus Completion status of the command.
|
|
* The completion status is only valid
|
|
* if this function returns VMK_OK.
|
|
*
|
|
* \retval VMK_OK The command was issued successfully and
|
|
* the command's status is valid.
|
|
* \retval VMK_NO_CONNECT Path is in process of being removed.
|
|
* \retval VMK_NO_MEMORY Unable to allocate memory for additional
|
|
* resources associated with command.
|
|
* \retval VMK_TIMEOUT The command had a timeout set and was
|
|
* already timed when it was to be issued.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiIssueSyncPathCommandWithRetries(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiCommand *command,
|
|
vmk_uint8 *data,
|
|
vmk_uint32 dataLen,
|
|
VMK_ReturnStatus *completionStatus);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssueSyncDumpCommand -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Issue a dump command to a path during a system core dump.
|
|
*
|
|
* This function issues a dump command on the given path and
|
|
* busywaits until the command completes. It is meant for an MP plugin
|
|
* to call this from it's device->dumpCommand entry point.
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \param[in] path Path to issue command to.
|
|
* \param[in] command Command to issue on path.
|
|
*
|
|
* \retval VMK_OK Dump command was issued successfully and
|
|
* the command's status is valid.
|
|
* \retval VMK_FAILURE The adapter backing the path is not enabled.
|
|
* \retval VMK_TIMEOUT Command timed out and should NOT be retried.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiIssueSyncDumpCommand(
|
|
vmk_ScsiPath *path,
|
|
vmk_ScsiCommand *command);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIssueSyncFilterCommandWithRetries -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Issue a synchronous command on a device.
|
|
*
|
|
* This function issues a command on the device on behalf of
|
|
* the Filter or VAAI plugin and waits for the command to complete
|
|
* before returning. The device is opened before command is issued,
|
|
* and is closed after the command completes. The caller can specify
|
|
* the buffer to use for any data transfer using either the data and
|
|
* dataLen parameters or vmkCmd->sgArray, but not both.
|
|
*
|
|
* The command gets retried for basic low level failures such
|
|
* as device busy, queue full, and some check conditions.
|
|
*
|
|
* \note Only Filters and VAAI plugins can use this API.
|
|
* \note This is a blocking call.
|
|
* \note The calling world sleeps until the command completes.
|
|
*
|
|
* \param[in] vmkPlugin Issuing plugin.
|
|
* Has to be Filter or VAAI type.
|
|
* \param[in] vmkDevice The device the cmd is to be issued to.
|
|
* \param[in] vmkCmd Command to be issued.
|
|
* \param[in] data Read/write data associated with
|
|
* the command.
|
|
* \param[in] dataLen Length of the read/write data
|
|
* associated with the command,
|
|
* or NULL if vmkCmd->sgArray is used.
|
|
*
|
|
* \return The IO issue status
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus
|
|
vmk_ScsiIssueSyncFilterCommandWithRetries(
|
|
vmk_ScsiPlugin *vmkPlugin,
|
|
struct vmk_ScsiDevice *vmkDevice,
|
|
vmk_ScsiCommand *vmkCmd,
|
|
vmk_uint8 *data,
|
|
vmk_int32 dataLen);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSchedCommandCompletion -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Schedules a non-blocking context to complete the command.
|
|
*
|
|
* This function schedules a non-blocking context to complete a
|
|
* command. The intent is to use this from the issuing path where
|
|
* a command cannot be completed directly since that could lead to
|
|
* stack exhaustion due to recursive calls to the issuing path from
|
|
* the completion path.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] command The cmd to complete.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiSchedCommandCompletion(
|
|
vmk_ScsiCommand *command);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiRegisterEventHandler -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Add an Event Handler for the specific masked event types
|
|
* on the specified adapter.
|
|
*
|
|
* This function registers a handler that will be called as certain
|
|
* events on the passed adapter occur.
|
|
*
|
|
* \see vmk_ScsiAdapterEvents.
|
|
* \see vmk_ScsiUnRegisterEventHandler().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note When the callback is called, it should not grab any locks
|
|
* below minor rank 7, major rank SP_RANK_SCSI.
|
|
*
|
|
* \param[in] adapterName Adapter name to register callback for.
|
|
* \param[in] mask Events to be notified of as a bit mask.
|
|
* \param[in] handlerCbk Callback to be called when an event
|
|
* occurs.
|
|
*
|
|
* \retval VMK_OK Event handler successfully registered.
|
|
* \retval VMK_INVALID_ADAPTER The passed adapter does not exist.
|
|
* \retval VMK_NO_MEMORY Failed to allocate memory for event.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus
|
|
vmk_ScsiRegisterEventHandler(const char *adapterName, vmk_uint32 mask,
|
|
vmk_EventHandlerCbk handlerCbk);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiUnRegisterEventHandler -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Remove an Event Handler for the specific masked event types
|
|
* on the specified adapter.
|
|
*
|
|
* This function unregisters an event handler earlier registered by
|
|
* vmk_ScsiRegisterEventHandler. All arguments need to match those that
|
|
* were used to register the handler in order for the call to succeed.
|
|
*
|
|
* \see vmk_ScsiRegisterEventHandler().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] adapterName Name of the adapter to unregister for events.
|
|
* \param[in] mask Event bit mask to unregister.
|
|
* \param[in] handlerCbk Event callback to be unregistered.
|
|
*
|
|
* \retval VMK_OK Event handler successfully unregistered.
|
|
* \retval VMK_INVALID_ADAPTER The passed adapter does not exist.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus
|
|
vmk_ScsiUnRegisterEventHandler(const char *adapterName, vmk_uint32 mask,
|
|
vmk_EventHandlerCbk handlerCbk);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiAllocatePlugin -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Allocate a plugin data structure.
|
|
*
|
|
* This function will allocate a plugin structure for use when
|
|
* registering the plugin with PSA. The structure should be freed
|
|
* with vmk_ScsiFreePlugin() again when it is no longer registered.
|
|
*
|
|
* \see vmk_ScsiRegisterPlugin().
|
|
* \see vmk_ScsiUnregisterPlugin().
|
|
* \see vmk_ScsiFreePlugin().
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \post The plugin MUST be freed through vmk_ScsiFreePlugin().
|
|
*
|
|
* \param[in] heapID Heap id to allocate memory from.
|
|
* \param[in] pluginName Name of allocating plugin.
|
|
*
|
|
* \return Pointer to vmk_ScsiPlugin structure or NULL if memory
|
|
* could not be allocated for the structure.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiPlugin *vmk_ScsiAllocatePlugin(
|
|
vmk_HeapID heapID, char *pluginName);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiFreePlugin -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Free a plugin data structure allocated by
|
|
* vmk_ScsiAllocatePlugin().
|
|
*
|
|
* \see vmk_ScsiAllocatePlugin().
|
|
* \see vmk_ScsiUnregisterPlugin().
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \pre The plugin structure must first be unregistered with PSA (or
|
|
* never have been registered).
|
|
*
|
|
* \param[in] plugin Plugin to free.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiFreePlugin(
|
|
vmk_ScsiPlugin *plugin);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiRegisterPlugin -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Register a plugin with SCSI.
|
|
*
|
|
* This function will register a plugin with PSA.
|
|
*
|
|
* \see vmk_ScsiAllocatePlugin().
|
|
* \see vmk_ScsiUnregisterPlugin().
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \pre The vmk_ScsiPlugin structure MUST have been allocated through
|
|
* vmk_ScsiAllocatePlugin().
|
|
*
|
|
* \param[in] plugin Plugin to register.
|
|
*
|
|
* \retval VKM_OK Successfully registered the plugin.
|
|
* \retval VMK_EXISTS The plugin is already registered with PSA.
|
|
* \retval VMK_NOT_SUPPORTED The API revision the plugin is compiled
|
|
* for is incompatible with the ESX server.
|
|
* \retval VMK_BAD_PARAM The plugin's type is invalid/unsupported
|
|
* or some required entry points are not set.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiRegisterPlugin(
|
|
vmk_ScsiPlugin *plugin);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiUnregisterPlugin -- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Unregister a plugin previously registered via
|
|
* vmk_ScsiRegisterPlugin().
|
|
*
|
|
* This function is used to unregister a plugin that has previously
|
|
* been successfully registered with PSA. Before a plugin can be
|
|
* unregistered it must not have any paths claimed or devices
|
|
* registered.
|
|
* The plugin must also have a state of VMK_SCSI_PLUGIN_STATE_DISABLED
|
|
* when this function is called, which has to be set through
|
|
* vmkScsiSetPluginState() - the latter will ensure that no claim
|
|
* operations will be passed to the plugin.
|
|
*
|
|
* \see vmk_ScsiFreePlugin().
|
|
* \see vmk_ScsiSetPluginState().
|
|
*
|
|
* \note This is a blocking call.
|
|
*
|
|
* \pre The plugin should have released all its SCSI resources (paths,
|
|
* devices, ...).
|
|
* \pre The plugin state must be VMK_SCSI_PLUGIN_STATE_DISABLED.
|
|
*
|
|
* \param[in] plugin Plugin to unregister.
|
|
*
|
|
* \retval VMK_OK Successfully unregistered the plugin.
|
|
* \retval VMK_BAD_PARAM The plugin was already not registered.
|
|
* \retval VMK_BUSY The plugin state was not set to disabled.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
VMK_ReturnStatus vmk_ScsiUnregisterPlugin(
|
|
vmk_ScsiPlugin *plugin);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiSetPluginState-- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Set the current state of the plugin.
|
|
*
|
|
* This function sets the plugin state to one of the possible values
|
|
* defined by the vmk_ScsiPluginState enum. The plugin will normally
|
|
* operate in ENABLED mode and when the \em pathClaimBegin entry point
|
|
* is called the plugin should (temporarily) set it to CLAIM_PATHS and
|
|
* then set it back to ENABLED when the \em pathClaimEnd entry point is
|
|
* later invoked. Lastly it should be set to DISABLED before the
|
|
* plugin is finally unregistered.
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] plugin Plugin to set state to.
|
|
* \param[in] state New state to set.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void vmk_ScsiSetPluginState(
|
|
vmk_ScsiPlugin *plugin,
|
|
vmk_ScsiPluginState state);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiGetPluginState-- */ /**
|
|
*
|
|
* \ingroup PSA_PLUGIN
|
|
*
|
|
* \brief Get the current state of the plugin.
|
|
*
|
|
* \see vmk_ScsiSetPluginState().
|
|
*
|
|
* \note This is a non-blocking call.
|
|
*
|
|
* \param[in] plugin Plugin to get state from.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_ScsiPluginState vmk_ScsiGetPluginState(
|
|
vmk_ScsiPlugin *plugin);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiIncReserveGeneration -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Increment the reservation generation count of the device.
|
|
*
|
|
* This function is used to tell the PSA layer that a reservation was
|
|
* broken/cleared by the MP plugin and thus PSA should fail any
|
|
* reservation sensitive transactions using the previous generation.
|
|
*
|
|
* The intent is that an MP plugin calls this if it has to do a failover
|
|
* while a SCSI-2 reservation is held on the device and thus has to
|
|
* force a LU reset on the new path (or if it has to do a LU reset for
|
|
* any other reason - or invokes/knows about any other operation that
|
|
* will clear or has cleared the held reservation).
|
|
*
|
|
* \note This is a non-blocking call.
|
|
* \note This call should only be used by MP plugins.
|
|
*
|
|
* \param[in] vmkDevice Device whose reservation generation to bump.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
void
|
|
vmk_ScsiIncReserveGeneration(vmk_ScsiDevice *vmkDevice);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiCommandMaxCommands -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Maximum outstanding SCSI commands
|
|
*
|
|
* This returns the maximum number of SCSI commands that the VMkernel
|
|
* SCSI command slab allocator supports. These many SCSI commands can
|
|
* be outstanding in the ESX kernel at any time.
|
|
*
|
|
* Any slab in a plugin, that is created for the purpose of allocating
|
|
* any per-command plugin data structures, should be sized per this, to
|
|
* ensure that at any time we have enough plugin objects for all the
|
|
* SCSI commands.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_uint32
|
|
vmk_ScsiCommandMaxCommands(void);
|
|
|
|
/*
|
|
***********************************************************************
|
|
* vmk_ScsiCommandMaxFree -- */ /**
|
|
*
|
|
* \ingroup MPP
|
|
*
|
|
* \brief Maximum idle SCSI commands
|
|
*
|
|
* This returns the maximum number of SCSI commands that the SCSI command
|
|
* allocator will keep in its cache for fast allocation. Any more freed
|
|
* SCSI commands are freed to the slab heap, for better memory utilization.
|
|
*
|
|
* This should be used by plugins as a good guidance value while creating
|
|
* their own slabs for any per-command object allocation.
|
|
*
|
|
***********************************************************************
|
|
*/
|
|
vmk_uint32
|
|
vmk_ScsiCommandMaxFree(void);
|
|
|
|
#endif /* _VMKAPI_MPP_H_ */
|
|
/** @} */
|
|
/** @} */
|