/*
 * Copyright (C) 2005-2006 Dell Inc.
 *	Released under GPL v2.
 *
 * Serial Attached SCSI (SAS) transport class.
 *
 * The SAS transport class contains common code to deal with SAS HBAs,
 * an aproximated representation of SAS topologies in the driver model,
 * and various sysfs attributes to expose these topologies and management
 * interfaces to userspace.
 *
 * In addition to the basic SCSI core objects this transport class
 * introduces two additional intermediate objects:  The SAS PHY
 * as represented by struct sas_phy defines an "outgoing" PHY on
 * a SAS HBA or Expander, and the SAS remote PHY represented by
 * struct sas_rphy defines an "incoming" PHY on a SAS Expander or
 * end device.  Note that this is purely a software concept, the
 * underlying hardware for a PHY and a remote PHY is the exactly
 * the same.
 *
 * There is no concept of a SAS port in this code, users can see
 * what PHYs form a wide port based on the port_identifier attribute,
 * which is the same for all PHYs in a port.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/blkdev.h>
#include <linux/bsg.h>

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_sas.h>

#include "scsi_sas_internal.h"
struct sas_host_attrs {
	struct list_head rphy_list;
	struct mutex lock;
	struct request_queue *q;
	u32 next_target_id;
	u32 next_expander_id;
	int next_port_id;
};
#define to_sas_host_attrs(host)	((struct sas_host_attrs *)(host)->shost_data)


/*
 * Hack to allow attributes of the same name in different objects.
 */
#define SAS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
	struct device_attribute dev_attr_##_prefix##_##_name = \
	__ATTR(_name,_mode,_show,_store)


/*
 * Pretty printing helpers
 */

#define sas_bitfield_name_match(title, table)			\
static ssize_t							\
get_sas_##title##_names(u32 table_key, char *buf)		\
{								\
	char *prefix = "";					\
	ssize_t len = 0;					\
	int i;							\
								\
	for (i = 0; i < ARRAY_SIZE(table); i++) {		\
		if (table[i].value & table_key) {		\
			len += sprintf(buf + len, "%s%s",	\
				prefix, table[i].name);		\
			prefix = ", ";				\
		}						\
	}							\
	len += sprintf(buf + len, "\n");			\
	return len;						\
}

#define sas_bitfield_name_set(title, table)			\
static ssize_t							\
set_sas_##title##_names(u32 *table_key, const char *buf)	\
{								\
	ssize_t len = 0;					\
	int i;							\
								\
	for (i = 0; i < ARRAY_SIZE(table); i++) {		\
		len = strlen(table[i].name);			\
		if (strncmp(buf, table[i].name, len) == 0 &&	\
		    (buf[len] == '\n' || buf[len] == '\0')) {	\
			*table_key = table[i].value;		\
			return 0;				\
		}						\
	}							\
	return -EINVAL;						\
}

#define sas_bitfield_name_search(title, table)			\
static ssize_t							\
get_sas_##title##_names(u32 table_key, char *buf)		\
{								\
	ssize_t len = 0;					\
	int i;							\
								\
	for (i = 0; i < ARRAY_SIZE(table); i++) {		\
		if (table[i].value == table_key) {		\
			len += sprintf(buf + len, "%s",		\
				table[i].name);			\
			break;					\
		}						\
	}							\
	len += sprintf(buf + len, "\n");			\
	return len;						\
}

static struct {
	u32		value;
	char		*name;
} sas_device_type_names[] = {
	{ SAS_PHY_UNUSED,		"unused" },
	{ SAS_END_DEVICE,		"end device" },
	{ SAS_EDGE_EXPANDER_DEVICE,	"edge expander" },
	{ SAS_FANOUT_EXPANDER_DEVICE,	"fanout expander" },
};
sas_bitfield_name_search(device_type, sas_device_type_names)


static struct {
	u32		value;
	char		*name;
} sas_protocol_names[] = {
	{ SAS_PROTOCOL_SATA,		"sata" },
	{ SAS_PROTOCOL_SMP,		"smp" },
	{ SAS_PROTOCOL_STP,		"stp" },
	{ SAS_PROTOCOL_SSP,		"ssp" },
};
sas_bitfield_name_match(protocol, sas_protocol_names)

static struct {
	u32		value;
	char		*name;
} sas_linkspeed_names[] = {
	{ SAS_LINK_RATE_UNKNOWN,	"Unknown" },
	{ SAS_PHY_DISABLED,		"Phy disabled" },
	{ SAS_LINK_RATE_FAILED,		"Link Rate failed" },
	{ SAS_SATA_SPINUP_HOLD,		"Spin-up hold" },
	{ SAS_LINK_RATE_1_5_GBPS,	"1.5 Gbit" },
	{ SAS_LINK_RATE_3_0_GBPS,	"3.0 Gbit" },
	{ SAS_LINK_RATE_6_0_GBPS,	"6.0 Gbit" },
	{ SAS_LINK_RATE_12_0_GBPS,	"12.0 Gbit" },
};
sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
sas_bitfield_name_set(linkspeed, sas_linkspeed_names)

static struct sas_end_device *sas_sdev_to_rdev(struct scsi_device *sdev)
{
	struct sas_rphy *rphy = target_to_rphy(sdev->sdev_target);
	struct sas_end_device *rdev;

	BUG_ON(rphy->identify.device_type != SAS_END_DEVICE);

	rdev = rphy_to_end_device(rphy);
	return rdev;
}

static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
			    struct sas_rphy *rphy)
{
	struct request *req;
	int ret;
	int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);

	while ((req = blk_fetch_request(q)) != NULL) {
		spin_unlock_irq(q->queue_lock);

		handler = to_sas_internal(shost->transportt)->f->smp_handler;
		ret = handler(shost, rphy, req);
		req->errors = ret;

		blk_end_request_all(req, ret);

		spin_lock_irq(q->queue_lock);
	}
}

static void sas_host_smp_request(struct request_queue *q)
{
	sas_smp_request(q, (struct Scsi_Host *)q->queuedata, NULL);
}

static void sas_non_host_smp_request(struct request_queue *q)
{
	struct sas_rphy *rphy = q->queuedata;
	sas_smp_request(q, rphy_to_shost(rphy), rphy);
}

static void sas_host_release(struct device *dev)
{
	struct Scsi_Host *shost = dev_to_shost(dev);
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
	struct request_queue *q = sas_host->q;

	if (q)
		blk_cleanup_queue(q);
}

static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
{
	struct request_queue *q;
	int error;
	struct device *dev;
	char namebuf[20];
	const char *name;
	void (*release)(struct device *);

	if (!to_sas_internal(shost->transportt)->f->smp_handler) {
		printk("%s can't handle SMP requests\n", shost->hostt->name);
		return 0;
	}

	if (rphy) {
		q = blk_init_queue(sas_non_host_smp_request, NULL);
		dev = &rphy->dev;
		name = dev_name(dev);
		release = NULL;
	} else {
		q = blk_init_queue(sas_host_smp_request, NULL);
		dev = &shost->shost_gendev;
		snprintf(namebuf, sizeof(namebuf),
			 "sas_host%d", shost->host_no);
		name = namebuf;
		release = sas_host_release;
	}
	if (!q)
		return -ENOMEM;

	error = bsg_register_queue(q, dev, name, release);
	if (error) {
		blk_cleanup_queue(q);
		return -ENOMEM;
	}

	if (rphy)
		rphy->q = q;
	else
		to_sas_host_attrs(shost)->q = q;

	if (rphy)
		q->queuedata = rphy;
	else
		q->queuedata = shost;

	queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
	return 0;
}

