drivers/scsi/elx/efct/efct_hw.c

Source file repositories/reference/linux-study-clean/drivers/scsi/elx/efct/efct_hw.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/efct/efct_hw.c
Extension
.c
Size
88289 bytes
Lines
3581
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct efct_hw_link_stat_cb_arg {
	void (*cb)(int status, u32 num_counters,
		   struct efct_hw_link_stat_counts *counters, void *arg);
	void *arg;
};

struct efct_hw_host_stat_cb_arg {
	void (*cb)(int status, u32 num_counters,
		   struct efct_hw_host_stat_counts *counters, void *arg);
	void *arg;
};

struct efct_hw_fw_wr_cb_arg {
	void (*cb)(int status, u32 bytes_written, u32 change_status, void *arg);
	void *arg;
};

struct efct_mbox_rqst_ctx {
	int (*callback)(struct efc *efc, int status, u8 *mqe, void *arg);
	void *arg;
};

static int
efct_hw_link_event_init(struct efct_hw *hw)
{
	hw->link.status = SLI4_LINK_STATUS_MAX;
	hw->link.topology = SLI4_LINK_TOPO_NONE;
	hw->link.medium = SLI4_LINK_MEDIUM_MAX;
	hw->link.speed = 0;
	hw->link.loop_map = NULL;
	hw->link.fc_id = U32_MAX;

	return 0;
}

static int
efct_hw_read_max_dump_size(struct efct_hw *hw)
{
	u8 buf[SLI4_BMBX_SIZE];
	struct efct *efct = hw->os;
	int rc = 0;
	struct sli4_rsp_cmn_set_dump_location *rsp;

	/* attempt to detemine the dump size for function 0 only. */
	if (PCI_FUNC(efct->pci->devfn) != 0)
		return rc;

	if (sli_cmd_common_set_dump_location(&hw->sli, buf, 1, 0, NULL, 0))
		return -EIO;

	rsp = (struct sli4_rsp_cmn_set_dump_location *)
	      (buf + offsetof(struct sli4_cmd_sli_config, payload.embed));

	rc = efct_hw_command(hw, buf, EFCT_CMD_POLL, NULL, NULL);
	if (rc != 0) {
		efc_log_debug(hw->os, "set dump location cmd failed\n");
		return rc;
	}

	hw->dump_size =
	  le32_to_cpu(rsp->buffer_length_dword) & SLI4_CMN_SET_DUMP_BUFFER_LEN;

	efc_log_debug(hw->os, "Dump size %x\n",	hw->dump_size);

	return rc;
}

static int
__efct_read_topology_cb(struct efct_hw *hw, int status, u8 *mqe, void *arg)
{
	struct sli4_cmd_read_topology *read_topo =
				(struct sli4_cmd_read_topology *)mqe;
	u8 speed;
	struct efc_domain_record drec = {0};
	struct efct *efct = hw->os;

	if (status || le16_to_cpu(read_topo->hdr.status)) {
		efc_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
			      le16_to_cpu(read_topo->hdr.status));
		return -EIO;
	}

	switch (le32_to_cpu(read_topo->dw2_attentype) &
		SLI4_READTOPO_ATTEN_TYPE) {
	case SLI4_READ_TOPOLOGY_LINK_UP:
		hw->link.status = SLI4_LINK_STATUS_UP;
		break;
	case SLI4_READ_TOPOLOGY_LINK_DOWN:
		hw->link.status = SLI4_LINK_STATUS_DOWN;
		break;

Annotation

Implementation Notes