linux/drivers/scsi/libsas/sas_expander.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Serial Attached SCSI (SAS) Expander discovery and configuration
 *
 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
 * Copyright (C) 2005 Luben Tuikov <[email protected]>
 *
 * This file is licensed under GPLv2.
 */

#include <linux/scatterlist.h>
#include <linux/blkdev.h>
#include <linux/slab.h>
#include <asm/unaligned.h>

#include "sas_internal.h"

#include <scsi/sas_ata.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_sas.h>
#include "scsi_sas_internal.h"

static int sas_discover_expander(struct domain_device *dev);
static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr);
static int sas_configure_phy(struct domain_device *dev, int phy_id,
			     u8 *sas_addr, int include);
static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr);

static void sas_port_add_ex_phy(struct sas_port *port, struct ex_phy *ex_phy)
{}

static void sas_ex_add_parent_port(struct domain_device *dev, int phy_id)
{}

/* ---------- SMP task management ---------- */

/* Give it some long enough timeout. In seconds. */
#define SMP_TIMEOUT

static int smp_execute_task_sg(struct domain_device *dev,
		struct scatterlist *req, struct scatterlist *resp)
{}

static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
			    void *resp, int resp_size)
{}

/* ---------- Allocations ---------- */

static inline void *alloc_smp_req(int size)
{}

static inline void *alloc_smp_resp(int size)
{}

static char sas_route_char(struct domain_device *dev, struct ex_phy *phy)
{}

static enum sas_device_type to_dev_type(struct discover_resp *dr)
{}

static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
			   struct smp_disc_resp *disc_resp)
{}

/* check if we have an existing attached ata device on this expander phy */
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
{}

#define DISCOVER_REQ_SIZE
#define DISCOVER_RESP_SIZE

static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
				      struct smp_disc_resp *disc_resp,
				      int single)
{}

int sas_ex_phy_discover(struct domain_device *dev, int single)
{}

static int sas_expander_discover(struct domain_device *dev)
{}

#define MAX_EXPANDER_PHYS

#define RG_REQ_SIZE
#define RG_RESP_SIZE

static int sas_ex_general(struct domain_device *dev)
{}

static void ex_assign_manuf_info(struct domain_device *dev, void
					*_mi_resp)
{}

#define MI_REQ_SIZE
#define MI_RESP_SIZE

static int sas_ex_manuf_info(struct domain_device *dev)
{}

#define PC_REQ_SIZE
#define PC_RESP_SIZE

int sas_smp_phy_control(struct domain_device *dev, int phy_id,
			enum phy_func phy_func,
			struct sas_phy_linkrates *rates)
{}

static void sas_ex_disable_phy(struct domain_device *dev, int phy_id)
{}

static void sas_ex_disable_port(struct domain_device *dev, u8 *sas_addr)
{}

static int sas_dev_present_in_domain(struct asd_sas_port *port,
					    u8 *sas_addr)
{}

#define RPEL_REQ_SIZE
#define RPEL_RESP_SIZE
int sas_smp_get_phy_events(struct sas_phy *phy)
{}

#ifdef CONFIG_SCSI_SAS_ATA

#define RPS_REQ_SIZE
#define RPS_RESP_SIZE

int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
			    struct smp_rps_resp *rps_resp)
{}
#endif

static void sas_ex_get_linkrate(struct domain_device *parent,
				       struct domain_device *child,
				       struct ex_phy *parent_phy)
{}

static int sas_ex_add_dev(struct domain_device *parent, struct ex_phy *phy,
			  struct domain_device *child, int phy_id)
{}

static struct domain_device *sas_ex_discover_end_dev(
	struct domain_device *parent, int phy_id)
{}

/* See if this phy is part of a wide port */
static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
{}

static struct domain_device *sas_ex_discover_expander(
	struct domain_device *parent, int phy_id)
{}

static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
{}

static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
{}

static int sas_check_level_subtractive_boundary(struct domain_device *dev)
{}
/**
 * sas_ex_discover_devices - discover devices attached to this expander
 * @dev: pointer to the expander domain device
 * @single: if you want to do a single phy, else set to -1;
 *
 * Configure this expander for use with its devices and register the
 * devices of this expander.
 */
static int sas_ex_discover_devices(struct domain_device *dev, int single)
{}

static int sas_check_ex_subtractive_boundary(struct domain_device *dev)
{}

static void sas_print_parent_topology_bug(struct domain_device *child,
						 struct ex_phy *parent_phy,
						 struct ex_phy *child_phy)
{}

static bool sas_eeds_valid(struct domain_device *parent,
			   struct domain_device *child)
{}

static int sas_check_eeds(struct domain_device *child,
			  struct ex_phy *parent_phy,
			  struct ex_phy *child_phy)
{}

static int sas_check_edge_expander_topo(struct domain_device *child,
					struct ex_phy *parent_phy)
{}

static int sas_check_fanout_expander_topo(struct domain_device *child,
					  struct ex_phy *parent_phy)
{}

static int sas_check_parent_topology(struct domain_device *child)
{}

#define RRI_REQ_SIZE
#define RRI_RESP_SIZE

static int sas_configure_present(struct domain_device *dev, int phy_id,
				 u8 *sas_addr, int *index, int *present)
{}

#define CRI_REQ_SIZE
#define CRI_RESP_SIZE

static int sas_configure_set(struct domain_device *dev, int phy_id,
			     u8 *sas_addr, int index, int include)
{}

static int sas_configure_phy(struct domain_device *dev, int phy_id,
				    u8 *sas_addr, int include)
{}

/**
 * sas_configure_parent - configure routing table of parent
 * @parent: parent expander
 * @child: child expander
 * @sas_addr: SAS port identifier of device directly attached to child
 * @include: whether or not to include @child in the expander routing table
 */
static int sas_configure_parent(struct domain_device *parent,
				struct domain_device *child,
				u8 *sas_addr, int include)
{}

/**
 * sas_configure_routing - configure routing
 * @dev: expander device
 * @sas_addr: port identifier of device directly attached to the expander device
 */
static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
{}

static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr)
{}

/**
 * sas_discover_expander - expander discovery
 * @dev: pointer to expander domain device
 *
 * See comment in sas_discover_sata().
 */
static int sas_discover_expander(struct domain_device *dev)
{}

static int sas_ex_level_discovery(struct asd_sas_port *port, const int level)
{}

static int sas_ex_bfs_disc(struct asd_sas_port *port)
{}

int sas_discover_root_expander(struct domain_device *dev)
{}

/* ---------- Domain revalidation ---------- */

static void sas_get_sas_addr_and_dev_type(struct smp_disc_resp *disc_resp,
					  u8 *sas_addr,
					  enum sas_device_type *type)
{}

static int sas_get_phy_discover(struct domain_device *dev,
				int phy_id, struct smp_disc_resp *disc_resp)
{}

static int sas_get_phy_change_count(struct domain_device *dev,
				    int phy_id, int *pcc)
{}

int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
			     u8 *sas_addr, enum sas_device_type *type)
{}

static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
			      int from_phy, bool update)
{}

static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
{}
/**
 * sas_find_bcast_dev -  find the device issue BROADCAST(CHANGE).
 * @dev:domain device to be detect.
 * @src_dev: the device which originated BROADCAST(CHANGE).
 *
 * Add self-configuration expander support. Suppose two expander cascading,
 * when the first level expander is self-configuring, hotplug the disks in
 * second level expander, BROADCAST(CHANGE) will not only be originated
 * in the second level expander, but also be originated in the first level
 * expander (see SAS protocol SAS 2r-14, 7.11 for detail), it is to say,
 * expander changed count in two level expanders will all increment at least
 * once, but the phy which chang count has changed is the source device which
 * we concerned.
 */

static int sas_find_bcast_dev(struct domain_device *dev,
			      struct domain_device **src_dev)
{}

static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_device *dev)
{}

static void sas_unregister_devs_sas_addr(struct domain_device *parent,
					 int phy_id, bool last)
{}

static int sas_discover_bfs_by_root_level(struct domain_device *root,
					  const int level)
{}

static int sas_discover_bfs_by_root(struct domain_device *dev)
{}

static int sas_discover_new(struct domain_device *dev, int phy_id)
{}

static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old)
{}

static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
			      bool last, int sibling)
{}

/**
 * sas_rediscover - revalidate the domain.
 * @dev:domain device to be detect.
 * @phy_id: the phy id will be detected.
 *
 * NOTE: this process _must_ quit (return) as soon as any connection
 * errors are encountered.  Connection recovery is done elsewhere.
 * Discover process only interrogates devices in order to discover the
 * domain.For plugging out, we un-register the device only when it is
 * the last phy in the port, for other phys in this port, we just delete it
 * from the port.For inserting, we do discovery when it is the
 * first phy,for other phys in this port, we add it to the port to
 * forming the wide-port.
 */
static int sas_rediscover(struct domain_device *dev, const int phy_id)
{}

/**
 * sas_ex_revalidate_domain - revalidate the domain
 * @port_dev: port domain device.
 *
 * NOTE: this process _must_ quit (return) as soon as any connection
 * errors are encountered.  Connection recovery is done elsewhere.
 * Discover process only interrogates devices in order to discover the
 * domain.
 */
int sas_ex_revalidate_domain(struct domain_device *port_dev)
{}

int sas_find_attached_phy_id(struct expander_device *ex_dev,
			     struct domain_device *dev)
{}
EXPORT_SYMBOL_GPL();

void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
		struct sas_rphy *rphy)
{}