drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
Extension
.c
Size
18526 bytes
Lines
678
Domain
Driver Families
Bucket
drivers/net
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!info->segs) {
				rc = -EIO;
				break;
			}

			info->dest_buf_size = info->segs *
					sizeof(struct coredump_segment_record);
			info->dest_buf = kmalloc(info->dest_buf_size,
						 GFP_KERNEL);
			if (!info->dest_buf) {
				rc = -ENOMEM;
				break;
			}
		}

		if (cmn_req->req_type ==
				cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE))
			info->dest_buf_size += len;

		if (info->dest_buf) {
			if ((info->seg_start + off + len) <=
			    BNXT_COREDUMP_BUF_LEN(info->buf_len)) {
				u16 copylen = min_t(u16, len,
						    info->dest_buf_size - off);

				memcpy(info->dest_buf + off, dma_buf, copylen);
				if (copylen < len)
					break;
			} else {
				rc = -ENOBUFS;
				if (cmn_req->req_type ==
				    cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) {
					kfree(info->dest_buf);
					info->dest_buf = NULL;
				}
				break;
			}
		}

		if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE))
			break;

		seq++;
		off += len;
	}
	hwrm_req_drop(bp, msg);
	return rc;
}

static int bnxt_hwrm_dbg_coredump_list(struct bnxt *bp,
				       struct bnxt_coredump *coredump)
{
	struct bnxt_hwrm_dbg_dma_info info = {NULL};
	struct hwrm_dbg_coredump_list_input *req;
	int rc;

	rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_LIST);
	if (rc)
		return rc;

	info.dma_len = COREDUMP_LIST_BUF_LEN;
	info.seq_off = offsetof(struct hwrm_dbg_coredump_list_input, seq_no);
	info.data_len_off = offsetof(struct hwrm_dbg_coredump_list_output,
				     data_len);

	rc = bnxt_hwrm_dbg_dma_data(bp, req, &info);
	if (!rc) {
		coredump->data = info.dest_buf;
		coredump->data_size = info.dest_buf_size;
		coredump->total_segs = info.segs;
	}
	return rc;
}

static int bnxt_hwrm_dbg_coredump_initiate(struct bnxt *bp, u16 dump_type,
					   u16 component_id, u16 segment_id)
{
	struct hwrm_dbg_coredump_initiate_input *req;
	int rc;

	rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_INITIATE);
	if (rc)
		return rc;

	hwrm_req_timeout(bp, req, bp->hwrm_cmd_max_timeout);
	req->component_id = cpu_to_le16(component_id);
	req->segment_id = cpu_to_le16(segment_id);
	if (dump_type == BNXT_DUMP_LIVE_WITH_CTX_L1_CACHE)
		req->seg_flags = DBG_COREDUMP_INITIATE_REQ_SEG_FLAGS_COLLECT_CTX_L1_CACHE;

Annotation

Implementation Notes