On 9/6/22 10:45 AM, Dmitry Bogdanov wrote: > From: Roman Bolshakov <r.bolshakov@xxxxxxxxx> > > SAM-5 4.6.5.2 (Relative Port Identifier attribute) defines the attribute > as unique across SCSI target ports. > > The change introduces RTPI attribute to se_portal group. The value is > auto-incremented and unique across all SCSI target ports. It also limits > number of SCSI target ports to 65535. > > Signed-off-by: Roman Bolshakov <r.bolshakov@xxxxxxxxx> > Signed-off-by: Dmitry Bogdanov <d.bogdanov@xxxxxxxxx> > --- > drivers/target/target_core_tpg.c | 78 +++++++++++++++++++++++++++++-- > include/target/target_core_base.h | 4 ++ > 2 files changed, 77 insertions(+), 5 deletions(-) > > diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c > index f0d38d77edcc..325ef439fb42 100644 > --- a/drivers/target/target_core_tpg.c > +++ b/drivers/target/target_core_tpg.c > @@ -31,6 +31,10 @@ > #include "target_core_ua.h" > > extern struct se_device *g_lun0_dev; > +static u16 g_tpg_count; > +static u16 g_tpg_rtpi_counter = 1; > +static LIST_HEAD(g_tpg_list); > +static DEFINE_SPINLOCK(g_tpg_lock); > > /* __core_tpg_get_initiator_node_acl(): > * > @@ -439,6 +443,57 @@ static void core_tpg_lun_ref_release(struct percpu_ref *ref) > complete(&lun->lun_shutdown_comp); > } > > +static int core_tpg_register_rtpi(struct se_portal_group *se_tpg) > +{ > + struct se_portal_group *tpg; > + > + /* > + * Allocate the next RELATIVE TARGET PORT IDENTIFIER. > + * Here is the table from SPC-4 4.3.4: > + * > + * Table 34 -- Relative target port identifier values > + * > + * Value Description > + * 0h Reserved > + * 1h Relative port 1, historically known as port A > + * 2h Relative port 2, historically known as port B > + * 3h to FFFFh Relative port 3 through 65 535 > + */ > + spin_lock(&g_tpg_lock); > + > + if (g_tpg_count == 0xffff) { > + spin_unlock(&g_tpg_lock); > + pr_warn("Reached g_tpg_count == 0xffff\n"); > + return -ENOSPC; > + } > +again: > + se_tpg->tpg_rtpi = g_tpg_rtpi_counter++; > + if (!se_tpg->tpg_rtpi) > + goto again; > + > + list_for_each_entry(tpg, &g_tpg_list, tpg_list) { > + /* > + * Make sure RELATIVE TARGET PORT IDENTIFIER is unique > + * for 16-bit wrap.. > + */ > + if (se_tpg->tpg_rtpi == tpg->tpg_rtpi) > + goto again; > + } > + list_add(&se_tpg->tpg_list, &g_tpg_list); > + g_tpg_count++; > + spin_unlock(&g_tpg_lock); > + I think you could just use an ida.