drivers/scsi/qla2xxx/qla_edif.c

Source file repositories/reference/linux-study-clean/drivers/scsi/qla2xxx/qla_edif.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/qla2xxx/qla_edif.c
Extension
.c
Size
105848 bytes
Lines
3716
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 edb_node {
	struct  list_head	list;
	uint32_t		ntype;
	union {
		port_id_t	plogi_did;
		uint32_t	async;
		port_id_t	els_sid;
		struct edif_sa_update_aen	sa_aen;
	} u;
};

static struct els_sub_cmd {
	uint16_t cmd;
	const char *str;
} sc_str[] = {
	{SEND_ELS, "send ELS"},
	{SEND_ELS_REPLY, "send ELS Reply"},
	{PULL_ELS, "retrieve ELS"},
};

const char *sc_to_str(uint16_t cmd)
{
	int i;
	struct els_sub_cmd *e;

	for (i = 0; i < ARRAY_SIZE(sc_str); i++) {
		e = sc_str + i;
		if (cmd == e->cmd)
			return e->str;
	}
	return "unknown";
}

static struct edb_node *qla_edb_getnext(scsi_qla_host_t *vha)
{
	unsigned long   flags;
	struct edb_node *edbnode = NULL;

	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);

	/* db nodes are fifo - no qualifications done */
	if (!list_empty(&vha->e_dbell.head)) {
		edbnode = list_first_entry(&vha->e_dbell.head,
					   struct edb_node, list);
		list_del_init(&edbnode->list);
	}

	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	return edbnode;
}

static void qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
{
	list_del_init(&node->list);
	kfree(node);
}

static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport,
		uint16_t handle)
{
	struct edif_list_entry *entry;
	struct edif_list_entry *tentry;
	struct list_head *indx_list = &fcport->edif.edif_indx_list;

	list_for_each_entry_safe(entry, tentry, indx_list, next) {
		if (entry->handle == handle)
			return entry;
	}
	return NULL;
}

/* timeout called when no traffic and delayed rx sa_index delete */
static void qla2x00_sa_replace_iocb_timeout(struct timer_list *t)
{
	struct edif_list_entry *edif_entry = timer_container_of(edif_entry, t,
								timer);
	fc_port_t *fcport = edif_entry->fcport;
	struct scsi_qla_host *vha = fcport->vha;
	struct  edif_sa_ctl *sa_ctl;
	uint16_t nport_handle;
	unsigned long flags = 0;

	ql_dbg(ql_dbg_edif, vha, 0x3069,
	    "%s:  nport_handle 0x%x,  SA REPL Delay Timeout, %8phC portid=%06x\n",
	    __func__, edif_entry->handle, fcport->port_name, fcport->d_id.b24);

	/*
	 * if delete_sa_index is valid then no one has serviced this
	 * delayed delete

Annotation

Implementation Notes