drivers/target/iscsi/iscsi_target_erl1.c

Source file repositories/reference/linux-study-clean/drivers/target/iscsi/iscsi_target_erl1.c

File Facts

System
Linux kernel
Corpus path
drivers/target/iscsi/iscsi_target_erl1.c
Extension
.c
Size
32075 bytes
Lines
1239
Domain
Driver Families
Bucket
drivers/target
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (rx_got != size) {
			ret = DATAOUT_CANNOT_RECOVER;
			break;
		}

		offset += size;
	}

	kfree(buf);
	return ret;
}

/*
 *	Used for retransmitting R2Ts from a R2T SNACK request.
 */
static int iscsit_send_recovery_r2t_for_snack(
	struct iscsit_cmd *cmd,
	struct iscsi_r2t *r2t)
{
	/*
	 * If the struct iscsi_r2t has not been sent yet, we can safely
	 * ignore retransmission
	 * of the R2TSN in question.
	 */
	spin_lock_bh(&cmd->r2t_lock);
	if (!r2t->sent_r2t) {
		spin_unlock_bh(&cmd->r2t_lock);
		return 0;
	}
	r2t->sent_r2t = 0;
	spin_unlock_bh(&cmd->r2t_lock);

	iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, ISTATE_SEND_R2T);

	return 0;
}

static int iscsit_handle_r2t_snack(
	struct iscsit_cmd *cmd,
	unsigned char *buf,
	u32 begrun,
	u32 runlength)
{
	u32 last_r2tsn;
	struct iscsi_r2t *r2t;

	/*
	 * Make sure the initiator is not requesting retransmission
	 * of R2TSNs already acknowledged by a TMR TASK_REASSIGN.
	 */
	if ((cmd->cmd_flags & ICF_GOT_DATACK_SNACK) &&
	    (begrun <= cmd->acked_data_sn)) {
		pr_err("ITT: 0x%08x, R2T SNACK requesting"
			" retransmission of R2TSN: 0x%08x to 0x%08x but already"
			" acked to  R2TSN: 0x%08x by TMR TASK_REASSIGN,"
			" protocol error.\n", cmd->init_task_tag, begrun,
			(begrun + runlength), cmd->acked_data_sn);

		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
	}

	if (runlength) {
		if ((begrun + runlength) > cmd->r2t_sn) {
			pr_err("Command ITT: 0x%08x received R2T SNACK"
			" with BegRun: 0x%08x, RunLength: 0x%08x, exceeds"
			" current R2TSN: 0x%08x, protocol error.\n",
			cmd->init_task_tag, begrun, runlength, cmd->r2t_sn);
			return iscsit_reject_cmd(cmd,
					ISCSI_REASON_BOOKMARK_INVALID, buf);
		}
		last_r2tsn = (begrun + runlength);
	} else
		last_r2tsn = cmd->r2t_sn;

	while (begrun < last_r2tsn) {
		r2t = iscsit_get_holder_for_r2tsn(cmd, begrun);
		if (!r2t)
			return -1;
		if (iscsit_send_recovery_r2t_for_snack(cmd, r2t) < 0)
			return -1;

		begrun++;
	}

	return 0;
}

/*
 *	Generates Offsets and NextBurstLength based on Begrun and Runlength
 *	carried in a Data SNACK or ExpDataSN in TMR TASK_REASSIGN.

Annotation

Implementation Notes