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