cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

scsi_transport_sas.c (52291B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2005-2006 Dell Inc.
      4 *
      5 * Serial Attached SCSI (SAS) transport class.
      6 *
      7 * The SAS transport class contains common code to deal with SAS HBAs,
      8 * an aproximated representation of SAS topologies in the driver model,
      9 * and various sysfs attributes to expose these topologies and management
     10 * interfaces to userspace.
     11 *
     12 * In addition to the basic SCSI core objects this transport class
     13 * introduces two additional intermediate objects:  The SAS PHY
     14 * as represented by struct sas_phy defines an "outgoing" PHY on
     15 * a SAS HBA or Expander, and the SAS remote PHY represented by
     16 * struct sas_rphy defines an "incoming" PHY on a SAS Expander or
     17 * end device.  Note that this is purely a software concept, the
     18 * underlying hardware for a PHY and a remote PHY is the exactly
     19 * the same.
     20 *
     21 * There is no concept of a SAS port in this code, users can see
     22 * what PHYs form a wide port based on the port_identifier attribute,
     23 * which is the same for all PHYs in a port.
     24 */
     25
     26#include <linux/init.h>
     27#include <linux/module.h>
     28#include <linux/jiffies.h>
     29#include <linux/err.h>
     30#include <linux/slab.h>
     31#include <linux/string.h>
     32#include <linux/blkdev.h>
     33#include <linux/bsg.h>
     34
     35#include <scsi/scsi.h>
     36#include <scsi/scsi_cmnd.h>
     37#include <scsi/scsi_device.h>
     38#include <scsi/scsi_host.h>
     39#include <scsi/scsi_transport.h>
     40#include <scsi/scsi_transport_sas.h>
     41
     42#include "scsi_sas_internal.h"
     43struct sas_host_attrs {
     44	struct list_head rphy_list;
     45	struct mutex lock;
     46	struct request_queue *q;
     47	u32 next_target_id;
     48	u32 next_expander_id;
     49	int next_port_id;
     50};
     51#define to_sas_host_attrs(host)	((struct sas_host_attrs *)(host)->shost_data)
     52
     53
     54/*
     55 * Hack to allow attributes of the same name in different objects.
     56 */
     57#define SAS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
     58	struct device_attribute dev_attr_##_prefix##_##_name = \
     59	__ATTR(_name,_mode,_show,_store)
     60
     61
     62/*
     63 * Pretty printing helpers
     64 */
     65
     66#define sas_bitfield_name_match(title, table)			\
     67static ssize_t							\
     68get_sas_##title##_names(u32 table_key, char *buf)		\
     69{								\
     70	char *prefix = "";					\
     71	ssize_t len = 0;					\
     72	int i;							\
     73								\
     74	for (i = 0; i < ARRAY_SIZE(table); i++) {		\
     75		if (table[i].value & table_key) {		\
     76			len += sprintf(buf + len, "%s%s",	\
     77				prefix, table[i].name);		\
     78			prefix = ", ";				\
     79		}						\
     80	}							\
     81	len += sprintf(buf + len, "\n");			\
     82	return len;						\
     83}
     84
     85#define sas_bitfield_name_set(title, table)			\
     86static ssize_t							\
     87set_sas_##title##_names(u32 *table_key, const char *buf)	\
     88{								\
     89	ssize_t len = 0;					\
     90	int i;							\
     91								\
     92	for (i = 0; i < ARRAY_SIZE(table); i++) {		\
     93		len = strlen(table[i].name);			\
     94		if (strncmp(buf, table[i].name, len) == 0 &&	\
     95		    (buf[len] == '\n' || buf[len] == '\0')) {	\
     96			*table_key = table[i].value;		\
     97			return 0;				\
     98		}						\
     99	}							\
    100	return -EINVAL;						\
    101}
    102
    103#define sas_bitfield_name_search(title, table)			\
    104static ssize_t							\
    105get_sas_##title##_names(u32 table_key, char *buf)		\
    106{								\
    107	ssize_t len = 0;					\
    108	int i;							\
    109								\
    110	for (i = 0; i < ARRAY_SIZE(table); i++) {		\
    111		if (table[i].value == table_key) {		\
    112			len += sprintf(buf + len, "%s",		\
    113				table[i].name);			\
    114			break;					\
    115		}						\
    116	}							\
    117	len += sprintf(buf + len, "\n");			\
    118	return len;						\
    119}
    120
    121static struct {
    122	u32		value;
    123	char		*name;
    124} sas_device_type_names[] = {
    125	{ SAS_PHY_UNUSED,		"unused" },
    126	{ SAS_END_DEVICE,		"end device" },
    127	{ SAS_EDGE_EXPANDER_DEVICE,	"edge expander" },
    128	{ SAS_FANOUT_EXPANDER_DEVICE,	"fanout expander" },
    129};
    130sas_bitfield_name_search(device_type, sas_device_type_names)
    131
    132
    133static struct {
    134	u32		value;
    135	char		*name;
    136} sas_protocol_names[] = {
    137	{ SAS_PROTOCOL_SATA,		"sata" },
    138	{ SAS_PROTOCOL_SMP,		"smp" },
    139	{ SAS_PROTOCOL_STP,		"stp" },
    140	{ SAS_PROTOCOL_SSP,		"ssp" },
    141};
    142sas_bitfield_name_match(protocol, sas_protocol_names)
    143
    144static struct {
    145	u32		value;
    146	char		*name;
    147} sas_linkspeed_names[] = {
    148	{ SAS_LINK_RATE_UNKNOWN,	"Unknown" },
    149	{ SAS_PHY_DISABLED,		"Phy disabled" },
    150	{ SAS_LINK_RATE_FAILED,		"Link Rate failed" },
    151	{ SAS_SATA_SPINUP_HOLD,		"Spin-up hold" },
    152	{ SAS_LINK_RATE_1_5_GBPS,	"1.5 Gbit" },
    153	{ SAS_LINK_RATE_3_0_GBPS,	"3.0 Gbit" },
    154	{ SAS_LINK_RATE_6_0_GBPS,	"6.0 Gbit" },
    155	{ SAS_LINK_RATE_12_0_GBPS,	"12.0 Gbit" },
    156	{ SAS_LINK_RATE_22_5_GBPS,	"22.5 Gbit" },
    157};
    158sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
    159sas_bitfield_name_set(linkspeed, sas_linkspeed_names)
    160
    161static struct sas_end_device *sas_sdev_to_rdev(struct scsi_device *sdev)
    162{
    163	struct sas_rphy *rphy = target_to_rphy(sdev->sdev_target);
    164	struct sas_end_device *rdev;
    165
    166	BUG_ON(rphy->identify.device_type != SAS_END_DEVICE);
    167
    168	rdev = rphy_to_end_device(rphy);
    169	return rdev;
    170}
    171
    172static int sas_smp_dispatch(struct bsg_job *job)
    173{
    174	struct Scsi_Host *shost = dev_to_shost(job->dev);
    175	struct sas_rphy *rphy = NULL;
    176
    177	if (!scsi_is_host_device(job->dev))
    178		rphy = dev_to_rphy(job->dev);
    179
    180	if (!job->reply_payload.payload_len) {
    181		dev_warn(job->dev, "space for a smp response is missing\n");
    182		bsg_job_done(job, -EINVAL, 0);
    183		return 0;
    184	}
    185
    186	to_sas_internal(shost->transportt)->f->smp_handler(job, shost, rphy);
    187	return 0;
    188}
    189
    190static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
    191{
    192	struct request_queue *q;
    193
    194	if (!to_sas_internal(shost->transportt)->f->smp_handler) {
    195		printk("%s can't handle SMP requests\n", shost->hostt->name);
    196		return 0;
    197	}
    198
    199	if (rphy) {
    200		q = bsg_setup_queue(&rphy->dev, dev_name(&rphy->dev),
    201				sas_smp_dispatch, NULL, 0);
    202		if (IS_ERR(q))
    203			return PTR_ERR(q);
    204		rphy->q = q;
    205	} else {
    206		char name[20];
    207
    208		snprintf(name, sizeof(name), "sas_host%d", shost->host_no);
    209		q = bsg_setup_queue(&shost->shost_gendev, name,
    210				sas_smp_dispatch, NULL, 0);
    211		if (IS_ERR(q))
    212			return PTR_ERR(q);
    213		to_sas_host_attrs(shost)->q = q;
    214	}
    215
    216	return 0;
    217}
    218
    219/*
    220 * SAS host attributes
    221 */
    222
    223static int sas_host_setup(struct transport_container *tc, struct device *dev,
    224			  struct device *cdev)
    225{
    226	struct Scsi_Host *shost = dev_to_shost(dev);
    227	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
    228
    229	INIT_LIST_HEAD(&sas_host->rphy_list);
    230	mutex_init(&sas_host->lock);
    231	sas_host->next_target_id = 0;
    232	sas_host->next_expander_id = 0;
    233	sas_host->next_port_id = 0;
    234
    235	if (sas_bsg_initialize(shost, NULL))
    236		dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n",
    237			   shost->host_no);
    238
    239	return 0;
    240}
    241
    242static int sas_host_remove(struct transport_container *tc, struct device *dev,
    243			   struct device *cdev)
    244{
    245	struct Scsi_Host *shost = dev_to_shost(dev);
    246	struct request_queue *q = to_sas_host_attrs(shost)->q;
    247
    248	bsg_remove_queue(q);
    249	return 0;
    250}
    251
    252static DECLARE_TRANSPORT_CLASS(sas_host_class,
    253		"sas_host", sas_host_setup, sas_host_remove, NULL);
    254
    255static int sas_host_match(struct attribute_container *cont,
    256			    struct device *dev)
    257{
    258	struct Scsi_Host *shost;
    259	struct sas_internal *i;
    260
    261	if (!scsi_is_host_device(dev))
    262		return 0;
    263	shost = dev_to_shost(dev);
    264
    265	if (!shost->transportt)
    266		return 0;
    267	if (shost->transportt->host_attrs.ac.class !=
    268			&sas_host_class.class)
    269		return 0;
    270
    271	i = to_sas_internal(shost->transportt);
    272	return &i->t.host_attrs.ac == cont;
    273}
    274
    275static int do_sas_phy_delete(struct device *dev, void *data)
    276{
    277	int pass = (int)(unsigned long)data;
    278
    279	if (pass == 0 && scsi_is_sas_port(dev))
    280		sas_port_delete(dev_to_sas_port(dev));
    281	else if (pass == 1 && scsi_is_sas_phy(dev))
    282		sas_phy_delete(dev_to_phy(dev));
    283	return 0;
    284}
    285
    286/**
    287 * sas_remove_children  -  tear down a devices SAS data structures
    288 * @dev:	device belonging to the sas object
    289 *
    290 * Removes all SAS PHYs and remote PHYs for a given object
    291 */
    292void sas_remove_children(struct device *dev)
    293{
    294	device_for_each_child(dev, (void *)0, do_sas_phy_delete);
    295	device_for_each_child(dev, (void *)1, do_sas_phy_delete);
    296}
    297EXPORT_SYMBOL(sas_remove_children);
    298
    299/**
    300 * sas_remove_host  -  tear down a Scsi_Host's SAS data structures
    301 * @shost:	Scsi Host that is torn down
    302 *
    303 * Removes all SAS PHYs and remote PHYs for a given Scsi_Host and remove the
    304 * Scsi_Host as well.
    305 *
    306 * Note: Do not call scsi_remove_host() on the Scsi_Host any more, as it is
    307 * already removed.
    308 */
    309void sas_remove_host(struct Scsi_Host *shost)
    310{
    311	sas_remove_children(&shost->shost_gendev);
    312	scsi_remove_host(shost);
    313}
    314EXPORT_SYMBOL(sas_remove_host);
    315
    316/**
    317 * sas_get_address - return the SAS address of the device
    318 * @sdev: scsi device
    319 *
    320 * Returns the SAS address of the scsi device
    321 */
    322u64 sas_get_address(struct scsi_device *sdev)
    323{
    324	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
    325
    326	return rdev->rphy.identify.sas_address;
    327}
    328EXPORT_SYMBOL(sas_get_address);
    329
    330/**
    331 * sas_tlr_supported - checking TLR bit in vpd 0x90
    332 * @sdev: scsi device struct
    333 *
    334 * Check Transport Layer Retries are supported or not.
    335 * If vpd page 0x90 is present, TRL is supported.
    336 *
    337 */
    338unsigned int
    339sas_tlr_supported(struct scsi_device *sdev)
    340{
    341	const int vpd_len = 32;
    342	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
    343	char *buffer = kzalloc(vpd_len, GFP_KERNEL);
    344	int ret = 0;
    345
    346	if (!buffer)
    347		goto out;
    348
    349	if (scsi_get_vpd_page(sdev, 0x90, buffer, vpd_len))
    350		goto out;
    351
    352	/*
    353	 * Magic numbers: the VPD Protocol page (0x90)
    354	 * has a 4 byte header and then one entry per device port
    355	 * the TLR bit is at offset 8 on each port entry
    356	 * if we take the first port, that's at total offset 12
    357	 */
    358	ret = buffer[12] & 0x01;
    359
    360 out:
    361	kfree(buffer);
    362	rdev->tlr_supported = ret;
    363	return ret;
    364
    365}
    366EXPORT_SYMBOL_GPL(sas_tlr_supported);
    367
    368/**
    369 * sas_disable_tlr - setting TLR flags
    370 * @sdev: scsi device struct
    371 *
    372 * Seting tlr_enabled flag to 0.
    373 *
    374 */
    375void
    376sas_disable_tlr(struct scsi_device *sdev)
    377{
    378	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
    379
    380	rdev->tlr_enabled = 0;
    381}
    382EXPORT_SYMBOL_GPL(sas_disable_tlr);
    383
    384/**
    385 * sas_enable_tlr - setting TLR flags
    386 * @sdev: scsi device struct
    387 *
    388 * Seting tlr_enabled flag 1.
    389 *
    390 */
    391void sas_enable_tlr(struct scsi_device *sdev)
    392{
    393	unsigned int tlr_supported = 0;
    394	tlr_supported  = sas_tlr_supported(sdev);
    395
    396	if (tlr_supported) {
    397		struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
    398
    399		rdev->tlr_enabled = 1;
    400	}
    401
    402	return;
    403}
    404EXPORT_SYMBOL_GPL(sas_enable_tlr);
    405
    406unsigned int sas_is_tlr_enabled(struct scsi_device *sdev)
    407{
    408	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
    409	return rdev->tlr_enabled;
    410}
    411EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);
    412
    413/*
    414 * SAS Phy attributes
    415 */
    416
    417#define sas_phy_show_simple(field, name, format_string, cast)		\
    418static ssize_t								\
    419show_sas_phy_##name(struct device *dev, 				\
    420		    struct device_attribute *attr, char *buf)		\
    421{									\
    422	struct sas_phy *phy = transport_class_to_phy(dev);		\
    423									\
    424	return snprintf(buf, 20, format_string, cast phy->field);	\
    425}
    426
    427#define sas_phy_simple_attr(field, name, format_string, type)		\
    428	sas_phy_show_simple(field, name, format_string, (type))	\
    429static DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)
    430
    431#define sas_phy_show_protocol(field, name)				\
    432static ssize_t								\
    433show_sas_phy_##name(struct device *dev, 				\
    434		    struct device_attribute *attr, char *buf)		\
    435{									\
    436	struct sas_phy *phy = transport_class_to_phy(dev);		\
    437									\
    438	if (!phy->field)						\
    439		return snprintf(buf, 20, "none\n");			\
    440	return get_sas_protocol_names(phy->field, buf);		\
    441}
    442
    443#define sas_phy_protocol_attr(field, name)				\
    444	sas_phy_show_protocol(field, name)				\
    445static DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)
    446
    447#define sas_phy_show_linkspeed(field)					\
    448static ssize_t								\
    449show_sas_phy_##field(struct device *dev, 				\
    450		     struct device_attribute *attr, char *buf)		\
    451{									\
    452	struct sas_phy *phy = transport_class_to_phy(dev);		\
    453									\
    454	return get_sas_linkspeed_names(phy->field, buf);		\
    455}
    456
    457/* Fudge to tell if we're minimum or maximum */
    458#define sas_phy_store_linkspeed(field)					\
    459static ssize_t								\
    460store_sas_phy_##field(struct device *dev, 				\
    461		      struct device_attribute *attr, 			\
    462		      const char *buf,	size_t count)			\
    463{									\
    464	struct sas_phy *phy = transport_class_to_phy(dev);		\
    465	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);	\
    466	struct sas_internal *i = to_sas_internal(shost->transportt);	\
    467	u32 value;							\
    468	struct sas_phy_linkrates rates = {0};				\
    469	int error;							\
    470									\
    471	error = set_sas_linkspeed_names(&value, buf);			\
    472	if (error)							\
    473		return error;						\
    474	rates.field = value;						\
    475	error = i->f->set_phy_speed(phy, &rates);			\
    476									\
    477	return error ? error : count;					\
    478}
    479
    480#define sas_phy_linkspeed_rw_attr(field)				\
    481	sas_phy_show_linkspeed(field)					\
    482	sas_phy_store_linkspeed(field)					\
    483static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field,		\
    484	store_sas_phy_##field)
    485
    486#define sas_phy_linkspeed_attr(field)					\
    487	sas_phy_show_linkspeed(field)					\
    488static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
    489
    490
    491#define sas_phy_show_linkerror(field)					\
    492static ssize_t								\
    493show_sas_phy_##field(struct device *dev, 				\
    494		     struct device_attribute *attr, char *buf)		\
    495{									\
    496	struct sas_phy *phy = transport_class_to_phy(dev);		\
    497	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);	\
    498	struct sas_internal *i = to_sas_internal(shost->transportt);	\
    499	int error;							\
    500									\
    501	error = i->f->get_linkerrors ? i->f->get_linkerrors(phy) : 0;	\
    502	if (error)							\
    503		return error;						\
    504	return snprintf(buf, 20, "%u\n", phy->field);			\
    505}
    506
    507#define sas_phy_linkerror_attr(field)					\
    508	sas_phy_show_linkerror(field)					\
    509static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
    510
    511
    512static ssize_t
    513show_sas_device_type(struct device *dev,
    514		     struct device_attribute *attr, char *buf)
    515{
    516	struct sas_phy *phy = transport_class_to_phy(dev);
    517
    518	if (!phy->identify.device_type)
    519		return snprintf(buf, 20, "none\n");
    520	return get_sas_device_type_names(phy->identify.device_type, buf);
    521}
    522static DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
    523
    524static ssize_t do_sas_phy_enable(struct device *dev,
    525		size_t count, int enable)
    526{
    527	struct sas_phy *phy = transport_class_to_phy(dev);
    528	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
    529	struct sas_internal *i = to_sas_internal(shost->transportt);
    530	int error;
    531
    532	error = i->f->phy_enable(phy, enable);
    533	if (error)
    534		return error;
    535	phy->enabled = enable;
    536	return count;
    537};
    538
    539static ssize_t
    540store_sas_phy_enable(struct device *dev, struct device_attribute *attr,
    541		     const char *buf, size_t count)
    542{
    543	if (count < 1)
    544		return -EINVAL;
    545
    546	switch (buf[0]) {
    547	case '0':
    548		do_sas_phy_enable(dev, count, 0);
    549		break;
    550	case '1':
    551		do_sas_phy_enable(dev, count, 1);
    552		break;
    553	default:
    554		return -EINVAL;
    555	}
    556
    557	return count;
    558}
    559
    560static ssize_t
    561show_sas_phy_enable(struct device *dev, struct device_attribute *attr,
    562		    char *buf)
    563{
    564	struct sas_phy *phy = transport_class_to_phy(dev);
    565
    566	return snprintf(buf, 20, "%d\n", phy->enabled);
    567}
    568
    569static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, show_sas_phy_enable,
    570			 store_sas_phy_enable);
    571
    572static ssize_t
    573do_sas_phy_reset(struct device *dev, size_t count, int hard_reset)
    574{
    575	struct sas_phy *phy = transport_class_to_phy(dev);
    576	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
    577	struct sas_internal *i = to_sas_internal(shost->transportt);
    578	int error;
    579
    580	error = i->f->phy_reset(phy, hard_reset);
    581	if (error)
    582		return error;
    583	phy->enabled = 1;
    584	return count;
    585};
    586
    587static ssize_t
    588store_sas_link_reset(struct device *dev, struct device_attribute *attr,
    589		     const char *buf, size_t count)
    590{
    591	return do_sas_phy_reset(dev, count, 0);
    592}
    593static DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset);
    594
    595static ssize_t
    596store_sas_hard_reset(struct device *dev, struct device_attribute *attr,
    597		     const char *buf, size_t count)
    598{
    599	return do_sas_phy_reset(dev, count, 1);
    600}
    601static DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset);
    602
    603sas_phy_protocol_attr(identify.initiator_port_protocols,
    604		initiator_port_protocols);
    605sas_phy_protocol_attr(identify.target_port_protocols,
    606		target_port_protocols);
    607sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
    608		unsigned long long);
    609sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
    610sas_phy_linkspeed_attr(negotiated_linkrate);
    611sas_phy_linkspeed_attr(minimum_linkrate_hw);
    612sas_phy_linkspeed_rw_attr(minimum_linkrate);
    613sas_phy_linkspeed_attr(maximum_linkrate_hw);
    614sas_phy_linkspeed_rw_attr(maximum_linkrate);
    615sas_phy_linkerror_attr(invalid_dword_count);
    616sas_phy_linkerror_attr(running_disparity_error_count);
    617sas_phy_linkerror_attr(loss_of_dword_sync_count);
    618sas_phy_linkerror_attr(phy_reset_problem_count);
    619
    620static int sas_phy_setup(struct transport_container *tc, struct device *dev,
    621			 struct device *cdev)
    622{
    623	struct sas_phy *phy = dev_to_phy(dev);
    624	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
    625	struct sas_internal *i = to_sas_internal(shost->transportt);
    626
    627	if (i->f->phy_setup)
    628		i->f->phy_setup(phy);
    629
    630	return 0;
    631}
    632
    633static DECLARE_TRANSPORT_CLASS(sas_phy_class,
    634		"sas_phy", sas_phy_setup, NULL, NULL);
    635
    636static int sas_phy_match(struct attribute_container *cont, struct device *dev)
    637{
    638	struct Scsi_Host *shost;
    639	struct sas_internal *i;
    640
    641	if (!scsi_is_sas_phy(dev))
    642		return 0;
    643	shost = dev_to_shost(dev->parent);
    644
    645	if (!shost->transportt)
    646		return 0;
    647	if (shost->transportt->host_attrs.ac.class !=
    648			&sas_host_class.class)
    649		return 0;
    650
    651	i = to_sas_internal(shost->transportt);
    652	return &i->phy_attr_cont.ac == cont;
    653}
    654
    655static void sas_phy_release(struct device *dev)
    656{
    657	struct sas_phy *phy = dev_to_phy(dev);
    658	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
    659	struct sas_internal *i = to_sas_internal(shost->transportt);
    660
    661	if (i->f->phy_release)
    662		i->f->phy_release(phy);
    663	put_device(dev->parent);
    664	kfree(phy);
    665}
    666
    667/**
    668 * sas_phy_alloc  -  allocates and initialize a SAS PHY structure
    669 * @parent:	Parent device
    670 * @number:	Phy index
    671 *
    672 * Allocates an SAS PHY structure.  It will be added in the device tree
    673 * below the device specified by @parent, which has to be either a Scsi_Host
    674 * or sas_rphy.
    675 *
    676 * Returns:
    677 *	SAS PHY allocated or %NULL if the allocation failed.
    678 */
    679struct sas_phy *sas_phy_alloc(struct device *parent, int number)
    680{
    681	struct Scsi_Host *shost = dev_to_shost(parent);
    682	struct sas_phy *phy;
    683
    684	phy = kzalloc(sizeof(*phy), GFP_KERNEL);
    685	if (!phy)
    686		return NULL;
    687
    688	phy->number = number;
    689	phy->enabled = 1;
    690
    691	device_initialize(&phy->dev);
    692	phy->dev.parent = get_device(parent);
    693	phy->dev.release = sas_phy_release;
    694	INIT_LIST_HEAD(&phy->port_siblings);
    695	if (scsi_is_sas_expander_device(parent)) {
    696		struct sas_rphy *rphy = dev_to_rphy(parent);
    697		dev_set_name(&phy->dev, "phy-%d:%d:%d", shost->host_no,
    698			rphy->scsi_target_id, number);
    699	} else
    700		dev_set_name(&phy->dev, "phy-%d:%d", shost->host_no, number);
    701
    702	transport_setup_device(&phy->dev);
    703
    704	return phy;
    705}
    706EXPORT_SYMBOL(sas_phy_alloc);
    707
    708/**
    709 * sas_phy_add  -  add a SAS PHY to the device hierarchy
    710 * @phy:	The PHY to be added
    711 *
    712 * Publishes a SAS PHY to the rest of the system.
    713 */
    714int sas_phy_add(struct sas_phy *phy)
    715{
    716	int error;
    717
    718	error = device_add(&phy->dev);
    719	if (!error) {
    720		transport_add_device(&phy->dev);
    721		transport_configure_device(&phy->dev);
    722	}
    723
    724	return error;
    725}
    726EXPORT_SYMBOL(sas_phy_add);
    727
    728/**
    729 * sas_phy_free  -  free a SAS PHY
    730 * @phy:	SAS PHY to free
    731 *
    732 * Frees the specified SAS PHY.
    733 *
    734 * Note:
    735 *   This function must only be called on a PHY that has not
    736 *   successfully been added using sas_phy_add().
    737 */
    738void sas_phy_free(struct sas_phy *phy)
    739{
    740	transport_destroy_device(&phy->dev);
    741	put_device(&phy->dev);
    742}
    743EXPORT_SYMBOL(sas_phy_free);
    744
    745/**
    746 * sas_phy_delete  -  remove SAS PHY
    747 * @phy:	SAS PHY to remove
    748 *
    749 * Removes the specified SAS PHY.  If the SAS PHY has an
    750 * associated remote PHY it is removed before.
    751 */
    752void
    753sas_phy_delete(struct sas_phy *phy)
    754{
    755	struct device *dev = &phy->dev;
    756
    757	/* this happens if the phy is still part of a port when deleted */
    758	BUG_ON(!list_empty(&phy->port_siblings));
    759
    760	transport_remove_device(dev);
    761	device_del(dev);
    762	transport_destroy_device(dev);
    763	put_device(dev);
    764}
    765EXPORT_SYMBOL(sas_phy_delete);
    766
    767/**
    768 * scsi_is_sas_phy  -  check if a struct device represents a SAS PHY
    769 * @dev:	device to check
    770 *
    771 * Returns:
    772 *	%1 if the device represents a SAS PHY, %0 else
    773 */
    774int scsi_is_sas_phy(const struct device *dev)
    775{
    776	return dev->release == sas_phy_release;
    777}
    778EXPORT_SYMBOL(scsi_is_sas_phy);
    779
    780/*
    781 * SAS Port attributes
    782 */
    783#define sas_port_show_simple(field, name, format_string, cast)		\
    784static ssize_t								\
    785show_sas_port_##name(struct device *dev, 				\
    786		     struct device_attribute *attr, char *buf)		\
    787{									\
    788	struct sas_port *port = transport_class_to_sas_port(dev);	\
    789									\
    790	return snprintf(buf, 20, format_string, cast port->field);	\
    791}
    792
    793#define sas_port_simple_attr(field, name, format_string, type)		\
    794	sas_port_show_simple(field, name, format_string, (type))	\
    795static DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL)
    796
    797sas_port_simple_attr(num_phys, num_phys, "%d\n", int);
    798
    799static DECLARE_TRANSPORT_CLASS(sas_port_class,
    800			       "sas_port", NULL, NULL, NULL);
    801
    802static int sas_port_match(struct attribute_container *cont, struct device *dev)
    803{
    804	struct Scsi_Host *shost;
    805	struct sas_internal *i;
    806
    807	if (!scsi_is_sas_port(dev))
    808		return 0;
    809	shost = dev_to_shost(dev->parent);
    810
    811	if (!shost->transportt)
    812		return 0;
    813	if (shost->transportt->host_attrs.ac.class !=
    814			&sas_host_class.class)
    815		return 0;
    816
    817	i = to_sas_internal(shost->transportt);
    818	return &i->port_attr_cont.ac == cont;
    819}
    820
    821
    822static void sas_port_release(struct device *dev)
    823{
    824	struct sas_port *port = dev_to_sas_port(dev);
    825
    826	BUG_ON(!list_empty(&port->phy_list));
    827
    828	put_device(dev->parent);
    829	kfree(port);
    830}
    831
    832static void sas_port_create_link(struct sas_port *port,
    833				 struct sas_phy *phy)
    834{
    835	int res;
    836
    837	res = sysfs_create_link(&port->dev.kobj, &phy->dev.kobj,
    838				dev_name(&phy->dev));
    839	if (res)
    840		goto err;
    841	res = sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port");
    842	if (res)
    843		goto err;
    844	return;
    845err:
    846	printk(KERN_ERR "%s: Cannot create port links, err=%d\n",
    847	       __func__, res);
    848}
    849
    850static void sas_port_delete_link(struct sas_port *port,
    851				 struct sas_phy *phy)
    852{
    853	sysfs_remove_link(&port->dev.kobj, dev_name(&phy->dev));
    854	sysfs_remove_link(&phy->dev.kobj, "port");
    855}
    856
    857/** sas_port_alloc - allocate and initialize a SAS port structure
    858 *
    859 * @parent:	parent device
    860 * @port_id:	port number
    861 *
    862 * Allocates a SAS port structure.  It will be added to the device tree
    863 * below the device specified by @parent which must be either a Scsi_Host
    864 * or a sas_expander_device.
    865 *
    866 * Returns %NULL on error
    867 */
    868struct sas_port *sas_port_alloc(struct device *parent, int port_id)
    869{
    870	struct Scsi_Host *shost = dev_to_shost(parent);
    871	struct sas_port *port;
    872
    873	port = kzalloc(sizeof(*port), GFP_KERNEL);
    874	if (!port)
    875		return NULL;
    876
    877	port->port_identifier = port_id;
    878
    879	device_initialize(&port->dev);
    880
    881	port->dev.parent = get_device(parent);
    882	port->dev.release = sas_port_release;
    883
    884	mutex_init(&port->phy_list_mutex);
    885	INIT_LIST_HEAD(&port->phy_list);
    886
    887	if (scsi_is_sas_expander_device(parent)) {
    888		struct sas_rphy *rphy = dev_to_rphy(parent);
    889		dev_set_name(&port->dev, "port-%d:%d:%d", shost->host_no,
    890			     rphy->scsi_target_id, port->port_identifier);
    891	} else
    892		dev_set_name(&port->dev, "port-%d:%d", shost->host_no,
    893			     port->port_identifier);
    894
    895	transport_setup_device(&port->dev);
    896
    897	return port;
    898}
    899EXPORT_SYMBOL(sas_port_alloc);
    900
    901/** sas_port_alloc_num - allocate and initialize a SAS port structure
    902 *
    903 * @parent:	parent device
    904 *
    905 * Allocates a SAS port structure and a number to go with it.  This
    906 * interface is really for adapters where the port number has no
    907 * meansing, so the sas class should manage them.  It will be added to
    908 * the device tree below the device specified by @parent which must be
    909 * either a Scsi_Host or a sas_expander_device.
    910 *
    911 * Returns %NULL on error
    912 */
    913struct sas_port *sas_port_alloc_num(struct device *parent)
    914{
    915	int index;
    916	struct Scsi_Host *shost = dev_to_shost(parent);
    917	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
    918
    919	/* FIXME: use idr for this eventually */
    920	mutex_lock(&sas_host->lock);
    921	if (scsi_is_sas_expander_device(parent)) {
    922		struct sas_rphy *rphy = dev_to_rphy(parent);
    923		struct sas_expander_device *exp = rphy_to_expander_device(rphy);
    924
    925		index = exp->next_port_id++;
    926	} else
    927		index = sas_host->next_port_id++;
    928	mutex_unlock(&sas_host->lock);
    929	return sas_port_alloc(parent, index);
    930}
    931EXPORT_SYMBOL(sas_port_alloc_num);
    932
    933/**
    934 * sas_port_add - add a SAS port to the device hierarchy
    935 * @port:	port to be added
    936 *
    937 * publishes a port to the rest of the system
    938 */
    939int sas_port_add(struct sas_port *port)
    940{
    941	int error;
    942
    943	/* No phys should be added until this is made visible */
    944	BUG_ON(!list_empty(&port->phy_list));
    945
    946	error = device_add(&port->dev);
    947
    948	if (error)
    949		return error;
    950
    951	transport_add_device(&port->dev);
    952	transport_configure_device(&port->dev);
    953
    954	return 0;
    955}
    956EXPORT_SYMBOL(sas_port_add);
    957
    958/**
    959 * sas_port_free  -  free a SAS PORT
    960 * @port:	SAS PORT to free
    961 *
    962 * Frees the specified SAS PORT.
    963 *
    964 * Note:
    965 *   This function must only be called on a PORT that has not
    966 *   successfully been added using sas_port_add().
    967 */
    968void sas_port_free(struct sas_port *port)
    969{
    970	transport_destroy_device(&port->dev);
    971	put_device(&port->dev);
    972}
    973EXPORT_SYMBOL(sas_port_free);
    974
    975/**
    976 * sas_port_delete  -  remove SAS PORT
    977 * @port:	SAS PORT to remove
    978 *
    979 * Removes the specified SAS PORT.  If the SAS PORT has an
    980 * associated phys, unlink them from the port as well.
    981 */
    982void sas_port_delete(struct sas_port *port)
    983{
    984	struct device *dev = &port->dev;
    985	struct sas_phy *phy, *tmp_phy;
    986
    987	if (port->rphy) {
    988		sas_rphy_delete(port->rphy);
    989		port->rphy = NULL;
    990	}
    991
    992	mutex_lock(&port->phy_list_mutex);
    993	list_for_each_entry_safe(phy, tmp_phy, &port->phy_list,
    994				 port_siblings) {
    995		sas_port_delete_link(port, phy);
    996		list_del_init(&phy->port_siblings);
    997	}
    998	mutex_unlock(&port->phy_list_mutex);
    999
   1000	if (port->is_backlink) {
   1001		struct device *parent = port->dev.parent;
   1002
   1003		sysfs_remove_link(&port->dev.kobj, dev_name(parent));
   1004		port->is_backlink = 0;
   1005	}
   1006
   1007	transport_remove_device(dev);
   1008	device_del(dev);
   1009	transport_destroy_device(dev);
   1010	put_device(dev);
   1011}
   1012EXPORT_SYMBOL(sas_port_delete);
   1013
   1014/**
   1015 * scsi_is_sas_port -  check if a struct device represents a SAS port
   1016 * @dev:	device to check
   1017 *
   1018 * Returns:
   1019 *	%1 if the device represents a SAS Port, %0 else
   1020 */
   1021int scsi_is_sas_port(const struct device *dev)
   1022{
   1023	return dev->release == sas_port_release;
   1024}
   1025EXPORT_SYMBOL(scsi_is_sas_port);
   1026
   1027/**
   1028 * sas_port_get_phy - try to take a reference on a port member
   1029 * @port: port to check
   1030 */
   1031struct sas_phy *sas_port_get_phy(struct sas_port *port)
   1032{
   1033	struct sas_phy *phy;
   1034
   1035	mutex_lock(&port->phy_list_mutex);
   1036	if (list_empty(&port->phy_list))
   1037		phy = NULL;
   1038	else {
   1039		struct list_head *ent = port->phy_list.next;
   1040
   1041		phy = list_entry(ent, typeof(*phy), port_siblings);
   1042		get_device(&phy->dev);
   1043	}
   1044	mutex_unlock(&port->phy_list_mutex);
   1045
   1046	return phy;
   1047}
   1048EXPORT_SYMBOL(sas_port_get_phy);
   1049
   1050/**
   1051 * sas_port_add_phy - add another phy to a port to form a wide port
   1052 * @port:	port to add the phy to
   1053 * @phy:	phy to add
   1054 *
   1055 * When a port is initially created, it is empty (has no phys).  All
   1056 * ports must have at least one phy to operated, and all wide ports
   1057 * must have at least two.  The current code makes no difference
   1058 * between ports and wide ports, but the only object that can be
   1059 * connected to a remote device is a port, so ports must be formed on
   1060 * all devices with phys if they're connected to anything.
   1061 */
   1062void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy)
   1063{
   1064	mutex_lock(&port->phy_list_mutex);
   1065	if (unlikely(!list_empty(&phy->port_siblings))) {
   1066		/* make sure we're already on this port */
   1067		struct sas_phy *tmp;
   1068
   1069		list_for_each_entry(tmp, &port->phy_list, port_siblings)
   1070			if (tmp == phy)
   1071				break;
   1072		/* If this trips, you added a phy that was already
   1073		 * part of a different port */
   1074		if (unlikely(tmp != phy)) {
   1075			dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n",
   1076				   dev_name(&phy->dev));
   1077			BUG();
   1078		}
   1079	} else {
   1080		sas_port_create_link(port, phy);
   1081		list_add_tail(&phy->port_siblings, &port->phy_list);
   1082		port->num_phys++;
   1083	}
   1084	mutex_unlock(&port->phy_list_mutex);
   1085}
   1086EXPORT_SYMBOL(sas_port_add_phy);
   1087
   1088/**
   1089 * sas_port_delete_phy - remove a phy from a port or wide port
   1090 * @port:	port to remove the phy from
   1091 * @phy:	phy to remove
   1092 *
   1093 * This operation is used for tearing down ports again.  It must be
   1094 * done to every port or wide port before calling sas_port_delete.
   1095 */
   1096void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
   1097{
   1098	mutex_lock(&port->phy_list_mutex);
   1099	sas_port_delete_link(port, phy);
   1100	list_del_init(&phy->port_siblings);
   1101	port->num_phys--;
   1102	mutex_unlock(&port->phy_list_mutex);
   1103}
   1104EXPORT_SYMBOL(sas_port_delete_phy);
   1105
   1106void sas_port_mark_backlink(struct sas_port *port)
   1107{
   1108	int res;
   1109	struct device *parent = port->dev.parent->parent->parent;
   1110
   1111	if (port->is_backlink)
   1112		return;
   1113	port->is_backlink = 1;
   1114	res = sysfs_create_link(&port->dev.kobj, &parent->kobj,
   1115				dev_name(parent));
   1116	if (res)
   1117		goto err;
   1118	return;
   1119err:
   1120	printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n",
   1121	       __func__, res);
   1122
   1123}
   1124EXPORT_SYMBOL(sas_port_mark_backlink);
   1125
   1126/*
   1127 * SAS remote PHY attributes.
   1128 */
   1129
   1130#define sas_rphy_show_simple(field, name, format_string, cast)		\
   1131static ssize_t								\
   1132show_sas_rphy_##name(struct device *dev, 				\
   1133		     struct device_attribute *attr, char *buf)		\
   1134{									\
   1135	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
   1136									\
   1137	return snprintf(buf, 20, format_string, cast rphy->field);	\
   1138}
   1139
   1140#define sas_rphy_simple_attr(field, name, format_string, type)		\
   1141	sas_rphy_show_simple(field, name, format_string, (type))	\
   1142static SAS_DEVICE_ATTR(rphy, name, S_IRUGO, 			\
   1143		show_sas_rphy_##name, NULL)
   1144
   1145#define sas_rphy_show_protocol(field, name)				\
   1146static ssize_t								\
   1147show_sas_rphy_##name(struct device *dev, 				\
   1148		     struct device_attribute *attr, char *buf)		\
   1149{									\
   1150	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
   1151									\
   1152	if (!rphy->field)					\
   1153		return snprintf(buf, 20, "none\n");			\
   1154	return get_sas_protocol_names(rphy->field, buf);	\
   1155}
   1156
   1157#define sas_rphy_protocol_attr(field, name)				\
   1158	sas_rphy_show_protocol(field, name)				\
   1159static SAS_DEVICE_ATTR(rphy, name, S_IRUGO,			\
   1160		show_sas_rphy_##name, NULL)
   1161
   1162static ssize_t
   1163show_sas_rphy_device_type(struct device *dev,
   1164			  struct device_attribute *attr, char *buf)
   1165{
   1166	struct sas_rphy *rphy = transport_class_to_rphy(dev);
   1167
   1168	if (!rphy->identify.device_type)
   1169		return snprintf(buf, 20, "none\n");
   1170	return get_sas_device_type_names(
   1171			rphy->identify.device_type, buf);
   1172}
   1173
   1174static SAS_DEVICE_ATTR(rphy, device_type, S_IRUGO,
   1175		show_sas_rphy_device_type, NULL);
   1176
   1177static ssize_t
   1178show_sas_rphy_enclosure_identifier(struct device *dev,
   1179				   struct device_attribute *attr, char *buf)
   1180{
   1181	struct sas_rphy *rphy = transport_class_to_rphy(dev);
   1182	struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
   1183	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
   1184	struct sas_internal *i = to_sas_internal(shost->transportt);
   1185	u64 identifier;
   1186	int error;
   1187
   1188	error = i->f->get_enclosure_identifier(rphy, &identifier);
   1189	if (error)
   1190		return error;
   1191	return sprintf(buf, "0x%llx\n", (unsigned long long)identifier);
   1192}
   1193
   1194static SAS_DEVICE_ATTR(rphy, enclosure_identifier, S_IRUGO,
   1195		show_sas_rphy_enclosure_identifier, NULL);
   1196
   1197static ssize_t
   1198show_sas_rphy_bay_identifier(struct device *dev,
   1199			     struct device_attribute *attr, char *buf)
   1200{
   1201	struct sas_rphy *rphy = transport_class_to_rphy(dev);
   1202	struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
   1203	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
   1204	struct sas_internal *i = to_sas_internal(shost->transportt);
   1205	int val;
   1206
   1207	val = i->f->get_bay_identifier(rphy);
   1208	if (val < 0)
   1209		return val;
   1210	return sprintf(buf, "%d\n", val);
   1211}
   1212
   1213static SAS_DEVICE_ATTR(rphy, bay_identifier, S_IRUGO,
   1214		show_sas_rphy_bay_identifier, NULL);
   1215
   1216sas_rphy_protocol_attr(identify.initiator_port_protocols,
   1217		initiator_port_protocols);
   1218sas_rphy_protocol_attr(identify.target_port_protocols, target_port_protocols);
   1219sas_rphy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
   1220		unsigned long long);
   1221sas_rphy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
   1222sas_rphy_simple_attr(scsi_target_id, scsi_target_id, "%d\n", u32);
   1223
   1224/* only need 8 bytes of data plus header (4 or 8) */
   1225#define BUF_SIZE 64
   1226
   1227int sas_read_port_mode_page(struct scsi_device *sdev)
   1228{
   1229	char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata;
   1230	struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
   1231	struct scsi_mode_data mode_data;
   1232	int error;
   1233
   1234	if (!buffer)
   1235		return -ENOMEM;
   1236
   1237	error = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
   1238				&mode_data, NULL);
   1239
   1240	if (error)
   1241		goto out;
   1242
   1243	msdata = buffer +  mode_data.header_length +
   1244		mode_data.block_descriptor_length;
   1245
   1246	if (msdata - buffer > BUF_SIZE - 8)
   1247		goto out;
   1248
   1249	error = 0;
   1250
   1251	rdev->ready_led_meaning = msdata[2] & 0x10 ? 1 : 0;
   1252	rdev->I_T_nexus_loss_timeout = (msdata[4] << 8) + msdata[5];
   1253	rdev->initiator_response_timeout = (msdata[6] << 8) + msdata[7];
   1254
   1255 out:
   1256	kfree(buffer);
   1257	return error;
   1258}
   1259EXPORT_SYMBOL(sas_read_port_mode_page);
   1260
   1261static DECLARE_TRANSPORT_CLASS(sas_end_dev_class,
   1262			       "sas_end_device", NULL, NULL, NULL);
   1263
   1264#define sas_end_dev_show_simple(field, name, format_string, cast)	\
   1265static ssize_t								\
   1266show_sas_end_dev_##name(struct device *dev, 				\
   1267			struct device_attribute *attr, char *buf)	\
   1268{									\
   1269	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
   1270	struct sas_end_device *rdev = rphy_to_end_device(rphy);		\
   1271									\
   1272	return snprintf(buf, 20, format_string, cast rdev->field);	\
   1273}
   1274
   1275#define sas_end_dev_simple_attr(field, name, format_string, type)	\
   1276	sas_end_dev_show_simple(field, name, format_string, (type))	\
   1277static SAS_DEVICE_ATTR(end_dev, name, S_IRUGO, 			\
   1278		show_sas_end_dev_##name, NULL)
   1279
   1280sas_end_dev_simple_attr(ready_led_meaning, ready_led_meaning, "%d\n", int);
   1281sas_end_dev_simple_attr(I_T_nexus_loss_timeout, I_T_nexus_loss_timeout,
   1282			"%d\n", int);
   1283sas_end_dev_simple_attr(initiator_response_timeout, initiator_response_timeout,
   1284			"%d\n", int);
   1285sas_end_dev_simple_attr(tlr_supported, tlr_supported,
   1286			"%d\n", int);
   1287sas_end_dev_simple_attr(tlr_enabled, tlr_enabled,
   1288			"%d\n", int);
   1289
   1290static DECLARE_TRANSPORT_CLASS(sas_expander_class,
   1291			       "sas_expander", NULL, NULL, NULL);
   1292
   1293#define sas_expander_show_simple(field, name, format_string, cast)	\
   1294static ssize_t								\
   1295show_sas_expander_##name(struct device *dev, 				\
   1296			 struct device_attribute *attr, char *buf)	\
   1297{									\
   1298	struct sas_rphy *rphy = transport_class_to_rphy(dev);		\
   1299	struct sas_expander_device *edev = rphy_to_expander_device(rphy); \
   1300									\
   1301	return snprintf(buf, 20, format_string, cast edev->field);	\
   1302}
   1303
   1304#define sas_expander_simple_attr(field, name, format_string, type)	\
   1305	sas_expander_show_simple(field, name, format_string, (type))	\
   1306static SAS_DEVICE_ATTR(expander, name, S_IRUGO, 			\
   1307		show_sas_expander_##name, NULL)
   1308
   1309sas_expander_simple_attr(vendor_id, vendor_id, "%s\n", char *);
   1310sas_expander_simple_attr(product_id, product_id, "%s\n", char *);
   1311sas_expander_simple_attr(product_rev, product_rev, "%s\n", char *);
   1312sas_expander_simple_attr(component_vendor_id, component_vendor_id,
   1313			 "%s\n", char *);
   1314sas_expander_simple_attr(component_id, component_id, "%u\n", unsigned int);
   1315sas_expander_simple_attr(component_revision_id, component_revision_id, "%u\n",
   1316			 unsigned int);
   1317sas_expander_simple_attr(level, level, "%d\n", int);
   1318
   1319static DECLARE_TRANSPORT_CLASS(sas_rphy_class,
   1320		"sas_device", NULL, NULL, NULL);
   1321
   1322static int sas_rphy_match(struct attribute_container *cont, struct device *dev)
   1323{
   1324	struct Scsi_Host *shost;
   1325	struct sas_internal *i;
   1326
   1327	if (!scsi_is_sas_rphy(dev))
   1328		return 0;
   1329	shost = dev_to_shost(dev->parent->parent);
   1330
   1331	if (!shost->transportt)
   1332		return 0;
   1333	if (shost->transportt->host_attrs.ac.class !=
   1334			&sas_host_class.class)
   1335		return 0;
   1336
   1337	i = to_sas_internal(shost->transportt);
   1338	return &i->rphy_attr_cont.ac == cont;
   1339}
   1340
   1341static int sas_end_dev_match(struct attribute_container *cont,
   1342			     struct device *dev)
   1343{
   1344	struct Scsi_Host *shost;
   1345	struct sas_internal *i;
   1346	struct sas_rphy *rphy;
   1347
   1348	if (!scsi_is_sas_rphy(dev))
   1349		return 0;
   1350	shost = dev_to_shost(dev->parent->parent);
   1351	rphy = dev_to_rphy(dev);
   1352
   1353	if (!shost->transportt)
   1354		return 0;
   1355	if (shost->transportt->host_attrs.ac.class !=
   1356			&sas_host_class.class)
   1357		return 0;
   1358
   1359	i = to_sas_internal(shost->transportt);
   1360	return &i->end_dev_attr_cont.ac == cont &&
   1361		rphy->identify.device_type == SAS_END_DEVICE;
   1362}
   1363
   1364static int sas_expander_match(struct attribute_container *cont,
   1365			      struct device *dev)
   1366{
   1367	struct Scsi_Host *shost;
   1368	struct sas_internal *i;
   1369	struct sas_rphy *rphy;
   1370
   1371	if (!scsi_is_sas_rphy(dev))
   1372		return 0;
   1373	shost = dev_to_shost(dev->parent->parent);
   1374	rphy = dev_to_rphy(dev);
   1375
   1376	if (!shost->transportt)
   1377		return 0;
   1378	if (shost->transportt->host_attrs.ac.class !=
   1379			&sas_host_class.class)
   1380		return 0;
   1381
   1382	i = to_sas_internal(shost->transportt);
   1383	return &i->expander_attr_cont.ac == cont &&
   1384		(rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
   1385		 rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE);
   1386}
   1387
   1388static void sas_expander_release(struct device *dev)
   1389{
   1390	struct sas_rphy *rphy = dev_to_rphy(dev);
   1391	struct sas_expander_device *edev = rphy_to_expander_device(rphy);
   1392
   1393	put_device(dev->parent);
   1394	kfree(edev);
   1395}
   1396
   1397static void sas_end_device_release(struct device *dev)
   1398{
   1399	struct sas_rphy *rphy = dev_to_rphy(dev);
   1400	struct sas_end_device *edev = rphy_to_end_device(rphy);
   1401
   1402	put_device(dev->parent);
   1403	kfree(edev);
   1404}
   1405
   1406/**
   1407 * sas_rphy_initialize - common rphy initialization
   1408 * @rphy:	rphy to initialise
   1409 *
   1410 * Used by both sas_end_device_alloc() and sas_expander_alloc() to
   1411 * initialise the common rphy component of each.
   1412 */
   1413static void sas_rphy_initialize(struct sas_rphy *rphy)
   1414{
   1415	INIT_LIST_HEAD(&rphy->list);
   1416}
   1417
   1418/**
   1419 * sas_end_device_alloc - allocate an rphy for an end device
   1420 * @parent: which port
   1421 *
   1422 * Allocates an SAS remote PHY structure, connected to @parent.
   1423 *
   1424 * Returns:
   1425 *	SAS PHY allocated or %NULL if the allocation failed.
   1426 */
   1427struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
   1428{
   1429	struct Scsi_Host *shost = dev_to_shost(&parent->dev);
   1430	struct sas_end_device *rdev;
   1431
   1432	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
   1433	if (!rdev) {
   1434		return NULL;
   1435	}
   1436
   1437	device_initialize(&rdev->rphy.dev);
   1438	rdev->rphy.dev.parent = get_device(&parent->dev);
   1439	rdev->rphy.dev.release = sas_end_device_release;
   1440	if (scsi_is_sas_expander_device(parent->dev.parent)) {
   1441		struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent);
   1442		dev_set_name(&rdev->rphy.dev, "end_device-%d:%d:%d",
   1443			     shost->host_no, rphy->scsi_target_id,
   1444			     parent->port_identifier);
   1445	} else
   1446		dev_set_name(&rdev->rphy.dev, "end_device-%d:%d",
   1447			     shost->host_no, parent->port_identifier);
   1448	rdev->rphy.identify.device_type = SAS_END_DEVICE;
   1449	sas_rphy_initialize(&rdev->rphy);
   1450	transport_setup_device(&rdev->rphy.dev);
   1451
   1452	return &rdev->rphy;
   1453}
   1454EXPORT_SYMBOL(sas_end_device_alloc);
   1455
   1456/**
   1457 * sas_expander_alloc - allocate an rphy for an end device
   1458 * @parent: which port
   1459 * @type: SAS_EDGE_EXPANDER_DEVICE or SAS_FANOUT_EXPANDER_DEVICE
   1460 *
   1461 * Allocates an SAS remote PHY structure, connected to @parent.
   1462 *
   1463 * Returns:
   1464 *	SAS PHY allocated or %NULL if the allocation failed.
   1465 */
   1466struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
   1467				    enum sas_device_type type)
   1468{
   1469	struct Scsi_Host *shost = dev_to_shost(&parent->dev);
   1470	struct sas_expander_device *rdev;
   1471	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
   1472
   1473	BUG_ON(type != SAS_EDGE_EXPANDER_DEVICE &&
   1474	       type != SAS_FANOUT_EXPANDER_DEVICE);
   1475
   1476	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
   1477	if (!rdev) {
   1478		return NULL;
   1479	}
   1480
   1481	device_initialize(&rdev->rphy.dev);
   1482	rdev->rphy.dev.parent = get_device(&parent->dev);
   1483	rdev->rphy.dev.release = sas_expander_release;
   1484	mutex_lock(&sas_host->lock);
   1485	rdev->rphy.scsi_target_id = sas_host->next_expander_id++;
   1486	mutex_unlock(&sas_host->lock);
   1487	dev_set_name(&rdev->rphy.dev, "expander-%d:%d",
   1488		     shost->host_no, rdev->rphy.scsi_target_id);
   1489	rdev->rphy.identify.device_type = type;
   1490	sas_rphy_initialize(&rdev->rphy);
   1491	transport_setup_device(&rdev->rphy.dev);
   1492
   1493	return &rdev->rphy;
   1494}
   1495EXPORT_SYMBOL(sas_expander_alloc);
   1496
   1497/**
   1498 * sas_rphy_add  -  add a SAS remote PHY to the device hierarchy
   1499 * @rphy:	The remote PHY to be added
   1500 *
   1501 * Publishes a SAS remote PHY to the rest of the system.
   1502 */
   1503int sas_rphy_add(struct sas_rphy *rphy)
   1504{
   1505	struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
   1506	struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
   1507	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
   1508	struct sas_identify *identify = &rphy->identify;
   1509	int error;
   1510
   1511	if (parent->rphy)
   1512		return -ENXIO;
   1513	parent->rphy = rphy;
   1514
   1515	error = device_add(&rphy->dev);
   1516	if (error)
   1517		return error;
   1518	transport_add_device(&rphy->dev);
   1519	transport_configure_device(&rphy->dev);
   1520	if (sas_bsg_initialize(shost, rphy))
   1521		printk("fail to a bsg device %s\n", dev_name(&rphy->dev));
   1522
   1523
   1524	mutex_lock(&sas_host->lock);
   1525	list_add_tail(&rphy->list, &sas_host->rphy_list);
   1526	if (identify->device_type == SAS_END_DEVICE &&
   1527	    (identify->target_port_protocols &
   1528	     (SAS_PROTOCOL_SSP | SAS_PROTOCOL_STP | SAS_PROTOCOL_SATA)))
   1529		rphy->scsi_target_id = sas_host->next_target_id++;
   1530	else if (identify->device_type == SAS_END_DEVICE)
   1531		rphy->scsi_target_id = -1;
   1532	mutex_unlock(&sas_host->lock);
   1533
   1534	if (identify->device_type == SAS_END_DEVICE &&
   1535	    rphy->scsi_target_id != -1) {
   1536		int lun;
   1537
   1538		if (identify->target_port_protocols & SAS_PROTOCOL_SSP)
   1539			lun = SCAN_WILD_CARD;
   1540		else
   1541			lun = 0;
   1542
   1543		scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun,
   1544				 SCSI_SCAN_INITIAL);
   1545	}
   1546
   1547	return 0;
   1548}
   1549EXPORT_SYMBOL(sas_rphy_add);
   1550
   1551/**
   1552 * sas_rphy_free  -  free a SAS remote PHY
   1553 * @rphy: SAS remote PHY to free
   1554 *
   1555 * Frees the specified SAS remote PHY.
   1556 *
   1557 * Note:
   1558 *   This function must only be called on a remote
   1559 *   PHY that has not successfully been added using
   1560 *   sas_rphy_add() (or has been sas_rphy_remove()'d)
   1561 */
   1562void sas_rphy_free(struct sas_rphy *rphy)
   1563{
   1564	struct device *dev = &rphy->dev;
   1565	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
   1566	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
   1567
   1568	mutex_lock(&sas_host->lock);
   1569	list_del(&rphy->list);
   1570	mutex_unlock(&sas_host->lock);
   1571
   1572	transport_destroy_device(dev);
   1573
   1574	put_device(dev);
   1575}
   1576EXPORT_SYMBOL(sas_rphy_free);
   1577
   1578/**
   1579 * sas_rphy_delete  -  remove and free SAS remote PHY
   1580 * @rphy:	SAS remote PHY to remove and free
   1581 *
   1582 * Removes the specified SAS remote PHY and frees it.
   1583 */
   1584void
   1585sas_rphy_delete(struct sas_rphy *rphy)
   1586{
   1587	sas_rphy_remove(rphy);
   1588	sas_rphy_free(rphy);
   1589}
   1590EXPORT_SYMBOL(sas_rphy_delete);
   1591
   1592/**
   1593 * sas_rphy_unlink  -  unlink SAS remote PHY
   1594 * @rphy:	SAS remote phy to unlink from its parent port
   1595 *
   1596 * Removes port reference to an rphy
   1597 */
   1598void sas_rphy_unlink(struct sas_rphy *rphy)
   1599{
   1600	struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
   1601
   1602	parent->rphy = NULL;
   1603}
   1604EXPORT_SYMBOL(sas_rphy_unlink);
   1605
   1606/**
   1607 * sas_rphy_remove  -  remove SAS remote PHY
   1608 * @rphy:	SAS remote phy to remove
   1609 *
   1610 * Removes the specified SAS remote PHY.
   1611 */
   1612void
   1613sas_rphy_remove(struct sas_rphy *rphy)
   1614{
   1615	struct device *dev = &rphy->dev;
   1616
   1617	switch (rphy->identify.device_type) {
   1618	case SAS_END_DEVICE:
   1619		scsi_remove_target(dev);
   1620		break;
   1621	case SAS_EDGE_EXPANDER_DEVICE:
   1622	case SAS_FANOUT_EXPANDER_DEVICE:
   1623		sas_remove_children(dev);
   1624		break;
   1625	default:
   1626		break;
   1627	}
   1628
   1629	sas_rphy_unlink(rphy);
   1630	bsg_remove_queue(rphy->q);
   1631	transport_remove_device(dev);
   1632	device_del(dev);
   1633}
   1634EXPORT_SYMBOL(sas_rphy_remove);
   1635
   1636/**
   1637 * scsi_is_sas_rphy  -  check if a struct device represents a SAS remote PHY
   1638 * @dev:	device to check
   1639 *
   1640 * Returns:
   1641 *	%1 if the device represents a SAS remote PHY, %0 else
   1642 */
   1643int scsi_is_sas_rphy(const struct device *dev)
   1644{
   1645	return dev->release == sas_end_device_release ||
   1646		dev->release == sas_expander_release;
   1647}
   1648EXPORT_SYMBOL(scsi_is_sas_rphy);
   1649
   1650
   1651/*
   1652 * SCSI scan helper
   1653 */
   1654
   1655static int sas_user_scan(struct Scsi_Host *shost, uint channel,
   1656		uint id, u64 lun)
   1657{
   1658	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
   1659	struct sas_rphy *rphy;
   1660
   1661	mutex_lock(&sas_host->lock);
   1662	list_for_each_entry(rphy, &sas_host->rphy_list, list) {
   1663		if (rphy->identify.device_type != SAS_END_DEVICE ||
   1664		    rphy->scsi_target_id == -1)
   1665			continue;
   1666
   1667		if ((channel == SCAN_WILD_CARD || channel == 0) &&
   1668		    (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
   1669			scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id,
   1670					 lun, SCSI_SCAN_MANUAL);
   1671		}
   1672	}
   1673	mutex_unlock(&sas_host->lock);
   1674
   1675	return 0;
   1676}
   1677
   1678
   1679/*
   1680 * Setup / Teardown code
   1681 */
   1682
   1683#define SETUP_TEMPLATE(attrb, field, perm, test)			\
   1684	i->private_##attrb[count] = dev_attr_##field;		\
   1685	i->private_##attrb[count].attr.mode = perm;			\
   1686	i->attrb[count] = &i->private_##attrb[count];			\
   1687	if (test)							\
   1688		count++
   1689
   1690#define SETUP_TEMPLATE_RW(attrb, field, perm, test, ro_test, ro_perm)	\
   1691	i->private_##attrb[count] = dev_attr_##field;		\
   1692	i->private_##attrb[count].attr.mode = perm;			\
   1693	if (ro_test) {							\
   1694		i->private_##attrb[count].attr.mode = ro_perm;		\
   1695		i->private_##attrb[count].store = NULL;			\
   1696	}								\
   1697	i->attrb[count] = &i->private_##attrb[count];			\
   1698	if (test)							\
   1699		count++
   1700
   1701#define SETUP_RPORT_ATTRIBUTE(field) 					\
   1702	SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, 1)
   1703
   1704#define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func)			\
   1705	SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func)
   1706
   1707#define SETUP_PHY_ATTRIBUTE(field)					\
   1708	SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1)
   1709
   1710#define SETUP_PHY_ATTRIBUTE_RW(field)					\
   1711	SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1,	\
   1712			!i->f->set_phy_speed, S_IRUGO)
   1713
   1714#define SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(field, func)			\
   1715	SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1,	\
   1716			  !i->f->func, S_IRUGO)
   1717
   1718#define SETUP_PORT_ATTRIBUTE(field)					\
   1719	SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
   1720
   1721#define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func)			\
   1722	SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func)
   1723
   1724#define SETUP_PHY_ATTRIBUTE_WRONLY(field)				\
   1725	SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, 1)
   1726
   1727#define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func)		\
   1728	SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, i->f->func)
   1729
   1730#define SETUP_END_DEV_ATTRIBUTE(field)					\
   1731	SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1)
   1732
   1733#define SETUP_EXPANDER_ATTRIBUTE(field)					\
   1734	SETUP_TEMPLATE(expander_attrs, expander_##field, S_IRUGO, 1)
   1735
   1736/**
   1737 * sas_attach_transport  -  instantiate SAS transport template
   1738 * @ft:		SAS transport class function template
   1739 */
   1740struct scsi_transport_template *
   1741sas_attach_transport(struct sas_function_template *ft)
   1742{
   1743	struct sas_internal *i;
   1744	int count;
   1745
   1746	i = kzalloc(sizeof(struct sas_internal), GFP_KERNEL);
   1747	if (!i)
   1748		return NULL;
   1749
   1750	i->t.user_scan = sas_user_scan;
   1751
   1752	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
   1753	i->t.host_attrs.ac.class = &sas_host_class.class;
   1754	i->t.host_attrs.ac.match = sas_host_match;
   1755	transport_container_register(&i->t.host_attrs);
   1756	i->t.host_size = sizeof(struct sas_host_attrs);
   1757
   1758	i->phy_attr_cont.ac.class = &sas_phy_class.class;
   1759	i->phy_attr_cont.ac.attrs = &i->phy_attrs[0];
   1760	i->phy_attr_cont.ac.match = sas_phy_match;
   1761	transport_container_register(&i->phy_attr_cont);
   1762
   1763	i->port_attr_cont.ac.class = &sas_port_class.class;
   1764	i->port_attr_cont.ac.attrs = &i->port_attrs[0];
   1765	i->port_attr_cont.ac.match = sas_port_match;
   1766	transport_container_register(&i->port_attr_cont);
   1767
   1768	i->rphy_attr_cont.ac.class = &sas_rphy_class.class;
   1769	i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0];
   1770	i->rphy_attr_cont.ac.match = sas_rphy_match;
   1771	transport_container_register(&i->rphy_attr_cont);
   1772
   1773	i->end_dev_attr_cont.ac.class = &sas_end_dev_class.class;
   1774	i->end_dev_attr_cont.ac.attrs = &i->end_dev_attrs[0];
   1775	i->end_dev_attr_cont.ac.match = sas_end_dev_match;
   1776	transport_container_register(&i->end_dev_attr_cont);
   1777
   1778	i->expander_attr_cont.ac.class = &sas_expander_class.class;
   1779	i->expander_attr_cont.ac.attrs = &i->expander_attrs[0];
   1780	i->expander_attr_cont.ac.match = sas_expander_match;
   1781	transport_container_register(&i->expander_attr_cont);
   1782
   1783	i->f = ft;
   1784
   1785	count = 0;
   1786	SETUP_PHY_ATTRIBUTE(initiator_port_protocols);
   1787	SETUP_PHY_ATTRIBUTE(target_port_protocols);
   1788	SETUP_PHY_ATTRIBUTE(device_type);
   1789	SETUP_PHY_ATTRIBUTE(sas_address);
   1790	SETUP_PHY_ATTRIBUTE(phy_identifier);
   1791	SETUP_PHY_ATTRIBUTE(negotiated_linkrate);
   1792	SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw);
   1793	SETUP_PHY_ATTRIBUTE_RW(minimum_linkrate);
   1794	SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw);
   1795	SETUP_PHY_ATTRIBUTE_RW(maximum_linkrate);
   1796
   1797	SETUP_PHY_ATTRIBUTE(invalid_dword_count);
   1798	SETUP_PHY_ATTRIBUTE(running_disparity_error_count);
   1799	SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count);
   1800	SETUP_PHY_ATTRIBUTE(phy_reset_problem_count);
   1801	SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset);
   1802	SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset);
   1803	SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(enable, phy_enable);
   1804	i->phy_attrs[count] = NULL;
   1805
   1806	count = 0;
   1807	SETUP_PORT_ATTRIBUTE(num_phys);
   1808	i->port_attrs[count] = NULL;
   1809
   1810	count = 0;
   1811	SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols);
   1812	SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols);
   1813	SETUP_RPORT_ATTRIBUTE(rphy_device_type);
   1814	SETUP_RPORT_ATTRIBUTE(rphy_sas_address);
   1815	SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier);
   1816	SETUP_RPORT_ATTRIBUTE(rphy_scsi_target_id);
   1817	SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_enclosure_identifier,
   1818				       get_enclosure_identifier);
   1819	SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_bay_identifier,
   1820				       get_bay_identifier);
   1821	i->rphy_attrs[count] = NULL;
   1822
   1823	count = 0;
   1824	SETUP_END_DEV_ATTRIBUTE(end_dev_ready_led_meaning);
   1825	SETUP_END_DEV_ATTRIBUTE(end_dev_I_T_nexus_loss_timeout);
   1826	SETUP_END_DEV_ATTRIBUTE(end_dev_initiator_response_timeout);
   1827	SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_supported);
   1828	SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_enabled);
   1829	i->end_dev_attrs[count] = NULL;
   1830
   1831	count = 0;
   1832	SETUP_EXPANDER_ATTRIBUTE(vendor_id);
   1833	SETUP_EXPANDER_ATTRIBUTE(product_id);
   1834	SETUP_EXPANDER_ATTRIBUTE(product_rev);
   1835	SETUP_EXPANDER_ATTRIBUTE(component_vendor_id);
   1836	SETUP_EXPANDER_ATTRIBUTE(component_id);
   1837	SETUP_EXPANDER_ATTRIBUTE(component_revision_id);
   1838	SETUP_EXPANDER_ATTRIBUTE(level);
   1839	i->expander_attrs[count] = NULL;
   1840
   1841	return &i->t;
   1842}
   1843EXPORT_SYMBOL(sas_attach_transport);
   1844
   1845/**
   1846 * sas_release_transport  -  release SAS transport template instance
   1847 * @t:		transport template instance
   1848 */
   1849void sas_release_transport(struct scsi_transport_template *t)
   1850{
   1851	struct sas_internal *i = to_sas_internal(t);
   1852
   1853	transport_container_unregister(&i->t.host_attrs);
   1854	transport_container_unregister(&i->phy_attr_cont);
   1855	transport_container_unregister(&i->port_attr_cont);
   1856	transport_container_unregister(&i->rphy_attr_cont);
   1857	transport_container_unregister(&i->end_dev_attr_cont);
   1858	transport_container_unregister(&i->expander_attr_cont);
   1859
   1860	kfree(i);
   1861}
   1862EXPORT_SYMBOL(sas_release_transport);
   1863
   1864static __init int sas_transport_init(void)
   1865{
   1866	int error;
   1867
   1868	error = transport_class_register(&sas_host_class);
   1869	if (error)
   1870		goto out;
   1871	error = transport_class_register(&sas_phy_class);
   1872	if (error)
   1873		goto out_unregister_transport;
   1874	error = transport_class_register(&sas_port_class);
   1875	if (error)
   1876		goto out_unregister_phy;
   1877	error = transport_class_register(&sas_rphy_class);
   1878	if (error)
   1879		goto out_unregister_port;
   1880	error = transport_class_register(&sas_end_dev_class);
   1881	if (error)
   1882		goto out_unregister_rphy;
   1883	error = transport_class_register(&sas_expander_class);
   1884	if (error)
   1885		goto out_unregister_end_dev;
   1886
   1887	return 0;
   1888
   1889 out_unregister_end_dev:
   1890	transport_class_unregister(&sas_end_dev_class);
   1891 out_unregister_rphy:
   1892	transport_class_unregister(&sas_rphy_class);
   1893 out_unregister_port:
   1894	transport_class_unregister(&sas_port_class);
   1895 out_unregister_phy:
   1896	transport_class_unregister(&sas_phy_class);
   1897 out_unregister_transport:
   1898	transport_class_unregister(&sas_host_class);
   1899 out:
   1900	return error;
   1901
   1902}
   1903
   1904static void __exit sas_transport_exit(void)
   1905{
   1906	transport_class_unregister(&sas_host_class);
   1907	transport_class_unregister(&sas_phy_class);
   1908	transport_class_unregister(&sas_port_class);
   1909	transport_class_unregister(&sas_rphy_class);
   1910	transport_class_unregister(&sas_end_dev_class);
   1911	transport_class_unregister(&sas_expander_class);
   1912}
   1913
   1914MODULE_AUTHOR("Christoph Hellwig");
   1915MODULE_DESCRIPTION("SAS Transport Attributes");
   1916MODULE_LICENSE("GPL");
   1917
   1918module_init(sas_transport_init);
   1919module_exit(sas_transport_exit);