linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* RE: [PATCH] minimal SAS transport class
@ 2005-08-23 16:16 James.Smart
  2005-08-23 17:28 ` Stefan Richter
  2005-08-23 17:57 ` Patrick Mansfield
  0 siblings, 2 replies; 83+ messages in thread
From: James.Smart @ 2005-08-23 16:16 UTC (permalink / raw)
  To: patmans
  Cc: luben_tuikov, hch, jejb, ltuikov, Eric.Moore, andrew.patterson,
	linux-scsi

> As others stated, id is already a tag/label. You should be 
> able to pass
> whatever id you want to scsi_scan_target, like the FC ID 
> (port_id), and
> then we also want an abstract iterator in fc transport for the id for
> usage in scsi_scan.c:scsi_scan_channel. Then you can lose all the
> fc_host->next_target_id code.

All nice and well, but....

How did this help things ?  The issue was the device with a changing
target id. If the device comes back at the same address each and
every time, ok. But, with FC, the Port ID is temporal. It can change
on a loop init, fabric reconfig, or with a user cable swap (kicked
the cable and replugged).

If the port id changes during run time, what are you to do ? What if
a new port is seen at the old port id, how do you now deal with the
name conflict ? You know apps are going to key off the physical bus
address being the target - if it changes, this becomes very problematic.

This approach only works as long as the transport's id fits within
the target id (an int). How would the SAS address(8byte wwn) utilize
such a scheme ?

-- james s

^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-23 18:25 James.Smart
  0 siblings, 0 replies; 83+ messages in thread
From: James.Smart @ 2005-08-23 18:25 UTC (permalink / raw)
  To: patmans
  Cc: luben_tuikov, hch, jejb, ltuikov, Eric.Moore, andrew.patterson,
	linux-scsi

> I thought by "the target id is logical for everything but 
> SPI" you meant
> that FC enumerated the scsi_device id.

Yes, I meant that.

> I didn't mean to address problems with persistent names, just map the
> scsi_device id to an FC value.

True. Port ID is just a bad example. Unfortunately, there's nothing in
FC, outside of wwpn (and sometimes wwnn), that you can uniquely identify
a device by. Since the wwpn didn't fit in the scsi_device id, it mandated
a translation to something that did. A simple sequential counter was
chosen. To keep things consistent, and done in a LLDD-independent manner,
the FC transport owned the assignment of the counter and the persistency
(and consistency) of the mapping.

-- james

