linux/drivers/scsi/mpi3mr/mpi3mr_transport.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for Broadcom MPI3 Storage Controllers
 *
 * Copyright (C) 2017-2023 Broadcom Inc.
 *  (mailto: [email protected])
 *
 */

#include <linux/vmalloc.h>

#include "mpi3mr.h"

/**
 * mpi3mr_post_transport_req - Issue transport requests and wait
 * @mrioc: Adapter instance reference
 * @request: Properly populated MPI3 request
 * @request_sz: Size of the MPI3 request
 * @reply: Pointer to return MPI3 reply
 * @reply_sz: Size of the MPI3 reply buffer
 * @timeout: Timeout in seconds
 * @ioc_status: Pointer to return ioc status
 *
 * A generic function for posting MPI3 requests from the SAS
 * transport layer that uses transport command infrastructure.
 * This blocks for the completion of request for timeout seconds
 * and if the request times out this function faults the
 * controller with proper reason code.
 *
 * On successful completion of the request this function returns
 * appropriate ioc status from the firmware back to the caller.
 *
 * Return: 0 on success, non-zero on failure.
 */
static int mpi3mr_post_transport_req(struct mpi3mr_ioc *mrioc, void *request,
	u16 request_sz, void *reply, u16 reply_sz, int timeout,
	u16 *ioc_status)
{}

/* report manufacture request structure */
struct rep_manu_request {};

/* report manufacture reply structure */
struct rep_manu_reply {};

/**
 * mpi3mr_report_manufacture - obtain SMP report_manufacture
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the expander device
 * @edev: SAS transport layer sas_expander_device object
 * @port_id: ID of the HBA port
 *
 * Fills in the sas_expander_device with manufacturing info.
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_report_manufacture(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct sas_expander_device *edev, u8 port_id)
{}

/**
 * __mpi3mr_expander_find_by_handle - expander search by handle
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle of the expander
 *
 * Context: The caller should acquire sas_node_lock
 *
 * This searches for expander device based on handle, then
 * returns the sas_node object.
 *
 * Return: Expander sas_node object reference or NULL
 */
struct mpi3mr_sas_node *__mpi3mr_expander_find_by_handle(struct mpi3mr_ioc
	*mrioc, u16 handle)
{}

/**
 * mpi3mr_is_expander_device - if device is an expander
 * @device_info: Bitfield providing information about the device
 *
 * Return: 1 if the device is expander device, else 0.
 */
u8 mpi3mr_is_expander_device(u16 device_info)
{}

/**
 * mpi3mr_get_sas_address - retrieve sas_address for handle
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle
 * @sas_address: Address to hold sas address
 *
 * This function issues device page0 read for a given device
 * handle and gets the SAS address and return it back
 *
 * Return: 0 for success, non-zero for failure
 */
static int mpi3mr_get_sas_address(struct mpi3mr_ioc *mrioc, u16 handle,
	u64 *sas_address)
{}

/**
 * __mpi3mr_get_tgtdev_by_addr - target device search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @hba_port: HBA port entry
 *
 * This searches for target device from sas address and hba port
 * pointer then return mpi3mr_tgt_dev object.
 *
 * Return: Valid tget_dev or NULL
 */
static struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_get_tgtdev_by_addr - target device search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @hba_port: HBA port entry
 *
 * This searches for target device from sas address and hba port
 * pointer then return mpi3mr_tgt_dev object.
 *
 * Context: This function will acquire tgtdev_lock and will
 * release before returning the mpi3mr_tgt_dev object.
 *
 * Return: Valid tget_dev or NULL
 */
static struct mpi3mr_tgt_dev *mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_remove_device_by_sas_address - remove the device
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @hba_port: HBA port entry
 *
 * This searches for target device using sas address and hba
 * port pointer then removes it from the OS.
 *
 * Return: None
 */
