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