^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-22 23:08 Moore, Eric Dean
  2005-08-24  8:59 ` Christoph Hellwig
  0 siblings, 1 reply; 83+ messages in thread
From: Moore, Eric Dean @ 2005-08-22 23:08 UTC (permalink / raw)
  To: Christoph Hellwig, James.Smart
  Cc: luben_tuikov, jejb, ltuikov, andrew.patterson, linux-scsi

On Sunday, August 21, 2005 10:53 AM, Christoph Hellwig wrote:
> This is just a brindup helper because the Fusion hardware does a SAS
> remote port to target ID mapping in firmware, in fact the firmware
> interface only addresses them using this assigned ID, which is a big
> shortcoming in the Fusion interface.  Once the more basic things are
> dealt with that will go away, similarly to how Fusion won't be able
> to use their firmware mapping for FC once they fully support the FC
> transport class.
>

Thats incorrect about the Fusion Firmware Interface.

The Sas Device Config pages offers three ways to access this config page.
They are:  (1) GetNextHandle (2) BusTargetID (3) Handle.
This is set in config page pageAddr field - bits 28-31.  Lets say you want
to know all the devices out in the sas domain that is discovered by
this HBA, you do the GetNextHandle method.  Bits 0-27 is the FormSpecific.
In FormSpecific, you pass 0xFFFF for the first request, then you pass the
devHandle for the previous config page to get the next.  The 3.02.55 code
I sent you did this discovery in mptbase.c, in a function called
mpt_sas_get_info.
All this info is stored in a link list, that currently is used for CSMI.

Eric Moore
 

^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-20  4:15 James.Smart
  2005-08-20  4:57 ` Jeff Garzik
                   ` (5 more replies)
  0 siblings, 6 replies; 83+ messages in thread
From: James.Smart @ 2005-08-20  4:15 UTC (permalink / raw)
  To: luben_tuikov; +Cc: hch, jejb, ltuikov, Eric.Moore, andrew.patterson, linux-scsi

> > This is a heck of a statement... The customers don't see it 
> as SAS vs FC
> > vs SPI, they just see it as SCSI, and there's a lot of 
> expectations on
> > consistent behavior. We take a lot of heat defending the community's
> > position, even from companies that you would have thought 
> had signed on
> > to the 2.6 behaviors.
> 
> I tried to understand this paragraph in the light of the very 
> few past days,
> but I couldn't.  What is it actually saying?
> 
> > I understand the need to push folks to the new 2.6 models, 
> but I fully
> > expect the same complaints to come from the users of SAS 
> and iSCSI as well.
> 
> What kind of complaints?
> 
> I ask because I'm a "user of SAS and iSCSI".

Ok, so I guess I owe you a response. I hesitate, as this discussion
always becomes larger than it should.

There are 2 key points:
- the target id is logical for everything but SPI
- following old SPI behavior, users expect the same devices to
  be enumerated at the same target ids, regardless of whether
  that enumeration is at the next link event, driver load/unload,
  or system reboot. The corollary for this is that the device's
  name should have remained the same as well.

For FC, target ids are typically assigned to devices on a
1st-seen-1st-assigned basis. For several reasons, there can be
changes in port discovery order after link events (cable pulls,
etc). For 2.4 kernels, the driver typically maintained a mapping
within the driver to ensure the same device showed up at the same
target id, even if it disappeared for some amount of time. If FC
was the boot device, wacky methods were used to ensure the mapping
persisted boot-to-boot.

For 2.6 kernels, the desire is to move away from relying on the
physical addressing. The recommendation is to use udev (preferred)
or filesystem labels (ok in some circumstances) to find the right
devices. By moving to lun/device-level id's, issues such as name
shift are better solved (note: name-shift still existed under 2.4).

We have found users having difficulty with the udev transition, as:
- From 2.4 history, old scsi behavior, and other unix's behavior
  (which functions much like 2.4), they are accustomed to not
  needing external tools or admin steps for device nameing.
  Things had just worked for the most part.
- Most view 2.6 as an upgrade and didn't expect something this
  basic to change.
- Many really don't know about or understand udev, hotplug,
  disk identifiers, and so on. Thus, there's a large education
  effort. It has to be dealt with in yet more documentation,
  help lines, etc.
- There are some real challenges in supporting a udev-named boot
  device. For the most part, it's a distro issue, which is becoming
  better. PS: for $10, name a 2.6 distro that uses udev out
  of the box for disk names and its installation. For $10 more, 
  can it install/boot from one?
- For better or worse, tools and api's exist that interacted with
  the old 2.4-style behavior. Now they must wait for the tools to
  be updated, suffer their non-functionality, and/or craft their
  own tools.
- Some of these vendors come from large disk farms, and in several
  cases, the disk farms change frequently. Thus, they must flush
  and regenerate their udev configurations on each change. Not a
  fun process.
- Most could care less about, or don't understand, the technical
  justifications for the new 2.6 behaviors. Thus, they push their
  vendors for same-style behaviors as 2.4 regardless of the 2.6
  stance.

Now - back to Christoph's point....

For iSCSI, (correct me if I'm wrong) as the scsi_host is mapped 1:1
with the session, there really is no such thing as multiple targets,
so it works. Even if it isn't 1:1, it is controlled via user space
so it's likely managable. Note: instead of target id shifting, there
may now be scsi_host number shifting.

For SAS, looking at Christoph's code - 
The target id comes from the LLDD. So either the LLDD maintains a
map of SAS port addresses to target ids, or the mapping could change,
same as FC. Christoph's argument is that FC's issue was historical.
SAS is sufficiently new that folks are now smart enough to use udev.
My contention is that people will expect the same behavior out of
SAS as they did w/ FC. To them its all "just SCSI".

I'm winded. Hope this helps.

-- james s

^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-18 18:48 James.Smart
  2005-08-18 19:04 ` Jeff Garzik
                   ` (2 more replies)
  0 siblings, 3 replies; 83+ messages in thread
From: James.Smart @ 2005-08-18 18:48 UTC (permalink / raw)
  To: hch; +Cc: jejb, ltuikov, Eric.Moore, andrew.patterson, linux-scsi

> I was trying to avoid the need for an rport object, but I'm 
> not yet sure
> it's feasible.  We certainly won't put in target-persistency support
> similar to FC, that was just a hack to get the existing 
> drivers migrated
> without lots of complaints, it's not going in for new transports like
> SAS or iSCSI. 

This is a heck of a statement... The customers don't see it as SAS vs FC
vs SPI, they just see it as SCSI, and there's a lot of expectations on
consistent behavior. We take a lot of heat defending the community's
position, even from companies that you would have thought had signed on
to the 2.6 behaviors.

I understand the need to push folks to the new 2.6 models, but I fully
expect the same complaints to come from the users of SAS and iSCSI as well.

Please note that by implementing the consistent mappings, you are lessening
the demands on the hba vendor to supply a non-upstream driver that works
around the issue.

> What we might need an rport for is to support SMP.  I'm
> not yet sure how to do SMP passthrough, but we will need some object
> to represent SMP ports.

Depending on how SATA support is implemented, it may be useful for that.

-- james s

^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-18 14:43 James.Smart
  0 siblings, 0 replies; 83+ messages in thread
From: James.Smart @ 2005-08-18 14:43 UTC (permalink / raw)
  To: James.Smart, hch, jejb; +Cc: ltuikov, Eric.Moore, andrew.patterson, linux-scsi

One more thing missing...

As there is a transport object between the scsi_host and scsi_target,
the transport needs to pick up the changes made to deal with scans
made outside of the transport (after a scsi_target has been removed).

The fix that got merged into the scsi-misc tree can be seen at:
http://www.kernel.org/pub/linux/kernel/people/jejb/scsi-rc-fixes-2.6.changelog
http://www.kernel.org/pub/linux/kernel/people/jejb/scsi-rc-fixes-2.6.diff

and correspond to the patch at:
http://marc.theaimsgroup.com/?l=linux-scsi&m=111845669410785&w=2

-- james s


^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-18 14:02 James.Smart
  2005-08-18 17:56 ` Christoph Hellwig
  0 siblings, 1 reply; 83+ messages in thread
From: James.Smart @ 2005-08-18 14:02 UTC (permalink / raw)
  To: James.Smart, hch, jejb; +Cc: ltuikov, Eric.Moore, andrew.patterson, linux-scsi

Ok, so I'm going to have to revert my statement. After perusing the
sas transport, I went to the previous patch, which added pre-init
data to scsi_scan_target calls.  I didn't understand why this was
needed.

