diff mbox series

scsi: target: core: Set MULTIP bit in INQUIRY

Message ID 20220906074820.18685-1-d.bogdanov@yadro.com
State Superseded
Headers show
Series scsi: target: core: Set MULTIP bit in INQUIRY | expand

Commit Message

Dmitry Bogdanov Sept. 6, 2022, 7:48 a.m. UTC
SAM-5 4.8.3 (SCSI target device with multiple SCSI ports structure)
obligates to set MULTIP bit when there's multiple SCSI target ports:

> Each device server shall indicate the presence of multiple SCSI target
> ports by setting the MULTIP bit to one in its standard INQUIRY data
> (see SPC-4).

The change sets MULTIP bit automatically to indicate the presence of
multiple SCSI target ports within standard inquiry response data if
there are multiple target ports in all target port groups of the
se_device.

Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
The patch is intended for 6.1/scsi-queue branch.
---
 drivers/target/target_core_spc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Mike Christie Sept. 7, 2022, 8:06 p.m. UTC | #1
On 9/6/22 2:48 AM, Dmitry Bogdanov wrote:
> 
> diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
> index c14441c89bed..32fb38ce98f4 100644
> --- a/drivers/target/target_core_spc.c
> +++ b/drivers/target/target_core_spc.c
> @@ -75,6 +75,8 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
>  	struct se_portal_group *tpg = lun->lun_tpg;
>  	struct se_device *dev = cmd->se_dev;
>  	struct se_session *sess = cmd->se_sess;
> +	struct se_lun *tmp_lun;
> +	size_t dev_ports = 0;
>  
>  	/* Set RMB (removable media) for tape devices */
>  	if (dev->transport->get_device_type(dev) == TYPE_TAPE)
> @@ -115,6 +117,20 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
>  			buf[5] |= 0x1;
>  	}
>  
> +	spin_lock(&dev->se_port_lock);
> +	list_for_each_entry(tmp_lun, &dev->dev_sep_list, lun_dev_link) {
> +		dev_ports++;
> +		/* Exact number of ports does not matter for MULTIP bit */
> +		if (dev_ports > 1)
> +			break;

Can you just check se_deice->export_count instead of looping?

Also, setting the bit seems fine. I was just wondering what uses it?
Dmitry Bogdanov Sept. 9, 2022, 8:30 a.m. UTC | #2
On Wed, Sep 07, 2022 at 03:06:04PM -0500, Mike Christie wrote:
> 
> On 9/6/22 2:48 AM, Dmitry Bogdanov wrote:
> >
> > diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
> > index c14441c89bed..32fb38ce98f4 100644
> > --- a/drivers/target/target_core_spc.c
> > +++ b/drivers/target/target_core_spc.c
> > @@ -75,6 +75,8 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
> >       struct se_portal_group *tpg = lun->lun_tpg;
> >       struct se_device *dev = cmd->se_dev;
> >       struct se_session *sess = cmd->se_sess;
> > +     struct se_lun *tmp_lun;
> > +     size_t dev_ports = 0;
> >
> >       /* Set RMB (removable media) for tape devices */
> >       if (dev->transport->get_device_type(dev) == TYPE_TAPE)
> > @@ -115,6 +117,20 @@ spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
> >                       buf[5] |= 0x1;
> >       }
> >
> > +     spin_lock(&dev->se_port_lock);
> > +     list_for_each_entry(tmp_lun, &dev->dev_sep_list, lun_dev_link) {
> > +             dev_ports++;
> > +             /* Exact number of ports does not matter for MULTIP bit */
> > +             if (dev_ports > 1)
> > +                     break;
> 
> Can you just check se_deice->export_count instead of looping?
Yes, of course, dev->export_count exactly fits here.
> 
> Also, setting the bit seems fine. I was just wondering what uses it?
There is no way to find it out. At least just to conform to the
standard. May be for some archaic users like AIX.
Btw, SCST reports MULTIP=1 always.

BR,
 Dmitry
diff mbox series

Patch

diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index c14441c89bed..32fb38ce98f4 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -75,6 +75,8 @@  spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
 	struct se_portal_group *tpg = lun->lun_tpg;
 	struct se_device *dev = cmd->se_dev;
 	struct se_session *sess = cmd->se_sess;
+	struct se_lun *tmp_lun;
+	size_t dev_ports = 0;
 
 	/* Set RMB (removable media) for tape devices */
 	if (dev->transport->get_device_type(dev) == TYPE_TAPE)
@@ -115,6 +117,20 @@  spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf)
 			buf[5] |= 0x1;
 	}
 
+	spin_lock(&dev->se_port_lock);
+	list_for_each_entry(tmp_lun, &dev->dev_sep_list, lun_dev_link) {
+		dev_ports++;
+		/* Exact number of ports does not matter for MULTIP bit */
+		if (dev_ports > 1)
+			break;
+	}
+	spin_unlock(&dev->se_port_lock);
+	/*
+	 * Set MULTIP bit to indicate presence of multiple SCSI target ports
+	 */
+	if (dev_ports > 1)
+		buf[6] |= 0x10;
+
 	buf[7] = 0x2; /* CmdQue=1 */
 
 	/*