All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luben Tuikov <luben_tuikov@adaptec.com>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	SCSI Mailing List <linux-scsi@vger.kernel.org>
Subject: [PATCH 2.6.13 12/14] sas-class: sas_phy.c SAS Phy (events, attrs, initializaion)
Date: Fri, 09 Sep 2005 15:41:54 -0400	[thread overview]
Message-ID: <4321E582.9020401@adaptec.com> (raw)

Signed-off-by: Luben Tuikov <luben_tuikov@adaptec.com>

diff -X linux-2.6.13/Documentation/dontdiff -Naur linux-2.6.13-orig/drivers/scsi/sas-class/sas_phy.c linux-2.6.13/drivers/scsi/sas-class/sas_phy.c
--- linux-2.6.13-orig/drivers/scsi/sas-class/sas_phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.13/drivers/scsi/sas-class/sas_phy.c	2005-09-09 11:14:29.000000000 -0400
@@ -0,0 +1,307 @@
+/*
+ * Serial Attached SCSI (SAS) Phy class
+ *
+ * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
+ * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
+ *
+ * This file is licensed under GPLv2.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * $Id: //depot/sas-class/sas_phy.c#37 $
+ */
+
+#include "sas_internal.h"
+
+/* ---------- Phy events ---------- */
+
+void sas_phye_loss_of_signal(struct sas_phy *phy)
+{
+	phy->error = 0;
+	sas_deform_port(phy);
+}
+
+void sas_phye_oob_done(struct sas_phy *phy)
+{
+	phy->error = 0;
+}
+
+void sas_phye_oob_error(struct sas_phy *phy)
+{
+	struct sas_ha_struct *sas_ha = phy->ha;
+	struct sas_port *port = phy->port;
+
+	sas_deform_port(phy);
+
+	if (!port && phy->enabled && sas_ha->lldd_control_phy) {
+		phy->error++;
+		switch (phy->error) {
+		case 1:
+		case 2:
+			sas_ha->lldd_control_phy(phy, PHY_FUNC_HARD_RESET);
+			break;
+		case 3:
+		default:
+			phy->error = 0;
+			phy->enabled = 0;
+			sas_ha->lldd_control_phy(phy, PHY_FUNC_DISABLE);
+			break;
+		}
+	}
+}
+
+void sas_phye_spinup_hold(struct sas_phy *phy)
+{
+	struct sas_ha_struct *sas_ha = phy->ha;
+
+	phy->error = 0;
+	sas_ha->lldd_control_phy(phy, PHY_FUNC_RELEASE_SPINUP_HOLD);
+}
+
+/* ---------- Phy attributes ---------- */
+
+static ssize_t sas_phy_id_show(struct sas_phy *phy, char *buf)
+{
+	return sprintf(buf, "%d\n", phy->id);
+}
+
+static ssize_t sas_phy_enabled_show(struct sas_phy *phy, char *buf)
+{
+	return sprintf(buf, "%d\n", phy->enabled);
+}
+
+static ssize_t sas_phy_enabled_store(struct sas_phy *phy, const char *buf,
+				     size_t size)
+{
+	if (size > 0) {
+		if (buf[0] == '1')
+			phy->ha->lldd_control_phy(phy, PHY_FUNC_LINK_RESET);
+	}
+	return size;
+}
+
+static ssize_t sas_phy_class_show(struct sas_phy *phy, char *buf)
+{
+	if (!phy->enabled)
+		return 0;
+	return sas_show_class(phy->class, buf);
+}
+
+static ssize_t sas_phy_iproto_show(struct sas_phy *phy, char *page)
+{
+	if (!phy->enabled)
+		return 0;
+	return sas_show_proto(phy->iproto, page);
+}
+
+static ssize_t sas_phy_tproto_show(struct sas_phy *phy, char *page)
+{
+	if (!phy->enabled)
+		return 0;
+	return sas_show_proto(phy->tproto, page);
+}
+
+static ssize_t sas_phy_type_show(struct sas_phy *phy, char *buf)
+{
+	static const char *phy_type_str[] = {
+		[PHY_TYPE_PHYSICAL] = "physical",
+		[PHY_TYPE_VIRTUAL] = "virtual",
+	};
+	if (!phy->enabled)
+		return 0;
+	return sprintf(buf, "%s\n", phy_type_str[phy->type]);
+}
+
+static ssize_t sas_phy_role_show(struct sas_phy *phy, char *page)
+{
+	static const char *phy_role_str[] = {
+		[PHY_ROLE_NONE] = "none",
+		[PHY_ROLE_TARGET] = "target",
+		[PHY_ROLE_INITIATOR] = "initiator",
+	};
+	int  v;
+	char *buf = page;
+
+	if (!phy->enabled)
+		return 0;
+
+	if (phy->role == PHY_ROLE_NONE)
+		return sprintf(buf, "%s\n", phy_role_str[PHY_ROLE_NONE]);
+
+	for (v = 1; v <= PHY_ROLE_INITIATOR; v <<= 1) {
+		if (v & phy->role) {
+			buf += sprintf(buf, "%s", phy_role_str[v]);
+			if (phy->role & ~((v<<1)-1))
+				buf += sprintf(buf, "|");
+			else
+				buf += sprintf(buf, "\n");
+		}
+	}
+	return buf-page;
+}
+
+static ssize_t sas_phy_linkrate_show(struct sas_phy *phy, char *buf)
+{
+	if (!phy->enabled)
+		return 0;
+	return sas_show_linkrate(phy->linkrate, buf);
+}
+
+static ssize_t sas_phy_addr_show(struct sas_phy *phy, char *buf)
+{
+	if (!phy->enabled)
+		return 0;
+	return sprintf(buf, "%llx\n", SAS_ADDR(phy->sas_addr));
+}
+
+static ssize_t sas_phy_oob_mode_show(struct sas_phy *phy, char *buf)
+{
+	if (!phy->enabled)
+		return 0;
+	return sas_show_oob_mode(phy->oob_mode, buf);
+}
+
+struct phy_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct sas_phy *phy, char *);
+	ssize_t (*store)(struct sas_phy *phy, const char *, size_t);
+};
+
+static struct phy_attribute phy_attrs[] = {
+	/* port is a symlink */
+	__ATTR(id, 0444, sas_phy_id_show, NULL),
+	__ATTR(enabled, 0644, sas_phy_enabled_show, sas_phy_enabled_store),
+	__ATTR(class, 0444, sas_phy_class_show, NULL),
+	__ATTR(iproto, 0444, sas_phy_iproto_show, NULL),
+	__ATTR(tproto, 0444, sas_phy_tproto_show, NULL),
+	__ATTR(type, 0444, sas_phy_type_show, NULL),
+	__ATTR(role, 0444, sas_phy_role_show, NULL),
+	__ATTR(linkrate, 0444, sas_phy_linkrate_show, NULL),
+	__ATTR(sas_addr, 0444, sas_phy_addr_show, NULL),
+	__ATTR(oob_mode, 0444, sas_phy_oob_mode_show, NULL),
+	__ATTR_NULL,
+};
+
+static struct attribute *def_attrs[ARRAY_SIZE(phy_attrs)];
+
+#define to_sas_phy(_obj) container_of(_obj, struct sas_phy, phy_kobj)
+#define to_phy_attr(_attr) container_of(_attr, struct phy_attribute, attr)
+
+static ssize_t phy_show_attr(struct kobject *kobj,
+			     struct attribute *attr,
+			     char *page)
+{
+	ssize_t ret = 0;
+	struct sas_phy *phy = to_sas_phy(kobj);
+	struct phy_attribute *phy_attr = to_phy_attr(attr);
+
+	if (phy_attr->show)
+		ret = phy_attr->show(phy, page);
+	return ret;
+}
+
+static ssize_t phy_store_attr(struct kobject *kobj,
+			      struct attribute *attr,
+			      const char *page, size_t size)
+{
+	ssize_t ret = 0;
+	struct sas_phy *phy = to_sas_phy(kobj);
+	struct phy_attribute *phy_attr = to_phy_attr(attr);
+	
+	if (phy_attr->store)
+		ret = phy_attr->store(phy, page, size);
+	return ret;
+}
+
+static struct sysfs_ops phy_sysfs_ops = {
+	.show = phy_show_attr,
+	.store = phy_store_attr,
+};
+
+static struct kobj_type phy_ktype = {
+	.sysfs_ops = &phy_sysfs_ops,
+	.default_attrs = def_attrs,
+};
+
+/* ---------- Phy class registration ---------- */
+
+int sas_register_phys(struct sas_ha_struct *sas_ha)
+{
+	int i, error;
+
+	for (i = 0; i < ARRAY_SIZE(def_attrs)-1; i++)
+		def_attrs[i] = &phy_attrs[i].attr;
+	def_attrs[i] = NULL;		
+	
+	/* make sas/ha/phys/ appear */
+	kobject_set_name(&sas_ha->phy_kset.kobj, "%s", "phys");
+	sas_ha->phy_kset.kobj.kset = &sas_ha->ha_kset; /* parent */
+	/* we do not inherit the type of the parent */
+	sas_ha->phy_kset.kobj.ktype = NULL;
+	sas_ha->phy_kset.ktype = &phy_ktype;
+	error = kset_register(&sas_ha->phy_kset);
+	if (error)
+		return error;
+
+	/* Now register the phys. */
+	for (i = 0; i < sas_ha->num_phys; i++) {
+		int k;
+		struct sas_phy *phy = sas_ha->sas_phy[i];
+
+		phy->error = 0;
+		INIT_LIST_HEAD(&phy->port_phy_el);
+		INIT_LIST_HEAD(&phy->port_event_list);
+		INIT_LIST_HEAD(&phy->phy_event_list);
+		for (k = 0; k < PORT_NUM_EVENTS; k++) {
+			struct sas_event *ev = &phy->port_events[k];
+			ev->event = k;
+			INIT_LIST_HEAD(&ev->el);
+		}
+		for (k = 0; k < PHY_NUM_EVENTS; k++) {
+			struct sas_event *ev = &phy->phy_events[k];
+			ev->event = k;
+			INIT_LIST_HEAD(&ev->el);
+		}
+		phy->port = NULL;
+		phy->ha = sas_ha;
+		spin_lock_init(&phy->frame_rcvd_lock);
+		spin_lock_init(&phy->sas_prim_lock);
+		phy->frame_rcvd_size = 0;
+
+		kobject_set_name(&phy->phy_kobj, "%d", i);
+		phy->phy_kobj.kset = &sas_ha->phy_kset; /* parent */
+		phy->phy_kobj.ktype = sas_ha->phy_kset.ktype;
+		error = kobject_register(&phy->phy_kobj);
+		if (error)
+			goto unroll;
+	}
+	
+	return 0;
+unroll:
+	for (i--; i >= 0; i--)
+		kobject_unregister(&sas_ha->sas_phy[i]->phy_kobj);
+
+	return error;
+}
+
+void sas_unregister_phys(struct sas_ha_struct *sas_ha)
+{
+	int i;
+
+	for (i = 0; i < sas_ha->num_phys; i++)
+		kobject_unregister(&sas_ha->sas_phy[i]->phy_kobj);
+	
+	kset_unregister(&sas_ha->phy_kset);
+}

                 reply	other threads:[~2005-09-09 19:41 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=4321E582.9020401@adaptec.com \
    --to=luben_tuikov@adaptec.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.