In tracking how you were using the patch, it highlighted that you 
were skipping a step.  The api is such that it does not expect remote
SAS ports to be instantiated.  They should have be (just like FC).
Your api is written only to instantiate local initiator SAS ports.
It needs to instantiate remote SAS ports as well. If it does so, the
remote port is the parent, and the pre-init data doesn't need to be
passed around. The remote SAS ports need to also implement consistent
target id bindings, just like FC.

Also, it appears that your api is allowing multiple SAS initiator
ports to SCSI host. This doesn't make sense, unless you are going to
map SAS ports to the scsi "channel" designator in the address.
In FC, there is a 1:1 correlation of the scsi_host to the local FC
port, so there's no need for a local port transport object as it's
simply the transport for the host.  Also, I prefer a distinction
between the local port and remote port as the functionality of each
will be different (e.g. for local port, you'll have statistics, 
more attributes, and more functions that can be performed. The remote
ports are rarely more than a reporting element, so they are less
featured).

-- James



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org
> [mailto:linux-scsi-owner@vger.kernel.org]On Behalf Of Smart, James
> Sent: Thursday, August 18, 2005 7:58 AM
> To: hch@lst.de; jejb@steeleye.com
> Cc: ltuikov@yahoo.com; Eric.Moore@lsil.com; andrew.patterson@hp.com;
> linux-scsi@vger.kernel.org
> Subject: RE: [PATCH] minimal SAS transport class
> 
> 
> Christoph,
> 
> I like it, and have no real complaints.  
> 
> As familiar as this looks, there were a couple of conventions 
> in the FC
> transport that I thought should have carried over here. Namely, I saw
> not all attributes being the same, thus I created 3 categories of
> attributes:
>   Private:
>     These are attributes fully owned by the transport. The LLDD does
>     not directly access them, or participate in the sysfs calls.
>     LLDD interaction is strictly indirect via transport functions.
>   Fixed:
>     These attributes, once set, are not expected to change. The LLDD
>     does set these values directly, but should only do so at
>     initialization. The sysfs functions will be handled solely by
>     the transport w/ no interaction with the LLDD.
>   Dynamic (Normal):
>     Values can change. Sysfs functions utilize LLDD to get/set values.
> 
> I expect that the SAS transport has much the same categories, and it
> would be beneficial to indicate which category the different 
> attributes
> fall into. This can be as simple as comments, grouping, or 
> name prefixes.
> 
> Also, I see your enums set explicit values. Just a caution. When I did
> the FC transport, there were cases where I specifically did not use
> specification-specific values, as the transport was a subset 
> or extension
> of the spec. This made anyone interacting with the transport 
> realize that
> this area was not just a reincarnation of the spec (plus, spec writers
> sometimes do stupid things).
> 
> -- james s
> 
> -
> To unsubscribe from this list: send the line "unsubscribe 
> linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 83+ messages in thread
* RE: [PATCH] minimal SAS transport class
@ 2005-08-18 11:57 James.Smart
  0 siblings, 0 replies; 83+ messages in thread
From: James.Smart @ 2005-08-18 11:57 UTC (permalink / raw)
  To: hch, jejb; +Cc: ltuikov, Eric.Moore, andrew.patterson, linux-scsi

Christoph,

I like it, and have no real complaints.  

As familiar as this looks, there were a couple of conventions in the FC
transport that I thought should have carried over here. Namely, I saw
not all attributes being the same, thus I created 3 categories of
attributes:
  Private:
    These are attributes fully owned by the transport. The LLDD does
    not directly access them, or participate in the sysfs calls.
    LLDD interaction is strictly indirect via transport functions.
  Fixed:
    These attributes, once set, are not expected to change. The LLDD
    does set these values directly, but should only do so at
    initialization. The sysfs functions will be handled solely by
    the transport w/ no interaction with the LLDD.
  Dynamic (Normal):
    Values can change. Sysfs functions utilize LLDD to get/set values.

I expect that the SAS transport has much the same categories, and it
would be beneficial to indicate which category the different attributes
fall into. This can be as simple as comments, grouping, or name prefixes.

Also, I see your enums set explicit values. Just a caution. When I did
the FC transport, there were cases where I specifically did not use
specification-specific values, as the transport was a subset or extension
of the spec. This made anyone interacting with the transport realize that
this area was not just a reincarnation of the spec (plus, spec writers
sometimes do stupid things).

-- james s


^ permalink raw reply	[flat|nested] 83+ messages in thread
* [PATCH] minimal SAS transport class
@ 2005-08-15 13:55 Christoph Hellwig
  2005-08-15 14:19 ` Luben Tuikov
                   ` (2 more replies)
  0 siblings, 3 replies; 83+ messages in thread
From: Christoph Hellwig @ 2005-08-15 13:55 UTC (permalink / raw)
  To: jejb; +Cc: ltuikov, Eric.Moore, andrew.patterson, linux-scsi

This is a minmal, bottom-up SAS transport class.  So far it only exposed
information about the SAS port/phy and SAS device (scsi target).  I hope
this will integrate nicely with the top-down work Luben has done once he
finally releases it publically, but for now I think we should have
something so SAS drivers can go in the tree.

In detail this transport class does:

 - introduces a SAS port object between the Scsi_Host and scsi_target,
   this is used to hold all information specific to the SAS port and
   PHY - right now they're used interchangable as I haven't found the
   right abstraction for wide ports yet - if there is a proper solution
   at all as the SAS spec leaves binding PHYs together to wide ports
   up to the implementation.
 - adds some attributes to the scsi_target, and an API call to
   preinitialize them.

