drivers/scsi/esas2r/esas2r_flash.c

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

File Facts

System
Linux kernel
Corpus path
drivers/scsi/esas2r/esas2r_flash.c
Extension
.c
Size
39017 bytes
Lines
1523
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 (vrq->sub_func) {
		case VDA_FLASH_BEGINW:
			if (fc->sgc.cur_offset == NULL)
				goto commit;

			vrq->sub_func = VDA_FLASH_WRITE;
			rq->req_stat = RS_PENDING;
			break;

		case VDA_FLASH_WRITE:
commit:
			vrq->sub_func = VDA_FLASH_COMMIT;
			rq->req_stat = RS_PENDING;
			rq->interrupt_cb = fc->interrupt_cb;
			break;

		default:
			break;
		}
	}

	if (rq->req_stat != RS_PENDING)
		/*
		 * All done. call the real callback to complete the FM API
		 * request.  We should only get here if a BEGINW or WRITE
		 * operation failed.
		 */
		(*fc->interrupt_cb)(a, rq);
}

/*
 * Build a flash request based on the flash context.  The request status
 * is filled in on an error.
 */
static void build_flash_msg(struct esas2r_adapter *a,
			    struct esas2r_request *rq)
{
	struct esas2r_flash_context *fc =
		(struct esas2r_flash_context *)rq->interrupt_cx;
	struct esas2r_sg_context *sgc = &fc->sgc;
	u8 cksum = 0;

	/* calculate the checksum */
	if (fc->func == VDA_FLASH_BEGINW) {
		if (sgc->cur_offset)
			cksum = esas2r_calc_byte_xor_cksum(sgc->cur_offset,
							   sgc->length,
							   0);
		rq->interrupt_cb = esas2r_fmapi_callback;
	} else {
		rq->interrupt_cb = fc->interrupt_cb;
	}
	esas2r_build_flash_req(a,
			       rq,
			       fc->func,
			       cksum,
			       fc->flsh_addr,
			       sgc->length);

	esas2r_rq_free_sg_lists(rq, a);

	/*
	 * remember the length we asked for.  we have to keep track of
	 * the current amount done so we know how much to compare when
	 * doing the verification phase.
	 */
	fc->curr_len = fc->sgc.length;

	if (sgc->cur_offset) {
		/* setup the S/G context to build the S/G table  */
		esas2r_sgc_init(sgc, a, rq, &rq->vrq->flash.data.sge[0]);

		if (!esas2r_build_sg_list(a, rq, sgc)) {
			rq->req_stat = RS_BUSY;
			return;
		}
	} else {
		fc->sgc.length = 0;
	}

	/* update the flsh_addr to the next one to write to  */
	fc->flsh_addr += fc->curr_len;
}

/* determine the method to process the flash request */
static bool load_image(struct esas2r_adapter *a, struct esas2r_request *rq)
{
	/*
	 * assume we have more to do.  if we return with the status set to
	 * RS_PENDING, FM API tasks will continue.

Annotation

Implementation Notes