summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2009-09-04 14:27:24 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2009-09-04 14:27:24 +1000
commita7cfd87dfcc41df62e1af1d47faa911e5b212f76 (patch)
tree7231ab3eea439b379fe703716c759a8e5fd4a4ae /drivers
parentb3e8b13b2c8396ee06155cc22bf83f6761109352 (diff)
parentba3690fca034aedc73ed4ed63bd93f0769e683ef (diff)
Merge commit 'osd/linux-next'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/osd/osd_initiator.c22
-rw-r--r--drivers/scsi/osd/osd_uld.c53
2 files changed, 68 insertions, 7 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 7a117c18114c..26e1b414a118 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -73,7 +73,8 @@ static const char *_osd_ver_desc(struct osd_request *or)
#define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
-static int _osd_print_system_info(struct osd_dev *od, void *caps)
+static int _osd_get_print_system_info(struct osd_dev *od,
+ void *caps, struct osd_dev_info *odi)
{
struct osd_request *or;
struct osd_attr get_attrs[] = {
@@ -137,8 +138,13 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps)
OSD_INFO("PRODUCT_SERIAL_NUMBER [%s]\n",
(char *)pFirst);
- pFirst = get_attrs[a].val_ptr;
- OSD_INFO("OSD_NAME [%s]\n", (char *)pFirst);
+ odi->osdname_len = get_attrs[a].len;
+ if (odi->osdname_len) {
+ odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL);
+ memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len);
+ } else
+ odi->osdname = NULL;
+ OSD_INFO("OSD_NAME [%s]\n", odi->osdname);
a++;
pFirst = get_attrs[a++].val_ptr;
@@ -171,6 +177,9 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps)
sid_dump, sizeof(sid_dump), true);
OSD_INFO("OSD_SYSTEM_ID(%d)\n"
" [%s]\n", len, sid_dump);
+
+ odi->systemid_len = len;
+ memcpy(odi->systemid, get_attrs[a].val_ptr, len);
a++;
}
out:
@@ -178,16 +187,17 @@ out:
return ret;
}
-int osd_auto_detect_ver(struct osd_dev *od, void *caps)
+int osd_auto_detect_ver(struct osd_dev *od,
+ void *caps, struct osd_dev_info *odi)
{
int ret;
/* Auto-detect the osd version */
- ret = _osd_print_system_info(od, caps);
+ ret = _osd_get_print_system_info(od, caps, odi);
if (ret) {
osd_dev_set_ver(od, OSD_VER1);
OSD_DEBUG("converting to OSD1\n");
- ret = _osd_print_system_info(od, caps);
+ ret = _osd_get_print_system_info(od, caps, odi);
}
return ret;
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index 0bdef3390902..8c069f961fb3 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -87,6 +87,7 @@ struct osd_uld_device {
struct osd_dev od;
struct gendisk *disk;
struct device *class_member;
+ struct osd_dev_info odi;
};
static void __uld_get(struct osd_uld_device *oud);
@@ -216,6 +217,48 @@ free_od:
}
EXPORT_SYMBOL(osduld_path_lookup);
+static inline bool _the_same_or_null(const u8 *a1, unsigned a1_len,
+ const u8 *a2, unsigned a2_len)
+{
+ if (!a2_len) /* User string is Empty means don't care */
+ return true;
+
+ if (a1_len != a2_len)
+ return false;
+
+ return 0 == memcmp(a1, a2, a1_len);
+}
+
+struct osd_dev *osduld_info_lookup(const struct osd_dev_info *odi)
+{
+ unsigned i;
+
+ for (i = 0; i < SCSI_OSD_MAX_MINOR; i++) {
+ char dev_str[16];
+ struct osd_uld_device *oud;
+ struct osd_dev *od;
+
+ sprintf(dev_str, "/dev/osd%d", i);
+ od = osduld_path_lookup(dev_str);
+ if (IS_ERR(od))
+ continue;
+
+ oud = od->file->private_data;
+ if (_the_same_or_null(oud->odi.systemid, oud->odi.systemid_len,
+ odi->systemid, odi->systemid_len) &&
+ _the_same_or_null(oud->odi.osdname, oud->odi.osdname_len,
+ odi->osdname, odi->osdname_len)) {
+ OSD_DEBUG("found device sysid_len=%d osdname=%d\n",
+ odi->systemid_len, odi->osdname_len);
+ return od;
+ }
+ osduld_put_device(od);
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL(osduld_info_lookup);
+
void osduld_put_device(struct osd_dev *od)
{
@@ -230,6 +273,13 @@ void osduld_put_device(struct osd_dev *od)
}
EXPORT_SYMBOL(osduld_put_device);
+const struct osd_dev_info *osduld_device_info(struct osd_dev *od)
+{
+ struct osd_uld_device *oud = od->file->private_data;
+ return &oud->odi;
+}
+EXPORT_SYMBOL(osduld_device_info);
+
/*
* Scsi Device operations
*/
@@ -250,7 +300,7 @@ static int __detect_osd(struct osd_uld_device *oud)
OSD_ERR("warning: scsi_test_unit_ready failed\n");
osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
- if (osd_auto_detect_ver(&oud->od, caps))
+ if (osd_auto_detect_ver(&oud->od, caps, &oud->odi))
return -ENODEV;
return 0;
@@ -402,6 +452,7 @@ static void __remove(struct kref *kref)
put_disk(oud->disk);
ida_remove(&osd_minor_ida, oud->minor);
+ kfree(oud->odi.osdname);
kfree(oud);
}