drivers/scsi/esas2r/esas2r_int.c

Source file repositories/reference/linux-study-clean/drivers/scsi/esas2r/esas2r_int.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/esas2r/esas2r_int.c
Extension
.c
Size
24654 bytes
Lines
945
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 (rq->req_stat == RS_ABORTED) {
			if (rq->timeout > RQ_MAX_TIMEOUT)
				rq->req_stat = RS_TIMEOUT;
		} else if (rq->req_stat == RS_SCSI_ERROR) {
			u8 scsistatus = rq->func_rsp.scsi_rsp.scsi_stat;

			esas2r_trace("scsistatus: %x", scsistatus);

			/* Any of these are a good result. */
			if (scsistatus == SAM_STAT_GOOD || scsistatus ==
			    SAM_STAT_CONDITION_MET || scsistatus ==
			    SAM_STAT_INTERMEDIATE || scsistatus ==
			    SAM_STAT_INTERMEDIATE_CONDITION_MET) {
				rq->req_stat = RS_SUCCESS;
				rq->func_rsp.scsi_rsp.scsi_stat =
					SAM_STAT_GOOD;
			}
		}
	}
}

static void esas2r_get_outbound_responses(struct esas2r_adapter *a)
{
	struct atto_vda_ob_rsp *rsp;
	u32 rspput_ptr;
	u32 rspget_ptr;
	struct esas2r_request *rq;
	u32 handle;
	unsigned long flags;

	LIST_HEAD(comp_list);

	esas2r_trace_enter();

	spin_lock_irqsave(&a->queue_lock, flags);

	/* Get the outbound limit and pointers */
	rspput_ptr = le32_to_cpu(*a->outbound_copy) & MU_OLC_WRT_PTR;
	rspget_ptr = a->last_read;

	esas2r_trace("rspput_ptr: %x, rspget_ptr: %x", rspput_ptr, rspget_ptr);

	/* If we don't have anything to process, get out */
	if (unlikely(rspget_ptr == rspput_ptr)) {
		spin_unlock_irqrestore(&a->queue_lock, flags);
		esas2r_trace_exit();
		return;
	}

	/* Make sure the firmware is healthy */
	if (unlikely(rspput_ptr >= a->list_size)) {
		spin_unlock_irqrestore(&a->queue_lock, flags);
		esas2r_bugon();
		esas2r_local_reset_adapter(a);
		esas2r_trace_exit();
		return;
	}

	do {
		rspget_ptr++;

		if (rspget_ptr >= a->list_size)
			rspget_ptr = 0;

		rsp = (struct atto_vda_ob_rsp *)a->outbound_list_md.virt_addr
		      + rspget_ptr;

		handle = rsp->handle;

		/* Verify the handle range */
		if (unlikely(LOWORD(handle) == 0
			     || LOWORD(handle) > num_requests +
			     num_ae_requests + 1)) {
			esas2r_bugon();
			continue;
		}

		/* Get the request for this handle */
		rq = a->req_table[LOWORD(handle)];

		if (unlikely(rq == NULL || rq->vrq->scsi.handle != handle)) {
			esas2r_bugon();
			continue;
		}

		list_del(&rq->req_list);

		/* Get the completion status */
		rq->req_stat = rsp->req_stat;

Annotation

Implementation Notes