drivers/scsi/fnic/fnic_scsi.c
Source file repositories/reference/linux-study-clean/drivers/scsi/fnic/fnic_scsi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/fnic/fnic_scsi.c- Extension
.c- Size
- 91903 bytes
- Lines
- 3036
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/mempool.hlinux/errno.hlinux/init.hlinux/workqueue.hlinux/pci.hlinux/scatterlist.hlinux/skbuff.hlinux/spinlock.hlinux/etherdevice.hlinux/if_ether.hlinux/if_vlan.hlinux/delay.hlinux/gfp.hscsi/scsi.hscsi/scsi_host.hscsi/scsi_device.hscsi/scsi_cmnd.hscsi/scsi_tcq.hscsi/fc/fc_els.hscsi/fc/fc_fcoe.hscsi/fc_frame.hscsi/scsi_transport_fc.hfnic_io.hfnic.h
Detected Declarations
struct fnic_rport_abort_io_iter_datastruct fnic_pending_aborts_iter_dataenum terminate_io_returnfunction fnic_release_ioreq_buffunction fnic_count_portid_ioreqs_iterfunction fnic_count_ioreqsfunction fnic_count_all_ioreqsfunction fnic_count_lun_ioreqs_iterfunction fnic_count_lun_ioreqsfunction free_wq_copy_descsfunction __fnic_set_state_flagsfunction fnic_fw_reset_handlerfunction fnic_flogi_reg_handlerfunction fnic_queue_wq_copy_descfunction for_each_sgfunction fnic_queuecommandfunction fnic_fcpio_fw_reset_cmpl_handlerfunction fnic_fcpio_flogi_reg_cmpl_handlerfunction is_ack_index_in_rangefunction fnic_fcpio_ack_handlerfunction fnic_fcpio_icmnd_cmpl_handlerfunction fnic_fcpio_itmf_cmpl_handlerfunction fnic_fcpio_cmpl_handlerfunction fnic_wq_copy_cmpl_handlerfunction fnic_cleanup_io_iterfunction fnic_cleanup_iofunction fnic_wq_copy_cleanup_handlerfunction fnic_queue_abort_io_reqfunction fnic_rport_abort_io_iterfunction fnic_rport_exch_resetfunction fnic_terminate_rport_iofunction fnic_scsi_unloadfunction fnic_scsi_unload_cleanupfunction fnic_abort_cmdfunction fnic_queue_dr_io_reqfunction fnic_pending_aborts_iterfunction fnic_clean_pending_abortsfunction fnic_device_resetfunction fnic_post_flogo_linkflapfunction fnic_resetfunction fnic_issue_fc_host_lipfunction fnic_host_resetfunction fnic_abts_pending_iterfunction fnic_is_abts_pendingfunction fnic_eh_host_reset_handler
Annotated Snippet
struct fnic_rport_abort_io_iter_data {
struct fnic *fnic;
u32 port_id;
int term_cnt;
};
static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data)
{
struct request *const rq = scsi_cmd_to_rq(sc);
struct fnic_rport_abort_io_iter_data *iter_data = data;
struct fnic *fnic = iter_data->fnic;
int abt_tag = 0;
struct fnic_io_req *io_req;
struct reset_stats *reset_stats = &fnic->fnic_stats.reset_stats;
struct terminate_stats *term_stats = &fnic->fnic_stats.term_stats;
struct scsi_lun fc_lun;
enum fnic_ioreq_state old_ioreq_state;
uint16_t hwq = 0;
unsigned long flags;
abt_tag = blk_mq_unique_tag(rq);
hwq = blk_mq_unique_tag_to_hwq(abt_tag);
if (!sc) {
FNIC_SCSI_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
"sc is NULL abt_tag: 0x%x hwq: %d\n", abt_tag, hwq);
return true;
}
spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
io_req = fnic_priv(sc)->io_req;
if (!io_req || io_req->port_id != iter_data->port_id) {
spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
return true;
}
if ((fnic_priv(sc)->flags & FNIC_DEVICE_RESET) &&
!(fnic_priv(sc)->flags & FNIC_DEV_RST_ISSUED)) {
FNIC_SCSI_DBG(KERN_ERR, fnic->host, fnic->fnic_num,
"hwq: %d abt_tag: 0x%x flags: 0x%x Device reset is not pending\n",
hwq, abt_tag, fnic_priv(sc)->flags);
spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
return true;
}
/*
* Found IO that is still pending with firmware and
* belongs to rport that went away
*/
if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING) {
spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
return true;
}
if (io_req->abts_done) {
shost_printk(KERN_ERR, fnic->host,
"fnic_rport_exch_reset: io_req->abts_done is set state is %s\n",
fnic_ioreq_state_to_str(fnic_priv(sc)->state));
}
if (!(fnic_priv(sc)->flags & FNIC_IO_ISSUED)) {
shost_printk(KERN_ERR, fnic->host,
"rport_exch_reset IO not yet issued %p abt_tag 0x%x",
sc, abt_tag);
shost_printk(KERN_ERR, fnic->host,
"flags %x state %d\n", fnic_priv(sc)->flags,
fnic_priv(sc)->state);
}
old_ioreq_state = fnic_priv(sc)->state;
fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
fnic_priv(sc)->abts_status = FCPIO_INVALID_CODE;
if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET) {
atomic64_inc(&reset_stats->device_reset_terminates);
abt_tag |= FNIC_TAG_DEV_RST;
FNIC_SCSI_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
"dev reset sc 0x%p\n", sc);
}
FNIC_SCSI_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
"fnic_rport_exch_reset: dev rst sc 0x%p\n", sc);
WARN_ON_ONCE(io_req->abts_done);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->host, fnic->fnic_num,
"fnic_rport_reset_exch: Issuing abts\n");
spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
/* Queue the abort command to firmware */
int_to_scsilun(sc->device->lun, &fc_lun);
if (fnic_queue_abort_io_req(fnic, abt_tag,
Annotation
- Immediate include surface: `linux/mempool.h`, `linux/errno.h`, `linux/init.h`, `linux/workqueue.h`, `linux/pci.h`, `linux/scatterlist.h`, `linux/skbuff.h`, `linux/spinlock.h`.
- Detected declarations: `struct fnic_rport_abort_io_iter_data`, `struct fnic_pending_aborts_iter_data`, `enum terminate_io_return`, `function fnic_release_ioreq_buf`, `function fnic_count_portid_ioreqs_iter`, `function fnic_count_ioreqs`, `function fnic_count_all_ioreqs`, `function fnic_count_lun_ioreqs_iter`, `function fnic_count_lun_ioreqs`, `function free_wq_copy_descs`.
- 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.