aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/osd/osd_initiator.c125
-rw-r--r--drivers/scsi/osd/osd_uld.c5
-rw-r--r--include/scsi/osd_initiator.h3
3 files changed, 133 insertions, 0 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 86a76cccfebd..f6340c2ceb25 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -41,6 +41,7 @@
41 41
42#include <scsi/osd_initiator.h> 42#include <scsi/osd_initiator.h>
43#include <scsi/osd_sec.h> 43#include <scsi/osd_sec.h>
44#include <scsi/osd_attributes.h>
44#include <scsi/scsi_device.h> 45#include <scsi/scsi_device.h>
45 46
46#include "osd_debug.h" 47#include "osd_debug.h"
@@ -63,6 +64,130 @@ static inline void build_test(void)
63 BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); 64 BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
64} 65}
65 66
67static const char *_osd_ver_desc(struct osd_request *or)
68{
69 return osd_req_is_ver1(or) ? "OSD1" : "OSD2";
70}
71
72#define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
73
74static int _osd_print_system_info(struct osd_dev *od, void *caps)
75{
76 struct osd_request *or;
77 struct osd_attr get_attrs[] = {
78 ATTR_DEF_RI(OSD_ATTR_RI_VENDOR_IDENTIFICATION, 8),
79 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_IDENTIFICATION, 16),
80 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_MODEL, 32),
81 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_REVISION_LEVEL, 4),
82 ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER, 64 /*variable*/),
83 ATTR_DEF_RI(OSD_ATTR_RI_OSD_NAME, 64 /*variable*/),
84 ATTR_DEF_RI(OSD_ATTR_RI_TOTAL_CAPACITY, 8),
85 ATTR_DEF_RI(OSD_ATTR_RI_USED_CAPACITY, 8),
86 ATTR_DEF_RI(OSD_ATTR_RI_NUMBER_OF_PARTITIONS, 8),
87 ATTR_DEF_RI(OSD_ATTR_RI_CLOCK, 6),
88 /* IBM-OSD-SIM Has a bug with this one put it last */
89 ATTR_DEF_RI(OSD_ATTR_RI_OSD_SYSTEM_ID, 20),
90 };
91 void *iter = NULL, *pFirst;
92 int nelem = ARRAY_SIZE(get_attrs), a = 0;
93 int ret;
94
95 or = osd_start_request(od, GFP_KERNEL);
96 if (!or)
97 return -ENOMEM;
98
99 /* get attrs */
100 osd_req_get_attributes(or, &osd_root_object);
101 osd_req_add_get_attr_list(or, get_attrs, ARRAY_SIZE(get_attrs));
102
103 ret = osd_finalize_request(or, 0, caps, NULL);
104 if (ret)
105 goto out;
106
107 ret = osd_execute_request(or);
108 if (ret) {
109 OSD_ERR("Failed to detect %s => %d\n", _osd_ver_desc(or), ret);
110 goto out;
111 }
112
113 osd_req_decode_get_attr_list(or, get_attrs, &nelem, &iter);
114
115 OSD_INFO("Detected %s device\n",
116 _osd_ver_desc(or));
117
118 pFirst = get_attrs[a++].val_ptr;
119 OSD_INFO("OSD_ATTR_RI_VENDOR_IDENTIFICATION [%s]\n",
120 (char *)pFirst);
121
122 pFirst = get_attrs[a++].val_ptr;
123 OSD_INFO("OSD_ATTR_RI_PRODUCT_IDENTIFICATION [%s]\n",
124 (char *)pFirst);
125
126 pFirst = get_attrs[a++].val_ptr;
127 OSD_INFO("OSD_ATTR_RI_PRODUCT_MODEL [%s]\n",
128 (char *)pFirst);
129
130 pFirst = get_attrs[a++].val_ptr;
131 OSD_INFO("OSD_ATTR_RI_PRODUCT_REVISION_LEVEL [%u]\n",
132 get_unaligned_be32(pFirst));
133
134 pFirst = get_attrs[a++].val_ptr;
135 OSD_INFO("OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER [%s]\n",
136 (char *)pFirst);
137
138 pFirst = get_attrs[a].val_ptr;
139 OSD_INFO("OSD_ATTR_RI_OSD_NAME [%s]\n", (char *)pFirst);
140 a++;
141
142 pFirst = get_attrs[a++].val_ptr;
143 OSD_INFO("OSD_ATTR_RI_TOTAL_CAPACITY [0x%llx]\n",
144 _LLU(get_unaligned_be64(pFirst)));
145
146 pFirst = get_attrs[a++].val_ptr;
147 OSD_INFO("OSD_ATTR_RI_USED_CAPACITY [0x%llx]\n",
148 _LLU(get_unaligned_be64(pFirst)));
149
150 pFirst = get_attrs[a++].val_ptr;
151 OSD_INFO("OSD_ATTR_RI_NUMBER_OF_PARTITIONS [%llu]\n",
152 _LLU(get_unaligned_be64(pFirst)));
153
154 /* FIXME: Where are the time utilities */
155 pFirst = get_attrs[a++].val_ptr;
156 OSD_INFO("OSD_ATTR_RI_CLOCK [0x%02x%02x%02x%02x%02x%02x]\n",
157 ((char *)pFirst)[0], ((char *)pFirst)[1],
158 ((char *)pFirst)[2], ((char *)pFirst)[3],
159 ((char *)pFirst)[4], ((char *)pFirst)[5]);
160
161 if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */
162 unsigned len = get_attrs[a].len;
163 char sid_dump[32*4 + 2]; /* 2nibbles+space+ASCII */
164
165 hex_dump_to_buffer(get_attrs[a].val_ptr, len, 32, 1,
166 sid_dump, sizeof(sid_dump), true);
167 OSD_INFO("OSD_ATTR_RI_OSD_SYSTEM_ID(%d) [%s]\n", len, sid_dump);
168 a++;
169 }
170out:
171 osd_end_request(or);
172 return ret;
173}
174
175int osd_auto_detect_ver(struct osd_dev *od, void *caps)
176{
177 int ret;
178
179 /* Auto-detect the osd version */
180 ret = _osd_print_system_info(od, caps);
181 if (ret) {
182 osd_dev_set_ver(od, OSD_VER1);
183 OSD_DEBUG("converting to OSD1\n");
184 ret = _osd_print_system_info(od, caps);
185 }
186
187 return ret;
188}
189EXPORT_SYMBOL(osd_auto_detect_ver);
190
66static unsigned _osd_req_cdb_len(struct osd_request *or) 191static unsigned _osd_req_cdb_len(struct osd_request *or)
67{ 192{
68 return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN; 193 return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN;
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index cd4ca7cd9f75..f8b1a749958b 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -243,6 +243,7 @@ EXPORT_SYMBOL(osduld_put_device);
243static int __detect_osd(struct osd_uld_device *oud) 243static int __detect_osd(struct osd_uld_device *oud)
244{ 244{
245 struct scsi_device *scsi_device = oud->od.scsi_device; 245 struct scsi_device *scsi_device = oud->od.scsi_device;
246 char caps[OSD_CAP_LEN];
246 int error; 247 int error;
247 248
248 /* sending a test_unit_ready as first command seems to be needed 249 /* sending a test_unit_ready as first command seems to be needed
@@ -254,6 +255,10 @@ static int __detect_osd(struct osd_uld_device *oud)
254 if (error) 255 if (error)
255 OSD_ERR("warning: scsi_test_unit_ready failed\n"); 256 OSD_ERR("warning: scsi_test_unit_ready failed\n");
256 257
258 osd_sec_init_nosec_doall_caps(caps, &osd_root_object, false, true);
259 if (osd_auto_detect_ver(&oud->od, caps))
260 return -ENODEV;
261
257 return 0; 262 return 0;
258} 263}
259 264
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
index 8482777416d8..24edeae48936 100644
--- a/include/scsi/osd_initiator.h
+++ b/include/scsi/osd_initiator.h
@@ -67,6 +67,9 @@ void osduld_unregister_test(unsigned ioctl);
67void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); 67void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
68void osd_dev_fini(struct osd_dev *od); 68void osd_dev_fini(struct osd_dev *od);
69 69
70/* some hi level device operations */
71int osd_auto_detect_ver(struct osd_dev *od, void *caps); /* GFP_KERNEL */
72
70/* we might want to use function vector in the future */ 73/* we might want to use function vector in the future */
71static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) 74static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v)
72{ 75{