Print this page
4233 mptsas topo change buffer overflow
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_smhba.c
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_smhba.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 25 */
25 26 /*
26 27 * This file contains SM-HBA support for MPT SAS driver
27 28 */
28 29
29 30 #if defined(lint) || defined(DEBUG)
30 31 #define MPTSAS_DEBUG
31 32 #endif
32 33
33 34 /*
34 35 * standard header files
35 36 */
36 37 #include <sys/note.h>
37 38 #include <sys/scsi/scsi.h>
38 39 #include <sys/pci.h>
39 40 #include <sys/scsi/generic/sas.h>
40 41 #include <sys/scsi/impl/scsi_sas.h>
41 42
42 43 #pragma pack(1)
43 44 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
44 45 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
45 46 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
46 47 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
47 48 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
48 49 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
49 50 #pragma pack()
50 51
51 52 /*
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
52 53 * private header files.
53 54 */
54 55 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
55 56 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
56 57
57 58 /*
58 59 * SM - HBA statics
59 60 */
60 61 extern char *mptsas_driver_rev;
61 62
63 +static void mptsas_smhba_create_phy_props(nvlist_t **, smhba_info_t *, uint8_t,
64 + uint16_t *);
65 +static void mptsas_smhba_update_phy_props(mptsas_t *, dev_info_t *, nvlist_t **,
66 + uint8_t);
67 +
62 68 static void
63 69 mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
64 70 char *prop_name, void *prop_val);
65 71
66 72 void
67 73 mptsas_smhba_show_phy_info(mptsas_t *mpt);
68 74
69 75 static void
70 76 mptsas_smhba_add_hba_prop(mptsas_t *mpt, data_type_t dt,
71 77 char *prop_name, void *prop_val)
72 78 {
73 79 ASSERT(mpt != NULL);
74 80
75 81 switch (dt) {
76 82 case DATA_TYPE_INT32:
77 83 if (ddi_prop_update_int(DDI_DEV_T_NONE, mpt->m_dip,
78 84 prop_name, *(int *)prop_val)) {
79 85 mptsas_log(mpt, CE_WARN,
80 86 "%s: %s prop update failed", __func__, prop_name);
81 87 }
82 88 break;
83 89 case DATA_TYPE_STRING:
84 90 if (ddi_prop_update_string(DDI_DEV_T_NONE, mpt->m_dip,
85 91 prop_name, (char *)prop_val)) {
86 92 mptsas_log(mpt, CE_WARN,
87 93 "%s: %s prop update failed", __func__, prop_name);
88 94 }
89 95 break;
90 96 default:
91 97 mptsas_log(mpt, CE_WARN, "%s: "
92 98 "Unhandled datatype(%d) for (%s). Skipping prop update.",
93 99 __func__, dt, prop_name);
94 100 }
95 101 }
96 102
97 103 void
98 104 mptsas_smhba_show_phy_info(mptsas_t *mpt)
99 105 {
100 106 int i;
101 107
102 108 ASSERT(mpt != NULL);
103 109
104 110 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
105 111 mptsas_log(mpt, CE_WARN,
106 112 "phy %d, Owner hdl:0x%x, attached hdl: 0x%x,"
107 113 "attached phy identifier %d,Program link rate 0x%x,"
108 114 "hw link rate 0x%x, negotiator link rate 0x%x, path %s",
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
109 115 i, mpt->m_phy_info[i].smhba_info.owner_devhdl,
110 116 mpt->m_phy_info[i].smhba_info.attached_devhdl,
111 117 mpt->m_phy_info[i].smhba_info.attached_phy_identify,
112 118 mpt->m_phy_info[i].smhba_info.programmed_link_rate,
113 119 mpt->m_phy_info[i].smhba_info.hw_link_rate,
114 120 mpt->m_phy_info[i].smhba_info.negotiated_link_rate,
115 121 mpt->m_phy_info[i].smhba_info.path);
116 122 }
117 123 }
118 124
119 -void
120 -mptsas_smhba_set_phy_props(mptsas_t *mpt, char *iport, dev_info_t *dip,
121 - uint8_t phy_nums, uint16_t *attached_devhdl)
125 +static void
126 +mptsas_smhba_create_phy_props(nvlist_t **phy_props, smhba_info_t *pSmhba,
127 + uint8_t phy_id, uint16_t *attached_devhdl)
122 128 {
123 - int i;
124 - int j = 0;
129 + (void) nvlist_alloc(phy_props, NV_UNIQUE_NAME, KM_SLEEP);
130 + (void) nvlist_add_uint8(*phy_props, SAS_PHY_ID, phy_id);
131 + (void) nvlist_add_uint8(*phy_props, "phyState",
132 + (pSmhba->negotiated_link_rate & 0x0f));
133 + (void) nvlist_add_int8(*phy_props, SAS_NEG_LINK_RATE,
134 + (pSmhba->negotiated_link_rate & 0x0f));
135 + (void) nvlist_add_int8(*phy_props, SAS_PROG_MIN_LINK_RATE,
136 + (pSmhba->programmed_link_rate & 0x0f));
137 + (void) nvlist_add_int8(*phy_props, SAS_HW_MIN_LINK_RATE,
138 + (pSmhba->hw_link_rate & 0x0f));
139 + (void) nvlist_add_int8(*phy_props, SAS_PROG_MAX_LINK_RATE,
140 + ((pSmhba->programmed_link_rate & 0xf0) >> 4));
141 + (void) nvlist_add_int8(*phy_props, SAS_HW_MAX_LINK_RATE,
142 + ((pSmhba->hw_link_rate & 0xf0) >> 4));
143 +
144 + if (pSmhba->attached_devhdl && (attached_devhdl != NULL))
145 + *attached_devhdl = pSmhba->attached_devhdl;
146 +}
147 +
148 +static void
149 +mptsas_smhba_update_phy_props(mptsas_t *mpt, dev_info_t *dip,
150 + nvlist_t **phy_props, uint8_t phy_nums)
151 +{
125 152 int rval;
126 153 size_t packed_size;
127 154 char *packed_data = NULL;
128 - char phymask[MPTSAS_MAX_PHYS];
129 - nvlist_t **phy_props;
130 155 nvlist_t *nvl;
131 - smhba_info_t *pSmhba = NULL;
132 156
133 - if (phy_nums == 0) {
157 + if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) != 0) {
158 + mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__);
134 159 return;
135 160 }
136 - if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
137 - mptsas_log(mpt, CE_WARN, "%s: nvlist_alloc() failed", __func__);
138 - }
139 161
140 - phy_props = kmem_zalloc(sizeof (nvlist_t *) * phy_nums,
141 - KM_SLEEP);
142 -
143 - for (i = 0; i < mpt->m_num_phys; i++) {
144 -
145 - bzero(phymask, sizeof (phymask));
146 - (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
147 - if (strcmp(phymask, iport) == 0) {
148 - pSmhba = &mpt->m_phy_info[i].smhba_info;
149 - (void) nvlist_alloc(&phy_props[j], NV_UNIQUE_NAME, 0);
150 - (void) nvlist_add_uint8(phy_props[j], SAS_PHY_ID, i);
151 - (void) nvlist_add_uint8(phy_props[j],
152 - "phyState",
153 - (pSmhba->negotiated_link_rate
154 - & 0x0f));
155 - (void) nvlist_add_int8(phy_props[j],
156 - SAS_NEG_LINK_RATE,
157 - (pSmhba->negotiated_link_rate
158 - & 0x0f));
159 - (void) nvlist_add_int8(phy_props[j],
160 - SAS_PROG_MIN_LINK_RATE,
161 - (pSmhba->programmed_link_rate
162 - & 0x0f));
163 - (void) nvlist_add_int8(phy_props[j],
164 - SAS_HW_MIN_LINK_RATE,
165 - (pSmhba->hw_link_rate
166 - & 0x0f));
167 - (void) nvlist_add_int8(phy_props[j],
168 - SAS_PROG_MAX_LINK_RATE,
169 - ((pSmhba->programmed_link_rate
170 - & 0xf0) >> 4));
171 - (void) nvlist_add_int8(phy_props[j],
172 - SAS_HW_MAX_LINK_RATE,
173 - ((pSmhba->hw_link_rate
174 - & 0xf0) >> 4));
175 -
176 - j++;
177 -
178 - if (pSmhba->attached_devhdl &&
179 - (attached_devhdl != NULL)) {
180 - *attached_devhdl =
181 - pSmhba->attached_devhdl;
182 - }
183 - }
184 - }
185 -
186 162 rval = nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props,
187 163 phy_nums);
188 164 if (rval) {
189 165 mptsas_log(mpt, CE_WARN,
190 - " nv list array add failed, return value %d.",
191 - rval);
166 + " nv list array add failed, return value %d.", rval);
192 167 goto exit;
193 168 }
194 169 (void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE);
195 170 packed_data = kmem_zalloc(packed_size, KM_SLEEP);
196 171 (void) nvlist_pack(nvl, &packed_data, &packed_size,
197 172 NV_ENCODE_NATIVE, 0);
198 173
199 174 (void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, dip,
200 175 SAS_PHY_INFO, (uchar_t *)packed_data, packed_size);
201 176
202 177 exit:
203 - for (i = 0; i < phy_nums && phy_props[i] != NULL; i++) {
204 - nvlist_free(phy_props[i]);
205 - }
206 178 nvlist_free(nvl);
207 - kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums);
208 179
209 180 if (packed_data != NULL) {
210 181 kmem_free(packed_data, packed_size);
211 182 }
212 183 }
213 184
185 +void
186 +mptsas_smhba_set_one_phy_props(mptsas_t *mpt, dev_info_t *dip, uint8_t phy_id,
187 + uint16_t *attached_devhdl)
188 +{
189 + nvlist_t *phy_props;
190 +
191 + ASSERT(phy_id < mpt->m_num_phys);
192 +
193 + mptsas_smhba_create_phy_props(&phy_props,
194 + &mpt->m_phy_info[phy_id].smhba_info, phy_id, attached_devhdl);
195 +
196 + mptsas_smhba_update_phy_props(mpt, dip, &phy_props, 1);
197 +
198 + nvlist_free(phy_props);
199 +}
200 +
201 +void
202 +mptsas_smhba_set_all_phy_props(mptsas_t *mpt, dev_info_t *dip, uint8_t phy_nums,
203 + mptsas_phymask_t phy_mask, uint16_t *attached_devhdl)
204 +{
205 + int i, j;
206 + nvlist_t **phy_props;
207 +
208 + if (phy_nums == 0)
209 + return;
210 +
211 + phy_props = kmem_zalloc(sizeof (nvlist_t *) * phy_nums, KM_SLEEP);
212 +
213 + for (i = 0, j = 0; i < mpt->m_num_phys && j < phy_nums; i++)
214 + if (phy_mask == mpt->m_phy_info[i].phy_mask)
215 + mptsas_smhba_create_phy_props(&phy_props[j++],
216 + &mpt->m_phy_info[i].smhba_info, i, attached_devhdl);
217 +
218 + mptsas_smhba_update_phy_props(mpt, dip, phy_props, j);
219 +
220 + for (i = 0; i < j && phy_props[i] != NULL; i++)
221 + nvlist_free(phy_props[i]);
222 +
223 + kmem_free(phy_props, sizeof (nvlist_t *) * phy_nums);
224 +}
225 +
214 226 /*
215 227 * Called with PHY lock held on phyp
216 228 */
217 229 void
218 230 mptsas_smhba_log_sysevent(mptsas_t *mpt, char *subclass, char *etype,
219 231 smhba_info_t *phyp)
220 232 {
221 233 nvlist_t *attr_list;
222 234 char *pname;
223 235 char sas_addr[MPTSAS_WWN_STRLEN];
224 236 uint8_t phynum = 0;
225 237 uint8_t lrate = 0;
226 238
227 239 if (mpt->m_dip == NULL)
228 240 return;
229 241 if (phyp == NULL)
230 242 return;
231 243
232 244 pname = kmem_zalloc(MAXPATHLEN, KM_NOSLEEP);
233 245 if (pname == NULL)
234 246 return;
235 247
236 248 if ((strcmp(subclass, ESC_SAS_PHY_EVENT) == 0) ||
237 249 (strcmp(subclass, ESC_SAS_HBA_PORT_BROADCAST) == 0)) {
238 250 ASSERT(phyp != NULL);
239 251 (void) strncpy(pname, phyp->path, strlen(phyp->path));
240 252 phynum = phyp->phy_id;
241 253 bzero(sas_addr, sizeof (sas_addr));
242 254 (void) sprintf(sas_addr, "w%016"PRIx64, phyp->sas_addr);
243 255 if (strcmp(etype, SAS_PHY_ONLINE) == 0) {
244 256 lrate = phyp->negotiated_link_rate;
245 257 }
246 258 }
247 259 if (strcmp(subclass, ESC_SAS_HBA_PORT_BROADCAST) == 0) {
248 260 (void) ddi_pathname(mpt->m_dip, pname);
249 261 }
250 262
251 263 if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, 0) != 0) {
252 264 mptsas_log(mpt, CE_WARN,
253 265 "%s: Failed to post sysevent", __func__);
254 266 kmem_free(pname, MAXPATHLEN);
255 267 return;
256 268 }
257 269
258 270 if (nvlist_add_int32(attr_list, SAS_DRV_INST,
259 271 ddi_get_instance(mpt->m_dip)) != 0)
260 272 goto fail;
261 273
262 274 if (nvlist_add_string(attr_list, SAS_PORT_ADDR, sas_addr) != 0)
263 275 goto fail;
264 276
265 277 if (nvlist_add_string(attr_list, SAS_DEVFS_PATH, pname) != 0)
266 278 goto fail;
267 279
268 280 if (nvlist_add_uint8(attr_list, SAS_PHY_ID, phynum) != 0)
269 281 goto fail;
270 282
271 283 if (strcmp(etype, SAS_PHY_ONLINE) == 0) {
272 284 if (nvlist_add_uint8(attr_list, SAS_LINK_RATE, lrate) != 0)
273 285 goto fail;
274 286 }
275 287
276 288 if (nvlist_add_string(attr_list, SAS_EVENT_TYPE, etype) != 0)
277 289 goto fail;
278 290
279 291 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_SUNW, EC_HBA, subclass,
280 292 attr_list, NULL, DDI_NOSLEEP);
281 293
282 294 fail:
283 295 kmem_free(pname, MAXPATHLEN);
284 296 nvlist_free(attr_list);
285 297 }
286 298
287 299 void
288 300 mptsas_create_phy_stats(mptsas_t *mpt, char *iport, dev_info_t *dip)
289 301 {
290 302 sas_phy_stats_t *ps;
291 303 smhba_info_t *phyp;
292 304 int ndata;
293 305 char ks_name[KSTAT_STRLEN];
294 306 char phymask[MPTSAS_MAX_PHYS];
295 307 int i;
296 308
297 309 ASSERT(iport != NULL);
298 310 ASSERT(mpt != NULL);
299 311
300 312 for (i = 0; i < mpt->m_num_phys; i++) {
301 313
302 314 bzero(phymask, sizeof (phymask));
303 315 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
304 316 if (strcmp(phymask, iport) == 0) {
305 317
306 318 phyp = &mpt->m_phy_info[i].smhba_info;
307 319 mutex_enter(&phyp->phy_mutex);
308 320
309 321 if (phyp->phy_stats != NULL) {
310 322 mutex_exit(&phyp->phy_mutex);
311 323 /* We've already created this kstat instance */
312 324 continue;
313 325 }
314 326
315 327 ndata = (sizeof (sas_phy_stats_t)/
316 328 sizeof (kstat_named_t));
317 329 (void) snprintf(ks_name, sizeof (ks_name),
318 330 "%s.%llx.%d.%d", ddi_driver_name(dip),
319 331 (longlong_t)mpt->un.m_base_wwid,
320 332 ddi_get_instance(dip), i);
321 333
322 334 phyp->phy_stats = kstat_create("mptsas",
323 335 ddi_get_instance(dip), ks_name, KSTAT_SAS_PHY_CLASS,
324 336 KSTAT_TYPE_NAMED, ndata, 0);
325 337
326 338 if (phyp->phy_stats == NULL) {
327 339 mutex_exit(&phyp->phy_mutex);
328 340 mptsas_log(mpt, CE_WARN,
329 341 "%s: Failed to create %s kstats", __func__,
330 342 ks_name);
331 343 continue;
332 344 }
333 345
334 346 ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
335 347
336 348 kstat_named_init(&ps->seconds_since_last_reset,
337 349 "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
338 350 kstat_named_init(&ps->tx_frames,
339 351 "TxFrames", KSTAT_DATA_ULONGLONG);
340 352 kstat_named_init(&ps->rx_frames,
341 353 "RxFrames", KSTAT_DATA_ULONGLONG);
342 354 kstat_named_init(&ps->tx_words,
343 355 "TxWords", KSTAT_DATA_ULONGLONG);
344 356 kstat_named_init(&ps->rx_words,
345 357 "RxWords", KSTAT_DATA_ULONGLONG);
346 358 kstat_named_init(&ps->invalid_dword_count,
347 359 "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
348 360 kstat_named_init(&ps->running_disparity_error_count,
349 361 "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
350 362 kstat_named_init(&ps->loss_of_dword_sync_count,
351 363 "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
352 364 kstat_named_init(&ps->phy_reset_problem_count,
353 365 "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
354 366
355 367 phyp->phy_stats->ks_private = phyp;
356 368 phyp->phy_stats->ks_update = mptsas_update_phy_stats;
357 369 kstat_install(phyp->phy_stats);
358 370 mutex_exit(&phyp->phy_mutex);
359 371 }
360 372 }
361 373 }
362 374
363 375 int
364 376 mptsas_update_phy_stats(kstat_t *ks, int rw)
365 377 {
366 378 int ret = DDI_FAILURE;
367 379 smhba_info_t *pptr = NULL;
368 380 sas_phy_stats_t *ps = ks->ks_data;
369 381 uint32_t page_address;
370 382 mptsas_t *mpt;
371 383
372 384 _NOTE(ARGUNUSED(rw));
373 385
374 386 pptr = (smhba_info_t *)ks->ks_private;
375 387 ASSERT((pptr != NULL));
376 388 mpt = (mptsas_t *)pptr->mpt;
377 389 ASSERT((mpt != NULL));
378 390 page_address = (MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | pptr->phy_id);
379 391
380 392 /*
381 393 * We just want to lock against other invocations of kstat;
382 394 * we don't need to pmcs_lock_phy() for this.
383 395 */
384 396 mutex_enter(&mpt->m_mutex);
385 397
386 398 ret = mptsas_get_sas_phy_page1(pptr->mpt, page_address, pptr);
387 399
388 400 if (ret == DDI_FAILURE)
389 401 goto fail;
390 402
391 403 ps->invalid_dword_count.value.ull =
392 404 (unsigned long long)pptr->invalid_dword_count;
393 405
394 406 ps->running_disparity_error_count.value.ull =
395 407 (unsigned long long)pptr->running_disparity_error_count;
396 408
397 409 ps->loss_of_dword_sync_count.value.ull =
398 410 (unsigned long long)pptr->loss_of_dword_sync_count;
399 411
400 412 ps->phy_reset_problem_count.value.ull =
401 413 (unsigned long long)pptr->phy_reset_problem_count;
402 414
403 415 ret = DDI_SUCCESS;
404 416 fail:
405 417 mutex_exit(&mpt->m_mutex);
406 418
407 419 return (ret);
408 420 }
409 421
410 422 void
411 423 mptsas_destroy_phy_stats(mptsas_t *mpt)
412 424 {
413 425 smhba_info_t *phyp;
414 426 int i = 0;
415 427
416 428 ASSERT(mpt != NULL);
417 429
418 430 for (i = 0; i < mpt->m_num_phys; i++) {
419 431 phyp = &mpt->m_phy_info[i].smhba_info;
420 432 if (phyp == NULL) {
421 433 continue;
422 434 }
423 435
424 436 mutex_enter(&phyp->phy_mutex);
425 437 if (phyp->phy_stats != NULL) {
426 438 kstat_delete(phyp->phy_stats);
427 439 phyp->phy_stats = NULL;
428 440 }
429 441 mutex_exit(&phyp->phy_mutex);
430 442 }
431 443 }
432 444
433 445 int
434 446 mptsas_smhba_phy_init(mptsas_t *mpt)
435 447 {
436 448 int i = 0;
437 449 int rval = DDI_SUCCESS;
438 450 uint32_t page_address;
439 451
440 452 ASSERT(mutex_owned(&mpt->m_mutex));
441 453
442 454 for (i = 0; i < mpt->m_num_phys; i++) {
443 455 page_address =
444 456 (MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER |
445 457 (MPI2_SAS_PHY_PGAD_PHY_NUMBER_MASK & i));
446 458 rval = mptsas_get_sas_phy_page0(mpt,
447 459 page_address, &mpt->m_phy_info[i].smhba_info);
448 460 if (rval != DDI_SUCCESS) {
449 461 mptsas_log(mpt, CE_WARN,
450 462 "Failed to get sas phy page 0"
451 463 " for each phy");
452 464 return (DDI_FAILURE);
453 465 }
454 466 mpt->m_phy_info[i].smhba_info.phy_id = (uint8_t)i;
455 467 mpt->m_phy_info[i].smhba_info.sas_addr =
456 468 mpt->un.m_base_wwid + i;
457 469 mpt->m_phy_info[i].smhba_info.mpt = mpt;
458 470 }
459 471 return (DDI_SUCCESS);
460 472 }
461 473
462 474 int
463 475 mptsas_smhba_setup(mptsas_t *mpt)
464 476 {
465 477 int sm_hba = 1;
466 478 char chiprev, hw_rev[24];
467 479 char serial_number[72];
468 480 int protocol = 0;
469 481
470 482 mutex_enter(&mpt->m_mutex);
471 483 if (mptsas_smhba_phy_init(mpt)) {
472 484 mutex_exit(&mpt->m_mutex);
473 485 return (DDI_FAILURE);
474 486 }
475 487 mutex_exit(&mpt->m_mutex);
476 488
477 489 /* SM-HBA support */
478 490 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_INT32, MPTSAS_SMHBA_SUPPORTED,
479 491 &sm_hba);
480 492
481 493 /* SM-HBA driver version */
482 494 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_DRV_VERSION,
483 495 mptsas_driver_rev);
484 496
485 497 /* SM-HBA hardware version */
486 498 chiprev = 'A' + mpt->m_revid;
487 499 (void) snprintf(hw_rev, 2, "%s", &chiprev);
488 500 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_HWARE_VERSION,
489 501 hw_rev);
490 502
491 503 /* SM-HBA phy number per HBA */
492 504 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_INT32, MPTSAS_NUM_PHYS_HBA,
493 505 &(mpt->m_num_phys));
494 506
495 507 /* SM-HBA protocal support */
496 508 protocol = SAS_SSP_SUPPORT | SAS_SATA_SUPPORT | SAS_SMP_SUPPORT;
497 509 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_INT32,
498 510 MPTSAS_SUPPORTED_PROTOCOL, &protocol);
499 511
500 512 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_MANUFACTURER,
501 513 mpt->m_MANU_page0.ChipName);
502 514
503 515 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_MODEL_NAME,
504 516 mpt->m_MANU_page0.BoardName);
505 517
506 518 /*
507 519 * VPD data is not available, we make a serial number for this.
508 520 */
509 521
510 522 (void) sprintf(serial_number, "%s%s%s%s%s",
511 523 mpt->m_MANU_page0.ChipName,
512 524 mpt->m_MANU_page0.ChipRevision,
513 525 mpt->m_MANU_page0.BoardName,
514 526 mpt->m_MANU_page0.BoardAssembly,
515 527 mpt->m_MANU_page0.BoardTracerNumber);
516 528
517 529 mptsas_smhba_add_hba_prop(mpt, DATA_TYPE_STRING, MPTSAS_SERIAL_NUMBER,
518 530 &serial_number[0]);
519 531
520 532 return (DDI_SUCCESS);
521 533 }
↓ open down ↓ |
298 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX