drivers/scsi/libsas/sas_expander.c
Source file repositories/reference/linux-study-clean/drivers/scsi/libsas/sas_expander.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/libsas/sas_expander.c- Extension
.c- Size
- 55619 bytes
- Lines
- 2176
- Domain
- Driver Families
- Bucket
- drivers/scsi
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/scatterlist.hlinux/blkdev.hlinux/slab.hlinux/unaligned.hsas_internal.hscsi/sas_ata.hscsi/scsi_transport.hscsi/scsi_transport_sas.hscsi_sas_internal.h
Detected Declarations
function sas_port_add_ex_phyfunction sas_ex_add_parent_portfunction smp_execute_task_sgfunction smp_execute_taskfunction sas_route_charfunction to_dev_typefunction sas_set_ex_phyfunction sas_ex_phy_discover_helperfunction sas_ex_phy_discoverfunction sas_expander_discoverfunction sas_ex_generalfunction ex_assign_manuf_infofunction sas_ex_manuf_infofunction sas_smp_phy_controlfunction sas_ex_disable_phyfunction sas_ex_disable_portfunction sas_dev_present_in_domainfunction sas_smp_get_phy_eventsfunction sas_get_report_phy_satafunction sas_ex_get_linkratefunction sas_ex_add_devfunction sas_ex_join_wide_portfunction sas_ex_discover_devfunction sas_find_sub_addrfunction sas_check_level_subtractive_boundaryfunction list_for_each_entryfunction sas_ex_discover_devicesfunction sas_check_ex_subtractive_boundaryfunction sas_print_parent_topology_bugfunction sas_eeds_validfunction sas_check_eedsfunction sas_check_edge_expander_topofunction sas_check_fanout_expander_topofunction sas_check_parent_topologyfunction sas_configure_presentfunction sas_configure_setfunction sas_configure_phyfunction sas_configure_parentfunction sas_configure_routingfunction sas_disable_routingfunction sas_discover_satafunction sas_ex_level_discoveryfunction list_for_each_entryfunction sas_ex_bfs_discfunction sas_discover_root_expanderfunction sas_get_sas_addr_and_dev_typefunction sas_get_phy_discoverfunction sas_get_phy_change_count
Annotated Snippet
if (test_bit(SAS_DEV_GONE, &dev->state)) {
res = -ECOMM;
break;
}
task = sas_alloc_slow_task(GFP_KERNEL);
if (!task) {
res = -ENOMEM;
break;
}
task->dev = dev;
task->task_proto = dev->tproto;
task->smp_task.smp_req = *req;
task->smp_task.smp_resp = *resp;
task->task_done = sas_task_internal_done;
task->slow_task->timer.function = sas_task_internal_timedout;
task->slow_task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
add_timer(&task->slow_task->timer);
res = i->dft->lldd_execute_task(task, GFP_KERNEL);
if (res) {
timer_delete_sync(&task->slow_task->timer);
pr_notice("executing SMP task failed:%d\n", res);
break;
}
wait_for_completion(&task->slow_task->completion);
res = -ECOMM;
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
pr_notice("smp task timed out or aborted\n");
i->dft->lldd_abort_task(task);
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
pr_notice("SMP task aborted and not done\n");
break;
}
}
if (task->task_status.resp == SAS_TASK_COMPLETE &&
task->task_status.stat == SAS_SAM_STAT_GOOD) {
res = 0;
break;
}
if (task->task_status.resp == SAS_TASK_COMPLETE &&
task->task_status.stat == SAS_DATA_UNDERRUN) {
/* no error, but return the number of bytes of
* underrun */
res = task->task_status.residual;
break;
}
if (task->task_status.resp == SAS_TASK_COMPLETE &&
task->task_status.stat == SAS_DATA_OVERRUN) {
res = -EMSGSIZE;
break;
}
if (task->task_status.resp == SAS_TASK_UNDELIVERED &&
task->task_status.stat == SAS_DEVICE_UNKNOWN)
break;
else {
pr_notice("%s: task to dev %016llx response: 0x%x status 0x%x\n",
__func__,
SAS_ADDR(dev->sas_addr),
task->task_status.resp,
task->task_status.stat);
sas_free_task(task);
task = NULL;
}
}
mutex_unlock(&dev->ex_dev.cmd_mutex);
pm_runtime_put_sync(ha->dev);
BUG_ON(retry == 3 && task != NULL);
sas_free_task(task);
return res;
}
static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
void *resp, int resp_size)
{
struct scatterlist req_sg;
struct scatterlist resp_sg;
sg_init_one(&req_sg, req, req_size);
sg_init_one(&resp_sg, resp, resp_size);
return smp_execute_task_sg(dev, &req_sg, &resp_sg);
}
/* ---------- Allocations ---------- */
Annotation
- Immediate include surface: `linux/scatterlist.h`, `linux/blkdev.h`, `linux/slab.h`, `linux/unaligned.h`, `sas_internal.h`, `scsi/sas_ata.h`, `scsi/scsi_transport.h`, `scsi/scsi_transport_sas.h`.
- Detected declarations: `function sas_port_add_ex_phy`, `function sas_ex_add_parent_port`, `function smp_execute_task_sg`, `function smp_execute_task`, `function sas_route_char`, `function to_dev_type`, `function sas_set_ex_phy`, `function sas_ex_phy_discover_helper`, `function sas_ex_phy_discover`, `function sas_expander_discover`.
- Atlas domain: Driver Families / drivers/scsi.
- Implementation status: integration 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.