[SCSI] libsas: Add a sysfs knob to enable/disable a phy
[linux-2.6] / drivers / scsi / libsas / sas_expander.c
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  out_free:
672         sas_port_delete(phy->port);
673  out_err:
674         phy->port = NULL;
675         kfree(child);
676         return NULL;
677 }
678
679 static struct domain_device *sas_ex_discover_expander(
680         struct domain_device *parent, int phy_id)
681 {
682         struct sas_expander_device *parent_ex = rphy_to_expander_device(parent->rphy);
683         struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
684         struct domain_device *child = NULL;
685         struct sas_rphy *rphy;
686         struct sas_expander_device *edev;
687         struct asd_sas_port *port;
688         int res;
689
690         if (phy->routing_attr == DIRECT_ROUTING) {
691                 SAS_DPRINTK("ex %016llx:0x%x:D <--> ex %016llx:0x%x is not "
692                             "allowed\n",
693                             SAS_ADDR(parent->sas_addr), phy_id,
694                             SAS_ADDR(phy->attached_sas_addr),
695                             phy->attached_phy_id);
696                 return NULL;
697         }
698         child = kzalloc(sizeof(*child), GFP_KERNEL);
699         if (!child)
700                 return NULL;
701
702         phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
703         /* FIXME: better error handling */
704         BUG_ON(sas_port_add(phy->port) != 0);
705
706
707         switch (phy->attached_dev_type) {
708         case EDGE_DEV:
709                 rphy = sas_expander_alloc(phy->port,
710                                           SAS_EDGE_EXPANDER_DEVICE);
711                 break;
712         case FANOUT_DEV:
713                 rphy = sas_expander_alloc(phy->port,
714                                           SAS_FANOUT_EXPANDER_DEVICE);
715                 break;
716         default:
717                 rphy = NULL;    /* shut gcc up */
718                 BUG();
719         }
720         port = parent->port;
721         child->rphy = rphy;
722         edev = rphy_to_expander_device(rphy);
723         child->dev_type = phy->attached_dev_type;
724         child->parent = parent;
725         child->port = port;
726         child->iproto = phy->attached_iproto;
727         child->tproto = phy->attached_tproto;
728         memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
729         sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
730         sas_ex_get_linkrate(parent, child, phy);
731         edev->level = parent_ex->level + 1;
732         parent->port->disc.max_level = max(parent->port->disc.max_level,
733                                            edev->level);
734         sas_init_dev(child);
735         sas_fill_in_rphy(child, rphy);
736         sas_rphy_add(rphy);
737
738         spin_lock(&parent->port->dev_list_lock);
739         list_add_tail(&child->dev_list_node, &parent->port->dev_list);
740         spin_unlock(&parent->port->dev_list_lock);
741
742         res = sas_discover_expander(child);
743         if (res) {
744                 kfree(child);
745                 return NULL;
746         }
747         list_add_tail(&child->siblings, &parent->ex_dev.children);
748         return child;
749 }
750
751 static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
752 {
753         struct expander_device *ex = &dev->ex_dev;
754         struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
755         struct domain_device *child = NULL;
756         int res = 0;
757
758         /* Phy state */
759         if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) {
760                 if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET, NULL))
761                         res = sas_ex_phy_discover(dev, phy_id);
762                 if (res)
763                         return res;
764         }
765
766         /* Parent and domain coherency */
767         if (!dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
768                              SAS_ADDR(dev->port->sas_addr))) {
769                 sas_add_parent_port(dev, phy_id);
770                 return 0;
771         }
772         if (dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
773                             SAS_ADDR(dev->parent->sas_addr))) {
774                 sas_add_parent_port(dev, phy_id);
775                 if (ex_phy->routing_attr == TABLE_ROUTING)
776                         sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1);
777                 return 0;
778         }
779
780         if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr))
781                 sas_ex_disable_port(dev, ex_phy->attached_sas_addr);
782
783         if (ex_phy->attached_dev_type == NO_DEVICE) {
784                 if (ex_phy->routing_attr == DIRECT_ROUTING) {
785                         memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
786                         sas_configure_routing(dev, ex_phy->attached_sas_addr);
787                 }
788                 return 0;
789         } else if (ex_phy->linkrate == SAS_LINK_RATE_UNKNOWN)
790                 return 0;
791
792         if (ex_phy->attached_dev_type != SAS_END_DEV &&
793             ex_phy->attached_dev_type != FANOUT_DEV &&
794             ex_phy->attached_dev_type != EDGE_DEV) {
795                 SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx "
796                             "phy 0x%x\n", ex_phy->attached_dev_type,
797                             SAS_ADDR(dev->sas_addr),
798                             phy_id);
799                 return 0;
800         }
801
802         res = sas_configure_routing(dev, ex_phy->attached_sas_addr);
803         if (res) {
804                 SAS_DPRINTK("configure routing for dev %016llx "
805                             "reported 0x%x. Forgotten\n",
806                             SAS_ADDR(ex_phy->attached_sas_addr), res);
807                 sas_disable_routing(dev, ex_phy->attached_sas_addr);
808                 return res;
809         }
810
811         switch (ex_phy->attached_dev_type) {
812         case SAS_END_DEV:
813                 child = sas_ex_discover_end_dev(dev, phy_id);
814                 break;
815         case FANOUT_DEV:
816                 if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) {
817                         SAS_DPRINTK("second fanout expander %016llx phy 0x%x "
818                                     "attached to ex %016llx phy 0x%x\n",
819                                     SAS_ADDR(ex_phy->attached_sas_addr),
820                                     ex_phy->attached_phy_id,
821                                     SAS_ADDR(dev->sas_addr),
822                                     phy_id);
823                         sas_ex_disable_phy(dev, phy_id);
824                         break;
825                 } else
826                         memcpy(dev->port->disc.fanout_sas_addr,
827                                ex_phy->attached_sas_addr, SAS_ADDR_SIZE);
828                 /* fallthrough */
829         case EDGE_DEV:
830                 child = sas_ex_discover_expander(dev, phy_id);
831                 break;
832         default:
833                 break;
834         }
835
836         if (child) {
837                 int i;
838
839                 for (i = 0; i < ex->num_phys; i++) {
840                         if (ex->ex_phy[i].phy_state == PHY_VACANT ||
841                             ex->ex_phy[i].phy_state == PHY_NOT_PRESENT)
842                                 continue;
843
844                         if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
845                             SAS_ADDR(child->sas_addr))
846                                 ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
847                 }
848         }
849
850         return res;
851 }
852
853 static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
854 {
855         struct expander_device *ex = &dev->ex_dev;
856         int i;
857
858         for (i = 0; i < ex->num_phys; i++) {
859                 struct ex_phy *phy = &ex->ex_phy[i];
860
861                 if (phy->phy_state == PHY_VACANT ||
862                     phy->phy_state == PHY_NOT_PRESENT)
863                         continue;
864
865                 if ((phy->attached_dev_type == EDGE_DEV ||
866                      phy->attached_dev_type == FANOUT_DEV) &&
867                     phy->routing_attr == SUBTRACTIVE_ROUTING) {
868
869                         memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE);
870
871                         return 1;
872                 }
873         }
874         return 0;
875 }
876
877 static int sas_check_level_subtractive_boundary(struct domain_device *dev)
878 {
879         struct expander_device *ex = &dev->ex_dev;
880         struct domain_device *child;
881         u8 sub_addr[8] = {0, };
882
883         list_for_each_entry(child, &ex->children, siblings) {
884                 if (child->dev_type != EDGE_DEV &&
885                     child->dev_type != FANOUT_DEV)
886                         continue;
887                 if (sub_addr[0] == 0) {
888                         sas_find_sub_addr(child, sub_addr);
889                         continue;
890                 } else {
891                         u8 s2[8];
892
893                         if (sas_find_sub_addr(child, s2) &&
894                             (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) {
895
896                                 SAS_DPRINTK("ex %016llx->%016llx-?->%016llx "
897                                             "diverges from subtractive "
898                                             "boundary %016llx\n",
899                                             SAS_ADDR(dev->sas_addr),
900                                             SAS_ADDR(child->sas_addr),
901                                             SAS_ADDR(s2),
902                                             SAS_ADDR(sub_addr));
903
904                                 sas_ex_disable_port(child, s2);
905                         }
906                 }
907         }
908         return 0;
909 }
910 /**
911  * sas_ex_discover_devices -- discover devices attached to this expander
912  * dev: pointer to the expander domain device
913  * single: if you want to do a single phy, else set to -1;
914  *
915  * Configure this expander for use with its devices and register the
916  * devices of this expander.
917  */
918 static int sas_ex_discover_devices(struct domain_device *dev, int single)
919 {
920         struct expander_device *ex = &dev->ex_dev;
921         int i = 0, end = ex->num_phys;
922         int res = 0;
923
924         if (0 <= single && single < end) {
925                 i = single;
926                 end = i+1;
927         }
928
929         for ( ; i < end; i++) {
930                 struct ex_phy *ex_phy = &ex->ex_phy[i];
931
932                 if (ex_phy->phy_state == PHY_VACANT ||
933                     ex_phy->phy_state == PHY_NOT_PRESENT ||
934                     ex_phy->phy_state == PHY_DEVICE_DISCOVERED)
935                         continue;
936
937                 switch (ex_phy->linkrate) {
938                 case SAS_PHY_DISABLED:
939                 case SAS_PHY_RESET_PROBLEM:
940                 case SAS_SATA_PORT_SELECTOR:
941                         continue;
942                 default:
943                         res = sas_ex_discover_dev(dev, i);
944                         if (res)
945                                 break;
946                         continue;
947                 }
948         }
949
950         if (!res)
951                 sas_check_level_subtractive_boundary(dev);
952
953         return res;
954 }
955
956 static int sas_check_ex_subtractive_boundary(struct domain_device *dev)
957 {
958         struct expander_device *ex = &dev->ex_dev;
959         int i;
960         u8  *sub_sas_addr = NULL;
961
962         if (dev->dev_type != EDGE_DEV)
963                 return 0;
964
965         for (i = 0; i < ex->num_phys; i++) {
966                 struct ex_phy *phy = &ex->ex_phy[i];
967
968                 if (phy->phy_state == PHY_VACANT ||
969                     phy->phy_state == PHY_NOT_PRESENT)
970                         continue;
971
972                 if ((phy->attached_dev_type == FANOUT_DEV ||
973                      phy->attached_dev_type == EDGE_DEV) &&
974                     phy->routing_attr == SUBTRACTIVE_ROUTING) {
975
976                         if (!sub_sas_addr)
977                                 sub_sas_addr = &phy->attached_sas_addr[0];
978                         else if (SAS_ADDR(sub_sas_addr) !=
979                                  SAS_ADDR(phy->attached_sas_addr)) {
980
981                                 SAS_DPRINTK("ex %016llx phy 0x%x "
982                                             "diverges(%016llx) on subtractive "
983                                             "boundary(%016llx). Disabled\n",
984                                             SAS_ADDR(dev->sas_addr), i,
985                                             SAS_ADDR(phy->attached_sas_addr),
986                                             SAS_ADDR(sub_sas_addr));
987                                 sas_ex_disable_phy(dev, i);
988                         }
989                 }
990         }
991         return 0;
992 }
993
994 static void sas_print_parent_topology_bug(struct domain_device *child,
995                                                  struct ex_phy *parent_phy,
996                                                  struct ex_phy *child_phy)
997 {
998         static const char ra_char[] = {
999                 [DIRECT_ROUTING] = 'D',
1000                 [SUBTRACTIVE_ROUTING] = 'S',
1001                 [TABLE_ROUTING] = 'T',
1002         };
1003         static const char *ex_type[] = {
1004                 [EDGE_DEV] = "edge",
1005                 [FANOUT_DEV] = "fanout",
1006         };
1007         struct domain_device *parent = child->parent;
1008
1009         sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx phy 0x%x "
1010                    "has %c:%c routing link!\n",
1011
1012                    ex_type[parent->dev_type],
1013                    SAS_ADDR(parent->sas_addr),
1014                    parent_phy->phy_id,
1015
1016                    ex_type[child->dev_type],
1017                    SAS_ADDR(child->sas_addr),
1018                    child_phy->phy_id,
1019
1020                    ra_char[parent_phy->routing_attr],
1021                    ra_char[child_phy->routing_attr]);
1022 }
1023
1024 static int sas_check_eeds(struct domain_device *child,
1025                                  struct ex_phy *parent_phy,
1026                                  struct ex_phy *child_phy)
1027 {
1028         int res = 0;
1029         struct domain_device *parent = child->parent;
1030
1031         if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) {
1032                 res = -ENODEV;
1033                 SAS_DPRINTK("edge ex %016llx phy S:0x%x <--> edge ex %016llx "
1034                             "phy S:0x%x, while there is a fanout ex %016llx\n",
1035                             SAS_ADDR(parent->sas_addr),
1036                             parent_phy->phy_id,
1037                             SAS_ADDR(child->sas_addr),
1038                             child_phy->phy_id,
1039                             SAS_ADDR(parent->port->disc.fanout_sas_addr));
1040         } else if (SAS_ADDR(parent->port->disc.eeds_a) == 0) {
1041                 memcpy(parent->port->disc.eeds_a, parent->sas_addr,
1042                        SAS_ADDR_SIZE);
1043                 memcpy(parent->port->disc.eeds_b, child->sas_addr,
1044                        SAS_ADDR_SIZE);
1045         } else if (((SAS_ADDR(parent->port->disc.eeds_a) ==
1046                     SAS_ADDR(parent->sas_addr)) ||
1047                    (SAS_ADDR(parent->port->disc.eeds_a) ==
1048                     SAS_ADDR(child->sas_addr)))
1049                    &&
1050                    ((SAS_ADDR(parent->port->disc.eeds_b) ==
1051                      SAS_ADDR(parent->sas_addr)) ||
1052                     (SAS_ADDR(parent->port->disc.eeds_b) ==
1053                      SAS_ADDR(child->sas_addr))))
1054                 ;
1055         else {
1056                 res = -ENODEV;
1057                 SAS_DPRINTK("edge ex %016llx phy 0x%x <--> edge ex %016llx "
1058                             "phy 0x%x link forms a third EEDS!\n",
1059                             SAS_ADDR(parent->sas_addr),
1060                             parent_phy->phy_id,
1061                             SAS_ADDR(child->sas_addr),
1062                             child_phy->phy_id);
1063         }
1064
1065         return res;
1066 }
1067
1068 /* Here we spill over 80 columns.  It is intentional.
1069  */
1070 static int sas_check_parent_topology(struct domain_device *child)
1071 {
1072         struct expander_device *child_ex = &child->ex_dev;
1073         struct expander_device *parent_ex;
1074         int i;
1075         int res = 0;
1076
1077         if (!child->parent)
1078                 return 0;
1079
1080         if (child->parent->dev_type != EDGE_DEV &&
1081             child->parent->dev_type != FANOUT_DEV)
1082                 return 0;
1083
1084         parent_ex = &child->parent->ex_dev;
1085
1086         for (i = 0; i < parent_ex->num_phys; i++) {
1087                 struct ex_phy *parent_phy = &parent_ex->ex_phy[i];
1088                 struct ex_phy *child_phy;
1089
1090                 if (parent_phy->phy_state == PHY_VACANT ||
1091                     parent_phy->phy_state == PHY_NOT_PRESENT)
1092                         continue;
1093
1094                 if (SAS_ADDR(parent_phy->attached_sas_addr) != SAS_ADDR(child->sas_addr))
1095                         continue;
1096
1097                 child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id];
1098
1099                 switch (child->parent->dev_type) {
1100                 case EDGE_DEV:
1101                         if (child->dev_type == FANOUT_DEV) {
1102                                 if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING ||
1103                                     child_phy->routing_attr != TABLE_ROUTING) {
1104                                         sas_print_parent_topology_bug(child, parent_phy, child_phy);
1105                                         res = -ENODEV;
1106                                 }
1107                         } else if (parent_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1108                                 if (child_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1109                                         res = sas_check_eeds(child, parent_phy, child_phy);
1110                                 } else if (child_phy->routing_attr != TABLE_ROUTING) {
1111                                         sas_print_parent_topology_bug(child, parent_phy, child_phy);
1112                                         res = -ENODEV;
1113                                 }
1114                         } else if (parent_phy->routing_attr == TABLE_ROUTING &&
1115                                    child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1116                                 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1117                                 res = -ENODEV;
1118                         }
1119                         break;
1120                 case FANOUT_DEV:
1121                         if (parent_phy->routing_attr != TABLE_ROUTING ||
1122                             child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1123                                 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1124                                 res = -ENODEV;
1125                         }
1126                         break;
1127                 default:
1128                         break;
1129                 }
1130         }
1131
1132         return res;
1133 }
1134
1135 #define RRI_REQ_SIZE  16
1136 #define RRI_RESP_SIZE 44
1137
1138 static int sas_configure_present(struct domain_device *dev, int phy_id,
1139                                  u8 *sas_addr, int *index, int *present)
1140 {
1141         int i, res = 0;
1142         struct expander_device *ex = &dev->ex_dev;
1143         struct ex_phy *phy = &ex->ex_phy[phy_id];
1144         u8 *rri_req;
1145         u8 *rri_resp;
1146
1147         *present = 0;
1148         *index = 0;
1149
1150         rri_req = alloc_smp_req(RRI_REQ_SIZE);
1151         if (!rri_req)
1152                 return -ENOMEM;
1153
1154         rri_resp = alloc_smp_resp(RRI_RESP_SIZE);
1155         if (!rri_resp) {
1156                 kfree(rri_req);
1157                 return -ENOMEM;
1158         }
1159
1160         rri_req[1] = SMP_REPORT_ROUTE_INFO;
1161         rri_req[9] = phy_id;
1162
1163         for (i = 0; i < ex->max_route_indexes ; i++) {
1164                 *(__be16 *)(rri_req+6) = cpu_to_be16(i);
1165                 res = smp_execute_task(dev, rri_req, RRI_REQ_SIZE, rri_resp,
1166                                        RRI_RESP_SIZE);
1167                 if (res)
1168                         goto out;
1169                 res = rri_resp[2];
1170                 if (res == SMP_RESP_NO_INDEX) {
1171                         SAS_DPRINTK("overflow of indexes: dev %016llx "
1172                                     "phy 0x%x index 0x%x\n",
1173                                     SAS_ADDR(dev->sas_addr), phy_id, i);
1174                         goto out;
1175                 } else if (res != SMP_RESP_FUNC_ACC) {
1176                         SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x "
1177                                     "result 0x%x\n", __FUNCTION__,
1178                                     SAS_ADDR(dev->sas_addr), phy_id, i, res);
1179                         goto out;
1180                 }
1181                 if (SAS_ADDR(sas_addr) != 0) {
1182                         if (SAS_ADDR(rri_resp+16) == SAS_ADDR(sas_addr)) {
1183                                 *index = i;
1184                                 if ((rri_resp[12] & 0x80) == 0x80)
1185                                         *present = 0;
1186                                 else
1187                                         *present = 1;
1188                                 goto out;
1189                         } else if (SAS_ADDR(rri_resp+16) == 0) {
1190                                 *index = i;
1191                                 *present = 0;
1192                                 goto out;
1193                         }
1194                 } else if (SAS_ADDR(rri_resp+16) == 0 &&
1195                            phy->last_da_index < i) {
1196                         phy->last_da_index = i;
1197                         *index = i;
1198                         *present = 0;
1199                         goto out;
1200                 }
1201         }
1202         res = -1;
1203 out:
1204         kfree(rri_req);
1205         kfree(rri_resp);
1206         return res;
1207 }
1208
1209 #define CRI_REQ_SIZE  44
1210 #define CRI_RESP_SIZE  8
1211
1212 static int sas_configure_set(struct domain_device *dev, int phy_id,
1213                              u8 *sas_addr, int index, int include)
1214 {
1215         int res;
1216         u8 *cri_req;
1217         u8 *cri_resp;
1218
1219         cri_req = alloc_smp_req(CRI_REQ_SIZE);
1220         if (!cri_req)
1221                 return -ENOMEM;
1222
1223         cri_resp = alloc_smp_resp(CRI_RESP_SIZE);
1224         if (!cri_resp) {
1225                 kfree(cri_req);
1226                 return -ENOMEM;
1227         }
1228
1229         cri_req[1] = SMP_CONF_ROUTE_INFO;
1230         *(__be16 *)(cri_req+6) = cpu_to_be16(index);
1231         cri_req[9] = phy_id;
1232         if (SAS_ADDR(sas_addr) == 0 || !include)
1233                 cri_req[12] |= 0x80;
1234         memcpy(cri_req+16, sas_addr, SAS_ADDR_SIZE);
1235
1236         res = smp_execute_task(dev, cri_req, CRI_REQ_SIZE, cri_resp,
1237                                CRI_RESP_SIZE);
1238         if (res)
1239                 goto out;
1240         res = cri_resp[2];
1241         if (res == SMP_RESP_NO_INDEX) {
1242                 SAS_DPRINTK("overflow of indexes: dev %016llx phy 0x%x "
1243                             "index 0x%x\n",
1244                             SAS_ADDR(dev->sas_addr), phy_id, index);
1245         }
1246 out:
1247         kfree(cri_req);
1248         kfree(cri_resp);
1249         return res;
1250 }
1251
1252 static int sas_configure_phy(struct domain_device *dev, int phy_id,
1253                                     u8 *sas_addr, int include)
1254 {
1255         int index;
1256         int present;
1257         int res;
1258
1259         res = sas_configure_present(dev, phy_id, sas_addr, &index, &present);
1260         if (res)
1261                 return res;
1262         if (include ^ present)
1263                 return sas_configure_set(dev, phy_id, sas_addr, index,include);
1264
1265         return res;
1266 }
1267
1268 /**
1269  * sas_configure_parent -- configure routing table of parent
1270  * parent: parent expander
1271  * child: child expander
1272  * sas_addr: SAS port identifier of device directly attached to child
1273  */
1274 static int sas_configure_parent(struct domain_device *parent,
1275                                 struct domain_device *child,
1276                                 u8 *sas_addr, int include)
1277 {
1278         struct expander_device *ex_parent = &parent->ex_dev;
1279         int res = 0;
1280         int i;
1281
1282         if (parent->parent) {
1283                 res = sas_configure_parent(parent->parent, parent, sas_addr,
1284                                            include);
1285                 if (res)
1286                         return res;
1287         }
1288
1289         if (ex_parent->conf_route_table == 0) {
1290                 SAS_DPRINTK("ex %016llx has self-configuring routing table\n",
1291                             SAS_ADDR(parent->sas_addr));
1292                 return 0;
1293         }
1294
1295         for (i = 0; i < ex_parent->num_phys; i++) {
1296                 struct ex_phy *phy = &ex_parent->ex_phy[i];
1297
1298                 if ((phy->routing_attr == TABLE_ROUTING) &&
1299                     (SAS_ADDR(phy->attached_sas_addr) ==
1300                      SAS_ADDR(child->sas_addr))) {
1301                         res = sas_configure_phy(parent, i, sas_addr, include);
1302                         if (res)
1303                                 return res;
1304                 }
1305         }
1306
1307         return res;
1308 }
1309
1310 /**
1311  * sas_configure_routing -- configure routing
1312  * dev: expander device
1313  * sas_addr: port identifier of device directly attached to the expander device
1314  */
1315 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
1316 {
1317         if (dev->parent)
1318                 return sas_configure_parent(dev->parent, dev, sas_addr, 1);
1319         return 0;
1320 }
1321
1322 static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr)
1323 {
1324         if (dev->parent)
1325                 return sas_configure_parent(dev->parent, dev, sas_addr, 0);
1326         return 0;
1327 }
1328
1329 #if 0
1330 #define SMP_BIN_ATTR_NAME "smp_portal"
1331
1332 static void sas_ex_smp_hook(struct domain_device *dev)
1333 {
1334         struct expander_device *ex_dev = &dev->ex_dev;
1335         struct bin_attribute *bin_attr = &ex_dev->smp_bin_attr;
1336
1337         memset(bin_attr, 0, sizeof(*bin_attr));
1338
1339         bin_attr->attr.name = SMP_BIN_ATTR_NAME;
1340         bin_attr->attr.owner = THIS_MODULE;
1341         bin_attr->attr.mode = 0600;
1342
1343         bin_attr->size = 0;
1344         bin_attr->private = NULL;
1345         bin_attr->read = smp_portal_read;
1346         bin_attr->write= smp_portal_write;
1347         bin_attr->mmap = NULL;
1348
1349         ex_dev->smp_portal_pid = -1;
1350         init_MUTEX(&ex_dev->smp_sema);
1351 }
1352 #endif
1353
1354 /**
1355  * sas_discover_expander -- expander discovery
1356  * @ex: pointer to expander domain device
1357  *
1358  * See comment in sas_discover_sata().
1359  */
1360 static int sas_discover_expander(struct domain_device *dev)
1361 {
1362         int res;
1363
1364         res = sas_notify_lldd_dev_found(dev);
1365         if (res)
1366                 return res;
1367
1368         res = sas_ex_general(dev);
1369         if (res)
1370                 goto out_err;
1371         res = sas_ex_manuf_info(dev);
1372         if (res)
1373                 goto out_err;
1374
1375         res = sas_expander_discover(dev);
1376         if (res) {
1377                 SAS_DPRINTK("expander %016llx discovery failed(0x%x)\n",
1378                             SAS_ADDR(dev->sas_addr), res);
1379                 goto out_err;
1380         }
1381
1382         sas_check_ex_subtractive_boundary(dev);
1383         res = sas_check_parent_topology(dev);
1384         if (res)
1385                 goto out_err;
1386         return 0;
1387 out_err:
1388         sas_notify_lldd_dev_gone(dev);
1389         return res;
1390 }
1391
1392 static int sas_ex_level_discovery(struct asd_sas_port *port, const int level)
1393 {
1394         int res = 0;
1395         struct domain_device *dev;
1396
1397         list_for_each_entry(dev, &port->dev_list, dev_list_node) {
1398                 if (dev->dev_type == EDGE_DEV ||
1399                     dev->dev_type == FANOUT_DEV) {
1400                         struct sas_expander_device *ex =
1401                                 rphy_to_expander_device(dev->rphy);
1402
1403                         if (level == ex->level)
1404                                 res = sas_ex_discover_devices(dev, -1);
1405                         else if (level > 0)
1406                                 res = sas_ex_discover_devices(port->port_dev, -1);
1407
1408                 }
1409         }
1410
1411         return res;
1412 }
1413
1414 static int sas_ex_bfs_disc(struct asd_sas_port *port)
1415 {
1416         int res;
1417         int level;
1418
1419         do {
1420                 level = port->disc.max_level;
1421                 res = sas_ex_level_discovery(port, level);
1422                 mb();
1423         } while (level < port->disc.max_level);
1424
1425         return res;
1426 }
1427
1428 int sas_discover_root_expander(struct domain_device *dev)
1429 {
1430         int res;
1431         struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1432
1433         res = sas_rphy_add(dev->rphy);
1434         if (res)
1435                 goto out_err;
1436
1437         ex->level = dev->port->disc.max_level; /* 0 */
1438         res = sas_discover_expander(dev);
1439         if (res)
1440                 goto out_err2;
1441
1442         sas_ex_bfs_disc(dev->port);
1443
1444         return res;
1445
1446 out_err2:
1447         sas_rphy_delete(dev->rphy);
1448         dev->rphy = NULL;
1449         return res;
1450 out_err:
1451         sas_rphy_free(dev->rphy);
1452         dev->rphy = NULL;
1453         return res;
1454 }
1455
1456 /* ---------- Domain revalidation ---------- */
1457
1458 static int sas_get_phy_discover(struct domain_device *dev,
1459                                 int phy_id, struct smp_resp *disc_resp)
1460 {
1461         int res;
1462         u8 *disc_req;
1463
1464         disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
1465         if (!disc_req)
1466                 return -ENOMEM;
1467
1468         disc_req[1] = SMP_DISCOVER;
1469         disc_req[9] = phy_id;
1470
1471         res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
1472                                disc_resp, DISCOVER_RESP_SIZE);
1473         if (res)
1474                 goto out;
1475         else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
1476                 res = disc_resp->result;
1477                 goto out;
1478         }
1479 out:
1480         kfree(disc_req);
1481         return res;
1482 }
1483
1484 static int sas_get_phy_change_count(struct domain_device *dev,
1485                                     int phy_id, int *pcc)
1486 {
1487         int res;
1488         struct smp_resp *disc_resp;
1489
1490         disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1491         if (!disc_resp)
1492                 return -ENOMEM;
1493
1494         res = sas_get_phy_discover(dev, phy_id, disc_resp);
1495         if (!res)
1496                 *pcc = disc_resp->disc.change_count;
1497
1498         kfree(disc_resp);
1499         return res;
1500 }
1501
1502 static int sas_get_phy_attached_sas_addr(struct domain_device *dev,
1503                                          int phy_id, u8 *attached_sas_addr)
1504 {
1505         int res;
1506         struct smp_resp *disc_resp;
1507         struct discover_resp *dr;
1508
1509         disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1510         if (!disc_resp)
1511                 return -ENOMEM;
1512         dr = &disc_resp->disc;
1513
1514         res = sas_get_phy_discover(dev, phy_id, disc_resp);
1515         if (!res) {
1516                 memcpy(attached_sas_addr,disc_resp->disc.attached_sas_addr,8);
1517                 if (dr->attached_dev_type == 0)
1518                         memset(attached_sas_addr, 0, 8);
1519         }
1520         kfree(disc_resp);
1521         return res;
1522 }
1523
1524 static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
1525                               int from_phy)
1526 {
1527         struct expander_device *ex = &dev->ex_dev;
1528         int res = 0;
1529         int i;
1530
1531         for (i = from_phy; i < ex->num_phys; i++) {
1532                 int phy_change_count = 0;
1533
1534                 res = sas_get_phy_change_count(dev, i, &phy_change_count);
1535                 if (res)
1536                         goto out;
1537                 else if (phy_change_count != ex->ex_phy[i].phy_change_count) {
1538                         ex->ex_phy[i].phy_change_count = phy_change_count;
1539                         *phy_id = i;
1540                         return 0;
1541                 }
1542         }
1543 out:
1544         return res;
1545 }
1546
1547 static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
1548 {
1549         int res;
1550         u8  *rg_req;
1551         struct smp_resp  *rg_resp;
1552
1553         rg_req = alloc_smp_req(RG_REQ_SIZE);
1554         if (!rg_req)
1555                 return -ENOMEM;
1556
1557         rg_resp = alloc_smp_resp(RG_RESP_SIZE);
1558         if (!rg_resp) {
1559                 kfree(rg_req);
1560                 return -ENOMEM;
1561         }
1562
1563         rg_req[1] = SMP_REPORT_GENERAL;
1564
1565         res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
1566                                RG_RESP_SIZE);
1567         if (res)
1568                 goto out;
1569         if (rg_resp->result != SMP_RESP_FUNC_ACC) {
1570                 res = rg_resp->result;
1571                 goto out;
1572         }
1573
1574         *ecc = be16_to_cpu(rg_resp->rg.change_count);
1575 out:
1576         kfree(rg_resp);
1577         kfree(rg_req);
1578         return res;
1579 }
1580
1581 static int sas_find_bcast_dev(struct domain_device *dev,
1582                               struct domain_device **src_dev)
1583 {
1584         struct expander_device *ex = &dev->ex_dev;
1585         int ex_change_count = -1;
1586         int res;
1587
1588         res = sas_get_ex_change_count(dev, &ex_change_count);
1589         if (res)
1590                 goto out;
1591         if (ex_change_count != -1 &&
1592             ex_change_count != ex->ex_change_count) {
1593                 *src_dev = dev;
1594                 ex->ex_change_count = ex_change_count;
1595         } else {
1596                 struct domain_device *ch;
1597
1598                 list_for_each_entry(ch, &ex->children, siblings) {
1599                         if (ch->dev_type == EDGE_DEV ||
1600                             ch->dev_type == FANOUT_DEV) {
1601                                 res = sas_find_bcast_dev(ch, src_dev);
1602                                 if (src_dev)
1603                                         return res;
1604                         }
1605                 }
1606         }
1607 out:
1608         return res;
1609 }
1610
1611 static void sas_unregister_ex_tree(struct domain_device *dev)
1612 {
1613         struct expander_device *ex = &dev->ex_dev;
1614         struct domain_device *child, *n;
1615
1616         list_for_each_entry_safe(child, n, &ex->children, siblings) {
1617                 if (child->dev_type == EDGE_DEV ||
1618                     child->dev_type == FANOUT_DEV)
1619                         sas_unregister_ex_tree(child);
1620                 else
1621                         sas_unregister_dev(child);
1622         }
1623         sas_unregister_dev(dev);
1624 }
1625
1626 static void sas_unregister_devs_sas_addr(struct domain_device *parent,
1627                                          int phy_id)
1628 {
1629         struct expander_device *ex_dev = &parent->ex_dev;
1630         struct ex_phy *phy = &ex_dev->ex_phy[phy_id];
1631         struct domain_device *child, *n;
1632
1633         list_for_each_entry_safe(child, n, &ex_dev->children, siblings) {
1634                 if (SAS_ADDR(child->sas_addr) ==
1635                     SAS_ADDR(phy->attached_sas_addr)) {
1636                         if (child->dev_type == EDGE_DEV ||
1637                             child->dev_type == FANOUT_DEV)
1638                                 sas_unregister_ex_tree(child);
1639                         else
1640                                 sas_unregister_dev(child);
1641                         break;
1642                 }
1643         }
1644         sas_disable_routing(parent, phy->attached_sas_addr);
1645         memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
1646         sas_port_delete_phy(phy->port, phy->phy);
1647         if (phy->port->num_phys == 0)
1648                 sas_port_delete(phy->port);
1649         phy->port = NULL;
1650 }
1651
1652 static int sas_discover_bfs_by_root_level(struct domain_device *root,
1653                                           const int level)
1654 {
1655         struct expander_device *ex_root = &root->ex_dev;
1656         struct domain_device *child;
1657         int res = 0;
1658
1659         list_for_each_entry(child, &ex_root->children, siblings) {
1660                 if (child->dev_type == EDGE_DEV ||
1661                     child->dev_type == FANOUT_DEV) {
1662                         struct sas_expander_device *ex =
1663                                 rphy_to_expander_device(child->rphy);
1664
1665                         if (level > ex->level)
1666                                 res = sas_discover_bfs_by_root_level(child,
1667                                                                      level);
1668                         else if (level == ex->level)
1669                                 res = sas_ex_discover_devices(child, -1);
1670                 }
1671         }
1672         return res;
1673 }
1674
1675 static int sas_discover_bfs_by_root(struct domain_device *dev)
1676 {
1677         int res;
1678         struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1679         int level = ex->level+1;
1680
1681         res = sas_ex_discover_devices(dev, -1);
1682         if (res)
1683                 goto out;
1684         do {
1685                 res = sas_discover_bfs_by_root_level(dev, level);
1686                 mb();
1687                 level += 1;
1688         } while (level <= dev->port->disc.max_level);
1689 out:
1690         return res;
1691 }
1692
1693 static int sas_discover_new(struct domain_device *dev, int phy_id)
1694 {
1695         struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
1696         struct domain_device *child;
1697         int res;
1698
1699         SAS_DPRINTK("ex %016llx phy%d new device attached\n",
1700                     SAS_ADDR(dev->sas_addr), phy_id);
1701         res = sas_ex_phy_discover(dev, phy_id);
1702         if (res)
1703                 goto out;
1704         res = sas_ex_discover_devices(dev, phy_id);
1705         if (res)
1706                 goto out;
1707         list_for_each_entry(child, &dev->ex_dev.children, siblings) {
1708                 if (SAS_ADDR(child->sas_addr) ==
1709                     SAS_ADDR(ex_phy->attached_sas_addr)) {
1710                         if (child->dev_type == EDGE_DEV ||
1711                             child->dev_type == FANOUT_DEV)
1712                                 res = sas_discover_bfs_by_root(child);
1713                         break;
1714                 }
1715         }
1716 out:
1717         return res;
1718 }
1719
1720 static int sas_rediscover_dev(struct domain_device *dev, int phy_id)
1721 {
1722         struct expander_device *ex = &dev->ex_dev;
1723         struct ex_phy *phy = &ex->ex_phy[phy_id];
1724         u8 attached_sas_addr[8];
1725         int res;
1726
1727         res = sas_get_phy_attached_sas_addr(dev, phy_id, attached_sas_addr);
1728         switch (res) {
1729         case SMP_RESP_NO_PHY:
1730                 phy->phy_state = PHY_NOT_PRESENT;
1731                 sas_unregister_devs_sas_addr(dev, phy_id);
1732                 goto out; break;
1733         case SMP_RESP_PHY_VACANT:
1734                 phy->phy_state = PHY_VACANT;
1735                 sas_unregister_devs_sas_addr(dev, phy_id);
1736                 goto out; break;
1737         case SMP_RESP_FUNC_ACC:
1738                 break;
1739         }
1740
1741         if (SAS_ADDR(attached_sas_addr) == 0) {
1742                 phy->phy_state = PHY_EMPTY;
1743                 sas_unregister_devs_sas_addr(dev, phy_id);
1744         } else if (SAS_ADDR(attached_sas_addr) ==
1745                    SAS_ADDR(phy->attached_sas_addr)) {
1746                 SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n",
1747                             SAS_ADDR(dev->sas_addr), phy_id);
1748                 sas_ex_phy_discover(dev, phy_id);
1749         } else
1750                 res = sas_discover_new(dev, phy_id);
1751 out:
1752         return res;
1753 }
1754
1755 static int sas_rediscover(struct domain_device *dev, const int phy_id)
1756 {
1757         struct expander_device *ex = &dev->ex_dev;
1758         struct ex_phy *changed_phy = &ex->ex_phy[phy_id];
1759         int res = 0;
1760         int i;
1761
1762         SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n",
1763                     SAS_ADDR(dev->sas_addr), phy_id);
1764
1765         if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) {
1766                 for (i = 0; i < ex->num_phys; i++) {
1767                         struct ex_phy *phy = &ex->ex_phy[i];
1768
1769                         if (i == phy_id)
1770                                 continue;
1771                         if (SAS_ADDR(phy->attached_sas_addr) ==
1772                             SAS_ADDR(changed_phy->attached_sas_addr)) {
1773                                 SAS_DPRINTK("phy%d part of wide port with "
1774                                             "phy%d\n", phy_id, i);
1775                                 goto out;
1776                         }
1777                 }
1778                 res = sas_rediscover_dev(dev, phy_id);
1779         } else
1780                 res = sas_discover_new(dev, phy_id);
1781 out:
1782         return res;
1783 }
1784
1785 /**
1786  * sas_revalidate_domain -- revalidate the domain
1787  * @port: port to the domain of interest
1788  *
1789  * NOTE: this process _must_ quit (return) as soon as any connection
1790  * errors are encountered.  Connection recovery is done elsewhere.
1791  * Discover process only interrogates devices in order to discover the
1792  * domain.
1793  */
1794 int sas_ex_revalidate_domain(struct domain_device *port_dev)
1795 {
1796         int res;
1797         struct domain_device *dev = NULL;
1798
1799         res = sas_find_bcast_dev(port_dev, &dev);
1800         if (res)
1801                 goto out;
1802         if (dev) {
1803                 struct expander_device *ex = &dev->ex_dev;
1804                 int i = 0, phy_id;
1805
1806                 do {
1807                         phy_id = -1;
1808                         res = sas_find_bcast_phy(dev, &phy_id, i);
1809                         if (phy_id == -1)
1810                                 break;
1811                         res = sas_rediscover(dev, phy_id);
1812                         i = phy_id + 1;
1813                 } while (i < ex->num_phys);
1814         }
1815 out:
1816         return res;
1817 }
1818
1819 #if 0
1820 /* ---------- SMP portal ---------- */
1821
1822 static ssize_t smp_portal_write(struct kobject *kobj, char *buf, loff_t offs,
1823                                 size_t size)
1824 {
1825         struct domain_device *dev = to_dom_device(kobj);
1826         struct expander_device *ex = &dev->ex_dev;
1827
1828         if (offs != 0)
1829                 return -EFBIG;
1830         else if (size == 0)
1831                 return 0;
1832
1833         down_interruptible(&ex->smp_sema);
1834         if (ex->smp_req)
1835                 kfree(ex->smp_req);
1836         ex->smp_req = kzalloc(size, GFP_USER);
1837         if (!ex->smp_req) {
1838                 up(&ex->smp_sema);
1839                 return -ENOMEM;
1840         }
1841         memcpy(ex->smp_req, buf, size);
1842         ex->smp_req_size = size;
1843         ex->smp_portal_pid = current->pid;
1844         up(&ex->smp_sema);
1845
1846         return size;
1847 }
1848
1849 static ssize_t smp_portal_read(struct kobject *kobj, char *buf, loff_t offs,
1850                                size_t size)
1851 {
1852         struct domain_device *dev = to_dom_device(kobj);
1853         struct expander_device *ex = &dev->ex_dev;
1854         u8 *smp_resp;
1855         int res = -EINVAL;
1856
1857         /* XXX: sysfs gives us an offset of 0x10 or 0x8 while in fact
1858          *  it should be 0.
1859          */
1860
1861         down_interruptible(&ex->smp_sema);
1862         if (!ex->smp_req || ex->smp_portal_pid != current->pid)
1863                 goto out;
1864
1865         res = 0;
1866         if (size == 0)
1867                 goto out;
1868
1869         res = -ENOMEM;
1870         smp_resp = alloc_smp_resp(size);
1871         if (!smp_resp)
1872                 goto out;
1873         res = smp_execute_task(dev, ex->smp_req, ex->smp_req_size,
1874                                smp_resp, size);
1875         if (!res) {
1876                 memcpy(buf, smp_resp, size);
1877                 res = size;
1878         }
1879
1880         kfree(smp_resp);
1881 out:
1882         kfree(ex->smp_req);
1883         ex->smp_req = NULL;
1884         ex->smp_req_size = 0;
1885         ex->smp_portal_pid = -1;
1886         up(&ex->smp_sema);
1887         return res;
1888 }
1889 #endif