static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy)
{
	struct request_queue *q;

	if (rphy)
		q = rphy->q;
	else
		q = to_sas_host_attrs(shost)->q;

	if (!q)
		return;

	bsg_unregister_queue(q);
}

/*
 * SAS host attributes
 */

static int sas_host_setup(struct transport_container *tc, struct device *dev,
			  struct device *cdev)
{
	struct Scsi_Host *shost = dev_to_shost(dev);
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);

	INIT_LIST_HEAD(&sas_host->rphy_list);
	mutex_init(&sas_host->lock);
	sas_host->next_target_id = 0;
	sas_host->next_expander_id = 0;
	sas_host->next_port_id = 0;

	if (sas_bsg_initialize(shost, NULL))
		dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n",
			   shost->host_no);

	return 0;
}

static int sas_host_remove(struct transport_container *tc, struct device *dev,
			   struct device *cdev)
{
	struct Scsi_Host *shost = dev_to_shost(dev);

	sas_bsg_remove(shost, NULL);

	return 0;
}

static DECLARE_TRANSPORT_CLASS(sas_host_class,
		"sas_host", sas_host_setup, sas_host_remove, NULL);

static int sas_host_match(struct attribute_container *cont,
			    struct device *dev)
{
	struct Scsi_Host *shost;
	struct sas_internal *i;

	if (!scsi_is_host_device(dev))
		return 0;
	shost = dev_to_shost(dev);

	if (!shost->transportt)
		return 0;
	if (shost->transportt->host_attrs.ac.class !=
			&sas_host_class.class)
		return 0;

	i = to_sas_internal(shost->transportt);
	return &i->t.host_attrs.ac == cont;
}

static int do_sas_phy_delete(struct device *dev, void *data)
{
	int pass = (int)(unsigned long)data;

	if (pass == 0 && scsi_is_sas_port(dev))
		sas_port_delete(dev_to_sas_port(dev));
	else if (pass == 1 && scsi_is_sas_phy(dev))
		sas_phy_delete(dev_to_phy(dev));
	return 0;
}

/**
 * sas_remove_children  -  tear down a devices SAS data structures
 * @dev:	device belonging to the sas object
 *
 * Removes all SAS PHYs and remote PHYs for a given object
 */
void sas_remove_children(struct device *dev)
{
	device_for_each_child(dev, (void *)0, do_sas_phy_delete);
	device_for_each_child(dev, (void *)1, do_sas_phy_delete);
}
EXPORT_SYMBOL(sas_remove_children);

/**
 * sas_remove_host  -  tear down a Scsi_Host's SAS data structures
 * @shost:	Scsi Host that is torn down
 *
 * Removes all SAS PHYs and remote PHYs for a given Scsi_Host.
 * Must be called just before scsi_remove_host for SAS HBAs.
 */
void sas_remove_host(struct Scsi_Host *shost)
{
	sas_remove_children(&shost->shost_gendev);
}
EXPORT_SYMBOL(sas_remove_host);

/**
 * sas_tlr_supported - checking TLR bit in vpd 0x90
 * @sdev: scsi device struct
 *
 * Check Transport Layer Retries are supported or not.
 * If vpd page 0x90 is present, TRL is supported.
 *
 */
unsigned int
sas_tlr_supported(struct scsi_device *sdev)
{
	const int vpd_len = 32;
	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
	char *buffer = kzalloc(vpd_len, GFP_KERNEL);
	int ret = 0;

	if (scsi_get_vpd_page(sdev, 0x90, buffer, vpd_len))
		goto out;

	/*
	 * Magic numbers: the VPD Protocol page (0x90)
	 * has a 4 byte header and then one entry per device port
	 * the TLR bit is at offset 8 on each port entry
	 * if we take the first port, that's at total offset 12
	 */
	ret = buffer[12] & 0x01;

 out:
	kfree(buffer);
	rdev->tlr_supported = ret;
	return ret;

}
EXPORT_SYMBOL_GPL(sas_tlr_supported);

/**
 * sas_disable_tlr - setting TLR flags
 * @sdev: scsi device struct
 *
 * Seting tlr_enabled flag to 0.
 *
 */
void
sas_disable_tlr(struct scsi_device *sdev)
{
	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);

	rdev->tlr_enabled = 0;
}
EXPORT_SYMBOL_GPL(sas_disable_tlr);

/**
 * sas_enable_tlr - setting TLR flags
 * @sdev: scsi device struct
 *
 * Seting tlr_enabled flag 1.
 *
 */
void sas_enable_tlr(struct scsi_device *sdev)
{
	unsigned int tlr_supported = 0;
	tlr_supported  = sas_tlr_supported(sdev);

	if (tlr_supported) {
		struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);

		rdev->tlr_enabled = 1;
	}

	return;
}
EXPORT_SYMBOL_GPL(sas_enable_tlr);

unsigned int sas_is_tlr_enabled(struct scsi_device *sdev)
{
	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
	return rdev->tlr_enabled;
}
EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);

/*
 * SAS Phy attributes
 */

#define sas_phy_show_simple(field, name, format_string, cast)		\
static ssize_t								\
show_sas_phy_##name(struct device *dev, 				\
		    struct device_attribute *attr, char *buf)		\
{									\
	struct sas_phy *phy = transport_class_to_phy(dev);		\
									\
	return snprintf(buf, 20, format_string, cast phy->field);	\
}

#define sas_phy_simple_attr(field, name, format_string, type)		\
	sas_phy_show_simple(field, name, format_string, (type))	\
static DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)

#define sas_phy_show_protocol(field, name)				\
static ssize_t								\
show_sas_phy_##name(struct device *dev, 				\
		    struct device_attribute *attr, char *buf)		\
{									\
	struct sas_phy *phy = transport_class_to_phy(dev);		\
									\
	if (!phy->field)						\
		return snprintf(buf, 20, "none\n");			\
	return get_sas_protocol_names(phy->field, buf);		\
}

#define sas_phy_protocol_attr(field, name)				\
	sas_phy_show_protocol(field, name)				\
static DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)

#define sas_phy_show_linkspeed(field)					\
static ssize_t								\
show_sas_phy_##field(struct device *dev, 				\
		     struct device_attribute *attr, char *buf)		\
{									\
	struct sas_phy *phy = transport_class_to_phy(dev);		\
									\
	return get_sas_linkspeed_names(phy->field, buf);		\
}

/* Fudge to tell if we're minimum or maximum */
#define sas_phy_store_linkspeed(field)					\
static ssize_t								\
store_sas_phy_##field(struct device *dev, 				\
		      struct device_attribute *attr, 			\
		      const char *buf,	size_t count)			\
{									\
	struct sas_phy *phy = transport_class_to_phy(dev);		\
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);	\
	struct sas_internal *i = to_sas_internal(shost->transportt);	\
	u32 value;							\
	struct sas_phy_linkrates rates = {0};				\
	int error;							\
									\
	error = set_sas_linkspeed_names(&value, buf);			\
	if (error)							\
		return error;						\
	rates.field = value;						\
	error = i->f->set_phy_speed(phy, &rates);			\
									\
	return error ? error : count;					\
}

#define sas_phy_linkspeed_rw_attr(field)				\
	sas_phy_show_linkspeed(field)					\
	sas_phy_store_linkspeed(field)					\
