drivers/target/iscsi/iscsi_target_tpg.c

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

File Facts

System
Linux kernel
Corpus path
drivers/target/iscsi/iscsi_target_tpg.c
Extension
.c
Size
22023 bytes
Lines
882
Domain
Driver Families
Bucket
drivers/target
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 (tpg->tpg_state != TPG_STATE_ACTIVE) {
			spin_unlock(&tpg->tpg_state_lock);
			continue;
		}
		spin_unlock(&tpg->tpg_state_lock);

		spin_lock(&tpg->tpg_np_lock);
		list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
			if (tpg_np->tpg_np == np) {
				*tpg_np_out = tpg_np;
				kref_get(&tpg_np->tpg_np_kref);
				spin_unlock(&tpg->tpg_np_lock);
				spin_unlock(&tiqn->tiqn_tpg_lock);
				return tpg;
			}
		}
		spin_unlock(&tpg->tpg_np_lock);
	}
	spin_unlock(&tiqn->tiqn_tpg_lock);

	return NULL;
}

int iscsit_get_tpg(
	struct iscsi_portal_group *tpg)
{
	return mutex_lock_interruptible(&tpg->tpg_access_lock);
}

void iscsit_put_tpg(struct iscsi_portal_group *tpg)
{
	mutex_unlock(&tpg->tpg_access_lock);
}

static void iscsit_clear_tpg_np_login_thread(
	struct iscsi_tpg_np *tpg_np,
	struct iscsi_portal_group *tpg,
	bool shutdown)
{
	if (!tpg_np->tpg_np) {
		pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
		return;
	}

	if (shutdown)
		tpg_np->tpg_np->enabled = false;
	iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown);
}

static void iscsit_clear_tpg_np_login_threads(
	struct iscsi_portal_group *tpg,
	bool shutdown)
{
	struct iscsi_tpg_np *tpg_np;

	spin_lock(&tpg->tpg_np_lock);
	list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
		if (!tpg_np->tpg_np) {
			pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
			continue;
		}
		spin_unlock(&tpg->tpg_np_lock);
		iscsit_clear_tpg_np_login_thread(tpg_np, tpg, shutdown);
		spin_lock(&tpg->tpg_np_lock);
	}
	spin_unlock(&tpg->tpg_np_lock);
}

static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
{
	struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;

	a->authentication = TA_AUTHENTICATION;
	a->login_timeout = TA_LOGIN_TIMEOUT;
	a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
	a->generate_node_acls = TA_GENERATE_NODE_ACLS;
	a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
	a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
	a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
	a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY;
	a->default_erl = TA_DEFAULT_ERL;
	a->t10_pi = TA_DEFAULT_T10_PI;
	a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
	a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
	a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
}

int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
{
	if (tpg->tpg_state != TPG_STATE_FREE) {

Annotation

Implementation Notes