diff options
-rw-r--r-- | drivers/scsi/osd/osd_initiator.c | 125 | ||||
-rw-r--r-- | drivers/scsi/osd/osd_uld.c | 5 | ||||
-rw-r--r-- | include/scsi/osd_initiator.h | 3 |
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 | ||
67 | static 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 | |||
74 | static 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 | } | ||
170 | out: | ||
171 | osd_end_request(or); | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | int 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 | } | ||
189 | EXPORT_SYMBOL(osd_auto_detect_ver); | ||
190 | |||
66 | static unsigned _osd_req_cdb_len(struct osd_request *or) | 191 | static 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); | |||
243 | static int __detect_osd(struct osd_uld_device *oud) | 243 | static 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); | |||
67 | void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); | 67 | void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); |
68 | void osd_dev_fini(struct osd_dev *od); | 68 | void osd_dev_fini(struct osd_dev *od); |
69 | 69 | ||
70 | /* some hi level device operations */ | ||
71 | int 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 */ |
71 | static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) | 74 | static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) |
72 | { | 75 | { |