drivers/scsi/libsas/sas_discover.c
Source file repositories/reference/linux-study-clean/drivers/scsi/libsas/sas_discover.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/libsas/sas_discover.c- Extension
.c- Size
- 15935 bytes
- Lines
- 608
- Domain
- Driver Families
- Bucket
- drivers/scsi
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/scatterlist.hlinux/slab.hscsi/scsi_host.hscsi/scsi_eh.hsas_internal.hscsi/scsi_transport.hscsi/scsi_transport_sas.hscsi/sas_ata.hscsi_sas_internal.h
Detected Declarations
function SCSIfunction arefunction sas_notify_lldd_dev_foundfunction sas_notify_lldd_dev_gonefunction sas_probe_devicesfunction list_for_each_entry_safefunction sas_suspend_devicesfunction sas_resume_devicesfunction sas_discover_satafunction sas_free_devicefunction sas_unregister_common_devfunction sas_destruct_devicesfunction list_for_each_entry_safefunction sas_destruct_portsfunction list_for_each_entry_safefunction sas_abort_cmdfunction sas_abort_device_scsi_cmdsfunction sas_unregister_devfunction sas_unregister_domain_devicesfunction list_for_each_entry_safe_reversefunction sas_device_set_phyfunction sas_discover_domainfunction sas_revalidate_domainfunction sas_chain_workfunction sas_chain_eventfunction sas_discover_eventfunction sas_init_disc
Annotated Snippet
if (rc) {
rphy = NULL;
break;
}
fallthrough;
case SAS_END_DEVICE:
rphy = sas_end_device_alloc(port->port);
break;
case SAS_EDGE_EXPANDER_DEVICE:
rphy = sas_expander_alloc(port->port,
SAS_EDGE_EXPANDER_DEVICE);
break;
case SAS_FANOUT_EXPANDER_DEVICE:
rphy = sas_expander_alloc(port->port,
SAS_FANOUT_EXPANDER_DEVICE);
break;
default:
pr_warn("ERROR: Unidentified device type %d\n", dev->dev_type);
rphy = NULL;
break;
}
if (!rphy) {
sas_put_device(dev);
return rc;
}
rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;
memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);
sas_fill_in_rphy(dev, rphy);
sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
port->port_dev = dev;
dev->linkrate = port->linkrate;
dev->min_linkrate = port->linkrate;
dev->max_linkrate = port->linkrate;
dev->pathways = port->num_phys;
memset(port->disc.fanout_sas_addr, 0, SAS_ADDR_SIZE);
memset(port->disc.eeds_a, 0, SAS_ADDR_SIZE);
memset(port->disc.eeds_b, 0, SAS_ADDR_SIZE);
port->disc.max_level = 0;
sas_device_set_phy(dev, port->port);
dev->rphy = rphy;
get_device(&dev->rphy->dev);
if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEVICE)
list_add_tail(&dev->disco_list_node, &port->disco_list);
else {
spin_lock_irq(&port->dev_list_lock);
list_add_tail(&dev->dev_list_node, &port->dev_list);
spin_unlock_irq(&port->dev_list_lock);
}
spin_lock_irq(&port->phy_list_lock);
list_for_each_entry(phy, &port->phy_list, port_phy_el)
sas_phy_set_target(phy, dev);
spin_unlock_irq(&port->phy_list_lock);
return 0;
}
/* ---------- Discover and Revalidate ---------- */
int sas_notify_lldd_dev_found(struct domain_device *dev)
{
int res = 0;
struct sas_ha_struct *sas_ha = dev->port->ha;
struct Scsi_Host *shost = sas_ha->shost;
struct sas_internal *i = to_sas_internal(shost->transportt);
if (!i->dft->lldd_dev_found)
return 0;
res = i->dft->lldd_dev_found(dev);
if (res) {
pr_warn("driver on host %s cannot handle device %016llx, error:%d\n",
dev_name(sas_ha->dev),
SAS_ADDR(dev->sas_addr), res);
return res;
}
set_bit(SAS_DEV_FOUND, &dev->state);
kref_get(&dev->kref);
return 0;
}
void sas_notify_lldd_dev_gone(struct domain_device *dev)
{
struct sas_ha_struct *sas_ha = dev->port->ha;
struct Scsi_Host *shost = sas_ha->shost;
Annotation
- Immediate include surface: `linux/scatterlist.h`, `linux/slab.h`, `scsi/scsi_host.h`, `scsi/scsi_eh.h`, `sas_internal.h`, `scsi/scsi_transport.h`, `scsi/scsi_transport_sas.h`, `scsi/sas_ata.h`.
- Detected declarations: `function SCSI`, `function are`, `function sas_notify_lldd_dev_found`, `function sas_notify_lldd_dev_gone`, `function sas_probe_devices`, `function list_for_each_entry_safe`, `function sas_suspend_devices`, `function sas_resume_devices`, `function sas_discover_sata`, `function sas_free_device`.
- Atlas domain: Driver Families / drivers/scsi.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.