drivers/scsi/lpfc/lpfc_vmid.c
Source file repositories/reference/linux-study-clean/drivers/scsi/lpfc/lpfc_vmid.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/lpfc/lpfc_vmid.c- Extension
.c- Size
- 10040 bytes
- Lines
- 326
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/interrupt.hlinux/dma-direction.hscsi/scsi_transport_fc.hlpfc_hw4.hlpfc_hw.hlpfc_sli.hlpfc_sli4.hlpfc_nl.hlpfc_disc.hlpfc.hlpfc_crtn.h
Detected Declarations
function hash_for_each_possiblefunction lpfc_put_vmid_in_hashtablefunction lpfc_vmid_hash_fnfunction lpfc_vmid_update_entryfunction lpfc_vmid_assign_cs_ctlfunction lpfc_vmid_get_appidfunction lpfc_reinit_vmid
Annotated Snippet
if (vmp && vmp->flag & LPFC_VMID_REGISTERED) {
lpfc_vmid_update_entry(vport, iodir, vmp, tag);
write_unlock(&vport->vmid_lock);
return 0;
} else if (vmp && vmp->flag & LPFC_VMID_REQ_REGISTER) {
write_unlock(&vport->vmid_lock);
return -EBUSY;
}
/* else search and allocate a free slot in the hash table */
if (vport->cur_vmid_cnt < vport->max_vmid) {
for (i = 0; i < vport->max_vmid; i++) {
vmp = vport->vmid + i;
if (vmp->flag == LPFC_VMID_SLOT_FREE)
break;
}
if (i == vport->max_vmid)
vmp = NULL;
} else {
vmp = NULL;
}
if (!vmp) {
write_unlock(&vport->vmid_lock);
return -ENOMEM;
}
/* Add the vmid and register */
lpfc_put_vmid_in_hashtable(vport, hash, vmp);
vmp->vmid_len = len;
memcpy(vmp->host_vmid, uuid, vmp->vmid_len);
vmp->io_rd_cnt = 0;
vmp->io_wr_cnt = 0;
vmp->flag = LPFC_VMID_SLOT_USED;
vmp->delete_inactive =
vport->vmid_inactivity_timeout ? 1 : 0;
/* if type priority tag, get next available VMID */
if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
lpfc_vmid_assign_cs_ctl(vport, vmp);
/* allocate the per cpu variable for holding */
/* the last access time stamp only if VMID is enabled */
if (!vmp->last_io_time)
vmp->last_io_time = alloc_percpu_gfp(u64, GFP_ATOMIC);
if (!vmp->last_io_time) {
hash_del(&vmp->hnode);
vmp->flag = LPFC_VMID_SLOT_FREE;
write_unlock(&vport->vmid_lock);
return -EIO;
}
write_unlock(&vport->vmid_lock);
/* complete transaction with switch */
if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
rc = lpfc_vmid_uvem(vport, vmp, true);
else if (vport->phba->cfg_vmid_app_header)
rc = lpfc_vmid_cmd(vport, SLI_CTAS_RAPP_IDENT, vmp);
if (!rc) {
write_lock(&vport->vmid_lock);
vport->cur_vmid_cnt++;
vmp->flag |= LPFC_VMID_REQ_REGISTER;
write_unlock(&vport->vmid_lock);
} else {
write_lock(&vport->vmid_lock);
hash_del(&vmp->hnode);
vmp->flag = LPFC_VMID_SLOT_FREE;
free_percpu(vmp->last_io_time);
write_unlock(&vport->vmid_lock);
return -EIO;
}
/* finally, enable the idle timer once */
if (!(vport->phba->pport->vmid_flag & LPFC_VMID_TIMER_ENBLD)) {
mod_timer(&vport->phba->inactive_vmid_poll,
jiffies +
secs_to_jiffies(LPFC_VMID_TIMER));
vport->phba->pport->vmid_flag |= LPFC_VMID_TIMER_ENBLD;
}
}
return rc;
}
/*
* lpfc_reinit_vmid - reinitializes the vmid data structure
* @vport: pointer to vport data structure
*
* This routine reinitializes the vmid post flogi completion
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/dma-direction.h`, `scsi/scsi_transport_fc.h`, `lpfc_hw4.h`, `lpfc_hw.h`, `lpfc_sli.h`, `lpfc_sli4.h`, `lpfc_nl.h`.
- Detected declarations: `function hash_for_each_possible`, `function lpfc_put_vmid_in_hashtable`, `function lpfc_vmid_hash_fn`, `function lpfc_vmid_update_entry`, `function lpfc_vmid_assign_cs_ctl`, `function lpfc_vmid_get_appid`, `function lpfc_reinit_vmid`.
- Atlas domain: Driver Families / drivers/scsi.
- Implementation status: source implementation candidate.
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.