Skip to contentSkip to conversation

scsi: storvsc: Support manual scan of FC hosts on Hyper-V

PATCH In review K. Y. Srinivasan 4 participants 15 messages Mar 12, 2016 – Mar 30, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 scsi: storvsc: Support manual scan of FC hosts on Hyper-V

The default user scan function associated with FC (fc_user_scan) is not suitable for FC hosts on Hyper-V since we don't have an rport associated with FC host on Hyper-V . Set it to NULL so we can support manual scan of FC targets on Hyper-V.

---
 drivers/scsi/storvsc_drv.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)
drivers/scsi/storvsc_drv.c +6 -0
index 132b168..8aec590 100644
@@ -1776,6 +1776,12 @@ static int __init storvsc_drv_init(void)
 	 * Install Hyper-V specific timeout handler.
 	 */
 	fc_transport_template->eh_timed_out = storvsc_eh_timed_out;
+	/*
+	 * The default user scan function associated with FC (fc_user_scan)
+	 * is not suitable for FC hosts on Hyper-V. Set it to NULL so we can
+	 * support manual scan of FC targets on Hyper-V.
+	 */
+	fc_transport_template->user_scan = NULL;
 #endif
 
 	ret = vmbus_driver_register(&storvsc_drv);
Signature · 1 line
1.7.4.1
#1 lore raw
Quoted 4 lines · K. Y. Srinivasan

The default user scan function associated with FC (fc_user_scan) is not suitable for FC hosts on Hyper-V since we don't have an rport associated with FC host on Hyper-V . Set it to NULL so we can support manual scan of FC targets on Hyper-V.

This isn't really how the FC transport class in intended to work, but neither is the eh_timed_out (which I haven't seen in my tree yet).

It sounds like storvsc simply shouldn't attach to the FC transport if it doesn't actually look like a FC HBA.

#2 lore raw
Quoted 20 lines

-----Original Message-----
From: Christoph Hellwig [mailto:[email protected]]
Sent: Tuesday, March 15, 2016 6:40 AM
To: KY Srinivasan <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 4 lines · K. Y. Srinivasan

The default user scan function associated with FC (fc_user_scan) is not suitable for FC hosts on Hyper-V since we don't have an rport associated with FC host on Hyper-V . Set it to NULL so we can support manual scan of FC targets on Hyper-V.

Quoted 5 lines

This isn't really how the FC transport class in intended to work, but neither is the eh_timed_out (which I haven't seen in my tree yet).

It sounds like storvsc simply shouldn't attach to the FC transport if it doesn't actually look like a FC HBA.

Till recently I had not. However, we do support publishing wwn in the guest and some customers wanted this. That is the reason I am attaching FC transport and working through the issues. With this change, I now have wwn names published in the guest and I can also issue manual scan.

Regards,

K. Y

#3 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

KY> Till recently I had not. However, we do support publishing wwn in KY> the guest and some customers wanted this. That is the reason I am KY> attaching FC transport and working through the issues. With this KY> change, I now have wwn names published in the guest and I can also KY> issue manual scan.

Why does it have to look like FC? Will a device identification VPD page not do the trick?

Signature · 1 line
Martin K. Petersen	Oracle Linux Engineering
#4 lore raw
Quoted 16 lines

-----Original Message-----
From: Martin K. Petersen [mailto:[email protected]]
Sent: Tuesday, March 15, 2016 2:25 PM
To: KY Srinivasan <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

Quoted 8 lines

KY> Till recently I had not. However, we do support publishing wwn in KY> the guest and some customers wanted this. That is the reason I am KY> attaching FC transport and working through the issues. With this KY> change, I now have wwn names published in the guest and I can also KY> issue manual scan.

Why does it have to look like FC? Will a device identification VPD page not do the trick?

How would I get the sysfs files under fc_host if I don't use the FC transport. The customer scripts expect these sysfs files.

Regards,

K. Y

Quoted 3 lines

--
Martin K. Petersen Oracle Linux Engineering

#5 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

KY> How would I get the sysfs files under fc_host if I don't use the FC KY> transport. The customer scripts expect these sysfs files.

Right, but I was interested in finding out why they need those files. And whether an alternative to the FC transport would be a better solution.

Signature · 1 line
Martin K. Petersen	Oracle Linux Engineering
maintainer
#6 lore raw
Quoted 9 lines · Martin K. Petersen
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

KY> How would I get the sysfs files under fc_host if I don't use the FC
KY> transport. The customer scripts expect these sysfs files.

Right, but I was interested in finding out why they need those files. And whether an alternative to the FC transport would be a better solution.

If it's just the wwn file (or a set of other values), we might be able to separate that bit out of the FC transport class so you can use it independently ... do you have a full list of the files being used?

Thanks,

James

#7 lore raw
Quoted 22 lines

-----Original Message-----
From: James Bottomley [mailto:[email protected]]
Sent: Wednesday, March 16, 2016 4:08 PM
To: Martin K. Petersen <[email protected]>; KY Srinivasan <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 6 lines · Martin K. Petersen
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

KY> How would I get the sysfs files under fc_host if I don't use the FC
KY> transport. The customer scripts expect these sysfs files.

Quoted 7 lines
Quoted 3 lines

Right, but I was interested in finding out why they need those files. And whether an alternative to the FC transport would be a better solution.

If it's just the wwn file (or a set of other values), we might be able to separate that bit out of the FC transport class so you can use it independently ... do you have a full list of the files being used?

Wwn files are what we can support on Hyper-V and that is what I want to support (to address customer requirements).

Regards,

K. Y

maintainer
#8 lore raw
Quoted 30 lines · KY Srinivasan
Quoted 30 lines

-----Original Message-----
From: James Bottomley [mailto:[email protected] ]
Sent: Wednesday, March 16, 2016 4:08 PM
To: Martin K. Petersen <[email protected]>; KY Srinivasan <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected];
[email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on
Hyper-V

Quoted 10 lines · Martin K. Petersen
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

KY> How would I get the sysfs files under fc_host if I don't use the
FC
KY> transport. The customer scripts expect these sysfs files.

Right, but I was interested in finding out why they need those files. And whether an alternative to the FC transport would be a better solution.

Quoted 8 lines
Quoted 5 lines

If it's just the wwn file (or a set of other values), we might be able
to separate that bit out of the FC transport class so you can use it
independently ... do you have a full list of the files being used?

Wwn files are what we can support on Hyper-V and that is what I want to support (to address customer requirements).

There is no wwn file. These are all the possible attributes they could use; which one(s) do you want:

	/*
	 * Setup SCSI Host Attributes.
	 */
	SETUP_HOST_ATTRIBUTE_RD(node_name);
	SETUP_HOST_ATTRIBUTE_RD(port_name);
	SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
	SETUP_HOST_ATTRIBUTE_RD(supported_classes);
	SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
	SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
	SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
	if (ft->vport_create) {
		SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports);
		SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
	}
	SETUP_HOST_ATTRIBUTE_RD(serial_number);
	SETUP_HOST_ATTRIBUTE_RD(manufacturer);
	SETUP_HOST_ATTRIBUTE_RD(model);
	SETUP_HOST_ATTRIBUTE_RD(model_description);
	SETUP_HOST_ATTRIBUTE_RD(hardware_version);
	SETUP_HOST_ATTRIBUTE_RD(driver_version);
	SETUP_HOST_ATTRIBUTE_RD(firmware_version);
	SETUP_HOST_ATTRIBUTE_RD(optionrom_version);

	SETUP_HOST_ATTRIBUTE_RD(port_id);
	SETUP_HOST_ATTRIBUTE_RD(port_type);
	SETUP_HOST_ATTRIBUTE_RD(port_state);
	SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
	SETUP_HOST_ATTRIBUTE_RD(speed);
	SETUP_HOST_ATTRIBUTE_RD(fabric_name);
	SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
	SETUP_HOST_ATTRIBUTE_RW(system_hostname);

	/* Transport-managed attributes */
	SETUP_PRIVATE_HOST_ATTRIBUTE_RW(dev_loss_tmo);
	SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
	if (ft->issue_fc_host_lip)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
	if (ft->vport_create)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create);
	if (ft->vport_delete)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete);
	/*
	 * Setup Remote Port Attributes.
	 */
	count=0;
	SETUP_RPORT_ATTRIBUTE_RD(maxframe_size);
	SETUP_RPORT_ATTRIBUTE_RD(supported_classes);
	SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);

	/*
	 * Setup Virtual Port Attributes.
	 */
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type);
	SETUP_VPORT_ATTRIBUTE_RW(symbolic_name);
	SETUP_VPORT_ATTRIBUTE_WR(vport_delete);
	SETUP_VPORT_ATTRIBUTE_WR(vport_disable);

I'm assuming it's host and rport port_id?

James

#9 lore raw
Quoted 128 lines

-----Original Message-----
From: James Bottomley [mailto:[email protected]]
Sent: Wednesday, March 16, 2016 4:41 PM
To: KY Srinivasan <[email protected]>; Martin K. Petersen <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 3 lines · KY Srinivasan
Quoted 3 lines

-----Original Message-----
From: James Bottomley

[mailto:[email protected]

Quoted 27 lines
Quoted 27 lines

]
Sent: Wednesday, March 16, 2016 4:08 PM
To: Martin K. Petersen <[email protected]>; KY Srinivasan <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected];
[email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on
Hyper-V

Quoted 10 lines · Martin K. Petersen
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"KY" == KY Srinivasan <[email protected]> writes:

KY> How would I get the sysfs files under fc_host if I don't use the
FC
KY> transport. The customer scripts expect these sysfs files.

Right, but I was interested in finding out why they need those files. And whether an alternative to the FC transport would be a better solution.

Quoted 8 lines
Quoted 5 lines

If it's just the wwn file (or a set of other values), we might be able
to separate that bit out of the FC transport class so you can use it
independently ... do you have a full list of the files being used?

Wwn files are what we can support on Hyper-V and that is what I want to support (to address customer requirements).

There is no wwn file. These are all the possible attributes they could use; which one(s) do you want:

	/*
	 * Setup SCSI Host Attributes.
	 */
	SETUP_HOST_ATTRIBUTE_RD(node_name);
	SETUP_HOST_ATTRIBUTE_RD(port_name);
	SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
	SETUP_HOST_ATTRIBUTE_RD(supported_classes);
	SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
	SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
	SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
	if (ft->vport_create) {
		SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports);
		SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
	}
	SETUP_HOST_ATTRIBUTE_RD(serial_number);
	SETUP_HOST_ATTRIBUTE_RD(manufacturer);
	SETUP_HOST_ATTRIBUTE_RD(model);
	SETUP_HOST_ATTRIBUTE_RD(model_description);
	SETUP_HOST_ATTRIBUTE_RD(hardware_version);
	SETUP_HOST_ATTRIBUTE_RD(driver_version);
	SETUP_HOST_ATTRIBUTE_RD(firmware_version);
	SETUP_HOST_ATTRIBUTE_RD(optionrom_version);

	SETUP_HOST_ATTRIBUTE_RD(port_id);
	SETUP_HOST_ATTRIBUTE_RD(port_type);
	SETUP_HOST_ATTRIBUTE_RD(port_state);
	SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
	SETUP_HOST_ATTRIBUTE_RD(speed);
	SETUP_HOST_ATTRIBUTE_RD(fabric_name);
	SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
	SETUP_HOST_ATTRIBUTE_RW(system_hostname);

	/* Transport-managed attributes */
	SETUP_PRIVATE_HOST_ATTRIBUTE_RW(dev_loss_tmo);
	SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
	if (ft->issue_fc_host_lip)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
	if (ft->vport_create)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create);
	if (ft->vport_delete)
		SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete);
	/*
	 * Setup Remote Port Attributes.
	 */
	count=0;
	SETUP_RPORT_ATTRIBUTE_RD(maxframe_size);
	SETUP_RPORT_ATTRIBUTE_RD(supported_classes);
	SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
	SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);

	/*
	 * Setup Virtual Port Attributes.
	 */
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles);
	SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type);
	SETUP_VPORT_ATTRIBUTE_RW(symbolic_name);
	SETUP_VPORT_ATTRIBUTE_WR(vport_delete);
	SETUP_VPORT_ATTRIBUTE_WR(vport_disable);