It does not:

 - handle any managment interfaces or chaning of attributes
 - any SAS devices that are not scsi targets, most importantly there's
   no support for SMP and extenders yet
 - wide ports (as mentioned above)
 - software device discovery (although I know Luben has some nice code
   for that)
 - everythig not mentioned here

A bit of warning: I've only tested this with an SATA disk attached to
a SAS HBA so far because I don't have any real SAS storage yet.

To use the transport class you need a patched fusion driver for now,
use the LSI tarball at:

  ftp://ftp.lsil.com/HostAdapterDrivers/linux/Fusion-MPT/mptlinux-3.02.55-src.tar.gz

plus my patch at:

  http://verein.lst.de/~hch/fusion-sas-transport-class.diff

I'll try to port my changes plus basic SAS support over to the mainline
driver, but the driver is currently not endian clean which makes it hard
for me to actually test it.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: scsi-misc-2.6/drivers/scsi/Kconfig
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/Kconfig	2005-08-13 13:53:51.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/Kconfig	2005-08-15 15:34:56.000000000 +0200
@@ -229,6 +229,13 @@
 	  each attached iSCSI device to sysfs, say Y.
 	  Otherwise, say N.
 
+config SCSI_SAS_ATTRS
+	tristate "SAS Transport Attributes"
+	depends on SCSI
+	help
+	  If you wish to export transport-specific information about
+	  each attached SAS device to sysfs, say Y.
+
 endmenu
 
 menu "SCSI low-level drivers"
Index: scsi-misc-2.6/drivers/scsi/Makefile
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/Makefile	2005-08-13 13:53:51.000000000 +0200
+++ scsi-misc-2.6/drivers/scsi/Makefile	2005-08-15 15:35:12.000000000 +0200
@@ -29,6 +29,7 @@
 obj-$(CONFIG_SCSI_SPI_ATTRS)	+= scsi_transport_spi.o
 obj-$(CONFIG_SCSI_FC_ATTRS) 	+= scsi_transport_fc.o
 obj-$(CONFIG_SCSI_ISCSI_ATTRS)	+= scsi_transport_iscsi.o
+obj-$(CONFIG_SCSI_SAS_ATTRS)	+= scsi_transport_sas.o
 
 obj-$(CONFIG_SCSI_AMIGA7XX)	+= amiga7xx.o	53c7xx.o
 obj-$(CONFIG_A3000_SCSI)	+= a3000.o	wd33c93.o
