linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Harald Hoyer <harald@redhat.com>
To: linux-hotplug@vger.kernel.org
Subject: Re: [PATCH] path_id: Handle SAS and SATA devices
Date: Mon, 12 Jul 2010 09:16:42 +0000	[thread overview]
Message-ID: <4C3ADD7A.2010009@redhat.com> (raw)
In-Reply-To: <20100707145508.A42312A2B9@ochil.suse.de>


Customers request connection (channel) and drive bay identifier to be part of 
the symlink name.

On 07/07/2010 04:55 PM, Hannes Reinecke wrote:
>
> SAS devices should be referenced by the SAS address of the target;
> on the initiator side we assume an identity mapping between SAS
> addresses and PCI devnumber.
> SATA devices have an identity mapping between SATA links and
> linux scsi_host structures, so we can map the host number onto
> the SATA link.
> For this to work the LUN numbering needs to be updated, too,
> as SATA devices do not have the concept of a LUN, whereas normal
> SCSI devices have.
>
> Signed-off-by: Hannes Reinecke<hare@suse.de>
>
> diff --git a/extras/path_id/path_id.c b/extras/path_id/path_id.c
> index dcee378..1b6c363 100644
> --- a/extras/path_id/path_id.c
> +++ b/extras/path_id/path_id.c
> @@ -97,7 +97,6 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
>   	struct udev_device *targetdev;
>   	struct udev_device *fcdev = NULL;
>   	const char *port;
> -	unsigned int lun;
>
>   	targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
>   	if (targetdev = NULL)
> @@ -112,8 +111,7 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
>   		goto out;
>   	}
>
> -	lun = strtoul(udev_device_get_sysnum(parent), NULL, 10);
> -	path_prepend(path, "fc-%s:0x%04x%04x00000000", port, lun&  0xffff, (lun>>  16)&  0xffff);
> +	path_prepend(path, "fc-%s", port);
>   out:
>   	udev_device_unref(fcdev);
>   	return parent;
> @@ -121,7 +119,34 @@ out:
>
>   static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
>   {
> -	return NULL;
> +	struct udev *udev  = udev_device_get_udev(parent);
> +	struct udev_device *end_dev = NULL;
> +	struct udev_device *sas_dev;
> +	const char *end_dev_wwn;
> +
> +	/* Find end device */
> +	end_dev = parent;
> +	while (1) {
> +		end_dev = udev_device_get_parent(end_dev);
> +		if (end_dev = NULL)
> +			return NULL;
> +		if (!strncmp(udev_device_get_sysname(end_dev), "end_device", 10))
> +			break;
> +	}
> +	if (end_dev = NULL)
> +		return NULL;
> +
> +	/* find sas end device */
> +	sas_dev = udev_device_new_from_subsystem_sysname(udev, "sas_device", udev_device_get_sysname(end_dev));
> +	if (sas_dev = NULL)
> +		return NULL;
> +
> +	end_dev_wwn = udev_device_get_sysattr_value(sas_dev, "sas_address");
> +
> +	path_prepend(path, "sas-%s", end_dev_wwn);
> +
> +	udev_device_unref(sas_dev);
> +	return end_dev;
>   }
>
>   static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path)
> @@ -174,7 +199,7 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **
>   		goto out;
>   	}
>
> -	path_prepend(path, "ip-%s:%s-iscsi-%s-lun-%s", addr, port, target, udev_device_get_sysnum(parent));
> +	path_prepend(path, "ip-%s:%s-iscsi-%s", addr, port, target);
>   out:
>   	udev_device_unref(sessiondev);
>   	udev_device_unref(conndev);
> @@ -183,23 +208,34 @@ out:
>
>   static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path)
>   {
> +	struct udev *udev  = udev_device_get_udev(parent);
>   	struct udev_device *hostdev;
> -	int host, bus, target, lun;
> -	const char *name;
> +	int host, bus, target;
> +	const char *name, *hba, *hostpath;
>   	char *base;
>   	char *pos;
> +	char *type = "scsi";
>   	DIR *dir;
>   	struct dirent *dent;
> -	int basenum;
> -
> -	hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
> -	if (hostdev = NULL)
> -		return NULL;
> +	int basenum, hostnum = 0;
>
>   	name = udev_device_get_sysname(parent);
> -	if (sscanf(name, "%d:%d:%d:%d",&host,&bus,&target,&lun) != 4)
> +	if (sscanf(name, "target%d:%d:%d",&host,&bus,&target) != 3)
>   		return NULL;
>
> +	parent = udev_device_get_parent(parent);
> +	/* Check for libata hosts */
> +	hostdev = udev_device_new_from_subsystem_sysname(udev, "scsi_host", udev_device_get_sysname(parent));
> +	if (hostdev = NULL)
> +		return NULL;
> +	hba = udev_device_get_sysattr_value(hostdev, "proc_name");
> +	if (hba&&  (!strncmp(hba, "sata", 4) || !strcmp(hba, "ahci")))
> +		type = "sata";
> +	if (hba&&  (!strncmp(hba, "pata", 4) || !strncmp(hba, "ata", 3)))
> +		type = "ata";
> +	udev_device_unref(hostdev);
> +	/* Reset to original host path */
> +	hostdev = parent;
>   	/* rebase host offset to get the local relative number */
>   	basenum = -1;
>   	base = strdup(udev_device_get_syspath(hostdev));
> @@ -227,6 +263,7 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
>   		if (strncmp(dent->d_name, "host", 4) != 0)
>   			continue;
>   		i = strtoul(&dent->d_name[4],&rest, 10);
> +		hostnum++;
>   		if (rest[0] != '\0')
>   			continue;
>   		if (basenum = -1 || i<  basenum)
> @@ -239,20 +276,54 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
>   	}
>   	host -= basenum;
>
> -	path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun);
> +	if (!strcmp(type, "scsi"))
> +		path_prepend(path, "scsi-%u:%u:%u", host, bus, target);
> +	else
> +		path_prepend(path, "%s-%u", type, host);
>   out:
>   	free(base);
>   	return hostdev;
>   }
>
> +static int scsi_is_sata(const char *name)
> +{
> +	char syspath[UTIL_PATH_SIZE];
> +	struct stat stbuf;
> +
> +	strcpy(syspath, name);
> +	strcat(syspath, "/unload_heads");
> +
> +	return (stat(syspath,&stbuf)<  0) ? 0 : 1;
> +}
> +
>   static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
>   {
> +	struct udev *udev  = udev_device_get_udev(parent);
>   	const char *devtype;
>   	const char *name;
>   	const char *id;
>
>   	devtype = udev_device_get_devtype(parent);
> -	if (devtype = NULL || strcmp(devtype, "scsi_device") != 0)
> +	if (devtype = NULL)
> +		return parent;
> +
> +	/* lousy scsi sysfs does not have a "subsystem" for the transport */
> +	name = udev_device_get_syspath(parent);
> +
> +	if (strcmp(devtype, "scsi_device") = 0) {
> +		if (!scsi_is_sata(name)) {
> +			unsigned int host, bus, target, lun;
> +
> +			if (sscanf(udev_device_get_sysname(parent),
> +				   "%d:%d:%d:%d",&host,&bus,&target,&lun) != 4)
> +				return NULL;
> +			path_prepend(path, "lun-0x%04x%04x00000000",
> +				     lun&  0xffff, (lun>>  16)&  0xffff);
> +		}
> +		return parent;
> +	}
> +
> +	if (strcmp(devtype, "scsi_host") = 0)
>   		return parent;
>
>   	/* firewire */
> @@ -263,9 +334,6 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
>   		goto out;
>   	}
>
> -	/* lousy scsi sysfs does not have a "subsystem" for the transport */
> -	name = udev_device_get_syspath(parent);
> -
>   	if (strstr(name, "/rport-") != NULL) {
>   		parent = handle_scsi_fibre_channel(parent, path);
>   		goto out;
> --
> To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


  parent reply	other threads:[~2010-07-12  9:16 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-07 14:55 [PATCH] path_id: Handle SAS and SATA devices Hannes Reinecke
2010-07-12  9:07 ` Kay Sievers
2010-07-12  9:16 ` Harald Hoyer [this message]
2010-07-12 14:47 ` David Zeuthen
2010-08-04 21:56 ` David Zeuthen
2010-08-05  7:37 ` Hannes Reinecke
2010-08-05 13:16 ` David Zeuthen
2010-08-05 13:35 ` Hannes Reinecke
2010-08-05 13:53 ` David Zeuthen

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=4C3ADD7A.2010009@redhat.com \
    --to=harald@redhat.com \
    --cc=linux-hotplug@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).