static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field,		\
	store_sas_phy_##field)

#define sas_phy_linkspeed_attr(field)					\
	sas_phy_show_linkspeed(field)					\
static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)


#define sas_phy_show_linkerror(field)					\
static ssize_t								\
show_sas_phy_##field(struct device *dev, 				\
		     struct device_attribute *attr, char *buf)		\
{									\
	struct sas_phy *phy = transport_class_to_phy(dev);		\
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);	\
	struct sas_internal *i = to_sas_internal(shost->transportt);	\
	int error;							\
									\
	error = i->f->get_linkerrors ? i->f->get_linkerrors(phy) : 0;	\
	if (error)							\
		return error;						\
	return snprintf(buf, 20, "%u\n", phy->field);			\
}

#define sas_phy_linkerror_attr(field)					\
	sas_phy_show_linkerror(field)					\
static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)


static ssize_t
show_sas_device_type(struct device *dev,
		     struct device_attribute *attr, char *buf)
{
	struct sas_phy *phy = transport_class_to_phy(dev);

	if (!phy->identify.device_type)
		return snprintf(buf, 20, "none\n");
	return get_sas_device_type_names(phy->identify.device_type, buf);
}
static DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);

static ssize_t do_sas_phy_enable(struct device *dev,
		size_t count, int enable)
{
	struct sas_phy *phy = transport_class_to_phy(dev);
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
	struct sas_internal *i = to_sas_internal(shost->transportt);
	int error;

	error = i->f->phy_enable(phy, enable);
	if (error)
		return error;
	phy->enabled = enable;
	return count;
};

static ssize_t
store_sas_phy_enable(struct device *dev, struct device_attribute *attr,
		     const char *buf, size_t count)
{
	if (count < 1)
		return -EINVAL;

	switch (buf[0]) {
	case '0':
		do_sas_phy_enable(dev, count, 0);
		break;
	case '1':
		do_sas_phy_enable(dev, count, 1);
		break;
	default:
		return -EINVAL;
	}

	return count;
}

static ssize_t
show_sas_phy_enable(struct device *dev, struct device_attribute *attr,
		    char *buf)
{
	struct sas_phy *phy = transport_class_to_phy(dev);

	return snprintf(buf, 20, "%d", phy->enabled);
}

static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, show_sas_phy_enable,
			 store_sas_phy_enable);

static ssize_t
do_sas_phy_reset(struct device *dev, size_t count, int hard_reset)
{
	struct sas_phy *phy = transport_class_to_phy(dev);
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
	struct sas_internal *i = to_sas_internal(shost->transportt);
	int error;

	error = i->f->phy_reset(phy, hard_reset);
	if (error)
		return error;
	phy->enabled = 1;
	return count;
};

static ssize_t
store_sas_link_reset(struct device *dev, struct device_attribute *attr,
		     const char *buf, size_t count)
{
	return do_sas_phy_reset(dev, count, 0);
}
static DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset);

static ssize_t
store_sas_hard_reset(struct device *dev, struct device_attribute *attr,
		     const char *buf, size_t count)
{
	return do_sas_phy_reset(dev, count, 1);
}
static DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset);

sas_phy_protocol_attr(identify.initiator_port_protocols,
		initiator_port_protocols);
sas_phy_protocol_attr(identify.target_port_protocols,
		target_port_protocols);
sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
		unsigned long long);
sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int);
sas_phy_linkspeed_attr(negotiated_linkrate);
sas_phy_linkspeed_attr(minimum_linkrate_hw);
sas_phy_linkspeed_rw_attr(minimum_linkrate);
sas_phy_linkspeed_attr(maximum_linkrate_hw);
sas_phy_linkspeed_rw_attr(maximum_linkrate);
sas_phy_linkerror_attr(invalid_dword_count);
sas_phy_linkerror_attr(running_disparity_error_count);
sas_phy_linkerror_attr(loss_of_dword_sync_count);
sas_phy_linkerror_attr(phy_reset_problem_count);

static int sas_phy_setup(struct transport_container *tc, struct device *dev,
			 struct device *cdev)
{
	struct sas_phy *phy = dev_to_phy(dev);
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
	struct sas_internal *i = to_sas_internal(shost->transportt);

	if (i->f->phy_setup)
		i->f->phy_setup(phy);

	return 0;
}

static DECLARE_TRANSPORT_CLASS(sas_phy_class,
		"sas_phy", sas_phy_setup, NULL, NULL);

static int sas_phy_match(struct attribute_container *cont, struct device *dev)
{
	struct Scsi_Host *shost;
	struct sas_internal *i;

	if (!scsi_is_sas_phy(dev))
		return 0;
	shost = dev_to_shost(dev->parent);

	if (!shost->transportt)
		return 0;
	if (shost->transportt->host_attrs.ac.class !=
			&sas_host_class.class)
		return 0;

	i = to_sas_internal(shost->transportt);
	return &i->phy_attr_cont.ac == cont;
}

static void sas_phy_release(struct device *dev)
{
	struct sas_phy *phy = dev_to_phy(dev);
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
	struct sas_internal *i = to_sas_internal(shost->transportt);

	if (i->f->phy_release)
		i->f->phy_release(phy);
	put_device(dev->parent);
	kfree(phy);
}

/**
 * sas_phy_alloc  -  allocates and initialize a SAS PHY structure
 * @parent:	Parent device
 * @number:	Phy index
 *
 * Allocates an SAS PHY structure.  It will be added in the device tree
 * below the device specified by @parent, which has to be either a Scsi_Host
 * or sas_rphy.
 *
 * Returns:
 *	SAS PHY allocated or %NULL if the allocation failed.
 */
struct sas_phy *sas_phy_alloc(struct device *parent, int number)
{
	struct Scsi_Host *shost = dev_to_shost(parent);
	struct sas_phy *phy;

	phy = kzalloc(sizeof(*phy), GFP_KERNEL);
	if (!phy)
		return NULL;

	phy->number = number;
	phy->enabled = 1;

	device_initialize(&phy->dev);
	phy->dev.parent = get_device(parent);
	phy->dev.release = sas_phy_release;
	INIT_LIST_HEAD(&phy->port_siblings);
	if (scsi_is_sas_expander_device(parent)) {
		struct sas_rphy *rphy = dev_to_rphy(parent);
		dev_set_name(&phy->dev, "phy-%d:%d:%d", shost->host_no,
			rphy->scsi_target_id, number);
	} else
		dev_set_name(&phy->dev, "phy-%d:%d", shost->host_no, number);

	transport_setup_device(&phy->dev);

	return phy;
}
EXPORT_SYMBOL(sas_phy_alloc);

/**
 * sas_phy_add  -  add a SAS PHY to the device hierarchy
 * @phy:	The PHY to be added
 *
 * Publishes a SAS PHY to the rest of the system.
 */
int sas_phy_add(struct sas_phy *phy)
{
	int error;

	error = device_add(&phy->dev);
	if (!error) {
		transport_add_device(&phy->dev);
		transport_configure_device(&phy->dev);
	}

	return error;
}
EXPORT_SYMBOL(sas_phy_add);

/**
 * sas_phy_free  -  free a SAS PHY
 * @phy:	SAS PHY to free
 *
 * Frees the specified SAS PHY.
 *
 * Note:
 *   This function must only be called on a PHY that has not
 *   successfully been added using sas_phy_add().
 */
void sas_phy_free(struct sas_phy *phy)
{
	transport_destroy_device(&phy->dev);
	put_device(&phy->dev);
}
EXPORT_SYMBOL(sas_phy_free);