static void mpi3mr_remove_device_by_sas_address(struct mpi3mr_ioc *mrioc,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{}

/**
 * __mpi3mr_get_tgtdev_by_addr_and_rphy - target device search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of the device
 * @rphy: SAS transport layer rphy object
 *
 * This searches for target device from sas address and rphy
 * pointer then return mpi3mr_tgt_dev object.
 *
 * Return: Valid tget_dev or NULL
 */
struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr_and_rphy(
	struct mpi3mr_ioc *mrioc, u64 sas_address, struct sas_rphy *rphy)
{}

/**
 * mpi3mr_expander_find_by_sas_address - sas expander search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of expander
 * @hba_port: HBA port entry
 *
 * Return: A valid SAS expander node or NULL.
 *
 */
static struct mpi3mr_sas_node *mpi3mr_expander_find_by_sas_address(
	struct mpi3mr_ioc *mrioc, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{}

/**
 * __mpi3mr_sas_node_find_by_sas_address - sas node search
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of expander or sas host
 * @hba_port: HBA port entry
 * Context: Caller should acquire mrioc->sas_node_lock.
 *
 * If the SAS address indicates the device is direct attached to
 * the controller (controller's SAS address) then the SAS node
 * associated with the controller is returned back else the SAS
 * address and hba port are used to identify the exact expander
 * and the associated sas_node object is returned. If there is
 * no match NULL is returned.
 *
 * Return: A valid SAS node or NULL.
 *
 */
static struct mpi3mr_sas_node *__mpi3mr_sas_node_find_by_sas_address(
	struct mpi3mr_ioc *mrioc, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_parent_present - Is parent present for a phy
 * @mrioc: Adapter instance reference
 * @phy: SAS transport layer phy object
 *
 * Return: 0 if parent is present else non-zero
 */
static int mpi3mr_parent_present(struct mpi3mr_ioc *mrioc, struct sas_phy *phy)
{}

/**
 * mpi3mr_convert_phy_link_rate -
 * @link_rate: link rate as defined in the MPI header
 *
 * Convert link_rate from mpi format into sas_transport layer
 * form.
 *
 * Return: A valid SAS transport layer defined link rate
 */
static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate)
{}

/**
 * mpi3mr_delete_sas_phy - Remove a single phy from port
 * @mrioc: Adapter instance reference
 * @mr_sas_port: Internal Port object
 * @mr_sas_phy: Internal Phy object
 *
 * Return: None.
 */
static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_port *mr_sas_port,
	struct mpi3mr_sas_phy *mr_sas_phy)
{}

/**
 * mpi3mr_add_sas_phy - Adding a single phy to a port
 * @mrioc: Adapter instance reference
 * @mr_sas_port: Internal Port object
 * @mr_sas_phy: Internal Phy object
 *
 * Return: None.
 */
static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_port *mr_sas_port,
	struct mpi3mr_sas_phy *mr_sas_phy)
{}

/**
 * mpi3mr_add_phy_to_an_existing_port - add phy to existing port
 * @mrioc: Adapter instance reference
 * @mr_sas_node: Internal sas node object (expander or host)
 * @mr_sas_phy: Internal Phy object *
 * @sas_address: SAS address of device/expander were phy needs
 *             to be added to
 * @hba_port: HBA port entry
 *
 * Return: None.
 */
static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *mr_sas_node, struct mpi3mr_sas_phy *mr_sas_phy,
	u64 sas_address, struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_delete_sas_port - helper function to removing a port
 * @mrioc: Adapter instance reference
 * @mr_sas_port: Internal Port object
 *
 * Return: None.
 */
static void  mpi3mr_delete_sas_port(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_port *mr_sas_port)
{}

/**
 * mpi3mr_del_phy_from_an_existing_port - del phy from a port
 * @mrioc: Adapter instance reference
 * @mr_sas_node: Internal sas node object (expander or host)
 * @mr_sas_phy: Internal Phy object
 *
 * Return: None.
 */
static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *mr_sas_node, struct mpi3mr_sas_phy *mr_sas_phy)
{}

/**
 * mpi3mr_sas_port_sanity_check - sanity check while adding port
 * @mrioc: Adapter instance reference
 * @mr_sas_node: Internal sas node object (expander or host)
 * @sas_address: SAS address of device/expander
 * @hba_port: HBA port entry
 *
 * Verifies whether the Phys attached to a device with the given
 * SAS address already belongs to an existing sas port if so
 * will remove those phys from the sas port
 *
 * Return: None.
 */
static void mpi3mr_sas_port_sanity_check(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *mr_sas_node, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_set_identify - set identify for phys and end devices
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle
 * @identify: SAS transport layer's identify info
 *
 * Populates sas identify info for a specific device.
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_set_identify(struct mpi3mr_ioc *mrioc, u16 handle,
	struct sas_identify *identify)
{}

/**
 * mpi3mr_add_host_phy - report sas_host phy to SAS transport
 * @mrioc: Adapter instance reference
 * @mr_sas_phy: Internal Phy object
 * @phy_pg0: SAS phy page 0
 * @parent_dev: Prent device class object
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_add_host_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_phy *mr_sas_phy, struct mpi3_sas_phy_page0 phy_pg0,
	struct device *parent_dev)
{}

/**
 * mpi3mr_add_expander_phy - report expander phy to transport
 * @mrioc: Adapter instance reference
 * @mr_sas_phy: Internal Phy object
 * @expander_pg1: SAS Expander page 1
 * @parent_dev: Parent device class object
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_add_expander_phy(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_phy *mr_sas_phy,
	struct mpi3_sas_expander_page1 expander_pg1,
	struct device *parent_dev)
{}

/**
 * mpi3mr_alloc_hba_port - alloc hba port object
 * @mrioc: Adapter instance reference
 * @port_id: Port number
 *
 * Alloc memory for hba port object.
 */
static struct mpi3mr_hba_port *
mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id)
{}

