drivers/scsi/lpfc/lpfc_vport.c
Source file repositories/reference/linux-study-clean/drivers/scsi/lpfc/lpfc_vport.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/lpfc/lpfc_vport.c- Extension
.c- Size
- 24010 bytes
- Lines
- 821
- 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.
- 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/blkdev.hlinux/delay.hlinux/dma-mapping.hlinux/idr.hlinux/interrupt.hlinux/kthread.hlinux/pci.hlinux/slab.hlinux/spinlock.hlinux/sched/signal.hscsi/scsi.hscsi/scsi_device.hscsi/scsi_host.hscsi/scsi_transport_fc.hlpfc_hw4.hlpfc_hw.hlpfc_sli.hlpfc_sli4.hlpfc_nl.hlpfc_disc.hlpfc_scsi.hlpfc.hlpfc_logmsg.hlpfc_crtn.hlpfc_version.hlpfc_vport.h
Detected Declarations
function lpfc_vport_set_statefunction lpfc_alloc_vpifunction lpfc_free_vpifunction lpfc_vport_sparmfunction lpfc_valid_wwn_formatfunction lpfc_unique_wwpnfunction lpfc_discovery_waitfunction lpfc_vport_createfunction test_bitfunction lpfc_send_npiv_logofunction disable_vportfunction enable_vportfunction lpfc_vport_disablefunction lpfc_vport_deletefunction lpfc_create_vport_work_arrayfunction lpfc_destroy_vport_work_array
Annotated Snippet
if (signal_pending(current)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
"1830 Signal aborted mbxCmd x%x\n",
mb->mbxCommand);
if (rc != MBX_TIMEOUT)
lpfc_mbox_rsrc_cleanup(phba, pmb,
MBOX_THD_UNLOCKED);
return -EINTR;
} else {
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
"1818 VPort failed init, mbxCmd x%x "
"READ_SPARM mbxStatus x%x, rc = x%x\n",
mb->mbxCommand, mb->mbxStatus, rc);
if (rc != MBX_TIMEOUT)
lpfc_mbox_rsrc_cleanup(phba, pmb,
MBOX_THD_UNLOCKED);
return -EIO;
}
}
mp = pmb->ctx_buf;
memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
sizeof (struct lpfc_name));
memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
sizeof (struct lpfc_name));
lpfc_mbox_rsrc_cleanup(phba, pmb, MBOX_THD_UNLOCKED);
return 0;
}
static int
lpfc_valid_wwn_format(struct lpfc_hba *phba, struct lpfc_name *wwn,
const char *name_type)
{
/* ensure that IEEE format 1 addresses
* contain zeros in bits 59-48
*/
if (!((wwn->u.wwn[0] >> 4) == 1 &&
((wwn->u.wwn[0] & 0xf) != 0 || (wwn->u.wwn[1] & 0xf) != 0)))
return 1;
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
"1822 Invalid %s: %02x:%02x:%02x:%02x:"
"%02x:%02x:%02x:%02x\n",
name_type,
wwn->u.wwn[0], wwn->u.wwn[1],
wwn->u.wwn[2], wwn->u.wwn[3],
wwn->u.wwn[4], wwn->u.wwn[5],
wwn->u.wwn[6], wwn->u.wwn[7]);
return 0;
}
static int
lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
{
struct lpfc_vport *vport;
unsigned long flags;
spin_lock_irqsave(&phba->port_list_lock, flags);
list_for_each_entry(vport, &phba->port_list, listentry) {
if (vport == new_vport)
continue;
/* If they match, return not unique */
if (memcmp(&vport->fc_sparam.portName,
&new_vport->fc_sparam.portName,
sizeof(struct lpfc_name)) == 0) {
spin_unlock_irqrestore(&phba->port_list_lock, flags);
return 0;
}
}
spin_unlock_irqrestore(&phba->port_list_lock, flags);
return 1;
}
/**
* lpfc_discovery_wait - Wait for driver discovery to quiesce
* @vport: The virtual port for which this call is being executed.
*
* This driver calls this routine specifically from lpfc_vport_delete
* to enforce a synchronous execution of vport
* delete relative to discovery activities. The
* lpfc_vport_delete routine should not return until it
* can reasonably guarantee that discovery has quiesced.
* Post FDISC LOGO, the driver must wait until its SAN teardown is
* complete and all resources recovered before allowing
* cleanup.
*
* This routine does not require any locks held.
**/
static void lpfc_discovery_wait(struct lpfc_vport *vport)
Annotation
- Immediate include surface: `linux/blkdev.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/idr.h`, `linux/interrupt.h`, `linux/kthread.h`, `linux/pci.h`, `linux/slab.h`.
- Detected declarations: `function lpfc_vport_set_state`, `function lpfc_alloc_vpi`, `function lpfc_free_vpi`, `function lpfc_vport_sparm`, `function lpfc_valid_wwn_format`, `function lpfc_unique_wwpn`, `function lpfc_discovery_wait`, `function lpfc_vport_create`, `function test_bit`, `function lpfc_send_npiv_logo`.
- 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.