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