scsi_transport_sas.c revision 07ba3a954714da10cbd3f6249d93ac2c1df72c4f
1c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 2c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Copyright (C) 2005 Dell Inc. 3c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Released under GPL v2. 4c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 5c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Serial Attached SCSI (SAS) transport class. 6c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 7c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * The SAS transport class contains common code to deal with SAS HBAs, 8c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * an aproximated representation of SAS topologies in the driver model, 9c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * and various sysfs attributes to expose these topologies and managment 10c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * interfaces to userspace. 11c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 12c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * In addition to the basic SCSI core objects this transport class 13c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * introduces two additional intermediate objects: The SAS PHY 14c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * as represented by struct sas_phy defines an "outgoing" PHY on 15c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * a SAS HBA or Expander, and the SAS remote PHY represented by 16c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * struct sas_rphy defines an "incoming" PHY on a SAS Expander or 17c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * end device. Note that this is purely a software concept, the 18c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * underlying hardware for a PHY and a remote PHY is the exactly 19c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * the same. 20c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 21c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * There is no concept of a SAS port in this code, users can see 22c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * what PHYs form a wide port based on the port_identifier attribute, 23c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * which is the same for all PHYs in a port. 24c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 25c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 26c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <linux/init.h> 27c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <linux/module.h> 28c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <linux/err.h> 29c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 30c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <scsi/scsi_device.h> 31c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <scsi/scsi_host.h> 32c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <scsi/scsi_transport.h> 33c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#include <scsi/scsi_transport_sas.h> 34c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 35c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 36c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define SAS_HOST_ATTRS 0 3707ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig#define SAS_PORT_ATTRS 17 38c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define SAS_RPORT_ATTRS 5 39c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 40c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstruct sas_internal { 41c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct scsi_transport_template t; 42c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_function_template *f; 43c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 44c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; 45c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS]; 46c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; 47c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 48c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct transport_container phy_attr_cont; 49c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct transport_container rphy_attr_cont; 50c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 51c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig /* 52c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * The array of null terminated pointers to attributes 53c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * needed by scsi_sysfs.c 54c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 55c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; 56c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1]; 57c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; 58c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig}; 59c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define to_sas_internal(tmpl) container_of(tmpl, struct sas_internal, t) 60c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 61c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstruct sas_host_attrs { 62c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct list_head rphy_list; 63c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spinlock_t lock; 64c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig u32 next_target_id; 65c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig}; 66c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) 67c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 68c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 69c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 70c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Hack to allow attributes of the same name in different objects. 71c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 72c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define SAS_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \ 73c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct class_device_attribute class_device_attr_##_prefix##_##_name = \ 74c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig __ATTR(_name,_mode,_show,_store) 75c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 76c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 77c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 78c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Pretty printing helpers 79c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 80c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 81c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_bitfield_name_match(title, table) \ 82c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 83c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigget_sas_##title##_names(u32 table_key, char *buf) \ 84c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 85c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig char *prefix = ""; \ 86c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig ssize_t len = 0; \ 87c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int i; \ 88c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 89c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 90c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (table[i].value & table_key) { \ 91c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig len += sprintf(buf + len, "%s%s", \ 92c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig prefix, table[i].name); \ 93c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig prefix = ", "; \ 94c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } \ 95c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } \ 96c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig len += sprintf(buf + len, "\n"); \ 97c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return len; \ 98c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 99c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 100c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_bitfield_name_search(title, table) \ 101c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 102c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigget_sas_##title##_names(u32 table_key, char *buf) \ 103c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 104c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig ssize_t len = 0; \ 105c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int i; \ 106c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 107c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 108c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (table[i].value == table_key) { \ 109c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig len += sprintf(buf + len, "%s", \ 110c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig table[i].name); \ 111c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig break; \ 112c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } \ 113c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } \ 114c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig len += sprintf(buf + len, "\n"); \ 115c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return len; \ 116c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 117c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 118c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic struct { 119c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig u32 value; 120c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig char *name; 121c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} sas_device_type_names[] = { 122c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_PHY_UNUSED, "unused" }, 123c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_END_DEVICE, "end device" }, 124c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_EDGE_EXPANDER_DEVICE, "edge expander" }, 125c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_FANOUT_EXPANDER_DEVICE, "fanout expander" }, 126c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig}; 127c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_bitfield_name_search(device_type, sas_device_type_names) 128c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 129c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 130c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic struct { 131c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig u32 value; 132c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig char *name; 133c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} sas_protocol_names[] = { 134c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_PROTOCOL_SATA, "sata" }, 135c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_PROTOCOL_SMP, "smp" }, 136c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_PROTOCOL_STP, "stp" }, 137c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_PROTOCOL_SSP, "ssp" }, 138c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig}; 139c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_bitfield_name_match(protocol, sas_protocol_names) 140c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 141c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic struct { 142c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig u32 value; 143c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig char *name; 144c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} sas_linkspeed_names[] = { 145c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_LINK_RATE_UNKNOWN, "Unknown" }, 146c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_PHY_DISABLED, "Phy disabled" }, 147c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_LINK_RATE_FAILED, "Link Rate failed" }, 148c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_SATA_SPINUP_HOLD, "Spin-up hold" }, 149c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_LINK_RATE_1_5_GBPS, "1.5 Gbit" }, 150c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" }, 151c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig}; 152c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_bitfield_name_search(linkspeed, sas_linkspeed_names) 153c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 154c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 155c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 156c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * SAS host attributes 157c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 158c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 15937be6eeb4990c05fc7dd683ceaf1501d46ebe9a4James Bottomleystatic int sas_host_setup(struct transport_container *tc, struct device *dev, 16037be6eeb4990c05fc7dd683ceaf1501d46ebe9a4James Bottomley struct class_device *cdev) 161c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 162c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(dev); 163c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 164c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 165c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig INIT_LIST_HEAD(&sas_host->rphy_list); 166c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_lock_init(&sas_host->lock); 167c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_host->next_target_id = 0; 168c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 169c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 170c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 171c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic DECLARE_TRANSPORT_CLASS(sas_host_class, 172c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig "sas_host", sas_host_setup, NULL, NULL); 173c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 174c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic int sas_host_match(struct attribute_container *cont, 175c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct device *dev) 176c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 177c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost; 178c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_internal *i; 179c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 180c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!scsi_is_host_device(dev)) 181c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 182c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig shost = dev_to_shost(dev); 183c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 184c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!shost->transportt) 185c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 186c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (shost->transportt->host_attrs.ac.class != 187c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig &sas_host_class.class) 188c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 189c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 190c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i = to_sas_internal(shost->transportt); 191c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return &i->t.host_attrs.ac == cont; 192c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 193c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 194c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic int do_sas_phy_delete(struct device *dev, void *data) 195c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 196c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (scsi_is_sas_phy(dev)) 197c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_phy_delete(dev_to_phy(dev)); 198c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 199c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 200c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 201c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 202c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_remove_host -- tear down a Scsi_Host's SAS data structures 203c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @shost: Scsi Host that is torn down 204c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 205c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Removes all SAS PHYs and remote PHYs for a given Scsi_Host. 206c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Must be called just before scsi_remove_host for SAS HBAs. 207c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 208c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigvoid sas_remove_host(struct Scsi_Host *shost) 209c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 210c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig device_for_each_child(&shost->shost_gendev, NULL, do_sas_phy_delete); 211c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 212c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_remove_host); 213c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 214c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 215c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 216c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * SAS Port attributes 217c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 218c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 219c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_phy_show_simple(field, name, format_string, cast) \ 220c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 221c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_phy_##name(struct class_device *cdev, char *buf) \ 222c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 223c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *phy = transport_class_to_phy(cdev); \ 224c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 225c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return snprintf(buf, 20, format_string, cast phy->field); \ 226c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 227c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 228c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_phy_simple_attr(field, name, format_string, type) \ 229c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_phy_show_simple(field, name, format_string, (type)) \ 230c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL) 231c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 232c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_phy_show_protocol(field, name) \ 233c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 234c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_phy_##name(struct class_device *cdev, char *buf) \ 235c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 236c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *phy = transport_class_to_phy(cdev); \ 237c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 238c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!phy->field) \ 239c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return snprintf(buf, 20, "none\n"); \ 240c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return get_sas_protocol_names(phy->field, buf); \ 241c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 242c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 243c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_phy_protocol_attr(field, name) \ 244c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_phy_show_protocol(field, name) \ 245c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL) 246c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 247c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_phy_show_linkspeed(field) \ 248c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 249c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_phy_##field(struct class_device *cdev, char *buf) \ 250c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 251c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *phy = transport_class_to_phy(cdev); \ 252c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 253c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return get_sas_linkspeed_names(phy->field, buf); \ 254c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 255c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 256c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_phy_linkspeed_attr(field) \ 257c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_phy_show_linkspeed(field) \ 258c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL) 259c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 260c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig#define sas_phy_show_linkerror(field) \ 261c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigstatic ssize_t \ 262c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigshow_sas_phy_##field(struct class_device *cdev, char *buf) \ 263c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig{ \ 264c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig struct sas_phy *phy = transport_class_to_phy(cdev); \ 265c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); \ 266c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig struct sas_internal *i = to_sas_internal(shost->transportt); \ 267c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig int error; \ 268c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig \ 269ac01bbbd3b7ebfca64357aed12cf476b16abe3ceChristoph Hellwig if (!phy->local_attached) \ 270ac01bbbd3b7ebfca64357aed12cf476b16abe3ceChristoph Hellwig return -EINVAL; \ 271ac01bbbd3b7ebfca64357aed12cf476b16abe3ceChristoph Hellwig \ 272c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig error = i->f->get_linkerrors(phy); \ 273c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig if (error) \ 274c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig return error; \ 275c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig return snprintf(buf, 20, "%u\n", phy->field); \ 276c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig} 277c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig 278c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig#define sas_phy_linkerror_attr(field) \ 279c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig sas_phy_show_linkerror(field) \ 280c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigstatic CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL) 281c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig 282c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig 283c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t 284c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_device_type(struct class_device *cdev, char *buf) 285c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 286c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *phy = transport_class_to_phy(cdev); 287c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 288c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!phy->identify.device_type) 289c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return snprintf(buf, 20, "none\n"); 290c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return get_sas_device_type_names(phy->identify.device_type, buf); 291c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 292c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); 293c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 29407ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwigstatic ssize_t do_sas_phy_reset(struct class_device *cdev, 29507ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig size_t count, int hard_reset) 29607ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig{ 29707ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig struct sas_phy *phy = transport_class_to_phy(cdev); 29807ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); 29907ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig struct sas_internal *i = to_sas_internal(shost->transportt); 30007ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig int error; 30107ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig 30207ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig if (!phy->local_attached) 30307ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig return -EINVAL; 30407ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig 30507ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig error = i->f->phy_reset(phy, hard_reset); 30607ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig if (error) 30707ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig return error; 30807ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig return count; 30907ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig}; 31007ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig 31107ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwigstatic ssize_t store_sas_link_reset(struct class_device *cdev, 31207ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig const char *buf, size_t count) 31307ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig{ 31407ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig return do_sas_phy_reset(cdev, count, 0); 31507ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig} 31607ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwigstatic CLASS_DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset); 31707ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig 31807ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwigstatic ssize_t store_sas_hard_reset(struct class_device *cdev, 31907ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig const char *buf, size_t count) 32007ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig{ 32107ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig return do_sas_phy_reset(cdev, count, 1); 32207ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig} 32307ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwigstatic CLASS_DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset); 32407ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig 325c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_protocol_attr(identify.initiator_port_protocols, 326c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig initiator_port_protocols); 327c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_protocol_attr(identify.target_port_protocols, 328c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig target_port_protocols); 329c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", 330c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig unsigned long long); 331c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); 332c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); 333c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_linkspeed_attr(negotiated_linkrate); 334c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_linkspeed_attr(minimum_linkrate_hw); 335c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_linkspeed_attr(minimum_linkrate); 336c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_linkspeed_attr(maximum_linkrate_hw); 337c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_linkspeed_attr(maximum_linkrate); 338c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigsas_phy_linkerror_attr(invalid_dword_count); 339c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigsas_phy_linkerror_attr(running_disparity_error_count); 340c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigsas_phy_linkerror_attr(loss_of_dword_sync_count); 341c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwigsas_phy_linkerror_attr(phy_reset_problem_count); 342c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 343c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 344c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic DECLARE_TRANSPORT_CLASS(sas_phy_class, 345c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig "sas_phy", NULL, NULL, NULL); 346c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 347c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic int sas_phy_match(struct attribute_container *cont, struct device *dev) 348c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 349c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost; 350c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_internal *i; 351c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 352c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!scsi_is_sas_phy(dev)) 353c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 354c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig shost = dev_to_shost(dev->parent); 355c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 356c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!shost->transportt) 357c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 358c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (shost->transportt->host_attrs.ac.class != 359c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig &sas_host_class.class) 360c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 361c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 362c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i = to_sas_internal(shost->transportt); 363c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return &i->phy_attr_cont.ac == cont; 364c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 365c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 366c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic void sas_phy_release(struct device *dev) 367c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 368c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *phy = dev_to_phy(dev); 369c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 370c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(dev->parent); 371c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig kfree(phy); 372c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 373c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 374c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 375c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_phy_alloc -- allocates and initialize a SAS PHY structure 376c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @parent: Parent device 377c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @number: Port number 378c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 379c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Allocates an SAS PHY structure. It will be added in the device tree 380c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * below the device specified by @parent, which has to be either a Scsi_Host 381c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * or sas_rphy. 382c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 383c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Returns: 384c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * SAS PHY allocated or %NULL if the allocation failed. 385c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 386c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstruct sas_phy *sas_phy_alloc(struct device *parent, int number) 387c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 388c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(parent); 389c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *phy; 390c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 391c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig phy = kmalloc(sizeof(*phy), GFP_KERNEL); 392c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!phy) 393c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return NULL; 394c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig memset(phy, 0, sizeof(*phy)); 395c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 396c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig get_device(parent); 397c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 398c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig phy->number = number; 399c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 400c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig device_initialize(&phy->dev); 401c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig phy->dev.parent = get_device(parent); 402c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig phy->dev.release = sas_phy_release; 403c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); 404c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 405c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_setup_device(&phy->dev); 406c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 407c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return phy; 408c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 409c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_phy_alloc); 410c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 411c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 412c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_phy_add -- add a SAS PHY to the device hierachy 413c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @phy: The PHY to be added 414c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 415c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Publishes a SAS PHY to the rest of the system. 416c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 417c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigint sas_phy_add(struct sas_phy *phy) 418c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 419c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int error; 420c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 421c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig error = device_add(&phy->dev); 422c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!error) { 423c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_add_device(&phy->dev); 424c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_configure_device(&phy->dev); 425c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } 426c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 427c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return error; 428c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 429c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_phy_add); 430c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 431c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 432c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_phy_free -- free a SAS PHY 433c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @phy: SAS PHY to free 434c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 435c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Frees the specified SAS PHY. 436c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 437c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Note: 438c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * This function must only be called on a PHY that has not 439c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sucessfully been added using sas_phy_add(). 440c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 441c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigvoid sas_phy_free(struct sas_phy *phy) 442c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 443c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_destroy_device(&phy->dev); 444c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(phy->dev.parent); 445c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(phy->dev.parent); 446c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(phy->dev.parent); 447c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig kfree(phy); 448c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 449c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_phy_free); 450c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 451c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 452c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_phy_delete -- remove SAS PHY 453c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @phy: SAS PHY to remove 454c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 455c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Removes the specified SAS PHY. If the SAS PHY has an 456c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * associated remote PHY it is removed before. 457c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 458c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigvoid 459c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_phy_delete(struct sas_phy *phy) 460c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 461c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct device *dev = &phy->dev; 462c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 463c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (phy->rphy) 464c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_rphy_delete(phy->rphy); 465c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 466c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_remove_device(dev); 467c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig device_del(dev); 468c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_destroy_device(dev); 469c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(dev->parent); 470c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 471c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_phy_delete); 472c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 473c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 474c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * scsi_is_sas_phy -- check if a struct device represents a SAS PHY 475c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @dev: device to check 476c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 477c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Returns: 478c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * %1 if the device represents a SAS PHY, %0 else 479c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 480c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigint scsi_is_sas_phy(const struct device *dev) 481c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 482c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return dev->release == sas_phy_release; 483c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 484c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(scsi_is_sas_phy); 485c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 486c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 487c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * SAS remote PHY attributes. 488c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 489c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 490c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_rphy_show_simple(field, name, format_string, cast) \ 491c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 492c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_rphy_##name(struct class_device *cdev, char *buf) \ 493c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 494c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_rphy *rphy = transport_class_to_rphy(cdev); \ 495c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 496c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return snprintf(buf, 20, format_string, cast rphy->field); \ 497c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 498c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 499c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_rphy_simple_attr(field, name, format_string, type) \ 500c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_rphy_show_simple(field, name, format_string, (type)) \ 501c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic SAS_CLASS_DEVICE_ATTR(rphy, name, S_IRUGO, \ 502c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig show_sas_rphy_##name, NULL) 503c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 504c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_rphy_show_protocol(field, name) \ 505c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t \ 506c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_rphy_##name(struct class_device *cdev, char *buf) \ 507c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ \ 508c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_rphy *rphy = transport_class_to_rphy(cdev); \ 509c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig \ 510c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!rphy->field) \ 511c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return snprintf(buf, 20, "none\n"); \ 512c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return get_sas_protocol_names(rphy->field, buf); \ 513c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 514c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 515c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define sas_rphy_protocol_attr(field, name) \ 516c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sas_rphy_show_protocol(field, name) \ 517c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic SAS_CLASS_DEVICE_ATTR(rphy, name, S_IRUGO, \ 518c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig show_sas_rphy_##name, NULL) 519c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 520c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic ssize_t 521c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigshow_sas_rphy_device_type(struct class_device *cdev, char *buf) 522c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 523c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_rphy *rphy = transport_class_to_rphy(cdev); 524c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 525c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!rphy->identify.device_type) 526c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return snprintf(buf, 20, "none\n"); 527c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return get_sas_device_type_names( 528c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->identify.device_type, buf); 529c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 530c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 531c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic SAS_CLASS_DEVICE_ATTR(rphy, device_type, S_IRUGO, 532c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig show_sas_rphy_device_type, NULL); 533c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 534c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_rphy_protocol_attr(identify.initiator_port_protocols, 535c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig initiator_port_protocols); 536c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_rphy_protocol_attr(identify.target_port_protocols, target_port_protocols); 537c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_rphy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", 538c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig unsigned long long); 539c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_rphy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); 540c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 541c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic DECLARE_TRANSPORT_CLASS(sas_rphy_class, 542c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig "sas_rphy", NULL, NULL, NULL); 543c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 544c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic int sas_rphy_match(struct attribute_container *cont, struct device *dev) 545c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 546c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost; 547c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_internal *i; 548c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 549c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!scsi_is_sas_rphy(dev)) 550c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 551c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig shost = dev_to_shost(dev->parent->parent); 552c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 553c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!shost->transportt) 554c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 555c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (shost->transportt->host_attrs.ac.class != 556c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig &sas_host_class.class) 557c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 558c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 559c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i = to_sas_internal(shost->transportt); 560c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return &i->rphy_attr_cont.ac == cont; 561c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 562c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 563c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic void sas_rphy_release(struct device *dev) 564c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 565c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_rphy *rphy = dev_to_rphy(dev); 566c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 567c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(dev->parent); 568c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig kfree(rphy); 569c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 570c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 571c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 572c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_rphy_alloc -- allocates and initialize a SAS remote PHY structure 573c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @parent: SAS PHY this remote PHY is conneted to 574c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 575c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Allocates an SAS remote PHY structure, connected to @parent. 576c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 577c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Returns: 578c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * SAS PHY allocated or %NULL if the allocation failed. 579c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 580c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstruct sas_rphy *sas_rphy_alloc(struct sas_phy *parent) 581c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 582c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(&parent->dev); 583c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_rphy *rphy; 584c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 585c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy = kmalloc(sizeof(*rphy), GFP_KERNEL); 586c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!rphy) { 587c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(&parent->dev); 588c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return NULL; 589c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } 590c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig memset(rphy, 0, sizeof(*rphy)); 591c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 592c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig device_initialize(&rphy->dev); 593c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->dev.parent = get_device(&parent->dev); 594c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->dev.release = sas_rphy_release; 595c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig sprintf(rphy->dev.bus_id, "rphy-%d:%d", 596c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig shost->host_no, parent->number); 597c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_setup_device(&rphy->dev); 598c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 599c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return rphy; 600c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 601c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_rphy_alloc); 602c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 603c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 604c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_rphy_add -- add a SAS remote PHY to the device hierachy 605c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @rphy: The remote PHY to be added 606c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 607c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Publishes a SAS remote PHY to the rest of the system. 608c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 609c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigint sas_rphy_add(struct sas_rphy *rphy) 610c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 611c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *parent = dev_to_phy(rphy->dev.parent); 612c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); 613c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 614c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_identify *identify = &rphy->identify; 615c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int error; 616c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 617c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (parent->rphy) 618c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return -ENXIO; 619c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig parent->rphy = rphy; 620c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 621c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig error = device_add(&rphy->dev); 622c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (error) 623c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return error; 624c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_add_device(&rphy->dev); 625c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_configure_device(&rphy->dev); 626c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 627c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_lock(&sas_host->lock); 628c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig list_add_tail(&rphy->list, &sas_host->rphy_list); 629c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (identify->device_type == SAS_END_DEVICE && 630c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig (identify->target_port_protocols & 631c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA))) 632c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->scsi_target_id = sas_host->next_target_id++; 633c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig else 634c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->scsi_target_id = -1; 635c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_unlock(&sas_host->lock); 636c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 637c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (rphy->scsi_target_id != -1) { 638c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig scsi_scan_target(&rphy->dev, parent->number, 639c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->scsi_target_id, ~0, 0); 640c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } 641c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 642c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 643c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 644c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_rphy_add); 645c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 646c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 647c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_rphy_free -- free a SAS remote PHY 648c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @rphy SAS remote PHY to free 649c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 650c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Frees the specified SAS remote PHY. 651c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 652c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Note: 653c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * This function must only be called on a remote 654c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * PHY that has not sucessfully been added using 655c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_rphy_add(). 656c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 657c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigvoid sas_rphy_free(struct sas_rphy *rphy) 658c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 659c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); 660c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 661c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 662c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_lock(&sas_host->lock); 663c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig list_del(&rphy->list); 664c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_unlock(&sas_host->lock); 665c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 666c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_destroy_device(&rphy->dev); 667c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(rphy->dev.parent); 668c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(rphy->dev.parent); 669c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(rphy->dev.parent); 670c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig kfree(rphy); 671c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 672c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_rphy_free); 673c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 674c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 675c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_rphy_delete -- remove SAS remote PHY 676c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @rphy: SAS remote PHY to remove 677c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 678c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Removes the specified SAS remote PHY. 679c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 680c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigvoid 681c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_rphy_delete(struct sas_rphy *rphy) 682c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 683c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct device *dev = &rphy->dev; 684c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *parent = dev_to_phy(dev->parent); 685c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); 686c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 687c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 688fe8b2304e54552cea113318e2f66c45628130fdcChristoph Hellwig scsi_remove_target(dev); 689c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 690fe8b2304e54552cea113318e2f66c45628130fdcChristoph Hellwig transport_remove_device(dev); 691fe8b2304e54552cea113318e2f66c45628130fdcChristoph Hellwig device_del(dev); 692fe8b2304e54552cea113318e2f66c45628130fdcChristoph Hellwig transport_destroy_device(dev); 693c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 694c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_lock(&sas_host->lock); 695c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig list_del(&rphy->list); 696c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_unlock(&sas_host->lock); 697c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 698c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig put_device(&parent->dev); 699c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 700c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_rphy_delete); 701c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 702c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 703c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY 704c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @dev: device to check 705c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * 706c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Returns: 707c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * %1 if the device represents a SAS remote PHY, %0 else 708c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 709c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigint scsi_is_sas_rphy(const struct device *dev) 710c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 711c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return dev->release == sas_rphy_release; 712c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 713c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(scsi_is_sas_rphy); 714c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 715c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 716c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 717c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * SCSI scan helper 718c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 719c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 720c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic struct device *sas_target_parent(struct Scsi_Host *shost, 721c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int channel, uint id) 722c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 723c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 724c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_rphy *rphy; 725c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct device *dev = NULL; 726c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 727c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_lock(&sas_host->lock); 728c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig list_for_each_entry(rphy, &sas_host->rphy_list, list) { 729c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_phy *parent = dev_to_phy(rphy->dev.parent); 730c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (parent->number == channel && 731c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig rphy->scsi_target_id == id) 732c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig dev = &rphy->dev; 733c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig } 734c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig spin_unlock(&sas_host->lock); 735c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 736c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return dev; 737c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 738c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 739c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 740c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/* 741c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * Setup / Teardown code 742c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 743c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 744c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define SETUP_RPORT_ATTRIBUTE(field) \ 745c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->private_rphy_attrs[count] = class_device_attr_##field; \ 746c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->private_rphy_attrs[count].attr.mode = S_IRUGO; \ 747c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->private_rphy_attrs[count].store = NULL; \ 748c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->rphy_attrs[count] = &i->private_rphy_attrs[count]; \ 749c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig count++ 750c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 751c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig#define SETUP_PORT_ATTRIBUTE(field) \ 752c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->private_phy_attrs[count] = class_device_attr_##field; \ 753c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->private_phy_attrs[count].attr.mode = S_IRUGO; \ 754c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->private_phy_attrs[count].store = NULL; \ 755c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->phy_attrs[count] = &i->private_phy_attrs[count]; \ 756c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig count++ 757c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 75807ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig#define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ 75907ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig i->private_phy_attrs[count] = class_device_attr_##field; \ 76007ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig i->private_phy_attrs[count].attr.mode = S_IWUGO; \ 76107ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig i->private_phy_attrs[count].show = NULL; \ 76207ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig i->phy_attrs[count] = &i->private_phy_attrs[count]; \ 76307ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig count++ 76407ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig 765c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 766c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 767c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_attach_transport -- instantiate SAS transport template 768c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @ft: SAS transport class function template 769c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 770c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstruct scsi_transport_template * 771c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigsas_attach_transport(struct sas_function_template *ft) 772c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 773c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_internal *i; 774c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int count; 775c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 776c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i = kmalloc(sizeof(struct sas_internal), GFP_KERNEL); 777c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (!i) 778c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return NULL; 779c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig memset(i, 0, sizeof(struct sas_internal)); 780c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 781c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->t.target_parent = sas_target_parent; 782c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 783c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 784c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->t.host_attrs.ac.class = &sas_host_class.class; 785c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->t.host_attrs.ac.match = sas_host_match; 786c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_container_register(&i->t.host_attrs); 787c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->t.host_size = sizeof(struct sas_host_attrs); 788c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 789c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->phy_attr_cont.ac.class = &sas_phy_class.class; 790c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->phy_attr_cont.ac.attrs = &i->phy_attrs[0]; 791c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->phy_attr_cont.ac.match = sas_phy_match; 792c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_container_register(&i->phy_attr_cont); 793c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 794c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->rphy_attr_cont.ac.class = &sas_rphy_class.class; 795c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; 796c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->rphy_attr_cont.ac.match = sas_rphy_match; 797c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_container_register(&i->rphy_attr_cont); 798c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 799c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->f = ft; 800c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 801c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig count = 0; 802c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->host_attrs[count] = NULL; 803c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 804c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig count = 0; 805c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(initiator_port_protocols); 806c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(target_port_protocols); 807c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(device_type); 808c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(sas_address); 809c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(phy_identifier); 810c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(port_identifier); 811c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(negotiated_linkrate); 812c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw); 813c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(minimum_linkrate); 814c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw); 815c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_PORT_ATTRIBUTE(maximum_linkrate); 816c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig 817c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig SETUP_PORT_ATTRIBUTE(invalid_dword_count); 818c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig SETUP_PORT_ATTRIBUTE(running_disparity_error_count); 819c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); 820c3ee74c4e91017169c7f1fa74a57ba8502ec49c3Christoph Hellwig SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); 82107ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig SETUP_PORT_ATTRIBUTE_WRONLY(link_reset); 82207ba3a954714da10cbd3f6249d93ac2c1df72c4fChristoph Hellwig SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset); 823c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->phy_attrs[count] = NULL; 824c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 825c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig count = 0; 826c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); 827c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); 828c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_RPORT_ATTRIBUTE(rphy_device_type); 829c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_RPORT_ATTRIBUTE(rphy_sas_address); 830c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier); 831c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig i->rphy_attrs[count] = NULL; 832c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 833c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return &i->t; 834c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 835c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_attach_transport); 836c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 837c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig/** 838c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * sas_release_transport -- release SAS transport template instance 839c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig * @t: transport template instance 840c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig */ 841c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigvoid sas_release_transport(struct scsi_transport_template *t) 842c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 843c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig struct sas_internal *i = to_sas_internal(t); 844c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 845c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_container_unregister(&i->t.host_attrs); 846c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_container_unregister(&i->phy_attr_cont); 847c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_container_unregister(&i->rphy_attr_cont); 848c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 849c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig kfree(i); 850c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 851c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigEXPORT_SYMBOL(sas_release_transport); 852c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 853c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic __init int sas_transport_init(void) 854c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 855c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig int error; 856c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 857c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig error = transport_class_register(&sas_host_class); 858c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (error) 859c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig goto out; 860c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig error = transport_class_register(&sas_phy_class); 861c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (error) 862c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig goto out_unregister_transport; 863c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig error = transport_class_register(&sas_rphy_class); 864c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig if (error) 865c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig goto out_unregister_phy; 866c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 867c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return 0; 868c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 869c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig out_unregister_phy: 870c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_class_unregister(&sas_phy_class); 871c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig out_unregister_transport: 872c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_class_unregister(&sas_host_class); 873c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig out: 874c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig return error; 875c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 876c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 877c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 878c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigstatic void __exit sas_transport_exit(void) 879c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig{ 880c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_class_unregister(&sas_host_class); 881c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_class_unregister(&sas_phy_class); 882c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig transport_class_unregister(&sas_rphy_class); 883c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig} 884c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 885c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigMODULE_AUTHOR("Christoph Hellwig"); 886c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigMODULE_DESCRIPTION("SAS Transphy Attributes"); 887c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph HellwigMODULE_LICENSE("GPL"); 888c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwig 889c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigmodule_init(sas_transport_init); 890c7ebbbce366c02e5657ac6b6059933fe0353b175Christoph Hellwigmodule_exit(sas_transport_exit); 891