cachepc-linux

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

sas_expander.c (55789B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Serial Attached SCSI (SAS) Expander discovery and configuration
      4 *
      5 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
      6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
      7 *
      8 * This file is licensed under GPLv2.
      9 */
     10
     11#include <linux/scatterlist.h>
     12#include <linux/blkdev.h>
     13#include <linux/slab.h>
     14#include <asm/unaligned.h>
     15
     16#include "sas_internal.h"
     17
     18#include <scsi/sas_ata.h>
     19#include <scsi/scsi_transport.h>
     20#include <scsi/scsi_transport_sas.h>
     21#include "scsi_sas_internal.h"
     22
     23static int sas_discover_expander(struct domain_device *dev);
     24static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr);
     25static int sas_configure_phy(struct domain_device *dev, int phy_id,
     26			     u8 *sas_addr, int include);
     27static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr);
     28
     29/* ---------- SMP task management ---------- */
     30
     31/* Give it some long enough timeout. In seconds. */
     32#define SMP_TIMEOUT 10
     33
     34static int smp_execute_task_sg(struct domain_device *dev,
     35		struct scatterlist *req, struct scatterlist *resp)
     36{
     37	int res, retry;
     38	struct sas_task *task = NULL;
     39	struct sas_internal *i =
     40		to_sas_internal(dev->port->ha->core.shost->transportt);
     41	struct sas_ha_struct *ha = dev->port->ha;
     42
     43	pm_runtime_get_sync(ha->dev);
     44	mutex_lock(&dev->ex_dev.cmd_mutex);
     45	for (retry = 0; retry < 3; retry++) {
     46		if (test_bit(SAS_DEV_GONE, &dev->state)) {
     47			res = -ECOMM;
     48			break;
     49		}
     50
     51		task = sas_alloc_slow_task(GFP_KERNEL);
     52		if (!task) {
     53			res = -ENOMEM;
     54			break;
     55		}
     56		task->dev = dev;
     57		task->task_proto = dev->tproto;
     58		task->smp_task.smp_req = *req;
     59		task->smp_task.smp_resp = *resp;
     60
     61		task->task_done = sas_task_internal_done;
     62
     63		task->slow_task->timer.function = sas_task_internal_timedout;
     64		task->slow_task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
     65		add_timer(&task->slow_task->timer);
     66
     67		res = i->dft->lldd_execute_task(task, GFP_KERNEL);
     68
     69		if (res) {
     70			del_timer(&task->slow_task->timer);
     71			pr_notice("executing SMP task failed:%d\n", res);
     72			break;
     73		}
     74
     75		wait_for_completion(&task->slow_task->completion);
     76		res = -ECOMM;
     77		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
     78			pr_notice("smp task timed out or aborted\n");
     79			i->dft->lldd_abort_task(task);
     80			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
     81				pr_notice("SMP task aborted and not done\n");
     82				break;
     83			}
     84		}
     85		if (task->task_status.resp == SAS_TASK_COMPLETE &&
     86		    task->task_status.stat == SAS_SAM_STAT_GOOD) {
     87			res = 0;
     88			break;
     89		}
     90		if (task->task_status.resp == SAS_TASK_COMPLETE &&
     91		    task->task_status.stat == SAS_DATA_UNDERRUN) {
     92			/* no error, but return the number of bytes of
     93			 * underrun */
     94			res = task->task_status.residual;
     95			break;
     96		}
     97		if (task->task_status.resp == SAS_TASK_COMPLETE &&
     98		    task->task_status.stat == SAS_DATA_OVERRUN) {
     99			res = -EMSGSIZE;
    100			break;
    101		}
    102		if (task->task_status.resp == SAS_TASK_UNDELIVERED &&
    103		    task->task_status.stat == SAS_DEVICE_UNKNOWN)
    104			break;
    105		else {
    106			pr_notice("%s: task to dev %016llx response: 0x%x status 0x%x\n",
    107				  __func__,
    108				  SAS_ADDR(dev->sas_addr),
    109				  task->task_status.resp,
    110				  task->task_status.stat);
    111			sas_free_task(task);
    112			task = NULL;
    113		}
    114	}
    115	mutex_unlock(&dev->ex_dev.cmd_mutex);
    116	pm_runtime_put_sync(ha->dev);
    117
    118	BUG_ON(retry == 3 && task != NULL);
    119	sas_free_task(task);
    120	return res;
    121}
    122
    123static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
    124			    void *resp, int resp_size)
    125{
    126	struct scatterlist req_sg;
    127	struct scatterlist resp_sg;
    128
    129	sg_init_one(&req_sg, req, req_size);
    130	sg_init_one(&resp_sg, resp, resp_size);
    131	return smp_execute_task_sg(dev, &req_sg, &resp_sg);
    132}
    133
    134/* ---------- Allocations ---------- */
    135
    136static inline void *alloc_smp_req(int size)
    137{
    138	u8 *p = kzalloc(size, GFP_KERNEL);
    139	if (p)
    140		p[0] = SMP_REQUEST;
    141	return p;
    142}
    143
    144static inline void *alloc_smp_resp(int size)
    145{
    146	return kzalloc(size, GFP_KERNEL);
    147}
    148
    149static char sas_route_char(struct domain_device *dev, struct ex_phy *phy)
    150{
    151	switch (phy->routing_attr) {
    152	case TABLE_ROUTING:
    153		if (dev->ex_dev.t2t_supp)
    154			return 'U';
    155		else
    156			return 'T';
    157	case DIRECT_ROUTING:
    158		return 'D';
    159	case SUBTRACTIVE_ROUTING:
    160		return 'S';
    161	default:
    162		return '?';
    163	}
    164}
    165
    166static enum sas_device_type to_dev_type(struct discover_resp *dr)
    167{
    168	/* This is detecting a failure to transmit initial dev to host
    169	 * FIS as described in section J.5 of sas-2 r16
    170	 */
    171	if (dr->attached_dev_type == SAS_PHY_UNUSED && dr->attached_sata_dev &&
    172	    dr->linkrate >= SAS_LINK_RATE_1_5_GBPS)
    173		return SAS_SATA_PENDING;
    174	else
    175		return dr->attached_dev_type;
    176}
    177
    178static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
    179{
    180	enum sas_device_type dev_type;
    181	enum sas_linkrate linkrate;
    182	u8 sas_addr[SAS_ADDR_SIZE];
    183	struct smp_resp *resp = rsp;
    184	struct discover_resp *dr = &resp->disc;
    185	struct sas_ha_struct *ha = dev->port->ha;
    186	struct expander_device *ex = &dev->ex_dev;
    187	struct ex_phy *phy = &ex->ex_phy[phy_id];
    188	struct sas_rphy *rphy = dev->rphy;
    189	bool new_phy = !phy->phy;
    190	char *type;
    191
    192	if (new_phy) {
    193		if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)))
    194			return;
    195		phy->phy = sas_phy_alloc(&rphy->dev, phy_id);
    196
    197		/* FIXME: error_handling */
    198		BUG_ON(!phy->phy);
    199	}
    200
    201	switch (resp->result) {
    202	case SMP_RESP_PHY_VACANT:
    203		phy->phy_state = PHY_VACANT;
    204		break;
    205	default:
    206		phy->phy_state = PHY_NOT_PRESENT;
    207		break;
    208	case SMP_RESP_FUNC_ACC:
    209		phy->phy_state = PHY_EMPTY; /* do not know yet */
    210		break;
    211	}
    212
    213	/* check if anything important changed to squelch debug */
    214	dev_type = phy->attached_dev_type;
    215	linkrate  = phy->linkrate;
    216	memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
    217
    218	/* Handle vacant phy - rest of dr data is not valid so skip it */
    219	if (phy->phy_state == PHY_VACANT) {
    220		memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
    221		phy->attached_dev_type = SAS_PHY_UNUSED;
    222		if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) {
    223			phy->phy_id = phy_id;
    224			goto skip;
    225		} else
    226			goto out;
    227	}
    228
    229	phy->attached_dev_type = to_dev_type(dr);
    230	if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))
    231		goto out;
    232	phy->phy_id = phy_id;
    233	phy->linkrate = dr->linkrate;
    234	phy->attached_sata_host = dr->attached_sata_host;
    235	phy->attached_sata_dev  = dr->attached_sata_dev;
    236	phy->attached_sata_ps   = dr->attached_sata_ps;
    237	phy->attached_iproto = dr->iproto << 1;
    238	phy->attached_tproto = dr->tproto << 1;
    239	/* help some expanders that fail to zero sas_address in the 'no
    240	 * device' case
    241	 */
    242	if (phy->attached_dev_type == SAS_PHY_UNUSED ||
    243	    phy->linkrate < SAS_LINK_RATE_1_5_GBPS)
    244		memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
    245	else
    246		memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
    247	phy->attached_phy_id = dr->attached_phy_id;
    248	phy->phy_change_count = dr->change_count;
    249	phy->routing_attr = dr->routing_attr;
    250	phy->virtual = dr->virtual;
    251	phy->last_da_index = -1;
    252
    253	phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr);
    254	phy->phy->identify.device_type = dr->attached_dev_type;
    255	phy->phy->identify.initiator_port_protocols = phy->attached_iproto;
    256	phy->phy->identify.target_port_protocols = phy->attached_tproto;
    257	if (!phy->attached_tproto && dr->attached_sata_dev)
    258		phy->phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
    259	phy->phy->identify.phy_identifier = phy_id;
    260	phy->phy->minimum_linkrate_hw = dr->hmin_linkrate;
    261	phy->phy->maximum_linkrate_hw = dr->hmax_linkrate;
    262	phy->phy->minimum_linkrate = dr->pmin_linkrate;
    263	phy->phy->maximum_linkrate = dr->pmax_linkrate;
    264	phy->phy->negotiated_linkrate = phy->linkrate;
    265	phy->phy->enabled = (phy->linkrate != SAS_PHY_DISABLED);
    266
    267 skip:
    268	if (new_phy)
    269		if (sas_phy_add(phy->phy)) {
    270			sas_phy_free(phy->phy);
    271			return;
    272		}
    273
    274 out:
    275	switch (phy->attached_dev_type) {
    276	case SAS_SATA_PENDING:
    277		type = "stp pending";
    278		break;
    279	case SAS_PHY_UNUSED:
    280		type = "no device";
    281		break;
    282	case SAS_END_DEVICE:
    283		if (phy->attached_iproto) {
    284			if (phy->attached_tproto)
    285				type = "host+target";
    286			else
    287				type = "host";
    288		} else {
    289			if (dr->attached_sata_dev)
    290				type = "stp";
    291			else
    292				type = "ssp";
    293		}
    294		break;
    295	case SAS_EDGE_EXPANDER_DEVICE:
    296	case SAS_FANOUT_EXPANDER_DEVICE:
    297		type = "smp";
    298		break;
    299	default:
    300		type = "unknown";
    301	}
    302
    303	/* this routine is polled by libata error recovery so filter
    304	 * unimportant messages
    305	 */
    306	if (new_phy || phy->attached_dev_type != dev_type ||
    307	    phy->linkrate != linkrate ||
    308	    SAS_ADDR(phy->attached_sas_addr) != SAS_ADDR(sas_addr))
    309		/* pass */;
    310	else
    311		return;
    312
    313	/* if the attached device type changed and ata_eh is active,
    314	 * make sure we run revalidation when eh completes (see:
    315	 * sas_enable_revalidation)
    316	 */
    317	if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))
    318		set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending);
    319
    320	pr_debug("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n",
    321		 test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "",
    322		 SAS_ADDR(dev->sas_addr), phy->phy_id,
    323		 sas_route_char(dev, phy), phy->linkrate,
    324		 SAS_ADDR(phy->attached_sas_addr), type);
    325}
    326
    327/* check if we have an existing attached ata device on this expander phy */
    328struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
    329{
    330	struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy_id];
    331	struct domain_device *dev;
    332	struct sas_rphy *rphy;
    333
    334	if (!ex_phy->port)
    335		return NULL;
    336
    337	rphy = ex_phy->port->rphy;
    338	if (!rphy)
    339		return NULL;
    340
    341	dev = sas_find_dev_by_rphy(rphy);
    342
    343	if (dev && dev_is_sata(dev))
    344		return dev;
    345
    346	return NULL;
    347}
    348
    349#define DISCOVER_REQ_SIZE  16
    350#define DISCOVER_RESP_SIZE 56
    351
    352static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
    353				      u8 *disc_resp, int single)
    354{
    355	struct discover_resp *dr;
    356	int res;
    357
    358	disc_req[9] = single;
    359
    360	res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
    361			       disc_resp, DISCOVER_RESP_SIZE);
    362	if (res)
    363		return res;
    364	dr = &((struct smp_resp *)disc_resp)->disc;
    365	if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) {
    366		pr_notice("Found loopback topology, just ignore it!\n");
    367		return 0;
    368	}
    369	sas_set_ex_phy(dev, single, disc_resp);
    370	return 0;
    371}
    372
    373int sas_ex_phy_discover(struct domain_device *dev, int single)
    374{
    375	struct expander_device *ex = &dev->ex_dev;
    376	int  res = 0;
    377	u8   *disc_req;
    378	u8   *disc_resp;
    379
    380	disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
    381	if (!disc_req)
    382		return -ENOMEM;
    383
    384	disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
    385	if (!disc_resp) {
    386		kfree(disc_req);
    387		return -ENOMEM;
    388	}
    389
    390	disc_req[1] = SMP_DISCOVER;
    391
    392	if (0 <= single && single < ex->num_phys) {
    393		res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single);
    394	} else {
    395		int i;
    396
    397		for (i = 0; i < ex->num_phys; i++) {
    398			res = sas_ex_phy_discover_helper(dev, disc_req,
    399							 disc_resp, i);
    400			if (res)
    401				goto out_err;
    402		}
    403	}
    404out_err:
    405	kfree(disc_resp);
    406	kfree(disc_req);
    407	return res;
    408}
    409
    410static int sas_expander_discover(struct domain_device *dev)
    411{
    412	struct expander_device *ex = &dev->ex_dev;
    413	int res;
    414
    415	ex->ex_phy = kcalloc(ex->num_phys, sizeof(*ex->ex_phy), GFP_KERNEL);
    416	if (!ex->ex_phy)
    417		return -ENOMEM;
    418
    419	res = sas_ex_phy_discover(dev, -1);
    420	if (res)
    421		goto out_err;
    422
    423	return 0;
    424 out_err:
    425	kfree(ex->ex_phy);
    426	ex->ex_phy = NULL;
    427	return res;
    428}
    429
    430#define MAX_EXPANDER_PHYS 128
    431
    432static void ex_assign_report_general(struct domain_device *dev,
    433					    struct smp_resp *resp)
    434{
    435	struct report_general_resp *rg = &resp->rg;
    436
    437	dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count);
    438	dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes);
    439	dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS);
    440	dev->ex_dev.t2t_supp = rg->t2t_supp;
    441	dev->ex_dev.conf_route_table = rg->conf_route_table;
    442	dev->ex_dev.configuring = rg->configuring;
    443	memcpy(dev->ex_dev.enclosure_logical_id, rg->enclosure_logical_id, 8);
    444}
    445
    446#define RG_REQ_SIZE   8
    447#define RG_RESP_SIZE 32
    448
    449static int sas_ex_general(struct domain_device *dev)
    450{
    451	u8 *rg_req;
    452	struct smp_resp *rg_resp;
    453	int res;
    454	int i;
    455
    456	rg_req = alloc_smp_req(RG_REQ_SIZE);
    457	if (!rg_req)
    458		return -ENOMEM;
    459
    460	rg_resp = alloc_smp_resp(RG_RESP_SIZE);
    461	if (!rg_resp) {
    462		kfree(rg_req);
    463		return -ENOMEM;
    464	}
    465
    466	rg_req[1] = SMP_REPORT_GENERAL;
    467
    468	for (i = 0; i < 5; i++) {
    469		res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
    470				       RG_RESP_SIZE);
    471
    472		if (res) {
    473			pr_notice("RG to ex %016llx failed:0x%x\n",
    474				  SAS_ADDR(dev->sas_addr), res);
    475			goto out;
    476		} else if (rg_resp->result != SMP_RESP_FUNC_ACC) {
    477			pr_debug("RG:ex %016llx returned SMP result:0x%x\n",
    478				 SAS_ADDR(dev->sas_addr), rg_resp->result);
    479			res = rg_resp->result;
    480			goto out;
    481		}
    482
    483		ex_assign_report_general(dev, rg_resp);
    484
    485		if (dev->ex_dev.configuring) {
    486			pr_debug("RG: ex %016llx self-configuring...\n",
    487				 SAS_ADDR(dev->sas_addr));
    488			schedule_timeout_interruptible(5*HZ);
    489		} else
    490			break;
    491	}
    492out:
    493	kfree(rg_req);
    494	kfree(rg_resp);
    495	return res;
    496}
    497
    498static void ex_assign_manuf_info(struct domain_device *dev, void
    499					*_mi_resp)
    500{
    501	u8 *mi_resp = _mi_resp;
    502	struct sas_rphy *rphy = dev->rphy;
    503	struct sas_expander_device *edev = rphy_to_expander_device(rphy);
    504
    505	memcpy(edev->vendor_id, mi_resp + 12, SAS_EXPANDER_VENDOR_ID_LEN);
    506	memcpy(edev->product_id, mi_resp + 20, SAS_EXPANDER_PRODUCT_ID_LEN);
    507	memcpy(edev->product_rev, mi_resp + 36,
    508	       SAS_EXPANDER_PRODUCT_REV_LEN);
    509
    510	if (mi_resp[8] & 1) {
    511		memcpy(edev->component_vendor_id, mi_resp + 40,
    512		       SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
    513		edev->component_id = mi_resp[48] << 8 | mi_resp[49];
    514		edev->component_revision_id = mi_resp[50];
    515	}
    516}
    517
    518#define MI_REQ_SIZE   8
    519#define MI_RESP_SIZE 64
    520
    521static int sas_ex_manuf_info(struct domain_device *dev)
    522{
    523	u8 *mi_req;
    524	u8 *mi_resp;
    525	int res;
    526
    527	mi_req = alloc_smp_req(MI_REQ_SIZE);
    528	if (!mi_req)
    529		return -ENOMEM;
    530
    531	mi_resp = alloc_smp_resp(MI_RESP_SIZE);
    532	if (!mi_resp) {
    533		kfree(mi_req);
    534		return -ENOMEM;
    535	}
    536
    537	mi_req[1] = SMP_REPORT_MANUF_INFO;
    538
    539	res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp, MI_RESP_SIZE);
    540	if (res) {
    541		pr_notice("MI: ex %016llx failed:0x%x\n",
    542			  SAS_ADDR(dev->sas_addr), res);
    543		goto out;
    544	} else if (mi_resp[2] != SMP_RESP_FUNC_ACC) {
    545		pr_debug("MI ex %016llx returned SMP result:0x%x\n",
    546			 SAS_ADDR(dev->sas_addr), mi_resp[2]);
    547		goto out;
    548	}
    549
    550	ex_assign_manuf_info(dev, mi_resp);
    551out:
    552	kfree(mi_req);
    553	kfree(mi_resp);
    554	return res;
    555}
    556
    557#define PC_REQ_SIZE  44
    558#define PC_RESP_SIZE 8
    559
    560int sas_smp_phy_control(struct domain_device *dev, int phy_id,
    561			enum phy_func phy_func,
    562			struct sas_phy_linkrates *rates)
    563{
    564	u8 *pc_req;
    565	u8 *pc_resp;
    566	int res;
    567
    568	pc_req = alloc_smp_req(PC_REQ_SIZE);
    569	if (!pc_req)
    570		return -ENOMEM;
    571
    572	pc_resp = alloc_smp_resp(PC_RESP_SIZE);
    573	if (!pc_resp) {
    574		kfree(pc_req);
    575		return -ENOMEM;
    576	}
    577
    578	pc_req[1] = SMP_PHY_CONTROL;
    579	pc_req[9] = phy_id;
    580	pc_req[10] = phy_func;
    581	if (rates) {
    582		pc_req[32] = rates->minimum_linkrate << 4;
    583		pc_req[33] = rates->maximum_linkrate << 4;
    584	}
    585
    586	res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp, PC_RESP_SIZE);
    587	if (res) {
    588		pr_err("ex %016llx phy%02d PHY control failed: %d\n",
    589		       SAS_ADDR(dev->sas_addr), phy_id, res);
    590	} else if (pc_resp[2] != SMP_RESP_FUNC_ACC) {
    591		pr_err("ex %016llx phy%02d PHY control failed: function result 0x%x\n",
    592		       SAS_ADDR(dev->sas_addr), phy_id, pc_resp[2]);
    593		res = pc_resp[2];
    594	}
    595	kfree(pc_resp);
    596	kfree(pc_req);
    597	return res;
    598}
    599
    600static void sas_ex_disable_phy(struct domain_device *dev, int phy_id)
    601{
    602	struct expander_device *ex = &dev->ex_dev;
    603	struct ex_phy *phy = &ex->ex_phy[phy_id];
    604
    605	sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE, NULL);
    606	phy->linkrate = SAS_PHY_DISABLED;
    607}
    608
    609static void sas_ex_disable_port(struct domain_device *dev, u8 *sas_addr)
    610{
    611	struct expander_device *ex = &dev->ex_dev;
    612	int i;
    613
    614	for (i = 0; i < ex->num_phys; i++) {
    615		struct ex_phy *phy = &ex->ex_phy[i];
    616
    617		if (phy->phy_state == PHY_VACANT ||
    618		    phy->phy_state == PHY_NOT_PRESENT)
    619			continue;
    620
    621		if (SAS_ADDR(phy->attached_sas_addr) == SAS_ADDR(sas_addr))
    622			sas_ex_disable_phy(dev, i);
    623	}
    624}
    625
    626static int sas_dev_present_in_domain(struct asd_sas_port *port,
    627					    u8 *sas_addr)
    628{
    629	struct domain_device *dev;
    630
    631	if (SAS_ADDR(port->sas_addr) == SAS_ADDR(sas_addr))
    632		return 1;
    633	list_for_each_entry(dev, &port->dev_list, dev_list_node) {
    634		if (SAS_ADDR(dev->sas_addr) == SAS_ADDR(sas_addr))
    635			return 1;
    636	}
    637	return 0;
    638}
    639
    640#define RPEL_REQ_SIZE	16
    641#define RPEL_RESP_SIZE	32
    642int sas_smp_get_phy_events(struct sas_phy *phy)
    643{
    644	int res;
    645	u8 *req;
    646	u8 *resp;
    647	struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
    648	struct domain_device *dev = sas_find_dev_by_rphy(rphy);
    649
    650	req = alloc_smp_req(RPEL_REQ_SIZE);
    651	if (!req)
    652		return -ENOMEM;
    653
    654	resp = alloc_smp_resp(RPEL_RESP_SIZE);
    655	if (!resp) {
    656		kfree(req);
    657		return -ENOMEM;
    658	}
    659
    660	req[1] = SMP_REPORT_PHY_ERR_LOG;
    661	req[9] = phy->number;
    662
    663	res = smp_execute_task(dev, req, RPEL_REQ_SIZE,
    664			       resp, RPEL_RESP_SIZE);
    665
    666	if (res)
    667		goto out;
    668
    669	phy->invalid_dword_count = get_unaligned_be32(&resp[12]);
    670	phy->running_disparity_error_count = get_unaligned_be32(&resp[16]);
    671	phy->loss_of_dword_sync_count = get_unaligned_be32(&resp[20]);
    672	phy->phy_reset_problem_count = get_unaligned_be32(&resp[24]);
    673
    674 out:
    675	kfree(req);
    676	kfree(resp);
    677	return res;
    678
    679}
    680
    681#ifdef CONFIG_SCSI_SAS_ATA
    682
    683#define RPS_REQ_SIZE  16
    684#define RPS_RESP_SIZE 60
    685
    686int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
    687			    struct smp_resp *rps_resp)
    688{
    689	int res;
    690	u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
    691	u8 *resp = (u8 *)rps_resp;
    692
    693	if (!rps_req)
    694		return -ENOMEM;
    695
    696	rps_req[1] = SMP_REPORT_PHY_SATA;
    697	rps_req[9] = phy_id;
    698
    699	res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
    700			       rps_resp, RPS_RESP_SIZE);
    701
    702	/* 0x34 is the FIS type for the D2H fis.  There's a potential
    703	 * standards cockup here.  sas-2 explicitly specifies the FIS
    704	 * should be encoded so that FIS type is in resp[24].
    705	 * However, some expanders endian reverse this.  Undo the
    706	 * reversal here */
    707	if (!res && resp[27] == 0x34 && resp[24] != 0x34) {
    708		int i;
    709
    710		for (i = 0; i < 5; i++) {
    711			int j = 24 + (i*4);
    712			u8 a, b;
    713			a = resp[j + 0];
    714			b = resp[j + 1];
    715			resp[j + 0] = resp[j + 3];
    716			resp[j + 1] = resp[j + 2];
    717			resp[j + 2] = b;
    718			resp[j + 3] = a;
    719		}
    720	}
    721
    722	kfree(rps_req);
    723	return res;
    724}
    725#endif
    726
    727static void sas_ex_get_linkrate(struct domain_device *parent,
    728				       struct domain_device *child,
    729				       struct ex_phy *parent_phy)
    730{
    731	struct expander_device *parent_ex = &parent->ex_dev;
    732	struct sas_port *port;
    733	int i;
    734
    735	child->pathways = 0;
    736
    737	port = parent_phy->port;
    738
    739	for (i = 0; i < parent_ex->num_phys; i++) {
    740		struct ex_phy *phy = &parent_ex->ex_phy[i];
    741
    742		if (phy->phy_state == PHY_VACANT ||
    743		    phy->phy_state == PHY_NOT_PRESENT)
    744			continue;
    745
    746		if (SAS_ADDR(phy->attached_sas_addr) ==
    747		    SAS_ADDR(child->sas_addr)) {
    748
    749			child->min_linkrate = min(parent->min_linkrate,
    750						  phy->linkrate);
    751			child->max_linkrate = max(parent->max_linkrate,
    752						  phy->linkrate);
    753			child->pathways++;
    754			sas_port_add_phy(port, phy->phy);
    755		}
    756	}
    757	child->linkrate = min(parent_phy->linkrate, child->max_linkrate);
    758	child->pathways = min(child->pathways, parent->pathways);
    759}
    760
    761static struct domain_device *sas_ex_discover_end_dev(
    762	struct domain_device *parent, int phy_id)
    763{
    764	struct expander_device *parent_ex = &parent->ex_dev;
    765	struct ex_phy *phy = &parent_ex->ex_phy[phy_id];
    766	struct domain_device *child = NULL;
    767	struct sas_rphy *rphy;
    768	int res;
    769
    770	if (phy->attached_sata_host || phy->attached_sata_ps)
    771		return NULL;
    772
    773	child = sas_alloc_device();
    774	if (!child)
    775		return NULL;
    776
    777	kref_get(&parent->kref);
    778	child->parent = parent;
    779	child->port   = parent->port;
    780	child->iproto = phy->attached_iproto;
    781	memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
    782	sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
    783	if (!phy->port) {
    784		phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
    785		if (unlikely(!phy->port))
    786			goto out_err;
    787		if (unlikely(sas_port_add(phy->port) != 0)) {
    788			sas_port_free(phy->port);
    789			goto out_err;
    790		}
    791	}
    792	sas_ex_get_linkrate(parent, child, phy);
    793	sas_device_set_phy(child, phy->port);
    794
    795#ifdef CONFIG_SCSI_SAS_ATA
    796	if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) {
    797		if (child->linkrate > parent->min_linkrate) {
    798			struct sas_phy *cphy = child->phy;
    799			enum sas_linkrate min_prate = cphy->minimum_linkrate,
    800				parent_min_lrate = parent->min_linkrate,
    801				min_linkrate = (min_prate > parent_min_lrate) ?
    802					       parent_min_lrate : 0;
    803			struct sas_phy_linkrates rates = {
    804				.maximum_linkrate = parent->min_linkrate,
    805				.minimum_linkrate = min_linkrate,
    806			};
    807			int ret;
    808
    809			pr_notice("ex %016llx phy%02d SATA device linkrate > min pathway connection rate, attempting to lower device linkrate\n",
    810				   SAS_ADDR(child->sas_addr), phy_id);
    811			ret = sas_smp_phy_control(parent, phy_id,
    812						  PHY_FUNC_LINK_RESET, &rates);
    813			if (ret) {
    814				pr_err("ex %016llx phy%02d SATA device could not set linkrate (%d)\n",
    815				       SAS_ADDR(child->sas_addr), phy_id, ret);
    816				goto out_free;
    817			}
    818			pr_notice("ex %016llx phy%02d SATA device set linkrate successfully\n",
    819				  SAS_ADDR(child->sas_addr), phy_id);
    820			child->linkrate = child->min_linkrate;
    821		}
    822		res = sas_get_ata_info(child, phy);
    823		if (res)
    824			goto out_free;
    825
    826		sas_init_dev(child);
    827		res = sas_ata_init(child);
    828		if (res)
    829			goto out_free;
    830		rphy = sas_end_device_alloc(phy->port);
    831		if (!rphy)
    832			goto out_free;
    833		rphy->identify.phy_identifier = phy_id;
    834
    835		child->rphy = rphy;
    836		get_device(&rphy->dev);
    837
    838		list_add_tail(&child->disco_list_node, &parent->port->disco_list);
    839
    840		res = sas_discover_sata(child);
    841		if (res) {
    842			pr_notice("sas_discover_sata() for device %16llx at %016llx:%02d returned 0x%x\n",
    843				  SAS_ADDR(child->sas_addr),
    844				  SAS_ADDR(parent->sas_addr), phy_id, res);
    845			goto out_list_del;
    846		}
    847	} else
    848#endif
    849	  if (phy->attached_tproto & SAS_PROTOCOL_SSP) {
    850		child->dev_type = SAS_END_DEVICE;
    851		rphy = sas_end_device_alloc(phy->port);
    852		/* FIXME: error handling */
    853		if (unlikely(!rphy))
    854			goto out_free;
    855		child->tproto = phy->attached_tproto;
    856		sas_init_dev(child);
    857
    858		child->rphy = rphy;
    859		get_device(&rphy->dev);
    860		rphy->identify.phy_identifier = phy_id;
    861		sas_fill_in_rphy(child, rphy);
    862
    863		list_add_tail(&child->disco_list_node, &parent->port->disco_list);
    864
    865		res = sas_discover_end_dev(child);
    866		if (res) {
    867			pr_notice("sas_discover_end_dev() for device %016llx at %016llx:%02d returned 0x%x\n",
    868				  SAS_ADDR(child->sas_addr),
    869				  SAS_ADDR(parent->sas_addr), phy_id, res);
    870			goto out_list_del;
    871		}
    872	} else {
    873		pr_notice("target proto 0x%x at %016llx:0x%x not handled\n",
    874			  phy->attached_tproto, SAS_ADDR(parent->sas_addr),
    875			  phy_id);
    876		goto out_free;
    877	}
    878
    879	list_add_tail(&child->siblings, &parent_ex->children);
    880	return child;
    881
    882 out_list_del:
    883	sas_rphy_free(child->rphy);
    884	list_del(&child->disco_list_node);
    885	spin_lock_irq(&parent->port->dev_list_lock);
    886	list_del(&child->dev_list_node);
    887	spin_unlock_irq(&parent->port->dev_list_lock);
    888 out_free:
    889	sas_port_delete(phy->port);
    890 out_err:
    891	phy->port = NULL;
    892	sas_put_device(child);
    893	return NULL;
    894}
    895
    896/* See if this phy is part of a wide port */
    897static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
    898{
    899	struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
    900	int i;
    901
    902	for (i = 0; i < parent->ex_dev.num_phys; i++) {
    903		struct ex_phy *ephy = &parent->ex_dev.ex_phy[i];
    904
    905		if (ephy == phy)
    906			continue;
    907
    908		if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr,
    909			    SAS_ADDR_SIZE) && ephy->port) {
    910			sas_port_add_phy(ephy->port, phy->phy);
    911			phy->port = ephy->port;
    912			phy->phy_state = PHY_DEVICE_DISCOVERED;
    913			return true;
    914		}
    915	}
    916
    917	return false;
    918}
    919
    920static struct domain_device *sas_ex_discover_expander(
    921	struct domain_device *parent, int phy_id)
    922{
    923	struct sas_expander_device *parent_ex = rphy_to_expander_device(parent->rphy);
    924	struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
    925	struct domain_device *child = NULL;
    926	struct sas_rphy *rphy;
    927	struct sas_expander_device *edev;
    928	struct asd_sas_port *port;
    929	int res;
    930
    931	if (phy->routing_attr == DIRECT_ROUTING) {
    932		pr_warn("ex %016llx:%02d:D <--> ex %016llx:0x%x is not allowed\n",
    933			SAS_ADDR(parent->sas_addr), phy_id,
    934			SAS_ADDR(phy->attached_sas_addr),
    935			phy->attached_phy_id);
    936		return NULL;
    937	}
    938	child = sas_alloc_device();
    939	if (!child)
    940		return NULL;
    941
    942	phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
    943	/* FIXME: better error handling */
    944	BUG_ON(sas_port_add(phy->port) != 0);
    945
    946
    947	switch (phy->attached_dev_type) {
    948	case SAS_EDGE_EXPANDER_DEVICE:
    949		rphy = sas_expander_alloc(phy->port,
    950					  SAS_EDGE_EXPANDER_DEVICE);
    951		break;
    952	case SAS_FANOUT_EXPANDER_DEVICE:
    953		rphy = sas_expander_alloc(phy->port,
    954					  SAS_FANOUT_EXPANDER_DEVICE);
    955		break;
    956	default:
    957		rphy = NULL;	/* shut gcc up */
    958		BUG();
    959	}
    960	port = parent->port;
    961	child->rphy = rphy;
    962	get_device(&rphy->dev);
    963	edev = rphy_to_expander_device(rphy);
    964	child->dev_type = phy->attached_dev_type;
    965	kref_get(&parent->kref);
    966	child->parent = parent;
    967	child->port = port;
    968	child->iproto = phy->attached_iproto;
    969	child->tproto = phy->attached_tproto;
    970	memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
    971	sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
    972	sas_ex_get_linkrate(parent, child, phy);
    973	edev->level = parent_ex->level + 1;
    974	parent->port->disc.max_level = max(parent->port->disc.max_level,
    975					   edev->level);
    976	sas_init_dev(child);
    977	sas_fill_in_rphy(child, rphy);
    978	sas_rphy_add(rphy);
    979
    980	spin_lock_irq(&parent->port->dev_list_lock);
    981	list_add_tail(&child->dev_list_node, &parent->port->dev_list);
    982	spin_unlock_irq(&parent->port->dev_list_lock);
    983
    984	res = sas_discover_expander(child);
    985	if (res) {
    986		sas_rphy_delete(rphy);
    987		spin_lock_irq(&parent->port->dev_list_lock);
    988		list_del(&child->dev_list_node);
    989		spin_unlock_irq(&parent->port->dev_list_lock);
    990		sas_put_device(child);
    991		sas_port_delete(phy->port);
    992		phy->port = NULL;
    993		return NULL;
    994	}
    995	list_add_tail(&child->siblings, &parent->ex_dev.children);
    996	return child;
    997}
    998
    999static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
   1000{
   1001	struct expander_device *ex = &dev->ex_dev;
   1002	struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
   1003	struct domain_device *child = NULL;
   1004	int res = 0;
   1005
   1006	/* Phy state */
   1007	if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) {
   1008		if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET, NULL))
   1009			res = sas_ex_phy_discover(dev, phy_id);
   1010		if (res)
   1011			return res;
   1012	}
   1013
   1014	/* Parent and domain coherency */
   1015	if (!dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
   1016			     SAS_ADDR(dev->port->sas_addr))) {
   1017		sas_add_parent_port(dev, phy_id);
   1018		return 0;
   1019	}
   1020	if (dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
   1021			    SAS_ADDR(dev->parent->sas_addr))) {
   1022		sas_add_parent_port(dev, phy_id);
   1023		if (ex_phy->routing_attr == TABLE_ROUTING)
   1024			sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1);
   1025		return 0;
   1026	}
   1027
   1028	if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr))
   1029		sas_ex_disable_port(dev, ex_phy->attached_sas_addr);
   1030
   1031	if (ex_phy->attached_dev_type == SAS_PHY_UNUSED) {
   1032		if (ex_phy->routing_attr == DIRECT_ROUTING) {
   1033			memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
   1034			sas_configure_routing(dev, ex_phy->attached_sas_addr);
   1035		}
   1036		return 0;
   1037	} else if (ex_phy->linkrate == SAS_LINK_RATE_UNKNOWN)
   1038		return 0;
   1039
   1040	if (ex_phy->attached_dev_type != SAS_END_DEVICE &&
   1041	    ex_phy->attached_dev_type != SAS_FANOUT_EXPANDER_DEVICE &&
   1042	    ex_phy->attached_dev_type != SAS_EDGE_EXPANDER_DEVICE &&
   1043	    ex_phy->attached_dev_type != SAS_SATA_PENDING) {
   1044		pr_warn("unknown device type(0x%x) attached to ex %016llx phy%02d\n",
   1045			ex_phy->attached_dev_type,
   1046			SAS_ADDR(dev->sas_addr),
   1047			phy_id);
   1048		return 0;
   1049	}
   1050
   1051	res = sas_configure_routing(dev, ex_phy->attached_sas_addr);
   1052	if (res) {
   1053		pr_notice("configure routing for dev %016llx reported 0x%x. Forgotten\n",
   1054			  SAS_ADDR(ex_phy->attached_sas_addr), res);
   1055		sas_disable_routing(dev, ex_phy->attached_sas_addr);
   1056		return res;
   1057	}
   1058
   1059	if (sas_ex_join_wide_port(dev, phy_id)) {
   1060		pr_debug("Attaching ex phy%02d to wide port %016llx\n",
   1061			 phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
   1062		return res;
   1063	}
   1064
   1065	switch (ex_phy->attached_dev_type) {
   1066	case SAS_END_DEVICE:
   1067	case SAS_SATA_PENDING:
   1068		child = sas_ex_discover_end_dev(dev, phy_id);
   1069		break;
   1070	case SAS_FANOUT_EXPANDER_DEVICE:
   1071		if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) {
   1072			pr_debug("second fanout expander %016llx phy%02d attached to ex %016llx phy%02d\n",
   1073				 SAS_ADDR(ex_phy->attached_sas_addr),
   1074				 ex_phy->attached_phy_id,
   1075				 SAS_ADDR(dev->sas_addr),
   1076				 phy_id);
   1077			sas_ex_disable_phy(dev, phy_id);
   1078			return res;
   1079		} else
   1080			memcpy(dev->port->disc.fanout_sas_addr,
   1081			       ex_phy->attached_sas_addr, SAS_ADDR_SIZE);
   1082		fallthrough;
   1083	case SAS_EDGE_EXPANDER_DEVICE:
   1084		child = sas_ex_discover_expander(dev, phy_id);
   1085		break;
   1086	default:
   1087		break;
   1088	}
   1089
   1090	if (!child)
   1091		pr_notice("ex %016llx phy%02d failed to discover\n",
   1092			  SAS_ADDR(dev->sas_addr), phy_id);
   1093	return res;
   1094}
   1095
   1096static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
   1097{
   1098	struct expander_device *ex = &dev->ex_dev;
   1099	int i;
   1100
   1101	for (i = 0; i < ex->num_phys; i++) {
   1102		struct ex_phy *phy = &ex->ex_phy[i];
   1103
   1104		if (phy->phy_state == PHY_VACANT ||
   1105		    phy->phy_state == PHY_NOT_PRESENT)
   1106			continue;
   1107
   1108		if (dev_is_expander(phy->attached_dev_type) &&
   1109		    phy->routing_attr == SUBTRACTIVE_ROUTING) {
   1110
   1111			memcpy(sub_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
   1112
   1113			return 1;
   1114		}
   1115	}
   1116	return 0;
   1117}
   1118
   1119static int sas_check_level_subtractive_boundary(struct domain_device *dev)
   1120{
   1121	struct expander_device *ex = &dev->ex_dev;
   1122	struct domain_device *child;
   1123	u8 sub_addr[SAS_ADDR_SIZE] = {0, };
   1124
   1125	list_for_each_entry(child, &ex->children, siblings) {
   1126		if (!dev_is_expander(child->dev_type))
   1127			continue;
   1128		if (sub_addr[0] == 0) {
   1129			sas_find_sub_addr(child, sub_addr);
   1130			continue;
   1131		} else {
   1132			u8 s2[SAS_ADDR_SIZE];
   1133
   1134			if (sas_find_sub_addr(child, s2) &&
   1135			    (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) {
   1136
   1137				pr_notice("ex %016llx->%016llx-?->%016llx diverges from subtractive boundary %016llx\n",
   1138					  SAS_ADDR(dev->sas_addr),
   1139					  SAS_ADDR(child->sas_addr),
   1140					  SAS_ADDR(s2),
   1141					  SAS_ADDR(sub_addr));
   1142
   1143				sas_ex_disable_port(child, s2);
   1144			}
   1145		}
   1146	}
   1147	return 0;
   1148}
   1149/**
   1150 * sas_ex_discover_devices - discover devices attached to this expander
   1151 * @dev: pointer to the expander domain device
   1152 * @single: if you want to do a single phy, else set to -1;
   1153 *
   1154 * Configure this expander for use with its devices and register the
   1155 * devices of this expander.
   1156 */
   1157static int sas_ex_discover_devices(struct domain_device *dev, int single)
   1158{
   1159	struct expander_device *ex = &dev->ex_dev;
   1160	int i = 0, end = ex->num_phys;
   1161	int res = 0;
   1162
   1163	if (0 <= single && single < end) {
   1164		i = single;
   1165		end = i+1;
   1166	}
   1167
   1168	for ( ; i < end; i++) {
   1169		struct ex_phy *ex_phy = &ex->ex_phy[i];
   1170
   1171		if (ex_phy->phy_state == PHY_VACANT ||
   1172		    ex_phy->phy_state == PHY_NOT_PRESENT ||
   1173		    ex_phy->phy_state == PHY_DEVICE_DISCOVERED)
   1174			continue;
   1175
   1176		switch (ex_phy->linkrate) {
   1177		case SAS_PHY_DISABLED:
   1178		case SAS_PHY_RESET_PROBLEM:
   1179		case SAS_SATA_PORT_SELECTOR:
   1180			continue;
   1181		default:
   1182			res = sas_ex_discover_dev(dev, i);
   1183			if (res)
   1184				break;
   1185			continue;
   1186		}
   1187	}
   1188
   1189	if (!res)
   1190		sas_check_level_subtractive_boundary(dev);
   1191
   1192	return res;
   1193}
   1194
   1195static int sas_check_ex_subtractive_boundary(struct domain_device *dev)
   1196{
   1197	struct expander_device *ex = &dev->ex_dev;
   1198	int i;
   1199	u8  *sub_sas_addr = NULL;
   1200
   1201	if (dev->dev_type != SAS_EDGE_EXPANDER_DEVICE)
   1202		return 0;
   1203
   1204	for (i = 0; i < ex->num_phys; i++) {
   1205		struct ex_phy *phy = &ex->ex_phy[i];
   1206
   1207		if (phy->phy_state == PHY_VACANT ||
   1208		    phy->phy_state == PHY_NOT_PRESENT)
   1209			continue;
   1210
   1211		if (dev_is_expander(phy->attached_dev_type) &&
   1212		    phy->routing_attr == SUBTRACTIVE_ROUTING) {
   1213
   1214			if (!sub_sas_addr)
   1215				sub_sas_addr = &phy->attached_sas_addr[0];
   1216			else if (SAS_ADDR(sub_sas_addr) !=
   1217				 SAS_ADDR(phy->attached_sas_addr)) {
   1218
   1219				pr_notice("ex %016llx phy%02d diverges(%016llx) on subtractive boundary(%016llx). Disabled\n",
   1220					  SAS_ADDR(dev->sas_addr), i,
   1221					  SAS_ADDR(phy->attached_sas_addr),
   1222					  SAS_ADDR(sub_sas_addr));
   1223				sas_ex_disable_phy(dev, i);
   1224			}
   1225		}
   1226	}
   1227	return 0;
   1228}
   1229
   1230static void sas_print_parent_topology_bug(struct domain_device *child,
   1231						 struct ex_phy *parent_phy,
   1232						 struct ex_phy *child_phy)
   1233{
   1234	static const char *ex_type[] = {
   1235		[SAS_EDGE_EXPANDER_DEVICE] = "edge",
   1236		[SAS_FANOUT_EXPANDER_DEVICE] = "fanout",
   1237	};
   1238	struct domain_device *parent = child->parent;
   1239
   1240	pr_notice("%s ex %016llx phy%02d <--> %s ex %016llx phy%02d has %c:%c routing link!\n",
   1241		  ex_type[parent->dev_type],
   1242		  SAS_ADDR(parent->sas_addr),
   1243		  parent_phy->phy_id,
   1244
   1245		  ex_type[child->dev_type],
   1246		  SAS_ADDR(child->sas_addr),
   1247		  child_phy->phy_id,
   1248
   1249		  sas_route_char(parent, parent_phy),
   1250		  sas_route_char(child, child_phy));
   1251}
   1252
   1253static int sas_check_eeds(struct domain_device *child,
   1254				 struct ex_phy *parent_phy,
   1255				 struct ex_phy *child_phy)
   1256{
   1257	int res = 0;
   1258	struct domain_device *parent = child->parent;
   1259
   1260	if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) {
   1261		res = -ENODEV;
   1262		pr_warn("edge ex %016llx phy S:%02d <--> edge ex %016llx phy S:%02d, while there is a fanout ex %016llx\n",
   1263			SAS_ADDR(parent->sas_addr),
   1264			parent_phy->phy_id,
   1265			SAS_ADDR(child->sas_addr),
   1266			child_phy->phy_id,
   1267			SAS_ADDR(parent->port->disc.fanout_sas_addr));
   1268	} else if (SAS_ADDR(parent->port->disc.eeds_a) == 0) {
   1269		memcpy(parent->port->disc.eeds_a, parent->sas_addr,
   1270		       SAS_ADDR_SIZE);
   1271		memcpy(parent->port->disc.eeds_b, child->sas_addr,
   1272		       SAS_ADDR_SIZE);
   1273	} else if (((SAS_ADDR(parent->port->disc.eeds_a) ==
   1274		    SAS_ADDR(parent->sas_addr)) ||
   1275		   (SAS_ADDR(parent->port->disc.eeds_a) ==
   1276		    SAS_ADDR(child->sas_addr)))
   1277		   &&
   1278		   ((SAS_ADDR(parent->port->disc.eeds_b) ==
   1279		     SAS_ADDR(parent->sas_addr)) ||
   1280		    (SAS_ADDR(parent->port->disc.eeds_b) ==
   1281		     SAS_ADDR(child->sas_addr))))
   1282		;
   1283	else {
   1284		res = -ENODEV;
   1285		pr_warn("edge ex %016llx phy%02d <--> edge ex %016llx phy%02d link forms a third EEDS!\n",
   1286			SAS_ADDR(parent->sas_addr),
   1287			parent_phy->phy_id,
   1288			SAS_ADDR(child->sas_addr),
   1289			child_phy->phy_id);
   1290	}
   1291
   1292	return res;
   1293}
   1294
   1295/* Here we spill over 80 columns.  It is intentional.
   1296 */
   1297static int sas_check_parent_topology(struct domain_device *child)
   1298{
   1299	struct expander_device *child_ex = &child->ex_dev;
   1300	struct expander_device *parent_ex;
   1301	int i;
   1302	int res = 0;
   1303
   1304	if (!child->parent)
   1305		return 0;
   1306
   1307	if (!dev_is_expander(child->parent->dev_type))
   1308		return 0;
   1309
   1310	parent_ex = &child->parent->ex_dev;
   1311
   1312	for (i = 0; i < parent_ex->num_phys; i++) {
   1313		struct ex_phy *parent_phy = &parent_ex->ex_phy[i];
   1314		struct ex_phy *child_phy;
   1315
   1316		if (parent_phy->phy_state == PHY_VACANT ||
   1317		    parent_phy->phy_state == PHY_NOT_PRESENT)
   1318			continue;
   1319
   1320		if (SAS_ADDR(parent_phy->attached_sas_addr) != SAS_ADDR(child->sas_addr))
   1321			continue;
   1322
   1323		child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id];
   1324
   1325		switch (child->parent->dev_type) {
   1326		case SAS_EDGE_EXPANDER_DEVICE:
   1327			if (child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) {
   1328				if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING ||
   1329				    child_phy->routing_attr != TABLE_ROUTING) {
   1330					sas_print_parent_topology_bug(child, parent_phy, child_phy);
   1331					res = -ENODEV;
   1332				}
   1333			} else if (parent_phy->routing_attr == SUBTRACTIVE_ROUTING) {
   1334				if (child_phy->routing_attr == SUBTRACTIVE_ROUTING) {
   1335					res = sas_check_eeds(child, parent_phy, child_phy);
   1336				} else if (child_phy->routing_attr != TABLE_ROUTING) {
   1337					sas_print_parent_topology_bug(child, parent_phy, child_phy);
   1338					res = -ENODEV;
   1339				}
   1340			} else if (parent_phy->routing_attr == TABLE_ROUTING) {
   1341				if (child_phy->routing_attr == SUBTRACTIVE_ROUTING ||
   1342				    (child_phy->routing_attr == TABLE_ROUTING &&
   1343				     child_ex->t2t_supp && parent_ex->t2t_supp)) {
   1344					/* All good */;
   1345				} else {
   1346					sas_print_parent_topology_bug(child, parent_phy, child_phy);
   1347					res = -ENODEV;
   1348				}
   1349			}
   1350			break;
   1351		case SAS_FANOUT_EXPANDER_DEVICE:
   1352			if (parent_phy->routing_attr != TABLE_ROUTING ||
   1353			    child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
   1354				sas_print_parent_topology_bug(child, parent_phy, child_phy);
   1355				res = -ENODEV;
   1356			}
   1357			break;
   1358		default:
   1359			break;
   1360		}
   1361	}
   1362
   1363	return res;
   1364}
   1365
   1366#define RRI_REQ_SIZE  16
   1367#define RRI_RESP_SIZE 44
   1368
   1369static int sas_configure_present(struct domain_device *dev, int phy_id,
   1370				 u8 *sas_addr, int *index, int *present)
   1371{
   1372	int i, res = 0;
   1373	struct expander_device *ex = &dev->ex_dev;
   1374	struct ex_phy *phy = &ex->ex_phy[phy_id];
   1375	u8 *rri_req;
   1376	u8 *rri_resp;
   1377
   1378	*present = 0;
   1379	*index = 0;
   1380
   1381	rri_req = alloc_smp_req(RRI_REQ_SIZE);
   1382	if (!rri_req)
   1383		return -ENOMEM;
   1384
   1385	rri_resp = alloc_smp_resp(RRI_RESP_SIZE);
   1386	if (!rri_resp) {
   1387		kfree(rri_req);
   1388		return -ENOMEM;
   1389	}
   1390
   1391	rri_req[1] = SMP_REPORT_ROUTE_INFO;
   1392	rri_req[9] = phy_id;
   1393
   1394	for (i = 0; i < ex->max_route_indexes ; i++) {
   1395		*(__be16 *)(rri_req+6) = cpu_to_be16(i);
   1396		res = smp_execute_task(dev, rri_req, RRI_REQ_SIZE, rri_resp,
   1397				       RRI_RESP_SIZE);
   1398		if (res)
   1399			goto out;
   1400		res = rri_resp[2];
   1401		if (res == SMP_RESP_NO_INDEX) {
   1402			pr_warn("overflow of indexes: dev %016llx phy%02d index 0x%x\n",
   1403				SAS_ADDR(dev->sas_addr), phy_id, i);
   1404			goto out;
   1405		} else if (res != SMP_RESP_FUNC_ACC) {
   1406			pr_notice("%s: dev %016llx phy%02d index 0x%x result 0x%x\n",
   1407				  __func__, SAS_ADDR(dev->sas_addr), phy_id,
   1408				  i, res);
   1409			goto out;
   1410		}
   1411		if (SAS_ADDR(sas_addr) != 0) {
   1412			if (SAS_ADDR(rri_resp+16) == SAS_ADDR(sas_addr)) {
   1413				*index = i;
   1414				if ((rri_resp[12] & 0x80) == 0x80)
   1415					*present = 0;
   1416				else
   1417					*present = 1;
   1418				goto out;
   1419			} else if (SAS_ADDR(rri_resp+16) == 0) {
   1420				*index = i;
   1421				*present = 0;
   1422				goto out;
   1423			}
   1424		} else if (SAS_ADDR(rri_resp+16) == 0 &&
   1425			   phy->last_da_index < i) {
   1426			phy->last_da_index = i;
   1427			*index = i;
   1428			*present = 0;
   1429			goto out;
   1430		}
   1431	}
   1432	res = -1;
   1433out:
   1434	kfree(rri_req);
   1435	kfree(rri_resp);
   1436	return res;
   1437}
   1438
   1439#define CRI_REQ_SIZE  44
   1440#define CRI_RESP_SIZE  8
   1441
   1442static int sas_configure_set(struct domain_device *dev, int phy_id,
   1443			     u8 *sas_addr, int index, int include)
   1444{
   1445	int res;
   1446	u8 *cri_req;
   1447	u8 *cri_resp;
   1448
   1449	cri_req = alloc_smp_req(CRI_REQ_SIZE);
   1450	if (!cri_req)
   1451		return -ENOMEM;
   1452
   1453	cri_resp = alloc_smp_resp(CRI_RESP_SIZE);
   1454	if (!cri_resp) {
   1455		kfree(cri_req);
   1456		return -ENOMEM;
   1457	}
   1458
   1459	cri_req[1] = SMP_CONF_ROUTE_INFO;
   1460	*(__be16 *)(cri_req+6) = cpu_to_be16(index);
   1461	cri_req[9] = phy_id;
   1462	if (SAS_ADDR(sas_addr) == 0 || !include)
   1463		cri_req[12] |= 0x80;
   1464	memcpy(cri_req+16, sas_addr, SAS_ADDR_SIZE);
   1465
   1466	res = smp_execute_task(dev, cri_req, CRI_REQ_SIZE, cri_resp,
   1467			       CRI_RESP_SIZE);
   1468	if (res)
   1469		goto out;
   1470	res = cri_resp[2];
   1471	if (res == SMP_RESP_NO_INDEX) {
   1472		pr_warn("overflow of indexes: dev %016llx phy%02d index 0x%x\n",
   1473			SAS_ADDR(dev->sas_addr), phy_id, index);
   1474	}
   1475out:
   1476	kfree(cri_req);
   1477	kfree(cri_resp);
   1478	return res;
   1479}
   1480
   1481static int sas_configure_phy(struct domain_device *dev, int phy_id,
   1482				    u8 *sas_addr, int include)
   1483{
   1484	int index;
   1485	int present;
   1486	int res;
   1487
   1488	res = sas_configure_present(dev, phy_id, sas_addr, &index, &present);
   1489	if (res)
   1490		return res;
   1491	if (include ^ present)
   1492		return sas_configure_set(dev, phy_id, sas_addr, index,
   1493					 include);
   1494
   1495	return res;
   1496}
   1497
   1498/**
   1499 * sas_configure_parent - configure routing table of parent
   1500 * @parent: parent expander
   1501 * @child: child expander
   1502 * @sas_addr: SAS port identifier of device directly attached to child
   1503 * @include: whether or not to include @child in the expander routing table
   1504 */
   1505static int sas_configure_parent(struct domain_device *parent,
   1506				struct domain_device *child,
   1507				u8 *sas_addr, int include)
   1508{
   1509	struct expander_device *ex_parent = &parent->ex_dev;
   1510	int res = 0;
   1511	int i;
   1512
   1513	if (parent->parent) {
   1514		res = sas_configure_parent(parent->parent, parent, sas_addr,
   1515					   include);
   1516		if (res)
   1517			return res;
   1518	}
   1519
   1520	if (ex_parent->conf_route_table == 0) {
   1521		pr_debug("ex %016llx has self-configuring routing table\n",
   1522			 SAS_ADDR(parent->sas_addr));
   1523		return 0;
   1524	}
   1525
   1526	for (i = 0; i < ex_parent->num_phys; i++) {
   1527		struct ex_phy *phy = &ex_parent->ex_phy[i];
   1528
   1529		if ((phy->routing_attr == TABLE_ROUTING) &&
   1530		    (SAS_ADDR(phy->attached_sas_addr) ==
   1531		     SAS_ADDR(child->sas_addr))) {
   1532			res = sas_configure_phy(parent, i, sas_addr, include);
   1533			if (res)
   1534				return res;
   1535		}
   1536	}
   1537
   1538	return res;
   1539}
   1540
   1541/**
   1542 * sas_configure_routing - configure routing
   1543 * @dev: expander device
   1544 * @sas_addr: port identifier of device directly attached to the expander device
   1545 */
   1546static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
   1547{
   1548	if (dev->parent)
   1549		return sas_configure_parent(dev->parent, dev, sas_addr, 1);
   1550	return 0;
   1551}
   1552
   1553static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr)
   1554{
   1555	if (dev->parent)
   1556		return sas_configure_parent(dev->parent, dev, sas_addr, 0);
   1557	return 0;
   1558}
   1559
   1560/**
   1561 * sas_discover_expander - expander discovery
   1562 * @dev: pointer to expander domain device
   1563 *
   1564 * See comment in sas_discover_sata().
   1565 */
   1566static int sas_discover_expander(struct domain_device *dev)
   1567{
   1568	int res;
   1569
   1570	res = sas_notify_lldd_dev_found(dev);
   1571	if (res)
   1572		return res;
   1573
   1574	res = sas_ex_general(dev);
   1575	if (res)
   1576		goto out_err;
   1577	res = sas_ex_manuf_info(dev);
   1578	if (res)
   1579		goto out_err;
   1580
   1581	res = sas_expander_discover(dev);
   1582	if (res) {
   1583		pr_warn("expander %016llx discovery failed(0x%x)\n",
   1584			SAS_ADDR(dev->sas_addr), res);
   1585		goto out_err;
   1586	}
   1587
   1588	sas_check_ex_subtractive_boundary(dev);
   1589	res = sas_check_parent_topology(dev);
   1590	if (res)
   1591		goto out_err;
   1592	return 0;
   1593out_err:
   1594	sas_notify_lldd_dev_gone(dev);
   1595	return res;
   1596}
   1597
   1598static int sas_ex_level_discovery(struct asd_sas_port *port, const int level)
   1599{
   1600	int res = 0;
   1601	struct domain_device *dev;
   1602
   1603	list_for_each_entry(dev, &port->dev_list, dev_list_node) {
   1604		if (dev_is_expander(dev->dev_type)) {
   1605			struct sas_expander_device *ex =
   1606				rphy_to_expander_device(dev->rphy);
   1607
   1608			if (level == ex->level)
   1609				res = sas_ex_discover_devices(dev, -1);
   1610			else if (level > 0)
   1611				res = sas_ex_discover_devices(port->port_dev, -1);
   1612
   1613		}
   1614	}
   1615
   1616	return res;
   1617}
   1618
   1619static int sas_ex_bfs_disc(struct asd_sas_port *port)
   1620{
   1621	int res;
   1622	int level;
   1623
   1624	do {
   1625		level = port->disc.max_level;
   1626		res = sas_ex_level_discovery(port, level);
   1627		mb();
   1628	} while (level < port->disc.max_level);
   1629
   1630	return res;
   1631}
   1632
   1633int sas_discover_root_expander(struct domain_device *dev)
   1634{
   1635	int res;
   1636	struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
   1637
   1638	res = sas_rphy_add(dev->rphy);
   1639	if (res)
   1640		goto out_err;
   1641
   1642	ex->level = dev->port->disc.max_level; /* 0 */
   1643	res = sas_discover_expander(dev);
   1644	if (res)
   1645		goto out_err2;
   1646
   1647	sas_ex_bfs_disc(dev->port);
   1648
   1649	return res;
   1650
   1651out_err2:
   1652	sas_rphy_remove(dev->rphy);
   1653out_err:
   1654	return res;
   1655}
   1656
   1657/* ---------- Domain revalidation ---------- */
   1658
   1659static int sas_get_phy_discover(struct domain_device *dev,
   1660				int phy_id, struct smp_resp *disc_resp)
   1661{
   1662	int res;
   1663	u8 *disc_req;
   1664
   1665	disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
   1666	if (!disc_req)
   1667		return -ENOMEM;
   1668
   1669	disc_req[1] = SMP_DISCOVER;
   1670	disc_req[9] = phy_id;
   1671
   1672	res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
   1673			       disc_resp, DISCOVER_RESP_SIZE);
   1674	if (res)
   1675		goto out;
   1676	else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
   1677		res = disc_resp->result;
   1678		goto out;
   1679	}
   1680out:
   1681	kfree(disc_req);
   1682	return res;
   1683}
   1684
   1685static int sas_get_phy_change_count(struct domain_device *dev,
   1686				    int phy_id, int *pcc)
   1687{
   1688	int res;
   1689	struct smp_resp *disc_resp;
   1690
   1691	disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
   1692	if (!disc_resp)
   1693		return -ENOMEM;
   1694
   1695	res = sas_get_phy_discover(dev, phy_id, disc_resp);
   1696	if (!res)
   1697		*pcc = disc_resp->disc.change_count;
   1698
   1699	kfree(disc_resp);
   1700	return res;
   1701}
   1702
   1703static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
   1704				    u8 *sas_addr, enum sas_device_type *type)
   1705{
   1706	int res;
   1707	struct smp_resp *disc_resp;
   1708	struct discover_resp *dr;
   1709
   1710	disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
   1711	if (!disc_resp)
   1712		return -ENOMEM;
   1713	dr = &disc_resp->disc;
   1714
   1715	res = sas_get_phy_discover(dev, phy_id, disc_resp);
   1716	if (res == 0) {
   1717		memcpy(sas_addr, disc_resp->disc.attached_sas_addr,
   1718		       SAS_ADDR_SIZE);
   1719		*type = to_dev_type(dr);
   1720		if (*type == 0)
   1721			memset(sas_addr, 0, SAS_ADDR_SIZE);
   1722	}
   1723	kfree(disc_resp);
   1724	return res;
   1725}
   1726
   1727static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
   1728			      int from_phy, bool update)
   1729{
   1730	struct expander_device *ex = &dev->ex_dev;
   1731	int res = 0;
   1732	int i;
   1733
   1734	for (i = from_phy; i < ex->num_phys; i++) {
   1735		int phy_change_count = 0;
   1736
   1737		res = sas_get_phy_change_count(dev, i, &phy_change_count);
   1738		switch (res) {
   1739		case SMP_RESP_PHY_VACANT:
   1740		case SMP_RESP_NO_PHY:
   1741			continue;
   1742		case SMP_RESP_FUNC_ACC:
   1743			break;
   1744		default:
   1745			return res;
   1746		}
   1747
   1748		if (phy_change_count != ex->ex_phy[i].phy_change_count) {
   1749			if (update)
   1750				ex->ex_phy[i].phy_change_count =
   1751					phy_change_count;
   1752			*phy_id = i;
   1753			return 0;
   1754		}
   1755	}
   1756	return 0;
   1757}
   1758
   1759static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
   1760{
   1761	int res;
   1762	u8  *rg_req;
   1763	struct smp_resp  *rg_resp;
   1764
   1765	rg_req = alloc_smp_req(RG_REQ_SIZE);
   1766	if (!rg_req)
   1767		return -ENOMEM;
   1768
   1769	rg_resp = alloc_smp_resp(RG_RESP_SIZE);
   1770	if (!rg_resp) {
   1771		kfree(rg_req);
   1772		return -ENOMEM;
   1773	}
   1774
   1775	rg_req[1] = SMP_REPORT_GENERAL;
   1776
   1777	res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
   1778			       RG_RESP_SIZE);
   1779	if (res)
   1780		goto out;
   1781	if (rg_resp->result != SMP_RESP_FUNC_ACC) {
   1782		res = rg_resp->result;
   1783		goto out;
   1784	}
   1785
   1786	*ecc = be16_to_cpu(rg_resp->rg.change_count);
   1787out:
   1788	kfree(rg_resp);
   1789	kfree(rg_req);
   1790	return res;
   1791}
   1792/**
   1793 * sas_find_bcast_dev -  find the device issue BROADCAST(CHANGE).
   1794 * @dev:domain device to be detect.
   1795 * @src_dev: the device which originated BROADCAST(CHANGE).
   1796 *
   1797 * Add self-configuration expander support. Suppose two expander cascading,
   1798 * when the first level expander is self-configuring, hotplug the disks in
   1799 * second level expander, BROADCAST(CHANGE) will not only be originated
   1800 * in the second level expander, but also be originated in the first level
   1801 * expander (see SAS protocol SAS 2r-14, 7.11 for detail), it is to say,
   1802 * expander changed count in two level expanders will all increment at least
   1803 * once, but the phy which chang count has changed is the source device which
   1804 * we concerned.
   1805 */
   1806
   1807static int sas_find_bcast_dev(struct domain_device *dev,
   1808			      struct domain_device **src_dev)
   1809{
   1810	struct expander_device *ex = &dev->ex_dev;
   1811	int ex_change_count = -1;
   1812	int phy_id = -1;
   1813	int res;
   1814	struct domain_device *ch;
   1815
   1816	res = sas_get_ex_change_count(dev, &ex_change_count);
   1817	if (res)
   1818		goto out;
   1819	if (ex_change_count != -1 && ex_change_count != ex->ex_change_count) {
   1820		/* Just detect if this expander phys phy change count changed,
   1821		* in order to determine if this expander originate BROADCAST,
   1822		* and do not update phy change count field in our structure.
   1823		*/
   1824		res = sas_find_bcast_phy(dev, &phy_id, 0, false);
   1825		if (phy_id != -1) {
   1826			*src_dev = dev;
   1827			ex->ex_change_count = ex_change_count;
   1828			pr_info("ex %016llx phy%02d change count has changed\n",
   1829				SAS_ADDR(dev->sas_addr), phy_id);
   1830			return res;
   1831		} else
   1832			pr_info("ex %016llx phys DID NOT change\n",
   1833				SAS_ADDR(dev->sas_addr));
   1834	}
   1835	list_for_each_entry(ch, &ex->children, siblings) {
   1836		if (dev_is_expander(ch->dev_type)) {
   1837			res = sas_find_bcast_dev(ch, src_dev);
   1838			if (*src_dev)
   1839				return res;
   1840		}
   1841	}
   1842out:
   1843	return res;
   1844}
   1845
   1846static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_device *dev)
   1847{
   1848	struct expander_device *ex = &dev->ex_dev;
   1849	struct domain_device *child, *n;
   1850
   1851	list_for_each_entry_safe(child, n, &ex->children, siblings) {
   1852		set_bit(SAS_DEV_GONE, &child->state);
   1853		if (dev_is_expander(child->dev_type))
   1854			sas_unregister_ex_tree(port, child);
   1855		else
   1856			sas_unregister_dev(port, child);
   1857	}
   1858	sas_unregister_dev(port, dev);
   1859}
   1860
   1861static void sas_unregister_devs_sas_addr(struct domain_device *parent,
   1862					 int phy_id, bool last)
   1863{
   1864	struct expander_device *ex_dev = &parent->ex_dev;
   1865	struct ex_phy *phy = &ex_dev->ex_phy[phy_id];
   1866	struct domain_device *child, *n, *found = NULL;
   1867	if (last) {
   1868		list_for_each_entry_safe(child, n,
   1869			&ex_dev->children, siblings) {
   1870			if (SAS_ADDR(child->sas_addr) ==
   1871			    SAS_ADDR(phy->attached_sas_addr)) {
   1872				set_bit(SAS_DEV_GONE, &child->state);
   1873				if (dev_is_expander(child->dev_type))
   1874					sas_unregister_ex_tree(parent->port, child);
   1875				else
   1876					sas_unregister_dev(parent->port, child);
   1877				found = child;
   1878				break;
   1879			}
   1880		}
   1881		sas_disable_routing(parent, phy->attached_sas_addr);
   1882	}
   1883	memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
   1884	if (phy->port) {
   1885		sas_port_delete_phy(phy->port, phy->phy);
   1886		sas_device_set_phy(found, phy->port);
   1887		if (phy->port->num_phys == 0)
   1888			list_add_tail(&phy->port->del_list,
   1889				&parent->port->sas_port_del_list);
   1890		phy->port = NULL;
   1891	}
   1892}
   1893
   1894static int sas_discover_bfs_by_root_level(struct domain_device *root,
   1895					  const int level)
   1896{
   1897	struct expander_device *ex_root = &root->ex_dev;
   1898	struct domain_device *child;
   1899	int res = 0;
   1900
   1901	list_for_each_entry(child, &ex_root->children, siblings) {
   1902		if (dev_is_expander(child->dev_type)) {
   1903			struct sas_expander_device *ex =
   1904				rphy_to_expander_device(child->rphy);
   1905
   1906			if (level > ex->level)
   1907				res = sas_discover_bfs_by_root_level(child,
   1908								     level);
   1909			else if (level == ex->level)
   1910				res = sas_ex_discover_devices(child, -1);
   1911		}
   1912	}
   1913	return res;
   1914}
   1915
   1916static int sas_discover_bfs_by_root(struct domain_device *dev)
   1917{
   1918	int res;
   1919	struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
   1920	int level = ex->level+1;
   1921
   1922	res = sas_ex_discover_devices(dev, -1);
   1923	if (res)
   1924		goto out;
   1925	do {
   1926		res = sas_discover_bfs_by_root_level(dev, level);
   1927		mb();
   1928		level += 1;
   1929	} while (level <= dev->port->disc.max_level);
   1930out:
   1931	return res;
   1932}
   1933
   1934static int sas_discover_new(struct domain_device *dev, int phy_id)
   1935{
   1936	struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
   1937	struct domain_device *child;
   1938	int res;
   1939
   1940	pr_debug("ex %016llx phy%02d new device attached\n",
   1941		 SAS_ADDR(dev->sas_addr), phy_id);
   1942	res = sas_ex_phy_discover(dev, phy_id);
   1943	if (res)
   1944		return res;
   1945
   1946	if (sas_ex_join_wide_port(dev, phy_id))
   1947		return 0;
   1948
   1949	res = sas_ex_discover_devices(dev, phy_id);
   1950	if (res)
   1951		return res;
   1952	list_for_each_entry(child, &dev->ex_dev.children, siblings) {
   1953		if (SAS_ADDR(child->sas_addr) ==
   1954		    SAS_ADDR(ex_phy->attached_sas_addr)) {
   1955			if (dev_is_expander(child->dev_type))
   1956				res = sas_discover_bfs_by_root(child);
   1957			break;
   1958		}
   1959	}
   1960	return res;
   1961}
   1962
   1963static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old)
   1964{
   1965	if (old == new)
   1966		return true;
   1967
   1968	/* treat device directed resets as flutter, if we went
   1969	 * SAS_END_DEVICE to SAS_SATA_PENDING the link needs recovery
   1970	 */
   1971	if ((old == SAS_SATA_PENDING && new == SAS_END_DEVICE) ||
   1972	    (old == SAS_END_DEVICE && new == SAS_SATA_PENDING))
   1973		return true;
   1974
   1975	return false;
   1976}
   1977
   1978static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
   1979			      bool last, int sibling)
   1980{
   1981	struct expander_device *ex = &dev->ex_dev;
   1982	struct ex_phy *phy = &ex->ex_phy[phy_id];
   1983	enum sas_device_type type = SAS_PHY_UNUSED;
   1984	u8 sas_addr[SAS_ADDR_SIZE];
   1985	char msg[80] = "";
   1986	int res;
   1987
   1988	if (!last)
   1989		sprintf(msg, ", part of a wide port with phy%02d", sibling);
   1990
   1991	pr_debug("ex %016llx rediscovering phy%02d%s\n",
   1992		 SAS_ADDR(dev->sas_addr), phy_id, msg);
   1993
   1994	memset(sas_addr, 0, SAS_ADDR_SIZE);
   1995	res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type);
   1996	switch (res) {
   1997	case SMP_RESP_NO_PHY:
   1998		phy->phy_state = PHY_NOT_PRESENT;
   1999		sas_unregister_devs_sas_addr(dev, phy_id, last);
   2000		return res;
   2001	case SMP_RESP_PHY_VACANT:
   2002		phy->phy_state = PHY_VACANT;
   2003		sas_unregister_devs_sas_addr(dev, phy_id, last);
   2004		return res;
   2005	case SMP_RESP_FUNC_ACC:
   2006		break;
   2007	case -ECOMM:
   2008		break;
   2009	default:
   2010		return res;
   2011	}
   2012
   2013	if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) {
   2014		phy->phy_state = PHY_EMPTY;
   2015		sas_unregister_devs_sas_addr(dev, phy_id, last);
   2016		/*
   2017		 * Even though the PHY is empty, for convenience we discover
   2018		 * the PHY to update the PHY info, like negotiated linkrate.
   2019		 */
   2020		sas_ex_phy_discover(dev, phy_id);
   2021		return res;
   2022	} else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
   2023		   dev_type_flutter(type, phy->attached_dev_type)) {
   2024		struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
   2025		char *action = "";
   2026
   2027		sas_ex_phy_discover(dev, phy_id);
   2028
   2029		if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING)
   2030			action = ", needs recovery";
   2031		pr_debug("ex %016llx phy%02d broadcast flutter%s\n",
   2032			 SAS_ADDR(dev->sas_addr), phy_id, action);
   2033		return res;
   2034	}
   2035
   2036	/* we always have to delete the old device when we went here */
   2037	pr_info("ex %016llx phy%02d replace %016llx\n",
   2038		SAS_ADDR(dev->sas_addr), phy_id,
   2039		SAS_ADDR(phy->attached_sas_addr));
   2040	sas_unregister_devs_sas_addr(dev, phy_id, last);
   2041
   2042	return sas_discover_new(dev, phy_id);
   2043}
   2044
   2045/**
   2046 * sas_rediscover - revalidate the domain.
   2047 * @dev:domain device to be detect.
   2048 * @phy_id: the phy id will be detected.
   2049 *
   2050 * NOTE: this process _must_ quit (return) as soon as any connection
   2051 * errors are encountered.  Connection recovery is done elsewhere.
   2052 * Discover process only interrogates devices in order to discover the
   2053 * domain.For plugging out, we un-register the device only when it is
   2054 * the last phy in the port, for other phys in this port, we just delete it
   2055 * from the port.For inserting, we do discovery when it is the
   2056 * first phy,for other phys in this port, we add it to the port to
   2057 * forming the wide-port.
   2058 */
   2059static int sas_rediscover(struct domain_device *dev, const int phy_id)
   2060{
   2061	struct expander_device *ex = &dev->ex_dev;
   2062	struct ex_phy *changed_phy = &ex->ex_phy[phy_id];
   2063	int res = 0;
   2064	int i;
   2065	bool last = true;	/* is this the last phy of the port */
   2066
   2067	pr_debug("ex %016llx phy%02d originated BROADCAST(CHANGE)\n",
   2068		 SAS_ADDR(dev->sas_addr), phy_id);
   2069
   2070	if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) {
   2071		for (i = 0; i < ex->num_phys; i++) {
   2072			struct ex_phy *phy = &ex->ex_phy[i];
   2073
   2074			if (i == phy_id)
   2075				continue;
   2076			if (SAS_ADDR(phy->attached_sas_addr) ==
   2077			    SAS_ADDR(changed_phy->attached_sas_addr)) {
   2078				last = false;
   2079				break;
   2080			}
   2081		}
   2082		res = sas_rediscover_dev(dev, phy_id, last, i);
   2083	} else
   2084		res = sas_discover_new(dev, phy_id);
   2085	return res;
   2086}
   2087
   2088/**
   2089 * sas_ex_revalidate_domain - revalidate the domain
   2090 * @port_dev: port domain device.
   2091 *
   2092 * NOTE: this process _must_ quit (return) as soon as any connection
   2093 * errors are encountered.  Connection recovery is done elsewhere.
   2094 * Discover process only interrogates devices in order to discover the
   2095 * domain.
   2096 */
   2097int sas_ex_revalidate_domain(struct domain_device *port_dev)
   2098{
   2099	int res;
   2100	struct domain_device *dev = NULL;
   2101
   2102	res = sas_find_bcast_dev(port_dev, &dev);
   2103	if (res == 0 && dev) {
   2104		struct expander_device *ex = &dev->ex_dev;
   2105		int i = 0, phy_id;
   2106
   2107		do {
   2108			phy_id = -1;
   2109			res = sas_find_bcast_phy(dev, &phy_id, i, true);
   2110			if (phy_id == -1)
   2111				break;
   2112			res = sas_rediscover(dev, phy_id);
   2113			i = phy_id + 1;
   2114		} while (i < ex->num_phys);
   2115	}
   2116	return res;
   2117}
   2118
   2119void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
   2120		struct sas_rphy *rphy)
   2121{
   2122	struct domain_device *dev;
   2123	unsigned int rcvlen = 0;
   2124	int ret = -EINVAL;
   2125
   2126	/* no rphy means no smp target support (ie aic94xx host) */
   2127	if (!rphy)
   2128		return sas_smp_host_handler(job, shost);
   2129
   2130	switch (rphy->identify.device_type) {
   2131	case SAS_EDGE_EXPANDER_DEVICE:
   2132	case SAS_FANOUT_EXPANDER_DEVICE:
   2133		break;
   2134	default:
   2135		pr_err("%s: can we send a smp request to a device?\n",
   2136		       __func__);
   2137		goto out;
   2138	}
   2139
   2140	dev = sas_find_dev_by_rphy(rphy);
   2141	if (!dev) {
   2142		pr_err("%s: fail to find a domain_device?\n", __func__);
   2143		goto out;
   2144	}
   2145
   2146	/* do we need to support multiple segments? */
   2147	if (job->request_payload.sg_cnt > 1 ||
   2148	    job->reply_payload.sg_cnt > 1) {
   2149		pr_info("%s: multiple segments req %u, rsp %u\n",
   2150			__func__, job->request_payload.payload_len,
   2151			job->reply_payload.payload_len);
   2152		goto out;
   2153	}
   2154
   2155	ret = smp_execute_task_sg(dev, job->request_payload.sg_list,
   2156			job->reply_payload.sg_list);
   2157	if (ret >= 0) {
   2158		/* bsg_job_done() requires the length received  */
   2159		rcvlen = job->reply_payload.payload_len - ret;
   2160		ret = 0;
   2161	}
   2162
   2163out:
   2164	bsg_job_done(job, ret, rcvlen);
   2165}