drivers/scsi/libsas/sas_port.c
Source file repositories/reference/linux-study-clean/drivers/scsi/libsas/sas_port.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/libsas/sas_port.c- Extension
.c- Size
- 9763 bytes
- Lines
- 371
- 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
sas_internal.hscsi/scsi_transport.hscsi/scsi_transport_sas.hscsi_sas_internal.h
Detected Declarations
function SCSIfunction sas_resume_portfunction sas_form_port_add_phyfunction sas_form_portfunction lostfunction sas_porte_bytes_dmaedfunction sas_porte_broadcast_rcvdfunction sas_porte_link_reset_errfunction sas_porte_timer_eventfunction sas_porte_hard_resetfunction sas_init_portfunction sas_register_portsfunction sas_unregister_ports
Annotated Snippet
if (rc) {
sas_unregister_dev(port, dev);
sas_destruct_devices(port);
continue;
}
if (dev_is_expander(dev->dev_type)) {
dev->ex_dev.ex_change_count = -1;
for (i = 0; i < dev->ex_dev.num_phys; i++) {
struct ex_phy *phy = &dev->ex_dev.ex_phy[i];
phy->phy_change_count = -1;
}
}
}
sas_discover_event(port, DISCE_RESUME);
}
static void sas_form_port_add_phy(struct asd_sas_port *port,
struct asd_sas_phy *phy, bool wideport)
{
list_add_tail(&phy->port_phy_el, &port->phy_list);
sas_phy_set_target(phy, port->port_dev);
phy->port = port;
port->num_phys++;
port->phy_mask |= (1U << phy->id);
if (wideport)
pr_debug("phy%d matched wide port%d\n", phy->id,
port->id);
else
memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE);
if (*(u64 *)port->attached_sas_addr == 0) {
memcpy(port->attached_sas_addr, phy->attached_sas_addr,
SAS_ADDR_SIZE);
port->iproto = phy->iproto;
port->tproto = phy->tproto;
port->oob_mode = phy->oob_mode;
port->linkrate = phy->linkrate;
} else {
port->linkrate = max(port->linkrate, phy->linkrate);
}
}
/**
* sas_form_port - add this phy to a port
* @phy: the phy of interest
*
* This function adds this phy to an existing port, thus creating a wide
* port, or it creates a port and adds the phy to the port.
*/
static void sas_form_port(struct asd_sas_phy *phy)
{
int i;
struct sas_ha_struct *sas_ha = phy->ha;
struct asd_sas_port *port = phy->port;
struct domain_device *port_dev = NULL;
struct sas_internal *si =
to_sas_internal(sas_ha->shost->transportt);
unsigned long flags;
if (port) {
if (!phy_is_wideport_member(port, phy))
sas_deform_port(phy, false);
else if (phy->suspended) {
phy->suspended = 0;
sas_resume_port(phy);
/* phy came back, try to cancel the timeout */
wake_up(&sas_ha->eh_wait_q);
return;
} else {
pr_info("%s: phy%d belongs to port%d already(%d)!\n",
__func__, phy->id, phy->port->id,
phy->port->num_phys);
return;
}
}
/* see if the phy should be part of a wide port */
spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
for (i = 0; i < sas_ha->num_phys; i++) {
port = sas_ha->sas_port[i];
spin_lock(&port->phy_list_lock);
if (*(u64 *) port->sas_addr &&
phy_is_wideport_member(port, phy) && port->num_phys > 0) {
/* wide port */
port_dev = port->port_dev;
Annotation
- Immediate include surface: `sas_internal.h`, `scsi/scsi_transport.h`, `scsi/scsi_transport_sas.h`, `scsi_sas_internal.h`.
- Detected declarations: `function SCSI`, `function sas_resume_port`, `function sas_form_port_add_phy`, `function sas_form_port`, `function lost`, `function sas_porte_bytes_dmaed`, `function sas_porte_broadcast_rcvd`, `function sas_porte_link_reset_err`, `function sas_porte_timer_event`, `function sas_porte_hard_reset`.
- 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.