drivers/target/iscsi/cxgbit/cxgbit_target.c
Source file repositories/reference/linux-study-clean/drivers/target/iscsi/cxgbit/cxgbit_target.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/target/iscsi/cxgbit/cxgbit_target.c- Extension
.c- Size
- 41556 bytes
- Lines
- 1655
- Domain
- Driver Families
- Bucket
- drivers/target
- 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/workqueue.hlinux/kthread.hlinux/sched/signal.hlinux/unaligned.hnet/tcp.htarget/target_core_base.htarget/target_core_fabric.hcxgbit.h
Detected Declarations
struct sge_opaque_hdrfunction cxgbit_is_ofld_immfunction cxgbit_sgl_lenfunction cxgbit_calc_tx_flits_ofldfunction cxgbit_cpl_tx_data_isofunction cxgbit_tx_data_wrfunction cxgbit_arp_failure_skb_discardfunction cxgbit_push_tx_framesfunction cxgbit_unlock_sockfunction cxgbit_queue_skbfunction cxgbit_map_skbfunction cxgbit_tx_datain_isofunction cxgbit_tx_datainfunction cxgbit_xmit_datain_pdufunction cxgbit_xmit_nondatain_pdufunction cxgbit_xmit_pdufunction cxgbit_validate_paramsfunction cxgbit_set_digestfunction cxgbit_set_iso_npdufunction cxgbit_seq_pdu_inorderfunction cxgbit_set_paramsfunction cxgbit_put_login_txfunction cxgbit_skb_copy_to_sgfunction cxgbit_handle_immediate_datafunction cxgbit_get_immediate_datafunction cxgbit_handle_scsi_cmdfunction cxgbit_handle_iscsi_dataoutfunction cxgbit_handle_nop_outfunction cxgbit_handle_text_cmdfunction cxgbit_target_rx_opcodefunction cxgbit_rx_opcodefunction cxgbit_rx_login_pdufunction cxgbit_process_iscsi_pdufunction cxgbit_lro_skb_dumpfunction cxgbit_lro_hskb_resetfunction cxgbit_lro_skb_mergefunction cxgbit_process_lro_skbfunction cxgbit_t5_rx_lro_skbfunction cxgbit_rx_lro_skbfunction cxgbit_rx_skbfunction cxgbit_rxq_lenfunction cxgbit_wait_rxqfunction cxgbit_get_login_rxfunction cxgbit_get_rx_pdu
Annotated Snippet
struct sge_opaque_hdr {
void *dev;
dma_addr_t addr[MAX_SKB_FRAGS + 1];
};
static const u8 cxgbit_digest_len[] = {0, 4, 4, 8};
#define TX_HDR_LEN (sizeof(struct sge_opaque_hdr) + \
sizeof(struct fw_ofld_tx_data_wr))
static struct sk_buff *
__cxgbit_alloc_skb(struct cxgbit_sock *csk, u32 len, bool iso)
{
struct sk_buff *skb = NULL;
u8 submode = 0;
int errcode;
static const u32 hdr_len = TX_HDR_LEN + ISCSI_HDR_LEN;
if (len) {
skb = alloc_skb_with_frags(hdr_len, len,
0, &errcode,
GFP_KERNEL);
if (!skb)
return NULL;
skb_reserve(skb, TX_HDR_LEN);
skb_reset_transport_header(skb);
__skb_put(skb, ISCSI_HDR_LEN);
skb->data_len = len;
skb->len += len;
submode |= (csk->submode & CXGBIT_SUBMODE_DCRC);
} else {
u32 iso_len = iso ? sizeof(struct cpl_tx_data_iso) : 0;
skb = alloc_skb(hdr_len + iso_len, GFP_KERNEL);
if (!skb)
return NULL;
skb_reserve(skb, TX_HDR_LEN + iso_len);
skb_reset_transport_header(skb);
__skb_put(skb, ISCSI_HDR_LEN);
}
submode |= (csk->submode & CXGBIT_SUBMODE_HCRC);
cxgbit_skcb_submode(skb) = submode;
cxgbit_skcb_tx_extralen(skb) = cxgbit_digest_len[submode];
cxgbit_skcb_flags(skb) |= SKCBF_TX_NEED_HDR;
return skb;
}
static struct sk_buff *cxgbit_alloc_skb(struct cxgbit_sock *csk, u32 len)
{
return __cxgbit_alloc_skb(csk, len, false);
}
/*
* cxgbit_is_ofld_imm - check whether a packet can be sent as immediate data
* @skb: the packet
*
* Returns true if a packet can be sent as an offload WR with immediate
* data. We currently use the same limit as for Ethernet packets.
*/
static int cxgbit_is_ofld_imm(const struct sk_buff *skb)
{
int length = skb->len;
if (likely(cxgbit_skcb_flags(skb) & SKCBF_TX_NEED_HDR))
length += sizeof(struct fw_ofld_tx_data_wr);
if (likely(cxgbit_skcb_flags(skb) & SKCBF_TX_ISO))
length += sizeof(struct cpl_tx_data_iso);
return length <= MAX_IMM_OFLD_TX_DATA_WR_LEN;
}
/*
* cxgbit_sgl_len - calculates the size of an SGL of the given capacity
* @n: the number of SGL entries
* Calculates the number of flits needed for a scatter/gather list that
* can hold the given number of entries.
*/
static inline unsigned int cxgbit_sgl_len(unsigned int n)
{
n--;
return (3 * n) / 2 + (n & 1) + 2;
}
/*
* cxgbit_calc_tx_flits_ofld - calculate # of flits for an offload packet
Annotation
- Immediate include surface: `linux/workqueue.h`, `linux/kthread.h`, `linux/sched/signal.h`, `linux/unaligned.h`, `net/tcp.h`, `target/target_core_base.h`, `target/target_core_fabric.h`, `cxgbit.h`.
- Detected declarations: `struct sge_opaque_hdr`, `function cxgbit_is_ofld_imm`, `function cxgbit_sgl_len`, `function cxgbit_calc_tx_flits_ofld`, `function cxgbit_cpl_tx_data_iso`, `function cxgbit_tx_data_wr`, `function cxgbit_arp_failure_skb_discard`, `function cxgbit_push_tx_frames`, `function cxgbit_unlock_sock`, `function cxgbit_queue_skb`.
- Atlas domain: Driver Families / drivers/target.
- 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.