drivers/scsi/elx/libefc/efc_els.c

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

File Facts

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

switch (reason_code) {
		case ELS_RJT_BUSY:
			els->node->els_req_cnt--;
			els_io_printf(els,
				      "LS_RJT Logical Busy, delay and retry\n");
			timer_setup(&els->delay_timer,
				    efc_els_delay_timer_cb, 0);
			mod_timer(&els->delay_timer,
				  jiffies + msecs_to_jiffies(5000));
			break;
		default:
			efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_RJT,
					   &cbdata);
			break;
		}
		break;

	case SLI4_FC_WCQE_STATUS_LOCAL_REJECT:
		switch (ext_status) {
		case SLI4_FC_LOCAL_REJECT_SEQUENCE_TIMEOUT:
			efc_els_retry(els);
			break;
		default:
			efc_log_err(efc, "LOCAL_REJECT with ext status:%x\n",
				    ext_status);
			efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL,
					   &cbdata);
			break;
		}
		break;
	default:	/* Other error */
		efc_log_warn(efc, "els req failed status x%x, ext_status x%x\n",
			     status, ext_status);
		efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL, &cbdata);
		break;
	}

	return 0;
}

void efc_disc_io_complete(struct efc_disc_io *io, u32 len, u32 status,
			  u32 ext_status)
{
	struct efc_els_io_req *els =
				container_of(io, struct efc_els_io_req, io);

	WARN_ON_ONCE(!els->cb);

	((efc_hw_srrs_cb_t)els->cb) (els, len, status, ext_status);
}

static int efc_els_send_req(struct efc_node *node, struct efc_els_io_req *els,
			    enum efc_disc_io_type io_type)
{
	int rc = 0;
	struct efc *efc = node->efc;
	struct efc_node_cb cbdata;

	/* update ELS request counter */
	els->node->els_req_cnt++;

	/* Prepare the IO request details */
	els->io.io_type = io_type;
	els->io.xmit_len = els->io.req.size;
	els->io.rsp_len = els->io.rsp.size;
	els->io.rpi = node->rnode.indicator;
	els->io.vpi = node->nport->indicator;
	els->io.s_id = node->nport->fc_id;
	els->io.d_id = node->rnode.fc_id;

	if (node->rnode.attached)
		els->io.rpi_registered = true;

	els->cb = efc_els_req_cb;

	rc = efc->tt.send_els(efc, &els->io);
	if (!rc)
		return rc;

	cbdata.status = EFC_STATUS_INVALID;
	cbdata.ext_status = EFC_STATUS_INVALID;
	cbdata.els_rsp = els->io.rsp;
	efc_log_err(efc, "efc_els_send failed: %d\n", rc);
	efc_els_io_cleanup(els, EFC_EVT_SRRS_ELS_REQ_FAIL, &cbdata);

	return rc;
}

static void
efc_els_retry(struct efc_els_io_req *els)

Annotation

Implementation Notes