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);
}
next prev parent 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