drivers/scsi/elx/libefc/efc_cmds.c

Source file repositories/reference/linux-study-clean/drivers/scsi/elx/libefc/efc_cmds.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/libefc/efc_cmds.c
Extension
.c
Size
18595 bytes
Lines
783
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

if (rnode->attached) {
			efc_log_err(efc, "rnode is still attached\n");
			return -EIO;
		}
		if (rnode->indicator != U32_MAX) {
			if (sli_resource_free(efc->sli, SLI4_RSRC_RPI,
					      rnode->indicator)) {
				efc_log_err(efc,
					    "RPI free fail RPI %d addr=%#x\n",
					    rnode->indicator, rnode->fc_id);
				rc = -EIO;
			} else {
				rnode->indicator = U32_MAX;
				rnode->index = U32_MAX;
			}
		}
	}

	return rc;
}

static int
efc_cmd_node_free_cb(struct efc *efc, int status, u8 *mqe, void *arg)
{
	struct efc_remote_node *rnode = arg;
	struct sli4_mbox_command_header *hdr =
				(struct sli4_mbox_command_header *)mqe;
	int evt = EFC_EVT_NODE_FREE_FAIL;
	int rc = 0;

	if (status || le16_to_cpu(hdr->status)) {
		efc_log_debug(efc, "bad status cqe=%#x mqe=%#x\n", status,
			      le16_to_cpu(hdr->status));

		/*
		 * In certain cases, a non-zero MQE status is OK (all must be
		 * true):
		 *   - node is attached
		 *   - status is 0x1400
		 */
		if (!rnode->attached ||
		    (le16_to_cpu(hdr->status) != SLI4_MBX_STATUS_RPI_NOT_REG))
			rc = -EIO;
	}

	if (!rc) {
		rnode->attached = false;
		evt = EFC_EVT_NODE_FREE_OK;
	}

	efc_remote_node_cb(efc, evt, rnode);

	return rc;
}

int
efc_cmd_node_detach(struct efc *efc, struct efc_remote_node *rnode)
{
	u8 buf[SLI4_BMBX_SIZE];
	int rc = -EIO;

	if (!rnode) {
		efc_log_err(efc, "bad parameter rnode=%p\n", rnode);
		return -EIO;
	}

	if (rnode->nport) {
		if (!rnode->attached)
			return -EIO;

		rc = -EIO;

		if (!sli_cmd_unreg_rpi(efc->sli, buf, rnode->indicator,
				       SLI4_RSRC_RPI, U32_MAX))
			rc = efc->tt.issue_mbox_rqst(efc->base, buf,
					efc_cmd_node_free_cb, rnode);

		if (rc != 0) {
			efc_log_err(efc, "UNREG_RPI failed\n");
			rc = -EIO;
		}
	}

	return rc;
}

Annotation

Implementation Notes