/**
 * mpi3mr_get_hba_port_by_id - find hba port by id
 * @mrioc: Adapter instance reference
 * @port_id - Port ID to search
 *
 * Return: mpi3mr_hba_port reference for the matched port
 */

struct mpi3mr_hba_port *mpi3mr_get_hba_port_by_id(struct mpi3mr_ioc *mrioc,
	u8 port_id)
{}

/**
 * mpi3mr_update_links - refreshing SAS phy link changes
 * @mrioc: Adapter instance reference
 * @sas_address_parent: SAS address of parent expander or host
 * @handle: Firmware device handle of attached device
 * @phy_number: Phy number
 * @link_rate: New link rate
 * @hba_port: HBA port entry
 *
 * Return: None.
 */
void mpi3mr_update_links(struct mpi3mr_ioc *mrioc,
	u64 sas_address_parent, u16 handle, u8 phy_number, u8 link_rate,
	struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_sas_host_refresh - refreshing sas host object contents
 * @mrioc: Adapter instance reference
 *
 * This function refreshes the controllers phy information and
 * updates the SAS transport layer with updated information,
 * this is executed for each device addition or device info
 * change events
 *
 * Return: None.
 */
void mpi3mr_sas_host_refresh(struct mpi3mr_ioc *mrioc)
{}

/**
 * mpi3mr_sas_host_add - create sas host object
 * @mrioc: Adapter instance reference
 *
 * This function creates the controllers phy information and
 * updates the SAS transport layer with updated information,
 * this is executed for first device addition or device info
 * change event.
 *
 * Return: None.
 */
void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc)
{}

/**
 * mpi3mr_sas_port_add - Expose the SAS device to the SAS TL
 * @mrioc: Adapter instance reference
 * @handle: Firmware device handle of the attached device
 * @sas_address_parent: sas address of parent expander or host
 * @hba_port: HBA port entry
 *
 * This function creates a new sas port object for the given end
 * device matching sas address and hba_port and adds it to the
 * sas_node's sas_port_list and expose the attached sas device
 * to the SAS transport layer through sas_rphy_add.
 *
 * Returns a valid mpi3mr_sas_port reference or NULL.
 */
static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
	u16 handle, u64 sas_address_parent, struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_sas_port_remove - remove port from the list
 * @mrioc: Adapter instance reference
 * @sas_address: SAS address of attached device
 * @sas_address_parent: SAS address of parent expander or host
 * @hba_port: HBA port entry
 *
 * Removing object and freeing associated memory from the
 * sas_port_list.
 *
 * Return: None
 */
static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
	u64 sas_address_parent, struct mpi3mr_hba_port *hba_port)
{}

/**
 * struct host_port - host port details
 * @sas_address: SAS Address of the attached device
 * @phy_mask: phy mask of host port
 * @handle: Device Handle of attached device
 * @iounit_port_id: port ID
 * @used: host port is already matched with sas port from sas_port_list
 * @lowest_phy: lowest phy ID of host port
 */
struct host_port {};

/**
 * mpi3mr_update_mr_sas_port - update sas port objects during reset
 * @mrioc: Adapter instance reference
 * @h_port: host_port object
 * @mr_sas_port: sas_port objects which needs to be updated
 *
 * Update the port ID of sas port object. Also add the phys if new phys got
 * added to current sas port and remove the phys if some phys are moved
 * out of the current sas port.
 *
 * Return: Nothing.
 */
static void
mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port,
	struct mpi3mr_sas_port *mr_sas_port)
{}

/**
 * mpi3mr_refresh_sas_ports - update host's sas ports during reset
 * @mrioc: Adapter instance reference
 *
 * Update the host's sas ports during reset by checking whether
 * sas ports are still intact or not. Add/remove phys if any hba
 * phys are (moved in)/(moved out) of sas port. Also update
 * io_unit_port if it got changed during reset.
 *
 * Return: Nothing.
 */
void
mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc)
{}

