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