Index: scsi-misc-2.6/drivers/scsi/scsi_transport_sas.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ scsi-misc-2.6/drivers/scsi/scsi_transport_sas.c	2005-08-15 15:40:00.000000000 +0200
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2005 Dell Inc.
+ *	Released under GPL v2.
+ *
+ * Based on the FC transport class work by James Smart, Emulex Corporation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_sas.h>
+
+
+#define SAS_TARGET_ATTRS	25
+#define SAS_PORT_ATTRS		25
+
+struct sas_internal {
+	struct scsi_transport_template t;
+	struct sas_function_template *f;
+
+	struct class_device_attribute private_target_attrs[SAS_TARGET_ATTRS];
+	struct class_device_attribute private_port_attrs[SAS_TARGET_ATTRS];
+
+	struct transport_container port_attr_cont;
+
+	/*
+	 * The array of null terminated pointers to attributes
+	 * needed by scsi_sysfs.c
+	 */
+	struct class_device_attribute *target_attrs[SAS_TARGET_ATTRS];
+	struct class_device_attribute *port_attrs[SAS_PORT_ATTRS + 1];
+};
+#define to_sas_internal(tmpl)	container_of(tmpl, struct sas_internal, t)
+
+/*
+ * Hack to allow attributes of the same name in different objects.
+ */
+#define SAS_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
+	struct class_device_attribute class_device_attr_##_prefix##_##_name = \
+	__ATTR(_name,_mode,_show,_store)
+
+
+/*
+ * Pretty printing helpers
+ */
+
+#define sas_bitfield_name_match(title, table)			\
+static ssize_t							\
+get_sas_##title##_names(u32 table_key, char *buf)		\
+{								\
+	char *prefix = "";					\
+	ssize_t len = 0;					\
+	int i;							\
+								\
+	for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) {	\
+		if (table[i].value & table_key) {		\
+			len += sprintf(buf + len, "%s%s",	\
+				prefix, table[i].name);		\
+			prefix = ", ";				\
+		}						\
+	}							\
+	len += sprintf(buf + len, "\n");			\
+	return len;						\
+}
+
+#define sas_bitfield_name_search(title, table)			\
+static ssize_t							\
+get_sas_##title##_names(u32 table_key, char *buf)		\
+{								\
+	ssize_t len = 0;					\
+	int i;							\
+								\
+	for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) {	\
+		if (table[i].value == table_key) {		\
+			len += sprintf(buf + len, "%s",		\
+				table[i].name);			\
+			break;					\
+		}						\
+	}							\
+	len += sprintf(buf + len, "\n");			\
+	return len;						\
+}
+
+static struct {
+	u32		value;
+	char		*name;
+} sas_device_type_names[] = {
+	{ SAS_PHY_UNUSED,		"unused" },
+	{ SAS_END_DEVICE,		"end device" },
+	{ SAS_EDGE_EXPANDER_DEVICE,	"edge expander" },
+	{ SAS_FANOUT_EXPANDER_DEVICE,	"fanout expander" },
+};
+sas_bitfield_name_search(device_type, sas_device_type_names)
+
+
+static struct {
+	u32		value;
+	char		*name;
+} sas_protocol_names[] = {
+	{ SAS_PROTOCOL_SATA,		"sata" },
+	{ SAS_PROTOCOL_SMP,		"smp" },
+	{ SAS_PROTOCOL_STP,		"stp" },
+	{ SAS_PROTOCOL_SSP,		"ssp" },
+};
+sas_bitfield_name_match(protocol, sas_protocol_names)
+
+static struct {
+	u32		value;
+	char		*name;
+} sas_linkspeed_names[] = {
+	{ SAS_LINK_RATE_UNKNOWN,	"Unknown" },
+	{ SAS_PHY_DISABLED,		"Phy disabled" },
+	{ SAS_LINK_RATE_FAILED,		"Link Rate failed" },
+	{ SAS_SATA_SPINUP_HOLD,		"Spin-up hold" },
+	{ SAS_LINK_RATE_1_5_GBPS,	"1.5 Gbit" },
+	{ SAS_LINK_RATE_3_0_GBPS,	"3.0 Gbit" },
+};
+sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
+
+
+/*
+ * SAS target attributes
+ */
+
+#define sas_transport_show_simple(field, name, format_string)		\
+static ssize_t								\
+show_sas_transport_##name(struct class_device *cdev, char *buf)		\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct sas_transport_attrs *tp;					\
+									\
+	tp = (struct sas_transport_attrs *)&starget->starget_data;	\
+	return snprintf(buf, 20, format_string, tp->field);		\
+}
+
+#define sas_transport_simple_attr(field, name, format_string)		\
+	sas_transport_show_simple(field, name, format_string)		\
+static SAS_CLASS_DEVICE_ATTR(transport, name, S_IRUGO, 			\
+		show_sas_transport_##name, NULL)
+
+#define sas_transport_show_protocol(field, name)			\
+static ssize_t								\
+show_sas_transport_##name(struct class_device *cdev, char *buf)		\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct sas_transport_attrs *tp =				\
+		(struct sas_transport_attrs *)&starget->starget_data;	\
+									\
+	if (!tp->field)							\
+		return snprintf(buf, 20, "none\n");			\
+	return get_sas_protocol_names(tp->field, buf);			\
+}
+
+#define sas_transport_protocol_attr(field, name)			\
+	sas_transport_show_protocol(field, name)			\
+static SAS_CLASS_DEVICE_ATTR(transport, name, S_IRUGO,			\
+		show_sas_transport_##name, NULL)
+
+static ssize_t
+show_sas_transport_device_type(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct sas_transport_attrs *tp =
+		(struct sas_transport_attrs *)&starget->starget_data;
+
+	if (!tp->attached.device_type)
+		return snprintf(buf, 20, "none\n");
+	return get_sas_device_type_names(tp->attached.device_type, buf);
+}
+
+static SAS_CLASS_DEVICE_ATTR(transport, device_type, S_IRUGO,
+		show_sas_transport_device_type, NULL);
+
+sas_transport_protocol_attr(attached.initiator_port_protocols,
+		initiator_port_protocols);
+sas_transport_protocol_attr(attached.target_port_protocols,
+		target_port_protocols);
+sas_transport_simple_attr(attached.sas_address,
+		sas_address, "0x%llx\n");
+sas_transport_simple_attr(attached.phy_identifier,
+		phy_identifier, "%d\n");
+
+static DECLARE_TRANSPORT_CLASS(sas_transport_class,
+		"sas_transport", NULL, NULL, NULL);
+
+static int sas_target_match(struct attribute_container *cont,
+			    struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct sas_internal *i;
+
+	if (!scsi_is_target_device(dev))
+		return 0;
+	shost = dev_to_shost(dev->parent);
+
+	if (!shost->transportt)
+		return 0;
+	if (shost->transportt->target_attrs.ac.class !=
+			&sas_transport_class.class)
+		return 0;
+
+	i = to_sas_internal(shost->transportt);
+	return &i->t.target_attrs.ac == cont;
+}
+
+void sas_add_target(struct sas_port *port, struct sas_identify *attached,
+		uint channel, uint target)
+{
+	if (attached->target_port_protocols &
+	    (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA))
+		scsi_scan_target(&port->dev, channel, target, ~0, 0, attached);
+}
+EXPORT_SYMBOL(sas_add_target);
+
+
+/*
+ * SAS Port attributes
+ */
+
+#define sas_port_show_simple(field, name, format_string)		\
+static ssize_t								\
+show_sas_port_##name(struct class_device *cdev, char *buf)		\
+{									\
+	struct sas_port *port = transport_class_to_port(cdev);		\
+									\
+	return snprintf(buf, 20, format_string, port->attrs->field);	\
+}
+
+#define sas_port_simple_attr(field, name, format_string)		\
+	sas_port_show_simple(field, name, format_string)		\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL)
+
+#define sas_port_show_protocol(field, name)				\
+static ssize_t								\
+show_sas_port_##name(struct class_device *cdev, char *buf)		\
+{									\
+	struct sas_port *port = transport_class_to_port(cdev);		\
+									\
+	if (!port->attrs->field)					\
+		return snprintf(buf, 20, "none\n");			\
+	return get_sas_protocol_names(port->attrs->field, buf);		\
+}
+
+#define sas_port_protocol_attr(field, name)				\
+	sas_port_show_protocol(field, name)				\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL)
+
+#define sas_port_show_linkspeed(field)					\
+static ssize_t								\
+show_sas_port_##field(struct class_device *cdev, char *buf)		\
+{									\
+	struct sas_port *port = transport_class_to_port(cdev);		\
+									\
+	return get_sas_linkspeed_names(port->attrs->field, buf);	\
+}
+
+#define sas_port_linkspeed_attr(field)					\
+	sas_port_show_linkspeed(field)					\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_sas_port_##field, NULL)
+
+static ssize_t
+show_sas_device_type(struct class_device *cdev, char *buf)
+{
+	struct sas_port *port = transport_class_to_port(cdev);
+
+	if (!port->attrs->identify.device_type)
+		return snprintf(buf, 20, "none\n");
+	return get_sas_device_type_names(
+			port->attrs->identify.device_type, buf);
+}
+
+static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
+
+sas_port_protocol_attr(identify.initiator_port_protocols,
+		initiator_port_protocols);
+sas_port_protocol_attr(identify.target_port_protocols,
+		target_port_protocols);
+sas_port_simple_attr(identify.sas_address,
+		sas_address, "0x%llx\n");
+sas_port_simple_attr(identify.phy_identifier,
+		phy_identifier, "%d\n");
+sas_port_simple_attr(port_identifier, port_identifier, "%d\n");
+sas_port_linkspeed_attr(negotiated_linkrate);
+sas_port_linkspeed_attr(minimum_linkrate_hw);
+sas_port_linkspeed_attr(minimum_linkrate);
+sas_port_linkspeed_attr(maximum_linkrate_hw);
+sas_port_linkspeed_attr(maximum_linkrate);
+
+
+static DECLARE_TRANSPORT_CLASS(sas_port_class,
+		"sas_port", NULL, NULL, NULL);
+
+static int sas_port_match(struct attribute_container *cont, struct device *dev)
+{
+	struct Scsi_Host *shost;
+	struct sas_internal *i;
+
+	if (!scsi_is_sas_port(dev))
+		return 0;
+	shost = dev_to_shost(dev->parent);
+
+	if (!shost->transportt)
+		return 0;
+	if (shost->transportt->target_attrs.ac.class !=
+			&sas_transport_class.class)
+		return 0;
+
+	i = to_sas_internal(shost->transportt);
+	return &i->port_attr_cont.ac == cont;
+}
+
+static void sas_port_release(struct device *dev)
+{
+	struct sas_port *port = dev_to_port(dev);
+
+	kfree(port->attrs);
+	put_device(dev->parent);
+	kfree(port);
+}
+
+struct sas_port *
+sas_port_add(struct Scsi_Host *shost, int number,
+		struct sas_port_attrs *attrs)
+{
+	struct sas_port *port;
+	int error;
+
+	port = kmalloc(sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return ERR_PTR(-ENOMEM);
+	memset(port, 0, sizeof(*port));
+
+	get_device(&shost->shost_gendev);
+
+	port->attrs = attrs;
+	port->number = number;
+
+	device_initialize(&port->dev);
+	port->dev.parent = get_device(&shost->shost_gendev);
+	port->dev.release = sas_port_release;
+	sprintf(port->dev.bus_id, "port-%d:%d",
+		shost->host_no, number);
+	transport_setup_device(&port->dev);
+
+	error = device_add(&port->dev);
+	if (error)
+		goto out_transport_destroy;
+	transport_add_device(&port->dev);
+	transport_configure_device(&port->dev);
+
+	return port;
+
+ out_transport_destroy:
+	transport_destroy_device(&port->dev);
+	put_device(port->dev.parent);
+	put_device(port->dev.parent);
+	put_device(&shost->shost_gendev);
+	kfree(port);
+	return NULL;
+}
+EXPORT_SYMBOL(sas_port_add);
+
+void
+sas_port_delete(struct sas_port *port)
+{
+	struct Scsi_Host *shost = port_to_shost(port);
+	struct device *dev = &port->dev;
+
+	scsi_remove_target(&port->dev);
+
+	transport_remove_device(dev);
+	device_del(dev);
+	transport_destroy_device(dev);
+	put_device(&shost->shost_gendev);
+}
+EXPORT_SYMBOL(sas_port_delete);
+
+int scsi_is_sas_port(const struct device *dev)
+{
+	return dev->release == sas_port_release;
+}
+EXPORT_SYMBOL(scsi_is_sas_port);
+
+
+/*
+ * Setup / Teardown code
+ */
+
+#define SETUP_TARGET_ATTRIBUTE(field)					\
+	i->private_target_attrs[count] = class_device_attr_##field;	\
+	i->private_target_attrs[count].attr.mode = S_IRUGO;		\
+	i->private_target_attrs[count].store = NULL;			\
+	i->target_attrs[count] = &i->private_target_attrs[count];	\
+	count++
+
+#define SETUP_PORT_ATTRIBUTE(field)					\
+	i->private_port_attrs[count] = class_device_attr_##field;	\
+        i->private_port_attrs[count].attr.mode = S_IRUGO;		\
+        i->private_port_attrs[count].store = NULL;			\
+        i->port_attrs[count] = &i->private_port_attrs[count];		\
+	count++
+
+struct scsi_transport_template *
+sas_attach_transport(struct sas_function_template *ft)
+{
+	struct sas_internal *i;
+	int count;
+
+	i = kmalloc(sizeof(struct sas_internal), GFP_KERNEL);
+	if (!i)
+		return NULL;
+	memset(i, 0, sizeof(struct sas_internal));
+
+	i->t.target_attrs.ac.class = &sas_transport_class.class;
+	i->t.target_attrs.ac.attrs = &i->target_attrs[0];
+	i->t.target_attrs.ac.match = sas_target_match;
+	transport_container_register(&i->t.target_attrs);
+	i->t.target_size = sizeof(struct sas_transport_attrs);
+
+	i->port_attr_cont.ac.class = &sas_port_class.class;
+	i->port_attr_cont.ac.attrs = &i->port_attrs[0];
+	i->port_attr_cont.ac.match = sas_port_match;
+	transport_container_register(&i->port_attr_cont);
+
+	i->f = ft;
+
+	count = 0;
+	SETUP_PORT_ATTRIBUTE(initiator_port_protocols);
+	SETUP_PORT_ATTRIBUTE(target_port_protocols);
+	SETUP_PORT_ATTRIBUTE(device_type);
+	SETUP_PORT_ATTRIBUTE(sas_address);
+	SETUP_PORT_ATTRIBUTE(phy_identifier);
+	SETUP_PORT_ATTRIBUTE(port_identifier);
+	SETUP_PORT_ATTRIBUTE(negotiated_linkrate);
+	SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw);
+	SETUP_PORT_ATTRIBUTE(minimum_linkrate);
+	SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw);
+	SETUP_PORT_ATTRIBUTE(maximum_linkrate);
+	i->port_attrs[count] = NULL;
+
+	count = 0;
+	SETUP_TARGET_ATTRIBUTE(transport_initiator_port_protocols);
+	SETUP_TARGET_ATTRIBUTE(transport_target_port_protocols);
+	SETUP_TARGET_ATTRIBUTE(transport_device_type);
+	SETUP_TARGET_ATTRIBUTE(transport_sas_address);
+	SETUP_TARGET_ATTRIBUTE(transport_phy_identifier);
+	i->target_attrs[count] = NULL;
+
+	return &i->t;
+}
+EXPORT_SYMBOL(sas_attach_transport);
+
+void sas_release_transport(struct scsi_transport_template *t)
+{
+	struct sas_internal *i = to_sas_internal(t);
+
+	transport_container_unregister(&i->t.target_attrs);
+	transport_container_unregister(&i->port_attr_cont);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(sas_release_transport);
+
+static __init int sas_transport_init(void)
+{
+	int error = transport_class_register(&sas_transport_class);
+	if (!error) {
+		error = transport_class_register(&sas_port_class);
+		if (error)
+			transport_class_unregister(&sas_transport_class);
+	}
+	return error;
+
+}
+
+static void __exit sas_transport_exit(void)
+{
+	transport_class_unregister(&sas_transport_class);
+	transport_class_unregister(&sas_port_class);
+}
+
+MODULE_AUTHOR("Christoph Hellwig");
+MODULE_DESCRIPTION("SAS Transport Attributes");
+MODULE_LICENSE("GPL");
+
+module_init(sas_transport_init);
+module_exit(sas_transport_exit);
Index: scsi-misc-2.6/include/scsi/scsi_transport_sas.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ scsi-misc-2.6/include/scsi/scsi_transport_sas.h	2005-08-15 15:33:45.000000000 +0200
@@ -0,0 +1,88 @@
+#ifndef SCSI_TRANSPORT_SAS_H
+#define SCSI_TRANSPORT_SAS_H
+
+#include <linux/transport_class.h>
+#include <linux/types.h>
+
+
+struct scsi_transport_template;
+
+enum sas_device_type {
+	SAS_PHY_UNUSED			= 0x00,
+	SAS_END_DEVICE			= 0x10,
+	SAS_EDGE_EXPANDER_DEVICE	= 0x20,
+	SAS_FANOUT_EXPANDER_DEVICE	= 0x30,
+};
+
+enum sas_protocol {
+	SAS_PROTOCOL_SATA		= 0x01,
+	SAS_PROTOCOL_SMP		= 0x02,
+	SAS_PROTOCOL_STP		= 0x04,
+	SAS_PROTOCOL_SSP		= 0x08,
+};
+
+enum sas_linkrate {
+	SAS_LINK_RATE_UNKNOWN		= 0x00,
+	SAS_PHY_DISABLED		= 0x01,
+	SAS_LINK_RATE_FAILED		= 0x02,
+	SAS_SATA_SPINUP_HOLD		= 0x03,
+	SAS_SATA_PORT_SELECTOR		= 0x04,
+	SAS_LINK_RATE_1_5_GBPS		= 0x08,
+	SAS_LINK_RATE_3_0_GBPS		= 0x09,
+	SAS_LINK_VIRTUAL		= 0x10,
+};
+
+struct sas_identify {
+	enum sas_device_type	device_type;
+	enum sas_protocol	initiator_port_protocols;
+	enum sas_protocol	target_port_protocols;
+	u64			sas_address;
+	u8			phy_identifier;
+};
+
+struct sas_transport_attrs {
+	struct sas_identify	attached;
+};
+
+struct sas_port_attrs {
+	struct list_head	port_list;
+	struct sas_identify	identify;
+	struct sas_identify	attached;
+	enum sas_linkrate	negotiated_linkrate;
+	enum sas_linkrate	minimum_linkrate_hw;
+	enum sas_linkrate	minimum_linkrate;
+	enum sas_linkrate	maximum_linkrate_hw;
+	enum sas_linkrate	maximum_linkrate;
+	u8			port_identifier;
+};
+
+/* The functions by which the transport class and the driver communicate */
+struct sas_function_template {
+};
+
+struct sas_port {
+	struct device		dev;
+	int			number;
+	struct sas_port_attrs	*attrs;
+};
+
+#define dev_to_port(d) \
+	container_of((d), struct sas_port, dev)
+#define transport_class_to_port(cdev) \
+	dev_to_port((cdev)->dev)
+#define port_to_shost(port) \
+	dev_to_shost((port)->dev.parent)
+
+extern void sas_add_target(struct sas_port *, struct sas_identify *,
+		uint, uint);
+
+extern struct sas_port *sas_port_add(struct Scsi_Host *, int,
+		struct sas_port_attrs *);
+extern void sas_port_delete(struct sas_port *);
+extern int scsi_is_sas_port(const struct device *);
+
+extern struct scsi_transport_template *
+sas_attach_transport(struct sas_function_template *);
+extern void sas_release_transport(struct scsi_transport_template *);
+
+#endif /* SCSI_TRANSPORT_SAS_H */

^ permalink raw reply	[flat|nested] 83+ messages in thread

end of thread, other threads:[~2005-08-29 18:34 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-23 16:16 [PATCH] minimal SAS transport class James.Smart
2005-08-23 17:28 ` Stefan Richter
2005-08-24  0:02   ` Luben Tuikov
2005-08-24  9:12     ` Christoph Hellwig
2005-08-26 15:47       ` Luben Tuikov
2005-08-26 16:29         ` scsi device driver Yijian Wang
2005-08-26 19:24         ` [PATCH] minimal SAS transport class Jeff Garzik
2005-08-26 19:44           ` Luben Tuikov
2005-08-27  1:53             ` Jeff Garzik
2005-08-27  7:35               ` Stefan Richter
2005-08-28 22:27               ` Luben Tuikov
2005-08-29  5:16               ` Stefan Richter
2005-08-29 17:11           ` Christoph Hellwig
2005-08-29 17:20             ` Luben Tuikov
2005-08-29 17:25               ` Christoph Hellwig
2005-08-29 17:16         ` Christoph Hellwig
2005-08-29 17:31           ` Luben Tuikov
2005-08-29 18:34             ` Luben Tuikov
2005-08-29 18:09           ` James Bottomley
2005-08-23 17:57 ` Patrick Mansfield
  -- strict thread matches above, loose matches on Subject: below --
2005-08-23 18:25 James.Smart
2005-08-22 23:08 Moore, Eric Dean
2005-08-24  8:59 ` Christoph Hellwig
2005-08-20  4:15 James.Smart
2005-08-20  4:57 ` Jeff Garzik
2005-08-20 17:23 ` Luben Tuikov
2005-08-21 17:03   ` Christoph Hellwig
2005-08-21 16:52 ` Christoph Hellwig
2005-08-21 18:23   ` Luben Tuikov
2005-08-22  4:55 ` Matt Domsch
2005-08-22 17:05   ` Luben Tuikov
2005-08-22 21:53     ` Mike Anderson
2005-08-23 23:55       ` Luben Tuikov
2005-08-24 17:12         ` Patrick Mansfield
2005-08-24 20:05           ` Luben Tuikov
2005-08-24 20:42             ` Patrick Mansfield
2005-08-24 21:48               ` Luben Tuikov
2005-08-23 11:10     ` Douglas Gilbert
2005-08-23  6:27 ` Hannes Reinecke
2005-08-23 15:42 ` Patrick Mansfield
2005-08-23 15:53   ` Matthew Wilcox
2005-08-24  0:13   ` Luben Tuikov
2005-08-25 19:32     ` Stefan Richter
2005-08-25 20:06       ` Jeff Garzik
2005-08-26 16:43         ` Luben Tuikov
2005-08-26 17:22           ` James Bottomley
2005-08-26 18:16             ` Luben Tuikov
2005-08-26 18:48               ` Jeff Garzik
2005-08-26 19:37                 ` Luben Tuikov
2005-08-27  1:39                   ` Jeff Garzik
2005-08-27  7:11                     ` Stefan Richter
2005-08-28 22:13                     ` Luben Tuikov
2005-08-18 18:48 James.Smart
2005-08-18 19:04 ` Jeff Garzik
2005-08-19 14:06   ` Christoph Hellwig
2005-08-19 17:51     ` Luben Tuikov
2005-08-19 17:54       ` Christoph Hellwig
2005-08-19 17:56         ` Luben Tuikov
2005-08-19 17:59           ` Christoph Hellwig
2005-08-19 18:07             ` Luben Tuikov
2005-08-19 19:59               ` James Bottomley
2005-08-19 20:32                 ` Luben Tuikov
2005-08-19 20:54                   ` Jeff Garzik
2005-08-20  9:18                   ` Christoph Hellwig
2005-08-20 17:34                     ` Luben Tuikov
2005-08-21  6:41                       ` Arjan van de Ven
2005-08-21 17:07                       ` Christoph Hellwig
2005-08-19 19:08             ` Luben Tuikov
2005-08-18 20:06 ` Luben Tuikov
2005-08-19 14:04 ` Christoph Hellwig
2005-08-18 14:43 James.Smart
2005-08-18 14:02 James.Smart
2005-08-18 17:56 ` Christoph Hellwig
2005-08-18 20:05   ` Luben Tuikov
2005-08-19 14:15     ` Christoph Hellwig
2005-08-18 11:57 James.Smart
2005-08-15 13:55 Christoph Hellwig
2005-08-15 14:19 ` Luben Tuikov
2005-08-15 14:35 ` Arjan van de Ven
2005-08-15 15:04   ` Luben Tuikov
2005-08-15 15:13 ` Luben Tuikov
2005-08-15 15:21   ` Christoph Hellwig
2005-08-15 15:33     ` Luben Tuikov

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).