/**
 * mpi3mr_refresh_expanders - Refresh expander device exposure
 * @mrioc: Adapter instance reference
 *
 * This is executed post controller reset to identify any
 * missing expander devices during reset and remove from the upper layers
 * or expose any newly detected expander device to the upper layers.
 *
 * Return: Nothing.
 */
void
mpi3mr_refresh_expanders(struct mpi3mr_ioc *mrioc)
{}

/**
 * mpi3mr_expander_node_add - insert an expander to the list.
 * @mrioc: Adapter instance reference
 * @sas_expander: Expander sas node
 * Context: This function will acquire sas_node_lock.
 *
 * Adding new object to the ioc->sas_expander_list.
 *
 * Return: None.
 */
static void mpi3mr_expander_node_add(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *sas_expander)
{}

/**
 * mpi3mr_expander_add -  Create expander object
 * @mrioc: Adapter instance reference
 * @handle: Expander firmware device handle
 *
 * This function creating expander object, stored in
 * sas_expander_list and expose it to the SAS transport
 * layer.
 *
 * Return: 0 for success, non-zero for failure.
 */
int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle)
{}

/**
 * mpi3mr_expander_node_remove - recursive removal of expander.
 * @mrioc: Adapter instance reference
 * @sas_expander: Expander device object
 *
 * Removes expander object and freeing associated memory from
 * the sas_expander_list and removes the same from SAS TL, if
 * one of the attached device is an expander then it recursively
 * removes the expander device too.
 *
 * Return nothing.
 */
void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_sas_node *sas_expander)
{}

/**
 * mpi3mr_expander_remove - Remove expander object
 * @mrioc: Adapter instance reference
 * @sas_address: Remove expander sas_address
 * @hba_port: HBA port reference
 *
 * This function remove expander object, stored in
 * mrioc->sas_expander_list and removes it from the SAS TL by
 * calling mpi3mr_expander_node_remove().
 *
 * Return: None
 */
void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
	struct mpi3mr_hba_port *hba_port)
{}

/**
 * mpi3mr_get_sas_negotiated_logical_linkrate - get linkrate
 * @mrioc: Adapter instance reference
 * @tgtdev: Target device
 *
 * This function identifies whether the target device is
 * attached directly or through expander and issues sas phy
 * page0 or expander phy page1 and gets the link rate, if there
 * is any failure in reading the pages then this returns link
 * rate of 1.5.
 *
 * Return: logical link rate.
 */
static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_tgt_dev *tgtdev)
{}

/**
 * mpi3mr_report_tgtdev_to_sas_transport - expose dev to SAS TL
 * @mrioc: Adapter instance reference
 * @tgtdev: Target device
 *
 * This function exposes the target device after
 * preparing host_phy, setting up link rate etc.
 *
 * Return: 0 on success, non-zero for failure.
 */
int mpi3mr_report_tgtdev_to_sas_transport(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_tgt_dev *tgtdev)
{}

/**
 * mpi3mr_remove_tgtdev_from_sas_transport - remove from SAS TL
 * @mrioc: Adapter instance reference
 * @tgtdev: Target device
 *
 * This function removes the target device
 *
 * Return: None.
 */
void mpi3mr_remove_tgtdev_from_sas_transport(struct mpi3mr_ioc *mrioc,
	struct mpi3mr_tgt_dev *tgtdev)
{}

/**
 * mpi3mr_get_port_id_by_sas_phy -  Get port ID of the given phy
 * @phy: SAS transport layer phy object
 *
 * Return: Port number for valid ID else 0xFFFF
 */
static inline u8 mpi3mr_get_port_id_by_sas_phy(struct sas_phy *phy)
{}

/**
 * mpi3mr_get_port_id_by_rphy - Get Port number from SAS rphy
 *
 * @mrioc: Adapter instance reference
 * @rphy: SAS transport layer remote phy object
 *
 * Retrieves HBA port number in which the device pointed by the
 * rphy object is attached with.
 *
 * Return: Valid port number on success else OxFFFF.
 */
static u8 mpi3mr_get_port_id_by_rphy(struct mpi3mr_ioc *mrioc, struct sas_rphy *rphy)
{}

static inline struct mpi3mr_ioc *phy_to_mrioc(struct sas_phy *phy)
{}

static inline struct mpi3mr_ioc *rphy_to_mrioc(struct sas_rphy *rphy)
{}

/* report phy error log structure */
struct phy_error_log_request {};

/* report phy error log reply structure */
struct phy_error_log_reply {};


/**
 * mpi3mr_get_expander_phy_error_log - return expander counters:
 * @mrioc: Adapter instance reference
 * @phy: The SAS transport layer phy object
 *
 * Return: 0 for success, non-zero for failure.
 *
 */