/**
 * sas_phy_delete  -  remove SAS PHY
 * @phy:	SAS PHY to remove
 *
 * Removes the specified SAS PHY.  If the SAS PHY has an
 * associated remote PHY it is removed before.
 */
void
sas_phy_delete(struct sas_phy *phy)
{
	struct device *dev = &phy->dev;

	/* this happens if the phy is still part of a port when deleted */
	BUG_ON(!list_empty(&phy->port_siblings));

	transport_remove_device(dev);
	device_del(dev);
	transport_destroy_device(dev);
	put_device(dev);
}
EXPORT_SYMBOL(sas_phy_delete);

/**
 * scsi_is_sas_phy  -  check if a struct device represents a SAS PHY
 * @dev:	device to check
 *
 * Returns:
 *	%1 if the device represents a SAS PHY, %0 else
 */
int scsi_is_sas_phy(const struct device *dev)
{
	return dev->release == sas_phy_release;
}
EXPORT_SYMBOL(scsi_is_sas_phy);

/*
 * SAS Port attributes
 */
#define sas_port_show_simple(field, name, format_string, cast)		\
static ssize_t								\
show_sas_port_##name(struct device *dev, 				\
		     struct device_attribute *attr, char *buf)		\
{									\
	struct sas_port *port = transport_class_to_sas_port(dev);	\
									\
	return snprintf(buf, 20, format_string, cast port->field);	\
}

#define sas_port_simple_attr(field, name, format_string, type)		\
	sas_port_show_simple(field, name, format_string, (type))	\
static DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL)

sas_port_simple_attr(num_phys, num_phys, "%d\n", int);

static DECLARE_TRANSPORT_CLASS(sas_port_class,
			       "sas_port", NULL, NULL, NULL);

static int sas_port_match(struct attribute_container *cont, struct device *dev)
{
	struct Scsi_Host *shost;
	struct sas_internal *i;

	if (!scsi_is_sas_port(dev))
		return 0;
	shost = dev_to_shost(dev->parent);

	if (!shost->transportt)
		return 0;
	if (shost->transportt->host_attrs.ac.class !=
			&sas_host_class.class)
		return 0;

	i = to_sas_internal(shost->transportt);
	return &i->port_attr_cont.ac == cont;
}


static void sas_port_release(struct device *dev)
{
	struct sas_port *port = dev_to_sas_port(dev);

	BUG_ON(!list_empty(&port->phy_list));

	put_device(dev->parent);
	kfree(port);
}

static void sas_port_create_link(struct sas_port *port,
				 struct sas_phy *phy)
{
	int res;

	res = sysfs_create_link(&port->dev.kobj, &phy->dev.kobj,
				dev_name(&phy->dev));
	if (res)
		goto err;
	res = sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port");
	if (res)
		goto err;
	return;
err:
	printk(KERN_ERR "%s: Cannot create port links, err=%d\n",
	       __func__, res);
}

static void sas_port_delete_link(struct sas_port *port,
				 struct sas_phy *phy)
{
	sysfs_remove_link(&port->dev.kobj, dev_name(&phy->dev));
	sysfs_remove_link(&phy->dev.kobj, "port");
}

/** sas_port_alloc - allocate and initialize a SAS port structure
 *
 * @parent:	parent device
 * @port_id:	port number
 *
 * Allocates a SAS port structure.  It will be added to the device tree
 * below the device specified by @parent which must be either a Scsi_Host
 * or a sas_expander_device.
 *
 * Returns %NULL on error
 */
struct sas_port *sas_port_alloc(struct device *parent, int port_id)
{
	struct Scsi_Host *shost = dev_to_shost(parent);
	struct sas_port *port;

	port = kzalloc(sizeof(*port), GFP_KERNEL);
	if (!port)
		return NULL;

	port->port_identifier = port_id;

	device_initialize(&port->dev);

	port->dev.parent = get_device(parent);
	port->dev.release = sas_port_release;

	mutex_init(&port->phy_list_mutex);
	INIT_LIST_HEAD(&port->phy_list);

	if (scsi_is_sas_expander_device(parent)) {
		struct sas_rphy *rphy = dev_to_rphy(parent);
		dev_set_name(&port->dev, "port-%d:%d:%d", shost->host_no,
			     rphy->scsi_target_id, port->port_identifier);
	} else
		dev_set_name(&port->dev, "port-%d:%d", shost->host_no,
			     port->port_identifier);

	transport_setup_device(&port->dev);

	return port;
}
EXPORT_SYMBOL(sas_port_alloc);

/** sas_port_alloc_num - allocate and initialize a SAS port structure
 *
 * @parent:	parent device
 *
 * Allocates a SAS port structure and a number to go with it.  This
 * interface is really for adapters where the port number has no
 * meansing, so the sas class should manage them.  It will be added to
 * the device tree below the device specified by @parent which must be
 * either a Scsi_Host or a sas_expander_device.
 *
 * Returns %NULL on error
 */
struct sas_port *sas_port_alloc_num(struct device *parent)
{
	int index;
	struct Scsi_Host *shost = dev_to_shost(parent);
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);

	/* FIXME: use idr for this eventually */
	mutex_lock(&sas_host->lock);
	if (scsi_is_sas_expander_device(parent)) {
		struct sas_rphy *rphy = dev_to_rphy(parent);
		struct sas_expander_device *exp = rphy_to_expander_device(rphy);

		index = exp->next_port_id++;
	} else
		index = sas_host->next_port_id++;
	mutex_unlock(&sas_host->lock);
	return sas_port_alloc(parent, index);
}
EXPORT_SYMBOL(sas_port_alloc_num);

/**
 * sas_port_add - add a SAS port to the device hierarchy
 * @port:	port to be added
 *
 * publishes a port to the rest of the system
 */
int sas_port_add(struct sas_port *port)
{
	int error;

	/* No phys should be added until this is made visible */
	BUG_ON(!list_empty(&port->phy_list));

	error = device_add(&port->dev);

	if (error)
		return error;

	transport_add_device(&port->dev);
	transport_configure_device(&port->dev);

	return 0;
}
EXPORT_SYMBOL(sas_port_add);

/**
 * sas_port_free  -  free a SAS PORT
 * @port:	SAS PORT to free
 *
 * Frees the specified SAS PORT.
 *
 * Note:
 *   This function must only be called on a PORT that has not
 *   successfully been added using sas_port_add().
 */
void sas_port_free(struct sas_port *port)
{
	transport_destroy_device(&port->dev);
	put_device(&port->dev);
}
EXPORT_SYMBOL(sas_port_free);

/**
 * sas_port_delete  -  remove SAS PORT
 * @port:	SAS PORT to remove
 *
 * Removes the specified SAS PORT.  If the SAS PORT has an
 * associated phys, unlink them from the port as well.
 */
void sas_port_delete(struct sas_port *port)
{
	struct device *dev = &port->dev;
	struct sas_phy *phy, *tmp_phy;

	if (port->rphy) {
		sas_rphy_delete(port->rphy);
		port->rphy = NULL;
	}

	mutex_lock(&port->phy_list_mutex);
	list_for_each_entry_safe(phy, tmp_phy, &port->phy_list,
				 port_siblings) {
		sas_port_delete_link(port, phy);
		list_del_init(&phy->port_siblings);
	}
	mutex_unlock(&port->phy_list_mutex);

	if (port->is_backlink) {
		struct device *parent = port->dev.parent;

		sysfs_remove_link(&port->dev.kobj, dev_name(parent));
		port->is_backlink = 0;
	}

	transport_remove_device(dev);
	device_del(dev);
	transport_destroy_device(dev);
	put_device(dev);
}
EXPORT_SYMBOL(sas_port_delete);