Quoted 1 line

I'm assuming it's host and rport port_id?

The only attributes I would be interested are:
1) node name
2) port name

Ideally, if this can show under /sys/class/fc_host/hostx/port_name and node_name, it will be ideal since all user scripts can work.

Regards,

K. Y

maintainer
#10 lore raw
Quoted 7 lines · KY Srinivasan

The only attributes I would be interested are:
1) node name
2) port name

Ideally, if this can show under /sys/class/fc_host/hostx/port_name and node_name,
it will be ideal since all user scripts can work.

OK, like this?

Quoted 1 line

From 7af7c428e7e04ddcc87fda12d6571e3dff8ae024 Mon Sep 17 00:00:00 2001

From: James Bottomley <[email protected]>
Date: Fri, 18 Mar 2016 15:35:45 -0700
Subject: scsi_transport_fc: introduce lightweight class for virtualization
systems

The FC transport class is very heavily tilted towards helping things which operate a fabric (as it should be). However, there seems to be a need for a lightweight version for use in virtual systems that simply want to show pass through FC information without making any use of the heavyweight functions. This is an attempt to give them what they want: the lightweight class has no vports or rports and only two host attributes. Essentially, it's designed for the HV storvsc driver, but if other virtualizataion systems have similar problems, we can add more attributes.

---
 drivers/scsi/scsi_transport_fc.c | 94 ++++++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_transport_fc.h |  3 ++
 2 files changed, 97 insertions(+)
drivers/scsi/scsi_transport_fc.c +94 -0
index 8a88226..a9fcb4d 100644
@@ -351,6 +351,27 @@ struct fc_internal {
 
 #define to_fc_internal(tmpl)	container_of(tmpl, struct fc_internal, t)
 
+#define FC_LW_HOST_NUM_ATTRS 	2
+struct fc_lw_internal {
+	struct scsi_transport_template t;
+	struct fc_function_template *f;
+
+	/*
+	 * For attributes : each object has :
+	 *   An array of the actual attributes structures
+	 *   An array of null-terminated pointers to the attribute
+	 *     structures - used for mid-layer interaction.
+	 *
+	 * The attribute containers for the starget and host are are
+	 * part of the midlayer. As the remote port is specific to the
+	 * fc transport, we must provide the attribute container.
+	 */
+	struct device_attribute private_host_attrs[FC_LW_HOST_NUM_ATTRS];
+	struct device_attribute *host_attrs[FC_LW_HOST_NUM_ATTRS + 1];
+};
+
+#define to_fc_lw_internal(tmpl)	container_of(tmpl, struct fc_lw_internal, t)
+
 static int fc_target_setup(struct transport_container *tc, struct device *dev,
 			   struct device *cdev)
 {
@@ -472,6 +493,12 @@ static int fc_host_remove(struct transport_container *tc, struct device *dev,
 	return 0;
 }
 
+static DECLARE_TRANSPORT_CLASS(fc_lw_host_class,
+			       "fc_host",
+			       NULL,
+			       NULL,
+			       NULL);
+
 static DECLARE_TRANSPORT_CLASS(fc_host_class,
 			       "fc_host",
 			       fc_host_setup,
@@ -1968,6 +1995,25 @@ static int fc_host_match(struct attribute_container *cont,
 	return &i->t.host_attrs.ac == cont;
 }
 
+static int fc_lw_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_lw_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.ac.class
+	    != &fc_lw_host_class.class)
+		return 0;
+
+	i = to_fc_lw_internal(shost->transportt);
+
+	return &i->t.host_attrs.ac == cont;
+}
+
 static int fc_target_match(struct attribute_container *cont,
 			    struct device *dev)
 {
@@ -2171,6 +2217,54 @@ static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
 	return i->f->it_nexus_response(shost, nexus, result);
 }
 
+/**
+ * fc_attach_lw_transport - light weight attach function
+ * @ft:		function template for optional attributes
+ *
+ * This attach function is to be used only for virtual FC emulators
+ * which do not have a physical fabric underneath them and thus only
+ * need a few attributes and no helper functions
+ */
+struct scsi_transport_template *
+fc_lw_attach_transport(struct fc_function_template *ft)
+{
+	int count;
+	struct fc_lw_internal *i = kzalloc(sizeof(struct fc_lw_internal),
+					   GFP_KERNEL);
+
+	if (unlikely(!i))
+		return NULL;
+
+	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+	i->t.host_attrs.ac.class = &fc_lw_host_class.class;
+	i->t.host_attrs.ac.match = fc_lw_host_match;
+	i->t.host_size = sizeof(struct fc_host_attrs);
+	transport_container_register(&i->t.host_attrs);
+
+	i->f = ft;
+
+	count = 0;
+	SETUP_HOST_ATTRIBUTE_RD(node_name);
+	SETUP_HOST_ATTRIBUTE_RD(port_name);
+
+	BUG_ON(count > FC_HOST_NUM_ATTRS);
+
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(fc_lw_attach_transport);
+
+void fc_lw_release_transport(struct scsi_transport_template *t)
+{
+	struct fc_lw_internal *i = to_fc_lw_internal(t);
+
+	transport_container_unregister(&i->t.host_attrs);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(fc_lw_release_transport);
+
 struct scsi_transport_template *
 fc_attach_transport(struct fc_function_template *ft)
 {
include/scsi/scsi_transport_fc.h +3 -0
index 784bc2c..b0a9a64 100644
@@ -835,6 +835,9 @@ fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
 	vport->vport_state = new_state;
 }
 
+struct scsi_transport_template *fc_lw_attach_transport(
+			struct fc_function_template *);
+void fc_lw_release_transport(struct scsi_transport_template *);
 struct scsi_transport_template *fc_attach_transport(
 			struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
Signature · 1 line
2.6.2
maintainer
#11 lore raw

PATCH 2/2 storvsc_drv: make use of the lightweight FC transport class

---
 drivers/scsi/storvsc_drv.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/scsi/storvsc_drv.c +3 -8
index 3ddcabb..dcb7393 100644
@@ -1769,21 +1769,16 @@ static int __init storvsc_drv_init(void)
 		sizeof(u64)));
 
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
-	fc_transport_template = fc_attach_transport(&fc_transport_functions);
+	fc_transport_template = fc_lw_attach_transport(&fc_transport_functions);
 	if (!fc_transport_template)
 		return -ENODEV;
-
-	/*
-	 * Install Hyper-V specific timeout handler.
-	 */
-	fc_transport_template->eh_timed_out = storvsc_eh_timed_out;
 #endif
 
 	ret = vmbus_driver_register(&storvsc_drv);
 
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
 	if (ret)
-		fc_release_transport(fc_transport_template);
+		fc_lw_release_transport(fc_transport_template);
 #endif
 
 	return ret;
@@ -1793,7 +1788,7 @@ static void __exit storvsc_drv_exit(void)
 {
 	vmbus_driver_unregister(&storvsc_drv);
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
-	fc_release_transport(fc_transport_template);
+	fc_lw_release_transport(fc_transport_template);
 #endif
 }
 
Signature · 1 line
2.6.2
#12 lore raw
In reply to James Bottomley
Quoted 20 lines

-----Original Message-----
From: James Bottomley [mailto:[email protected]]
Sent: Friday, March 18, 2016 3:41 PM
To: KY Srinivasan <[email protected]>; Martin K. Petersen <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 4 lines · KY Srinivasan

The only attributes I would be interested are:
1) node name
2) port name

