drivers/scsi/esas2r/esas2r_io.c

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

File Facts

System
Linux kernel
Corpus path
drivers/scsi/esas2r/esas2r_io.c
Extension
.c
Size
23656 bytes
Lines
878
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

test_bit(AF_POWER_DOWN, &a->flags))) {
		if (rq->vrq->scsi.function == VDA_FUNC_SCSI)
			rq->req_stat = RS_SEL2;
		else
			rq->req_stat = RS_DEGRADED;
	} else if (likely(rq->vrq->scsi.function == VDA_FUNC_SCSI)) {
		t = a->targetdb + rq->target_id;

		if (unlikely(t >= a->targetdb_end
			     || !(t->flags & TF_USED))) {
			rq->req_stat = RS_SEL;
		} else {
			/* copy in the target ID. */
			rq->vrq->scsi.target_id = cpu_to_le16(t->virt_targ_id);

			/*
			 * Test if we want to report RS_SEL for missing target.
			 * Note that if AF_DISC_PENDING is set than this will
			 * go on the defer queue.
			 */
			if (unlikely(t->target_state != TS_PRESENT &&
				     !test_bit(AF_DISC_PENDING, &a->flags)))
				rq->req_stat = RS_SEL;
		}
	}

	if (unlikely(rq->req_stat != RS_PENDING)) {
		esas2r_complete_request(a, rq);
		return;
	}

	esas2r_trace("rq=%p", rq);
	esas2r_trace("rq->vrq->scsi.handle=%x", rq->vrq->scsi.handle);

	if (rq->vrq->scsi.function == VDA_FUNC_SCSI) {
		esas2r_trace("rq->target_id=%d", rq->target_id);
		esas2r_trace("rq->vrq->scsi.flags=%x", rq->vrq->scsi.flags);
	}

	spin_lock_irqsave(&a->queue_lock, flags);

	if (likely(list_empty(&a->defer_list) &&
		   !test_bit(AF_CHPRST_PENDING, &a->flags) &&
		   !test_bit(AF_FLASHING, &a->flags) &&
		   !test_bit(AF_DISC_PENDING, &a->flags)))
		esas2r_local_start_request(a, startrq);
	else
		list_add_tail(&startrq->req_list, &a->defer_list);

	spin_unlock_irqrestore(&a->queue_lock, flags);
}

/*
 * Starts the specified request.  all requests have RS_PENDING set when this
 * routine is called.  The caller is usually esas2r_start_request, but
 * esas2r_do_deferred_processes will start request that are deferred.
 *
 * The caller must ensure that requests can be started.
 *
 * esas2r_start_request will defer a request if there are already requests
 * waiting or there is a chip reset pending.  once the reset condition clears,
 * esas2r_do_deferred_processes will call this function to start the request.
 *
 * When a request is started, it is placed on the active list and queued to
 * the controller.
 */
void esas2r_local_start_request(struct esas2r_adapter *a,
				struct esas2r_request *rq)
{
	esas2r_trace_enter();
	esas2r_trace("rq=%p", rq);
	esas2r_trace("rq->vrq:%p", rq->vrq);
	esas2r_trace("rq->vrq_md->phys_addr:%x", rq->vrq_md->phys_addr);

	if (unlikely(rq->vrq->scsi.function == VDA_FUNC_FLASH
		     && rq->vrq->flash.sub_func == VDA_FLASH_COMMIT))
		set_bit(AF_FLASHING, &a->flags);

	list_add_tail(&rq->req_list, &a->active_list);
	esas2r_start_vda_request(a, rq);
	esas2r_trace_exit();
	return;
}

void esas2r_start_vda_request(struct esas2r_adapter *a,
			      struct esas2r_request *rq)
{
	struct esas2r_inbound_list_source_entry *element;
	u32 dw;

Annotation

Implementation Notes