/**
 * scsi_is_sas_port -  check if a struct device represents a SAS port
 * @dev:	device to check
 *
 * Returns:
 *	%1 if the device represents a SAS Port, %0 else
 */
int scsi_is_sas_port(const struct device *dev)
{
	return dev->release == sas_port_release;
}
EXPORT_SYMBOL(scsi_is_sas_port);

/**
 * sas_port_get_phy - try to take a reference on a port member
 * @port: port to check
 */
struct sas_phy *sas_port_get_phy(struct sas_port *port)
{
	struct sas_phy *phy;

	mutex_lock(&port->phy_list_mutex);
	if (list_empty(&port->phy_list))
		phy = NULL;
	else {
		struct list_head *ent = port->phy_list.next;

		phy = list_entry(ent, typeof(*phy), port_siblings);
		get_device(&phy->dev);
	}
	mutex_unlock(&port->phy_list_mutex);

	return phy;
}
EXPORT_SYMBOL(sas_port_get_phy);

/**
 * sas_port_add_phy - add another phy to a port to form a wide port
 * @port:	port to add the phy to
 * @phy:	phy to add
 *
 * When a port is initially created, it is empty (has no phys).  All
 * ports must have at least one phy to operated, and all wide ports
 * must have at least two.  The current code makes no difference
 * between ports and wide ports, but the only object that can be
 * connected to a remote device is a port, so ports must be formed on
 * all devices with phys if they're connected to anything.
 */
void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy)
{
	mutex_lock(&port->phy_list_mutex);
	if (unlikely(!list_empty(&phy->port_siblings))) {
		/* make sure we're already on this port */
		struct sas_phy *tmp;

		list_for_each_entry(tmp, &port->phy_list, port_siblings)
			if (tmp == phy)
				break;
		/* If this trips, you added a phy that was already
		 * part of a different port */
		if (unlikely(tmp != phy)) {
			dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n",
				   dev_name(&phy->dev));
			BUG();
		}
	} else {
		sas_port_create_link(port, phy);
		list_add_tail(&phy->port_siblings, &port->phy_list);
		port->num_phys++;
	}
	mutex_unlock(&port->phy_list_mutex);
}
EXPORT_SYMBOL(sas_port_add_phy);

/**
 * sas_port_delete_phy - remove a phy from a port or wide port
 * @port:	port to remove the phy from
 * @phy:	phy to remove
 *
 * This operation is used for tearing down ports again.  It must be
 * done to every port or wide port before calling sas_port_delete.
 */
void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
{
	mutex_lock(&port->phy_list_mutex);
	sas_port_delete_link(port, phy);
	list_del_init(&phy->port_siblings);
	port->num_phys--;
	mutex_unlock(&port->phy_list_mutex);
}
EXPORT_SYMBOL(sas_port_delete_phy);

void sas_port_mark_backlink(struct sas_port *port)
{
	int res;
	struct device *parent = port->dev.parent->parent->parent;

	if (port->is_backlink)
		return;
	port->is_backlink = 1;
	res = sysfs_create_link(&port->dev.kobj, &parent->kobj,
				dev_name(parent));
	if (res)
		goto err;
	return;
err:
	printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n",
	       __func__, res);

}
EXPORT_SYMBOL(sas_port_mark_backlink);

/*
 * SAS remote PHY attributes.
 */

#define sas_rphy_show_simple(field, name, format_string, cast)		\
static ssize_t								\
show_sas_rphy_##name(struct device *dev, 				\
		     struct device_attribute *attr, char *buf)		\
{									\
	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
									\
	return snprintf(buf, 20, format_string, cast rphy->field);	\
}

#define sas_rphy_simple_attr(field, name, format_string, type)		\
	sas_rphy_show_simple(field, name, format_string, (type))	\
static SAS_DEVICE_ATTR(rphy, name, S_IRUGO, 			\
		show_sas_rphy_##name, NULL)

#define sas_rphy_show_protocol(field, name)				\
static ssize_t								\
show_sas_rphy_##name(struct device *dev, 				\
		     struct device_attribute *attr, char *buf)		\
{									\
	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
									\
	if (!rphy->field)					\
		return snprintf(buf, 20, "none\n");			\
	return get_sas_protocol_names(rphy->field, buf);	\
}

#define sas_rphy_protocol_attr(field, name)				\
	sas_rphy_show_protocol(field, name)				\
static SAS_DEVICE_ATTR(rphy, name, S_IRUGO,			\
		show_sas_rphy_##name, NULL)

static ssize_t
show_sas_rphy_device_type(struct device *dev,
			  struct device_attribute *attr, char *buf)
{
	struct sas_rphy *rphy = transport_class_to_rphy(dev);

	if (!rphy->identify.device_type)
		return snprintf(buf, 20, "none\n");
	return get_sas_device_type_names(
			rphy->identify.device_type, buf);
}

static SAS_DEVICE_ATTR(rphy, device_type, S_IRUGO,
		show_sas_rphy_device_type, NULL);

static ssize_t
show_sas_rphy_enclosure_identifier(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct sas_rphy *rphy = transport_class_to_rphy(dev);
	struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
	struct sas_internal *i = to_sas_internal(shost->transportt);
	u64 identifier;
	int error;

	error = i->f->get_enclosure_identifier(rphy, &identifier);
	if (error)
		return error;
	return sprintf(buf, "0x%llx\n", (unsigned long long)identifier);
}

static SAS_DEVICE_ATTR(rphy, enclosure_identifier, S_IRUGO,
		show_sas_rphy_enclosure_identifier, NULL);

static ssize_t
show_sas_rphy_bay_identifier(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct sas_rphy *rphy = transport_class_to_rphy(dev);
	struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
	struct sas_internal *i = to_sas_internal(shost->transportt);
	int val;

	val = i->f->get_bay_identifier(rphy);
	if (val < 0)
		return val;
	return sprintf(buf, "%d\n", val);
}

static SAS_DEVICE_ATTR(rphy, bay_identifier, S_IRUGO,
		show_sas_rphy_bay_identifier, NULL);

sas_rphy_protocol_attr(identify.initiator_port_protocols,
		initiator_port_protocols);
sas_rphy_protocol_attr(identify.target_port_protocols, target_port_protocols);
sas_rphy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
		unsigned long long);
sas_rphy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);

/* only need 8 bytes of data plus header (4 or 8) */
#define BUF_SIZE 64

int sas_read_port_mode_page(struct scsi_device *sdev)
{
	char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata;
	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
	struct scsi_mode_data mode_data;
	int res, error;

	if (!buffer)
		return -ENOMEM;

	res = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
			      &mode_data, NULL);

	error = -EINVAL;
	if (!scsi_status_is_good(res))
		goto out;

	msdata = buffer +  mode_data.header_length +
		mode_data.block_descriptor_length;

	if (msdata - buffer > BUF_SIZE - 8)
		goto out;

	error = 0;

	rdev->ready_led_meaning = msdata[2] & 0x10 ? 1 : 0;
	rdev->I_T_nexus_loss_timeout = (msdata[4] << 8) + msdata[5];
	rdev->initiator_response_timeout = (msdata[6] << 8) + msdata[7];

 out:
	kfree(buffer);
	return error;
}
EXPORT_SYMBOL(sas_read_port_mode_page);

