drivers/nvme/host/fc.c
Source file repositories/reference/linux-study-clean/drivers/nvme/host/fc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvme/host/fc.c- Extension
.c- Size
- 109133 bytes
- Lines
- 3975
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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
linux/module.hlinux/parser.huapi/scsi/fc/fc_fs.huapi/scsi/fc/fc_els.hlinux/delay.hlinux/overflow.hlinux/blk-cgroup.hnvme.hfabrics.hlinux/nvme-fc-driver.hlinux/nvme-fc.hfc.hscsi/scsi_transport_fc.h
Detected Declarations
struct nvme_fc_queuestruct nvmefc_ls_req_opstruct nvmefc_ls_rcv_opstruct nvme_fc_fcp_opstruct nvme_fcp_op_w_sglstruct nvme_fc_lportstruct nvme_fc_rportstruct nvme_fc_ctrlstruct nvmet_fc_traddrenum nvme_fc_queue_flagsenum nvme_fcop_flagsenum nvme_fcpop_statefunction to_fc_ctrlfunction localport_to_lportfunction remoteport_to_rportfunction ls_req_to_lsopfunction fcp_req_to_fcp_opfunction nvme_fc_free_lportfunction nvme_fc_lport_putfunction nvme_fc_lport_getfunction nvme_fc_attach_to_unreg_lportfunction list_for_each_entryfunction nvme_fc_register_localportfunction nvme_fc_unregister_localportfunction nvme_fc_signal_discovery_scanfunction nvme_fc_free_rportfunction nvme_fc_rport_putfunction nvme_fc_rport_getfunction nvme_fc_resume_controllerfunction nvme_fc_attach_to_suspended_rportfunction list_for_each_entryfunction __nvme_fc_set_dev_loss_tmofunction nvme_fc_register_remoteportfunction nvme_fc_abort_lsopsfunction list_for_each_entryfunction nvme_fc_ctrl_connectivity_lossfunction nvme_fc_unregister_remoteportfunction list_for_each_entryfunction nvme_fc_rescan_remoteportfunction nvme_fc_set_remoteport_devlossfunction mappingsfunction fc_dma_mapping_errorfunction fc_dma_unmap_singlefunction fc_dma_sync_single_for_cpufunction fc_dma_sync_single_for_devicefunction fc_map_sgfunction for_each_sgfunction fc_dma_map_sg
Annotated Snippet
static const struct blk_mq_ops nvme_fc_mq_ops = {
.queue_rq = nvme_fc_queue_rq,
.complete = nvme_fc_complete_rq,
.init_request = nvme_fc_init_request,
.exit_request = nvme_fc_exit_request,
.init_hctx = nvme_fc_init_hctx,
.timeout = nvme_fc_timeout,
.map_queues = nvme_fc_map_queues,
};
static int
nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl)
{
struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
unsigned int nr_io_queues;
int ret;
nr_io_queues = min3(opts->nr_io_queues, num_online_cpus(),
ctrl->lport->ops->max_hw_queues);
ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
if (ret) {
dev_info(ctrl->ctrl.device,
"set_queue_count failed: %d\n", ret);
return ret;
}
ctrl->ctrl.queue_count = nr_io_queues + 1;
if (!nr_io_queues)
return 0;
nvme_fc_init_io_queues(ctrl);
ret = nvme_alloc_io_tag_set(&ctrl->ctrl, &ctrl->tag_set,
&nvme_fc_mq_ops, 1,
struct_size_t(struct nvme_fcp_op_w_sgl, priv,
ctrl->lport->ops->fcprqst_priv_sz));
if (ret)
return ret;
ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.sqsize + 1);
if (ret)
goto out_cleanup_tagset;
ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.sqsize + 1);
if (ret)
goto out_delete_hw_queues;
ctrl->ioq_live = true;
return 0;
out_delete_hw_queues:
nvme_fc_delete_hw_io_queues(ctrl);
out_cleanup_tagset:
nvme_remove_io_tag_set(&ctrl->ctrl);
nvme_fc_free_io_queues(ctrl);
/* force put free routine to ignore io queues */
ctrl->ctrl.tagset = NULL;
return ret;
}
static int
nvme_fc_recreate_io_queues(struct nvme_fc_ctrl *ctrl)
{
struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
u32 prior_ioq_cnt = ctrl->ctrl.queue_count - 1;
unsigned int nr_io_queues;
int ret;
nr_io_queues = min3(opts->nr_io_queues, num_online_cpus(),
ctrl->lport->ops->max_hw_queues);
ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
if (ret) {
dev_info(ctrl->ctrl.device,
"set_queue_count failed: %d\n", ret);
return ret;
}
if (!nr_io_queues && prior_ioq_cnt) {
dev_info(ctrl->ctrl.device,
"Fail Reconnect: At least 1 io queue "
"required (was %d)\n", prior_ioq_cnt);
return -ENOSPC;
}
ctrl->ctrl.queue_count = nr_io_queues + 1;
/* check for io queues existing */
if (ctrl->ctrl.queue_count == 1)
Annotation
- Immediate include surface: `linux/module.h`, `linux/parser.h`, `uapi/scsi/fc/fc_fs.h`, `uapi/scsi/fc/fc_els.h`, `linux/delay.h`, `linux/overflow.h`, `linux/blk-cgroup.h`, `nvme.h`.
- Detected declarations: `struct nvme_fc_queue`, `struct nvmefc_ls_req_op`, `struct nvmefc_ls_rcv_op`, `struct nvme_fc_fcp_op`, `struct nvme_fcp_op_w_sgl`, `struct nvme_fc_lport`, `struct nvme_fc_rport`, `struct nvme_fc_ctrl`, `struct nvmet_fc_traddr`, `enum nvme_fc_queue_flags`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern 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.