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