static DECLARE_TRANSPORT_CLASS(sas_end_dev_class,
			       "sas_end_device", NULL, NULL, NULL);

#define sas_end_dev_show_simple(field, name, format_string, cast)	\
static ssize_t								\
show_sas_end_dev_##name(struct device *dev, 				\
			struct device_attribute *attr, char *buf)	\
{									\
	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
	struct sas_end_device *rdev = rphy_to_end_device(rphy);		\
									\
	return snprintf(buf, 20, format_string, cast rdev->field);	\
}

#define sas_end_dev_simple_attr(field, name, format_string, type)	\
	sas_end_dev_show_simple(field, name, format_string, (type))	\
static SAS_DEVICE_ATTR(end_dev, name, S_IRUGO, 			\
		show_sas_end_dev_##name, NULL)

sas_end_dev_simple_attr(ready_led_meaning, ready_led_meaning, "%d\n", int);
sas_end_dev_simple_attr(I_T_nexus_loss_timeout, I_T_nexus_loss_timeout,
			"%d\n", int);
sas_end_dev_simple_attr(initiator_response_timeout, initiator_response_timeout,
			"%d\n", int);
sas_end_dev_simple_attr(tlr_supported, tlr_supported,
			"%d\n", int);
sas_end_dev_simple_attr(tlr_enabled, tlr_enabled,
			"%d\n", int);

static DECLARE_TRANSPORT_CLASS(sas_expander_class,
			       "sas_expander", NULL, NULL, NULL);

#define sas_expander_show_simple(field, name, format_string, cast)	\
static ssize_t								\
show_sas_expander_##name(struct device *dev, 				\
			 struct device_attribute *attr, char *buf)	\
{									\
	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
	struct sas_expander_device *edev = rphy_to_expander_device(rphy); \
									\
	return snprintf(buf, 20, format_string, cast edev->field);	\
}

#define sas_expander_simple_attr(field, name, format_string, type)	\
	sas_expander_show_simple(field, name, format_string, (type))	\
static SAS_DEVICE_ATTR(expander, name, S_IRUGO, 			\
		show_sas_expander_##name, NULL)

sas_expander_simple_attr(vendor_id, vendor_id, "%s\n", char *);
sas_expander_simple_attr(product_id, product_id, "%s\n", char *);
sas_expander_simple_attr(product_rev, product_rev, "%s\n", char *);
sas_expander_simple_attr(component_vendor_id, component_vendor_id,
			 "%s\n", char *);
sas_expander_simple_attr(component_id, component_id, "%u\n", unsigned int);
sas_expander_simple_attr(component_revision_id, component_revision_id, "%u\n",
			 unsigned int);
sas_expander_simple_attr(level, level, "%d\n", int);

static DECLARE_TRANSPORT_CLASS(sas_rphy_class,
		"sas_device", NULL, NULL, NULL);

static int sas_rphy_match(struct attribute_container *cont, struct device *dev)
{
	struct Scsi_Host *shost;
	struct sas_internal *i;

	if (!scsi_is_sas_rphy(dev))
		return 0;
	shost = dev_to_shost(dev->parent->parent);

	if (!shost->transportt)
		return 0;
	if (shost->transportt->host_attrs.ac.class !=
			&sas_host_class.class)
		return 0;

	i = to_sas_internal(shost->transportt);
	return &i->rphy_attr_cont.ac == cont;
}

static int sas_end_dev_match(struct attribute_container *cont,
			     struct device *dev)
{
	struct Scsi_Host *shost;
	struct sas_internal *i;
	struct sas_rphy *rphy;

	if (!scsi_is_sas_rphy(dev))
		return 0;
	shost = dev_to_shost(dev->parent->parent);
	rphy = dev_to_rphy(dev);

	if (!shost->transportt)
		return 0;
	if (shost->transportt->host_attrs.ac.class !=
			&sas_host_class.class)
		return 0;

	i = to_sas_internal(shost->transportt);
	return &i->end_dev_attr_cont.ac == cont &&
		rphy->identify.device_type == SAS_END_DEVICE;
}

static int sas_expander_match(struct attribute_container *cont,
			      struct device *dev)
{
	struct Scsi_Host *shost;
	struct sas_internal *i;
	struct sas_rphy *rphy;

	if (!scsi_is_sas_rphy(dev))
		return 0;
	shost = dev_to_shost(dev->parent->parent);
	rphy = dev_to_rphy(dev);

	if (!shost->transportt)
		return 0;
	if (shost->transportt->host_attrs.ac.class !=
			&sas_host_class.class)
		return 0;

	i = to_sas_internal(shost->transportt);
	return &i->expander_attr_cont.ac == cont &&
		(rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
		 rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE);
}

static void sas_expander_release(struct device *dev)
{
	struct sas_rphy *rphy = dev_to_rphy(dev);
	struct sas_expander_device *edev = rphy_to_expander_device(rphy);

	if (rphy->q)
		blk_cleanup_queue(rphy->q);

	put_device(dev->parent);
	kfree(edev);
}

static void sas_end_device_release(struct device *dev)
{
	struct sas_rphy *rphy = dev_to_rphy(dev);
	struct sas_end_device *edev = rphy_to_end_device(rphy);

	if (rphy->q)
		blk_cleanup_queue(rphy->q);

	put_device(dev->parent);
	kfree(edev);
}

/**
 * sas_rphy_initialize - common rphy intialization
 * @rphy:	rphy to initialise
 *
 * Used by both sas_end_device_alloc() and sas_expander_alloc() to
 * initialise the common rphy component of each.
 */
static void sas_rphy_initialize(struct sas_rphy *rphy)
{
	INIT_LIST_HEAD(&rphy->list);
}

/**
 * sas_end_device_alloc - allocate an rphy for an end device
 * @parent: which port
 *
 * Allocates an SAS remote PHY structure, connected to @parent.
 *
 * Returns:
 *	SAS PHY allocated or %NULL if the allocation failed.
 */
struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
{
	struct Scsi_Host *shost = dev_to_shost(&parent->dev);
	struct sas_end_device *rdev;

	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
	if (!rdev) {
		return NULL;
	}

	device_initialize(&rdev->rphy.dev);
	rdev->rphy.dev.parent = get_device(&parent->dev);
	rdev->rphy.dev.release = sas_end_device_release;
	if (scsi_is_sas_expander_device(parent->dev.parent)) {
		struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent);
		dev_set_name(&rdev->rphy.dev, "end_device-%d:%d:%d",
			     shost->host_no, rphy->scsi_target_id,
			     parent->port_identifier);
	} else
		dev_set_name(&rdev->rphy.dev, "end_device-%d:%d",
			     shost->host_no, parent->port_identifier);
	rdev->rphy.identify.device_type = SAS_END_DEVICE;
	sas_rphy_initialize(&rdev->rphy);
	transport_setup_device(&rdev->rphy.dev);

	return &rdev->rphy;
}
EXPORT_SYMBOL(sas_end_device_alloc);

/**
 * sas_expander_alloc - allocate an rphy for an end device
 * @parent: which port
 * @type: SAS_EDGE_EXPANDER_DEVICE or SAS_FANOUT_EXPANDER_DEVICE
 *
 * Allocates an SAS remote PHY structure, connected to @parent.
 *
 * Returns:
 *	SAS PHY allocated or %NULL if the allocation failed.
 */
struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
				    enum sas_device_type type)
{
	struct Scsi_Host *shost = dev_to_shost(&parent->dev);
	struct sas_expander_device *rdev;
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);

	BUG_ON(type != SAS_EDGE_EXPANDER_DEVICE &&
	       type != SAS_FANOUT_EXPANDER_DEVICE);

	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
	if (!rdev) {
		return NULL;
	}

	device_initialize(&rdev->rphy.dev);
	rdev->rphy.dev.parent = get_device(&parent->dev);
	rdev->rphy.dev.release = sas_expander_release;
	mutex_lock(&sas_host->lock);
	rdev->rphy.scsi_target_id = sas_host->next_expander_id++;
	mutex_unlock(&sas_host->lock);
	dev_set_name(&rdev->rphy.dev, "expander-%d:%d",
		     shost->host_no, rdev->rphy.scsi_target_id);
	rdev->rphy.identify.device_type = type;
	sas_rphy_initialize(&rdev->rphy);
	transport_setup_device(&rdev->rphy.dev);

	return &rdev->rphy;
}
EXPORT_SYMBOL(sas_expander_alloc);

/**
 * sas_rphy_add  -  add a SAS remote PHY to the device hierarchy
 * @rphy:	The remote PHY to be added
 *
 * Publishes a SAS remote PHY to the rest of the system.
 */
int sas_rphy_add(struct sas_rphy *rphy)
{
	struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
	struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
	struct sas_identify *identify = &rphy->identify;
	int error;

	if (parent->rphy)
		return -ENXIO;
	parent->rphy = rphy;

	error = device_add(&rphy->dev);
	if (error)
		return error;
	transport_add_device(&rphy->dev);
	transport_configure_device(&rphy->dev);
	if (sas_bsg_initialize(shost, rphy))
		printk("fail to a bsg device %s\n", dev_name(&rphy->dev));


	mutex_lock(&sas_host->lock);
	list_add_tail(&rphy->list, &sas_host->rphy_list);
	if (identify->device_type == SAS_END_DEVICE &&
	    (identify->target_port_protocols &
	     (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA)))
		rphy->scsi_target_id = sas_host->next_target_id++;
	else if (identify->device_type == SAS_END_DEVICE)
		rphy->scsi_target_id = -1;
	mutex_unlock(&sas_host->lock);

	if (identify->device_type == SAS_END_DEVICE &&
	    rphy->scsi_target_id != -1) {
		int lun;

		if (identify->target_port_protocols & SAS_PROTOCOL_SSP)
			lun = SCAN_WILD_CARD;
		else
			lun = 0;

		scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun, 0);
	}

	return 0;
}
EXPORT_SYMBOL(sas_rphy_add);

/**
 * sas_rphy_free  -  free a SAS remote PHY
 * @rphy: SAS remote PHY to free
 *
 * Frees the specified SAS remote PHY.
 *
 * Note:
 *   This function must only be called on a remote
 *   PHY that has not successfully been added using
 *   sas_rphy_add() (or has been sas_rphy_remove()'d)
 */
void sas_rphy_free(struct sas_rphy *rphy)
{
	struct device *dev = &rphy->dev;
	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);

	mutex_lock(&sas_host->lock);
	list_del(&rphy->list);
	mutex_unlock(&sas_host->lock);

	transport_destroy_device(dev);

	put_device(dev);
}
EXPORT_SYMBOL(sas_rphy_free);

/**
 * sas_rphy_delete  -  remove and free SAS remote PHY
 * @rphy:	SAS remote PHY to remove and free
 *
 * Removes the specified SAS remote PHY and frees it.
 */
void
sas_rphy_delete(struct sas_rphy *rphy)
{
	sas_rphy_remove(rphy);
	sas_rphy_free(rphy);
}
EXPORT_SYMBOL(sas_rphy_delete);

/**
 * sas_rphy_unlink  -  unlink SAS remote PHY
 * @rphy:	SAS remote phy to unlink from its parent port
 *
 * Removes port reference to an rphy
 */
void sas_rphy_unlink(struct sas_rphy *rphy)
{
	struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);

	parent->rphy = NULL;
}
EXPORT_SYMBOL(sas_rphy_unlink);

/**
 * sas_rphy_remove  -  remove SAS remote PHY
 * @rphy:	SAS remote phy to remove
 *
 * Removes the specified SAS remote PHY.
 */
void
sas_rphy_remove(struct sas_rphy *rphy)
{
	struct device *dev = &rphy->dev;

	switch (rphy->identify.device_type) {
	case SAS_END_DEVICE:
		scsi_remove_target(dev);
		break;
	case SAS_EDGE_EXPANDER_DEVICE:
	case SAS_FANOUT_EXPANDER_DEVICE:
		sas_remove_children(dev);
		break;
	default:
		break;
	}

	sas_rphy_unlink(rphy);
	sas_bsg_remove(NULL, rphy);
	transport_remove_device(dev);
	device_del(dev);
}
EXPORT_SYMBOL(sas_rphy_remove);

/**
 * scsi_is_sas_rphy  -  check if a struct device represents a SAS remote PHY
 * @dev:	device to check
 *
 * Returns:
 *	%1 if the device represents a SAS remote PHY, %0 else
 */
int scsi_is_sas_rphy(const struct device *dev)
{
	return dev->release == sas_end_device_release ||
		dev->release == sas_expander_release;
}
EXPORT_SYMBOL(scsi_is_sas_rphy);


/*
 * SCSI scan helper
 */

static int sas_user_scan(struct Scsi_Host *shost, uint channel,
		uint id, u64 lun)
{
	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
	struct sas_rphy *rphy;

	mutex_lock(&sas_host->lock);
	list_for_each_entry(rphy, &sas_host->rphy_list, list) {
		if (rphy->identify.device_type != SAS_END_DEVICE ||
		    rphy->scsi_target_id == -1)
			continue;

		if ((channel == SCAN_WILD_CARD || channel == 0) &&
		    (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
			scsi_scan_target(&rphy->dev, 0,
					 rphy->scsi_target_id, lun, 1);
		}
	}
	mutex_unlock(&sas_host->lock);

	return 0;
}


/*
 * Setup / Teardown code
 */

#define SETUP_TEMPLATE(attrb, field, perm, test)			\
	i->private_##attrb[count] = dev_attr_##field;		\
	i->private_##attrb[count].attr.mode = perm;			\
	i->attrb[count] = &i->private_##attrb[count];			\
	if (test)							\
		count++

#define SETUP_TEMPLATE_RW(attrb, field, perm, test, ro_test, ro_perm)	\
	i->private_##attrb[count] = dev_attr_##field;		\
	i->private_##attrb[count].attr.mode = perm;			\
	if (ro_test) {							\
		i->private_##attrb[count].attr.mode = ro_perm;		\
		i->private_##attrb[count].store = NULL;			\
	}								\
	i->attrb[count] = &i->private_##attrb[count];			\
	if (test)							\
		count++

#define SETUP_RPORT_ATTRIBUTE(field) 					\
	SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, 1)

#define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func)			\
	SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func)

#define SETUP_PHY_ATTRIBUTE(field)					\
	SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1)

#define SETUP_PHY_ATTRIBUTE_RW(field)					\
	SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1,	\
			!i->f->set_phy_speed, S_IRUGO)

#define SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(field, func)			\
	SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1,	\
			  !i->f->func, S_IRUGO)

