public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Chandra Seetharaman <sekharan@us.ibm.com>
To: linux-scsi@vger.kernel.org
Cc: Chandra Seetharaman <sekharan@us.ibm.com>,
	pjones@redhat.com, michaelc@cs.wisc.edu,
	James.Bottomley@HansenPartnership.com
Subject: [PATCH 1/3] scsi_dh: Add modalias support for SCSI targets
Date: Tue, 17 Mar 2009 18:36:21 -0700	[thread overview]
Message-ID: <20090318013621.26548.10529.sendpatchset@chandra-ubuntu> (raw)
In-Reply-To: <20090318013615.26548.36303.sendpatchset@chandra-ubuntu>

From: Peter Jones <pjones@redhat.com>

This patch allows the use of modaliases on scsi targets to correctly
load scsi device handler modules when the devices are found.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>

---
 drivers/scsi/scsi_sysfs.c       |   55 +++++++++++++++++++++++++++++++++++++++-
 include/linux/mod_devicetable.h |    6 ++++
 include/linux/string_helpers.h  |    2 +
 include/scsi/scsi.h             |    1 +
 include/scsi/scsi_device.h      |    9 +-----
 lib/string_helpers.c            |   32 +++++++++++++++++++++++
 scripts/mod/file2alias.c        |   38 ++++++++++++++++++++++++++++
 7 files changed, 134 insertions(+), 9 deletions(-)

Index: linux-2.6.28/drivers/scsi/scsi_sysfs.c
===================================================================
--- linux-2.6.28.orig/drivers/scsi/scsi_sysfs.c
+++ linux-2.6.28/drivers/scsi/scsi_sysfs.c
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/device.h>
+#include <linux/string_helpers.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -362,16 +363,63 @@ static int scsi_bus_match(struct device 
 	return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
 }
 
+static ssize_t format_scsi_modalias(struct scsi_device *sdev, char *buffer,
+				    ssize_t len)
+{
+	char vendor[9];
+	char *hex_vendor;
+	char model[17];
+	char *hex_model;
+	int i;
+
+	strncpy(vendor, sdev->vendor, 8);
+	vendor[8] = '\0';
+	for (i = strlen(vendor) - 1; i >= 0; i--) {
+		if (vendor[i] != ' ')
+			break;
+		vendor[i] = '\0';
+	}
+	hex_vendor = string_to_hex(vendor);
+	if (!hex_vendor)
+		return -ENOMEM;
+
+	strncpy(model, sdev->model, 16);
+	model[8] = '\0';
+	for (i = strlen(model) - 1; i >= 0; i--) {
+		if (model[i] != ' ')
+			break;
+		model[i] = '\0';
+	}
+	hex_model = string_to_hex(model);
+	if (!hex_model) {
+		kfree(hex_vendor);
+		return -ENOMEM;
+	}
+
+	i = snprintf(buffer, len, "scsi:t-0x%02xv%.16sm%.32s", sdev->type,
+		 hex_vendor, hex_model);
+	kfree(hex_vendor);
+	kfree(hex_model);
+	return i;
+}
+
 static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct scsi_device *sdev;
+	char buffer[501];
+	int rc;
 
 	if (dev->type != &scsi_dev_type)
 		return 0;
 
 	sdev = to_scsi_device(dev);
 
-	add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
+	buffer[500] = '\0';
+	rc = format_scsi_modalias(sdev, buffer, 500);
+	if (rc < 0)
+		return rc;
+
+	add_uevent_var(env, "MODALIAS=%s", buffer);
 	return 0;
 }
 
@@ -697,8 +745,11 @@ static ssize_t
 sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev;
+	ssize_t rc;
+
 	sdev = to_scsi_device(dev);
-	return snprintf (buf, 20, SCSI_DEVICE_MODALIAS_FMT "\n", sdev->type);
+	rc = format_scsi_modalias(sdev, buf, 500);
+	return rc;
 }
 static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL);
 
Index: linux-2.6.28/include/linux/mod_devicetable.h
===================================================================
--- linux-2.6.28.orig/include/linux/mod_devicetable.h
+++ linux-2.6.28/include/linux/mod_devicetable.h
@@ -454,4 +454,10 @@ struct dmi_system_id {
 
 #define DMI_MATCH(a, b)	{ a, b }
 
+struct scsi_dh_device_id {
+	unsigned char type;
+	char vendor[9];
+	char model[17];
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
Index: linux-2.6.28/include/linux/string_helpers.h
===================================================================
--- linux-2.6.28.orig/include/linux/string_helpers.h
+++ linux-2.6.28/include/linux/string_helpers.h
@@ -13,4 +13,6 @@ enum string_size_units {
 int string_get_size(u64 size, enum string_size_units units,
 		    char *buf, int len);
 
+unsigned char *string_to_hex(const unsigned char *s);
+
 #endif
Index: linux-2.6.28/include/scsi/scsi.h
===================================================================
--- linux-2.6.28.orig/include/scsi/scsi.h
+++ linux-2.6.28/include/scsi/scsi.h
@@ -264,6 +264,7 @@ static inline int scsi_status_is_good(in
 #define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
 #define TYPE_RBC	    0x0e
 #define TYPE_NO_LUN         0x7f
+#define TYPE_ANY	    0xff
 
 /* SCSI protocols; these are taken from SPC-3 section 7.5 */
 enum scsi_protocol {
Index: linux-2.6.28/include/scsi/scsi_device.h
===================================================================
--- linux-2.6.28.orig/include/scsi/scsi_device.h
+++ linux-2.6.28/include/scsi/scsi_device.h
@@ -1,6 +1,7 @@
 #ifndef _SCSI_SCSI_DEVICE_H
 #define _SCSI_SCSI_DEVICE_H
 
+#include <linux/mod_devicetable.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
@@ -169,11 +170,6 @@ struct scsi_device {
 	unsigned long		sdev_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
 
-struct scsi_dh_devlist {
-	char *vendor;
-	char *model;
-};
-
 struct scsi_device_handler {
 	/* Used by the infrastructure */
 	struct list_head list; /* list of scsi_device_handlers */
@@ -181,7 +177,7 @@ struct scsi_device_handler {
 	/* Filled by the hardware handler */
 	struct module *module;
 	const char *name;
-	const struct scsi_dh_devlist *devlist;
+	const struct scsi_dh_device_id *devlist;
 	int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
 	int (*attach)(struct scsi_device *);
 	void (*detach)(struct scsi_device *);
@@ -456,6 +452,5 @@ static inline int scsi_device_protection
 
 #define MODULE_ALIAS_SCSI_DEVICE(type) \
 	MODULE_ALIAS("scsi:t-" __stringify(type) "*")
-#define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x"
 
 #endif /* _SCSI_SCSI_DEVICE_H */
Index: linux-2.6.28/lib/string_helpers.c
===================================================================
--- linux-2.6.28.orig/lib/string_helpers.c
+++ linux-2.6.28/lib/string_helpers.c
@@ -66,3 +66,35 @@ int string_get_size(u64 size, const enum
 	return 0;
 }
 EXPORT_SYMBOL(string_get_size);
+
+/**
+ * string_to_hex - convert a string to a series of hexidecimal values
+ * @s:	The string to operate on
+ *
+ * This function returns a GFP_KERNEL allocated buffer filled with
+ * the hexidecimal representation of the value of each character in @s .
+ * Returns a pointer to the allocated string on success and NULL on error,
+ * and the returned string is zero terminated.
+ *
+ */
+unsigned char *string_to_hex(const unsigned char *s)
+{
+	unsigned char *ret, *ptr;
+	static const unsigned char *hex = "0123456789ABCDEF";
+	int len;
+
+	len = strlen(s);
+
+	ret = ptr = kmalloc(len * 2 + 1, GFP_KERNEL);
+	if (!ret)
+		return NULL;
+
+	for (; *s; s++) {
+		*ptr++ = hex[(*s & 0xf0)>>4];
+		*ptr++ = hex[*s & 0x0f];
+	}
+	*ptr = '\0';
+
+	return ret;
+}
+EXPORT_SYMBOL(string_to_hex);
Index: linux-2.6.28/scripts/mod/file2alias.c
===================================================================
--- linux-2.6.28.orig/scripts/mod/file2alias.c
+++ linux-2.6.28/scripts/mod/file2alias.c
@@ -51,6 +51,22 @@ do {                                    
                 sprintf(str + strlen(str), "*");                \
 } while(0)
 
+#define ADD_HEX_STR(str, sep, cond, field)				\
+do {									\
+	strcat(str, sep);						\
+	if (cond) {							\
+		char * _s = str + strlen(str);				\
+		char * _f = field;					\
+		static const char *_hex = "0123456789ABCDEF";		\
+									\
+		for (; *_f; _f++) {					\
+			*_s++ = _hex[(*_f & 0xf0)>>4];			\
+			*_s++ = _hex[*_f & 0xf];			\
+		}							\
+	} else								\
+		strcat(str, "*");					\
+} while(0)
+
 /* Always end in a wildcard, for future extension */
 static inline void add_wildcard(char *str)
 {
@@ -710,6 +726,23 @@ static int do_dmi_entry(const char *file
 	strcat(alias, ":");
 	return 1;
 }
+
+/* Looks like: scsi:t-NvSmS */
+/* defining TYPE_ANY here is a gross hack to avoid moving all the scsi.h
+ * TYPE_ definitions into mod_devicetable.h */
+#define TYPE_ANY 0xff
+static int do_scsi_entry(const char *filename,
+			struct scsi_dh_device_id *id, char *alias)
+{
+	strcpy(alias, "scsi:");
+	ADD(alias, "t-", id->type != TYPE_ANY, id->type);
+	ADD_HEX_STR(alias, "v", id->vendor[0] != '\0', id->vendor);
+	ADD_HEX_STR(alias, "m", id->model[0] != '\0', id->model);
+
+	add_wildcard(alias);
+	return 1;
+}
+
 /* Ignore any prefix, eg. some architectures prepend _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -736,6 +769,7 @@ static void do_table(void *symval, unsig
 	size -= id_size;
 
 	for (i = 0; i < size; i += id_size) {
+		memset(alias, '\0', 500);
 		if (do_entry(mod->name, symval+i, alias)) {
 			buf_printf(&mod->dev_table_buf,
 				   "MODULE_ALIAS(\"%s\");\n", alias);
@@ -849,6 +883,10 @@ void handle_moddevtable(struct module *m
 		do_table(symval, sym->st_size,
 			 sizeof(struct dmi_system_id), "dmi",
 			 do_dmi_entry, mod);
+	else if (sym_is(symname, "__mod_scsi_dh_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct scsi_dh_device_id), "scsi",
+			 do_scsi_entry, mod);
 	free(zeros);
 }
 

  reply	other threads:[~2009-03-18  1:33 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-18  1:36 [PATCH 0/3] scsi_dh: Make scsi device handler modules automatically inserted Chandra Seetharaman
2009-03-18  1:36 ` Chandra Seetharaman [this message]
2009-03-18 13:44   ` [PATCH 1/3] scsi_dh: Add modalias support for SCSI targets Konrad Rzeszutek
2009-03-18 14:02     ` James Bottomley
2009-03-18 14:36       ` Konrad Rzeszutek
2009-03-18 18:30   ` Kay Sievers
2009-03-18 19:18     ` Chandra Seetharaman
2009-03-19 18:54       ` Chandra Seetharaman
2009-03-20 18:24         ` Peter Jones
2009-03-23 22:13           ` Chandra Seetharaman
2009-04-03 22:43             ` Chandra Seetharaman
2009-04-07 20:59               ` James Bottomley
2009-04-07 23:41                 ` Chandra Seetharaman
2009-04-08 15:08                 ` Peter Jones
2009-04-15 21:52                   ` Chandra Seetharaman
2009-04-16 15:18                     ` Hannes Reinecke
2009-04-07 23:22               ` Hannes Reinecke
2009-04-07 23:50                 ` Chandra Seetharaman
2009-04-08  5:15                   ` Kay Sievers
2009-04-08 19:13                     ` Chandra Seetharaman
2009-03-18 18:47   ` James Bottomley
2009-03-18 19:12     ` Chandra Seetharaman
2009-03-18 20:09       ` James Bottomley
2009-03-18 20:24         ` Kay Sievers
2009-03-18 20:26           ` James Bottomley
2009-03-18 20:59         ` Chandra Seetharaman
2009-03-20 17:41         ` Peter Jones
2009-03-18  1:36 ` [PATCH 2/3] scsi_dh: Change scsi device handler modules to utilize modalias Chandra Seetharaman
2009-03-18 13:46   ` Konrad Rzeszutek
2009-03-18 15:43     ` Stefan Richter
2009-03-18 17:25       ` Chandra Seetharaman
2009-03-18 17:50         ` Stefan Richter
2009-03-18 18:18           ` Kay Sievers
2009-03-18 19:44             ` Stefan Richter
2009-03-18 18:50           ` Chandra Seetharaman
2009-03-18 19:46             ` Stefan Richter
2009-03-18  1:36 ` [PATCH 3/3] scsi_dh: Workaround a race condition in module insertion Chandra Seetharaman
2009-03-18 11:31 ` [PATCH 0/3] scsi_dh: Make scsi device handler modules automatically inserted Hannes Reinecke
  -- strict thread matches above, loose matches on Subject: below --
2009-04-27 18:06 Chandra Seetharaman
2009-04-27 18:06 ` [PATCH 1/3] scsi_dh: Add modalias support for SCSI targets Chandra Seetharaman

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=20090318013621.26548.10529.sendpatchset@chandra-ubuntu \
    --to=sekharan@us.ibm.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=michaelc@cs.wisc.edu \
    --cc=pjones@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