diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-09-04 14:27:24 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-09-04 14:27:24 +1000 |
commit | a7cfd87dfcc41df62e1af1d47faa911e5b212f76 (patch) | |
tree | 7231ab3eea439b379fe703716c759a8e5fd4a4ae /drivers | |
parent | b3e8b13b2c8396ee06155cc22bf83f6761109352 (diff) | |
parent | ba3690fca034aedc73ed4ed63bd93f0769e683ef (diff) |
Merge commit 'osd/linux-next'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/osd/osd_initiator.c | 22 | ||||
-rw-r--r-- | drivers/scsi/osd/osd_uld.c | 53 |
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); } |