Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Serial Attached SCSI (SAS) Discover process
0004  *
0005  * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
0006  * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
0007  */
0008 
0009 #include <linux/scatterlist.h>
0010 #include <linux/slab.h>
0011 #include <scsi/scsi_host.h>
0012 #include <scsi/scsi_eh.h>
0013 #include "sas_internal.h"
0014 
0015 #include <scsi/scsi_transport.h>
0016 #include <scsi/scsi_transport_sas.h>
0017 #include <scsi/sas_ata.h>
0018 #include "scsi_sas_internal.h"
0019 
0020 /* ---------- Basic task processing for discovery purposes ---------- */
0021 
0022 void sas_init_dev(struct domain_device *dev)
0023 {
0024     switch (dev->dev_type) {
0025     case SAS_END_DEVICE:
0026         INIT_LIST_HEAD(&dev->ssp_dev.eh_list_node);
0027         break;
0028     case SAS_EDGE_EXPANDER_DEVICE:
0029     case SAS_FANOUT_EXPANDER_DEVICE:
0030         INIT_LIST_HEAD(&dev->ex_dev.children);
0031         mutex_init(&dev->ex_dev.cmd_mutex);
0032         break;
0033     default:
0034         break;
0035     }
0036 }
0037 
0038 /* ---------- Domain device discovery ---------- */
0039 
0040 /**
0041  * sas_get_port_device - Discover devices which caused port creation
0042  * @port: pointer to struct sas_port of interest
0043  *
0044  * Devices directly attached to a HA port, have no parent.  This is
0045  * how we know they are (domain) "root" devices.  All other devices
0046  * do, and should have their "parent" pointer set appropriately as
0047  * soon as a child device is discovered.
0048  */
0049 static int sas_get_port_device(struct asd_sas_port *port)
0050 {
0051     struct asd_sas_phy *phy;
0052     struct sas_rphy *rphy;
0053     struct domain_device *dev;
0054     int rc = -ENODEV;
0055 
0056     dev = sas_alloc_device();
0057     if (!dev)
0058         return -ENOMEM;
0059 
0060     spin_lock_irq(&port->phy_list_lock);
0061     if (list_empty(&port->phy_list)) {
0062         spin_unlock_irq(&port->phy_list_lock);
0063         sas_put_device(dev);
0064         return -ENODEV;
0065     }
0066     phy = container_of(port->phy_list.next, struct asd_sas_phy, port_phy_el);
0067     spin_lock(&phy->frame_rcvd_lock);
0068     memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd),
0069                          (size_t)phy->frame_rcvd_size));
0070     spin_unlock(&phy->frame_rcvd_lock);
0071     spin_unlock_irq(&port->phy_list_lock);
0072 
0073     if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) {
0074         struct dev_to_host_fis *fis =
0075             (struct dev_to_host_fis *) dev->frame_rcvd;
0076         if (fis->interrupt_reason == 1 && fis->lbal == 1 &&
0077             fis->byte_count_low == 0x69 && fis->byte_count_high == 0x96
0078             && (fis->device & ~0x10) == 0)
0079             dev->dev_type = SAS_SATA_PM;
0080         else
0081             dev->dev_type = SAS_SATA_DEV;
0082         dev->tproto = SAS_PROTOCOL_SATA;
0083     } else if (port->oob_mode == SAS_OOB_MODE) {
0084         struct sas_identify_frame *id =
0085             (struct sas_identify_frame *) dev->frame_rcvd;
0086         dev->dev_type = id->dev_type;
0087         dev->iproto = id->initiator_bits;
0088         dev->tproto = id->target_bits;
0089     } else {
0090         /* If the oob mode is OOB_NOT_CONNECTED, the port is
0091          * disconnected due to race with PHY down. We cannot
0092          * continue to discover this port
0093          */
0094         sas_put_device(dev);
0095         pr_warn("Port %016llx is disconnected when discovering\n",
0096             SAS_ADDR(port->attached_sas_addr));
0097         return -ENODEV;
0098     }
0099 
0100     sas_init_dev(dev);
0101 
0102     dev->port = port;
0103     switch (dev->dev_type) {
0104     case SAS_SATA_DEV:
0105         rc = sas_ata_init(dev);
0106         if (rc) {
0107             rphy = NULL;
0108             break;
0109         }
0110         fallthrough;
0111     case SAS_END_DEVICE:
0112         rphy = sas_end_device_alloc(port->port);
0113         break;
0114     case SAS_EDGE_EXPANDER_DEVICE:
0115         rphy = sas_expander_alloc(port->port,
0116                       SAS_EDGE_EXPANDER_DEVICE);
0117         break;
0118     case SAS_FANOUT_EXPANDER_DEVICE:
0119         rphy = sas_expander_alloc(port->port,
0120                       SAS_FANOUT_EXPANDER_DEVICE);
0121         break;
0122     default:
0123         pr_warn("ERROR: Unidentified device type %d\n", dev->dev_type);
0124         rphy = NULL;
0125         break;
0126     }
0127 
0128     if (!rphy) {
0129         sas_put_device(dev);
0130         return rc;
0131     }
0132 
0133     rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;
0134     memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);
0135     sas_fill_in_rphy(dev, rphy);
0136     sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
0137     port->port_dev = dev;
0138     dev->linkrate = port->linkrate;
0139     dev->min_linkrate = port->linkrate;
0140     dev->max_linkrate = port->linkrate;
0141     dev->pathways = port->num_phys;
0142     memset(port->disc.fanout_sas_addr, 0, SAS_ADDR_SIZE);
0143     memset(port->disc.eeds_a, 0, SAS_ADDR_SIZE);
0144     memset(port->disc.eeds_b, 0, SAS_ADDR_SIZE);
0145     port->disc.max_level = 0;
0146     sas_device_set_phy(dev, port->port);
0147 
0148     dev->rphy = rphy;
0149     get_device(&dev->rphy->dev);
0150 
0151     if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEVICE)
0152         list_add_tail(&dev->disco_list_node, &port->disco_list);
0153     else {
0154         spin_lock_irq(&port->dev_list_lock);
0155         list_add_tail(&dev->dev_list_node, &port->dev_list);
0156         spin_unlock_irq(&port->dev_list_lock);
0157     }
0158 
0159     spin_lock_irq(&port->phy_list_lock);
0160     list_for_each_entry(phy, &port->phy_list, port_phy_el)
0161         sas_phy_set_target(phy, dev);
0162     spin_unlock_irq(&port->phy_list_lock);
0163 
0164     return 0;
0165 }
0166 
0167 /* ---------- Discover and Revalidate ---------- */
0168 
0169 int sas_notify_lldd_dev_found(struct domain_device *dev)
0170 {
0171     int res = 0;
0172     struct sas_ha_struct *sas_ha = dev->port->ha;
0173     struct Scsi_Host *shost = sas_ha->core.shost;
0174     struct sas_internal *i = to_sas_internal(shost->transportt);
0175 
0176     if (!i->dft->lldd_dev_found)
0177         return 0;
0178 
0179     res = i->dft->lldd_dev_found(dev);
0180     if (res) {
0181         pr_warn("driver on host %s cannot handle device %016llx, error:%d\n",
0182             dev_name(sas_ha->dev),
0183             SAS_ADDR(dev->sas_addr), res);
0184         return res;
0185     }
0186     set_bit(SAS_DEV_FOUND, &dev->state);
0187     kref_get(&dev->kref);
0188     return 0;
0189 }
0190 
0191 
0192 void sas_notify_lldd_dev_gone(struct domain_device *dev)
0193 {
0194     struct sas_ha_struct *sas_ha = dev->port->ha;
0195     struct Scsi_Host *shost = sas_ha->core.shost;
0196     struct sas_internal *i = to_sas_internal(shost->transportt);
0197 
0198     if (!i->dft->lldd_dev_gone)
0199         return;
0200 
0201     if (test_and_clear_bit(SAS_DEV_FOUND, &dev->state)) {
0202         i->dft->lldd_dev_gone(dev);
0203         sas_put_device(dev);
0204     }
0205 }
0206 
0207 static void sas_probe_devices(struct asd_sas_port *port)
0208 {
0209     struct domain_device *dev, *n;
0210 
0211     /* devices must be domain members before link recovery and probe */
0212     list_for_each_entry(dev, &port->disco_list, disco_list_node) {
0213         spin_lock_irq(&port->dev_list_lock);
0214         list_add_tail(&dev->dev_list_node, &port->dev_list);
0215         spin_unlock_irq(&port->dev_list_lock);
0216     }
0217 
0218     sas_probe_sata(port);
0219 
0220     list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
0221         int err;
0222 
0223         err = sas_rphy_add(dev->rphy);
0224         if (err)
0225             sas_fail_probe(dev, __func__, err);
0226         else
0227             list_del_init(&dev->disco_list_node);
0228     }
0229 }
0230 
0231 static void sas_suspend_devices(struct work_struct *work)
0232 {
0233     struct asd_sas_phy *phy;
0234     struct domain_device *dev;
0235     struct sas_discovery_event *ev = to_sas_discovery_event(work);
0236     struct asd_sas_port *port = ev->port;
0237     struct Scsi_Host *shost = port->ha->core.shost;
0238     struct sas_internal *si = to_sas_internal(shost->transportt);
0239 
0240     clear_bit(DISCE_SUSPEND, &port->disc.pending);
0241 
0242     sas_suspend_sata(port);
0243 
0244     /* lldd is free to forget the domain_device across the
0245      * suspension, we force the issue here to keep the reference
0246      * counts aligned
0247      */
0248     list_for_each_entry(dev, &port->dev_list, dev_list_node)
0249         sas_notify_lldd_dev_gone(dev);
0250 
0251     /* we are suspending, so we know events are disabled and
0252      * phy_list is not being mutated
0253      */
0254     list_for_each_entry(phy, &port->phy_list, port_phy_el) {
0255         if (si->dft->lldd_port_deformed)
0256             si->dft->lldd_port_deformed(phy);
0257         phy->suspended = 1;
0258         port->suspended = 1;
0259     }
0260 }
0261 
0262 static void sas_resume_devices(struct work_struct *work)
0263 {
0264     struct sas_discovery_event *ev = to_sas_discovery_event(work);
0265     struct asd_sas_port *port = ev->port;
0266 
0267     clear_bit(DISCE_RESUME, &port->disc.pending);
0268 
0269     sas_resume_sata(port);
0270 }
0271 
0272 /**
0273  * sas_discover_end_dev - discover an end device (SSP, etc)
0274  * @dev: pointer to domain device of interest
0275  *
0276  * See comment in sas_discover_sata().
0277  */
0278 int sas_discover_end_dev(struct domain_device *dev)
0279 {
0280     return sas_notify_lldd_dev_found(dev);
0281 }
0282 
0283 /* ---------- Device registration and unregistration ---------- */
0284 
0285 void sas_free_device(struct kref *kref)
0286 {
0287     struct domain_device *dev = container_of(kref, typeof(*dev), kref);
0288 
0289     put_device(&dev->rphy->dev);
0290     dev->rphy = NULL;
0291 
0292     if (dev->parent)
0293         sas_put_device(dev->parent);
0294 
0295     sas_port_put_phy(dev->phy);
0296     dev->phy = NULL;
0297 
0298     /* remove the phys and ports, everything else should be gone */
0299     if (dev_is_expander(dev->dev_type))
0300         kfree(dev->ex_dev.ex_phy);
0301 
0302     if (dev_is_sata(dev) && dev->sata_dev.ap) {
0303         ata_sas_tport_delete(dev->sata_dev.ap);
0304         ata_sas_port_destroy(dev->sata_dev.ap);
0305         ata_host_put(dev->sata_dev.ata_host);
0306         dev->sata_dev.ata_host = NULL;
0307         dev->sata_dev.ap = NULL;
0308     }
0309 
0310     kfree(dev);
0311 }
0312 
0313 static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_device *dev)
0314 {
0315     struct sas_ha_struct *ha = port->ha;
0316 
0317     sas_notify_lldd_dev_gone(dev);
0318     if (!dev->parent)
0319         dev->port->port_dev = NULL;
0320     else
0321         list_del_init(&dev->siblings);
0322 
0323     spin_lock_irq(&port->dev_list_lock);
0324     list_del_init(&dev->dev_list_node);
0325     if (dev_is_sata(dev))
0326         sas_ata_end_eh(dev->sata_dev.ap);
0327     spin_unlock_irq(&port->dev_list_lock);
0328 
0329     spin_lock_irq(&ha->lock);
0330     if (dev->dev_type == SAS_END_DEVICE &&
0331         !list_empty(&dev->ssp_dev.eh_list_node)) {
0332         list_del_init(&dev->ssp_dev.eh_list_node);
0333         ha->eh_active--;
0334     }
0335     spin_unlock_irq(&ha->lock);
0336 
0337     sas_put_device(dev);
0338 }
0339 
0340 void sas_destruct_devices(struct asd_sas_port *port)
0341 {
0342     struct domain_device *dev, *n;
0343 
0344     list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) {
0345         list_del_init(&dev->disco_list_node);
0346 
0347         sas_remove_children(&dev->rphy->dev);
0348         sas_rphy_delete(dev->rphy);
0349         sas_unregister_common_dev(port, dev);
0350     }
0351 }
0352 
0353 static void sas_destruct_ports(struct asd_sas_port *port)
0354 {
0355     struct sas_port *sas_port, *p;
0356 
0357     list_for_each_entry_safe(sas_port, p, &port->sas_port_del_list, del_list) {
0358         list_del_init(&sas_port->del_list);
0359         sas_port_delete(sas_port);
0360     }
0361 }
0362 
0363 void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
0364 {
0365     if (!test_bit(SAS_DEV_DESTROY, &dev->state) &&
0366         !list_empty(&dev->disco_list_node)) {
0367         /* this rphy never saw sas_rphy_add */
0368         list_del_init(&dev->disco_list_node);
0369         sas_rphy_free(dev->rphy);
0370         sas_unregister_common_dev(port, dev);
0371         return;
0372     }
0373 
0374     if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) {
0375         sas_rphy_unlink(dev->rphy);
0376         list_move_tail(&dev->disco_list_node, &port->destroy_list);
0377     }
0378 }
0379 
0380 void sas_unregister_domain_devices(struct asd_sas_port *port, int gone)
0381 {
0382     struct domain_device *dev, *n;
0383 
0384     list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node) {
0385         if (gone)
0386             set_bit(SAS_DEV_GONE, &dev->state);
0387         sas_unregister_dev(port, dev);
0388     }
0389 
0390     list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node)
0391         sas_unregister_dev(port, dev);
0392 
0393     port->port->rphy = NULL;
0394 
0395 }
0396 
0397 void sas_device_set_phy(struct domain_device *dev, struct sas_port *port)
0398 {
0399     struct sas_ha_struct *ha;
0400     struct sas_phy *new_phy;
0401 
0402     if (!dev)
0403         return;
0404 
0405     ha = dev->port->ha;
0406     new_phy = sas_port_get_phy(port);
0407 
0408     /* pin and record last seen phy */
0409     spin_lock_irq(&ha->phy_port_lock);
0410     if (new_phy) {
0411         sas_port_put_phy(dev->phy);
0412         dev->phy = new_phy;
0413     }
0414     spin_unlock_irq(&ha->phy_port_lock);
0415 }
0416 
0417 /* ---------- Discovery and Revalidation ---------- */
0418 
0419 /**
0420  * sas_discover_domain - discover the domain
0421  * @work: work structure embedded in port domain device.
0422  *
0423  * NOTE: this process _must_ quit (return) as soon as any connection
0424  * errors are encountered.  Connection recovery is done elsewhere.
0425  * Discover process only interrogates devices in order to discover the
0426  * domain.
0427  */
0428 static void sas_discover_domain(struct work_struct *work)
0429 {
0430     struct domain_device *dev;
0431     int error = 0;
0432     struct sas_discovery_event *ev = to_sas_discovery_event(work);
0433     struct asd_sas_port *port = ev->port;
0434 
0435     clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending);
0436 
0437     if (port->port_dev)
0438         return;
0439 
0440     error = sas_get_port_device(port);
0441     if (error)
0442         return;
0443     dev = port->port_dev;
0444 
0445     pr_debug("DOING DISCOVERY on port %d, pid:%d\n", port->id,
0446          task_pid_nr(current));
0447 
0448     switch (dev->dev_type) {
0449     case SAS_END_DEVICE:
0450         error = sas_discover_end_dev(dev);
0451         break;
0452     case SAS_EDGE_EXPANDER_DEVICE:
0453     case SAS_FANOUT_EXPANDER_DEVICE:
0454         error = sas_discover_root_expander(dev);
0455         break;
0456     case SAS_SATA_DEV:
0457     case SAS_SATA_PM:
0458 #ifdef CONFIG_SCSI_SAS_ATA
0459         error = sas_discover_sata(dev);
0460         break;
0461 #else
0462         pr_notice("ATA device seen but CONFIG_SCSI_SAS_ATA=N so cannot attach\n");
0463         fallthrough;
0464 #endif
0465         /* Fall through - only for the #else condition above. */
0466     default:
0467         error = -ENXIO;
0468         pr_err("unhandled device %d\n", dev->dev_type);
0469         break;
0470     }
0471 
0472     if (error) {
0473         sas_rphy_free(dev->rphy);
0474         list_del_init(&dev->disco_list_node);
0475         spin_lock_irq(&port->dev_list_lock);
0476         list_del_init(&dev->dev_list_node);
0477         spin_unlock_irq(&port->dev_list_lock);
0478 
0479         sas_put_device(dev);
0480         port->port_dev = NULL;
0481     }
0482 
0483     sas_probe_devices(port);
0484 
0485     pr_debug("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
0486          task_pid_nr(current), error);
0487 }
0488 
0489 static void sas_revalidate_domain(struct work_struct *work)
0490 {
0491     int res = 0;
0492     struct sas_discovery_event *ev = to_sas_discovery_event(work);
0493     struct asd_sas_port *port = ev->port;
0494     struct sas_ha_struct *ha = port->ha;
0495     struct domain_device *ddev = port->port_dev;
0496 
0497     /* prevent revalidation from finding sata links in recovery */
0498     mutex_lock(&ha->disco_mutex);
0499     if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) {
0500         pr_debug("REVALIDATION DEFERRED on port %d, pid:%d\n",
0501              port->id, task_pid_nr(current));
0502         goto out;
0503     }
0504 
0505     clear_bit(DISCE_REVALIDATE_DOMAIN, &port->disc.pending);
0506 
0507     pr_debug("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
0508          task_pid_nr(current));
0509 
0510     if (ddev && dev_is_expander(ddev->dev_type))
0511         res = sas_ex_revalidate_domain(ddev);
0512 
0513     pr_debug("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
0514          port->id, task_pid_nr(current), res);
0515  out:
0516     mutex_unlock(&ha->disco_mutex);
0517 
0518     sas_destruct_devices(port);
0519     sas_destruct_ports(port);
0520     sas_probe_devices(port);
0521 }
0522 
0523 /* ---------- Events ---------- */
0524 
0525 static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw)
0526 {
0527     /* chained work is not subject to SA_HA_DRAINING or
0528      * SAS_HA_REGISTERED, because it is either submitted in the
0529      * workqueue, or known to be submitted from a context that is
0530      * not racing against draining
0531      */
0532     queue_work(ha->disco_q, &sw->work);
0533 }
0534 
0535 static void sas_chain_event(int event, unsigned long *pending,
0536                 struct sas_work *sw,
0537                 struct sas_ha_struct *ha)
0538 {
0539     if (!test_and_set_bit(event, pending)) {
0540         unsigned long flags;
0541 
0542         spin_lock_irqsave(&ha->lock, flags);
0543         sas_chain_work(ha, sw);
0544         spin_unlock_irqrestore(&ha->lock, flags);
0545     }
0546 }
0547 
0548 void sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
0549 {
0550     struct sas_discovery *disc;
0551 
0552     if (!port)
0553         return;
0554     disc = &port->disc;
0555 
0556     BUG_ON(ev >= DISC_NUM_EVENTS);
0557 
0558     sas_chain_event(ev, &disc->pending, &disc->disc_work[ev].work, port->ha);
0559 }
0560 
0561 /**
0562  * sas_init_disc - initialize the discovery struct in the port
0563  * @disc: port discovery structure
0564  * @port: pointer to struct port
0565  *
0566  * Called when the ports are being initialized.
0567  */
0568 void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
0569 {
0570     int i;
0571 
0572     static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
0573         [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
0574         [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
0575         [DISCE_SUSPEND] = sas_suspend_devices,
0576         [DISCE_RESUME] = sas_resume_devices,
0577     };
0578 
0579     disc->pending = 0;
0580     for (i = 0; i < DISC_NUM_EVENTS; i++) {
0581         INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
0582         disc->disc_work[i].port = port;
0583     }
0584 }