sas_expander.c (55789B)
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}