Print this page
WIP on 24 port PHY
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_init.c
+++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_init.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 2009 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 */
27 27
28 28 /*
29 29 * Copyright (c) 2000 to 2009, LSI Corporation.
30 30 * All rights reserved.
31 31 *
32 32 * Redistribution and use in source and binary forms of all code within
33 33 * this file that is exclusively owned by LSI, with or without
34 34 * modification, is permitted provided that, in addition to the CDDL 1.0
35 35 * License requirements, the following conditions are met:
36 36 *
37 37 * Neither the name of the author nor the names of its contributors may be
38 38 * used to endorse or promote products derived from this software without
39 39 * specific prior written permission.
40 40 *
41 41 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
42 42 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
43 43 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
44 44 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
45 45 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
46 46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
47 47 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
48 48 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
49 49 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
52 52 * DAMAGE.
53 53 */
54 54
55 55 /*
56 56 * mptsas_init - This file contains all the functions used to initialize
57 57 * MPT2.0 based hardware.
58 58 */
59 59
60 60 #if defined(lint) || defined(DEBUG)
61 61 #define MPTSAS_DEBUG
62 62 #endif
63 63
64 64 /*
65 65 * standard header files
66 66 */
67 67 #include <sys/note.h>
68 68 #include <sys/scsi/scsi.h>
69 69
70 70 #pragma pack(1)
71 71 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
72 72 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
73 73 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
74 74 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
75 75 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
76 76 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
77 77 #pragma pack()
78 78 /*
79 79 * private header files.
80 80 */
81 81 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
82 82
83 83 static int mptsas_ioc_do_get_facts(mptsas_t *mpt, caddr_t memp, int var,
84 84 ddi_acc_handle_t accessp);
85 85 static int mptsas_ioc_do_get_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
86 86 ddi_acc_handle_t accessp);
87 87 static int mptsas_ioc_do_get_port_facts(mptsas_t *mpt, caddr_t memp, int var,
88 88 ddi_acc_handle_t accessp);
89 89 static int mptsas_ioc_do_get_port_facts_reply(mptsas_t *mpt, caddr_t memp,
90 90 int var, ddi_acc_handle_t accessp);
91 91 static int mptsas_ioc_do_enable_port(mptsas_t *mpt, caddr_t memp, int var,
92 92 ddi_acc_handle_t accessp);
93 93 static int mptsas_ioc_do_enable_port_reply(mptsas_t *mpt, caddr_t memp, int var,
94 94 ddi_acc_handle_t accessp);
95 95 static int mptsas_ioc_do_enable_event_notification(mptsas_t *mpt, caddr_t memp,
96 96 int var, ddi_acc_handle_t accessp);
97 97 static int mptsas_ioc_do_enable_event_notification_reply(mptsas_t *mpt,
98 98 caddr_t memp, int var, ddi_acc_handle_t accessp);
99 99 static int mptsas_do_ioc_init(mptsas_t *mpt, caddr_t memp, int var,
100 100 ddi_acc_handle_t accessp);
101 101 static int mptsas_do_ioc_init_reply(mptsas_t *mpt, caddr_t memp, int var,
102 102 ddi_acc_handle_t accessp);
103 103
104 104 static const char *
105 105 mptsas_devid_type_string(mptsas_t *mpt)
106 106 {
107 107 switch (mpt->m_devid) {
108 108 case MPI2_MFGPAGE_DEVID_SAS2008:
109 109 return ("SAS2008");
110 110 case MPI2_MFGPAGE_DEVID_SAS2004:
111 111 return ("SAS2004");
112 112 case MPI2_MFGPAGE_DEVID_SAS2108_1:
113 113 case MPI2_MFGPAGE_DEVID_SAS2108_2:
114 114 case MPI2_MFGPAGE_DEVID_SAS2108_3:
115 115 return ("SAS2108");
116 116 case MPI2_MFGPAGE_DEVID_SAS2116_1:
117 117 case MPI2_MFGPAGE_DEVID_SAS2116_2:
118 118 return ("SAS2116");
119 119 case MPI2_MFGPAGE_DEVID_SAS2208_1:
120 120 case MPI2_MFGPAGE_DEVID_SAS2208_2:
121 121 case MPI2_MFGPAGE_DEVID_SAS2208_3:
122 122 case MPI2_MFGPAGE_DEVID_SAS2208_4:
123 123 case MPI2_MFGPAGE_DEVID_SAS2208_5:
124 124 case MPI2_MFGPAGE_DEVID_SAS2208_6:
125 125 return ("SAS2208");
126 126 case MPI2_MFGPAGE_DEVID_SAS2308_1:
127 127 case MPI2_MFGPAGE_DEVID_SAS2308_2:
128 128 case MPI2_MFGPAGE_DEVID_SAS2308_3:
129 129 return ("SAS2308");
130 130 case MPI25_MFGPAGE_DEVID_SAS3004:
131 131 return ("SAS3004");
132 132 case MPI25_MFGPAGE_DEVID_SAS3008:
133 133 return ("SAS3008");
134 134 case MPI25_MFGPAGE_DEVID_SAS3108_1:
135 135 case MPI25_MFGPAGE_DEVID_SAS3108_2:
136 136 case MPI25_MFGPAGE_DEVID_SAS3108_5:
137 137 case MPI25_MFGPAGE_DEVID_SAS3108_6:
138 138 return ("SAS3108");
139 139 default:
140 140 return ("?");
141 141 }
142 142 }
143 143
144 144 int
145 145 mptsas_ioc_get_facts(mptsas_t *mpt)
146 146 {
147 147 /*
148 148 * Send get facts messages
149 149 */
150 150 if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_FACTS_REQUEST), NULL,
151 151 mptsas_ioc_do_get_facts)) {
152 152 return (DDI_FAILURE);
153 153 }
154 154
155 155 /*
156 156 * Get facts reply messages
157 157 */
158 158 if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_FACTS_REPLY), NULL,
159 159 mptsas_ioc_do_get_facts_reply)) {
160 160 return (DDI_FAILURE);
161 161 }
162 162
163 163 return (DDI_SUCCESS);
164 164 }
165 165
166 166 static int
167 167 mptsas_ioc_do_get_facts(mptsas_t *mpt, caddr_t memp, int var,
168 168 ddi_acc_handle_t accessp)
169 169 {
170 170 #ifndef __lock_lint
171 171 _NOTE(ARGUNUSED(var))
172 172 #endif
173 173 pMpi2IOCFactsRequest_t facts;
174 174 int numbytes;
175 175
176 176 bzero(memp, sizeof (*facts));
177 177 facts = (void *)memp;
178 178 ddi_put8(accessp, &facts->Function, MPI2_FUNCTION_IOC_FACTS);
179 179 numbytes = sizeof (*facts);
180 180
181 181 /*
182 182 * Post message via handshake
183 183 */
184 184 if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
185 185 return (DDI_FAILURE);
186 186 }
187 187
188 188 return (DDI_SUCCESS);
189 189 }
190 190
191 191 static int
192 192 mptsas_ioc_do_get_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
193 193 ddi_acc_handle_t accessp)
194 194 {
195 195 #ifndef __lock_lint
196 196 _NOTE(ARGUNUSED(var))
197 197 #endif
198 198
199 199 pMpi2IOCFactsReply_t factsreply;
200 200 int numbytes;
201 201 uint_t iocstatus;
202 202 char buf[32];
203 203 uint16_t numReplyFrames;
204 204 uint16_t queueSize, queueDiff;
205 205 int simple_sge_main;
206 206 int simple_sge_next;
207 207 uint32_t capabilities;
208 208 uint16_t msgversion;
209 209
210 210 bzero(memp, sizeof (*factsreply));
211 211 factsreply = (void *)memp;
212 212 numbytes = sizeof (*factsreply);
213 213
214 214 /*
215 215 * get ioc facts reply message
216 216 */
217 217 if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
218 218 return (DDI_FAILURE);
219 219 }
220 220
221 221 if (iocstatus = ddi_get16(accessp, &factsreply->IOCStatus)) {
222 222 mptsas_log(mpt, CE_WARN, "mptsas_ioc_do_get_facts_reply: "
223 223 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
224 224 ddi_get32(accessp, &factsreply->IOCLogInfo));
225 225 return (DDI_FAILURE);
226 226 }
227 227
228 228 /*
229 229 * store key values from reply to mpt structure
230 230 */
231 231 mpt->m_fwversion = ddi_get32(accessp, &factsreply->FWVersion.Word);
232 232 mpt->m_productid = ddi_get16(accessp, &factsreply->ProductID);
233 233
234 234
235 235 (void) sprintf(buf, "%u.%u.%u.%u",
236 236 ddi_get8(accessp, &factsreply->FWVersion.Struct.Major),
237 237 ddi_get8(accessp, &factsreply->FWVersion.Struct.Minor),
238 238 ddi_get8(accessp, &factsreply->FWVersion.Struct.Unit),
239 239 ddi_get8(accessp, &factsreply->FWVersion.Struct.Dev));
240 240 mptsas_log(mpt, CE_NOTE, "?MPT Firmware version v%s (%s)\n",
241 241 buf, mptsas_devid_type_string(mpt));
242 242 (void) ddi_prop_update_string(DDI_DEV_T_NONE, mpt->m_dip,
243 243 "firmware-version", buf);
244 244
245 245 /*
246 246 * Set up request info.
247 247 */
248 248 mpt->m_max_requests = ddi_get16(accessp,
249 249 &factsreply->RequestCredit) - 1;
250 250 mpt->m_req_frame_size = ddi_get16(accessp,
251 251 &factsreply->IOCRequestFrameSize) * 4;
252 252
253 253 /*
254 254 * Size of reply free queue should be the number of requests
255 255 * plus some additional for events (32). Make sure number of
256 256 * reply frames is not a multiple of 16 so that the queue sizes
257 257 * are calculated correctly later to be a multiple of 16.
258 258 */
259 259 mpt->m_reply_frame_size = ddi_get8(accessp,
260 260 &factsreply->ReplyFrameSize) * 4;
261 261 numReplyFrames = mpt->m_max_requests + 32;
262 262 if (!(numReplyFrames % 16)) {
263 263 numReplyFrames--;
264 264 }
265 265 mpt->m_max_replies = numReplyFrames;
266 266 queueSize = numReplyFrames;
267 267 queueSize += 16 - (queueSize % 16);
268 268 mpt->m_free_queue_depth = queueSize;
269 269
270 270 /*
271 271 * Size of reply descriptor post queue should be the number of
272 272 * request frames + the number of reply frames + 1 and needs to
273 273 * be a multiple of 16. This size can be no larger than
274 274 * MaxReplyDescriptorPostQueueDepth from IOCFacts. If the
275 275 * calculated queue size is larger than allowed, subtract a
276 276 * multiple of 16 from m_max_requests, m_max_replies, and
277 277 * m_reply_free_depth.
278 278 */
279 279 queueSize = mpt->m_max_requests + numReplyFrames + 1;
280 280 if (queueSize % 16) {
281 281 queueSize += 16 - (queueSize % 16);
282 282 }
283 283 mpt->m_post_queue_depth = ddi_get16(accessp,
284 284 &factsreply->MaxReplyDescriptorPostQueueDepth);
285 285 if (queueSize > mpt->m_post_queue_depth) {
286 286 queueDiff = queueSize - mpt->m_post_queue_depth;
287 287 if (queueDiff % 16) {
288 288 queueDiff += 16 - (queueDiff % 16);
289 289 }
290 290 mpt->m_max_requests -= queueDiff;
291 291 mpt->m_max_replies -= queueDiff;
292 292 mpt->m_free_queue_depth -= queueDiff;
293 293 queueSize -= queueDiff;
294 294 }
295 295 mpt->m_post_queue_depth = queueSize;
296 296
297 297 /*
298 298 * Set up max chain depth.
299 299 */
300 300 mpt->m_max_chain_depth = ddi_get8(accessp,
301 301 &factsreply->MaxChainDepth);
302 302 mpt->m_ioc_capabilities = ddi_get32(accessp,
303 303 &factsreply->IOCCapabilities);
304 304
305 305 /*
306 306 * Set flag to check for SAS3 support.
307 307 */
308 308 msgversion = ddi_get16(accessp, &factsreply->MsgVersion);
309 309 if (msgversion == MPI2_VERSION_02_05) {
310 310 mptsas_log(mpt, CE_NOTE, "?mpt_sas%d SAS 3 Supported\n",
311 311 mpt->m_instance);
312 312 mpt->m_MPI25 = TRUE;
313 313 } else {
314 314 mptsas_log(mpt, CE_NOTE, "?mpt_sas%d MPI Version 0x%x\n",
315 315 mpt->m_instance, msgversion);
316 316 }
317 317
318 318 /*
319 319 * Calculate max frames per request based on DMA S/G length.
320 320 */
321 321 simple_sge_main = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
322 322 simple_sge_next = mpt->m_req_frame_size / MPTSAS_SGE_SIZE(mpt) - 1;
323 323
324 324 mpt->m_max_request_frames = (MPTSAS_MAX_DMA_SEGS -
325 325 simple_sge_main) / simple_sge_next + 1;
326 326 if (((MPTSAS_MAX_DMA_SEGS - simple_sge_main) %
327 327 simple_sge_next) > 1) {
328 328 mpt->m_max_request_frames++;
329 329 }
330 330
331 331 /*
332 332 * Check if controller supports FW diag buffers and set flag to enable
333 333 * each type.
334 334 */
335 335 capabilities = ddi_get32(accessp, &factsreply->IOCCapabilities);
336 336 if (capabilities & MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) {
337 337 mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_TRACE].enabled =
338 338 TRUE;
339 339 }
340 340 if (capabilities & MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) {
341 341 mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_SNAPSHOT].
342 342 enabled = TRUE;
343 343 }
344 344 if (capabilities & MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
345 345 mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_EXTENDED].
346 346 enabled = TRUE;
347 347 }
348 348
349 349 /*
350 350 * Check if controller supports replaying events when issuing Message
351 351 * Unit Reset and set flag to enable MUR.
352 352 */
353 353 if (capabilities & MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY) {
354 354 mpt->m_event_replay = TRUE;
355 355 }
356 356
357 357 /*
358 358 * Check if controller supports IR.
359 359 */
360 360 if (capabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
361 361 mpt->m_ir_capable = TRUE;
362 362 }
363 363
364 364 return (DDI_SUCCESS);
365 365 }
366 366
367 367 int
368 368 mptsas_ioc_get_port_facts(mptsas_t *mpt, int port)
369 369 {
370 370 /*
371 371 * Send get port facts message
372 372 */
373 373 if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_FACTS_REQUEST), port,
374 374 mptsas_ioc_do_get_port_facts)) {
375 375 return (DDI_FAILURE);
376 376 }
377 377
378 378 /*
379 379 * Get port facts reply message
380 380 */
381 381 if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_FACTS_REPLY), port,
382 382 mptsas_ioc_do_get_port_facts_reply)) {
383 383 return (DDI_FAILURE);
384 384 }
385 385
386 386 return (DDI_SUCCESS);
387 387 }
388 388
389 389 static int
390 390 mptsas_ioc_do_get_port_facts(mptsas_t *mpt, caddr_t memp, int var,
391 391 ddi_acc_handle_t accessp)
392 392 {
393 393 pMpi2PortFactsRequest_t facts;
394 394 int numbytes;
395 395
396 396 bzero(memp, sizeof (*facts));
397 397 facts = (void *)memp;
398 398 ddi_put8(accessp, &facts->Function, MPI2_FUNCTION_PORT_FACTS);
399 399 ddi_put8(accessp, &facts->PortNumber, var);
400 400 numbytes = sizeof (*facts);
401 401
402 402 /*
403 403 * Send port facts message via handshake
404 404 */
405 405 if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
406 406 return (DDI_FAILURE);
407 407 }
408 408
409 409 return (DDI_SUCCESS);
410 410 }
411 411
412 412 static int
413 413 mptsas_ioc_do_get_port_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
414 414 ddi_acc_handle_t accessp)
415 415 {
416 416 #ifndef __lock_lint
417 417 _NOTE(ARGUNUSED(var))
418 418 #endif
419 419 pMpi2PortFactsReply_t factsreply;
420 420 int numbytes;
421 421 uint_t iocstatus;
422 422
423 423 bzero(memp, sizeof (*factsreply));
424 424 factsreply = (void *)memp;
425 425 numbytes = sizeof (*factsreply);
426 426
427 427 /*
428 428 * Get port facts reply message via handshake
429 429 */
430 430 if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
431 431 return (DDI_FAILURE);
432 432 }
433 433
434 434 if (iocstatus = ddi_get16(accessp, &factsreply->IOCStatus)) {
435 435 mptsas_log(mpt, CE_WARN, "mptsas_ioc_do_get_port_facts_reply: "
436 436 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
437 437 ddi_get32(accessp, &factsreply->IOCLogInfo));
438 438 return (DDI_FAILURE);
439 439 }
440 440
441 441 return (DDI_SUCCESS);
442 442 }
443 443
444 444 int
445 445 mptsas_ioc_enable_port(mptsas_t *mpt)
446 446 {
447 447 /*
448 448 * Send enable port message
449 449 */
450 450 if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_ENABLE_REQUEST), 0,
451 451 mptsas_ioc_do_enable_port)) {
452 452 return (DDI_FAILURE);
453 453 }
454 454
455 455 /*
456 456 * Get enable port reply message
457 457 */
458 458 if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_ENABLE_REPLY), 0,
459 459 mptsas_ioc_do_enable_port_reply)) {
460 460 return (DDI_FAILURE);
461 461 }
462 462
463 463 return (DDI_SUCCESS);
464 464 }
465 465
466 466 static int
467 467 mptsas_ioc_do_enable_port(mptsas_t *mpt, caddr_t memp, int var,
468 468 ddi_acc_handle_t accessp)
469 469 {
470 470 #ifndef __lock_lint
471 471 _NOTE(ARGUNUSED(var))
472 472 #endif
473 473 pMpi2PortEnableRequest_t enable;
474 474 int numbytes;
475 475
476 476 bzero(memp, sizeof (*enable));
477 477 enable = (void *)memp;
478 478 ddi_put8(accessp, &enable->Function, MPI2_FUNCTION_PORT_ENABLE);
479 479 numbytes = sizeof (*enable);
480 480
481 481 /*
482 482 * Send message via handshake
483 483 */
484 484 if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
485 485 return (DDI_FAILURE);
486 486 }
487 487
488 488 return (DDI_SUCCESS);
489 489 }
490 490
491 491 static int
492 492 mptsas_ioc_do_enable_port_reply(mptsas_t *mpt, caddr_t memp, int var,
493 493 ddi_acc_handle_t accessp)
494 494 {
495 495 #ifndef __lock_lint
496 496 _NOTE(ARGUNUSED(var))
497 497 #endif
498 498
499 499 int numbytes;
500 500 uint_t iocstatus;
501 501 pMpi2PortEnableReply_t portreply;
502 502
503 503 numbytes = sizeof (MPI2_PORT_ENABLE_REPLY);
504 504 bzero(memp, numbytes);
505 505 portreply = (void *)memp;
506 506
507 507 /*
508 508 * Get message via handshake
509 509 */
510 510 if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
511 511 return (DDI_FAILURE);
512 512 }
513 513
514 514 if (iocstatus = ddi_get16(accessp, &portreply->IOCStatus)) {
515 515 mptsas_log(mpt, CE_WARN, "mptsas_ioc_do_enable_port_reply: "
516 516 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
517 517 ddi_get32(accessp, &portreply->IOCLogInfo));
518 518 return (DDI_FAILURE);
519 519 }
520 520
521 521 return (DDI_SUCCESS);
522 522 }
523 523
524 524 int
525 525 mptsas_ioc_enable_event_notification(mptsas_t *mpt)
526 526 {
527 527 ASSERT(mutex_owned(&mpt->m_mutex));
528 528
529 529 /*
530 530 * Send enable event notification message
531 531 */
532 532 if (mptsas_do_dma(mpt, sizeof (MPI2_EVENT_NOTIFICATION_REQUEST), NULL,
533 533 mptsas_ioc_do_enable_event_notification)) {
534 534 return (DDI_FAILURE);
535 535 }
536 536
537 537 /*
538 538 * Get enable event reply message
539 539 */
540 540 if (mptsas_do_dma(mpt, sizeof (MPI2_EVENT_NOTIFICATION_REPLY), NULL,
541 541 mptsas_ioc_do_enable_event_notification_reply)) {
542 542 return (DDI_FAILURE);
543 543 }
544 544
545 545 return (DDI_SUCCESS);
546 546 }
547 547
548 548 static int
549 549 mptsas_ioc_do_enable_event_notification(mptsas_t *mpt, caddr_t memp, int var,
550 550 ddi_acc_handle_t accessp)
551 551 {
552 552 #ifndef __lock_lint
553 553 _NOTE(ARGUNUSED(var))
554 554 #endif
555 555
556 556 pMpi2EventNotificationRequest_t event;
557 557 int numbytes;
558 558
559 559 bzero(memp, sizeof (*event));
560 560 event = (void *)memp;
561 561 ddi_put8(accessp, &event->Function, MPI2_FUNCTION_EVENT_NOTIFICATION);
562 562 numbytes = sizeof (*event);
563 563
564 564 /*
565 565 * Send message via handshake
566 566 */
567 567 if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
568 568 return (DDI_FAILURE);
569 569 }
570 570
571 571 return (DDI_SUCCESS);
572 572 }
573 573
574 574 static int
575 575 mptsas_ioc_do_enable_event_notification_reply(mptsas_t *mpt, caddr_t memp,
576 576 int var, ddi_acc_handle_t accessp)
577 577 {
578 578 #ifndef __lock_lint
579 579 _NOTE(ARGUNUSED(var))
580 580 #endif
581 581 int numbytes;
582 582 uint_t iocstatus;
583 583 pMpi2EventNotificationReply_t eventsreply;
584 584
585 585 numbytes = sizeof (MPI2_EVENT_NOTIFICATION_REPLY);
586 586 bzero(memp, numbytes);
587 587 eventsreply = (void *)memp;
588 588
589 589 /*
590 590 * Get message via handshake
591 591 */
592 592 if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
593 593 return (DDI_FAILURE);
594 594 }
595 595
596 596 if (iocstatus = ddi_get16(accessp, &eventsreply->IOCStatus)) {
597 597 mptsas_log(mpt, CE_WARN,
598 598 "mptsas_ioc_do_enable_event_notification_reply: "
599 599 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
600 600 ddi_get32(accessp, &eventsreply->IOCLogInfo));
601 601 return (DDI_FAILURE);
602 602 }
603 603
604 604 return (DDI_SUCCESS);
605 605 }
606 606
607 607 int
608 608 mptsas_ioc_init(mptsas_t *mpt)
609 609 {
610 610 /*
611 611 * Send ioc init message
612 612 */
613 613 if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_INIT_REQUEST), NULL,
614 614 mptsas_do_ioc_init)) {
615 615 return (DDI_FAILURE);
616 616 }
617 617
618 618 /*
619 619 * Get ioc init reply message
620 620 */
621 621 if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_INIT_REPLY), NULL,
622 622 mptsas_do_ioc_init_reply)) {
623 623 return (DDI_FAILURE);
624 624 }
625 625
626 626 return (DDI_SUCCESS);
627 627 }
628 628
629 629 static int
630 630 mptsas_do_ioc_init(mptsas_t *mpt, caddr_t memp, int var,
631 631 ddi_acc_handle_t accessp)
632 632 {
633 633 #ifndef __lock_lint
634 634 _NOTE(ARGUNUSED(var))
635 635 #endif
636 636
637 637 pMpi2IOCInitRequest_t init;
638 638 int numbytes;
639 639 timespec_t time;
640 640 uint64_t mSec;
641 641
642 642 bzero(memp, sizeof (*init));
643 643 init = (void *)memp;
644 644 ddi_put8(accessp, &init->Function, MPI2_FUNCTION_IOC_INIT);
645 645 ddi_put8(accessp, &init->WhoInit, MPI2_WHOINIT_HOST_DRIVER);
646 646 ddi_put16(accessp, &init->MsgVersion, MPI2_VERSION);
647 647 ddi_put16(accessp, &init->HeaderVersion, MPI2_HEADER_VERSION);
648 648 ddi_put16(accessp, &init->SystemRequestFrameSize,
649 649 mpt->m_req_frame_size / 4);
650 650 ddi_put16(accessp, &init->ReplyDescriptorPostQueueDepth,
651 651 mpt->m_post_queue_depth);
652 652 ddi_put16(accessp, &init->ReplyFreeQueueDepth,
653 653 mpt->m_free_queue_depth);
654 654
655 655 /*
656 656 * These addresses are set using the DMA cookie addresses from when the
657 657 * memory was allocated. Sense buffer hi address should be 0.
658 658 */
659 659 ddi_put32(accessp, &init->SenseBufferAddressHigh,
660 660 (uint32_t)(mpt->m_req_sense_dma_addr >> 32));
661 661 ddi_put32(accessp, &init->SystemReplyAddressHigh,
662 662 (uint32_t)(mpt->m_reply_frame_dma_addr >> 32));
663 663 ddi_put32(accessp, &init->SystemRequestFrameBaseAddress.High,
664 664 (uint32_t)(mpt->m_req_frame_dma_addr >> 32));
665 665 ddi_put32(accessp, &init->SystemRequestFrameBaseAddress.Low,
666 666 (uint32_t)mpt->m_req_frame_dma_addr);
667 667 ddi_put32(accessp, &init->ReplyDescriptorPostQueueAddress.High,
668 668 (uint32_t)(mpt->m_post_queue_dma_addr >> 32));
669 669 ddi_put32(accessp, &init->ReplyDescriptorPostQueueAddress.Low,
670 670 (uint32_t)mpt->m_post_queue_dma_addr);
671 671 ddi_put32(accessp, &init->ReplyFreeQueueAddress.High,
672 672 (uint32_t)(mpt->m_free_queue_dma_addr >> 32));
673 673 ddi_put32(accessp, &init->ReplyFreeQueueAddress.Low,
674 674 (uint32_t)mpt->m_free_queue_dma_addr);
675 675
676 676 /*
677 677 * Fill in the timestamp with the number of milliseconds since midnight
678 678 * of January 1, 1970 UT (Greenwich Mean Time). Time is returned in
679 679 * seconds and nanoseconds. Translate both to milliseconds and add
680 680 * them together to get total milliseconds.
681 681 */
682 682 gethrestime(&time);
683 683 mSec = time.tv_sec * MILLISEC;
684 684 mSec += (time.tv_nsec / MICROSEC);
685 685 ddi_put32(accessp, &init->TimeStamp.High, (uint32_t)(mSec >> 32));
686 686 ddi_put32(accessp, &init->TimeStamp.Low, (uint32_t)mSec);
687 687
688 688 numbytes = sizeof (*init);
689 689
690 690 /*
691 691 * Post message via handshake
692 692 */
693 693 if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
694 694 return (DDI_FAILURE);
695 695 }
696 696
697 697 return (DDI_SUCCESS);
698 698 }
699 699
700 700 static int
701 701 mptsas_do_ioc_init_reply(mptsas_t *mpt, caddr_t memp, int var,
702 702 ddi_acc_handle_t accessp)
703 703 {
704 704 #ifndef __lock_lint
705 705 _NOTE(ARGUNUSED(var))
706 706 #endif
707 707
708 708 pMpi2IOCInitReply_t initreply;
709 709 int numbytes;
710 710 uint_t iocstatus;
711 711
712 712 numbytes = sizeof (MPI2_IOC_INIT_REPLY);
713 713 bzero(memp, numbytes);
714 714 initreply = (void *)memp;
715 715
716 716 /*
717 717 * Get reply message via handshake
718 718 */
719 719 if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
720 720 return (DDI_FAILURE);
721 721 }
722 722
723 723 if (iocstatus = ddi_get16(accessp, &initreply->IOCStatus)) {
724 724 mptsas_log(mpt, CE_WARN, "mptsas_do_ioc_init_reply: "
725 725 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
726 726 ddi_get32(accessp, &initreply->IOCLogInfo));
727 727 return (DDI_FAILURE);
728 728 }
729 729
730 730 if ((ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell)) &
731 731 MPI2_IOC_STATE_OPERATIONAL) {
732 732 mptsas_log(mpt, CE_NOTE,
733 733 "?mpt%d: IOC Operational.\n", mpt->m_instance);
734 734 } else {
735 735 return (DDI_FAILURE);
736 736 }
737 737
738 738 return (DDI_SUCCESS);
739 739 }
↓ open down ↓ |
739 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX