xref: /linux/drivers/scsi/libsas/sas_expander.c (revision 99b5aa3c10c7cff1e97239fda93649222fc12d25)
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/pci.h>
26 #include <linux/scatterlist.h>
27 
28 #include "sas_internal.h"
29 
30 #include <scsi/scsi_transport.h>
31 #include <scsi/scsi_transport_sas.h>
32 #include "../scsi_sas_internal.h"
33 
34 static int sas_discover_expander(struct domain_device *dev);
35 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr);
36 static int sas_configure_phy(struct domain_device *dev, int phy_id,
37 			     u8 *sas_addr, int include);
38 static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr);
39 
40 #if 0
41 /* FIXME: smp needs to migrate into the sas class */
42 static ssize_t smp_portal_read(struct kobject *, char *, loff_t, size_t);
43 static ssize_t smp_portal_write(struct kobject *, char *, loff_t, size_t);
44 #endif
45 
46 /* ---------- SMP task management ---------- */
47 
48 static void smp_task_timedout(unsigned long _task)
49 {
50 	struct sas_task *task = (void *) _task;
51 	unsigned long flags;
52 
53 	spin_lock_irqsave(&task->task_state_lock, flags);
54 	if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
55 		task->task_state_flags |= SAS_TASK_STATE_ABORTED;
56 	spin_unlock_irqrestore(&task->task_state_lock, flags);
57 
58 	complete(&task->completion);
59 }
60 
61 static void smp_task_done(struct sas_task *task)
62 {
63 	if (!del_timer(&task->timer))
64 		return;
65 	complete(&task->completion);
66 }
67 
68 /* Give it some long enough timeout. In seconds. */
69 #define SMP_TIMEOUT 10
70 
71 static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
72 			    void *resp, int resp_size)
73 {
74 	int res, retry;
75 	struct sas_task *task = NULL;
76 	struct sas_internal *i =
77 		to_sas_internal(dev->port->ha->core.shost->transportt);
78 
79 	for (retry = 0; retry < 3; retry++) {
80 		task = sas_alloc_task(GFP_KERNEL);
81 		if (!task)
82 			return -ENOMEM;
83 
84 		task->dev = dev;
85 		task->task_proto = dev->tproto;
86 		sg_init_one(&task->smp_task.smp_req, req, req_size);
87 		sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
88 
89 		task->task_done = smp_task_done;
90 
91 		task->timer.data = (unsigned long) task;
92 		task->timer.function = smp_task_timedout;
93 		task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
94 		add_timer(&task->timer);
95 
96 		res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
97 
98 		if (res) {
99 			del_timer(&task->timer);
100 			SAS_DPRINTK("executing SMP task failed:%d\n", res);
101 			goto ex_err;
102 		}
103 
104 		wait_for_completion(&task->completion);
105 		res = -ETASK;
106 		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
107 			SAS_DPRINTK("smp task timed out or aborted\n");
108 			i->dft->lldd_abort_task(task);
109 			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
110 				SAS_DPRINTK("SMP task aborted and not done\n");
111 				goto ex_err;
112 			}
113 		}
114 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
115 		    task->task_status.stat == SAM_GOOD) {
116 			res = 0;
117 			break;
118 		} else {
119 			SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
120 				    "status 0x%x\n", __FUNCTION__,
121 				    SAS_ADDR(dev->sas_addr),
122 				    task->task_status.resp,
123 				    task->task_status.stat);
124 			sas_free_task(task);
125 			task = NULL;
126 		}
127 	}
128 ex_err:
129 	BUG_ON(retry == 3 && task != NULL);
130 	if (task != NULL) {
131 		sas_free_task(task);
132 	}
133 	return res;
134 }
135 
136 /* ---------- Allocations ---------- */
137 
138 static inline void *alloc_smp_req(int size)
139 {
140 	u8 *p = kzalloc(size, GFP_KERNEL);
141 	if (p)
142 		p[0] = SMP_REQUEST;
143 	return p;
144 }
145 
146 static inline void *alloc_smp_resp(int size)
147 {
148 	return kzalloc(size, GFP_KERNEL);
149 }
150 
151 /* ---------- Expander configuration ---------- */
152 
153 static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
154 			   void *disc_resp)
155 {
156 	struct expander_device *ex = &dev->ex_dev;
157 	struct ex_phy *phy = &ex->ex_phy[phy_id];
158 	struct smp_resp *resp = disc_resp;
159 	struct discover_resp *dr = &resp->disc;
160 	struct sas_rphy *rphy = dev->rphy;
161 	int rediscover = (phy->phy != NULL);
162 
163 	if (!rediscover) {
164 		phy->phy = sas_phy_alloc(&rphy->dev, phy_id);
165 
166 		/* FIXME: error_handling */
167 		BUG_ON(!phy->phy);
168 	}
169 
170 	switch (resp->result) {
171 	case SMP_RESP_PHY_VACANT:
172 		phy->phy_state = PHY_VACANT;
173 		return;
174 	default:
175 		phy->phy_state = PHY_NOT_PRESENT;
176 		return;
177 	case SMP_RESP_FUNC_ACC:
178 		phy->phy_state = PHY_EMPTY; /* do not know yet */
179 		break;
180 	}
181 
182 	phy->phy_id = phy_id;
183 	phy->attached_dev_type = dr->attached_dev_type;
184 	phy->linkrate = dr->linkrate;
185 	phy->attached_sata_host = dr->attached_sata_host;
186 	phy->attached_sata_dev  = dr->attached_sata_dev;
187 	phy->attached_sata_ps   = dr->attached_sata_ps;
188 	phy->attached_iproto = dr->iproto << 1;
189 	phy->attached_tproto = dr->tproto << 1;
190 	memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
191 	phy->attached_phy_id = dr->attached_phy_id;
192 	phy->phy_change_count = dr->change_count;
193 	phy->routing_attr = dr->routing_attr;
194 	phy->virtual = dr->virtual;
195 	phy->last_da_index = -1;
196 
197 	phy->phy->identify.initiator_port_protocols = phy->attached_iproto;
198 	phy->phy->identify.target_port_protocols = phy->attached_tproto;
199 	phy->phy->identify.phy_identifier = phy_id;
200 	phy->phy->minimum_linkrate_hw = dr->hmin_linkrate;
201 	phy->phy->maximum_linkrate_hw = dr->hmax_linkrate;
202 	phy->phy->minimum_linkrate = dr->pmin_linkrate;
203 	phy->phy->maximum_linkrate = dr->pmax_linkrate;
204 	phy->phy->negotiated_linkrate = phy->linkrate;
205 
206 	if (!rediscover)
207 		sas_phy_add(phy->phy);
208 
209 	SAS_DPRINTK("ex %016llx phy%02d:%c attached: %016llx\n",
210 		    SAS_ADDR(dev->sas_addr), phy->phy_id,
211 		    phy->routing_attr == TABLE_ROUTING ? 'T' :
212 		    phy->routing_attr == DIRECT_ROUTING ? 'D' :
213 		    phy->routing_attr == SUBTRACTIVE_ROUTING ? 'S' : '?',
214 		    SAS_ADDR(phy->attached_sas_addr));
215 
216 	return;
217 }
218 
219 #define DISCOVER_REQ_SIZE  16
220 #define DISCOVER_RESP_SIZE 56
221 
222 static int sas_ex_phy_discover(struct domain_device *dev, int single)
223 {
224 	struct expander_device *ex = &dev->ex_dev;
225 	int  res = 0;
226 	u8   *disc_req;
227 	u8   *disc_resp;
228 
229 	disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
230 	if (!disc_req)
231 		return -ENOMEM;
232 
233 	disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE);
234 	if (!disc_resp) {
235 		kfree(disc_req);
236 		return -ENOMEM;
237 	}
238 
239 	disc_req[1] = SMP_DISCOVER;
240 
241 	if (0 <= single && single < ex->num_phys) {
242 		disc_req[9] = single;
243 		res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
244 				       disc_resp, DISCOVER_RESP_SIZE);
245 		if (res)
246 			goto out_err;
247 		sas_set_ex_phy(dev, single, disc_resp);
248 	} else {
249 		int i;
250 
251 		for (i = 0; i < ex->num_phys; i++) {
252 			disc_req[9] = i;
253 			res = smp_execute_task(dev, disc_req,
254 					       DISCOVER_REQ_SIZE, disc_resp,
255 					       DISCOVER_RESP_SIZE);
256 			if (res)
257 				goto out_err;
258 			sas_set_ex_phy(dev, i, disc_resp);
259 		}
260 	}
261 out_err:
262 	kfree(disc_resp);
263 	kfree(disc_req);
264 	return res;
265 }
266 
267 static int sas_expander_discover(struct domain_device *dev)
268 {
269 	struct expander_device *ex = &dev->ex_dev;
270 	int res = -ENOMEM;
271 
272 	ex->ex_phy = kzalloc(sizeof(*ex->ex_phy)*ex->num_phys, GFP_KERNEL);
273 	if (!ex->ex_phy)
274 		return -ENOMEM;
275 
276 	res = sas_ex_phy_discover(dev, -1);
277 	if (res)
278 		goto out_err;
279 
280 	return 0;
281  out_err:
282 	kfree(ex->ex_phy);
283 	ex->ex_phy = NULL;
284 	return res;
285 }
286 
287 #define MAX_EXPANDER_PHYS 128
288 
289 static void ex_assign_report_general(struct domain_device *dev,
290 					    struct smp_resp *resp)
291 {
292 	struct report_general_resp *rg = &resp->rg;
293 
294 	dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count);
295 	dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes);
296 	dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS);
297 	dev->ex_dev.conf_route_table = rg->conf_route_table;
298 	dev->ex_dev.configuring = rg->configuring;
299 	memcpy(dev->ex_dev.enclosure_logical_id, rg->enclosure_logical_id, 8);
300 }
301 
302 #define RG_REQ_SIZE   8
303 #define RG_RESP_SIZE 32
304 
305 static int sas_ex_general(struct domain_device *dev)
306 {
307 	u8 *rg_req;
308 	struct smp_resp *rg_resp;
309 	int res;
310 	int i;
311 
312 	rg_req = alloc_smp_req(RG_REQ_SIZE);
313 	if (!rg_req)
314 		return -ENOMEM;
315 
316 	rg_resp = alloc_smp_resp(RG_RESP_SIZE);
317 	if (!rg_resp) {
318 		kfree(rg_req);
319 		return -ENOMEM;
320 	}
321 
322 	rg_req[1] = SMP_REPORT_GENERAL;
323 
324 	for (i = 0; i < 5; i++) {
325 		res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
326 				       RG_RESP_SIZE);
327 
328 		if (res) {
329 			SAS_DPRINTK("RG to ex %016llx failed:0x%x\n",
330 				    SAS_ADDR(dev->sas_addr), res);
331 			goto out;
332 		} else if (rg_resp->result != SMP_RESP_FUNC_ACC) {
333 			SAS_DPRINTK("RG:ex %016llx returned SMP result:0x%x\n",
334 				    SAS_ADDR(dev->sas_addr), rg_resp->result);
335 			res = rg_resp->result;
336 			goto out;
337 		}
338 
339 		ex_assign_report_general(dev, rg_resp);
340 
341 		if (dev->ex_dev.configuring) {
342 			SAS_DPRINTK("RG: ex %llx self-configuring...\n",
343 				    SAS_ADDR(dev->sas_addr));
344 			schedule_timeout_interruptible(5*HZ);
345 		} else
346 			break;
347 	}
348 out:
349 	kfree(rg_req);
350 	kfree(rg_resp);
351 	return res;
352 }
353 
354 static void ex_assign_manuf_info(struct domain_device *dev, void
355 					*_mi_resp)
356 {
357 	u8 *mi_resp = _mi_resp;
358 	struct sas_rphy *rphy = dev->rphy;
359 	struct sas_expander_device *edev = rphy_to_expander_device(rphy);
360 
361 	memcpy(edev->vendor_id, mi_resp + 12, SAS_EXPANDER_VENDOR_ID_LEN);
362 	memcpy(edev->product_id, mi_resp + 20, SAS_EXPANDER_PRODUCT_ID_LEN);
363 	memcpy(edev->product_rev, mi_resp + 36,
364 	       SAS_EXPANDER_PRODUCT_REV_LEN);
365 
366 	if (mi_resp[8] & 1) {
367 		memcpy(edev->component_vendor_id, mi_resp + 40,
368 		       SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
369 		edev->component_id = mi_resp[48] << 8 | mi_resp[49];
370 		edev->component_revision_id = mi_resp[50];
371 	}
372 }
373 
374 #define MI_REQ_SIZE   8
375 #define MI_RESP_SIZE 64
376 
377 static int sas_ex_manuf_info(struct domain_device *dev)
378 {
379 	u8 *mi_req;
380 	u8 *mi_resp;
381 	int res;
382 
383 	mi_req = alloc_smp_req(MI_REQ_SIZE);
384 	if (!mi_req)
385 		return -ENOMEM;
386 
387 	mi_resp = alloc_smp_resp(MI_RESP_SIZE);
388 	if (!mi_resp) {
389 		kfree(mi_req);
390 		return -ENOMEM;
391 	}
392 
393 	mi_req[1] = SMP_REPORT_MANUF_INFO;
394 
395 	res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp,MI_RESP_SIZE);
396 	if (res) {
397 		SAS_DPRINTK("MI: ex %016llx failed:0x%x\n",
398 			    SAS_ADDR(dev->sas_addr), res);
399 		goto out;
400 	} else if (mi_resp[2] != SMP_RESP_FUNC_ACC) {
401 		SAS_DPRINTK("MI ex %016llx returned SMP result:0x%x\n",
402 			    SAS_ADDR(dev->sas_addr), mi_resp[2]);
403 		goto out;
404 	}
405 
406 	ex_assign_manuf_info(dev, mi_resp);
407 out:
408 	kfree(mi_req);
409 	kfree(mi_resp);
410 	return res;
411 }
412 
413 #define PC_REQ_SIZE  44
414 #define PC_RESP_SIZE 8
415 
416 int sas_smp_phy_control(struct domain_device *dev, int phy_id,
417 			enum phy_func phy_func,
418 			struct sas_phy_linkrates *rates)
419 {
420 	u8 *pc_req;
421 	u8 *pc_resp;
422 	int res;
423 
424 	pc_req = alloc_smp_req(PC_REQ_SIZE);
425 	if (!pc_req)
426 		return -ENOMEM;
427 
428 	pc_resp = alloc_smp_resp(PC_RESP_SIZE);
429 	if (!pc_resp) {
430 		kfree(pc_req);
431 		return -ENOMEM;
432 	}
433 
434 	pc_req[1] = SMP_PHY_CONTROL;
435 	pc_req[9] = phy_id;
436 	pc_req[10]= phy_func;
437 	if (rates) {
438 		pc_req[32] = rates->minimum_linkrate << 4;
439 		pc_req[33] = rates->maximum_linkrate << 4;
440 	}
441 
442 	res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE);
443 
444 	kfree(pc_resp);
445 	kfree(pc_req);
446 	return res;
447 }
448 
449 static void sas_ex_disable_phy(struct domain_device *dev, int phy_id)
450 {
451 	struct expander_device *ex = &dev->ex_dev;
452 	struct ex_phy *phy = &ex->ex_phy[phy_id];
453 
454 	sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE, NULL);
455 	phy->linkrate = SAS_PHY_DISABLED;
456 }
457 
458 static void sas_ex_disable_port(struct domain_device *dev, u8 *sas_addr)
459 {
460 	struct expander_device *ex = &dev->ex_dev;
461 	int i;
462 
463 	for (i = 0; i < ex->num_phys; i++) {
464 		struct ex_phy *phy = &ex->ex_phy[i];
465 
466 		if (phy->phy_state == PHY_VACANT ||
467 		    phy->phy_state == PHY_NOT_PRESENT)
468 			continue;
469 
470 		if (SAS_ADDR(phy->attached_sas_addr) == SAS_ADDR(sas_addr))
471 			sas_ex_disable_phy(dev, i);
472 	}
473 }
474 
475 static int sas_dev_present_in_domain(struct asd_sas_port *port,
476 					    u8 *sas_addr)
477 {
478 	struct domain_device *dev;
479 
480 	if (SAS_ADDR(port->sas_addr) == SAS_ADDR(sas_addr))
481 		return 1;
482 	list_for_each_entry(dev, &port->dev_list, dev_list_node) {
483 		if (SAS_ADDR(dev->sas_addr) == SAS_ADDR(sas_addr))
484 			return 1;
485 	}
486 	return 0;
487 }
488 
489 #define RPEL_REQ_SIZE	16
490 #define RPEL_RESP_SIZE	32
491 int sas_smp_get_phy_events(struct sas_phy *phy)
492 {
493 	int res;
494 	struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
495 	struct domain_device *dev = sas_find_dev_by_rphy(rphy);
496 	u8 *req = alloc_smp_req(RPEL_REQ_SIZE);
497 	u8 *resp = kzalloc(RPEL_RESP_SIZE, GFP_KERNEL);
498 
499 	if (!resp)
500 		return -ENOMEM;
501 
502 	req[1] = SMP_REPORT_PHY_ERR_LOG;
503 	req[9] = phy->number;
504 
505 	res = smp_execute_task(dev, req, RPEL_REQ_SIZE,
506 			            resp, RPEL_RESP_SIZE);
507 
508 	if (!res)
509 		goto out;
510 
511 	phy->invalid_dword_count = scsi_to_u32(&resp[12]);
512 	phy->running_disparity_error_count = scsi_to_u32(&resp[16]);
513 	phy->loss_of_dword_sync_count = scsi_to_u32(&resp[20]);
514 	phy->phy_reset_problem_count = scsi_to_u32(&resp[24]);
515 
516  out:
517 	kfree(resp);
518 	return res;
519 
520 }
521 
522 #define RPS_REQ_SIZE  16
523 #define RPS_RESP_SIZE 60
524 
525 static int sas_get_report_phy_sata(struct domain_device *dev,
526 					  int phy_id,
527 					  struct smp_resp *rps_resp)
528 {
529 	int res;
530 	u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
531 
532 	if (!rps_req)
533 		return -ENOMEM;
534 
535 	rps_req[1] = SMP_REPORT_PHY_SATA;
536 	rps_req[9] = phy_id;
537 
538 	res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
539 			            rps_resp, RPS_RESP_SIZE);
540 
541 	kfree(rps_req);
542 	return 0;
543 }
544 
545 static void sas_ex_get_linkrate(struct domain_device *parent,
546 				       struct domain_device *child,
547 				       struct ex_phy *parent_phy)
548 {
549 	struct expander_device *parent_ex = &parent->ex_dev;
550 	struct sas_port *port;
551 	int i;
552 
553 	child->pathways = 0;
554 
555 	port = parent_phy->port;
556 
557 	for (i = 0; i < parent_ex->num_phys; i++) {
558 		struct ex_phy *phy = &parent_ex->ex_phy[i];
559 
560 		if (phy->phy_state == PHY_VACANT ||
561 		    phy->phy_state == PHY_NOT_PRESENT)
562 			continue;
563 
564 		if (SAS_ADDR(phy->attached_sas_addr) ==
565 		    SAS_ADDR(child->sas_addr)) {
566 
567 			child->min_linkrate = min(parent->min_linkrate,
568 						  phy->linkrate);
569 			child->max_linkrate = max(parent->max_linkrate,
570 						  phy->linkrate);
571 			child->pathways++;
572 			sas_port_add_phy(port, phy->phy);
573 		}
574 	}
575 	child->linkrate = min(parent_phy->linkrate, child->max_linkrate);
576 	child->pathways = min(child->pathways, parent->pathways);
577 }
578 
579 static struct domain_device *sas_ex_discover_end_dev(
580 	struct domain_device *parent, int phy_id)
581 {
582 	struct expander_device *parent_ex = &parent->ex_dev;
583 	struct ex_phy *phy = &parent_ex->ex_phy[phy_id];
584 	struct domain_device *child = NULL;
585 	struct sas_rphy *rphy;
586 	int res;
587 
588 	if (phy->attached_sata_host || phy->attached_sata_ps)
589 		return NULL;
590 
591 	child = kzalloc(sizeof(*child), GFP_KERNEL);
592 	if (!child)
593 		return NULL;
594 
595 	child->parent = parent;
596 	child->port   = parent->port;
597 	child->iproto = phy->attached_iproto;
598 	memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
599 	sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
600 	if (!phy->port) {
601 		phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
602 		if (unlikely(!phy->port))
603 			goto out_err;
604 		if (unlikely(sas_port_add(phy->port) != 0)) {
605 			sas_port_free(phy->port);
606 			goto out_err;
607 		}
608 	}
609 	sas_ex_get_linkrate(parent, child, phy);
610 
611 	if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
612 		child->dev_type = SATA_DEV;
613 		if (phy->attached_tproto & SAS_PROTO_STP)
614 			child->tproto = phy->attached_tproto;
615 		if (phy->attached_sata_dev)
616 			child->tproto |= SATA_DEV;
617 		res = sas_get_report_phy_sata(parent, phy_id,
618 					      &child->sata_dev.rps_resp);
619 		if (res) {
620 			SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
621 				    "0x%x\n", SAS_ADDR(parent->sas_addr),
622 				    phy_id, res);
623 			goto out_free;
624 		}
625 		memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
626 		       sizeof(struct dev_to_host_fis));
627 		sas_init_dev(child);
628 		res = sas_discover_sata(child);
629 		if (res) {
630 			SAS_DPRINTK("sas_discover_sata() for device %16llx at "
631 				    "%016llx:0x%x returned 0x%x\n",
632 				    SAS_ADDR(child->sas_addr),
633 				    SAS_ADDR(parent->sas_addr), phy_id, res);
634 			goto out_free;
635 		}
636 	} else if (phy->attached_tproto & SAS_PROTO_SSP) {
637 		child->dev_type = SAS_END_DEV;
638 		rphy = sas_end_device_alloc(phy->port);
639 		/* FIXME: error handling */
640 		if (unlikely(!rphy))
641 			goto out_free;
642 		child->tproto = phy->attached_tproto;
643 		sas_init_dev(child);
644 
645 		child->rphy = rphy;
646 		sas_fill_in_rphy(child, rphy);
647 
648 		spin_lock(&parent->port->dev_list_lock);
649 		list_add_tail(&child->dev_list_node, &parent->port->dev_list);
650 		spin_unlock(&parent->port->dev_list_lock);
651 
652 		res = sas_discover_end_dev(child);
653 		if (res) {
654 			SAS_DPRINTK("sas_discover_end_dev() for device %16llx "
655 				    "at %016llx:0x%x returned 0x%x\n",
656 				    SAS_ADDR(child->sas_addr),
657 				    SAS_ADDR(parent->sas_addr), phy_id, res);
658 			goto out_list_del;
659 		}
660 	} else {
661 		SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
662 			    phy->attached_tproto, SAS_ADDR(parent->sas_addr),
663 			    phy_id);
664 	}
665 
666 	list_add_tail(&child->siblings, &parent_ex->children);
667 	return child;
668 
669  out_list_del:
670 	list_del(&child->dev_list_node);
671 	sas_rphy_free(rphy);
672  out_free:
673 	sas_port_delete(phy->port);
674  out_err:
675 	phy->port = NULL;
676 	kfree(child);
677 	return NULL;
678 }
679 
680 static struct domain_device *sas_ex_discover_expander(
681 	struct domain_device *parent, int phy_id)
682 {
683 	struct sas_expander_device *parent_ex = rphy_to_expander_device(parent->rphy);
684 	struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
685 	struct domain_device *child = NULL;
686 	struct sas_rphy *rphy;
687 	struct sas_expander_device *edev;
688 	struct asd_sas_port *port;
689 	int res;
690 
691 	if (phy->routing_attr == DIRECT_ROUTING) {
692 		SAS_DPRINTK("ex %016llx:0x%x:D <--> ex %016llx:0x%x is not "
693 			    "allowed\n",
694 			    SAS_ADDR(parent->sas_addr), phy_id,
695 			    SAS_ADDR(phy->attached_sas_addr),
696 			    phy->attached_phy_id);
697 		return NULL;
698 	}
699 	child = kzalloc(sizeof(*child), GFP_KERNEL);
700 	if (!child)
701 		return NULL;
702 
703 	phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
704 	/* FIXME: better error handling */
705 	BUG_ON(sas_port_add(phy->port) != 0);
706 
707 
708 	switch (phy->attached_dev_type) {
709 	case EDGE_DEV:
710 		rphy = sas_expander_alloc(phy->port,
711 					  SAS_EDGE_EXPANDER_DEVICE);
712 		break;
713 	case FANOUT_DEV:
714 		rphy = sas_expander_alloc(phy->port,
715 					  SAS_FANOUT_EXPANDER_DEVICE);
716 		break;
717 	default:
718 		rphy = NULL;	/* shut gcc up */
719 		BUG();
720 	}
721 	port = parent->port;
722 	child->rphy = rphy;
723 	edev = rphy_to_expander_device(rphy);
724 	child->dev_type = phy->attached_dev_type;
725 	child->parent = parent;
726 	child->port = port;
727 	child->iproto = phy->attached_iproto;
728 	child->tproto = phy->attached_tproto;
729 	memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
730 	sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
731 	sas_ex_get_linkrate(parent, child, phy);
732 	edev->level = parent_ex->level + 1;
733 	parent->port->disc.max_level = max(parent->port->disc.max_level,
734 					   edev->level);
735 	sas_init_dev(child);
736 	sas_fill_in_rphy(child, rphy);
737 	sas_rphy_add(rphy);
738 
739 	spin_lock(&parent->port->dev_list_lock);
740 	list_add_tail(&child->dev_list_node, &parent->port->dev_list);
741 	spin_unlock(&parent->port->dev_list_lock);
742 
743 	res = sas_discover_expander(child);
744 	if (res) {
745 		kfree(child);
746 		return NULL;
747 	}
748 	list_add_tail(&child->siblings, &parent->ex_dev.children);
749 	return child;
750 }
751 
752 static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
753 {
754 	struct expander_device *ex = &dev->ex_dev;
755 	struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
756 	struct domain_device *child = NULL;
757 	int res = 0;
758 
759 	/* Phy state */
760 	if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) {
761 		if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET, NULL))
762 			res = sas_ex_phy_discover(dev, phy_id);
763 		if (res)
764 			return res;
765 	}
766 
767 	/* Parent and domain coherency */
768 	if (!dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
769 			     SAS_ADDR(dev->port->sas_addr))) {
770 		sas_add_parent_port(dev, phy_id);
771 		return 0;
772 	}
773 	if (dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
774 			    SAS_ADDR(dev->parent->sas_addr))) {
775 		sas_add_parent_port(dev, phy_id);
776 		if (ex_phy->routing_attr == TABLE_ROUTING)
777 			sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1);
778 		return 0;
779 	}
780 
781 	if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr))
782 		sas_ex_disable_port(dev, ex_phy->attached_sas_addr);
783 
784 	if (ex_phy->attached_dev_type == NO_DEVICE) {
785 		if (ex_phy->routing_attr == DIRECT_ROUTING) {
786 			memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
787 			sas_configure_routing(dev, ex_phy->attached_sas_addr);
788 		}
789 		return 0;
790 	} else if (ex_phy->linkrate == SAS_LINK_RATE_UNKNOWN)
791 		return 0;
792 
793 	if (ex_phy->attached_dev_type != SAS_END_DEV &&
794 	    ex_phy->attached_dev_type != FANOUT_DEV &&
795 	    ex_phy->attached_dev_type != EDGE_DEV) {
796 		SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx "
797 			    "phy 0x%x\n", ex_phy->attached_dev_type,
798 			    SAS_ADDR(dev->sas_addr),
799 			    phy_id);
800 		return 0;
801 	}
802 
803 	res = sas_configure_routing(dev, ex_phy->attached_sas_addr);
804 	if (res) {
805 		SAS_DPRINTK("configure routing for dev %016llx "
806 			    "reported 0x%x. Forgotten\n",
807 			    SAS_ADDR(ex_phy->attached_sas_addr), res);
808 		sas_disable_routing(dev, ex_phy->attached_sas_addr);
809 		return res;
810 	}
811 
812 	switch (ex_phy->attached_dev_type) {
813 	case SAS_END_DEV:
814 		child = sas_ex_discover_end_dev(dev, phy_id);
815 		break;
816 	case FANOUT_DEV:
817 		if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) {
818 			SAS_DPRINTK("second fanout expander %016llx phy 0x%x "
819 				    "attached to ex %016llx phy 0x%x\n",
820 				    SAS_ADDR(ex_phy->attached_sas_addr),
821 				    ex_phy->attached_phy_id,
822 				    SAS_ADDR(dev->sas_addr),
823 				    phy_id);
824 			sas_ex_disable_phy(dev, phy_id);
825 			break;
826 		} else
827 			memcpy(dev->port->disc.fanout_sas_addr,
828 			       ex_phy->attached_sas_addr, SAS_ADDR_SIZE);
829 		/* fallthrough */
830 	case EDGE_DEV:
831 		child = sas_ex_discover_expander(dev, phy_id);
832 		break;
833 	default:
834 		break;
835 	}
836 
837 	if (child) {
838 		int i;
839 
840 		for (i = 0; i < ex->num_phys; i++) {
841 			if (ex->ex_phy[i].phy_state == PHY_VACANT ||
842 			    ex->ex_phy[i].phy_state == PHY_NOT_PRESENT)
843 				continue;
844 
845 			if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
846 			    SAS_ADDR(child->sas_addr))
847 				ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
848 		}
849 	}
850 
851 	return res;
852 }
853 
854 static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
855 {
856 	struct expander_device *ex = &dev->ex_dev;
857 	int i;
858 
859 	for (i = 0; i < ex->num_phys; i++) {
860 		struct ex_phy *phy = &ex->ex_phy[i];
861 
862 		if (phy->phy_state == PHY_VACANT ||
863 		    phy->phy_state == PHY_NOT_PRESENT)
864 			continue;
865 
866 		if ((phy->attached_dev_type == EDGE_DEV ||
867 		     phy->attached_dev_type == FANOUT_DEV) &&
868 		    phy->routing_attr == SUBTRACTIVE_ROUTING) {
869 
870 			memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE);
871 
872 			return 1;
873 		}
874 	}
875 	return 0;
876 }
877 
878 static int sas_check_level_subtractive_boundary(struct domain_device *dev)
879 {
880 	struct expander_device *ex = &dev->ex_dev;
881 	struct domain_device *child;
882 	u8 sub_addr[8] = {0, };
883 
884 	list_for_each_entry(child, &ex->children, siblings) {
885 		if (child->dev_type != EDGE_DEV &&
886 		    child->dev_type != FANOUT_DEV)
887 			continue;
888 		if (sub_addr[0] == 0) {
889 			sas_find_sub_addr(child, sub_addr);
890 			continue;
891 		} else {
892 			u8 s2[8];
893 
894 			if (sas_find_sub_addr(child, s2) &&
895 			    (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) {
896 
897 				SAS_DPRINTK("ex %016llx->%016llx-?->%016llx "
898 					    "diverges from subtractive "
899 					    "boundary %016llx\n",
900 					    SAS_ADDR(dev->sas_addr),
901 					    SAS_ADDR(child->sas_addr),
902 					    SAS_ADDR(s2),
903 					    SAS_ADDR(sub_addr));
904 
905 				sas_ex_disable_port(child, s2);
906 			}
907 		}
908 	}
909 	return 0;
910 }
911 /**
912  * sas_ex_discover_devices -- discover devices attached to this expander
913  * dev: pointer to the expander domain device
914  * single: if you want to do a single phy, else set to -1;
915  *
916  * Configure this expander for use with its devices and register the
917  * devices of this expander.
918  */
919 static int sas_ex_discover_devices(struct domain_device *dev, int single)
920 {
921 	struct expander_device *ex = &dev->ex_dev;
922 	int i = 0, end = ex->num_phys;
923 	int res = 0;
924 
925 	if (0 <= single && single < end) {
926 		i = single;
927 		end = i+1;
928 	}
929 
930 	for ( ; i < end; i++) {
931 		struct ex_phy *ex_phy = &ex->ex_phy[i];
932 
933 		if (ex_phy->phy_state == PHY_VACANT ||
934 		    ex_phy->phy_state == PHY_NOT_PRESENT ||
935 		    ex_phy->phy_state == PHY_DEVICE_DISCOVERED)
936 			continue;
937 
938 		switch (ex_phy->linkrate) {
939 		case SAS_PHY_DISABLED:
940 		case SAS_PHY_RESET_PROBLEM:
941 		case SAS_SATA_PORT_SELECTOR:
942 			continue;
943 		default:
944 			res = sas_ex_discover_dev(dev, i);
945 			if (res)
946 				break;
947 			continue;
948 		}
949 	}
950 
951 	if (!res)
952 		sas_check_level_subtractive_boundary(dev);
953 
954 	return res;
955 }
956 
957 static int sas_check_ex_subtractive_boundary(struct domain_device *dev)
958 {
959 	struct expander_device *ex = &dev->ex_dev;
960 	int i;
961 	u8  *sub_sas_addr = NULL;
962 
963 	if (dev->dev_type != EDGE_DEV)
964 		return 0;
965 
966 	for (i = 0; i < ex->num_phys; i++) {
967 		struct ex_phy *phy = &ex->ex_phy[i];
968 
969 		if (phy->phy_state == PHY_VACANT ||
970 		    phy->phy_state == PHY_NOT_PRESENT)
971 			continue;
972 
973 		if ((phy->attached_dev_type == FANOUT_DEV ||
974 		     phy->attached_dev_type == EDGE_DEV) &&
975 		    phy->routing_attr == SUBTRACTIVE_ROUTING) {
976 
977 			if (!sub_sas_addr)
978 				sub_sas_addr = &phy->attached_sas_addr[0];
979 			else if (SAS_ADDR(sub_sas_addr) !=
980 				 SAS_ADDR(phy->attached_sas_addr)) {
981 
982 				SAS_DPRINTK("ex %016llx phy 0x%x "
983 					    "diverges(%016llx) on subtractive "
984 					    "boundary(%016llx). Disabled\n",
985 					    SAS_ADDR(dev->sas_addr), i,
986 					    SAS_ADDR(phy->attached_sas_addr),
987 					    SAS_ADDR(sub_sas_addr));
988 				sas_ex_disable_phy(dev, i);
989 			}
990 		}
991 	}
992 	return 0;
993 }
994 
995 static void sas_print_parent_topology_bug(struct domain_device *child,
996 						 struct ex_phy *parent_phy,
997 						 struct ex_phy *child_phy)
998 {
999 	static const char ra_char[] = {
1000 		[DIRECT_ROUTING] = 'D',
1001 		[SUBTRACTIVE_ROUTING] = 'S',
1002 		[TABLE_ROUTING] = 'T',
1003 	};
1004 	static const char *ex_type[] = {
1005 		[EDGE_DEV] = "edge",
1006 		[FANOUT_DEV] = "fanout",
1007 	};
1008 	struct domain_device *parent = child->parent;
1009 
1010 	sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx phy 0x%x "
1011 		   "has %c:%c routing link!\n",
1012 
1013 		   ex_type[parent->dev_type],
1014 		   SAS_ADDR(parent->sas_addr),
1015 		   parent_phy->phy_id,
1016 
1017 		   ex_type[child->dev_type],
1018 		   SAS_ADDR(child->sas_addr),
1019 		   child_phy->phy_id,
1020 
1021 		   ra_char[parent_phy->routing_attr],
1022 		   ra_char[child_phy->routing_attr]);
1023 }
1024 
1025 static int sas_check_eeds(struct domain_device *child,
1026 				 struct ex_phy *parent_phy,
1027 				 struct ex_phy *child_phy)
1028 {
1029 	int res = 0;
1030 	struct domain_device *parent = child->parent;
1031 
1032 	if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) {
1033 		res = -ENODEV;
1034 		SAS_DPRINTK("edge ex %016llx phy S:0x%x <--> edge ex %016llx "
1035 			    "phy S:0x%x, while there is a fanout ex %016llx\n",
1036 			    SAS_ADDR(parent->sas_addr),
1037 			    parent_phy->phy_id,
1038 			    SAS_ADDR(child->sas_addr),
1039 			    child_phy->phy_id,
1040 			    SAS_ADDR(parent->port->disc.fanout_sas_addr));
1041 	} else if (SAS_ADDR(parent->port->disc.eeds_a) == 0) {
1042 		memcpy(parent->port->disc.eeds_a, parent->sas_addr,
1043 		       SAS_ADDR_SIZE);
1044 		memcpy(parent->port->disc.eeds_b, child->sas_addr,
1045 		       SAS_ADDR_SIZE);
1046 	} else if (((SAS_ADDR(parent->port->disc.eeds_a) ==
1047 		    SAS_ADDR(parent->sas_addr)) ||
1048 		   (SAS_ADDR(parent->port->disc.eeds_a) ==
1049 		    SAS_ADDR(child->sas_addr)))
1050 		   &&
1051 		   ((SAS_ADDR(parent->port->disc.eeds_b) ==
1052 		     SAS_ADDR(parent->sas_addr)) ||
1053 		    (SAS_ADDR(parent->port->disc.eeds_b) ==
1054 		     SAS_ADDR(child->sas_addr))))
1055 		;
1056 	else {
1057 		res = -ENODEV;
1058 		SAS_DPRINTK("edge ex %016llx phy 0x%x <--> edge ex %016llx "
1059 			    "phy 0x%x link forms a third EEDS!\n",
1060 			    SAS_ADDR(parent->sas_addr),
1061 			    parent_phy->phy_id,
1062 			    SAS_ADDR(child->sas_addr),
1063 			    child_phy->phy_id);
1064 	}
1065 
1066 	return res;
1067 }
1068 
1069 /* Here we spill over 80 columns.  It is intentional.
1070  */
1071 static int sas_check_parent_topology(struct domain_device *child)
1072 {
1073 	struct expander_device *child_ex = &child->ex_dev;
1074 	struct expander_device *parent_ex;
1075 	int i;
1076 	int res = 0;
1077 
1078 	if (!child->parent)
1079 		return 0;
1080 
1081 	if (child->parent->dev_type != EDGE_DEV &&
1082 	    child->parent->dev_type != FANOUT_DEV)
1083 		return 0;
1084 
1085 	parent_ex = &child->parent->ex_dev;
1086 
1087 	for (i = 0; i < parent_ex->num_phys; i++) {
1088 		struct ex_phy *parent_phy = &parent_ex->ex_phy[i];
1089 		struct ex_phy *child_phy;
1090 
1091 		if (parent_phy->phy_state == PHY_VACANT ||
1092 		    parent_phy->phy_state == PHY_NOT_PRESENT)
1093 			continue;
1094 
1095 		if (SAS_ADDR(parent_phy->attached_sas_addr) != SAS_ADDR(child->sas_addr))
1096 			continue;
1097 
1098 		child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id];
1099 
1100 		switch (child->parent->dev_type) {
1101 		case EDGE_DEV:
1102 			if (child->dev_type == FANOUT_DEV) {
1103 				if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING ||
1104 				    child_phy->routing_attr != TABLE_ROUTING) {
1105 					sas_print_parent_topology_bug(child, parent_phy, child_phy);
1106 					res = -ENODEV;
1107 				}
1108 			} else if (parent_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1109 				if (child_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1110 					res = sas_check_eeds(child, parent_phy, child_phy);
1111 				} else if (child_phy->routing_attr != TABLE_ROUTING) {
1112 					sas_print_parent_topology_bug(child, parent_phy, child_phy);
1113 					res = -ENODEV;
1114 				}
1115 			} else if (parent_phy->routing_attr == TABLE_ROUTING &&
1116 				   child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1117 				sas_print_parent_topology_bug(child, parent_phy, child_phy);
1118 				res = -ENODEV;
1119 			}
1120 			break;
1121 		case FANOUT_DEV:
1122 			if (parent_phy->routing_attr != TABLE_ROUTING ||
1123 			    child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1124 				sas_print_parent_topology_bug(child, parent_phy, child_phy);
1125 				res = -ENODEV;
1126 			}
1127 			break;
1128 		default:
1129 			break;
1130 		}
1131 	}
1132 
1133 	return res;
1134 }
1135 
1136 #define RRI_REQ_SIZE  16
1137 #define RRI_RESP_SIZE 44
1138 
1139 static int sas_configure_present(struct domain_device *dev, int phy_id,
1140 				 u8 *sas_addr, int *index, int *present)
1141 {
1142 	int i, res = 0;
1143 	struct expander_device *ex = &dev->ex_dev;
1144 	struct ex_phy *phy = &ex->ex_phy[phy_id];
1145 	u8 *rri_req;
1146 	u8 *rri_resp;
1147 
1148 	*present = 0;
1149 	*index = 0;
1150 
1151 	rri_req = alloc_smp_req(RRI_REQ_SIZE);
1152 	if (!rri_req)
1153 		return -ENOMEM;
1154 
1155 	rri_resp = alloc_smp_resp(RRI_RESP_SIZE);
1156 	if (!rri_resp) {
1157 		kfree(rri_req);
1158 		return -ENOMEM;
1159 	}
1160 
1161 	rri_req[1] = SMP_REPORT_ROUTE_INFO;
1162 	rri_req[9] = phy_id;
1163 
1164 	for (i = 0; i < ex->max_route_indexes ; i++) {
1165 		*(__be16 *)(rri_req+6) = cpu_to_be16(i);
1166 		res = smp_execute_task(dev, rri_req, RRI_REQ_SIZE, rri_resp,
1167 				       RRI_RESP_SIZE);
1168 		if (res)
1169 			goto out;
1170 		res = rri_resp[2];
1171 		if (res == SMP_RESP_NO_INDEX) {
1172 			SAS_DPRINTK("overflow of indexes: dev %016llx "
1173 				    "phy 0x%x index 0x%x\n",
1174 				    SAS_ADDR(dev->sas_addr), phy_id, i);
1175 			goto out;
1176 		} else if (res != SMP_RESP_FUNC_ACC) {
1177 			SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x "
1178 				    "result 0x%x\n", __FUNCTION__,
1179 				    SAS_ADDR(dev->sas_addr), phy_id, i, res);
1180 			goto out;
1181 		}
1182 		if (SAS_ADDR(sas_addr) != 0) {
1183 			if (SAS_ADDR(rri_resp+16) == SAS_ADDR(sas_addr)) {
1184 				*index = i;
1185 				if ((rri_resp[12] & 0x80) == 0x80)
1186 					*present = 0;
1187 				else
1188 					*present = 1;
1189 				goto out;
1190 			} else if (SAS_ADDR(rri_resp+16) == 0) {
1191 				*index = i;
1192 				*present = 0;
1193 				goto out;
1194 			}
1195 		} else if (SAS_ADDR(rri_resp+16) == 0 &&
1196 			   phy->last_da_index < i) {
1197 			phy->last_da_index = i;
1198 			*index = i;
1199 			*present = 0;
1200 			goto out;
1201 		}
1202 	}
1203 	res = -1;
1204 out:
1205 	kfree(rri_req);
1206 	kfree(rri_resp);
1207 	return res;
1208 }
1209 
1210 #define CRI_REQ_SIZE  44
1211 #define CRI_RESP_SIZE  8
1212 
1213 static int sas_configure_set(struct domain_device *dev, int phy_id,
1214 			     u8 *sas_addr, int index, int include)
1215 {
1216 	int res;
1217 	u8 *cri_req;
1218 	u8 *cri_resp;
1219 
1220 	cri_req = alloc_smp_req(CRI_REQ_SIZE);
1221 	if (!cri_req)
1222 		return -ENOMEM;
1223 
1224 	cri_resp = alloc_smp_resp(CRI_RESP_SIZE);
1225 	if (!cri_resp) {
1226 		kfree(cri_req);
1227 		return -ENOMEM;
1228 	}
1229 
1230 	cri_req[1] = SMP_CONF_ROUTE_INFO;
1231 	*(__be16 *)(cri_req+6) = cpu_to_be16(index);
1232 	cri_req[9] = phy_id;
1233 	if (SAS_ADDR(sas_addr) == 0 || !include)
1234 		cri_req[12] |= 0x80;
1235 	memcpy(cri_req+16, sas_addr, SAS_ADDR_SIZE);
1236 
1237 	res = smp_execute_task(dev, cri_req, CRI_REQ_SIZE, cri_resp,
1238 			       CRI_RESP_SIZE);
1239 	if (res)
1240 		goto out;
1241 	res = cri_resp[2];
1242 	if (res == SMP_RESP_NO_INDEX) {
1243 		SAS_DPRINTK("overflow of indexes: dev %016llx phy 0x%x "
1244 			    "index 0x%x\n",
1245 			    SAS_ADDR(dev->sas_addr), phy_id, index);
1246 	}
1247 out:
1248 	kfree(cri_req);
1249 	kfree(cri_resp);
1250 	return res;
1251 }
1252 
1253 static int sas_configure_phy(struct domain_device *dev, int phy_id,
1254 				    u8 *sas_addr, int include)
1255 {
1256 	int index;
1257 	int present;
1258 	int res;
1259 
1260 	res = sas_configure_present(dev, phy_id, sas_addr, &index, &present);
1261 	if (res)
1262 		return res;
1263 	if (include ^ present)
1264 		return sas_configure_set(dev, phy_id, sas_addr, index,include);
1265 
1266 	return res;
1267 }
1268 
1269 /**
1270  * sas_configure_parent -- configure routing table of parent
1271  * parent: parent expander
1272  * child: child expander
1273  * sas_addr: SAS port identifier of device directly attached to child
1274  */
1275 static int sas_configure_parent(struct domain_device *parent,
1276 				struct domain_device *child,
1277 				u8 *sas_addr, int include)
1278 {
1279 	struct expander_device *ex_parent = &parent->ex_dev;
1280 	int res = 0;
1281 	int i;
1282 
1283 	if (parent->parent) {
1284 		res = sas_configure_parent(parent->parent, parent, sas_addr,
1285 					   include);
1286 		if (res)
1287 			return res;
1288 	}
1289 
1290 	if (ex_parent->conf_route_table == 0) {
1291 		SAS_DPRINTK("ex %016llx has self-configuring routing table\n",
1292 			    SAS_ADDR(parent->sas_addr));
1293 		return 0;
1294 	}
1295 
1296 	for (i = 0; i < ex_parent->num_phys; i++) {
1297 		struct ex_phy *phy = &ex_parent->ex_phy[i];
1298 
1299 		if ((phy->routing_attr == TABLE_ROUTING) &&
1300 		    (SAS_ADDR(phy->attached_sas_addr) ==
1301 		     SAS_ADDR(child->sas_addr))) {
1302 			res = sas_configure_phy(parent, i, sas_addr, include);
1303 			if (res)
1304 				return res;
1305 		}
1306 	}
1307 
1308 	return res;
1309 }
1310 
1311 /**
1312  * sas_configure_routing -- configure routing
1313  * dev: expander device
1314  * sas_addr: port identifier of device directly attached to the expander device
1315  */
1316 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
1317 {
1318 	if (dev->parent)
1319 		return sas_configure_parent(dev->parent, dev, sas_addr, 1);
1320 	return 0;
1321 }
1322 
1323 static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr)
1324 {
1325 	if (dev->parent)
1326 		return sas_configure_parent(dev->parent, dev, sas_addr, 0);
1327 	return 0;
1328 }
1329 
1330 #if 0
1331 #define SMP_BIN_ATTR_NAME "smp_portal"
1332 
1333 static void sas_ex_smp_hook(struct domain_device *dev)
1334 {
1335 	struct expander_device *ex_dev = &dev->ex_dev;
1336 	struct bin_attribute *bin_attr = &ex_dev->smp_bin_attr;
1337 
1338 	memset(bin_attr, 0, sizeof(*bin_attr));
1339 
1340 	bin_attr->attr.name = SMP_BIN_ATTR_NAME;
1341 	bin_attr->attr.owner = THIS_MODULE;
1342 	bin_attr->attr.mode = 0600;
1343 
1344 	bin_attr->size = 0;
1345 	bin_attr->private = NULL;
1346 	bin_attr->read = smp_portal_read;
1347 	bin_attr->write= smp_portal_write;
1348 	bin_attr->mmap = NULL;
1349 
1350 	ex_dev->smp_portal_pid = -1;
1351 	init_MUTEX(&ex_dev->smp_sema);
1352 }
1353 #endif
1354 
1355 /**
1356  * sas_discover_expander -- expander discovery
1357  * @ex: pointer to expander domain device
1358  *
1359  * See comment in sas_discover_sata().
1360  */
1361 static int sas_discover_expander(struct domain_device *dev)
1362 {
1363 	int res;
1364 
1365 	res = sas_notify_lldd_dev_found(dev);
1366 	if (res)
1367 		return res;
1368 
1369 	res = sas_ex_general(dev);
1370 	if (res)
1371 		goto out_err;
1372 	res = sas_ex_manuf_info(dev);
1373 	if (res)
1374 		goto out_err;
1375 
1376 	res = sas_expander_discover(dev);
1377 	if (res) {
1378 		SAS_DPRINTK("expander %016llx discovery failed(0x%x)\n",
1379 			    SAS_ADDR(dev->sas_addr), res);
1380 		goto out_err;
1381 	}
1382 
1383 	sas_check_ex_subtractive_boundary(dev);
1384 	res = sas_check_parent_topology(dev);
1385 	if (res)
1386 		goto out_err;
1387 	return 0;
1388 out_err:
1389 	sas_notify_lldd_dev_gone(dev);
1390 	return res;
1391 }
1392 
1393 static int sas_ex_level_discovery(struct asd_sas_port *port, const int level)
1394 {
1395 	int res = 0;
1396 	struct domain_device *dev;
1397 
1398 	list_for_each_entry(dev, &port->dev_list, dev_list_node) {
1399 		if (dev->dev_type == EDGE_DEV ||
1400 		    dev->dev_type == FANOUT_DEV) {
1401 			struct sas_expander_device *ex =
1402 				rphy_to_expander_device(dev->rphy);
1403 
1404 			if (level == ex->level)
1405 				res = sas_ex_discover_devices(dev, -1);
1406 			else if (level > 0)
1407 				res = sas_ex_discover_devices(port->port_dev, -1);
1408 
1409 		}
1410 	}
1411 
1412 	return res;
1413 }
1414 
1415 static int sas_ex_bfs_disc(struct asd_sas_port *port)
1416 {
1417 	int res;
1418 	int level;
1419 
1420 	do {
1421 		level = port->disc.max_level;
1422 		res = sas_ex_level_discovery(port, level);
1423 		mb();
1424 	} while (level < port->disc.max_level);
1425 
1426 	return res;
1427 }
1428 
1429 int sas_discover_root_expander(struct domain_device *dev)
1430 {
1431 	int res;
1432 	struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1433 
1434 	sas_rphy_add(dev->rphy);
1435 
1436 	ex->level = dev->port->disc.max_level; /* 0 */
1437 	res = sas_discover_expander(dev);
1438 	if (!res)
1439 		sas_ex_bfs_disc(dev->port);
1440 
1441 	return res;
1442 }
1443 
1444 /* ---------- Domain revalidation ---------- */
1445 
1446 static int sas_get_phy_discover(struct domain_device *dev,
1447 				int phy_id, struct smp_resp *disc_resp)
1448 {
1449 	int res;
1450 	u8 *disc_req;
1451 
1452 	disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
1453 	if (!disc_req)
1454 		return -ENOMEM;
1455 
1456 	disc_req[1] = SMP_DISCOVER;
1457 	disc_req[9] = phy_id;
1458 
1459 	res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
1460 			       disc_resp, DISCOVER_RESP_SIZE);
1461 	if (res)
1462 		goto out;
1463 	else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
1464 		res = disc_resp->result;
1465 		goto out;
1466 	}
1467 out:
1468 	kfree(disc_req);
1469 	return res;
1470 }
1471 
1472 static int sas_get_phy_change_count(struct domain_device *dev,
1473 				    int phy_id, int *pcc)
1474 {
1475 	int res;
1476 	struct smp_resp *disc_resp;
1477 
1478 	disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1479 	if (!disc_resp)
1480 		return -ENOMEM;
1481 
1482 	res = sas_get_phy_discover(dev, phy_id, disc_resp);
1483 	if (!res)
1484 		*pcc = disc_resp->disc.change_count;
1485 
1486 	kfree(disc_resp);
1487 	return res;
1488 }
1489 
1490 static int sas_get_phy_attached_sas_addr(struct domain_device *dev,
1491 					 int phy_id, u8 *attached_sas_addr)
1492 {
1493 	int res;
1494 	struct smp_resp *disc_resp;
1495 	struct discover_resp *dr;
1496 
1497 	disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1498 	if (!disc_resp)
1499 		return -ENOMEM;
1500 	dr = &disc_resp->disc;
1501 
1502 	res = sas_get_phy_discover(dev, phy_id, disc_resp);
1503 	if (!res) {
1504 		memcpy(attached_sas_addr,disc_resp->disc.attached_sas_addr,8);
1505 		if (dr->attached_dev_type == 0)
1506 			memset(attached_sas_addr, 0, 8);
1507 	}
1508 	kfree(disc_resp);
1509 	return res;
1510 }
1511 
1512 static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
1513 			      int from_phy)
1514 {
1515 	struct expander_device *ex = &dev->ex_dev;
1516 	int res = 0;
1517 	int i;
1518 
1519 	for (i = from_phy; i < ex->num_phys; i++) {
1520 		int phy_change_count = 0;
1521 
1522 		res = sas_get_phy_change_count(dev, i, &phy_change_count);
1523 		if (res)
1524 			goto out;
1525 		else if (phy_change_count != ex->ex_phy[i].phy_change_count) {
1526 			ex->ex_phy[i].phy_change_count = phy_change_count;
1527 			*phy_id = i;
1528 			return 0;
1529 		}
1530 	}
1531 out:
1532 	return res;
1533 }
1534 
1535 static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
1536 {
1537 	int res;
1538 	u8  *rg_req;
1539 	struct smp_resp  *rg_resp;
1540 
1541 	rg_req = alloc_smp_req(RG_REQ_SIZE);
1542 	if (!rg_req)
1543 		return -ENOMEM;
1544 
1545 	rg_resp = alloc_smp_resp(RG_RESP_SIZE);
1546 	if (!rg_resp) {
1547 		kfree(rg_req);
1548 		return -ENOMEM;
1549 	}
1550 
1551 	rg_req[1] = SMP_REPORT_GENERAL;
1552 
1553 	res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
1554 			       RG_RESP_SIZE);
1555 	if (res)
1556 		goto out;
1557 	if (rg_resp->result != SMP_RESP_FUNC_ACC) {
1558 		res = rg_resp->result;
1559 		goto out;
1560 	}
1561 
1562 	*ecc = be16_to_cpu(rg_resp->rg.change_count);
1563 out:
1564 	kfree(rg_resp);
1565 	kfree(rg_req);
1566 	return res;
1567 }
1568 
1569 static int sas_find_bcast_dev(struct domain_device *dev,
1570 			      struct domain_device **src_dev)
1571 {
1572 	struct expander_device *ex = &dev->ex_dev;
1573 	int ex_change_count = -1;
1574 	int res;
1575 
1576 	res = sas_get_ex_change_count(dev, &ex_change_count);
1577 	if (res)
1578 		goto out;
1579 	if (ex_change_count != -1 &&
1580 	    ex_change_count != ex->ex_change_count) {
1581 		*src_dev = dev;
1582 		ex->ex_change_count = ex_change_count;
1583 	} else {
1584 		struct domain_device *ch;
1585 
1586 		list_for_each_entry(ch, &ex->children, siblings) {
1587 			if (ch->dev_type == EDGE_DEV ||
1588 			    ch->dev_type == FANOUT_DEV) {
1589 				res = sas_find_bcast_dev(ch, src_dev);
1590 				if (src_dev)
1591 					return res;
1592 			}
1593 		}
1594 	}
1595 out:
1596 	return res;
1597 }
1598 
1599 static void sas_unregister_ex_tree(struct domain_device *dev)
1600 {
1601 	struct expander_device *ex = &dev->ex_dev;
1602 	struct domain_device *child, *n;
1603 
1604 	list_for_each_entry_safe(child, n, &ex->children, siblings) {
1605 		if (child->dev_type == EDGE_DEV ||
1606 		    child->dev_type == FANOUT_DEV)
1607 			sas_unregister_ex_tree(child);
1608 		else
1609 			sas_unregister_dev(child);
1610 	}
1611 	sas_unregister_dev(dev);
1612 }
1613 
1614 static void sas_unregister_devs_sas_addr(struct domain_device *parent,
1615 					 int phy_id)
1616 {
1617 	struct expander_device *ex_dev = &parent->ex_dev;
1618 	struct ex_phy *phy = &ex_dev->ex_phy[phy_id];
1619 	struct domain_device *child, *n;
1620 
1621 	list_for_each_entry_safe(child, n, &ex_dev->children, siblings) {
1622 		if (SAS_ADDR(child->sas_addr) ==
1623 		    SAS_ADDR(phy->attached_sas_addr)) {
1624 			if (child->dev_type == EDGE_DEV ||
1625 			    child->dev_type == FANOUT_DEV)
1626 				sas_unregister_ex_tree(child);
1627 			else
1628 				sas_unregister_dev(child);
1629 			break;
1630 		}
1631 	}
1632 	sas_disable_routing(parent, phy->attached_sas_addr);
1633 	memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
1634 	sas_port_delete_phy(phy->port, phy->phy);
1635 	if (phy->port->num_phys == 0)
1636 		sas_port_delete(phy->port);
1637 	phy->port = NULL;
1638 }
1639 
1640 static int sas_discover_bfs_by_root_level(struct domain_device *root,
1641 					  const int level)
1642 {
1643 	struct expander_device *ex_root = &root->ex_dev;
1644 	struct domain_device *child;
1645 	int res = 0;
1646 
1647 	list_for_each_entry(child, &ex_root->children, siblings) {
1648 		if (child->dev_type == EDGE_DEV ||
1649 		    child->dev_type == FANOUT_DEV) {
1650 			struct sas_expander_device *ex =
1651 				rphy_to_expander_device(child->rphy);
1652 
1653 			if (level > ex->level)
1654 				res = sas_discover_bfs_by_root_level(child,
1655 								     level);
1656 			else if (level == ex->level)
1657 				res = sas_ex_discover_devices(child, -1);
1658 		}
1659 	}
1660 	return res;
1661 }
1662 
1663 static int sas_discover_bfs_by_root(struct domain_device *dev)
1664 {
1665 	int res;
1666 	struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1667 	int level = ex->level+1;
1668 
1669 	res = sas_ex_discover_devices(dev, -1);
1670 	if (res)
1671 		goto out;
1672 	do {
1673 		res = sas_discover_bfs_by_root_level(dev, level);
1674 		mb();
1675 		level += 1;
1676 	} while (level <= dev->port->disc.max_level);
1677 out:
1678 	return res;
1679 }
1680 
1681 static int sas_discover_new(struct domain_device *dev, int phy_id)
1682 {
1683 	struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
1684 	struct domain_device *child;
1685 	int res;
1686 
1687 	SAS_DPRINTK("ex %016llx phy%d new device attached\n",
1688 		    SAS_ADDR(dev->sas_addr), phy_id);
1689 	res = sas_ex_phy_discover(dev, phy_id);
1690 	if (res)
1691 		goto out;
1692 	res = sas_ex_discover_devices(dev, phy_id);
1693 	if (res)
1694 		goto out;
1695 	list_for_each_entry(child, &dev->ex_dev.children, siblings) {
1696 		if (SAS_ADDR(child->sas_addr) ==
1697 		    SAS_ADDR(ex_phy->attached_sas_addr)) {
1698 			if (child->dev_type == EDGE_DEV ||
1699 			    child->dev_type == FANOUT_DEV)
1700 				res = sas_discover_bfs_by_root(child);
1701 			break;
1702 		}
1703 	}
1704 out:
1705 	return res;
1706 }
1707 
1708 static int sas_rediscover_dev(struct domain_device *dev, int phy_id)
1709 {
1710 	struct expander_device *ex = &dev->ex_dev;
1711 	struct ex_phy *phy = &ex->ex_phy[phy_id];
1712 	u8 attached_sas_addr[8];
1713 	int res;
1714 
1715 	res = sas_get_phy_attached_sas_addr(dev, phy_id, attached_sas_addr);
1716 	switch (res) {
1717 	case SMP_RESP_NO_PHY:
1718 		phy->phy_state = PHY_NOT_PRESENT;
1719 		sas_unregister_devs_sas_addr(dev, phy_id);
1720 		goto out; break;
1721 	case SMP_RESP_PHY_VACANT:
1722 		phy->phy_state = PHY_VACANT;
1723 		sas_unregister_devs_sas_addr(dev, phy_id);
1724 		goto out; break;
1725 	case SMP_RESP_FUNC_ACC:
1726 		break;
1727 	}
1728 
1729 	if (SAS_ADDR(attached_sas_addr) == 0) {
1730 		phy->phy_state = PHY_EMPTY;
1731 		sas_unregister_devs_sas_addr(dev, phy_id);
1732 	} else if (SAS_ADDR(attached_sas_addr) ==
1733 		   SAS_ADDR(phy->attached_sas_addr)) {
1734 		SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n",
1735 			    SAS_ADDR(dev->sas_addr), phy_id);
1736 		sas_ex_phy_discover(dev, phy_id);
1737 	} else
1738 		res = sas_discover_new(dev, phy_id);
1739 out:
1740 	return res;
1741 }
1742 
1743 static int sas_rediscover(struct domain_device *dev, const int phy_id)
1744 {
1745 	struct expander_device *ex = &dev->ex_dev;
1746 	struct ex_phy *changed_phy = &ex->ex_phy[phy_id];
1747 	int res = 0;
1748 	int i;
1749 
1750 	SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n",
1751 		    SAS_ADDR(dev->sas_addr), phy_id);
1752 
1753 	if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) {
1754 		for (i = 0; i < ex->num_phys; i++) {
1755 			struct ex_phy *phy = &ex->ex_phy[i];
1756 
1757 			if (i == phy_id)
1758 				continue;
1759 			if (SAS_ADDR(phy->attached_sas_addr) ==
1760 			    SAS_ADDR(changed_phy->attached_sas_addr)) {
1761 				SAS_DPRINTK("phy%d part of wide port with "
1762 					    "phy%d\n", phy_id, i);
1763 				goto out;
1764 			}
1765 		}
1766 		res = sas_rediscover_dev(dev, phy_id);
1767 	} else
1768 		res = sas_discover_new(dev, phy_id);
1769 out:
1770 	return res;
1771 }
1772 
1773 /**
1774  * sas_revalidate_domain -- revalidate the domain
1775  * @port: port to the domain of interest
1776  *
1777  * NOTE: this process _must_ quit (return) as soon as any connection
1778  * errors are encountered.  Connection recovery is done elsewhere.
1779  * Discover process only interrogates devices in order to discover the
1780  * domain.
1781  */
1782 int sas_ex_revalidate_domain(struct domain_device *port_dev)
1783 {
1784 	int res;
1785 	struct domain_device *dev = NULL;
1786 
1787 	res = sas_find_bcast_dev(port_dev, &dev);
1788 	if (res)
1789 		goto out;
1790 	if (dev) {
1791 		struct expander_device *ex = &dev->ex_dev;
1792 		int i = 0, phy_id;
1793 
1794 		do {
1795 			phy_id = -1;
1796 			res = sas_find_bcast_phy(dev, &phy_id, i);
1797 			if (phy_id == -1)
1798 				break;
1799 			res = sas_rediscover(dev, phy_id);
1800 			i = phy_id + 1;
1801 		} while (i < ex->num_phys);
1802 	}
1803 out:
1804 	return res;
1805 }
1806 
1807 #if 0
1808 /* ---------- SMP portal ---------- */
1809 
1810 static ssize_t smp_portal_write(struct kobject *kobj, char *buf, loff_t offs,
1811 				size_t size)
1812 {
1813 	struct domain_device *dev = to_dom_device(kobj);
1814 	struct expander_device *ex = &dev->ex_dev;
1815 
1816 	if (offs != 0)
1817 		return -EFBIG;
1818 	else if (size == 0)
1819 		return 0;
1820 
1821 	down_interruptible(&ex->smp_sema);
1822 	if (ex->smp_req)
1823 		kfree(ex->smp_req);
1824 	ex->smp_req = kzalloc(size, GFP_USER);
1825 	if (!ex->smp_req) {
1826 		up(&ex->smp_sema);
1827 		return -ENOMEM;
1828 	}
1829 	memcpy(ex->smp_req, buf, size);
1830 	ex->smp_req_size = size;
1831 	ex->smp_portal_pid = current->pid;
1832 	up(&ex->smp_sema);
1833 
1834 	return size;
1835 }
1836 
1837 static ssize_t smp_portal_read(struct kobject *kobj, char *buf, loff_t offs,
1838 			       size_t size)
1839 {
1840 	struct domain_device *dev = to_dom_device(kobj);
1841 	struct expander_device *ex = &dev->ex_dev;
1842 	u8 *smp_resp;
1843 	int res = -EINVAL;
1844 
1845 	/* XXX: sysfs gives us an offset of 0x10 or 0x8 while in fact
1846 	 *  it should be 0.
1847 	 */
1848 
1849 	down_interruptible(&ex->smp_sema);
1850 	if (!ex->smp_req || ex->smp_portal_pid != current->pid)
1851 		goto out;
1852 
1853 	res = 0;
1854 	if (size == 0)
1855 		goto out;
1856 
1857 	res = -ENOMEM;
1858 	smp_resp = alloc_smp_resp(size);
1859 	if (!smp_resp)
1860 		goto out;
1861 	res = smp_execute_task(dev, ex->smp_req, ex->smp_req_size,
1862 			       smp_resp, size);
1863 	if (!res) {
1864 		memcpy(buf, smp_resp, size);
1865 		res = size;
1866 	}
1867 
1868 	kfree(smp_resp);
1869 out:
1870 	kfree(ex->smp_req);
1871 	ex->smp_req = NULL;
1872 	ex->smp_req_size = 0;
1873 	ex->smp_portal_pid = -1;
1874 	up(&ex->smp_sema);
1875 	return res;
1876 }
1877 #endif
1878