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