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