static int mpi3mr_get_expander_phy_error_log(struct mpi3mr_ioc *mrioc,
	struct sas_phy *phy)
{}

/**
 * mpi3mr_transport_get_linkerrors - return phy error counters
 * @phy: The SAS transport layer phy object
 *
 * This function retrieves the phy error log information of the
 * HBA or expander for which the phy belongs to
 *
 * Return: 0 for success, non-zero for failure.
 */
static int mpi3mr_transport_get_linkerrors(struct sas_phy *phy)
{}

/**
 * mpi3mr_transport_get_enclosure_identifier - Get Enclosure ID
 * @rphy: The SAS transport layer remote phy object
 * @identifier: Enclosure identifier to be returned
 *
 * Returns the enclosure id for the device pointed by the remote
 * phy object.
 *
 * Return: 0 on success or -ENXIO
 */
static int
mpi3mr_transport_get_enclosure_identifier(struct sas_rphy *rphy,
	u64 *identifier)
{}

/**
 * mpi3mr_transport_get_bay_identifier - Get bay ID
 * @rphy: The SAS transport layer remote phy object
 *
 * Returns the slot id for the device pointed by the remote phy
 * object.
 *
 * Return: Valid slot ID on success or -ENXIO
 */
static int
mpi3mr_transport_get_bay_identifier(struct sas_rphy *rphy)
{}

/* phy control request structure */
struct phy_control_request {};

/* phy control reply structure */
struct phy_control_reply {};

#define SMP_PHY_CONTROL_LINK_RESET
#define SMP_PHY_CONTROL_HARD_RESET
#define SMP_PHY_CONTROL_DISABLE

/**
 * mpi3mr_expander_phy_control - expander phy control
 * @mrioc: Adapter instance reference
 * @phy: The SAS transport layer phy object
 * @phy_operation: The phy operation to be executed
 *
 * Issues SMP passthru phy control request to execute a specific
 * phy operation for a given expander device.
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_expander_phy_control(struct mpi3mr_ioc *mrioc,
	struct sas_phy *phy, u8 phy_operation)
{}

/**
 * mpi3mr_transport_phy_reset - Reset a given phy
 * @phy: The SAS transport layer phy object
 * @hard_reset: Flag to indicate the type of reset
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_transport_phy_reset(struct sas_phy *phy, int hard_reset)
{}

/**
 * mpi3mr_transport_phy_enable - enable/disable phys
 * @phy: The SAS transport layer phy object
 * @enable: flag to enable/disable, enable phy when true
 *
 * This function enables/disables a given by executing required
 * configuration page changes or expander phy control command
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_transport_phy_enable(struct sas_phy *phy, int enable)
{}

/**
 * mpi3mr_transport_phy_speed - set phy min/max speed
 * @phy: The SAS transport later phy object
 * @rates: Rates defined as in sas_phy_linkrates
 *
 * This function sets the link rates given in the rates
 * argument to the given phy by executing required configuration
 * page changes or expander phy control command
 *
 * Return: 0 for success, non-zero for failure.
 */
static int
mpi3mr_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates)
{}

/**
 * mpi3mr_map_smp_buffer - map BSG dma buffer
 * @dev: Generic device reference
 * @buf: BSG buffer pointer
 * @dma_addr: Physical address holder
 * @dma_len: Mapped DMA buffer length.
 * @p: Virtual address holder
 *
 * This function maps the DMAable buffer
 *
 * Return: 0 on success, non-zero on failure
 */
static int
mpi3mr_map_smp_buffer(struct device *dev, struct bsg_buffer *buf,
		dma_addr_t *dma_addr, size_t *dma_len, void **p)
{}

/**
 * mpi3mr_unmap_smp_buffer - unmap BSG dma buffer
 * @dev: Generic device reference
 * @buf: BSG buffer pointer
 * @dma_addr: Physical address to be unmapped
 * @p: Virtual address
 *
 * This function unmaps the DMAable buffer
 */
static void
mpi3mr_unmap_smp_buffer(struct device *dev, struct bsg_buffer *buf,
		dma_addr_t dma_addr, void *p)
{}

/**
 * mpi3mr_transport_smp_handler - handler for smp passthru
 * @job: BSG job reference
 * @shost: SCSI host object reference
 * @rphy: SAS transport rphy object pointing the expander
 *
 * This is used primarily by smp utils for sending the SMP
 * commands to the expanders attached to the controller
 */
static void
mpi3mr_transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
	struct sas_rphy *rphy)
{}

struct sas_function_template mpi3mr_transport_functions =;

struct scsi_transport_template *mpi3mr_transport_template;