Quoted 5 lines
Quoted 3 lines

Ideally, if this can show under /sys/class/fc_host/hostx/port_name and node_name,
it will be ideal since all user scripts can work.

OK, like this?

Yes; thank you very much James. Looking at the patch though, it may be an overkill considering how much of the code is duplicated. The current fc transport class does give us the flexibility to control the attributes we want to surface (fc_function_template). In any case I will test this code and get back to you soon.

Regards,

K. Y

Quoted 173 lines

From 7af7c428e7e04ddcc87fda12d6571e3dff8ae024 Mon Sep 17 00:00:00 2001
From: James Bottomley <[email protected]>
Date: Fri, 18 Mar 2016 15:35:45 -0700
Subject: scsi_transport_fc: introduce lightweight class for virtualization
systems

The FC transport class is very heavily tilted towards helping things which operate a fabric (as it should be). However, there seems to be a need for a lightweight version for use in virtual systems that simply want to show pass through FC information without making any use of the heavyweight functions. This is an attempt to give them what they want: the lightweight class has no vports or rports and only two host attributes. Essentially, it's designed for the HV storvsc driver, but if other virtualizataion systems have similar problems, we can add more attributes.

---
 drivers/scsi/scsi_transport_fc.c | 94
++++++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_transport_fc.h |  3 ++
 2 files changed, 97 insertions(+)
drivers/scsi/scsi_transport_fc.c +21 -0
index 8a88226..a9fcb4d 100644
@@ -351,6 +351,27 @@ struct fc_internal {
 
 #define to_fc_internal(tmpl)	container_of(tmpl, struct fc_internal, t)
 
+#define FC_LW_HOST_NUM_ATTRS 	2
+struct fc_lw_internal {
+	struct scsi_transport_template t;
+	struct fc_function_template *f;
+
+	/*
+	 * For attributes : each object has :
+	 *   An array of the actual attributes structures
+	 *   An array of null-terminated pointers to the attribute
+	 *     structures - used for mid-layer interaction.
+	 *
+	 * The attribute containers for the starget and host are are
+	 * part of the midlayer. As the remote port is specific to the
+	 * fc transport, we must provide the attribute container.
+	 */
+	struct device_attribute
 private_host_attrs[FC_LW_HOST_NUM_ATTRS];
+	struct device_attribute *host_attrs[FC_LW_HOST_NUM_ATTRS + 1];
+};
+
+#define to_fc_lw_internal(tmpl)	container_of(tmpl, struct
 fc_lw_internal, t)
+
 static int fc_target_setup(struct transport_container *tc, struct device *dev,
drivers/scsi/scsi_transport_fc.c +6 -0
 			   struct device *cdev)
 {
@@ -472,6 +493,12 @@ static int fc_host_remove(struct transport_container
 *tc, struct device *dev,
 	return 0;
 }
 
+static DECLARE_TRANSPORT_CLASS(fc_lw_host_class,
+			       "fc_host",
+			       NULL,
+			       NULL,
+			       NULL);
+
 static DECLARE_TRANSPORT_CLASS(fc_host_class,
 			       "fc_host",
drivers/scsi/scsi_transport_fc.c +19 -0
 			       fc_host_setup,
@@ -1968,6 +1995,25 @@ static int fc_host_match(struct
 attribute_container *cont,
 	return &i->t.host_attrs.ac == cont;
 }
 
+static int fc_lw_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_lw_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.ac.class
+	    != &fc_lw_host_class.class)
+		return 0;
+
+	i = to_fc_lw_internal(shost->transportt);
+
+	return &i->t.host_attrs.ac == cont;
+}
+
 static int fc_target_match(struct attribute_container *cont,
 			    struct device *dev)

{

drivers/scsi/scsi_transport_fc.c +48 -0
@@ -2171,6 +2217,54 @@ static int fc_it_nexus_response(struct Scsi_Host
 *shost, u64 nexus, int result)
 	return i->f->it_nexus_response(shost, nexus, result);
 }
 
+/**
+ * fc_attach_lw_transport - light weight attach function
+ * @ft:		function template for optional attributes
+ *
+ * This attach function is to be used only for virtual FC emulators
+ * which do not have a physical fabric underneath them and thus only
+ * need a few attributes and no helper functions
+ */
+struct scsi_transport_template *
+fc_lw_attach_transport(struct fc_function_template *ft)
+{
+	int count;
+	struct fc_lw_internal *i = kzalloc(sizeof(struct fc_lw_internal),
+					   GFP_KERNEL);
+
+	if (unlikely(!i))
+		return NULL;
+
+	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+	i->t.host_attrs.ac.class = &fc_lw_host_class.class;
+	i->t.host_attrs.ac.match = fc_lw_host_match;
+	i->t.host_size = sizeof(struct fc_host_attrs);
+	transport_container_register(&i->t.host_attrs);
+
+	i->f = ft;
+
+	count = 0;
+	SETUP_HOST_ATTRIBUTE_RD(node_name);
+	SETUP_HOST_ATTRIBUTE_RD(port_name);
+
+	BUG_ON(count > FC_HOST_NUM_ATTRS);
+
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(fc_lw_attach_transport);
+
+void fc_lw_release_transport(struct scsi_transport_template *t)
+{
+	struct fc_lw_internal *i = to_fc_lw_internal(t);
+
+	transport_container_unregister(&i->t.host_attrs);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(fc_lw_release_transport);
+
 struct scsi_transport_template *
 fc_attach_transport(struct fc_function_template *ft)

{

include/scsi/scsi_transport_fc.h +3 -0
index 784bc2c..b0a9a64 100644
@@ -835,6 +835,9 @@ fc_vport_set_state(struct fc_vport *vport, enum
 fc_vport_state new_state)
 	vport->vport_state = new_state;
 }
 
+struct scsi_transport_template *fc_lw_attach_transport(
+			struct fc_function_template *);
+void fc_lw_release_transport(struct scsi_transport_template *);
 struct scsi_transport_template *fc_attach_transport(
 			struct fc_function_template *);

void fc_release_transport(struct scsi_transport_template *);
--
2.6.2

#13 lore raw
Quoted 40 lines

-----Original Message-----
From: KY Srinivasan
Sent: Sunday, March 20, 2016 11:59 AM
To: 'James Bottomley' <[email protected]>; Martin K. Petersen <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: RE: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 2 lines

-----Original Message-----
From: James Bottomley

[mailto:[email protected]]

Quoted 20 lines

Sent: Friday, March 18, 2016 3:41 PM
To: KY Srinivasan <[email protected]>; Martin K. Petersen <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 7 lines · KY Srinivasan

The only attributes I would be interested are:
1) node name
2) port name

Ideally, if this can show under /sys/class/fc_host/hostx/port_name and node_name,
it will be ideal since all user scripts can work.

Quoted 8 lines
Quoted 1 line

OK, like this?

Yes; thank you very much James. Looking at the patch though, it may be an overkill considering how much of the code is duplicated. The current fc transport
class does give us the flexibility to control the attributes we want to surface (fc_function_template). In any case I will test this code and get back to you soon.

Today I got a chance to test this patch. Looks like all the state is not getting properly set in this new transport class. I am hitting this NULL pointer reference fault in get_device_parent(). Looks like the device class is not properly setup for this transport class. class_dir_create_and_add() is not called for this class
and so the glue_dirs is NULL. I fixed the issue:

1) You will need to call the transport_class_register() for this new transport class in fc_transport_init()
2) We cannot use fc_host as the name in this new class since the standard fc transport already Uses that name. I changed the name to get this to work. This will create a new directory under /sys/class. So my original goal of being compatible with existing scripts that expect to find the information under /sys/class/fc_host will not be met.

Regards,

K. Y

Quoted 183 lines

Regards,

K. Y

Quoted 18 lines

From 7af7c428e7e04ddcc87fda12d6571e3dff8ae024 Mon Sep 17 00:00:00 2001
From: James Bottomley <[email protected]>
Date: Fri, 18 Mar 2016 15:35:45 -0700
Subject: scsi_transport_fc: introduce lightweight class for virtualization
systems

The FC transport class is very heavily tilted towards helping things which operate a fabric (as it should be). However, there seems to be a need for a lightweight version for use in virtual systems that simply want to show pass through FC information without making any use of the heavyweight functions. This is an attempt to give them what they want: the lightweight class has no vports or rports and only two host attributes. Essentially, it's designed for the HV storvsc driver, but if other virtualizataion systems have similar problems, we can add more attributes.

Review

Quoted 8 lines
---
 drivers/scsi/scsi_transport_fc.c | 94
++++++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_transport_fc.h |  3 ++
 2 files changed, 97 insertions(+)
(quoted diff) +0 -0

b/drivers/scsi/scsi_transport_fc.c

Quoted 21 lines

index 8a88226..a9fcb4d 100644

drivers/scsi/scsi_transport_fc.c +14 -0
@@ -351,6 +351,27 @@ struct fc_internal {
 
 #define to_fc_internal(tmpl)	container_of(tmpl, struct fc_internal, t)
 
+#define FC_LW_HOST_NUM_ATTRS 	2
+struct fc_lw_internal {
+	struct scsi_transport_template t;
+	struct fc_function_template *f;
+
+	/*
+	 * For attributes : each object has :
+	 *   An array of the actual attributes structures
+	 *   An array of null-terminated pointers to the attribute
+	 *     structures - used for mid-layer interaction.
+	 *
+	 * The attribute containers for the starget and host are are
+	 * part of the midlayer. As the remote port is specific to the
+	 * fc transport, we must provide the attribute container.

drivers/scsi/scsi_transport_fc.c struct fc_internal { · line 377

Quoted 10 lines
drivers/scsi/scsi_transport_fc.c +7 -0
+	 */
+	struct device_attribute
 private_host_attrs[FC_LW_HOST_NUM_ATTRS];
+	struct device_attribute *host_attrs[FC_LW_HOST_NUM_ATTRS + 1];
+};
+
+#define to_fc_lw_internal(tmpl)	container_of(tmpl, struct
 fc_lw_internal, t)
+
 static int fc_target_setup(struct transport_container *tc, struct device

*dev,

drivers/scsi/scsi_transport_fc.c static int fc_host_remove(struct

Quoted 3 lines
drivers/scsi/scsi_transport_fc.c +0 -0
 			   struct device *cdev)
 {
@@ -472,6 +493,12 @@ static int fc_host_remove(struct

transport_container

Quoted 96 lines
drivers/scsi/scsi_transport_fc.c +6 -0
 *tc, struct device *dev,
 	return 0;
 }
 
+static DECLARE_TRANSPORT_CLASS(fc_lw_host_class,
+			       "fc_host",
+			       NULL,
+			       NULL,
+			       NULL);
+
 static DECLARE_TRANSPORT_CLASS(fc_host_class,
 			       "fc_host",
drivers/scsi/scsi_transport_fc.c +19 -0
 			       fc_host_setup,
@@ -1968,6 +1995,25 @@ static int fc_host_match(struct
 attribute_container *cont,
 	return &i->t.host_attrs.ac == cont;
 }
 
+static int fc_lw_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_lw_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.ac.class
+	    != &fc_lw_host_class.class)
+		return 0;
+
+	i = to_fc_lw_internal(shost->transportt);
+
+	return &i->t.host_attrs.ac == cont;
+}
+
 static int fc_target_match(struct attribute_container *cont,
 			    struct device *dev)

{

drivers/scsi/scsi_transport_fc.c +48 -0
@@ -2171,6 +2217,54 @@ static int fc_it_nexus_response(struct Scsi_Host
 *shost, u64 nexus, int result)
 	return i->f->it_nexus_response(shost, nexus, result);
 }
 
+/**
+ * fc_attach_lw_transport - light weight attach function
+ * @ft:		function template for optional attributes
+ *
+ * This attach function is to be used only for virtual FC emulators
+ * which do not have a physical fabric underneath them and thus only
+ * need a few attributes and no helper functions
+ */
+struct scsi_transport_template *
+fc_lw_attach_transport(struct fc_function_template *ft)
+{
+	int count;
+	struct fc_lw_internal *i = kzalloc(sizeof(struct fc_lw_internal),
+					   GFP_KERNEL);
+
+	if (unlikely(!i))
+		return NULL;
+
+	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+	i->t.host_attrs.ac.class = &fc_lw_host_class.class;
+	i->t.host_attrs.ac.match = fc_lw_host_match;
+	i->t.host_size = sizeof(struct fc_host_attrs);
+	transport_container_register(&i->t.host_attrs);
+
+	i->f = ft;
+
+	count = 0;
+	SETUP_HOST_ATTRIBUTE_RD(node_name);
+	SETUP_HOST_ATTRIBUTE_RD(port_name);
+
+	BUG_ON(count > FC_HOST_NUM_ATTRS);
+
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(fc_lw_attach_transport);
+
+void fc_lw_release_transport(struct scsi_transport_template *t)
+{
+	struct fc_lw_internal *i = to_fc_lw_internal(t);
+
+	transport_container_unregister(&i->t.host_attrs);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(fc_lw_release_transport);
+
 struct scsi_transport_template *
 fc_attach_transport(struct fc_function_template *ft)

{

Review

Quoted 1 line
(quoted diff) +0 -0

b/include/scsi/scsi_transport_fc.h

Quoted 16 lines

index 784bc2c..b0a9a64 100644

include/scsi/scsi_transport_fc.h +3 -0
@@ -835,6 +835,9 @@ fc_vport_set_state(struct fc_vport *vport, enum
 fc_vport_state new_state)
 	vport->vport_state = new_state;
 }
 
+struct scsi_transport_template *fc_lw_attach_transport(
+			struct fc_function_template *);
+void fc_lw_release_transport(struct scsi_transport_template *);
 struct scsi_transport_template *fc_attach_transport(
 			struct fc_function_template *);

void fc_release_transport(struct scsi_transport_template *);
--
2.6.2

#14 lore raw
In reply to James Bottomley
Quoted 195 lines

-----Original Message-----
From: James Bottomley [mailto:[email protected]]
Sent: Friday, March 18, 2016 3:41 PM
To: KY Srinivasan <[email protected]>; Martin K. Petersen <[email protected]>
Cc: Christoph Hellwig <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH 1/1] scsi: storvsc: Support manual scan of FC hosts on Hyper-V

Quoted 7 lines · KY Srinivasan

The only attributes I would be interested are:
1) node name
2) port name

Ideally, if this can show under /sys/class/fc_host/hostx/port_name and node_name,
it will be ideal since all user scripts can work.

OK, like this?

From 7af7c428e7e04ddcc87fda12d6571e3dff8ae024 Mon Sep 17 00:00:00 2001
From: James Bottomley <[email protected]>
Date: Fri, 18 Mar 2016 15:35:45 -0700
Subject: scsi_transport_fc: introduce lightweight class for virtualization
systems

The FC transport class is very heavily tilted towards helping things which operate a fabric (as it should be). However, there seems to be a need for a lightweight version for use in virtual systems that simply want to show pass through FC information without making any use of the heavyweight functions. This is an attempt to give them what they want: the lightweight class has no vports or rports and only two host attributes. Essentially, it's designed for the HV storvsc driver, but if other virtualizataion systems have similar problems, we can add more attributes.

---
 drivers/scsi/scsi_transport_fc.c | 94
++++++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_transport_fc.h |  3 ++
 2 files changed, 97 insertions(+)
drivers/scsi/scsi_transport_fc.c +21 -0
index 8a88226..a9fcb4d 100644
@@ -351,6 +351,27 @@ struct fc_internal {
 
 #define to_fc_internal(tmpl)	container_of(tmpl, struct fc_internal, t)
 
+#define FC_LW_HOST_NUM_ATTRS 	2
+struct fc_lw_internal {
+	struct scsi_transport_template t;
+	struct fc_function_template *f;
+
+	/*
+	 * For attributes : each object has :
+	 *   An array of the actual attributes structures
+	 *   An array of null-terminated pointers to the attribute
+	 *     structures - used for mid-layer interaction.
+	 *
+	 * The attribute containers for the starget and host are are
+	 * part of the midlayer. As the remote port is specific to the
+	 * fc transport, we must provide the attribute container.
+	 */
+	struct device_attribute
 private_host_attrs[FC_LW_HOST_NUM_ATTRS];
+	struct device_attribute *host_attrs[FC_LW_HOST_NUM_ATTRS + 1];
+};
+
+#define to_fc_lw_internal(tmpl)	container_of(tmpl, struct
 fc_lw_internal, t)
+
 static int fc_target_setup(struct transport_container *tc, struct device *dev,
drivers/scsi/scsi_transport_fc.c +6 -0
 			   struct device *cdev)
 {
@@ -472,6 +493,12 @@ static int fc_host_remove(struct transport_container
 *tc, struct device *dev,
 	return 0;
 }
 
+static DECLARE_TRANSPORT_CLASS(fc_lw_host_class,
+			       "fc_host",
+			       NULL,
+			       NULL,
+			       NULL);
+
 static DECLARE_TRANSPORT_CLASS(fc_host_class,
 			       "fc_host",
drivers/scsi/scsi_transport_fc.c +19 -0
 			       fc_host_setup,
@@ -1968,6 +1995,25 @@ static int fc_host_match(struct
 attribute_container *cont,
 	return &i->t.host_attrs.ac == cont;
 }
 
+static int fc_lw_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_lw_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.ac.class
+	    != &fc_lw_host_class.class)
+		return 0;
+
+	i = to_fc_lw_internal(shost->transportt);
+
+	return &i->t.host_attrs.ac == cont;
+}
+
 static int fc_target_match(struct attribute_container *cont,
 			    struct device *dev)

{

drivers/scsi/scsi_transport_fc.c +48 -0
@@ -2171,6 +2217,54 @@ static int fc_it_nexus_response(struct Scsi_Host
 *shost, u64 nexus, int result)
 	return i->f->it_nexus_response(shost, nexus, result);
 }
 
+/**
+ * fc_attach_lw_transport - light weight attach function
+ * @ft:		function template for optional attributes
+ *
+ * This attach function is to be used only for virtual FC emulators
+ * which do not have a physical fabric underneath them and thus only
+ * need a few attributes and no helper functions
+ */
+struct scsi_transport_template *
+fc_lw_attach_transport(struct fc_function_template *ft)
+{
+	int count;
+	struct fc_lw_internal *i = kzalloc(sizeof(struct fc_lw_internal),
+					   GFP_KERNEL);
+
+	if (unlikely(!i))
+		return NULL;
+
+	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+	i->t.host_attrs.ac.class = &fc_lw_host_class.class;
+	i->t.host_attrs.ac.match = fc_lw_host_match;
+	i->t.host_size = sizeof(struct fc_host_attrs);
+	transport_container_register(&i->t.host_attrs);
+
+	i->f = ft;
+
+	count = 0;
+	SETUP_HOST_ATTRIBUTE_RD(node_name);
+	SETUP_HOST_ATTRIBUTE_RD(port_name);
+
+	BUG_ON(count > FC_HOST_NUM_ATTRS);
+
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(fc_lw_attach_transport);
+
+void fc_lw_release_transport(struct scsi_transport_template *t)
+{
+	struct fc_lw_internal *i = to_fc_lw_internal(t);
+
+	transport_container_unregister(&i->t.host_attrs);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(fc_lw_release_transport);
+
 struct scsi_transport_template *
 fc_attach_transport(struct fc_function_template *ft)

{

include/scsi/scsi_transport_fc.h +3 -0
index 784bc2c..b0a9a64 100644
@@ -835,6 +835,9 @@ fc_vport_set_state(struct fc_vport *vport, enum
 fc_vport_state new_state)
 	vport->vport_state = new_state;
 }
 
+struct scsi_transport_template *fc_lw_attach_transport(
+			struct fc_function_template *);
+void fc_lw_release_transport(struct scsi_transport_template *);
 struct scsi_transport_template *fc_attach_transport(
 			struct fc_function_template *);
Quoted 3 lines

void fc_release_transport(struct scsi_transport_template *);
--
2.6.2

James,

It was great talking to you this afternoon. Is this what you had in mind:

drivers/scsi/scsi_transport_fc.c | 133 ++++++++++++++++++++++++++++++++++++--

 include/scsi/scsi_transport_fc.h |    3 +
 2 files changed, 130 insertions(+), 6 deletions(-)
drivers/scsi/scsi_transport_fc.c +127 -6
index 24eaaf6..b8cadd2 100644
@@ -351,6 +351,27 @@ struct fc_internal {
 
 #define to_fc_internal(tmpl)	container_of(tmpl, struct fc_internal, t)
 
+#define FC_LW_HOST_NUM_ATTRS 	2
+struct fc_lw_internal {
+	struct scsi_transport_template t;
+	struct fc_function_template *f;
+
+	/*
+	 * For attributes : each object has :
+	 *   An array of the actual attributes structures
+	 *   An array of null-terminated pointers to the attribute
+	 *     structures - used for mid-layer interaction.
+	 *
+	 * The attribute containers for the starget and host are are
+	 * part of the midlayer. As the remote port is specific to the
+	 * fc transport, we must provide the attribute container.
+	 */
+	struct device_attribute private_host_attrs[FC_LW_HOST_NUM_ATTRS];
+	struct device_attribute *host_attrs[FC_LW_HOST_NUM_ATTRS + 1];
+};
+
+#define to_fc_lw_internal(tmpl)	container_of(tmpl, struct fc_lw_internal, t)
+
 static int fc_target_setup(struct transport_container *tc, struct device *dev,
 			   struct device *cdev)
 {
@@ -472,6 +493,12 @@ static int fc_host_remove(struct transport_container *tc, struct device *dev,
 	return 0;
 }
 
+static DECLARE_TRANSPORT_CLASS(fc_lw_host_class,
+			       "fc_host",
+			       NULL,
+			       NULL,
+			       NULL);
+
 static DECLARE_TRANSPORT_CLASS(fc_host_class,
 			       "fc_host",
 			       fc_host_setup,
@@ -654,11 +681,20 @@ send_vendor_fail:
 EXPORT_SYMBOL(fc_host_post_vendor_event);
 
 
+static bool transport_inited;
+static bool lw_transport_inited;
 
-static __init int fc_transport_init(void)
+static int fc_transport_init(bool lw_transport)
 {
 	int error;
+	bool inited = cmpxchg(&transport_inited, transport_inited, true);
 
+	/*
+	 * If transport has already been inited, just return.
+	 */
+	if (inited)
+		return 0;
+	
 	atomic_set(&fc_event_seq, 0);
 
 	error = transport_class_register(&fc_host_class);
@@ -670,9 +706,15 @@ static __init int fc_transport_init(void)
 	error = transport_class_register(&fc_rport_class);
 	if (error)
 		goto unreg_vport_class;
-	error = transport_class_register(&fc_transport_class);
+	if (lw_transport)
+		error = transport_class_register(&fc_lw_host_class);
+	else 
+		error = transport_class_register(&fc_transport_class);
 	if (error)
 		goto unreg_rport_class;
+
+	if (lw_transport)
+		 lw_transport_inited = true;
 	return 0;
 
 unreg_rport_class:
@@ -686,8 +728,12 @@ unreg_host_class:
 
 static void __exit fc_transport_exit(void)
 {
-	transport_class_unregister(&fc_transport_class);
+	if (lw_transport_inited)
+		transport_class_unregister(&fc_lw_host_class);
+	else
+		transport_class_unregister(&fc_transport_class);
 	transport_class_unregister(&fc_rport_class);
+	if (lw_transport_inited)
 	transport_class_unregister(&fc_host_class);
 	transport_class_unregister(&fc_vport_class);
 }
@@ -1968,6 +2014,25 @@ static int fc_host_match(struct attribute_container *cont,
 	return &i->t.host_attrs.ac == cont;
 }
 
+static int fc_lw_host_match(struct attribute_container *cont,
+			  struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct fc_lw_internal *i;
+
+	if (!scsi_is_host_device(dev))
+		return 0;
+
+	shost = dev_to_shost(dev);
+	if (!shost->transportt  || shost->transportt->host_attrs.ac.class
+	    != &fc_lw_host_class.class)
+		return 0;
+
+	i = to_fc_lw_internal(shost->transportt);
+
+	return &i->t.host_attrs.ac == cont;
+}
+
 static int fc_target_match(struct attribute_container *cont,
 			    struct device *dev)
 {
@@ -2171,13 +2236,70 @@ static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
 	return i->f->it_nexus_response(shost, nexus, result);
 }
 
+/**
+ * fc_attach_lw_transport - light weight attach function
+ * @ft:		function template for optional attributes
+ *
+ * This attach function is to be used only for virtual FC emulators
+ * which do not have a physical fabric underneath them and thus only
+ * need a few attributes and no helper functions
+ */
+struct scsi_transport_template *
+fc_lw_attach_transport(struct fc_function_template *ft)
+{
+	int count;
+	struct fc_lw_internal *i;
+
+	if (fc_transport_init(true))
+		return NULL;
+
+	i = kzalloc(sizeof(struct fc_lw_internal),
+		    GFP_KERNEL);
+
+	if (unlikely(!i))
+		return NULL;
+
+	i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+	i->t.host_attrs.ac.class = &fc_lw_host_class.class;
+	i->t.host_attrs.ac.match = fc_lw_host_match;
+	i->t.host_size = sizeof(struct fc_host_attrs);
+	transport_container_register(&i->t.host_attrs);
+
+	i->f = ft;
+
+	count = 0;
+	SETUP_HOST_ATTRIBUTE_RD(node_name);
+	SETUP_HOST_ATTRIBUTE_RD(port_name);
+
+	BUG_ON(count > FC_HOST_NUM_ATTRS);
+
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(fc_lw_attach_transport);
+
+void fc_lw_release_transport(struct scsi_transport_template *t)
+{
+	struct fc_lw_internal *i = to_fc_lw_internal(t);
+
+	transport_container_unregister(&i->t.host_attrs);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(fc_lw_release_transport);
+
 struct scsi_transport_template *
 fc_attach_transport(struct fc_function_template *ft)
 {
 	int count;
-	struct fc_internal *i = kzalloc(sizeof(struct fc_internal),
-					GFP_KERNEL);
+	struct fc_internal *i;
+
+	if (fc_transport_init(false))
+		return NULL;
 
+	i = kzalloc(sizeof(struct fc_internal),
+			   GFP_KERNEL);
 	if (unlikely(!i))
 		return NULL;
 
@@ -4148,5 +4270,4 @@ MODULE_AUTHOR("James Smart");
 MODULE_DESCRIPTION("FC Transport Attributes");
 MODULE_LICENSE("GPL");
 
-module_init(fc_transport_init);
 module_exit(fc_transport_exit);
include/scsi/scsi_transport_fc.h +3 -0
index 784bc2c..b0a9a64 100644
@@ -835,6 +835,9 @@ fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
 	vport->vport_state = new_state;
 }
 
+struct scsi_transport_template *fc_lw_attach_transport(
+			struct fc_function_template *);
+void fc_lw_release_transport(struct scsi_transport_template *);
 struct scsi_transport_template *fc_attach_transport(
 			struct fc_function_template *);
 void fc_release_transport(struct scsi_transport_template *);
Signature · 1 line
1.7.4.1