From: Hannes Reinecke <hare@suse.de>
To: "K. Y. Srinivasan" <kys@microsoft.com>,
gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
devel@linuxdriverproject.org, ohering@suse.com,
jbottomley@parallels.com, hch@infradead.org,
linux-scsi@vger.kernel.org, apw@canonical.com,
vkuznets@redhat.com, jasowang@redhat.com,
martin.petersen@oracle.com
Subject: Re: [PATCH V4 2/4] scsi: storvsc: Properly support Fibre Channel devices
Date: Mon, 28 Dec 2015 13:01:56 +0100 [thread overview]
Message-ID: <568124B4.7030609@suse.de> (raw)
In-Reply-To: <1450905351-9538-2-git-send-email-kys@microsoft.com>
On 12/23/2015 10:15 PM, K. Y. Srinivasan wrote:
> For FC devices managed by this driver, atttach the appropriate transport
> template. This will allow us to create the appropriate sysfs files for
> these devices. With this we can publish the wwn for both the port and the node.
>
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Reviewed-by: Long Li <longli@microsoft.com>
> Tested-by: Alex Ng <alexng@microsoft.com>
> ---
> V2: Fixed error paths - Dan Carpenter <dan.carpenter@oracle.com>
> V3: Fixed build issues reported by kbuild test robot <lkp@intel.com>
> V4: Handle configuration of SCSI_FC_ATTRS correctly (both module and built in)
>
> drivers/scsi/storvsc_drv.c | 181 ++++++++++++++++++++++++++++++++-----------
> 1 files changed, 134 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
> index 00bb4bd..cfbb289 100644
> --- a/drivers/scsi/storvsc_drv.c
> +++ b/drivers/scsi/storvsc_drv.c
> @@ -41,6 +41,7 @@
> #include <scsi/scsi_eh.h>
> #include <scsi/scsi_devinfo.h>
> #include <scsi/scsi_dbg.h>
> +#include <scsi/scsi_transport_fc.h>
>
> /*
> * All wire protocol details (storage protocol between the guest and the host)
> @@ -397,6 +398,9 @@ static int storvsc_timeout = 180;
>
> static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
>
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> +static struct scsi_transport_template *fc_transport_template;
> +#endif
>
> static void storvsc_on_channel_callback(void *context);
>
> @@ -456,6 +460,11 @@ struct storvsc_device {
> /* Used for vsc/vsp channel reset process */
> struct storvsc_cmd_request init_request;
> struct storvsc_cmd_request reset_request;
> + /*
> + * Currently active port and node names for FC devices.
> + */
> + u64 node_name;
> + u64 port_name;
> };
>
> struct hv_host_device {
> @@ -695,7 +704,26 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns)
> vmbus_are_subchannels_present(device->channel);
> }
>
> -static int storvsc_channel_init(struct hv_device *device)
> +static void cache_wwn(struct storvsc_device *stor_device,
> + struct vstor_packet *vstor_packet)
> +{
> + /*
> + * Cache the currently active port and node ww names.
> + */
> + if (vstor_packet->wwn_packet.primary_active) {
> + stor_device->node_name =
> + wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn);
> + stor_device->port_name =
> + wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn);
> + } else {
> + stor_device->node_name =
> + wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn);
> + stor_device->port_name =
> + wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn);
> + }
> +}
> +
> +static int storvsc_channel_init(struct hv_device *device, bool is_fc)
> {
> struct storvsc_device *stor_device;
> struct storvsc_cmd_request *request;
> @@ -727,19 +755,15 @@ static int storvsc_channel_init(struct hv_device *device)
> VM_PKT_DATA_INBAND,
> VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
> if (ret != 0)
> - goto cleanup;
> + return ret;
>
> t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
> - if (t == 0) {
> - ret = -ETIMEDOUT;
> - goto cleanup;
> - }
> + if (t == 0)
> + return -ETIMEDOUT;
>
> if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
> - vstor_packet->status != 0) {
> - ret = -EINVAL;
> - goto cleanup;
> - }
> + vstor_packet->status != 0)
> + return -EINVAL;
>
>
> for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) {
> @@ -764,18 +788,14 @@ static int storvsc_channel_init(struct hv_device *device)
> VM_PKT_DATA_INBAND,
> VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
> if (ret != 0)
> - goto cleanup;
> + return ret;
>
> t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
> - if (t == 0) {
> - ret = -ETIMEDOUT;
> - goto cleanup;
> - }
> + if (t == 0)
> + return -ETIMEDOUT;
>
> - if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) {
> - ret = -EINVAL;
> - goto cleanup;
> - }
> + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO)
> + return -EINVAL;
>
> if (vstor_packet->status == 0) {
> vmstor_proto_version =
> @@ -791,10 +811,8 @@ static int storvsc_channel_init(struct hv_device *device)
> }
> }
>
> - if (vstor_packet->status != 0) {
> - ret = -EINVAL;
> - goto cleanup;
> - }
> + if (vstor_packet->status != 0)
> + return -EINVAL;
>
>
> memset(vstor_packet, 0, sizeof(struct vstor_packet));
> @@ -809,19 +827,15 @@ static int storvsc_channel_init(struct hv_device *device)
> VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
>
> if (ret != 0)
> - goto cleanup;
> + return ret;
>
> t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
> - if (t == 0) {
> - ret = -ETIMEDOUT;
> - goto cleanup;
> - }
> + if (t == 0)
> + return -ETIMEDOUT;
>
> if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
> - vstor_packet->status != 0) {
> - ret = -EINVAL;
> - goto cleanup;
> - }
> + vstor_packet->status != 0)
> + return -EINVAL;
>
> /*
> * Check to see if multi-channel support is there.
> @@ -837,6 +851,38 @@ static int storvsc_channel_init(struct hv_device *device)
> stor_device->max_transfer_bytes =
> vstor_packet->storage_channel_properties.max_transfer_bytes;
>
> + if (!is_fc)
> + goto done;
> +
> + memset(vstor_packet, 0, sizeof(struct vstor_packet));
> + vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA;
> + vstor_packet->flags = REQUEST_COMPLETION_FLAG;
> +
> + ret = vmbus_sendpacket(device->channel, vstor_packet,
> + (sizeof(struct vstor_packet) -
> + vmscsi_size_delta),
> + (unsigned long)request,
> + VM_PKT_DATA_INBAND,
> + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
> +
> + if (ret != 0)
> + return ret;
> +
> + t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
> + if (t == 0)
> + return -ETIMEDOUT;
> +
> + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
> + vstor_packet->status != 0)
> + return -EINVAL;
> +
> + /*
> + * Cache the currently active port and node ww names.
> + */
> + cache_wwn(stor_device, vstor_packet);
> +
> +done:
> +
> memset(vstor_packet, 0, sizeof(struct vstor_packet));
> vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
> vstor_packet->flags = REQUEST_COMPLETION_FLAG;
> @@ -849,25 +895,19 @@ static int storvsc_channel_init(struct hv_device *device)
> VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
>
> if (ret != 0)
> - goto cleanup;
> + return ret;
>
> t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
> - if (t == 0) {
> - ret = -ETIMEDOUT;
> - goto cleanup;
> - }
> + if (t == 0)
> + return -ETIMEDOUT;
>
> if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
> - vstor_packet->status != 0) {
> - ret = -EINVAL;
> - goto cleanup;
> - }
> + vstor_packet->status != 0)
> + return -EINVAL;
>
> if (process_sub_channels)
> handle_multichannel_storage(device, max_chns);
>
> -
> -cleanup:
> return ret;
> }
>
> @@ -1076,6 +1116,14 @@ static void storvsc_on_receive(struct hv_device *device,
> schedule_work(&work->work);
> break;
>
> + case VSTOR_OPERATION_FCHBA_DATA:
> + stor_device = get_in_stor_device(device);
> + cache_wwn(stor_device, vstor_packet);
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> + fc_host_node_name(stor_device->host) = stor_device->node_name;
> + fc_host_port_name(stor_device->host) = stor_device->port_name;
> +#endif
> + break;
> default:
> break;
> }
> @@ -1131,7 +1179,8 @@ static void storvsc_on_channel_callback(void *context)
> return;
> }
>
> -static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
> +static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size,
> + bool is_fc)
> {
> struct vmstorage_channel_properties props;
> int ret;
> @@ -1148,7 +1197,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
> if (ret != 0)
> return ret;
>
> - ret = storvsc_channel_init(device);
> + ret = storvsc_channel_init(device, is_fc);
>
> return ret;
> }
> @@ -1573,6 +1622,7 @@ static int storvsc_probe(struct hv_device *device,
> struct Scsi_Host *host;
> struct hv_host_device *host_dev;
> bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false);
> + bool is_fc = ((dev_id->driver_data == SFC_GUID) ? true : false);
> int target = 0;
> struct storvsc_device *stor_device;
> int max_luns_per_target;
> @@ -1630,7 +1680,7 @@ static int storvsc_probe(struct hv_device *device,
> hv_set_drvdata(device, stor_device);
>
> stor_device->port_number = host->host_no;
> - ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
> + ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size, is_fc);
> if (ret)
> goto err_out1;
>
> @@ -1642,6 +1692,9 @@ static int storvsc_probe(struct hv_device *device,
> host->max_lun = STORVSC_FC_MAX_LUNS_PER_TARGET;
> host->max_id = STORVSC_FC_MAX_TARGETS;
> host->max_channel = STORVSC_FC_MAX_CHANNELS - 1;
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> + host->transportt = fc_transport_template;
> +#endif
> break;
>
> case SCSI_GUID:
> @@ -1681,6 +1734,12 @@ static int storvsc_probe(struct hv_device *device,
> goto err_out2;
> }
> }
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> + if (host->transportt == fc_transport_template) {
> + fc_host_node_name(host) = stor_device->node_name;
> + fc_host_port_name(host) = stor_device->port_name;
> + }
> +#endif
> return 0;
>
> err_out2:
> @@ -1706,6 +1765,10 @@ static int storvsc_remove(struct hv_device *dev)
> struct storvsc_device *stor_device = hv_get_drvdata(dev);
> struct Scsi_Host *host = stor_device->host;
>
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> + if (host->transportt == fc_transport_template)
> + fc_remove_host(host);
> +#endif
> scsi_remove_host(host);
> storvsc_dev_remove(dev);
> scsi_host_put(host);
> @@ -1720,8 +1783,16 @@ static struct hv_driver storvsc_drv = {
> .remove = storvsc_remove,
> };
>
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> +static struct fc_function_template fc_transport_functions = {
> + .show_host_node_name = 1,
> + .show_host_port_name = 1,
> +};
> +#endif
> +
> static int __init storvsc_drv_init(void)
> {
> + int ret;
>
> /*
> * Divide the ring buffer data size (which is 1 page less
> @@ -1736,12 +1807,28 @@ static int __init storvsc_drv_init(void)
> vmscsi_size_delta,
> sizeof(u64)));
>
> - return vmbus_driver_register(&storvsc_drv);
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> + fc_transport_template = fc_attach_transport(&fc_transport_functions);
> + if (!fc_transport_template)
> + return -ENODEV;
> +#endif
> +
> + ret = vmbus_driver_register(&storvsc_drv);
> +
> +#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
> + if (ret)
> + fc_release_transport(fc_transport_template);
> +#endif
> +
> + return ret;
> }
>
> 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);
> +#endif
> }
>
> MODULE_LICENSE("GPL");
>
My original question still stands: Where is the point if supporting FC
devices if CONFIG_SCSI_FC_ATTRS is disabled?
I would rather disable FC support completely if that option is
deselected; otherwise you'll end up with a strange cross-breed which
presents FC LUNs but no attributes.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
next prev parent reply other threads:[~2015-12-28 12:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-23 21:15 [PATCH V4 0/4] scsi: storvsc: Properly support FC hosts K. Y. Srinivasan
2015-12-23 21:15 ` [PATCH V4 1/4] scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet K. Y. Srinivasan
2015-12-23 21:15 ` [PATCH V4 2/4] scsi: storvsc: Properly support Fibre Channel devices K. Y. Srinivasan
2015-12-28 12:01 ` Hannes Reinecke [this message]
2015-12-28 17:59 ` KY Srinivasan
2015-12-23 21:15 ` [PATCH V4 3/4] scsi: storvsc: Refactor the code in storvsc_channel_init() K. Y. Srinivasan
2015-12-23 21:15 ` [PATCH V4 4/4] scsi: storvsc: Tighten up the interrupt path K. Y. Srinivasan
2016-01-06 21:10 ` [PATCH V4 0/4] scsi: storvsc: Properly support FC hosts Martin K. Petersen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=568124B4.7030609@suse.de \
--to=hare@suse.de \
--cc=apw@canonical.com \
--cc=devel@linuxdriverproject.org \
--cc=gregkh@linuxfoundation.org \
--cc=hch@infradead.org \
--cc=jasowang@redhat.com \
--cc=jbottomley@parallels.com \
--cc=kys@microsoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=ohering@suse.com \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox