1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Serial Attached SCSI (SAS) Discover process 4 * 5 * Copyright (C) 2005 Adaptec, Inc. All rights reserved. 6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> 7 */ 8 9 #include <linux/scatterlist.h> 10 #include <linux/slab.h> 11 #include <linux/async.h> 12 #include <scsi/scsi_host.h> 13 #include <scsi/scsi_eh.h> 14 #include "sas_internal.h" 15 16 #include <scsi/scsi_transport.h> 17 #include <scsi/scsi_transport_sas.h> 18 #include <scsi/sas_ata.h> 19 #include "../scsi_sas_internal.h" 20 21 /* ---------- Basic task processing for discovery purposes ---------- */ 22 23 void sas_init_dev(struct domain_device *dev) 24 { 25 switch (dev->dev_type) { 26 case SAS_END_DEVICE: 27 INIT_LIST_HEAD(&dev->ssp_dev.eh_list_node); 28 break; 29 case SAS_EDGE_EXPANDER_DEVICE: 30 case SAS_FANOUT_EXPANDER_DEVICE: 31 INIT_LIST_HEAD(&dev->ex_dev.children); 32 mutex_init(&dev->ex_dev.cmd_mutex); 33 break; 34 default: 35 break; 36 } 37 } 38 39 /* ---------- Domain device discovery ---------- */ 40 41 /** 42 * sas_get_port_device - Discover devices which caused port creation 43 * @port: pointer to struct sas_port of interest 44 * 45 * Devices directly attached to a HA port, have no parent. This is 46 * how we know they are (domain) "root" devices. All other devices 47 * do, and should have their "parent" pointer set appropriately as 48 * soon as a child device is discovered. 49 */ 50 static int sas_get_port_device(struct asd_sas_port *port) 51 { 52 struct asd_sas_phy *phy; 53 struct sas_rphy *rphy; 54 struct domain_device *dev; 55 int rc = -ENODEV; 56 57 dev = sas_alloc_device(); 58 if (!dev) 59 return -ENOMEM; 60 61 spin_lock_irq(&port->phy_list_lock); 62 if (list_empty(&port->phy_list)) { 63 spin_unlock_irq(&port->phy_list_lock); 64 sas_put_device(dev); 65 return -ENODEV; 66 } 67 phy = container_of(port->phy_list.next, struct asd_sas_phy, port_phy_el); 68 spin_lock(&phy->frame_rcvd_lock); 69 memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd), 70 (size_t)phy->frame_rcvd_size)); 71 spin_unlock(&phy->frame_rcvd_lock); 72 spin_unlock_irq(&port->phy_list_lock); 73 74 if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) { 75 struct dev_to_host_fis *fis = 76 (struct dev_to_host_fis *) dev->frame_rcvd; 77 if (fis->interrupt_reason == 1 && fis->lbal == 1 && 78 fis->byte_count_low==0x69 && fis->byte_count_high == 0x96 79 && (fis->device & ~0x10) == 0) 80 dev->dev_type = SAS_SATA_PM; 81 else 82 dev->dev_type = SAS_SATA_DEV; 83 dev->tproto = SAS_PROTOCOL_SATA; 84 } else if (port->oob_mode == SAS_OOB_MODE) { 85 struct sas_identify_frame *id = 86 (struct sas_identify_frame *) dev->frame_rcvd; 87 dev->dev_type = id->dev_type; 88 dev->iproto = id->initiator_bits; 89 dev->tproto = id->target_bits; 90 } else { 91 /* If the oob mode is OOB_NOT_CONNECTED, the port is 92 * disconnected due to race with PHY down. We cannot 93 * continue to discover this port 94 */ 95 sas_put_device(dev); 96 pr_warn("Port %016llx is disconnected when discovering\n", 97 SAS_ADDR(port->attached_sas_addr)); 98 return -ENODEV; 99 } 100 101 sas_init_dev(dev); 102 103 dev->port = port; 104 switch (dev->dev_type) { 105 case SAS_SATA_DEV: 106 rc = sas_ata_init(dev); 107 if (rc) { 108 rphy = NULL; 109 break; 110 } 111 /* fall through */ 112 case SAS_END_DEVICE: 113 rphy = sas_end_device_alloc(port->port); 114 break; 115 case SAS_EDGE_EXPANDER_DEVICE: 116 rphy = sas_expander_alloc(port->port, 117 SAS_EDGE_EXPANDER_DEVICE); 118 break; 119 case SAS_FANOUT_EXPANDER_DEVICE: 120 rphy = sas_expander_alloc(port->port, 121 SAS_FANOUT_EXPANDER_DEVICE); 122 break; 123 default: 124 pr_warn("ERROR: Unidentified device type %d\n", dev->dev_type); 125 rphy = NULL; 126 break; 127 } 128 129 if (!rphy) { 130 sas_put_device(dev); 131 return rc; 132 } 133 134 rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; 135 memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); 136 sas_fill_in_rphy(dev, rphy); 137 sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); 138 port->port_dev = dev; 139 dev->linkrate = port->linkrate; 140 dev->min_linkrate = port->linkrate; 141 dev->max_linkrate = port->linkrate; 142 dev->pathways = port->num_phys; 143 memset(port->disc.fanout_sas_addr, 0, SAS_ADDR_SIZE); 144 memset(port->disc.eeds_a, 0, SAS_ADDR_SIZE); 145 memset(port->disc.eeds_b, 0, SAS_ADDR_SIZE); 146 port->disc.max_level = 0; 147 sas_device_set_phy(dev, port->port); 148 149 dev->rphy = rphy; 150 get_device(&dev->rphy->dev); 151 152 if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEVICE) 153 list_add_tail(&dev->disco_list_node, &port->disco_list); 154 else { 155 spin_lock_irq(&port->dev_list_lock); 156 list_add_tail(&dev->dev_list_node, &port->dev_list); 157 spin_unlock_irq(&port->dev_list_lock); 158 } 159 160 spin_lock_irq(&port->phy_list_lock); 161 list_for_each_entry(phy, &port->phy_list, port_phy_el) 162 sas_phy_set_target(phy, dev); 163 spin_unlock_irq(&port->phy_list_lock); 164 165 return 0; 166 } 167 168 /* ---------- Discover and Revalidate ---------- */ 169 170 int sas_notify_lldd_dev_found(struct domain_device *dev) 171 { 172 int res = 0; 173 struct sas_ha_struct *sas_ha = dev->port->ha; 174 struct Scsi_Host *shost = sas_ha->core.shost; 175 struct sas_internal *i = to_sas_internal(shost->transportt); 176 177 if (!i->dft->lldd_dev_found) 178 return 0; 179 180 res = i->dft->lldd_dev_found(dev); 181 if (res) { 182 pr_warn("driver on host %s cannot handle device %llx, error:%d\n", 183 dev_name(sas_ha->dev), 184 SAS_ADDR(dev->sas_addr), res); 185 } 186 set_bit(SAS_DEV_FOUND, &dev->state); 187 kref_get(&dev->kref); 188 return res; 189 } 190 191 192 void sas_notify_lldd_dev_gone(struct domain_device *dev) 193 { 194 struct sas_ha_struct *sas_ha = dev->port->ha; 195 struct Scsi_Host *shost = sas_ha->core.shost; 196 struct sas_internal *i = to_sas_internal(shost->transportt); 197 198 if (!i->dft->lldd_dev_gone) 199 return; 200 201 if (test_and_clear_bit(SAS_DEV_FOUND, &dev->state)) { 202 i->dft->lldd_dev_gone(dev); 203 sas_put_device(dev); 204 } 205 } 206 207 static void sas_probe_devices(struct asd_sas_port *port) 208 { 209 struct domain_device *dev, *n; 210 211 /* devices must be domain members before link recovery and probe */ 212 list_for_each_entry(dev, &port->disco_list, disco_list_node) { 213 spin_lock_irq(&port->dev_list_lock); 214 list_add_tail(&dev->dev_list_node, &port->dev_list); 215 spin_unlock_irq(&port->dev_list_lock); 216 } 217 218 sas_probe_sata(port); 219 220 list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { 221 int err; 222 223 err = sas_rphy_add(dev->rphy); 224 if (err) 225 sas_fail_probe(dev, __func__, err); 226 else 227 list_del_init(&dev->disco_list_node); 228 } 229 } 230 231 static void sas_suspend_devices(struct work_struct *work) 232 { 233 struct asd_sas_phy *phy; 234 struct domain_device *dev; 235 struct sas_discovery_event *ev = to_sas_discovery_event(work); 236 struct asd_sas_port *port = ev->port; 237 struct Scsi_Host *shost = port->ha->core.shost; 238 struct sas_internal *si = to_sas_internal(shost->transportt); 239 240 clear_bit(DISCE_SUSPEND, &port->disc.pending); 241 242 sas_suspend_sata(port); 243 244 /* lldd is free to forget the domain_device across the 245 * suspension, we force the issue here to keep the reference 246 * counts aligned 247 */ 248 list_for_each_entry(dev, &port->dev_list, dev_list_node) 249 sas_notify_lldd_dev_gone(dev); 250 251 /* we are suspending, so we know events are disabled and 252 * phy_list is not being mutated 253 */ 254 list_for_each_entry(phy, &port->phy_list, port_phy_el) { 255 if (si->dft->lldd_port_deformed) 256 si->dft->lldd_port_deformed(phy); 257 phy->suspended = 1; 258 port->suspended = 1; 259 } 260 } 261 262 static void sas_resume_devices(struct work_struct *work) 263 { 264 struct sas_discovery_event *ev = to_sas_discovery_event(work); 265 struct asd_sas_port *port = ev->port; 266 267 clear_bit(DISCE_RESUME, &port->disc.pending); 268 269 sas_resume_sata(port); 270 } 271 272 /** 273 * sas_discover_end_dev - discover an end device (SSP, etc) 274 * @dev: pointer to domain device of interest 275 * 276 * See comment in sas_discover_sata(). 277 */ 278 int sas_discover_end_dev(struct domain_device *dev) 279 { 280 int res; 281 282 res = sas_notify_lldd_dev_found(dev); 283 if (res) 284 return res; 285 286 return 0; 287 } 288 289 /* ---------- Device registration and unregistration ---------- */ 290 291 void sas_free_device(struct kref *kref) 292 { 293 struct domain_device *dev = container_of(kref, typeof(*dev), kref); 294 295 put_device(&dev->rphy->dev); 296 dev->rphy = NULL; 297 298 if (dev->parent) 299 sas_put_device(dev->parent); 300 301 sas_port_put_phy(dev->phy); 302 dev->phy = NULL; 303 304 /* remove the phys and ports, everything else should be gone */ 305 if (dev_is_expander(dev->dev_type)) 306 kfree(dev->ex_dev.ex_phy); 307 308 if (dev_is_sata(dev) && dev->sata_dev.ap) { 309 ata_sas_tport_delete(dev->sata_dev.ap); 310 ata_sas_port_destroy(dev->sata_dev.ap); 311 ata_host_put(dev->sata_dev.ata_host); 312 dev->sata_dev.ata_host = NULL; 313 dev->sata_dev.ap = NULL; 314 } 315 316 kfree(dev); 317 } 318 319 static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_device *dev) 320 { 321 struct sas_ha_struct *ha = port->ha; 322 323 sas_notify_lldd_dev_gone(dev); 324 if (!dev->parent) 325 dev->port->port_dev = NULL; 326 else 327 list_del_init(&dev->siblings); 328 329 spin_lock_irq(&port->dev_list_lock); 330 list_del_init(&dev->dev_list_node); 331 if (dev_is_sata(dev)) 332 sas_ata_end_eh(dev->sata_dev.ap); 333 spin_unlock_irq(&port->dev_list_lock); 334 335 spin_lock_irq(&ha->lock); 336 if (dev->dev_type == SAS_END_DEVICE && 337 !list_empty(&dev->ssp_dev.eh_list_node)) { 338 list_del_init(&dev->ssp_dev.eh_list_node); 339 ha->eh_active--; 340 } 341 spin_unlock_irq(&ha->lock); 342 343 sas_put_device(dev); 344 } 345 346 void sas_destruct_devices(struct asd_sas_port *port) 347 { 348 struct domain_device *dev, *n; 349 350 list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) { 351 list_del_init(&dev->disco_list_node); 352 353 sas_remove_children(&dev->rphy->dev); 354 sas_rphy_delete(dev->rphy); 355 sas_unregister_common_dev(port, dev); 356 } 357 } 358 359 static void sas_destruct_ports(struct asd_sas_port *port) 360 { 361 struct sas_port *sas_port, *p; 362 363 list_for_each_entry_safe(sas_port, p, &port->sas_port_del_list, del_list) { 364 list_del_init(&sas_port->del_list); 365 sas_port_delete(sas_port); 366 } 367 } 368 369 void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) 370 { 371 if (!test_bit(SAS_DEV_DESTROY, &dev->state) && 372 !list_empty(&dev->disco_list_node)) { 373 /* this rphy never saw sas_rphy_add */ 374 list_del_init(&dev->disco_list_node); 375 sas_rphy_free(dev->rphy); 376 sas_unregister_common_dev(port, dev); 377 return; 378 } 379 380 if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { 381 sas_rphy_unlink(dev->rphy); 382 list_move_tail(&dev->disco_list_node, &port->destroy_list); 383 } 384 } 385 386 void sas_unregister_domain_devices(struct asd_sas_port *port, int gone) 387 { 388 struct domain_device *dev, *n; 389 390 list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node) { 391 if (gone) 392 set_bit(SAS_DEV_GONE, &dev->state); 393 sas_unregister_dev(port, dev); 394 } 395 396 list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) 397 sas_unregister_dev(port, dev); 398 399 port->port->rphy = NULL; 400 401 } 402 403 void sas_device_set_phy(struct domain_device *dev, struct sas_port *port) 404 { 405 struct sas_ha_struct *ha; 406 struct sas_phy *new_phy; 407 408 if (!dev) 409 return; 410 411 ha = dev->port->ha; 412 new_phy = sas_port_get_phy(port); 413 414 /* pin and record last seen phy */ 415 spin_lock_irq(&ha->phy_port_lock); 416 if (new_phy) { 417 sas_port_put_phy(dev->phy); 418 dev->phy = new_phy; 419 } 420 spin_unlock_irq(&ha->phy_port_lock); 421 } 422 423 /* ---------- Discovery and Revalidation ---------- */ 424 425 /** 426 * sas_discover_domain - discover the domain 427 * @work: work structure embedded in port domain device. 428 * 429 * NOTE: this process _must_ quit (return) as soon as any connection 430 * errors are encountered. Connection recovery is done elsewhere. 431 * Discover process only interrogates devices in order to discover the 432 * domain. 433 */ 434 static void sas_discover_domain(struct work_struct *work) 435 { 436 struct domain_device *dev; 437 int error = 0; 438 struct sas_discovery_event *ev = to_sas_discovery_event(work); 439 struct asd_sas_port *port = ev->port; 440 441 clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending); 442 443 if (port->port_dev) 444 return; 445 446 error = sas_get_port_device(port); 447 if (error) 448 return; 449 dev = port->port_dev; 450 451 pr_debug("DOING DISCOVERY on port %d, pid:%d\n", port->id, 452 task_pid_nr(current)); 453 454 switch (dev->dev_type) { 455 case SAS_END_DEVICE: 456 error = sas_discover_end_dev(dev); 457 break; 458 case SAS_EDGE_EXPANDER_DEVICE: 459 case SAS_FANOUT_EXPANDER_DEVICE: 460 error = sas_discover_root_expander(dev); 461 break; 462 case SAS_SATA_DEV: 463 case SAS_SATA_PM: 464 #ifdef CONFIG_SCSI_SAS_ATA 465 error = sas_discover_sata(dev); 466 break; 467 #else 468 pr_notice("ATA device seen but CONFIG_SCSI_SAS_ATA=N so cannot attach\n"); 469 /* Fall through */ 470 #endif 471 /* Fall through - only for the #else condition above. */ 472 default: 473 error = -ENXIO; 474 pr_err("unhandled device %d\n", dev->dev_type); 475 break; 476 } 477 478 if (error) { 479 sas_rphy_free(dev->rphy); 480 list_del_init(&dev->disco_list_node); 481 spin_lock_irq(&port->dev_list_lock); 482 list_del_init(&dev->dev_list_node); 483 spin_unlock_irq(&port->dev_list_lock); 484 485 sas_put_device(dev); 486 port->port_dev = NULL; 487 } 488 489 sas_probe_devices(port); 490 491 pr_debug("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id, 492 task_pid_nr(current), error); 493 } 494 495 static void sas_revalidate_domain(struct work_struct *work) 496 { 497 int res = 0; 498 struct sas_discovery_event *ev = to_sas_discovery_event(work); 499 struct asd_sas_port *port = ev->port; 500 struct sas_ha_struct *ha = port->ha; 501 struct domain_device *ddev = port->port_dev; 502 503 /* prevent revalidation from finding sata links in recovery */ 504 mutex_lock(&ha->disco_mutex); 505 if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) { 506 pr_debug("REVALIDATION DEFERRED on port %d, pid:%d\n", 507 port->id, task_pid_nr(current)); 508 goto out; 509 } 510 511 clear_bit(DISCE_REVALIDATE_DOMAIN, &port->disc.pending); 512 513 pr_debug("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id, 514 task_pid_nr(current)); 515 516 if (ddev && dev_is_expander(ddev->dev_type)) 517 res = sas_ex_revalidate_domain(ddev); 518 519 pr_debug("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n", 520 port->id, task_pid_nr(current), res); 521 out: 522 mutex_unlock(&ha->disco_mutex); 523 524 sas_destruct_devices(port); 525 sas_destruct_ports(port); 526 sas_probe_devices(port); 527 } 528 529 /* ---------- Events ---------- */ 530 531 static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) 532 { 533 /* chained work is not subject to SA_HA_DRAINING or 534 * SAS_HA_REGISTERED, because it is either submitted in the 535 * workqueue, or known to be submitted from a context that is 536 * not racing against draining 537 */ 538 queue_work(ha->disco_q, &sw->work); 539 } 540 541 static void sas_chain_event(int event, unsigned long *pending, 542 struct sas_work *sw, 543 struct sas_ha_struct *ha) 544 { 545 if (!test_and_set_bit(event, pending)) { 546 unsigned long flags; 547 548 spin_lock_irqsave(&ha->lock, flags); 549 sas_chain_work(ha, sw); 550 spin_unlock_irqrestore(&ha->lock, flags); 551 } 552 } 553 554 int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) 555 { 556 struct sas_discovery *disc; 557 558 if (!port) 559 return 0; 560 disc = &port->disc; 561 562 BUG_ON(ev >= DISC_NUM_EVENTS); 563 564 sas_chain_event(ev, &disc->pending, &disc->disc_work[ev].work, port->ha); 565 566 return 0; 567 } 568 569 /** 570 * sas_init_disc - initialize the discovery struct in the port 571 * @disc: port discovery structure 572 * @port: pointer to struct port 573 * 574 * Called when the ports are being initialized. 575 */ 576 void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) 577 { 578 int i; 579 580 static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { 581 [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, 582 [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, 583 [DISCE_SUSPEND] = sas_suspend_devices, 584 [DISCE_RESUME] = sas_resume_devices, 585 }; 586 587 disc->pending = 0; 588 for (i = 0; i < DISC_NUM_EVENTS; i++) { 589 INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]); 590 disc->disc_work[i].port = port; 591 } 592 } 593