Print this page
NEX-16174 scsi error messages should go to system log only
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3717 mptsas doesn't handle timeouts in mptsas_get_sata_guid()
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
4500 mptsas_hash_traverse() is unsafe, leads to missing devices
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Approved by: Albert Lee <trisk@nexenta.com>
backout 4500 mptsas_hash_traverse() is unsafe, leads to missing devices
4500 mptsas_hash_traverse() is unsafe, leads to missing devices
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Approved by: Albert Lee <trisk@nexenta.com>
re #6530 mpt_sas crash when more than 1 Initiator involved - ie HA
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_raid.c
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_raid.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
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 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
26 26 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 27 */
28 28
29 29 /*
30 30 * Copyright (c) 2000 to 2010, LSI Corporation.
31 31 * All rights reserved.
32 32 *
33 33 * Redistribution and use in source and binary forms of all code within
34 34 * this file that is exclusively owned by LSI, with or without
35 35 * modification, is permitted provided that, in addition to the CDDL 1.0
36 36 * License requirements, the following conditions are met:
37 37 *
38 38 * Neither the name of the author nor the names of its contributors may be
39 39 * used to endorse or promote products derived from this software without
40 40 * specific prior written permission.
41 41 *
42 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
45 45 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
46 46 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
47 47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
48 48 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
49 49 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
50 50 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51 51 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
52 52 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
53 53 * DAMAGE.
54 54 */
55 55
56 56 /*
57 57 * mptsas_raid - This file contains all the RAID related functions for the
58 58 * MPT interface.
59 59 */
60 60
61 61 #if defined(lint) || defined(DEBUG)
62 62 #define MPTSAS_DEBUG
63 63 #endif
64 64
65 65 #define MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX 2
66 66
67 67 /*
68 68 * standard header files
69 69 */
70 70 #include <sys/note.h>
71 71 #include <sys/scsi/scsi.h>
72 72 #include <sys/byteorder.h>
73 73 #include <sys/raidioctl.h>
74 74
75 75 #pragma pack(1)
76 76
77 77 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
78 78 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
79 79 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
80 80 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
81 81 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
82 82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
83 83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
84 84
85 85 #pragma pack()
86 86
87 87 /*
88 88 * private header files.
89 89 */
90 90 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
91 91
92 92 static int mptsas_get_raid_wwid(mptsas_t *mpt, mptsas_raidvol_t *raidvol);
93 93
94 94 extern int mptsas_check_dma_handle(ddi_dma_handle_t handle);
95 95 extern int mptsas_check_acc_handle(ddi_acc_handle_t handle);
96 96 extern mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t,
97 97 uint64_t, uint32_t, mptsas_phymask_t, uint8_t);
98 98
99 99 static int
100 100 mptsas_raidconf_page_0_cb(mptsas_t *mpt, caddr_t page_memp,
101 101 ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
102 102 va_list ap)
103 103 {
104 104 #ifndef __lock_lint
105 105 _NOTE(ARGUNUSED(ap))
106 106 #endif
107 107 pMpi2RaidConfigurationPage0_t raidconfig_page0;
108 108 pMpi2RaidConfig0ConfigElement_t element;
109 109 uint32_t *confignum;
110 110 int rval = DDI_SUCCESS, i;
111 111 uint8_t numelements, vol, disk;
112 112 uint16_t elementtype, voldevhandle;
113 113 uint16_t etype_vol, etype_pd, etype_hs;
114 114 uint16_t etype_oce;
115 115 m_raidconfig_t *raidconfig;
116 116 uint64_t raidwwn;
117 117 uint32_t native;
118 118 mptsas_target_t *ptgt;
119 119 uint32_t configindex;
120 120
121 121 if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
122 122 return (DDI_FAILURE);
123 123 }
124 124
125 125 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
126 126 mptsas_log(mpt, CE_WARN, "mptsas_get_raid_conf_page0 "
127 127 "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
128 128 iocstatus, iocloginfo);
129 129 rval = DDI_FAILURE;
130 130 return (rval);
131 131 }
132 132 confignum = va_arg(ap, uint32_t *);
133 133 configindex = va_arg(ap, uint32_t);
134 134 raidconfig_page0 = (pMpi2RaidConfigurationPage0_t)page_memp;
135 135 /*
136 136 * Get all RAID configurations.
137 137 */
138 138 etype_vol = MPI2_RAIDCONFIG0_EFLAGS_VOLUME_ELEMENT;
139 139 etype_pd = MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT;
140 140 etype_hs = MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT;
141 141 etype_oce = MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT;
142 142 /*
143 143 * Set up page address for next time through.
144 144 */
145 145 *confignum = ddi_get8(accessp,
146 146 &raidconfig_page0->ConfigNum);
147 147
148 148 /*
149 149 * Point to the right config in the structure.
150 150 * Increment the number of valid RAID configs.
151 151 */
152 152 raidconfig = &mpt->m_raidconfig[configindex];
153 153 mpt->m_num_raid_configs++;
154 154
155 155 /*
156 156 * Set the native flag if this is not a foreign
157 157 * configuration.
158 158 */
159 159 native = ddi_get32(accessp, &raidconfig_page0->Flags);
160 160 if (native & MPI2_RAIDCONFIG0_FLAG_FOREIGN_CONFIG) {
161 161 native = FALSE;
162 162 } else {
163 163 native = TRUE;
164 164 }
165 165 raidconfig->m_native = (uint8_t)native;
166 166
167 167 /*
168 168 * Get volume information for the volumes in the
169 169 * config.
170 170 */
171 171 numelements = ddi_get8(accessp, &raidconfig_page0->NumElements);
172 172 vol = 0;
173 173 disk = 0;
174 174 element = (pMpi2RaidConfig0ConfigElement_t)
175 175 &raidconfig_page0->ConfigElement;
176 176
177 177 for (i = 0; ((i < numelements) && native); i++, element++) {
178 178 /*
179 179 * Get the element type. Could be Volume,
180 180 * PhysDisk, Hot Spare, or Online Capacity
181 181 * Expansion PhysDisk.
182 182 */
183 183 elementtype = ddi_get16(accessp, &element->ElementFlags);
184 184 elementtype &= MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
185 185
186 186 /*
187 187 * For volumes, get the RAID settings and the
188 188 * WWID.
189 189 */
190 190 if (elementtype == etype_vol) {
191 191 voldevhandle = ddi_get16(accessp,
192 192 &element->VolDevHandle);
193 193 raidconfig->m_raidvol[vol].m_israid = 1;
194 194 raidconfig->m_raidvol[vol].
195 195 m_raidhandle = voldevhandle;
196 196 /*
197 197 * Get the settings for the raid
198 198 * volume. This includes the
199 199 * DevHandles for the disks making up
200 200 * the raid volume.
201 201 */
202 202 if (mptsas_get_raid_settings(mpt,
203 203 &raidconfig->m_raidvol[vol]))
204 204 continue;
205 205
206 206 /*
207 207 * Get the WWID of the RAID volume for
208 208 * SAS HBA
209 209 */
210 210 if (mptsas_get_raid_wwid(mpt,
211 211 &raidconfig->m_raidvol[vol]))
212 212 continue;
213 213
214 214 raidwwn = raidconfig->m_raidvol[vol].
215 215 m_raidwwid;
216 216
217 217 /*
218 218 * RAID uses phymask of 0.
219 219 */
220 220 ptgt = mptsas_tgt_alloc(mpt->m_targets,
221 221 voldevhandle, raidwwn, 0, 0, 0);
222 222
223 223 raidconfig->m_raidvol[vol].m_raidtgt =
224 224 ptgt;
225 225
226 226 /*
227 227 * Increment volume index within this
228 228 * raid config.
229 229 */
230 230 vol++;
231 231 } else if ((elementtype == etype_pd) ||
232 232 (elementtype == etype_hs) ||
233 233 (elementtype == etype_oce)) {
234 234 /*
235 235 * For all other element types, put
236 236 * their DevHandles in the phys disk
237 237 * list of the config. These are all
238 238 * some variation of a Phys Disk and
239 239 * this list is used to keep these
240 240 * disks from going online.
241 241 */
242 242 raidconfig->m_physdisk_devhdl[disk] = ddi_get16(accessp,
243 243 &element->PhysDiskDevHandle);
244 244
245 245 /*
246 246 * Increment disk index within this
247 247 * raid config.
248 248 */
249 249 disk++;
250 250 }
251 251 }
252 252
253 253 return (rval);
254 254 }
255 255
256 256 int
257 257 mptsas_get_raid_info(mptsas_t *mpt)
258 258 {
259 259 int rval = DDI_SUCCESS;
260 260 uint32_t confignum, pageaddress;
261 261 uint8_t configindex;
262 262
263 263 ASSERT(mutex_owned(&mpt->m_mutex));
264 264
265 265 /*
266 266 * Clear all RAID info before starting.
267 267 */
268 268 bzero(mpt->m_raidconfig, sizeof (mpt->m_raidconfig));
269 269 mpt->m_num_raid_configs = 0;
270 270
271 271 configindex = 0;
272 272 confignum = 0xff;
273 273 pageaddress = MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM | confignum;
274 274 while (rval == DDI_SUCCESS) {
275 275 /*
276 276 * Get the header and config page. reply contains the reply
277 277 * frame, which holds status info for the request.
278 278 */
279 279 rval = mptsas_access_config_page(mpt,
280 280 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
281 281 MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG, 0, pageaddress,
282 282 mptsas_raidconf_page_0_cb, &confignum, configindex);
283 283 configindex++;
284 284 pageaddress = MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM |
285 285 confignum;
286 286 }
287 287
288 288 return (rval);
289 289 }
290 290
291 291 static int
292 292 mptsas_raidvol_page_0_cb(mptsas_t *mpt, caddr_t page_memp,
293 293 ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
294 294 va_list ap)
295 295 {
296 296 #ifndef __lock_lint
297 297 _NOTE(ARGUNUSED(ap))
298 298 #endif
299 299 pMpi2RaidVolPage0_t raidpage;
300 300 int rval = DDI_SUCCESS, i;
301 301 mptsas_raidvol_t *raidvol;
302 302 uint8_t numdisks, volstate, voltype, physdisknum;
303 303 uint32_t volsetting;
304 304 uint32_t statusflags, resync_flag;
305 305
306 306 if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
307 307 return (DDI_FAILURE);
308 308
309 309 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
310 310 mptsas_log(mpt, CE_WARN, "mptsas_raidvol_page0_cb "
311 311 "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
312 312 iocstatus, iocloginfo);
313 313 rval = DDI_FAILURE;
314 314 return (rval);
315 315 }
316 316
317 317 raidvol = va_arg(ap, mptsas_raidvol_t *);
318 318
319 319 raidpage = (pMpi2RaidVolPage0_t)page_memp;
320 320 volstate = ddi_get8(accessp, &raidpage->VolumeState);
321 321 volsetting = ddi_get32(accessp,
322 322 (uint32_t *)(void *)&raidpage->VolumeSettings);
323 323 statusflags = ddi_get32(accessp, &raidpage->VolumeStatusFlags);
324 324 voltype = ddi_get8(accessp, &raidpage->VolumeType);
325 325
|
↓ open down ↓ |
325 lines elided |
↑ open up ↑ |
326 326 raidvol->m_state = volstate;
327 327 raidvol->m_statusflags = statusflags;
328 328 /*
329 329 * Volume size is not used right now. Set to 0.
330 330 */
331 331 raidvol->m_raidsize = 0;
332 332 raidvol->m_settings = volsetting;
333 333 raidvol->m_raidlevel = voltype;
334 334
335 335 if (statusflags & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED) {
336 - mptsas_log(mpt, CE_NOTE, "?Volume %d is quiesced\n",
336 + mptsas_log(mpt, CE_NOTE, "Volume %d is quiesced",
337 337 raidvol->m_raidhandle);
338 338 }
339 339
340 340 if (statusflags &
341 341 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) {
342 - mptsas_log(mpt, CE_NOTE, "?Volume %d is resyncing\n",
342 + mptsas_log(mpt, CE_NOTE, "Volume %d is resyncing",
343 343 raidvol->m_raidhandle);
344 344 }
345 345
346 346 resync_flag = MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
347 347 switch (volstate) {
348 348 case MPI2_RAID_VOL_STATE_OPTIMAL:
349 - mptsas_log(mpt, CE_NOTE, "?Volume %d is "
350 - "optimal\n", raidvol->m_raidhandle);
349 + mptsas_log(mpt, CE_NOTE, "Volume %d is "
350 + "optimal", raidvol->m_raidhandle);
351 351 break;
352 352 case MPI2_RAID_VOL_STATE_DEGRADED:
353 353 if ((statusflags & resync_flag) == 0) {
354 354 mptsas_log(mpt, CE_WARN, "Volume %d "
355 - "is degraded\n",
355 + "is degraded",
356 356 raidvol->m_raidhandle);
357 357 }
358 358 break;
359 359 case MPI2_RAID_VOL_STATE_FAILED:
360 360 mptsas_log(mpt, CE_WARN, "Volume %d is "
361 - "failed\n", raidvol->m_raidhandle);
361 + "failed", raidvol->m_raidhandle);
362 362 break;
363 363 case MPI2_RAID_VOL_STATE_MISSING:
364 364 mptsas_log(mpt, CE_WARN, "Volume %d is "
365 - "missing\n", raidvol->m_raidhandle);
365 + "missing", raidvol->m_raidhandle);
366 366 break;
367 367 default:
368 368 break;
369 369 }
370 370 numdisks = raidpage->NumPhysDisks;
371 371 raidvol->m_ndisks = numdisks;
372 372 for (i = 0; i < numdisks; i++) {
373 373 physdisknum = raidpage->PhysDisk[i].PhysDiskNum;
374 374 raidvol->m_disknum[i] = physdisknum;
375 375 if (mptsas_get_physdisk_settings(mpt, raidvol,
376 376 physdisknum))
377 377 break;
378 378 }
379 379 return (rval);
380 380 }
381 381
382 382 int
383 383 mptsas_get_raid_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol)
384 384 {
385 385 int rval = DDI_SUCCESS;
386 386 uint32_t page_address;
387 387
388 388 ASSERT(mutex_owned(&mpt->m_mutex));
389 389
390 390 /*
391 391 * Get the header and config page. reply contains the reply frame,
392 392 * which holds status info for the request.
393 393 */
394 394 page_address = (MPI2_RAID_VOLUME_PGAD_FORM_MASK &
395 395 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE) | raidvol->m_raidhandle;
396 396 rval = mptsas_access_config_page(mpt,
397 397 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
398 398 MPI2_CONFIG_PAGETYPE_RAID_VOLUME, 0, page_address,
399 399 mptsas_raidvol_page_0_cb, raidvol);
400 400
401 401 return (rval);
402 402 }
403 403
404 404 static int
405 405 mptsas_raidvol_page_1_cb(mptsas_t *mpt, caddr_t page_memp,
406 406 ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
407 407 va_list ap)
408 408 {
409 409 #ifndef __lock_lint
410 410 _NOTE(ARGUNUSED(ap))
411 411 #endif
412 412 pMpi2RaidVolPage1_t raidpage;
413 413 int rval = DDI_SUCCESS, i;
414 414 uint8_t *sas_addr = NULL;
415 415 uint8_t tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
416 416 uint64_t *sas_wwn;
417 417
418 418 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
419 419 mptsas_log(mpt, CE_WARN, "mptsas_raidvol_page_1_cb "
420 420 "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
421 421 iocstatus, iocloginfo);
422 422 rval = DDI_FAILURE;
423 423 return (rval);
424 424 }
425 425 sas_wwn = va_arg(ap, uint64_t *);
426 426
427 427 raidpage = (pMpi2RaidVolPage1_t)page_memp;
428 428 sas_addr = (uint8_t *)(&raidpage->WWID);
429 429 for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
430 430 tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
431 431 }
432 432 bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
433 433 *sas_wwn = LE_64(*sas_wwn);
434 434 return (rval);
435 435 }
436 436
437 437 static int
438 438 mptsas_get_raid_wwid(mptsas_t *mpt, mptsas_raidvol_t *raidvol)
439 439 {
440 440 int rval = DDI_SUCCESS;
441 441 uint32_t page_address;
442 442 uint64_t sas_wwn;
443 443
444 444 ASSERT(mutex_owned(&mpt->m_mutex));
445 445
446 446 /*
447 447 * Get the header and config page. reply contains the reply frame,
448 448 * which holds status info for the request.
449 449 */
450 450 page_address = (MPI2_RAID_VOLUME_PGAD_FORM_MASK &
451 451 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE) | raidvol->m_raidhandle;
452 452 rval = mptsas_access_config_page(mpt,
453 453 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
454 454 MPI2_CONFIG_PAGETYPE_RAID_VOLUME, 1, page_address,
455 455 mptsas_raidvol_page_1_cb, &sas_wwn);
456 456
457 457 /*
458 458 * Get the required information from the page.
459 459 */
460 460 if (rval == DDI_SUCCESS) {
461 461
462 462 /*
463 463 * replace top nibble of WWID of RAID to '3' for OBP
464 464 */
465 465 sas_wwn = MPTSAS_RAID_WWID(sas_wwn);
466 466 raidvol->m_raidwwid = sas_wwn;
467 467 }
468 468
469 469 return (rval);
470 470 }
471 471
472 472 static int
473 473 mptsas_raidphydsk_page_0_cb(mptsas_t *mpt, caddr_t page_memp,
474 474 ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
475 475 va_list ap)
476 476 {
477 477 #ifndef __lock_lint
478 478 _NOTE(ARGUNUSED(ap))
479 479 #endif
480 480 pMpi2RaidPhysDiskPage0_t diskpage;
481 481 int rval = DDI_SUCCESS;
482 482 uint16_t *devhdl;
483 483 uint8_t *state;
484 484
485 485 if (iocstatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
486 486 return (DDI_FAILURE);
487 487
488 488 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
489 489 mptsas_log(mpt, CE_WARN, "mptsas_raidphydsk_page0_cb "
490 490 "config: IOCStatus=0x%x, IOCLogInfo=0x%x",
491 491 iocstatus, iocloginfo);
492 492 rval = DDI_FAILURE;
493 493 return (rval);
494 494 }
495 495 devhdl = va_arg(ap, uint16_t *);
496 496 state = va_arg(ap, uint8_t *);
497 497 diskpage = (pMpi2RaidPhysDiskPage0_t)page_memp;
498 498 *devhdl = ddi_get16(accessp, &diskpage->DevHandle);
499 499 *state = ddi_get8(accessp, &diskpage->PhysDiskState);
500 500 return (rval);
501 501 }
502 502
503 503 int
504 504 mptsas_get_physdisk_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol,
505 505 uint8_t physdisknum)
506 506 {
507 507 int rval = DDI_SUCCESS, i;
508 508 uint8_t state;
509 509 uint16_t devhdl;
510 510 uint32_t page_address;
511 511
512 512 ASSERT(mutex_owned(&mpt->m_mutex));
513 513
514 514 /*
515 515 * Get the header and config page. reply contains the reply frame,
516 516 * which holds status info for the request.
517 517 */
518 518 page_address = (MPI2_PHYSDISK_PGAD_FORM_MASK &
519 519 MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM) | physdisknum;
520 520 rval = mptsas_access_config_page(mpt,
521 521 MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
522 522 MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK, 0, page_address,
523 523 mptsas_raidphydsk_page_0_cb, &devhdl, &state);
524 524
525 525 /*
526 526 * Get the required information from the page.
527 527 */
528 528 if (rval == DDI_SUCCESS) {
529 529 for (i = 0; i < MPTSAS_MAX_DISKS_IN_VOL; i++) {
530 530 /* find the correct position in the arrays */
531 531 if (raidvol->m_disknum[i] == physdisknum)
532 532 break;
533 533 }
534 534 raidvol->m_devhdl[i] = devhdl;
535 535
536 536 switch (state) {
537 537 case MPI2_RAID_PD_STATE_OFFLINE:
538 538 raidvol->m_diskstatus[i] =
539 539 RAID_DISKSTATUS_FAILED;
540 540 break;
541 541
542 542 case MPI2_RAID_PD_STATE_HOT_SPARE:
543 543 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
544 544 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
545 545 break;
546 546
547 547 case MPI2_RAID_PD_STATE_DEGRADED:
548 548 case MPI2_RAID_PD_STATE_OPTIMAL:
549 549 case MPI2_RAID_PD_STATE_REBUILDING:
550 550 case MPI2_RAID_PD_STATE_ONLINE:
551 551 default:
552 552 raidvol->m_diskstatus[i] =
553 553 RAID_DISKSTATUS_GOOD;
554 554 break;
555 555 }
556 556 }
557 557
558 558 return (rval);
559 559 }
560 560
561 561 /*
562 562 * RAID Action for System Shutdown. This request uses the dedicated TM slot to
563 563 * avoid a call to mptsas_save_cmd. Since Solaris requires that the mutex is
564 564 * not held during the mptsas_quiesce function, this RAID action must not use
565 565 * the normal code path of requests and replies.
566 566 */
567 567 void
568 568 mptsas_raid_action_system_shutdown(mptsas_t *mpt)
569 569 {
570 570 pMpi2RaidActionRequest_t action;
571 571 uint8_t ir_active = FALSE, reply_type;
572 572 uint8_t function, found_reply = FALSE;
573 573 uint16_t SMID, action_type;
574 574 mptsas_slots_t *slots = mpt->m_active;
575 575 int config, vol;
576 576 mptsas_cmd_t *cmd;
577 577 uint32_t reply_addr;
578 578 uint64_t request_desc;
579 579 int cnt;
580 580 pMpi2ReplyDescriptorsUnion_t reply_desc_union;
581 581 pMPI2DefaultReply_t reply;
582 582 pMpi2AddressReplyDescriptor_t address_reply;
583 583
584 584 /*
585 585 * Before doing the system shutdown RAID Action, make sure that the IOC
586 586 * supports IR and make sure there is a valid volume for the request.
587 587 */
588 588 if (mpt->m_ir_capable) {
589 589 for (config = 0; (config < mpt->m_num_raid_configs) &&
590 590 (!ir_active); config++) {
591 591 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
592 592 if (mpt->m_raidconfig[config].m_raidvol[vol].
593 593 m_israid) {
594 594 ir_active = TRUE;
595 595 break;
596 596 }
597 597 }
598 598 }
599 599 }
|
↓ open down ↓ |
224 lines elided |
↑ open up ↑ |
600 600 if (!ir_active) {
601 601 return;
602 602 }
603 603
604 604 /*
605 605 * If TM slot is already being used (highly unlikely), show message and
606 606 * don't issue the RAID action.
607 607 */
608 608 if (slots->m_slot[MPTSAS_TM_SLOT(mpt)] != NULL) {
609 609 mptsas_log(mpt, CE_WARN, "RAID Action slot in use. Cancelling"
610 - " System Shutdown RAID Action.\n");
610 + " System Shutdown RAID Action.");
611 611 return;
612 612 }
613 613
614 614 /*
615 615 * Create the cmd and put it in the dedicated TM slot.
616 616 */
617 617 cmd = &(mpt->m_event_task_mgmt.m_event_cmd);
618 618 bzero((caddr_t)cmd, sizeof (*cmd));
619 619 cmd->cmd_pkt = NULL;
620 620 cmd->cmd_slot = MPTSAS_TM_SLOT(mpt);
621 621 slots->m_slot[MPTSAS_TM_SLOT(mpt)] = cmd;
622 622
623 623 /*
624 624 * Form message for raid action.
625 625 */
626 626 action = (pMpi2RaidActionRequest_t)(mpt->m_req_frame +
627 627 (mpt->m_req_frame_size * cmd->cmd_slot));
628 628 bzero(action, mpt->m_req_frame_size);
629 629 action->Function = MPI2_FUNCTION_RAID_ACTION;
630 630 action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
631 631
632 632 /*
633 633 * Send RAID Action.
634 634 */
635 635 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
636 636 DDI_DMA_SYNC_FORDEV);
637 637 request_desc = (cmd->cmd_slot << 16) +
638 638 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
639 639 MPTSAS_START_CMD(mpt, request_desc);
640 640
641 641 /*
642 642 * Even though reply does not matter because the system is shutting
643 643 * down, wait no more than 5 seconds here to get the reply just because
644 644 * we don't want to leave it hanging if it's coming. Poll because
645 645 * interrupts are disabled when this function is called.
646 646 */
647 647 for (cnt = 0; cnt < 5000; cnt++) {
648 648 /*
649 649 * Check for a reply.
650 650 */
651 651 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
652 652 DDI_DMA_SYNC_FORCPU);
653 653
654 654 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
655 655 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
656 656
657 657 if (ddi_get32(mpt->m_acc_post_queue_hdl,
658 658 &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
659 659 ddi_get32(mpt->m_acc_post_queue_hdl,
660 660 &reply_desc_union->Words.High) == 0xFFFFFFFF) {
661 661 drv_usecwait(1000);
662 662 continue;
663 663 }
664 664
665 665 /*
666 666 * There is a reply. If it's not an address reply, ignore it.
667 667 */
668 668 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
669 669 &reply_desc_union->Default.ReplyFlags);
670 670 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
671 671 if (reply_type != MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
672 672 goto clear_and_continue;
673 673 }
674 674
675 675 /*
676 676 * SMID must be the TM slot since that's what we're using for
677 677 * this RAID action. If not, ignore this reply.
678 678 */
679 679 address_reply =
680 680 (pMpi2AddressReplyDescriptor_t)reply_desc_union;
681 681 SMID = ddi_get16(mpt->m_acc_post_queue_hdl,
682 682 &address_reply->SMID);
683 683 if (SMID != MPTSAS_TM_SLOT(mpt)) {
684 684 goto clear_and_continue;
685 685 }
686 686
687 687 /*
688 688 * If reply frame is not in the proper range ignore it.
689 689 */
690 690 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
691 691 &address_reply->ReplyFrameAddress);
692 692 if ((reply_addr < mpt->m_reply_frame_dma_addr) ||
693 693 (reply_addr >= (mpt->m_reply_frame_dma_addr +
694 694 (mpt->m_reply_frame_size * mpt->m_free_queue_depth))) ||
695 695 ((reply_addr - mpt->m_reply_frame_dma_addr) %
696 696 mpt->m_reply_frame_size != 0)) {
697 697 goto clear_and_continue;
698 698 }
699 699
700 700 /*
701 701 * If not a RAID action reply ignore it.
702 702 */
703 703 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
704 704 DDI_DMA_SYNC_FORCPU);
705 705 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame +
706 706 (reply_addr - mpt->m_reply_frame_dma_addr));
707 707 function = ddi_get8(mpt->m_acc_reply_frame_hdl,
708 708 &reply->Function);
709 709 if (function != MPI2_FUNCTION_RAID_ACTION) {
710 710 goto clear_and_continue;
711 711 }
712 712
713 713 /*
714 714 * Finally, make sure this is the System Shutdown RAID action.
715 715 * If not, ignore reply.
716 716 */
717 717 action_type = ddi_get16(mpt->m_acc_reply_frame_hdl,
718 718 &reply->FunctionDependent1);
719 719 if (action_type !=
720 720 MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED) {
721 721 goto clear_and_continue;
722 722 }
723 723 found_reply = TRUE;
724 724
725 725 clear_and_continue:
726 726 /*
727 727 * Clear the reply descriptor for re-use and increment index.
728 728 */
729 729 ddi_put64(mpt->m_acc_post_queue_hdl,
730 730 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
731 731 0xFFFFFFFFFFFFFFFF);
732 732 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
733 733 DDI_DMA_SYNC_FORDEV);
734 734
735 735 /*
736 736 * Update the global reply index and keep looking for the
737 737 * reply if not found yet.
738 738 */
739 739 if (++mpt->m_post_index == mpt->m_post_queue_depth) {
740 740 mpt->m_post_index = 0;
741 741 }
742 742 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyPostHostIndex,
743 743 mpt->m_post_index);
744 744 if (!found_reply) {
745 745 continue;
746 746 }
747 747
748 748 break;
749 749 }
750 750
751 751 /*
752 752 * clear the used slot as the last step.
753 753 */
754 754 slots->m_slot[MPTSAS_TM_SLOT(mpt)] = NULL;
755 755 }
756 756
757 757 int
758 758 mptsas_delete_volume(mptsas_t *mpt, uint16_t volid)
759 759 {
760 760 int config, i = 0, vol = (-1);
761 761
762 762 for (config = 0; (config < mpt->m_num_raid_configs) && (vol != i);
763 763 config++) {
764 764 for (i = 0; i < MPTSAS_MAX_RAIDVOLS; i++) {
765 765 if (mpt->m_raidconfig[config].m_raidvol[i].
766 766 m_raidhandle == volid) {
767 767 vol = i;
768 768 break;
769 769 }
770 770 }
771 771 }
772 772
773 773 if (vol < 0) {
774 774 mptsas_log(mpt, CE_WARN, "raid doesn't exist at specified "
775 775 "target.");
776 776 return (-1);
777 777 }
778 778
779 779 mpt->m_raidconfig[config].m_raidvol[vol].m_israid = 0;
780 780 mpt->m_raidconfig[config].m_raidvol[vol].m_ndisks = 0;
781 781 for (i = 0; i < MPTSAS_MAX_DISKS_IN_VOL; i++) {
782 782 mpt->m_raidconfig[config].m_raidvol[vol].m_disknum[i] = 0;
783 783 mpt->m_raidconfig[config].m_raidvol[vol].m_devhdl[i] = 0;
784 784 }
785 785
786 786 return (0);
787 787 }
|
↓ open down ↓ |
167 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX