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