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