#define SETUP_PORT_ATTRIBUTE(field)					\
	SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)

#define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func)			\
	SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func)

#define SETUP_PHY_ATTRIBUTE_WRONLY(field)				\
	SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, 1)

#define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func)		\
	SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, i->f->func)

#define SETUP_END_DEV_ATTRIBUTE(field)					\
	SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1)

#define SETUP_EXPANDER_ATTRIBUTE(field)					\
	SETUP_TEMPLATE(expander_attrs, expander_##field, S_IRUGO, 1)

/**
 * sas_attach_transport  -  instantiate SAS transport template
 * @ft:		SAS transport class function template
 */
struct scsi_transport_template *
sas_attach_transport(struct sas_function_template *ft)
{
	struct sas_internal *i;
	int count;

	i = kzalloc(sizeof(struct sas_internal), GFP_KERNEL);
	if (!i)
		return NULL;

	i->t.user_scan = sas_user_scan;

	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
	i->t.host_attrs.ac.class = &sas_host_class.class;
	i->t.host_attrs.ac.match = sas_host_match;
	transport_container_register(&i->t.host_attrs);
	i->t.host_size = sizeof(struct sas_host_attrs);

	i->phy_attr_cont.ac.class = &sas_phy_class.class;
	i->phy_attr_cont.ac.attrs = &i->phy_attrs[0];
	i->phy_attr_cont.ac.match = sas_phy_match;
	transport_container_register(&i->phy_attr_cont);

	i->port_attr_cont.ac.class = &sas_port_class.class;
	i->port_attr_cont.ac.attrs = &i->port_attrs[0];
	i->port_attr_cont.ac.match = sas_port_match;
	transport_container_register(&i->port_attr_cont);

	i->rphy_attr_cont.ac.class = &sas_rphy_class.class;
	i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0];
	i->rphy_attr_cont.ac.match = sas_rphy_match;
	transport_container_register(&i->rphy_attr_cont);

	i->end_dev_attr_cont.ac.class = &sas_end_dev_class.class;
	i->end_dev_attr_cont.ac.attrs = &i->end_dev_attrs[0];
	i->end_dev_attr_cont.ac.match = sas_end_dev_match;
	transport_container_register(&i->end_dev_attr_cont);

	i->expander_attr_cont.ac.class = &sas_expander_class.class;
	i->expander_attr_cont.ac.attrs = &i->expander_attrs[0];
	i->expander_attr_cont.ac.match = sas_expander_match;
	transport_container_register(&i->expander_attr_cont);

	i->f = ft;

	count = 0;
	SETUP_PHY_ATTRIBUTE(initiator_port_protocols);
	SETUP_PHY_ATTRIBUTE(target_port_protocols);
	SETUP_PHY_ATTRIBUTE(device_type);
	SETUP_PHY_ATTRIBUTE(sas_address);
	SETUP_PHY_ATTRIBUTE(phy_identifier);
	//SETUP_PHY_ATTRIBUTE(port_identifier);
	SETUP_PHY_ATTRIBUTE(negotiated_linkrate);
	SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw);
	SETUP_PHY_ATTRIBUTE_RW(minimum_linkrate);
	SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw);
	SETUP_PHY_ATTRIBUTE_RW(maximum_linkrate);

	SETUP_PHY_ATTRIBUTE(invalid_dword_count);
	SETUP_PHY_ATTRIBUTE(running_disparity_error_count);
	SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count);
	SETUP_PHY_ATTRIBUTE(phy_reset_problem_count);
	SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset);
	SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset);
	SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(enable, phy_enable);
	i->phy_attrs[count] = NULL;

	count = 0;
	SETUP_PORT_ATTRIBUTE(num_phys);
	i->port_attrs[count] = NULL;

	count = 0;
	SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols);
	SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols);
	SETUP_RPORT_ATTRIBUTE(rphy_device_type);
	SETUP_RPORT_ATTRIBUTE(rphy_sas_address);
	SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier);
	SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_enclosure_identifier,
				       get_enclosure_identifier);
	SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_bay_identifier,
				       get_bay_identifier);
	i->rphy_attrs[count] = NULL;

	count = 0;
	SETUP_END_DEV_ATTRIBUTE(end_dev_ready_led_meaning);
	SETUP_END_DEV_ATTRIBUTE(end_dev_I_T_nexus_loss_timeout);
	SETUP_END_DEV_ATTRIBUTE(end_dev_initiator_response_timeout);
	SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_supported);
	SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_enabled);
	i->end_dev_attrs[count] = NULL;

	count = 0;
	SETUP_EXPANDER_ATTRIBUTE(vendor_id);
	SETUP_EXPANDER_ATTRIBUTE(product_id);
	SETUP_EXPANDER_ATTRIBUTE(product_rev);
	SETUP_EXPANDER_ATTRIBUTE(component_vendor_id);
	SETUP_EXPANDER_ATTRIBUTE(component_id);
	SETUP_EXPANDER_ATTRIBUTE(component_revision_id);
	SETUP_EXPANDER_ATTRIBUTE(level);
	i->expander_attrs[count] = NULL;

	return &i->t;
}
EXPORT_SYMBOL(sas_attach_transport);

/**
 * sas_release_transport  -  release SAS transport template instance
 * @t:		transport template instance
 */
void sas_release_transport(struct scsi_transport_template *t)
{
	struct sas_internal *i = to_sas_internal(t);

	transport_container_unregister(&i->t.host_attrs);
	transport_container_unregister(&i->phy_attr_cont);
	transport_container_unregister(&i->port_attr_cont);
	transport_container_unregister(&i->rphy_attr_cont);
	transport_container_unregister(&i->end_dev_attr_cont);
	transport_container_unregister(&i->expander_attr_cont);

	kfree(i);
}
EXPORT_SYMBOL(sas_release_transport);

static __init int sas_transport_init(void)
{
	int error;

	error = transport_class_register(&sas_host_class);
	if (error)
		goto out;
	error = transport_class_register(&sas_phy_class);
	if (error)
		goto out_unregister_transport;
	error = transport_class_register(&sas_port_class);
	if (error)
		goto out_unregister_phy;
	error = transport_class_register(&sas_rphy_class);
	if (error)
		goto out_unregister_port;
	error = transport_class_register(&sas_end_dev_class);
	if (error)
		goto out_unregister_rphy;
	error = transport_class_register(&sas_expander_class);
	if (error)
		goto out_unregister_end_dev;

	return 0;

 out_unregister_end_dev:
	transport_class_unregister(&sas_end_dev_class);
 out_unregister_rphy:
	transport_class_unregister(&sas_rphy_class);
 out_unregister_port:
	transport_class_unregister(&sas_port_class);
 out_unregister_phy:
	transport_class_unregister(&sas_phy_class);
 out_unregister_transport:
	transport_class_unregister(&sas_host_class);
 out:
	return error;

}

static void __exit sas_transport_exit(void)
{
	transport_class_unregister(&sas_host_class);
	transport_class_unregister(&sas_phy_class);
	transport_class_unregister(&sas_port_class);
	transport_class_unregister(&sas_rphy_class);
	transport_class_unregister(&sas_end_dev_class);
	transport_class_unregister(&sas_expander_class);
}

MODULE_AUTHOR("Christoph Hellwig");
MODULE_DESCRIPTION("SAS Transport Attributes");
MODULE_LICENSE("GPL");

module_init(sas_transport_init);
module_exit(sas_transport_exit);
