drivers/scsi/mvsas/mv_sas.c
Source file repositories/reference/linux-study-clean/drivers/scsi/mvsas/mv_sas.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/mvsas/mv_sas.c- Extension
.c- Size
- 50279 bytes
- Lines
- 1924
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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
mv_sas.h
Detected Declarations
function mvs_find_tagfunction mvs_tag_clearfunction mvs_tag_freefunction mvs_tag_setfunction mvs_tag_allocfunction mvs_find_dev_phynofunction list_for_each_entryfunction mvs_free_reg_setfunction mvs_assign_reg_setfunction mvs_phy_controlfunction mvs_set_sas_addrfunction mvs_bytes_dmaedfunction mvs_scan_startfunction mvs_scan_finishedfunction mvs_task_prep_smpfunction mvs_get_ncq_tagfunction mvs_task_prep_atafunction mvs_task_prep_sspfunction mvs_task_prepfunction mvs_queue_commandfunction mvs_slot_freefunction mvs_slot_task_freefunction mvs_update_wideportfunction for_each_phyfunction mvs_is_phy_readyfunction mvs_is_sig_fis_receivedfunction mvs_sig_remove_timerfunction mvs_update_phyinfofunction mvs_port_notify_formedfunction mvs_port_notify_deformedfunction mvs_port_formedfunction mvs_port_deformedfunction mvs_free_devfunction mvs_dev_found_notifyfunction mvs_dev_foundfunction mvs_dev_gone_notifyfunction mvs_dev_gonefunction SSPfunction mvs_lu_resetfunction mvs_I_T_nexus_resetfunction mvs_query_taskfunction mvs_abort_taskfunction mvs_sata_donefunction mvs_set_sensefunction mvs_fill_ssp_resp_iufunction mvs_slot_errfunction mvs_slot_completefunction mvs_do_release_task
Annotated Snippet
if (sha->sas_port[i] == dev->port) {
spin_lock(&sha->sas_port[i]->phy_list_lock);
phy = container_of(sha->sas_port[i]->phy_list.next,
struct asd_sas_phy, port_phy_el);
spin_unlock(&sha->sas_port[i]->phy_list_lock);
j = 0;
while (sha->sas_phy[j]) {
if (sha->sas_phy[j] == phy)
break;
j++;
}
break;
}
i++;
}
hi = j/((struct mvs_prv_info *)sha->lldd_ha)->n_phy;
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[hi];
return mvi;
}
static int mvs_find_dev_phyno(struct domain_device *dev, int *phyno)
{
unsigned long i = 0, j = 0, n = 0, num = 0;
struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev;
struct mvs_info *mvi = mvi_dev->mvi_info;
struct sas_ha_struct *sha = dev->port->ha;
while (sha->sas_port[i]) {
if (sha->sas_port[i] == dev->port) {
struct asd_sas_phy *phy;
spin_lock(&sha->sas_port[i]->phy_list_lock);
list_for_each_entry(phy,
&sha->sas_port[i]->phy_list, port_phy_el) {
j = 0;
while (sha->sas_phy[j]) {
if (sha->sas_phy[j] == phy)
break;
j++;
}
phyno[n] = (j >= mvi->chip->n_phy) ?
(j - mvi->chip->n_phy) : j;
num++;
n++;
}
spin_unlock(&sha->sas_port[i]->phy_list_lock);
break;
}
i++;
}
return num;
}
struct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi,
u8 reg_set)
{
u32 dev_no;
for (dev_no = 0; dev_no < MVS_MAX_DEVICES; dev_no++) {
if (mvi->devices[dev_no].taskfileset == MVS_ID_NOT_MAPPED)
continue;
if (mvi->devices[dev_no].taskfileset == reg_set)
return &mvi->devices[dev_no];
}
return NULL;
}
static inline void mvs_free_reg_set(struct mvs_info *mvi,
struct mvs_device *dev)
{
if (!dev) {
mv_printk("device has been free.\n");
return;
}
if (dev->taskfileset == MVS_ID_NOT_MAPPED)
return;
MVS_CHIP_DISP->free_reg_set(mvi, &dev->taskfileset);
}
static inline u8 mvs_assign_reg_set(struct mvs_info *mvi,
struct mvs_device *dev)
{
if (dev->taskfileset != MVS_ID_NOT_MAPPED)
return 0;
return MVS_CHIP_DISP->assign_reg_set(mvi, &dev->taskfileset);
}
int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
Annotation
- Immediate include surface: `mv_sas.h`.
- Detected declarations: `function mvs_find_tag`, `function mvs_tag_clear`, `function mvs_tag_free`, `function mvs_tag_set`, `function mvs_tag_alloc`, `function mvs_find_dev_phyno`, `function list_for_each_entry`, `function mvs_free_reg_set`, `function mvs_assign_reg_set`, `function mvs_phy_control`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.