Print this page
fixup .text where possible
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/mr_sas/mr_sas.c
+++ new/usr/src/uts/common/io/mr_sas/mr_sas.c
1 1 /*
2 2 * mr_sas.c: source for mr_sas driver
3 3 *
4 4 * Solaris MegaRAID device driver for SAS2.0 controllers
5 5 * Copyright (c) 2008-2012, LSI Logic Corporation.
6 6 * All rights reserved.
7 7 *
8 8 * Version:
9 9 * Author:
10 10 * Swaminathan K S
11 11 * Arun Chandrashekhar
12 12 * Manju R
13 13 * Rasheed
14 14 * Shakeel Bukhari
15 15 *
16 16 * Redistribution and use in source and binary forms, with or without
17 17 * modification, are permitted provided that the following conditions are met:
18 18 *
19 19 * 1. Redistributions of source code must retain the above copyright notice,
20 20 * this list of conditions and the following disclaimer.
21 21 *
22 22 * 2. Redistributions in binary form must reproduce the above copyright notice,
23 23 * this list of conditions and the following disclaimer in the documentation
24 24 * and/or other materials provided with the distribution.
25 25 *
26 26 * 3. Neither the name of the author nor the names of its contributors may be
27 27 * used to endorse or promote products derived from this software without
28 28 * specific prior written permission.
29 29 *
30 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 34 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 36 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
37 37 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
38 38 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39 39 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
40 40 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
41 41 * DAMAGE.
42 42 */
43 43
44 44 /*
45 45 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
46 46 * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
47 47 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
48 48 * Copyright 2015 Citrus IT Limited. All rights reserved.
49 49 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
50 50 */
51 51
52 52 #include <sys/types.h>
53 53 #include <sys/param.h>
54 54 #include <sys/file.h>
55 55 #include <sys/errno.h>
56 56 #include <sys/open.h>
57 57 #include <sys/cred.h>
58 58 #include <sys/modctl.h>
59 59 #include <sys/conf.h>
60 60 #include <sys/devops.h>
61 61 #include <sys/cmn_err.h>
62 62 #include <sys/kmem.h>
63 63 #include <sys/stat.h>
64 64 #include <sys/mkdev.h>
65 65 #include <sys/pci.h>
66 66 #include <sys/scsi/scsi.h>
67 67 #include <sys/ddi.h>
68 68 #include <sys/sunddi.h>
69 69 #include <sys/atomic.h>
70 70 #include <sys/signal.h>
71 71 #include <sys/byteorder.h>
72 72 #include <sys/sdt.h>
73 73 #include <sys/fs/dv_node.h> /* devfs_clean */
74 74
75 75 #include "mr_sas.h"
76 76
77 77 /*
78 78 * FMA header files
79 79 */
80 80 #include <sys/ddifm.h>
81 81 #include <sys/fm/protocol.h>
82 82 #include <sys/fm/util.h>
83 83 #include <sys/fm/io/ddi.h>
84 84
85 85 /* Macros to help Skinny and stock 2108/MFI live together. */
86 86 #define WR_IB_PICK_QPORT(addr, instance) \
87 87 if ((instance)->skinny) { \
88 88 WR_IB_LOW_QPORT((addr), (instance)); \
89 89 WR_IB_HIGH_QPORT(0, (instance)); \
90 90 } else { \
91 91 WR_IB_QPORT((addr), (instance)); \
92 92 }
93 93
94 94 /*
95 95 * Local static data
96 96 */
97 97 static void *mrsas_state = NULL;
98 98 static volatile boolean_t mrsas_relaxed_ordering = B_TRUE;
99 99 volatile int debug_level_g = CL_NONE;
100 100 static volatile int msi_enable = 1;
101 101 static volatile int ctio_enable = 1;
102 102
103 103 /* Default Timeout value to issue online controller reset */
104 104 volatile int debug_timeout_g = 0xF0; /* 0xB4; */
105 105 /* Simulate consecutive firmware fault */
106 106 static volatile int debug_fw_faults_after_ocr_g = 0;
107 107 #ifdef OCRDEBUG
108 108 /* Simulate three consecutive timeout for an IO */
109 109 static volatile int debug_consecutive_timeout_after_ocr_g = 0;
110 110 #endif
111 111
112 112 #pragma weak scsi_hba_open
113 113 #pragma weak scsi_hba_close
114 114 #pragma weak scsi_hba_ioctl
115 115
116 116 /* Local static prototypes. */
117 117 static int mrsas_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
118 118 static int mrsas_attach(dev_info_t *, ddi_attach_cmd_t);
119 119 #ifdef __sparc
120 120 static int mrsas_reset(dev_info_t *, ddi_reset_cmd_t);
121 121 #else
122 122 static int mrsas_quiesce(dev_info_t *);
123 123 #endif
124 124 static int mrsas_detach(dev_info_t *, ddi_detach_cmd_t);
125 125 static int mrsas_open(dev_t *, int, int, cred_t *);
126 126 static int mrsas_close(dev_t, int, int, cred_t *);
127 127 static int mrsas_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
128 128
129 129 static int mrsas_tran_tgt_init(dev_info_t *, dev_info_t *,
130 130 scsi_hba_tran_t *, struct scsi_device *);
131 131 static struct scsi_pkt *mrsas_tran_init_pkt(struct scsi_address *, register
132 132 struct scsi_pkt *, struct buf *, int, int, int, int,
133 133 int (*)(), caddr_t);
134 134 static int mrsas_tran_start(struct scsi_address *,
135 135 register struct scsi_pkt *);
136 136 static int mrsas_tran_abort(struct scsi_address *, struct scsi_pkt *);
137 137 static int mrsas_tran_reset(struct scsi_address *, int);
138 138 static int mrsas_tran_getcap(struct scsi_address *, char *, int);
139 139 static int mrsas_tran_setcap(struct scsi_address *, char *, int, int);
140 140 static void mrsas_tran_destroy_pkt(struct scsi_address *,
141 141 struct scsi_pkt *);
142 142 static void mrsas_tran_dmafree(struct scsi_address *, struct scsi_pkt *);
143 143 static void mrsas_tran_sync_pkt(struct scsi_address *, struct scsi_pkt *);
144 144 static int mrsas_tran_quiesce(dev_info_t *dip);
145 145 static int mrsas_tran_unquiesce(dev_info_t *dip);
146 146 static uint_t mrsas_isr();
147 147 static uint_t mrsas_softintr();
148 148 static void mrsas_undo_resources(dev_info_t *, struct mrsas_instance *);
149 149
150 150 static void free_space_for_mfi(struct mrsas_instance *);
151 151 static uint32_t read_fw_status_reg_ppc(struct mrsas_instance *);
152 152 static void issue_cmd_ppc(struct mrsas_cmd *, struct mrsas_instance *);
153 153 static int issue_cmd_in_poll_mode_ppc(struct mrsas_instance *,
154 154 struct mrsas_cmd *);
155 155 static int issue_cmd_in_sync_mode_ppc(struct mrsas_instance *,
156 156 struct mrsas_cmd *);
157 157 static void enable_intr_ppc(struct mrsas_instance *);
158 158 static void disable_intr_ppc(struct mrsas_instance *);
159 159 static int intr_ack_ppc(struct mrsas_instance *);
160 160 static void flush_cache(struct mrsas_instance *instance);
161 161 void display_scsi_inquiry(caddr_t);
162 162 static int start_mfi_aen(struct mrsas_instance *instance);
163 163 static int handle_drv_ioctl(struct mrsas_instance *instance,
164 164 struct mrsas_ioctl *ioctl, int mode);
165 165 static int handle_mfi_ioctl(struct mrsas_instance *instance,
166 166 struct mrsas_ioctl *ioctl, int mode);
167 167 static int handle_mfi_aen(struct mrsas_instance *instance,
168 168 struct mrsas_aen *aen);
169 169 static struct mrsas_cmd *build_cmd(struct mrsas_instance *,
170 170 struct scsi_address *, struct scsi_pkt *, uchar_t *);
171 171 static int alloc_additional_dma_buffer(struct mrsas_instance *);
172 172 static void complete_cmd_in_sync_mode(struct mrsas_instance *,
173 173 struct mrsas_cmd *);
174 174 static int mrsas_kill_adapter(struct mrsas_instance *);
175 175 static int mrsas_issue_init_mfi(struct mrsas_instance *);
176 176 static int mrsas_reset_ppc(struct mrsas_instance *);
177 177 static uint32_t mrsas_initiate_ocr_if_fw_is_faulty(struct mrsas_instance *);
178 178 static int wait_for_outstanding(struct mrsas_instance *instance);
179 179 static int register_mfi_aen(struct mrsas_instance *instance,
180 180 uint32_t seq_num, uint32_t class_locale_word);
181 181 static int issue_mfi_pthru(struct mrsas_instance *instance, struct
182 182 mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
183 183 static int issue_mfi_dcmd(struct mrsas_instance *instance, struct
184 184 mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
185 185 static int issue_mfi_smp(struct mrsas_instance *instance, struct
186 186 mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
187 187 static int issue_mfi_stp(struct mrsas_instance *instance, struct
188 188 mrsas_ioctl *ioctl, struct mrsas_cmd *cmd, int mode);
189 189 static int abort_aen_cmd(struct mrsas_instance *instance,
190 190 struct mrsas_cmd *cmd_to_abort);
191 191
192 192 static void mrsas_rem_intrs(struct mrsas_instance *instance);
193 193 static int mrsas_add_intrs(struct mrsas_instance *instance, int intr_type);
194 194
195 195 static void mrsas_tran_tgt_free(dev_info_t *, dev_info_t *,
196 196 scsi_hba_tran_t *, struct scsi_device *);
197 197 static int mrsas_tran_bus_config(dev_info_t *, uint_t,
198 198 ddi_bus_config_op_t, void *, dev_info_t **);
199 199 static int mrsas_parse_devname(char *, int *, int *);
200 200 static int mrsas_config_all_devices(struct mrsas_instance *);
201 201 static int mrsas_config_ld(struct mrsas_instance *, uint16_t,
202 202 uint8_t, dev_info_t **);
203 203 static int mrsas_name_node(dev_info_t *, char *, int);
204 204 static void mrsas_issue_evt_taskq(struct mrsas_eventinfo *);
205 205 static void free_additional_dma_buffer(struct mrsas_instance *);
206 206 static void io_timeout_checker(void *);
207 207 static void mrsas_fm_init(struct mrsas_instance *);
208 208 static void mrsas_fm_fini(struct mrsas_instance *);
209 209
210 210 static struct mrsas_function_template mrsas_function_template_ppc = {
211 211 .read_fw_status_reg = read_fw_status_reg_ppc,
212 212 .issue_cmd = issue_cmd_ppc,
213 213 .issue_cmd_in_sync_mode = issue_cmd_in_sync_mode_ppc,
214 214 .issue_cmd_in_poll_mode = issue_cmd_in_poll_mode_ppc,
215 215 .enable_intr = enable_intr_ppc,
216 216 .disable_intr = disable_intr_ppc,
217 217 .intr_ack = intr_ack_ppc,
218 218 .init_adapter = mrsas_init_adapter_ppc
219 219 };
220 220
221 221
222 222 static struct mrsas_function_template mrsas_function_template_fusion = {
223 223 .read_fw_status_reg = tbolt_read_fw_status_reg,
224 224 .issue_cmd = tbolt_issue_cmd,
225 225 .issue_cmd_in_sync_mode = tbolt_issue_cmd_in_sync_mode,
226 226 .issue_cmd_in_poll_mode = tbolt_issue_cmd_in_poll_mode,
227 227 .enable_intr = tbolt_enable_intr,
228 228 .disable_intr = tbolt_disable_intr,
229 229 .intr_ack = tbolt_intr_ack,
230 230 .init_adapter = mrsas_init_adapter_tbolt
231 231 };
232 232
233 233
234 234 ddi_dma_attr_t mrsas_generic_dma_attr = {
235 235 DMA_ATTR_V0, /* dma_attr_version */
236 236 0, /* low DMA address range */
237 237 0xFFFFFFFFU, /* high DMA address range */
238 238 0xFFFFFFFFU, /* DMA counter register */
239 239 8, /* DMA address alignment */
240 240 0x07, /* DMA burstsizes */
241 241 1, /* min DMA size */
242 242 0xFFFFFFFFU, /* max DMA size */
243 243 0xFFFFFFFFU, /* segment boundary */
244 244 MRSAS_MAX_SGE_CNT, /* dma_attr_sglen */
245 245 512, /* granularity of device */
246 246 0 /* bus specific DMA flags */
247 247 };
248 248
249 249 int32_t mrsas_max_cap_maxxfer = 0x1000000;
250 250
251 251 /*
252 252 * Fix for: Thunderbolt controller IO timeout when IO write size is 1MEG,
253 253 * Limit size to 256K
254 254 */
255 255 uint32_t mrsas_tbolt_max_cap_maxxfer = (512 * 512);
256 256
257 257 /*
258 258 * cb_ops contains base level routines
259 259 */
260 260 static struct cb_ops mrsas_cb_ops = {
261 261 mrsas_open, /* open */
262 262 mrsas_close, /* close */
263 263 nodev, /* strategy */
264 264 nodev, /* print */
265 265 nodev, /* dump */
266 266 nodev, /* read */
267 267 nodev, /* write */
268 268 mrsas_ioctl, /* ioctl */
269 269 nodev, /* devmap */
270 270 nodev, /* mmap */
271 271 nodev, /* segmap */
272 272 nochpoll, /* poll */
273 273 nodev, /* cb_prop_op */
274 274 0, /* streamtab */
275 275 D_NEW | D_HOTPLUG, /* cb_flag */
276 276 CB_REV, /* cb_rev */
277 277 nodev, /* cb_aread */
278 278 nodev /* cb_awrite */
279 279 };
280 280
281 281 /*
282 282 * dev_ops contains configuration routines
283 283 */
284 284 static struct dev_ops mrsas_ops = {
285 285 DEVO_REV, /* rev, */
286 286 0, /* refcnt */
287 287 mrsas_getinfo, /* getinfo */
288 288 nulldev, /* identify */
289 289 nulldev, /* probe */
290 290 mrsas_attach, /* attach */
291 291 mrsas_detach, /* detach */
292 292 #ifdef __sparc
293 293 mrsas_reset, /* reset */
294 294 #else /* __sparc */
295 295 nodev,
296 296 #endif /* __sparc */
297 297 &mrsas_cb_ops, /* char/block ops */
298 298 NULL, /* bus ops */
299 299 NULL, /* power */
300 300 #ifdef __sparc
301 301 ddi_quiesce_not_needed
302 302 #else /* __sparc */
303 303 mrsas_quiesce /* quiesce */
↓ open down ↓ |
303 lines elided |
↑ open up ↑ |
304 304 #endif /* __sparc */
305 305 };
306 306
307 307 static struct modldrv modldrv = {
308 308 &mod_driverops, /* module type - driver */
309 309 MRSAS_VERSION,
310 310 &mrsas_ops, /* driver ops */
311 311 };
312 312
313 313 static struct modlinkage modlinkage = {
314 - MODREV_1, /* ml_rev - must be MODREV_1 */
315 - &modldrv, /* ml_linkage */
316 - NULL /* end of driver linkage */
314 + MODREV_1, /* ml_rev - must be MODREV_1 */
315 + { &modldrv, /* ml_linkage */
316 + NULL }
317 317 };
318 318
319 319 static struct ddi_device_acc_attr endian_attr = {
320 320 DDI_DEVICE_ATTR_V1,
321 321 DDI_STRUCTURE_LE_ACC,
322 322 DDI_STRICTORDER_ACC,
323 323 DDI_DEFAULT_ACC
324 324 };
325 325
326 326 /* Use the LSI Fast Path for the 2208 (tbolt) commands. */
327 327 unsigned int enable_fp = 1;
328 328
329 329
330 330 /*
331 331 * ************************************************************************** *
332 332 * *
333 333 * common entry points - for loadable kernel modules *
334 334 * *
335 335 * ************************************************************************** *
336 336 */
337 337
338 338 /*
339 339 * _init - initialize a loadable module
340 340 * @void
341 341 *
342 342 * The driver should perform any one-time resource allocation or data
343 343 * initialization during driver loading in _init(). For example, the driver
344 344 * should initialize any mutexes global to the driver in this routine.
345 345 * The driver should not, however, use _init() to allocate or initialize
346 346 * anything that has to do with a particular instance of the device.
347 347 * Per-instance initialization must be done in attach().
348 348 */
349 349 int
350 350 _init(void)
351 351 {
352 352 int ret;
353 353
354 354 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
355 355
356 356 ret = ddi_soft_state_init(&mrsas_state,
357 357 sizeof (struct mrsas_instance), 0);
358 358
359 359 if (ret != DDI_SUCCESS) {
360 360 cmn_err(CE_WARN, "mr_sas: could not init state");
361 361 return (ret);
362 362 }
363 363
364 364 if ((ret = scsi_hba_init(&modlinkage)) != DDI_SUCCESS) {
365 365 cmn_err(CE_WARN, "mr_sas: could not init scsi hba");
366 366 ddi_soft_state_fini(&mrsas_state);
367 367 return (ret);
368 368 }
369 369
370 370 ret = mod_install(&modlinkage);
371 371
372 372 if (ret != DDI_SUCCESS) {
373 373 cmn_err(CE_WARN, "mr_sas: mod_install failed");
374 374 scsi_hba_fini(&modlinkage);
375 375 ddi_soft_state_fini(&mrsas_state);
376 376 }
377 377
378 378 return (ret);
379 379 }
380 380
381 381 /*
382 382 * _info - returns information about a loadable module.
383 383 * @void
384 384 *
385 385 * _info() is called to return module information. This is a typical entry
386 386 * point that does predefined role. It simply calls mod_info().
387 387 */
388 388 int
389 389 _info(struct modinfo *modinfop)
390 390 {
391 391 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
392 392
393 393 return (mod_info(&modlinkage, modinfop));
394 394 }
395 395
396 396 /*
397 397 * _fini - prepare a loadable module for unloading
398 398 * @void
399 399 *
400 400 * In _fini(), the driver should release any resources that were allocated in
401 401 * _init(). The driver must remove itself from the system module list.
402 402 */
403 403 int
404 404 _fini(void)
405 405 {
406 406 int ret;
407 407
408 408 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
409 409
410 410 if ((ret = mod_remove(&modlinkage)) != DDI_SUCCESS) {
411 411 con_log(CL_ANN1,
412 412 (CE_WARN, "_fini: mod_remove() failed, error 0x%X", ret));
413 413 return (ret);
414 414 }
415 415
416 416 scsi_hba_fini(&modlinkage);
417 417 con_log(CL_DLEVEL1, (CE_NOTE, "_fini: scsi_hba_fini() done."));
418 418
419 419 ddi_soft_state_fini(&mrsas_state);
420 420 con_log(CL_DLEVEL1, (CE_NOTE, "_fini: ddi_soft_state_fini() done."));
421 421
422 422 return (ret);
423 423 }
424 424
425 425
426 426 /*
427 427 * ************************************************************************** *
428 428 * *
429 429 * common entry points - for autoconfiguration *
430 430 * *
431 431 * ************************************************************************** *
432 432 */
433 433 /*
434 434 * attach - adds a device to the system as part of initialization
435 435 * @dip:
436 436 * @cmd:
437 437 *
438 438 * The kernel calls a driver's attach() entry point to attach an instance of
439 439 * a device (for MegaRAID, it is instance of a controller) or to resume
440 440 * operation for an instance of a device that has been suspended or has been
441 441 * shut down by the power management framework
442 442 * The attach() entry point typically includes the following types of
443 443 * processing:
444 444 * - allocate a soft-state structure for the device instance (for MegaRAID,
445 445 * controller instance)
446 446 * - initialize per-instance mutexes
447 447 * - initialize condition variables
448 448 * - register the device's interrupts (for MegaRAID, controller's interrupts)
449 449 * - map the registers and memory of the device instance (for MegaRAID,
450 450 * controller instance)
451 451 * - create minor device nodes for the device instance (for MegaRAID,
452 452 * controller instance)
453 453 * - report that the device instance (for MegaRAID, controller instance) has
454 454 * attached
455 455 */
456 456 static int
457 457 mrsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
458 458 {
459 459 int instance_no;
460 460 int nregs;
461 461 int i = 0;
462 462 uint8_t irq;
463 463 uint16_t vendor_id;
464 464 uint16_t device_id;
465 465 uint16_t subsysvid;
466 466 uint16_t subsysid;
467 467 uint16_t command;
468 468 off_t reglength = 0;
469 469 int intr_types = 0;
470 470 char *data;
471 471
472 472 scsi_hba_tran_t *tran;
473 473 ddi_dma_attr_t tran_dma_attr;
474 474 struct mrsas_instance *instance;
475 475
476 476 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
477 477
478 478 /* CONSTCOND */
479 479 ASSERT(NO_COMPETING_THREADS);
480 480
481 481 instance_no = ddi_get_instance(dip);
482 482
483 483 /*
484 484 * check to see whether this device is in a DMA-capable slot.
485 485 */
486 486 if (ddi_slaveonly(dip) == DDI_SUCCESS) {
487 487 dev_err(dip, CE_WARN, "Device in slave-only slot, unused");
488 488 return (DDI_FAILURE);
489 489 }
490 490
491 491 switch (cmd) {
492 492 case DDI_ATTACH:
493 493 /* allocate the soft state for the instance */
494 494 if (ddi_soft_state_zalloc(mrsas_state, instance_no)
495 495 != DDI_SUCCESS) {
496 496 dev_err(dip, CE_WARN, "Failed to allocate soft state");
497 497 return (DDI_FAILURE);
498 498 }
499 499
500 500 instance = (struct mrsas_instance *)ddi_get_soft_state
501 501 (mrsas_state, instance_no);
502 502
503 503 if (instance == NULL) {
504 504 dev_err(dip, CE_WARN, "Bad soft state");
505 505 ddi_soft_state_free(mrsas_state, instance_no);
506 506 return (DDI_FAILURE);
507 507 }
508 508
509 509 instance->unroll.softs = 1;
510 510
511 511 /* Setup the PCI configuration space handles */
512 512 if (pci_config_setup(dip, &instance->pci_handle) !=
513 513 DDI_SUCCESS) {
514 514 dev_err(dip, CE_WARN, "pci config setup failed");
515 515
516 516 ddi_soft_state_free(mrsas_state, instance_no);
517 517 return (DDI_FAILURE);
518 518 }
519 519
520 520 if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) {
521 521 dev_err(dip, CE_WARN, "Failed to get registers");
522 522
523 523 pci_config_teardown(&instance->pci_handle);
524 524 ddi_soft_state_free(mrsas_state, instance_no);
525 525 return (DDI_FAILURE);
526 526 }
527 527
528 528 vendor_id = pci_config_get16(instance->pci_handle,
529 529 PCI_CONF_VENID);
530 530 device_id = pci_config_get16(instance->pci_handle,
531 531 PCI_CONF_DEVID);
532 532
533 533 subsysvid = pci_config_get16(instance->pci_handle,
534 534 PCI_CONF_SUBVENID);
535 535 subsysid = pci_config_get16(instance->pci_handle,
536 536 PCI_CONF_SUBSYSID);
537 537
538 538 pci_config_put16(instance->pci_handle, PCI_CONF_COMM,
539 539 (pci_config_get16(instance->pci_handle,
540 540 PCI_CONF_COMM) | PCI_COMM_ME));
541 541 irq = pci_config_get8(instance->pci_handle,
542 542 PCI_CONF_ILINE);
543 543
544 544 dev_err(dip, CE_CONT,
545 545 "?0x%x:0x%x 0x%x:0x%x, irq:%d drv-ver:%s\n",
546 546 vendor_id, device_id, subsysvid,
547 547 subsysid, irq, MRSAS_VERSION);
548 548
549 549 /* enable bus-mastering */
550 550 command = pci_config_get16(instance->pci_handle,
551 551 PCI_CONF_COMM);
552 552
553 553 if (!(command & PCI_COMM_ME)) {
554 554 command |= PCI_COMM_ME;
555 555
556 556 pci_config_put16(instance->pci_handle,
557 557 PCI_CONF_COMM, command);
558 558
559 559 con_log(CL_ANN, (CE_CONT, "mr_sas%d: "
560 560 "enable bus-mastering", instance_no));
561 561 } else {
562 562 con_log(CL_DLEVEL1, (CE_CONT, "mr_sas%d: "
563 563 "bus-mastering already set", instance_no));
564 564 }
565 565
566 566 /* initialize function pointers */
567 567 switch (device_id) {
568 568 case PCI_DEVICE_ID_LSI_TBOLT:
569 569 case PCI_DEVICE_ID_LSI_INVADER:
570 570 case PCI_DEVICE_ID_LSI_FURY:
571 571 dev_err(dip, CE_CONT, "?TBOLT device detected\n");
572 572
573 573 instance->func_ptr =
574 574 &mrsas_function_template_fusion;
575 575 instance->tbolt = 1;
576 576 break;
577 577
578 578 case PCI_DEVICE_ID_LSI_SKINNY:
579 579 case PCI_DEVICE_ID_LSI_SKINNY_NEW:
580 580 /*
581 581 * FALLTHRU to PPC-style functions, but mark this
582 582 * instance as Skinny, because the register set is
583 583 * slightly different (See WR_IB_PICK_QPORT), and
584 584 * certain other features are available to a Skinny
585 585 * HBA.
586 586 */
587 587 instance->skinny = 1;
588 588 /* FALLTHRU */
589 589
590 590 case PCI_DEVICE_ID_LSI_2108VDE:
591 591 case PCI_DEVICE_ID_LSI_2108V:
592 592 dev_err(dip, CE_CONT,
593 593 "?2108 Liberator device detected\n");
594 594
595 595 instance->func_ptr =
596 596 &mrsas_function_template_ppc;
597 597 break;
598 598
599 599 default:
600 600 dev_err(dip, CE_WARN, "Invalid device detected");
601 601
602 602 pci_config_teardown(&instance->pci_handle);
603 603 ddi_soft_state_free(mrsas_state, instance_no);
604 604 return (DDI_FAILURE);
605 605 }
606 606
607 607 instance->baseaddress = pci_config_get32(
608 608 instance->pci_handle, PCI_CONF_BASE0);
609 609 instance->baseaddress &= 0x0fffc;
610 610
611 611 instance->dip = dip;
612 612 instance->vendor_id = vendor_id;
613 613 instance->device_id = device_id;
614 614 instance->subsysvid = subsysvid;
615 615 instance->subsysid = subsysid;
616 616 instance->instance = instance_no;
617 617
618 618 /* Initialize FMA */
619 619 instance->fm_capabilities = ddi_prop_get_int(
620 620 DDI_DEV_T_ANY, instance->dip, DDI_PROP_DONTPASS,
621 621 "fm-capable", DDI_FM_EREPORT_CAPABLE |
622 622 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE
623 623 | DDI_FM_ERRCB_CAPABLE);
624 624
625 625 mrsas_fm_init(instance);
626 626
627 627 /* Setup register map */
628 628 if ((ddi_dev_regsize(instance->dip,
629 629 REGISTER_SET_IO_2108, ®length) != DDI_SUCCESS) ||
630 630 reglength < MINIMUM_MFI_MEM_SZ) {
631 631 goto fail_attach;
632 632 }
633 633 if (reglength > DEFAULT_MFI_MEM_SZ) {
634 634 reglength = DEFAULT_MFI_MEM_SZ;
635 635 con_log(CL_DLEVEL1, (CE_NOTE,
636 636 "mr_sas: register length to map is 0x%lx bytes",
637 637 reglength));
638 638 }
639 639 if (ddi_regs_map_setup(instance->dip,
640 640 REGISTER_SET_IO_2108, &instance->regmap, 0,
641 641 reglength, &endian_attr, &instance->regmap_handle)
642 642 != DDI_SUCCESS) {
643 643 dev_err(dip, CE_WARN, "couldn't map control registers");
644 644 goto fail_attach;
645 645 }
646 646
647 647 instance->unroll.regs = 1;
648 648
649 649 /*
650 650 * Disable Interrupt Now.
651 651 * Setup Software interrupt
652 652 */
653 653 instance->func_ptr->disable_intr(instance);
654 654
655 655 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
656 656 "mrsas-enable-msi", &data) == DDI_SUCCESS) {
657 657 if (strncmp(data, "no", 3) == 0) {
658 658 msi_enable = 0;
659 659 con_log(CL_ANN1, (CE_WARN,
660 660 "msi_enable = %d disabled", msi_enable));
661 661 }
662 662 ddi_prop_free(data);
663 663 }
664 664
665 665 dev_err(dip, CE_CONT, "?msi_enable = %d\n", msi_enable);
666 666
667 667 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
668 668 "mrsas-enable-fp", &data) == DDI_SUCCESS) {
669 669 if (strncmp(data, "no", 3) == 0) {
670 670 enable_fp = 0;
671 671 dev_err(dip, CE_NOTE,
672 672 "enable_fp = %d, Fast-Path disabled.\n",
673 673 enable_fp);
674 674 }
675 675
676 676 ddi_prop_free(data);
677 677 }
678 678
679 679 dev_err(dip, CE_CONT, "?enable_fp = %d\n", enable_fp);
680 680
681 681 /* Check for all supported interrupt types */
682 682 if (ddi_intr_get_supported_types(
683 683 dip, &intr_types) != DDI_SUCCESS) {
684 684 dev_err(dip, CE_WARN,
685 685 "ddi_intr_get_supported_types() failed");
686 686 goto fail_attach;
687 687 }
688 688
689 689 con_log(CL_DLEVEL1, (CE_NOTE,
690 690 "ddi_intr_get_supported_types() ret: 0x%x", intr_types));
691 691
692 692 /* Initialize and Setup Interrupt handler */
693 693 if (msi_enable && (intr_types & DDI_INTR_TYPE_MSIX)) {
694 694 if (mrsas_add_intrs(instance, DDI_INTR_TYPE_MSIX) !=
695 695 DDI_SUCCESS) {
696 696 dev_err(dip, CE_WARN,
697 697 "MSIX interrupt query failed");
698 698 goto fail_attach;
699 699 }
700 700 instance->intr_type = DDI_INTR_TYPE_MSIX;
701 701 } else if (msi_enable && (intr_types & DDI_INTR_TYPE_MSI)) {
702 702 if (mrsas_add_intrs(instance, DDI_INTR_TYPE_MSI) !=
703 703 DDI_SUCCESS) {
704 704 dev_err(dip, CE_WARN,
705 705 "MSI interrupt query failed");
706 706 goto fail_attach;
707 707 }
708 708 instance->intr_type = DDI_INTR_TYPE_MSI;
709 709 } else if (intr_types & DDI_INTR_TYPE_FIXED) {
710 710 msi_enable = 0;
711 711 if (mrsas_add_intrs(instance, DDI_INTR_TYPE_FIXED) !=
712 712 DDI_SUCCESS) {
713 713 dev_err(dip, CE_WARN,
714 714 "FIXED interrupt query failed");
715 715 goto fail_attach;
716 716 }
717 717 instance->intr_type = DDI_INTR_TYPE_FIXED;
718 718 } else {
719 719 dev_err(dip, CE_WARN, "Device cannot "
720 720 "suppport either FIXED or MSI/X "
721 721 "interrupts");
722 722 goto fail_attach;
723 723 }
724 724
725 725 instance->unroll.intr = 1;
726 726
727 727 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
728 728 "mrsas-enable-ctio", &data) == DDI_SUCCESS) {
729 729 if (strncmp(data, "no", 3) == 0) {
730 730 ctio_enable = 0;
731 731 con_log(CL_ANN1, (CE_WARN,
732 732 "ctio_enable = %d disabled", ctio_enable));
733 733 }
734 734 ddi_prop_free(data);
735 735 }
736 736
737 737 dev_err(dip, CE_CONT, "?ctio_enable = %d\n", ctio_enable);
738 738
739 739 /* setup the mfi based low level driver */
740 740 if (mrsas_init_adapter(instance) != DDI_SUCCESS) {
741 741 dev_err(dip, CE_WARN,
742 742 "could not initialize the low level driver");
743 743
744 744 goto fail_attach;
745 745 }
746 746
747 747 /* Initialize all Mutex */
748 748 INIT_LIST_HEAD(&instance->completed_pool_list);
749 749 mutex_init(&instance->completed_pool_mtx, NULL,
750 750 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
751 751
752 752 mutex_init(&instance->sync_map_mtx, NULL,
753 753 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
754 754
755 755 mutex_init(&instance->app_cmd_pool_mtx, NULL,
756 756 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
757 757
758 758 mutex_init(&instance->config_dev_mtx, NULL,
759 759 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
760 760
761 761 mutex_init(&instance->cmd_pend_mtx, NULL,
762 762 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
763 763
764 764 mutex_init(&instance->ocr_flags_mtx, NULL,
765 765 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
766 766
767 767 mutex_init(&instance->int_cmd_mtx, NULL,
768 768 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
769 769 cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL);
770 770
771 771 mutex_init(&instance->cmd_pool_mtx, NULL,
772 772 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
773 773
774 774 mutex_init(&instance->reg_write_mtx, NULL,
775 775 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
776 776
777 777 if (instance->tbolt) {
778 778 mutex_init(&instance->cmd_app_pool_mtx, NULL,
779 779 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
780 780
781 781 mutex_init(&instance->chip_mtx, NULL,
782 782 MUTEX_DRIVER, DDI_INTR_PRI(instance->intr_pri));
783 783
784 784 }
785 785
786 786 instance->unroll.mutexs = 1;
787 787
788 788 instance->timeout_id = (timeout_id_t)-1;
789 789
790 790 /* Register our soft-isr for highlevel interrupts. */
791 791 instance->isr_level = instance->intr_pri;
792 792 if (!(instance->tbolt)) {
793 793 if (instance->isr_level == HIGH_LEVEL_INTR) {
794 794 if (ddi_add_softintr(dip,
795 795 DDI_SOFTINT_HIGH,
796 796 &instance->soft_intr_id, NULL, NULL,
797 797 mrsas_softintr, (caddr_t)instance) !=
798 798 DDI_SUCCESS) {
799 799 dev_err(dip, CE_WARN,
800 800 "Software ISR did not register");
801 801
802 802 goto fail_attach;
803 803 }
804 804
805 805 instance->unroll.soft_isr = 1;
806 806
807 807 }
808 808 }
809 809
810 810 instance->softint_running = 0;
811 811
812 812 /* Allocate a transport structure */
813 813 tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
814 814
815 815 if (tran == NULL) {
816 816 dev_err(dip, CE_WARN,
817 817 "scsi_hba_tran_alloc failed");
818 818 goto fail_attach;
819 819 }
820 820
821 821 instance->tran = tran;
822 822 instance->unroll.tran = 1;
823 823
824 824 tran->tran_hba_private = instance;
825 825 tran->tran_tgt_init = mrsas_tran_tgt_init;
826 826 tran->tran_tgt_probe = scsi_hba_probe;
827 827 tran->tran_tgt_free = mrsas_tran_tgt_free;
828 828 tran->tran_init_pkt = mrsas_tran_init_pkt;
829 829 if (instance->tbolt)
830 830 tran->tran_start = mrsas_tbolt_tran_start;
831 831 else
832 832 tran->tran_start = mrsas_tran_start;
833 833 tran->tran_abort = mrsas_tran_abort;
834 834 tran->tran_reset = mrsas_tran_reset;
835 835 tran->tran_getcap = mrsas_tran_getcap;
836 836 tran->tran_setcap = mrsas_tran_setcap;
837 837 tran->tran_destroy_pkt = mrsas_tran_destroy_pkt;
838 838 tran->tran_dmafree = mrsas_tran_dmafree;
839 839 tran->tran_sync_pkt = mrsas_tran_sync_pkt;
840 840 tran->tran_quiesce = mrsas_tran_quiesce;
841 841 tran->tran_unquiesce = mrsas_tran_unquiesce;
842 842 tran->tran_bus_config = mrsas_tran_bus_config;
843 843
844 844 if (mrsas_relaxed_ordering)
845 845 mrsas_generic_dma_attr.dma_attr_flags |=
846 846 DDI_DMA_RELAXED_ORDERING;
847 847
848 848
849 849 tran_dma_attr = mrsas_generic_dma_attr;
850 850 tran_dma_attr.dma_attr_sgllen = instance->max_num_sge;
851 851
852 852 /* Attach this instance of the hba */
853 853 if (scsi_hba_attach_setup(dip, &tran_dma_attr, tran, 0)
854 854 != DDI_SUCCESS) {
855 855 dev_err(dip, CE_WARN,
856 856 "scsi_hba_attach failed");
857 857
858 858 goto fail_attach;
859 859 }
860 860 instance->unroll.tranSetup = 1;
861 861 con_log(CL_ANN1,
862 862 (CE_CONT, "scsi_hba_attach_setup() done."));
863 863
864 864 /* create devctl node for cfgadm command */
865 865 if (ddi_create_minor_node(dip, "devctl",
866 866 S_IFCHR, INST2DEVCTL(instance_no),
867 867 DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) {
868 868 dev_err(dip, CE_WARN, "failed to create devctl node.");
869 869
870 870 goto fail_attach;
871 871 }
872 872
873 873 instance->unroll.devctl = 1;
874 874
875 875 /* create scsi node for cfgadm command */
876 876 if (ddi_create_minor_node(dip, "scsi", S_IFCHR,
877 877 INST2SCSI(instance_no), DDI_NT_SCSI_ATTACHMENT_POINT, 0) ==
878 878 DDI_FAILURE) {
879 879 dev_err(dip, CE_WARN, "failed to create scsi node.");
880 880
881 881 goto fail_attach;
882 882 }
883 883
884 884 instance->unroll.scsictl = 1;
885 885
886 886 (void) sprintf(instance->iocnode, "%d:lsirdctl", instance_no);
887 887
888 888 /*
889 889 * Create a node for applications
890 890 * for issuing ioctl to the driver.
891 891 */
892 892 if (ddi_create_minor_node(dip, instance->iocnode,
893 893 S_IFCHR, INST2LSIRDCTL(instance_no), DDI_PSEUDO, 0) ==
894 894 DDI_FAILURE) {
895 895 dev_err(dip, CE_WARN, "failed to create ioctl node.");
896 896
897 897 goto fail_attach;
898 898 }
899 899
900 900 instance->unroll.ioctl = 1;
901 901
902 902 /* Create a taskq to handle dr events */
903 903 if ((instance->taskq = ddi_taskq_create(dip,
904 904 "mrsas_dr_taskq", 1, TASKQ_DEFAULTPRI, 0)) == NULL) {
905 905 dev_err(dip, CE_WARN, "failed to create taskq.");
906 906 instance->taskq = NULL;
907 907 goto fail_attach;
908 908 }
909 909 instance->unroll.taskq = 1;
910 910 con_log(CL_ANN1, (CE_CONT, "ddi_taskq_create() done."));
911 911
912 912 /* enable interrupt */
913 913 instance->func_ptr->enable_intr(instance);
914 914
915 915 /* initiate AEN */
916 916 if (start_mfi_aen(instance)) {
917 917 dev_err(dip, CE_WARN, "failed to initiate AEN.");
918 918 goto fail_attach;
919 919 }
920 920 instance->unroll.aenPend = 1;
921 921 con_log(CL_ANN1,
922 922 (CE_CONT, "AEN started for instance %d.", instance_no));
923 923
924 924 /* Finally! We are on the air. */
925 925 ddi_report_dev(dip);
926 926
927 927 /* FMA handle checking. */
928 928 if (mrsas_check_acc_handle(instance->regmap_handle) !=
929 929 DDI_SUCCESS) {
930 930 goto fail_attach;
931 931 }
932 932 if (mrsas_check_acc_handle(instance->pci_handle) !=
933 933 DDI_SUCCESS) {
934 934 goto fail_attach;
935 935 }
936 936
937 937 instance->mr_ld_list =
938 938 kmem_zalloc(MRDRV_MAX_LD * sizeof (struct mrsas_ld),
939 939 KM_SLEEP);
940 940 instance->unroll.ldlist_buff = 1;
941 941
942 942 #ifdef PDSUPPORT
943 943 if (instance->tbolt || instance->skinny) {
944 944 instance->mr_tbolt_pd_max = MRSAS_TBOLT_PD_TGT_MAX;
945 945 instance->mr_tbolt_pd_list =
946 946 kmem_zalloc(MRSAS_TBOLT_GET_PD_MAX(instance) *
947 947 sizeof (struct mrsas_tbolt_pd), KM_SLEEP);
948 948 ASSERT(instance->mr_tbolt_pd_list);
949 949 for (i = 0; i < instance->mr_tbolt_pd_max; i++) {
950 950 instance->mr_tbolt_pd_list[i].lun_type =
951 951 MRSAS_TBOLT_PD_LUN;
952 952 instance->mr_tbolt_pd_list[i].dev_id =
953 953 (uint8_t)i;
954 954 }
955 955
956 956 instance->unroll.pdlist_buff = 1;
957 957 }
958 958 #endif
959 959 break;
960 960 case DDI_PM_RESUME:
961 961 con_log(CL_ANN, (CE_NOTE, "mr_sas: DDI_PM_RESUME"));
962 962 break;
963 963 case DDI_RESUME:
964 964 con_log(CL_ANN, (CE_NOTE, "mr_sas: DDI_RESUME"));
965 965 break;
966 966 default:
967 967 con_log(CL_ANN,
968 968 (CE_WARN, "mr_sas: invalid attach cmd=%x", cmd));
969 969 return (DDI_FAILURE);
970 970 }
971 971
972 972
973 973 con_log(CL_DLEVEL1,
974 974 (CE_NOTE, "mrsas_attach() return SUCCESS instance_num %d",
975 975 instance_no));
976 976 return (DDI_SUCCESS);
977 977
978 978 fail_attach:
979 979
980 980 mrsas_undo_resources(dip, instance);
981 981
982 982 mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
983 983 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
984 984
985 985 mrsas_fm_fini(instance);
986 986
987 987 pci_config_teardown(&instance->pci_handle);
988 988 ddi_soft_state_free(mrsas_state, instance_no);
989 989
990 990 return (DDI_FAILURE);
991 991 }
992 992
993 993 /*
994 994 * getinfo - gets device information
995 995 * @dip:
996 996 * @cmd:
997 997 * @arg:
998 998 * @resultp:
999 999 *
1000 1000 * The system calls getinfo() to obtain configuration information that only
1001 1001 * the driver knows. The mapping of minor numbers to device instance is
1002 1002 * entirely under the control of the driver. The system sometimes needs to ask
1003 1003 * the driver which device a particular dev_t represents.
1004 1004 * Given the device number return the devinfo pointer from the scsi_device
1005 1005 * structure.
1006 1006 */
1007 1007 /*ARGSUSED*/
1008 1008 static int
1009 1009 mrsas_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
1010 1010 {
1011 1011 int rval;
1012 1012 int mrsas_minor = getminor((dev_t)arg);
1013 1013
1014 1014 struct mrsas_instance *instance;
1015 1015
1016 1016 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1017 1017
1018 1018 switch (cmd) {
1019 1019 case DDI_INFO_DEVT2DEVINFO:
1020 1020 instance = (struct mrsas_instance *)
1021 1021 ddi_get_soft_state(mrsas_state,
1022 1022 MINOR2INST(mrsas_minor));
1023 1023
1024 1024 if (instance == NULL) {
1025 1025 *resultp = NULL;
1026 1026 rval = DDI_FAILURE;
1027 1027 } else {
1028 1028 *resultp = instance->dip;
1029 1029 rval = DDI_SUCCESS;
1030 1030 }
1031 1031 break;
1032 1032 case DDI_INFO_DEVT2INSTANCE:
1033 1033 *resultp = (void *)(intptr_t)
1034 1034 (MINOR2INST(getminor((dev_t)arg)));
1035 1035 rval = DDI_SUCCESS;
1036 1036 break;
1037 1037 default:
1038 1038 *resultp = NULL;
1039 1039 rval = DDI_FAILURE;
1040 1040 }
1041 1041
1042 1042 return (rval);
1043 1043 }
1044 1044
1045 1045 /*
1046 1046 * detach - detaches a device from the system
1047 1047 * @dip: pointer to the device's dev_info structure
1048 1048 * @cmd: type of detach
1049 1049 *
1050 1050 * A driver's detach() entry point is called to detach an instance of a device
1051 1051 * that is bound to the driver. The entry point is called with the instance of
1052 1052 * the device node to be detached and with DDI_DETACH, which is specified as
1053 1053 * the cmd argument to the entry point.
1054 1054 * This routine is called during driver unload. We free all the allocated
1055 1055 * resources and call the corresponding LLD so that it can also release all
1056 1056 * its resources.
1057 1057 */
1058 1058 static int
1059 1059 mrsas_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1060 1060 {
1061 1061 int instance_no;
1062 1062
1063 1063 struct mrsas_instance *instance;
1064 1064
1065 1065 con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1066 1066
1067 1067
1068 1068 /* CONSTCOND */
1069 1069 ASSERT(NO_COMPETING_THREADS);
1070 1070
1071 1071 instance_no = ddi_get_instance(dip);
1072 1072
1073 1073 instance = (struct mrsas_instance *)ddi_get_soft_state(mrsas_state,
1074 1074 instance_no);
1075 1075
1076 1076 if (!instance) {
1077 1077 dev_err(dip, CE_WARN, "could not get instance in detach");
1078 1078
1079 1079 return (DDI_FAILURE);
1080 1080 }
1081 1081
1082 1082 switch (cmd) {
1083 1083 case DDI_DETACH:
1084 1084 con_log(CL_ANN, (CE_NOTE,
1085 1085 "mrsas_detach: DDI_DETACH"));
1086 1086
1087 1087 mutex_enter(&instance->config_dev_mtx);
1088 1088 if (instance->timeout_id != (timeout_id_t)-1) {
1089 1089 mutex_exit(&instance->config_dev_mtx);
1090 1090 (void) untimeout(instance->timeout_id);
1091 1091 instance->timeout_id = (timeout_id_t)-1;
1092 1092 mutex_enter(&instance->config_dev_mtx);
1093 1093 instance->unroll.timer = 0;
1094 1094 }
1095 1095 mutex_exit(&instance->config_dev_mtx);
1096 1096
1097 1097 if (instance->unroll.tranSetup == 1) {
1098 1098 if (scsi_hba_detach(dip) != DDI_SUCCESS) {
1099 1099 dev_err(dip, CE_WARN,
1100 1100 "failed to detach");
1101 1101 return (DDI_FAILURE);
1102 1102 }
1103 1103 instance->unroll.tranSetup = 0;
1104 1104 con_log(CL_ANN1,
1105 1105 (CE_CONT, "scsi_hba_dettach() done."));
1106 1106 }
1107 1107
1108 1108 flush_cache(instance);
1109 1109
1110 1110 mrsas_undo_resources(dip, instance);
1111 1111
1112 1112 mrsas_fm_fini(instance);
1113 1113
1114 1114 pci_config_teardown(&instance->pci_handle);
1115 1115 ddi_soft_state_free(mrsas_state, instance_no);
1116 1116 break;
1117 1117
1118 1118 case DDI_PM_SUSPEND:
1119 1119 con_log(CL_ANN, (CE_NOTE,
1120 1120 "mrsas_detach: DDI_PM_SUSPEND"));
1121 1121
1122 1122 break;
1123 1123 case DDI_SUSPEND:
1124 1124 con_log(CL_ANN, (CE_NOTE,
1125 1125 "mrsas_detach: DDI_SUSPEND"));
1126 1126
1127 1127 break;
1128 1128 default:
1129 1129 con_log(CL_ANN, (CE_WARN,
1130 1130 "invalid detach command:0x%x", cmd));
1131 1131 return (DDI_FAILURE);
1132 1132 }
1133 1133
1134 1134 return (DDI_SUCCESS);
1135 1135 }
1136 1136
1137 1137
1138 1138 static void
1139 1139 mrsas_undo_resources(dev_info_t *dip, struct mrsas_instance *instance)
1140 1140 {
1141 1141 con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1142 1142
1143 1143 if (instance->unroll.ioctl == 1) {
1144 1144 ddi_remove_minor_node(dip, instance->iocnode);
1145 1145 instance->unroll.ioctl = 0;
1146 1146 }
1147 1147
1148 1148 if (instance->unroll.scsictl == 1) {
1149 1149 ddi_remove_minor_node(dip, "scsi");
1150 1150 instance->unroll.scsictl = 0;
1151 1151 }
1152 1152
1153 1153 if (instance->unroll.devctl == 1) {
1154 1154 ddi_remove_minor_node(dip, "devctl");
1155 1155 instance->unroll.devctl = 0;
1156 1156 }
1157 1157
1158 1158 if (instance->unroll.tranSetup == 1) {
1159 1159 if (scsi_hba_detach(dip) != DDI_SUCCESS) {
1160 1160 dev_err(dip, CE_WARN, "failed to detach");
1161 1161 return; /* DDI_FAILURE */
1162 1162 }
1163 1163 instance->unroll.tranSetup = 0;
1164 1164 con_log(CL_ANN1, (CE_CONT, "scsi_hba_dettach() done."));
1165 1165 }
1166 1166
1167 1167 if (instance->unroll.tran == 1) {
1168 1168 scsi_hba_tran_free(instance->tran);
1169 1169 instance->unroll.tran = 0;
1170 1170 con_log(CL_ANN1, (CE_CONT, "scsi_hba_tran_free() done."));
1171 1171 }
1172 1172
1173 1173 if (instance->unroll.syncCmd == 1) {
1174 1174 if (instance->tbolt) {
1175 1175 if (abort_syncmap_cmd(instance,
1176 1176 instance->map_update_cmd)) {
1177 1177 dev_err(dip, CE_WARN, "mrsas_detach: "
1178 1178 "failed to abort previous syncmap command");
1179 1179 }
1180 1180
1181 1181 instance->unroll.syncCmd = 0;
1182 1182 con_log(CL_ANN1, (CE_CONT, "sync cmd aborted, done."));
1183 1183 }
1184 1184 }
1185 1185
1186 1186 if (instance->unroll.aenPend == 1) {
1187 1187 if (abort_aen_cmd(instance, instance->aen_cmd))
1188 1188 dev_err(dip, CE_WARN, "mrsas_detach: "
1189 1189 "failed to abort prevous AEN command");
1190 1190
1191 1191 instance->unroll.aenPend = 0;
1192 1192 con_log(CL_ANN1, (CE_CONT, "aen cmd aborted, done."));
1193 1193 /* This means the controller is fully initialized and running */
1194 1194 /* Shutdown should be a last command to controller. */
1195 1195 /* shutdown_controller(); */
1196 1196 }
1197 1197
1198 1198
1199 1199 if (instance->unroll.timer == 1) {
1200 1200 if (instance->timeout_id != (timeout_id_t)-1) {
1201 1201 (void) untimeout(instance->timeout_id);
1202 1202 instance->timeout_id = (timeout_id_t)-1;
1203 1203
1204 1204 instance->unroll.timer = 0;
1205 1205 }
1206 1206 }
1207 1207
1208 1208 instance->func_ptr->disable_intr(instance);
1209 1209
1210 1210
1211 1211 if (instance->unroll.mutexs == 1) {
1212 1212 mutex_destroy(&instance->cmd_pool_mtx);
1213 1213 mutex_destroy(&instance->app_cmd_pool_mtx);
1214 1214 mutex_destroy(&instance->cmd_pend_mtx);
1215 1215 mutex_destroy(&instance->completed_pool_mtx);
1216 1216 mutex_destroy(&instance->sync_map_mtx);
1217 1217 mutex_destroy(&instance->int_cmd_mtx);
1218 1218 cv_destroy(&instance->int_cmd_cv);
1219 1219 mutex_destroy(&instance->config_dev_mtx);
1220 1220 mutex_destroy(&instance->ocr_flags_mtx);
1221 1221 mutex_destroy(&instance->reg_write_mtx);
1222 1222
1223 1223 if (instance->tbolt) {
1224 1224 mutex_destroy(&instance->cmd_app_pool_mtx);
1225 1225 mutex_destroy(&instance->chip_mtx);
1226 1226 }
1227 1227
1228 1228 instance->unroll.mutexs = 0;
1229 1229 con_log(CL_ANN1, (CE_CONT, "Destroy mutex & cv, done."));
1230 1230 }
1231 1231
1232 1232
1233 1233 if (instance->unroll.soft_isr == 1) {
1234 1234 ddi_remove_softintr(instance->soft_intr_id);
1235 1235 instance->unroll.soft_isr = 0;
1236 1236 }
1237 1237
1238 1238 if (instance->unroll.intr == 1) {
1239 1239 mrsas_rem_intrs(instance);
1240 1240 instance->unroll.intr = 0;
1241 1241 }
1242 1242
1243 1243
1244 1244 if (instance->unroll.taskq == 1) {
1245 1245 if (instance->taskq) {
1246 1246 ddi_taskq_destroy(instance->taskq);
1247 1247 instance->unroll.taskq = 0;
1248 1248 }
1249 1249
1250 1250 }
1251 1251
1252 1252 /*
1253 1253 * free dma memory allocated for
1254 1254 * cmds/frames/queues/driver version etc
1255 1255 */
1256 1256 if (instance->unroll.verBuff == 1) {
1257 1257 (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
1258 1258 instance->unroll.verBuff = 0;
1259 1259 }
1260 1260
1261 1261 if (instance->unroll.pdlist_buff == 1) {
1262 1262 if (instance->mr_tbolt_pd_list != NULL) {
1263 1263 kmem_free(instance->mr_tbolt_pd_list,
1264 1264 MRSAS_TBOLT_GET_PD_MAX(instance) *
1265 1265 sizeof (struct mrsas_tbolt_pd));
1266 1266 }
1267 1267
1268 1268 instance->mr_tbolt_pd_list = NULL;
1269 1269 instance->unroll.pdlist_buff = 0;
1270 1270 }
1271 1271
1272 1272 if (instance->unroll.ldlist_buff == 1) {
1273 1273 if (instance->mr_ld_list != NULL) {
1274 1274 kmem_free(instance->mr_ld_list, MRDRV_MAX_LD
1275 1275 * sizeof (struct mrsas_ld));
1276 1276 }
1277 1277
1278 1278 instance->mr_ld_list = NULL;
1279 1279 instance->unroll.ldlist_buff = 0;
1280 1280 }
1281 1281
1282 1282 if (instance->tbolt) {
1283 1283 if (instance->unroll.alloc_space_mpi2 == 1) {
1284 1284 free_space_for_mpi2(instance);
1285 1285 instance->unroll.alloc_space_mpi2 = 0;
1286 1286 }
1287 1287 } else {
1288 1288 if (instance->unroll.alloc_space_mfi == 1) {
1289 1289 free_space_for_mfi(instance);
1290 1290 instance->unroll.alloc_space_mfi = 0;
1291 1291 }
1292 1292 }
1293 1293
1294 1294 if (instance->unroll.regs == 1) {
1295 1295 ddi_regs_map_free(&instance->regmap_handle);
1296 1296 instance->unroll.regs = 0;
1297 1297 con_log(CL_ANN1, (CE_CONT, "ddi_regs_map_free() done."));
1298 1298 }
1299 1299 }
1300 1300
1301 1301
1302 1302
1303 1303 /*
1304 1304 * ************************************************************************** *
1305 1305 * *
1306 1306 * common entry points - for character driver types *
1307 1307 * *
1308 1308 * ************************************************************************** *
1309 1309 */
1310 1310 /*
1311 1311 * open - gets access to a device
1312 1312 * @dev:
1313 1313 * @openflags:
1314 1314 * @otyp:
1315 1315 * @credp:
1316 1316 *
1317 1317 * Access to a device by one or more application programs is controlled
1318 1318 * through the open() and close() entry points. The primary function of
1319 1319 * open() is to verify that the open request is allowed.
1320 1320 */
1321 1321 static int
1322 1322 mrsas_open(dev_t *dev, int openflags, int otyp, cred_t *credp)
1323 1323 {
1324 1324 int rval = 0;
1325 1325
1326 1326 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1327 1327
1328 1328 /* Check root permissions */
1329 1329 if (drv_priv(credp) != 0) {
1330 1330 con_log(CL_ANN, (CE_WARN,
1331 1331 "mr_sas: Non-root ioctl access denied!"));
1332 1332 return (EPERM);
1333 1333 }
1334 1334
1335 1335 /* Verify we are being opened as a character device */
1336 1336 if (otyp != OTYP_CHR) {
1337 1337 con_log(CL_ANN, (CE_WARN,
1338 1338 "mr_sas: ioctl node must be a char node"));
1339 1339 return (EINVAL);
1340 1340 }
1341 1341
1342 1342 if (ddi_get_soft_state(mrsas_state, MINOR2INST(getminor(*dev)))
1343 1343 == NULL) {
1344 1344 return (ENXIO);
1345 1345 }
1346 1346
1347 1347 if (scsi_hba_open) {
1348 1348 rval = scsi_hba_open(dev, openflags, otyp, credp);
1349 1349 }
1350 1350
1351 1351 return (rval);
1352 1352 }
1353 1353
1354 1354 /*
1355 1355 * close - gives up access to a device
1356 1356 * @dev:
1357 1357 * @openflags:
1358 1358 * @otyp:
1359 1359 * @credp:
1360 1360 *
1361 1361 * close() should perform any cleanup necessary to finish using the minor
1362 1362 * device, and prepare the device (and driver) to be opened again.
1363 1363 */
1364 1364 static int
1365 1365 mrsas_close(dev_t dev, int openflags, int otyp, cred_t *credp)
1366 1366 {
1367 1367 int rval = 0;
1368 1368
1369 1369 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1370 1370
1371 1371 /* no need for locks! */
1372 1372
1373 1373 if (scsi_hba_close) {
1374 1374 rval = scsi_hba_close(dev, openflags, otyp, credp);
1375 1375 }
1376 1376
1377 1377 return (rval);
1378 1378 }
1379 1379
1380 1380 /*
1381 1381 * ioctl - performs a range of I/O commands for character drivers
1382 1382 * @dev:
1383 1383 * @cmd:
1384 1384 * @arg:
1385 1385 * @mode:
1386 1386 * @credp:
1387 1387 * @rvalp:
1388 1388 *
1389 1389 * ioctl() routine must make sure that user data is copied into or out of the
1390 1390 * kernel address space explicitly using copyin(), copyout(), ddi_copyin(),
1391 1391 * and ddi_copyout(), as appropriate.
1392 1392 * This is a wrapper routine to serialize access to the actual ioctl routine.
1393 1393 * ioctl() should return 0 on success, or the appropriate error number. The
1394 1394 * driver may also set the value returned to the calling process through rvalp.
1395 1395 */
1396 1396
1397 1397 static int
1398 1398 mrsas_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1399 1399 int *rvalp)
1400 1400 {
1401 1401 int rval = 0;
1402 1402
1403 1403 struct mrsas_instance *instance;
1404 1404 struct mrsas_ioctl *ioctl;
1405 1405 struct mrsas_aen aen;
1406 1406 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1407 1407
1408 1408 instance = ddi_get_soft_state(mrsas_state, MINOR2INST(getminor(dev)));
1409 1409
1410 1410 if (instance == NULL) {
1411 1411 /* invalid minor number */
1412 1412 con_log(CL_ANN, (CE_WARN, "mr_sas: adapter not found."));
1413 1413 return (ENXIO);
1414 1414 }
1415 1415
1416 1416 ioctl = (struct mrsas_ioctl *)kmem_zalloc(sizeof (struct mrsas_ioctl),
1417 1417 KM_SLEEP);
1418 1418 ASSERT(ioctl);
1419 1419
1420 1420 switch ((uint_t)cmd) {
1421 1421 case MRSAS_IOCTL_FIRMWARE:
1422 1422 if (ddi_copyin((void *)arg, ioctl,
1423 1423 sizeof (struct mrsas_ioctl), mode)) {
1424 1424 con_log(CL_ANN, (CE_WARN, "mrsas_ioctl: "
1425 1425 "ERROR IOCTL copyin"));
1426 1426 kmem_free(ioctl, sizeof (struct mrsas_ioctl));
1427 1427 return (EFAULT);
1428 1428 }
1429 1429
1430 1430 if (ioctl->control_code == MRSAS_DRIVER_IOCTL_COMMON) {
1431 1431 rval = handle_drv_ioctl(instance, ioctl, mode);
1432 1432 } else {
1433 1433 rval = handle_mfi_ioctl(instance, ioctl, mode);
1434 1434 }
1435 1435
1436 1436 if (ddi_copyout((void *)ioctl, (void *)arg,
1437 1437 (sizeof (struct mrsas_ioctl) - 1), mode)) {
1438 1438 con_log(CL_ANN, (CE_WARN,
1439 1439 "mrsas_ioctl: copy_to_user failed"));
1440 1440 rval = 1;
1441 1441 }
1442 1442
1443 1443 break;
1444 1444 case MRSAS_IOCTL_AEN:
1445 1445 if (ddi_copyin((void *) arg, &aen,
1446 1446 sizeof (struct mrsas_aen), mode)) {
1447 1447 con_log(CL_ANN, (CE_WARN,
1448 1448 "mrsas_ioctl: ERROR AEN copyin"));
1449 1449 kmem_free(ioctl, sizeof (struct mrsas_ioctl));
1450 1450 return (EFAULT);
1451 1451 }
1452 1452
1453 1453 rval = handle_mfi_aen(instance, &aen);
1454 1454
1455 1455 if (ddi_copyout((void *) &aen, (void *)arg,
1456 1456 sizeof (struct mrsas_aen), mode)) {
1457 1457 con_log(CL_ANN, (CE_WARN,
1458 1458 "mrsas_ioctl: copy_to_user failed"));
1459 1459 rval = 1;
1460 1460 }
1461 1461
1462 1462 break;
1463 1463 default:
1464 1464 rval = scsi_hba_ioctl(dev, cmd, arg,
1465 1465 mode, credp, rvalp);
1466 1466
1467 1467 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_ioctl: "
1468 1468 "scsi_hba_ioctl called, ret = %x.", rval));
1469 1469 }
1470 1470
1471 1471 kmem_free(ioctl, sizeof (struct mrsas_ioctl));
1472 1472 return (rval);
1473 1473 }
1474 1474
1475 1475 /*
1476 1476 * ************************************************************************** *
1477 1477 * *
1478 1478 * common entry points - for block driver types *
1479 1479 * *
1480 1480 * ************************************************************************** *
1481 1481 */
1482 1482 #ifdef __sparc
1483 1483 /*
1484 1484 * reset - TBD
1485 1485 * @dip:
1486 1486 * @cmd:
1487 1487 *
1488 1488 * TBD
1489 1489 */
1490 1490 /*ARGSUSED*/
1491 1491 static int
1492 1492 mrsas_reset(dev_info_t *dip, ddi_reset_cmd_t cmd)
1493 1493 {
1494 1494 int instance_no;
1495 1495
1496 1496 struct mrsas_instance *instance;
1497 1497
1498 1498 instance_no = ddi_get_instance(dip);
1499 1499 instance = (struct mrsas_instance *)ddi_get_soft_state
1500 1500 (mrsas_state, instance_no);
1501 1501
1502 1502 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1503 1503
1504 1504 if (!instance) {
1505 1505 con_log(CL_ANN, (CE_WARN, "mr_sas:%d could not get adapter "
1506 1506 "in reset", instance_no));
1507 1507 return (DDI_FAILURE);
1508 1508 }
1509 1509
1510 1510 instance->func_ptr->disable_intr(instance);
1511 1511
1512 1512 con_log(CL_ANN1, (CE_CONT, "flushing cache for instance %d",
1513 1513 instance_no));
1514 1514
1515 1515 flush_cache(instance);
1516 1516
1517 1517 return (DDI_SUCCESS);
1518 1518 }
1519 1519 #else /* __sparc */
1520 1520 /*ARGSUSED*/
1521 1521 static int
1522 1522 mrsas_quiesce(dev_info_t *dip)
1523 1523 {
1524 1524 int instance_no;
1525 1525
1526 1526 struct mrsas_instance *instance;
1527 1527
1528 1528 instance_no = ddi_get_instance(dip);
1529 1529 instance = (struct mrsas_instance *)ddi_get_soft_state
1530 1530 (mrsas_state, instance_no);
1531 1531
1532 1532 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1533 1533
1534 1534 if (!instance) {
1535 1535 con_log(CL_ANN1, (CE_WARN, "mr_sas:%d could not get adapter "
1536 1536 "in quiesce", instance_no));
1537 1537 return (DDI_FAILURE);
1538 1538 }
1539 1539 if (instance->deadadapter || instance->adapterresetinprogress) {
1540 1540 con_log(CL_ANN1, (CE_WARN, "mr_sas:%d adapter is not in "
1541 1541 "healthy state", instance_no));
1542 1542 return (DDI_FAILURE);
1543 1543 }
1544 1544
1545 1545 if (abort_aen_cmd(instance, instance->aen_cmd)) {
1546 1546 con_log(CL_ANN1, (CE_WARN, "mrsas_quiesce: "
1547 1547 "failed to abort prevous AEN command QUIESCE"));
1548 1548 }
1549 1549
1550 1550 if (instance->tbolt) {
1551 1551 if (abort_syncmap_cmd(instance,
1552 1552 instance->map_update_cmd)) {
1553 1553 dev_err(dip, CE_WARN,
1554 1554 "mrsas_detach: failed to abort "
1555 1555 "previous syncmap command");
1556 1556 return (DDI_FAILURE);
1557 1557 }
1558 1558 }
1559 1559
1560 1560 instance->func_ptr->disable_intr(instance);
1561 1561
1562 1562 con_log(CL_ANN1, (CE_CONT, "flushing cache for instance %d",
1563 1563 instance_no));
1564 1564
1565 1565 flush_cache(instance);
1566 1566
1567 1567 if (wait_for_outstanding(instance)) {
1568 1568 con_log(CL_ANN1,
1569 1569 (CE_CONT, "wait_for_outstanding: return FAIL.\n"));
1570 1570 return (DDI_FAILURE);
1571 1571 }
1572 1572 return (DDI_SUCCESS);
1573 1573 }
1574 1574 #endif /* __sparc */
1575 1575
1576 1576 /*
1577 1577 * ************************************************************************** *
1578 1578 * *
1579 1579 * entry points (SCSI HBA) *
1580 1580 * *
1581 1581 * ************************************************************************** *
1582 1582 */
1583 1583 /*
1584 1584 * tran_tgt_init - initialize a target device instance
1585 1585 * @hba_dip:
1586 1586 * @tgt_dip:
1587 1587 * @tran:
1588 1588 * @sd:
1589 1589 *
1590 1590 * The tran_tgt_init() entry point enables the HBA to allocate and initialize
1591 1591 * any per-target resources. tran_tgt_init() also enables the HBA to qualify
1592 1592 * the device's address as valid and supportable for that particular HBA.
1593 1593 * By returning DDI_FAILURE, the instance of the target driver for that device
1594 1594 * is not probed or attached.
1595 1595 */
1596 1596 /*ARGSUSED*/
1597 1597 static int
1598 1598 mrsas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
1599 1599 scsi_hba_tran_t *tran, struct scsi_device *sd)
1600 1600 {
1601 1601 struct mrsas_instance *instance;
1602 1602 uint16_t tgt = sd->sd_address.a_target;
1603 1603 uint8_t lun = sd->sd_address.a_lun;
1604 1604 dev_info_t *child = NULL;
1605 1605
1606 1606 con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init target %d lun %d",
1607 1607 tgt, lun));
1608 1608
1609 1609 instance = ADDR2MR(&sd->sd_address);
1610 1610
1611 1611 if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
1612 1612 /*
1613 1613 * If no persistent node exists, we don't allow .conf node
1614 1614 * to be created.
1615 1615 */
1616 1616 if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
1617 1617 con_log(CL_DLEVEL2,
1618 1618 (CE_NOTE, "mrsas_tgt_init find child ="
1619 1619 " %p t = %d l = %d", (void *)child, tgt, lun));
1620 1620 if (ndi_merge_node(tgt_dip, mrsas_name_node) !=
1621 1621 DDI_SUCCESS)
1622 1622 /* Create this .conf node */
1623 1623 return (DDI_SUCCESS);
1624 1624 }
1625 1625 con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init in ndi_per "
1626 1626 "DDI_FAILURE t = %d l = %d", tgt, lun));
1627 1627 return (DDI_FAILURE);
1628 1628
1629 1629 }
1630 1630
1631 1631 con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_tgt_init dev_dip %p tgt_dip %p",
1632 1632 (void *)instance->mr_ld_list[tgt].dip, (void *)tgt_dip));
1633 1633
1634 1634 if (tgt < MRDRV_MAX_LD && lun == 0) {
1635 1635 if (instance->mr_ld_list[tgt].dip == NULL &&
1636 1636 strcmp(ddi_driver_name(sd->sd_dev), "sd") == 0) {
1637 1637 mutex_enter(&instance->config_dev_mtx);
1638 1638 instance->mr_ld_list[tgt].dip = tgt_dip;
1639 1639 instance->mr_ld_list[tgt].lun_type = MRSAS_LD_LUN;
1640 1640 instance->mr_ld_list[tgt].flag = MRDRV_TGT_VALID;
1641 1641 mutex_exit(&instance->config_dev_mtx);
1642 1642 }
1643 1643 }
1644 1644
1645 1645 #ifdef PDSUPPORT
1646 1646 else if (instance->tbolt || instance->skinny) {
1647 1647 if (instance->mr_tbolt_pd_list[tgt].dip == NULL) {
1648 1648 mutex_enter(&instance->config_dev_mtx);
1649 1649 instance->mr_tbolt_pd_list[tgt].dip = tgt_dip;
1650 1650 instance->mr_tbolt_pd_list[tgt].flag =
1651 1651 MRDRV_TGT_VALID;
1652 1652 mutex_exit(&instance->config_dev_mtx);
1653 1653 con_log(CL_ANN1, (CE_NOTE, "mrsas_tran_tgt_init:"
1654 1654 "t%xl%x", tgt, lun));
1655 1655 }
1656 1656 }
1657 1657 #endif
1658 1658
1659 1659 return (DDI_SUCCESS);
1660 1660 }
1661 1661
1662 1662 /*ARGSUSED*/
1663 1663 static void
1664 1664 mrsas_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
1665 1665 scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
1666 1666 {
1667 1667 struct mrsas_instance *instance;
1668 1668 int tgt = sd->sd_address.a_target;
1669 1669 int lun = sd->sd_address.a_lun;
1670 1670
1671 1671 instance = ADDR2MR(&sd->sd_address);
1672 1672
1673 1673 con_log(CL_DLEVEL2, (CE_NOTE, "tgt_free t = %d l = %d", tgt, lun));
1674 1674
1675 1675 if (tgt < MRDRV_MAX_LD && lun == 0) {
1676 1676 if (instance->mr_ld_list[tgt].dip == tgt_dip) {
1677 1677 mutex_enter(&instance->config_dev_mtx);
1678 1678 instance->mr_ld_list[tgt].dip = NULL;
1679 1679 mutex_exit(&instance->config_dev_mtx);
1680 1680 }
1681 1681 }
1682 1682
1683 1683 #ifdef PDSUPPORT
1684 1684 else if (instance->tbolt || instance->skinny) {
1685 1685 mutex_enter(&instance->config_dev_mtx);
1686 1686 instance->mr_tbolt_pd_list[tgt].dip = NULL;
1687 1687 mutex_exit(&instance->config_dev_mtx);
1688 1688 con_log(CL_ANN1, (CE_NOTE, "tgt_free: Setting dip = NULL"
1689 1689 "for tgt:%x", tgt));
1690 1690 }
1691 1691 #endif
1692 1692
1693 1693 }
1694 1694
1695 1695 dev_info_t *
1696 1696 mrsas_find_child(struct mrsas_instance *instance, uint16_t tgt, uint8_t lun)
1697 1697 {
1698 1698 dev_info_t *child = NULL;
1699 1699 char addr[SCSI_MAXNAMELEN];
1700 1700 char tmp[MAXNAMELEN];
1701 1701
1702 1702 (void) sprintf(addr, "%x,%x", tgt, lun);
1703 1703 for (child = ddi_get_child(instance->dip); child;
1704 1704 child = ddi_get_next_sibling(child)) {
1705 1705
1706 1706 if (ndi_dev_is_persistent_node(child) == 0) {
1707 1707 continue;
1708 1708 }
1709 1709
1710 1710 if (mrsas_name_node(child, tmp, MAXNAMELEN) !=
1711 1711 DDI_SUCCESS) {
1712 1712 continue;
1713 1713 }
1714 1714
1715 1715 if (strcmp(addr, tmp) == 0) {
1716 1716 break;
1717 1717 }
1718 1718 }
1719 1719 con_log(CL_DLEVEL2, (CE_NOTE, "mrsas_find_child: return child = %p",
1720 1720 (void *)child));
1721 1721 return (child);
1722 1722 }
1723 1723
1724 1724 /*
1725 1725 * mrsas_name_node -
1726 1726 * @dip:
1727 1727 * @name:
1728 1728 * @len:
1729 1729 */
1730 1730 static int
1731 1731 mrsas_name_node(dev_info_t *dip, char *name, int len)
1732 1732 {
1733 1733 int tgt, lun;
1734 1734
1735 1735 tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1736 1736 DDI_PROP_DONTPASS, "target", -1);
1737 1737 con_log(CL_DLEVEL2, (CE_NOTE,
1738 1738 "mrsas_name_node: dip %p tgt %d", (void *)dip, tgt));
1739 1739 if (tgt == -1) {
1740 1740 return (DDI_FAILURE);
1741 1741 }
1742 1742 lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1743 1743 "lun", -1);
1744 1744 con_log(CL_DLEVEL2,
1745 1745 (CE_NOTE, "mrsas_name_node: tgt %d lun %d", tgt, lun));
1746 1746 if (lun == -1) {
1747 1747 return (DDI_FAILURE);
1748 1748 }
1749 1749 (void) snprintf(name, len, "%x,%x", tgt, lun);
1750 1750 return (DDI_SUCCESS);
1751 1751 }
1752 1752
1753 1753 /*
1754 1754 * tran_init_pkt - allocate & initialize a scsi_pkt structure
1755 1755 * @ap:
1756 1756 * @pkt:
1757 1757 * @bp:
1758 1758 * @cmdlen:
1759 1759 * @statuslen:
1760 1760 * @tgtlen:
1761 1761 * @flags:
1762 1762 * @callback:
1763 1763 *
1764 1764 * The tran_init_pkt() entry point allocates and initializes a scsi_pkt
1765 1765 * structure and DMA resources for a target driver request. The
1766 1766 * tran_init_pkt() entry point is called when the target driver calls the
1767 1767 * SCSA function scsi_init_pkt(). Each call of the tran_init_pkt() entry point
1768 1768 * is a request to perform one or more of three possible services:
1769 1769 * - allocation and initialization of a scsi_pkt structure
1770 1770 * - allocation of DMA resources for data transfer
1771 1771 * - reallocation of DMA resources for the next portion of the data transfer
1772 1772 */
1773 1773 static struct scsi_pkt *
1774 1774 mrsas_tran_init_pkt(struct scsi_address *ap, register struct scsi_pkt *pkt,
1775 1775 struct buf *bp, int cmdlen, int statuslen, int tgtlen,
1776 1776 int flags, int (*callback)(), caddr_t arg)
1777 1777 {
1778 1778 struct scsa_cmd *acmd;
1779 1779 struct mrsas_instance *instance;
1780 1780 struct scsi_pkt *new_pkt;
1781 1781
1782 1782 con_log(CL_DLEVEL1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1783 1783
1784 1784 instance = ADDR2MR(ap);
1785 1785
1786 1786 /* step #1 : pkt allocation */
1787 1787 if (pkt == NULL) {
1788 1788 pkt = scsi_hba_pkt_alloc(instance->dip, ap, cmdlen, statuslen,
1789 1789 tgtlen, sizeof (struct scsa_cmd), callback, arg);
1790 1790 if (pkt == NULL) {
1791 1791 return (NULL);
1792 1792 }
1793 1793
1794 1794 acmd = PKT2CMD(pkt);
1795 1795
1796 1796 /*
1797 1797 * Initialize the new pkt - we redundantly initialize
1798 1798 * all the fields for illustrative purposes.
1799 1799 */
1800 1800 acmd->cmd_pkt = pkt;
1801 1801 acmd->cmd_flags = 0;
1802 1802 acmd->cmd_scblen = statuslen;
1803 1803 acmd->cmd_cdblen = cmdlen;
1804 1804 acmd->cmd_dmahandle = NULL;
1805 1805 acmd->cmd_ncookies = 0;
1806 1806 acmd->cmd_cookie = 0;
1807 1807 acmd->cmd_cookiecnt = 0;
1808 1808 acmd->cmd_nwin = 0;
1809 1809
1810 1810 pkt->pkt_address = *ap;
1811 1811 pkt->pkt_comp = (void (*)())NULL;
1812 1812 pkt->pkt_flags = 0;
1813 1813 pkt->pkt_time = 0;
1814 1814 pkt->pkt_resid = 0;
1815 1815 pkt->pkt_state = 0;
1816 1816 pkt->pkt_statistics = 0;
1817 1817 pkt->pkt_reason = 0;
1818 1818 new_pkt = pkt;
1819 1819 } else {
1820 1820 acmd = PKT2CMD(pkt);
1821 1821 new_pkt = NULL;
1822 1822 }
1823 1823
1824 1824 /* step #2 : dma allocation/move */
1825 1825 if (bp && bp->b_bcount != 0) {
1826 1826 if (acmd->cmd_dmahandle == NULL) {
1827 1827 if (mrsas_dma_alloc(instance, pkt, bp, flags,
1828 1828 callback) == DDI_FAILURE) {
1829 1829 if (new_pkt) {
1830 1830 scsi_hba_pkt_free(ap, new_pkt);
1831 1831 }
1832 1832 return ((struct scsi_pkt *)NULL);
1833 1833 }
1834 1834 } else {
1835 1835 if (mrsas_dma_move(instance, pkt, bp) == DDI_FAILURE) {
1836 1836 return ((struct scsi_pkt *)NULL);
1837 1837 }
1838 1838 }
1839 1839 }
1840 1840
1841 1841 return (pkt);
1842 1842 }
1843 1843
1844 1844 /*
1845 1845 * tran_start - transport a SCSI command to the addressed target
1846 1846 * @ap:
1847 1847 * @pkt:
1848 1848 *
1849 1849 * The tran_start() entry point for a SCSI HBA driver is called to transport a
1850 1850 * SCSI command to the addressed target. The SCSI command is described
1851 1851 * entirely within the scsi_pkt structure, which the target driver allocated
1852 1852 * through the HBA driver's tran_init_pkt() entry point. If the command
1853 1853 * involves a data transfer, DMA resources must also have been allocated for
1854 1854 * the scsi_pkt structure.
1855 1855 *
1856 1856 * Return Values :
1857 1857 * TRAN_BUSY - request queue is full, no more free scbs
1858 1858 * TRAN_ACCEPT - pkt has been submitted to the instance
1859 1859 */
1860 1860 static int
1861 1861 mrsas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt)
1862 1862 {
1863 1863 uchar_t cmd_done = 0;
1864 1864
1865 1865 struct mrsas_instance *instance = ADDR2MR(ap);
1866 1866 struct mrsas_cmd *cmd;
1867 1867
1868 1868 con_log(CL_DLEVEL1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1869 1869 if (instance->deadadapter == 1) {
1870 1870 con_log(CL_ANN1, (CE_WARN,
1871 1871 "mrsas_tran_start: return TRAN_FATAL_ERROR "
1872 1872 "for IO, as the HBA doesnt take any more IOs"));
1873 1873 if (pkt) {
1874 1874 pkt->pkt_reason = CMD_DEV_GONE;
1875 1875 pkt->pkt_statistics = STAT_DISCON;
1876 1876 }
1877 1877 return (TRAN_FATAL_ERROR);
1878 1878 }
1879 1879
1880 1880 if (instance->adapterresetinprogress) {
1881 1881 con_log(CL_ANN1, (CE_NOTE, "mrsas_tran_start: Reset flag set, "
1882 1882 "returning mfi_pkt and setting TRAN_BUSY\n"));
1883 1883 return (TRAN_BUSY);
1884 1884 }
1885 1885
1886 1886 con_log(CL_ANN1, (CE_CONT, "chkpnt:%s:%d:SCSI CDB[0]=0x%x time:%x",
1887 1887 __func__, __LINE__, pkt->pkt_cdbp[0], pkt->pkt_time));
1888 1888
1889 1889 pkt->pkt_reason = CMD_CMPLT;
1890 1890 *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
1891 1891
1892 1892 cmd = build_cmd(instance, ap, pkt, &cmd_done);
1893 1893
1894 1894 /*
1895 1895 * Check if the command is already completed by the mrsas_build_cmd()
1896 1896 * routine. In which case the busy_flag would be clear and scb will be
1897 1897 * NULL and appropriate reason provided in pkt_reason field
1898 1898 */
1899 1899 if (cmd_done) {
1900 1900 pkt->pkt_reason = CMD_CMPLT;
1901 1901 pkt->pkt_scbp[0] = STATUS_GOOD;
1902 1902 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET
1903 1903 | STATE_SENT_CMD;
1904 1904 if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && pkt->pkt_comp) {
1905 1905 (*pkt->pkt_comp)(pkt);
1906 1906 }
1907 1907
1908 1908 return (TRAN_ACCEPT);
1909 1909 }
1910 1910
1911 1911 if (cmd == NULL) {
1912 1912 return (TRAN_BUSY);
1913 1913 }
1914 1914
1915 1915 if ((pkt->pkt_flags & FLAG_NOINTR) == 0) {
1916 1916 if (instance->fw_outstanding > instance->max_fw_cmds) {
1917 1917 con_log(CL_ANN, (CE_CONT, "mr_sas:Firmware busy"));
1918 1918 DTRACE_PROBE2(start_tran_err,
1919 1919 uint16_t, instance->fw_outstanding,
1920 1920 uint16_t, instance->max_fw_cmds);
1921 1921 mrsas_return_mfi_pkt(instance, cmd);
1922 1922 return (TRAN_BUSY);
1923 1923 }
1924 1924
1925 1925 /* Synchronize the Cmd frame for the controller */
1926 1926 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
1927 1927 DDI_DMA_SYNC_FORDEV);
1928 1928 con_log(CL_ANN, (CE_CONT, "issue_cmd_ppc: SCSI CDB[0]=0x%x"
1929 1929 "cmd->index:%x\n", pkt->pkt_cdbp[0], cmd->index));
1930 1930 instance->func_ptr->issue_cmd(cmd, instance);
1931 1931
1932 1932 } else {
1933 1933 struct mrsas_header *hdr = &cmd->frame->hdr;
1934 1934
1935 1935 instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd);
1936 1936
1937 1937 pkt->pkt_reason = CMD_CMPLT;
1938 1938 pkt->pkt_statistics = 0;
1939 1939 pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS;
1940 1940
1941 1941 switch (ddi_get8(cmd->frame_dma_obj.acc_handle,
1942 1942 &hdr->cmd_status)) {
1943 1943 case MFI_STAT_OK:
1944 1944 pkt->pkt_scbp[0] = STATUS_GOOD;
1945 1945 break;
1946 1946
1947 1947 case MFI_STAT_SCSI_DONE_WITH_ERROR:
1948 1948 con_log(CL_ANN, (CE_CONT,
1949 1949 "mrsas_tran_start: scsi done with error"));
1950 1950 pkt->pkt_reason = CMD_CMPLT;
1951 1951 pkt->pkt_statistics = 0;
1952 1952
1953 1953 ((struct scsi_status *)pkt->pkt_scbp)->sts_chk = 1;
1954 1954 break;
1955 1955
1956 1956 case MFI_STAT_DEVICE_NOT_FOUND:
1957 1957 con_log(CL_ANN, (CE_CONT,
1958 1958 "mrsas_tran_start: device not found error"));
1959 1959 pkt->pkt_reason = CMD_DEV_GONE;
1960 1960 pkt->pkt_statistics = STAT_DISCON;
1961 1961 break;
1962 1962
1963 1963 default:
1964 1964 ((struct scsi_status *)pkt->pkt_scbp)->sts_busy = 1;
1965 1965 }
1966 1966
1967 1967 (void) mrsas_common_check(instance, cmd);
1968 1968 DTRACE_PROBE2(start_nointr_done, uint8_t, hdr->cmd,
1969 1969 uint8_t, hdr->cmd_status);
1970 1970 mrsas_return_mfi_pkt(instance, cmd);
1971 1971
1972 1972 if (pkt->pkt_comp) {
1973 1973 (*pkt->pkt_comp)(pkt);
1974 1974 }
1975 1975
1976 1976 }
1977 1977
1978 1978 return (TRAN_ACCEPT);
1979 1979 }
1980 1980
1981 1981 /*
1982 1982 * tran_abort - Abort any commands that are currently in transport
1983 1983 * @ap:
1984 1984 * @pkt:
1985 1985 *
1986 1986 * The tran_abort() entry point for a SCSI HBA driver is called to abort any
1987 1987 * commands that are currently in transport for a particular target. This entry
1988 1988 * point is called when a target driver calls scsi_abort(). The tran_abort()
1989 1989 * entry point should attempt to abort the command denoted by the pkt
1990 1990 * parameter. If the pkt parameter is NULL, tran_abort() should attempt to
1991 1991 * abort all outstanding commands in the transport layer for the particular
1992 1992 * target or logical unit.
1993 1993 */
1994 1994 /*ARGSUSED*/
1995 1995 static int
1996 1996 mrsas_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
1997 1997 {
1998 1998 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
1999 1999
2000 2000 /* abort command not supported by H/W */
2001 2001
2002 2002 return (DDI_FAILURE);
2003 2003 }
2004 2004
2005 2005 /*
2006 2006 * tran_reset - reset either the SCSI bus or target
2007 2007 * @ap:
2008 2008 * @level:
2009 2009 *
2010 2010 * The tran_reset() entry point for a SCSI HBA driver is called to reset either
2011 2011 * the SCSI bus or a particular SCSI target device. This entry point is called
2012 2012 * when a target driver calls scsi_reset(). The tran_reset() entry point must
2013 2013 * reset the SCSI bus if level is RESET_ALL. If level is RESET_TARGET, just the
2014 2014 * particular target or logical unit must be reset.
2015 2015 */
2016 2016 /*ARGSUSED*/
2017 2017 static int
2018 2018 mrsas_tran_reset(struct scsi_address *ap, int level)
2019 2019 {
2020 2020 struct mrsas_instance *instance = ADDR2MR(ap);
2021 2021
2022 2022 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2023 2023
2024 2024 if (wait_for_outstanding(instance)) {
2025 2025 con_log(CL_ANN1,
2026 2026 (CE_CONT, "wait_for_outstanding: return FAIL.\n"));
2027 2027 return (DDI_FAILURE);
2028 2028 } else {
2029 2029 return (DDI_SUCCESS);
2030 2030 }
2031 2031 }
2032 2032
2033 2033 /*
2034 2034 * tran_getcap - get one of a set of SCSA-defined capabilities
2035 2035 * @ap:
2036 2036 * @cap:
2037 2037 * @whom:
2038 2038 *
2039 2039 * The target driver can request the current setting of the capability for a
2040 2040 * particular target by setting the whom parameter to nonzero. A whom value of
2041 2041 * zero indicates a request for the current setting of the general capability
2042 2042 * for the SCSI bus or for adapter hardware. The tran_getcap() should return -1
2043 2043 * for undefined capabilities or the current value of the requested capability.
2044 2044 */
2045 2045 /*ARGSUSED*/
2046 2046 static int
2047 2047 mrsas_tran_getcap(struct scsi_address *ap, char *cap, int whom)
2048 2048 {
2049 2049 int rval = 0;
2050 2050
2051 2051 struct mrsas_instance *instance = ADDR2MR(ap);
2052 2052
2053 2053 con_log(CL_DLEVEL2, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2054 2054
2055 2055 /* we do allow inquiring about capabilities for other targets */
2056 2056 if (cap == NULL) {
2057 2057 return (-1);
2058 2058 }
2059 2059
2060 2060 switch (scsi_hba_lookup_capstr(cap)) {
2061 2061 case SCSI_CAP_DMA_MAX:
2062 2062 if (instance->tbolt) {
2063 2063 /* Limit to 256k max transfer */
2064 2064 rval = mrsas_tbolt_max_cap_maxxfer;
2065 2065 } else {
2066 2066 /* Limit to 16MB max transfer */
2067 2067 rval = mrsas_max_cap_maxxfer;
2068 2068 }
2069 2069 break;
2070 2070 case SCSI_CAP_MSG_OUT:
2071 2071 rval = 1;
2072 2072 break;
2073 2073 case SCSI_CAP_DISCONNECT:
2074 2074 rval = 0;
2075 2075 break;
2076 2076 case SCSI_CAP_SYNCHRONOUS:
2077 2077 rval = 0;
2078 2078 break;
2079 2079 case SCSI_CAP_WIDE_XFER:
2080 2080 rval = 1;
2081 2081 break;
2082 2082 case SCSI_CAP_TAGGED_QING:
2083 2083 rval = 1;
2084 2084 break;
2085 2085 case SCSI_CAP_UNTAGGED_QING:
2086 2086 rval = 1;
2087 2087 break;
2088 2088 case SCSI_CAP_PARITY:
2089 2089 rval = 1;
2090 2090 break;
2091 2091 case SCSI_CAP_INITIATOR_ID:
2092 2092 rval = instance->init_id;
2093 2093 break;
2094 2094 case SCSI_CAP_ARQ:
2095 2095 rval = 1;
2096 2096 break;
2097 2097 case SCSI_CAP_LINKED_CMDS:
2098 2098 rval = 0;
2099 2099 break;
2100 2100 case SCSI_CAP_RESET_NOTIFICATION:
2101 2101 rval = 1;
2102 2102 break;
2103 2103 case SCSI_CAP_GEOMETRY:
2104 2104 rval = -1;
2105 2105
2106 2106 break;
2107 2107 default:
2108 2108 con_log(CL_DLEVEL2, (CE_NOTE, "Default cap coming 0x%x",
2109 2109 scsi_hba_lookup_capstr(cap)));
2110 2110 rval = -1;
2111 2111 break;
2112 2112 }
2113 2113
2114 2114 return (rval);
2115 2115 }
2116 2116
2117 2117 /*
2118 2118 * tran_setcap - set one of a set of SCSA-defined capabilities
2119 2119 * @ap:
2120 2120 * @cap:
2121 2121 * @value:
2122 2122 * @whom:
2123 2123 *
2124 2124 * The target driver might request that the new value be set for a particular
2125 2125 * target by setting the whom parameter to nonzero. A whom value of zero
2126 2126 * means that request is to set the new value for the SCSI bus or for adapter
2127 2127 * hardware in general.
2128 2128 * The tran_setcap() should return the following values as appropriate:
2129 2129 * - -1 for undefined capabilities
2130 2130 * - 0 if the HBA driver cannot set the capability to the requested value
2131 2131 * - 1 if the HBA driver is able to set the capability to the requested value
2132 2132 */
2133 2133 /*ARGSUSED*/
2134 2134 static int
2135 2135 mrsas_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
2136 2136 {
2137 2137 int rval = 1;
2138 2138
2139 2139 con_log(CL_DLEVEL2, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2140 2140
2141 2141 /* We don't allow setting capabilities for other targets */
2142 2142 if (cap == NULL || whom == 0) {
2143 2143 return (-1);
2144 2144 }
2145 2145
2146 2146 switch (scsi_hba_lookup_capstr(cap)) {
2147 2147 case SCSI_CAP_DMA_MAX:
2148 2148 case SCSI_CAP_MSG_OUT:
2149 2149 case SCSI_CAP_PARITY:
2150 2150 case SCSI_CAP_LINKED_CMDS:
2151 2151 case SCSI_CAP_RESET_NOTIFICATION:
2152 2152 case SCSI_CAP_DISCONNECT:
2153 2153 case SCSI_CAP_SYNCHRONOUS:
2154 2154 case SCSI_CAP_UNTAGGED_QING:
2155 2155 case SCSI_CAP_WIDE_XFER:
2156 2156 case SCSI_CAP_INITIATOR_ID:
2157 2157 case SCSI_CAP_ARQ:
2158 2158 /*
2159 2159 * None of these are settable via
2160 2160 * the capability interface.
2161 2161 */
2162 2162 break;
2163 2163 case SCSI_CAP_TAGGED_QING:
2164 2164 rval = 1;
2165 2165 break;
2166 2166 case SCSI_CAP_SECTOR_SIZE:
2167 2167 rval = 1;
2168 2168 break;
2169 2169
2170 2170 case SCSI_CAP_TOTAL_SECTORS:
2171 2171 rval = 1;
2172 2172 break;
2173 2173 default:
2174 2174 rval = -1;
2175 2175 break;
2176 2176 }
2177 2177
2178 2178 return (rval);
2179 2179 }
2180 2180
2181 2181 /*
2182 2182 * tran_destroy_pkt - deallocate scsi_pkt structure
2183 2183 * @ap:
2184 2184 * @pkt:
2185 2185 *
2186 2186 * The tran_destroy_pkt() entry point is the HBA driver function that
2187 2187 * deallocates scsi_pkt structures. The tran_destroy_pkt() entry point is
2188 2188 * called when the target driver calls scsi_destroy_pkt(). The
2189 2189 * tran_destroy_pkt() entry point must free any DMA resources that have been
2190 2190 * allocated for the packet. An implicit DMA synchronization occurs if the
2191 2191 * DMA resources are freed and any cached data remains after the completion
2192 2192 * of the transfer.
2193 2193 */
2194 2194 static void
2195 2195 mrsas_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2196 2196 {
2197 2197 struct scsa_cmd *acmd = PKT2CMD(pkt);
2198 2198
2199 2199 con_log(CL_DLEVEL2, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2200 2200
2201 2201 if (acmd->cmd_flags & CFLAG_DMAVALID) {
2202 2202 acmd->cmd_flags &= ~CFLAG_DMAVALID;
2203 2203
2204 2204 (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);
2205 2205
2206 2206 ddi_dma_free_handle(&acmd->cmd_dmahandle);
2207 2207
2208 2208 acmd->cmd_dmahandle = NULL;
2209 2209 }
2210 2210
2211 2211 /* free the pkt */
2212 2212 scsi_hba_pkt_free(ap, pkt);
2213 2213 }
2214 2214
2215 2215 /*
2216 2216 * tran_dmafree - deallocates DMA resources
2217 2217 * @ap:
2218 2218 * @pkt:
2219 2219 *
2220 2220 * The tran_dmafree() entry point deallocates DMAQ resources that have been
2221 2221 * allocated for a scsi_pkt structure. The tran_dmafree() entry point is
2222 2222 * called when the target driver calls scsi_dmafree(). The tran_dmafree() must
2223 2223 * free only DMA resources allocated for a scsi_pkt structure, not the
2224 2224 * scsi_pkt itself. When DMA resources are freed, a DMA synchronization is
2225 2225 * implicitly performed.
2226 2226 */
2227 2227 /*ARGSUSED*/
2228 2228 static void
2229 2229 mrsas_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
2230 2230 {
2231 2231 register struct scsa_cmd *acmd = PKT2CMD(pkt);
2232 2232
2233 2233 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2234 2234
2235 2235 if (acmd->cmd_flags & CFLAG_DMAVALID) {
2236 2236 acmd->cmd_flags &= ~CFLAG_DMAVALID;
2237 2237
2238 2238 (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle);
2239 2239
2240 2240 ddi_dma_free_handle(&acmd->cmd_dmahandle);
2241 2241
2242 2242 acmd->cmd_dmahandle = NULL;
2243 2243 }
2244 2244 }
2245 2245
2246 2246 /*
2247 2247 * tran_sync_pkt - synchronize the DMA object allocated
2248 2248 * @ap:
2249 2249 * @pkt:
2250 2250 *
2251 2251 * The tran_sync_pkt() entry point synchronizes the DMA object allocated for
2252 2252 * the scsi_pkt structure before or after a DMA transfer. The tran_sync_pkt()
2253 2253 * entry point is called when the target driver calls scsi_sync_pkt(). If the
2254 2254 * data transfer direction is a DMA read from device to memory, tran_sync_pkt()
2255 2255 * must synchronize the CPU's view of the data. If the data transfer direction
2256 2256 * is a DMA write from memory to device, tran_sync_pkt() must synchronize the
2257 2257 * device's view of the data.
2258 2258 */
2259 2259 /*ARGSUSED*/
2260 2260 static void
2261 2261 mrsas_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
2262 2262 {
2263 2263 register struct scsa_cmd *acmd = PKT2CMD(pkt);
2264 2264
2265 2265 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2266 2266
2267 2267 if (acmd->cmd_flags & CFLAG_DMAVALID) {
2268 2268 (void) ddi_dma_sync(acmd->cmd_dmahandle, acmd->cmd_dma_offset,
2269 2269 acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ?
2270 2270 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
2271 2271 }
2272 2272 }
2273 2273
2274 2274 /*ARGSUSED*/
2275 2275 static int
2276 2276 mrsas_tran_quiesce(dev_info_t *dip)
2277 2277 {
2278 2278 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2279 2279
2280 2280 return (1);
2281 2281 }
2282 2282
2283 2283 /*ARGSUSED*/
2284 2284 static int
2285 2285 mrsas_tran_unquiesce(dev_info_t *dip)
2286 2286 {
2287 2287 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2288 2288
2289 2289 return (1);
2290 2290 }
2291 2291
2292 2292
2293 2293 /*
2294 2294 * mrsas_isr(caddr_t)
2295 2295 *
2296 2296 * The Interrupt Service Routine
2297 2297 *
2298 2298 * Collect status for all completed commands and do callback
2299 2299 *
2300 2300 */
2301 2301 static uint_t
2302 2302 mrsas_isr(struct mrsas_instance *instance)
2303 2303 {
2304 2304 int need_softintr;
2305 2305 uint32_t producer;
2306 2306 uint32_t consumer;
2307 2307 uint32_t context;
2308 2308 int retval;
2309 2309
2310 2310 struct mrsas_cmd *cmd;
2311 2311 struct mrsas_header *hdr;
2312 2312 struct scsi_pkt *pkt;
2313 2313
2314 2314 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2315 2315 ASSERT(instance);
2316 2316 if (instance->tbolt) {
2317 2317 mutex_enter(&instance->chip_mtx);
2318 2318 if ((instance->intr_type == DDI_INTR_TYPE_FIXED) &&
2319 2319 !(instance->func_ptr->intr_ack(instance))) {
2320 2320 mutex_exit(&instance->chip_mtx);
2321 2321 return (DDI_INTR_UNCLAIMED);
2322 2322 }
2323 2323 retval = mr_sas_tbolt_process_outstanding_cmd(instance);
2324 2324 mutex_exit(&instance->chip_mtx);
2325 2325 return (retval);
2326 2326 } else {
2327 2327 if ((instance->intr_type == DDI_INTR_TYPE_FIXED) &&
2328 2328 !instance->func_ptr->intr_ack(instance)) {
2329 2329 return (DDI_INTR_UNCLAIMED);
2330 2330 }
2331 2331 }
2332 2332
2333 2333 (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
2334 2334 0, 0, DDI_DMA_SYNC_FORCPU);
2335 2335
2336 2336 if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
2337 2337 != DDI_SUCCESS) {
2338 2338 mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
2339 2339 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
2340 2340 con_log(CL_ANN1, (CE_WARN,
2341 2341 "mr_sas_isr(): FMA check, returning DDI_INTR_UNCLAIMED"));
2342 2342 return (DDI_INTR_CLAIMED);
2343 2343 }
2344 2344 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
2345 2345
2346 2346 #ifdef OCRDEBUG
2347 2347 if (debug_consecutive_timeout_after_ocr_g == 1) {
2348 2348 con_log(CL_ANN1, (CE_NOTE,
2349 2349 "simulating consecutive timeout after ocr"));
2350 2350 return (DDI_INTR_CLAIMED);
2351 2351 }
2352 2352 #endif
2353 2353
2354 2354 mutex_enter(&instance->completed_pool_mtx);
2355 2355 mutex_enter(&instance->cmd_pend_mtx);
2356 2356
2357 2357 producer = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
2358 2358 instance->producer);
2359 2359 consumer = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
2360 2360 instance->consumer);
2361 2361
2362 2362 con_log(CL_ANN, (CE_CONT, " producer %x consumer %x ",
2363 2363 producer, consumer));
2364 2364 if (producer == consumer) {
2365 2365 con_log(CL_ANN, (CE_WARN, "producer == consumer case"));
2366 2366 DTRACE_PROBE2(isr_pc_err, uint32_t, producer,
2367 2367 uint32_t, consumer);
2368 2368 mutex_exit(&instance->cmd_pend_mtx);
2369 2369 mutex_exit(&instance->completed_pool_mtx);
2370 2370 return (DDI_INTR_CLAIMED);
2371 2371 }
2372 2372
2373 2373 while (consumer != producer) {
2374 2374 context = ddi_get32(instance->mfi_internal_dma_obj.acc_handle,
2375 2375 &instance->reply_queue[consumer]);
2376 2376 cmd = instance->cmd_list[context];
2377 2377
2378 2378 if (cmd->sync_cmd == MRSAS_TRUE) {
2379 2379 hdr = (struct mrsas_header *)&cmd->frame->hdr;
2380 2380 if (hdr) {
2381 2381 mlist_del_init(&cmd->list);
2382 2382 }
2383 2383 } else {
2384 2384 pkt = cmd->pkt;
2385 2385 if (pkt) {
2386 2386 mlist_del_init(&cmd->list);
2387 2387 }
2388 2388 }
2389 2389
2390 2390 mlist_add_tail(&cmd->list, &instance->completed_pool_list);
2391 2391
2392 2392 consumer++;
2393 2393 if (consumer == (instance->max_fw_cmds + 1)) {
2394 2394 consumer = 0;
2395 2395 }
2396 2396 }
2397 2397 ddi_put32(instance->mfi_internal_dma_obj.acc_handle,
2398 2398 instance->consumer, consumer);
2399 2399 mutex_exit(&instance->cmd_pend_mtx);
2400 2400 mutex_exit(&instance->completed_pool_mtx);
2401 2401
2402 2402 (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle,
2403 2403 0, 0, DDI_DMA_SYNC_FORDEV);
2404 2404
2405 2405 if (instance->softint_running) {
2406 2406 need_softintr = 0;
2407 2407 } else {
2408 2408 need_softintr = 1;
2409 2409 }
2410 2410
2411 2411 if (instance->isr_level == HIGH_LEVEL_INTR) {
2412 2412 if (need_softintr) {
2413 2413 ddi_trigger_softintr(instance->soft_intr_id);
2414 2414 }
2415 2415 } else {
2416 2416 /*
2417 2417 * Not a high-level interrupt, therefore call the soft level
2418 2418 * interrupt explicitly
2419 2419 */
2420 2420 (void) mrsas_softintr(instance);
2421 2421 }
2422 2422
2423 2423 return (DDI_INTR_CLAIMED);
2424 2424 }
2425 2425
2426 2426
2427 2427 /*
2428 2428 * ************************************************************************** *
2429 2429 * *
2430 2430 * libraries *
2431 2431 * *
2432 2432 * ************************************************************************** *
2433 2433 */
2434 2434 /*
2435 2435 * get_mfi_pkt : Get a command from the free pool
2436 2436 * After successful allocation, the caller of this routine
2437 2437 * must clear the frame buffer (memset to zero) before
2438 2438 * using the packet further.
2439 2439 *
2440 2440 * ***** Note *****
2441 2441 * After clearing the frame buffer the context id of the
2442 2442 * frame buffer SHOULD be restored back.
2443 2443 */
2444 2444 struct mrsas_cmd *
2445 2445 mrsas_get_mfi_pkt(struct mrsas_instance *instance)
2446 2446 {
2447 2447 mlist_t *head = &instance->cmd_pool_list;
2448 2448 struct mrsas_cmd *cmd = NULL;
2449 2449
2450 2450 mutex_enter(&instance->cmd_pool_mtx);
2451 2451
2452 2452 if (!mlist_empty(head)) {
2453 2453 cmd = mlist_entry(head->next, struct mrsas_cmd, list);
2454 2454 mlist_del_init(head->next);
2455 2455 }
2456 2456 if (cmd != NULL) {
2457 2457 cmd->pkt = NULL;
2458 2458 cmd->retry_count_for_ocr = 0;
2459 2459 cmd->drv_pkt_time = 0;
2460 2460
2461 2461 }
2462 2462 mutex_exit(&instance->cmd_pool_mtx);
2463 2463
2464 2464 return (cmd);
2465 2465 }
2466 2466
2467 2467 static struct mrsas_cmd *
2468 2468 get_mfi_app_pkt(struct mrsas_instance *instance)
2469 2469 {
2470 2470 mlist_t *head = &instance->app_cmd_pool_list;
2471 2471 struct mrsas_cmd *cmd = NULL;
2472 2472
2473 2473 mutex_enter(&instance->app_cmd_pool_mtx);
2474 2474
2475 2475 if (!mlist_empty(head)) {
2476 2476 cmd = mlist_entry(head->next, struct mrsas_cmd, list);
2477 2477 mlist_del_init(head->next);
2478 2478 }
2479 2479 if (cmd != NULL) {
2480 2480 cmd->pkt = NULL;
2481 2481 cmd->retry_count_for_ocr = 0;
2482 2482 cmd->drv_pkt_time = 0;
2483 2483 }
2484 2484
2485 2485 mutex_exit(&instance->app_cmd_pool_mtx);
2486 2486
2487 2487 return (cmd);
2488 2488 }
2489 2489 /*
2490 2490 * return_mfi_pkt : Return a cmd to free command pool
2491 2491 */
2492 2492 void
2493 2493 mrsas_return_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
2494 2494 {
2495 2495 mutex_enter(&instance->cmd_pool_mtx);
2496 2496 /* use mlist_add_tail for debug assistance */
2497 2497 mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
2498 2498
2499 2499 mutex_exit(&instance->cmd_pool_mtx);
2500 2500 }
2501 2501
2502 2502 static void
2503 2503 return_mfi_app_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
2504 2504 {
2505 2505 mutex_enter(&instance->app_cmd_pool_mtx);
2506 2506
2507 2507 mlist_add(&cmd->list, &instance->app_cmd_pool_list);
2508 2508
2509 2509 mutex_exit(&instance->app_cmd_pool_mtx);
2510 2510 }
2511 2511 void
2512 2512 push_pending_mfi_pkt(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
2513 2513 {
2514 2514 struct scsi_pkt *pkt;
2515 2515 struct mrsas_header *hdr;
2516 2516 con_log(CL_DLEVEL2, (CE_NOTE, "push_pending_pkt(): Called\n"));
2517 2517 mutex_enter(&instance->cmd_pend_mtx);
2518 2518 mlist_del_init(&cmd->list);
2519 2519 mlist_add_tail(&cmd->list, &instance->cmd_pend_list);
2520 2520 if (cmd->sync_cmd == MRSAS_TRUE) {
2521 2521 hdr = (struct mrsas_header *)&cmd->frame->hdr;
2522 2522 if (hdr) {
2523 2523 con_log(CL_ANN1, (CE_CONT,
2524 2524 "push_pending_mfi_pkt: "
2525 2525 "cmd %p index %x "
2526 2526 "time %llx",
2527 2527 (void *)cmd, cmd->index,
2528 2528 gethrtime()));
2529 2529 /* Wait for specified interval */
2530 2530 cmd->drv_pkt_time = ddi_get16(
2531 2531 cmd->frame_dma_obj.acc_handle, &hdr->timeout);
2532 2532 if (cmd->drv_pkt_time < debug_timeout_g)
2533 2533 cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
2534 2534 con_log(CL_ANN1, (CE_CONT,
2535 2535 "push_pending_pkt(): "
2536 2536 "Called IO Timeout Value %x\n",
2537 2537 cmd->drv_pkt_time));
2538 2538 }
2539 2539 if (hdr && instance->timeout_id == (timeout_id_t)-1) {
2540 2540 instance->timeout_id = timeout(io_timeout_checker,
2541 2541 (void *) instance, drv_usectohz(MRSAS_1_SECOND));
2542 2542 }
2543 2543 } else {
2544 2544 pkt = cmd->pkt;
2545 2545 if (pkt) {
2546 2546 con_log(CL_ANN1, (CE_CONT,
2547 2547 "push_pending_mfi_pkt: "
2548 2548 "cmd %p index %x pkt %p, "
2549 2549 "time %llx",
2550 2550 (void *)cmd, cmd->index, (void *)pkt,
2551 2551 gethrtime()));
2552 2552 cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
2553 2553 }
2554 2554 if (pkt && instance->timeout_id == (timeout_id_t)-1) {
2555 2555 instance->timeout_id = timeout(io_timeout_checker,
2556 2556 (void *) instance, drv_usectohz(MRSAS_1_SECOND));
2557 2557 }
2558 2558 }
2559 2559
2560 2560 mutex_exit(&instance->cmd_pend_mtx);
2561 2561
2562 2562 }
2563 2563
2564 2564 int
2565 2565 mrsas_print_pending_cmds(struct mrsas_instance *instance)
2566 2566 {
2567 2567 mlist_t *head = &instance->cmd_pend_list;
2568 2568 mlist_t *tmp = head;
2569 2569 struct mrsas_cmd *cmd = NULL;
2570 2570 struct mrsas_header *hdr;
2571 2571 unsigned int flag = 1;
2572 2572 struct scsi_pkt *pkt;
2573 2573 int saved_level;
2574 2574 int cmd_count = 0;
2575 2575
2576 2576 saved_level = debug_level_g;
2577 2577 debug_level_g = CL_ANN1;
2578 2578
2579 2579 dev_err(instance->dip, CE_NOTE,
2580 2580 "mrsas_print_pending_cmds(): Called");
2581 2581
2582 2582 while (flag) {
2583 2583 mutex_enter(&instance->cmd_pend_mtx);
2584 2584 tmp = tmp->next;
2585 2585 if (tmp == head) {
2586 2586 mutex_exit(&instance->cmd_pend_mtx);
2587 2587 flag = 0;
2588 2588 con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds():"
2589 2589 " NO MORE CMDS PENDING....\n"));
2590 2590 break;
2591 2591 } else {
2592 2592 cmd = mlist_entry(tmp, struct mrsas_cmd, list);
2593 2593 mutex_exit(&instance->cmd_pend_mtx);
2594 2594 if (cmd) {
2595 2595 if (cmd->sync_cmd == MRSAS_TRUE) {
2596 2596 hdr = (struct mrsas_header *)
2597 2597 &cmd->frame->hdr;
2598 2598 if (hdr) {
2599 2599 con_log(CL_ANN1, (CE_CONT,
2600 2600 "print: cmd %p index 0x%x "
2601 2601 "drv_pkt_time 0x%x (NO-PKT)"
2602 2602 " hdr %p\n", (void *)cmd,
2603 2603 cmd->index,
2604 2604 cmd->drv_pkt_time,
2605 2605 (void *)hdr));
2606 2606 }
2607 2607 } else {
2608 2608 pkt = cmd->pkt;
2609 2609 if (pkt) {
2610 2610 con_log(CL_ANN1, (CE_CONT,
2611 2611 "print: cmd %p index 0x%x "
2612 2612 "drv_pkt_time 0x%x pkt %p \n",
2613 2613 (void *)cmd, cmd->index,
2614 2614 cmd->drv_pkt_time, (void *)pkt));
2615 2615 }
2616 2616 }
2617 2617
2618 2618 if (++cmd_count == 1) {
2619 2619 mrsas_print_cmd_details(instance, cmd,
2620 2620 0xDD);
2621 2621 } else {
2622 2622 mrsas_print_cmd_details(instance, cmd,
2623 2623 1);
2624 2624 }
2625 2625
2626 2626 }
2627 2627 }
2628 2628 }
2629 2629 con_log(CL_ANN1, (CE_CONT, "mrsas_print_pending_cmds(): Done\n"));
2630 2630
2631 2631
2632 2632 debug_level_g = saved_level;
2633 2633
2634 2634 return (DDI_SUCCESS);
2635 2635 }
2636 2636
2637 2637
2638 2638 int
2639 2639 mrsas_complete_pending_cmds(struct mrsas_instance *instance)
2640 2640 {
2641 2641
2642 2642 struct mrsas_cmd *cmd = NULL;
2643 2643 struct scsi_pkt *pkt;
2644 2644 struct mrsas_header *hdr;
2645 2645
2646 2646 struct mlist_head *pos, *next;
2647 2647
2648 2648 con_log(CL_ANN1, (CE_NOTE,
2649 2649 "mrsas_complete_pending_cmds(): Called"));
2650 2650
2651 2651 mutex_enter(&instance->cmd_pend_mtx);
2652 2652 mlist_for_each_safe(pos, next, &instance->cmd_pend_list) {
2653 2653 cmd = mlist_entry(pos, struct mrsas_cmd, list);
2654 2654 if (cmd) {
2655 2655 pkt = cmd->pkt;
2656 2656 if (pkt) { /* for IO */
2657 2657 if (((pkt->pkt_flags & FLAG_NOINTR)
2658 2658 == 0) && pkt->pkt_comp) {
2659 2659 pkt->pkt_reason
2660 2660 = CMD_DEV_GONE;
2661 2661 pkt->pkt_statistics
2662 2662 = STAT_DISCON;
2663 2663 con_log(CL_ANN1, (CE_CONT,
2664 2664 "fail and posting to scsa "
2665 2665 "cmd %p index %x"
2666 2666 " pkt %p "
2667 2667 "time : %llx",
2668 2668 (void *)cmd, cmd->index,
2669 2669 (void *)pkt, gethrtime()));
2670 2670 (*pkt->pkt_comp)(pkt);
2671 2671 }
2672 2672 } else { /* for DCMDS */
2673 2673 if (cmd->sync_cmd == MRSAS_TRUE) {
2674 2674 hdr = (struct mrsas_header *)&cmd->frame->hdr;
2675 2675 con_log(CL_ANN1, (CE_CONT,
2676 2676 "posting invalid status to application "
2677 2677 "cmd %p index %x"
2678 2678 " hdr %p "
2679 2679 "time : %llx",
2680 2680 (void *)cmd, cmd->index,
2681 2681 (void *)hdr, gethrtime()));
2682 2682 hdr->cmd_status = MFI_STAT_INVALID_STATUS;
2683 2683 complete_cmd_in_sync_mode(instance, cmd);
2684 2684 }
2685 2685 }
2686 2686 mlist_del_init(&cmd->list);
2687 2687 } else {
2688 2688 con_log(CL_ANN1, (CE_CONT,
2689 2689 "mrsas_complete_pending_cmds:"
2690 2690 "NULL command\n"));
2691 2691 }
2692 2692 con_log(CL_ANN1, (CE_CONT,
2693 2693 "mrsas_complete_pending_cmds:"
2694 2694 "looping for more commands\n"));
2695 2695 }
2696 2696 mutex_exit(&instance->cmd_pend_mtx);
2697 2697
2698 2698 con_log(CL_ANN1, (CE_CONT, "mrsas_complete_pending_cmds(): DONE\n"));
2699 2699 return (DDI_SUCCESS);
2700 2700 }
2701 2701
2702 2702 void
2703 2703 mrsas_print_cmd_details(struct mrsas_instance *instance, struct mrsas_cmd *cmd,
2704 2704 int detail)
2705 2705 {
2706 2706 struct scsi_pkt *pkt = cmd->pkt;
2707 2707 Mpi2RaidSCSIIORequest_t *scsi_io = cmd->scsi_io_request;
2708 2708 int i;
2709 2709 int saved_level;
2710 2710 ddi_acc_handle_t acc_handle =
2711 2711 instance->mpi2_frame_pool_dma_obj.acc_handle;
2712 2712
2713 2713 if (detail == 0xDD) {
2714 2714 saved_level = debug_level_g;
2715 2715 debug_level_g = CL_ANN1;
2716 2716 }
2717 2717
2718 2718
2719 2719 if (instance->tbolt) {
2720 2720 con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p "
2721 2721 "cmd->index 0x%x SMID 0x%x timer 0x%x sec\n",
2722 2722 (void *)cmd, cmd->index, cmd->SMID, cmd->drv_pkt_time));
2723 2723 } else {
2724 2724 con_log(CL_ANN1, (CE_CONT, "print_cmd_details: cmd %p "
2725 2725 "cmd->index 0x%x timer 0x%x sec\n",
2726 2726 (void *)cmd, cmd->index, cmd->drv_pkt_time));
2727 2727 }
2728 2728
2729 2729 if (pkt) {
2730 2730 con_log(CL_ANN1, (CE_CONT, "scsi_pkt CDB[0]=0x%x",
2731 2731 pkt->pkt_cdbp[0]));
2732 2732 } else {
2733 2733 con_log(CL_ANN1, (CE_CONT, "NO-PKT"));
2734 2734 }
2735 2735
2736 2736 if ((detail == 0xDD) && instance->tbolt) {
2737 2737 con_log(CL_ANN1, (CE_CONT, "RAID_SCSI_IO_REQUEST\n"));
2738 2738 con_log(CL_ANN1, (CE_CONT, "DevHandle=0x%X Function=0x%X "
2739 2739 "IoFlags=0x%X SGLFlags=0x%X DataLength=0x%X\n",
2740 2740 ddi_get16(acc_handle, &scsi_io->DevHandle),
2741 2741 ddi_get8(acc_handle, &scsi_io->Function),
2742 2742 ddi_get16(acc_handle, &scsi_io->IoFlags),
2743 2743 ddi_get16(acc_handle, &scsi_io->SGLFlags),
2744 2744 ddi_get32(acc_handle, &scsi_io->DataLength)));
2745 2745
2746 2746 for (i = 0; i < 32; i++) {
2747 2747 con_log(CL_ANN1, (CE_CONT, "CDB[%d]=0x%x ", i,
2748 2748 ddi_get8(acc_handle, &scsi_io->CDB.CDB32[i])));
2749 2749 }
2750 2750
2751 2751 con_log(CL_ANN1, (CE_CONT, "RAID-CONTEXT\n"));
2752 2752 con_log(CL_ANN1, (CE_CONT, "status=0x%X extStatus=0x%X "
2753 2753 "ldTargetId=0x%X timeoutValue=0x%X regLockFlags=0x%X "
2754 2754 "RAIDFlags=0x%X regLockRowLBA=0x%" PRIu64
2755 2755 " regLockLength=0x%X spanArm=0x%X\n",
2756 2756 ddi_get8(acc_handle, &scsi_io->RaidContext.status),
2757 2757 ddi_get8(acc_handle, &scsi_io->RaidContext.extStatus),
2758 2758 ddi_get16(acc_handle, &scsi_io->RaidContext.ldTargetId),
2759 2759 ddi_get16(acc_handle, &scsi_io->RaidContext.timeoutValue),
2760 2760 ddi_get8(acc_handle, &scsi_io->RaidContext.regLockFlags),
2761 2761 ddi_get8(acc_handle, &scsi_io->RaidContext.RAIDFlags),
2762 2762 ddi_get64(acc_handle, &scsi_io->RaidContext.regLockRowLBA),
2763 2763 ddi_get32(acc_handle, &scsi_io->RaidContext.regLockLength),
2764 2764 ddi_get8(acc_handle, &scsi_io->RaidContext.spanArm)));
2765 2765 }
2766 2766
2767 2767 if (detail == 0xDD) {
2768 2768 debug_level_g = saved_level;
2769 2769 }
2770 2770 }
2771 2771
2772 2772
2773 2773 int
2774 2774 mrsas_issue_pending_cmds(struct mrsas_instance *instance)
2775 2775 {
2776 2776 mlist_t *head = &instance->cmd_pend_list;
2777 2777 mlist_t *tmp = head->next;
2778 2778 struct mrsas_cmd *cmd = NULL;
2779 2779 struct scsi_pkt *pkt;
2780 2780
2781 2781 con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_pending_cmds(): Called"));
2782 2782 while (tmp != head) {
2783 2783 mutex_enter(&instance->cmd_pend_mtx);
2784 2784 cmd = mlist_entry(tmp, struct mrsas_cmd, list);
2785 2785 tmp = tmp->next;
2786 2786 mutex_exit(&instance->cmd_pend_mtx);
2787 2787 if (cmd) {
2788 2788 con_log(CL_ANN1, (CE_CONT,
2789 2789 "mrsas_issue_pending_cmds(): "
2790 2790 "Got a cmd: cmd %p index 0x%x drv_pkt_time 0x%x ",
2791 2791 (void *)cmd, cmd->index, cmd->drv_pkt_time));
2792 2792
2793 2793 /* Reset command timeout value */
2794 2794 if (cmd->drv_pkt_time < debug_timeout_g)
2795 2795 cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
2796 2796
2797 2797 cmd->retry_count_for_ocr++;
2798 2798
2799 2799 dev_err(instance->dip, CE_CONT,
2800 2800 "cmd retry count = %d\n",
2801 2801 cmd->retry_count_for_ocr);
2802 2802
2803 2803 if (cmd->retry_count_for_ocr > IO_RETRY_COUNT) {
2804 2804 dev_err(instance->dip,
2805 2805 CE_WARN, "mrsas_issue_pending_cmds(): "
2806 2806 "cmd->retry_count exceeded limit >%d\n",
2807 2807 IO_RETRY_COUNT);
2808 2808 mrsas_print_cmd_details(instance, cmd, 0xDD);
2809 2809
2810 2810 dev_err(instance->dip, CE_WARN,
2811 2811 "mrsas_issue_pending_cmds():"
2812 2812 "Calling KILL Adapter");
2813 2813 if (instance->tbolt)
2814 2814 mrsas_tbolt_kill_adapter(instance);
2815 2815 else
2816 2816 (void) mrsas_kill_adapter(instance);
2817 2817 return (DDI_FAILURE);
2818 2818 }
2819 2819
2820 2820 pkt = cmd->pkt;
2821 2821 if (pkt) {
2822 2822 con_log(CL_ANN1, (CE_CONT,
2823 2823 "PENDING PKT-CMD ISSUE: cmd %p index %x "
2824 2824 "pkt %p time %llx",
2825 2825 (void *)cmd, cmd->index,
2826 2826 (void *)pkt,
2827 2827 gethrtime()));
2828 2828
2829 2829 } else {
2830 2830 dev_err(instance->dip, CE_CONT,
2831 2831 "mrsas_issue_pending_cmds(): NO-PKT, "
2832 2832 "cmd %p index 0x%x drv_pkt_time 0x%x",
2833 2833 (void *)cmd, cmd->index, cmd->drv_pkt_time);
2834 2834 }
2835 2835
2836 2836
2837 2837 if (cmd->sync_cmd == MRSAS_TRUE) {
2838 2838 dev_err(instance->dip, CE_CONT,
2839 2839 "mrsas_issue_pending_cmds(): "
2840 2840 "SYNC_CMD == TRUE \n");
2841 2841 instance->func_ptr->issue_cmd_in_sync_mode(
2842 2842 instance, cmd);
2843 2843 } else {
2844 2844 instance->func_ptr->issue_cmd(cmd, instance);
2845 2845 }
2846 2846 } else {
2847 2847 con_log(CL_ANN1, (CE_CONT,
2848 2848 "mrsas_issue_pending_cmds: NULL command\n"));
2849 2849 }
2850 2850 con_log(CL_ANN1, (CE_CONT,
2851 2851 "mrsas_issue_pending_cmds:"
2852 2852 "looping for more commands"));
2853 2853 }
2854 2854 con_log(CL_ANN1, (CE_CONT, "mrsas_issue_pending_cmds(): DONE\n"));
2855 2855 return (DDI_SUCCESS);
2856 2856 }
2857 2857
2858 2858
2859 2859
2860 2860 /*
2861 2861 * destroy_mfi_frame_pool
2862 2862 */
2863 2863 void
2864 2864 destroy_mfi_frame_pool(struct mrsas_instance *instance)
2865 2865 {
2866 2866 int i;
2867 2867 uint32_t max_cmd = instance->max_fw_cmds;
2868 2868
2869 2869 struct mrsas_cmd *cmd;
2870 2870
2871 2871 /* return all frames to pool */
2872 2872
2873 2873 for (i = 0; i < max_cmd; i++) {
2874 2874
2875 2875 cmd = instance->cmd_list[i];
2876 2876
2877 2877 if (cmd->frame_dma_obj_status == DMA_OBJ_ALLOCATED)
2878 2878 (void) mrsas_free_dma_obj(instance, cmd->frame_dma_obj);
2879 2879
2880 2880 cmd->frame_dma_obj_status = DMA_OBJ_FREED;
2881 2881 }
2882 2882
2883 2883 }
2884 2884
2885 2885 /*
2886 2886 * create_mfi_frame_pool
2887 2887 */
2888 2888 int
2889 2889 create_mfi_frame_pool(struct mrsas_instance *instance)
2890 2890 {
2891 2891 int i = 0;
2892 2892 int cookie_cnt;
2893 2893 uint16_t max_cmd;
2894 2894 uint16_t sge_sz;
2895 2895 uint32_t sgl_sz;
2896 2896 uint32_t tot_frame_size;
2897 2897 struct mrsas_cmd *cmd;
2898 2898 int retval = DDI_SUCCESS;
2899 2899
2900 2900 max_cmd = instance->max_fw_cmds;
2901 2901 sge_sz = sizeof (struct mrsas_sge_ieee);
2902 2902 /* calculated the number of 64byte frames required for SGL */
2903 2903 sgl_sz = sge_sz * instance->max_num_sge;
2904 2904 tot_frame_size = sgl_sz + MRMFI_FRAME_SIZE + SENSE_LENGTH;
2905 2905
2906 2906 con_log(CL_DLEVEL3, (CE_NOTE, "create_mfi_frame_pool: "
2907 2907 "sgl_sz %x tot_frame_size %x", sgl_sz, tot_frame_size));
2908 2908
2909 2909 while (i < max_cmd) {
2910 2910 cmd = instance->cmd_list[i];
2911 2911
2912 2912 cmd->frame_dma_obj.size = tot_frame_size;
2913 2913 cmd->frame_dma_obj.dma_attr = mrsas_generic_dma_attr;
2914 2914 cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
2915 2915 cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
2916 2916 cmd->frame_dma_obj.dma_attr.dma_attr_sgllen = 1;
2917 2917 cmd->frame_dma_obj.dma_attr.dma_attr_align = 64;
2918 2918
2919 2919 cookie_cnt = mrsas_alloc_dma_obj(instance, &cmd->frame_dma_obj,
2920 2920 (uchar_t)DDI_STRUCTURE_LE_ACC);
2921 2921
2922 2922 if (cookie_cnt == -1 || cookie_cnt > 1) {
2923 2923 dev_err(instance->dip, CE_WARN,
2924 2924 "create_mfi_frame_pool: could not alloc.");
2925 2925 retval = DDI_FAILURE;
2926 2926 goto mrsas_undo_frame_pool;
2927 2927 }
2928 2928
2929 2929 bzero(cmd->frame_dma_obj.buffer, tot_frame_size);
2930 2930
2931 2931 cmd->frame_dma_obj_status = DMA_OBJ_ALLOCATED;
2932 2932 cmd->frame = (union mrsas_frame *)cmd->frame_dma_obj.buffer;
2933 2933 cmd->frame_phys_addr =
2934 2934 cmd->frame_dma_obj.dma_cookie[0].dmac_address;
2935 2935
2936 2936 cmd->sense = (uint8_t *)(((unsigned long)
2937 2937 cmd->frame_dma_obj.buffer) +
2938 2938 tot_frame_size - SENSE_LENGTH);
2939 2939 cmd->sense_phys_addr =
2940 2940 cmd->frame_dma_obj.dma_cookie[0].dmac_address +
2941 2941 tot_frame_size - SENSE_LENGTH;
2942 2942
2943 2943 if (!cmd->frame || !cmd->sense) {
2944 2944 dev_err(instance->dip, CE_WARN,
2945 2945 "pci_pool_alloc failed");
2946 2946 retval = ENOMEM;
2947 2947 goto mrsas_undo_frame_pool;
2948 2948 }
2949 2949
2950 2950 ddi_put32(cmd->frame_dma_obj.acc_handle,
2951 2951 &cmd->frame->io.context, cmd->index);
2952 2952 i++;
2953 2953
2954 2954 con_log(CL_DLEVEL3, (CE_NOTE, "[%x]-%x",
2955 2955 cmd->index, cmd->frame_phys_addr));
2956 2956 }
2957 2957
2958 2958 return (DDI_SUCCESS);
2959 2959
2960 2960 mrsas_undo_frame_pool:
2961 2961 if (i > 0)
2962 2962 destroy_mfi_frame_pool(instance);
2963 2963
2964 2964 return (retval);
2965 2965 }
2966 2966
2967 2967 /*
2968 2968 * free_additional_dma_buffer
2969 2969 */
2970 2970 static void
2971 2971 free_additional_dma_buffer(struct mrsas_instance *instance)
2972 2972 {
2973 2973 if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) {
2974 2974 (void) mrsas_free_dma_obj(instance,
2975 2975 instance->mfi_internal_dma_obj);
2976 2976 instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
2977 2977 }
2978 2978
2979 2979 if (instance->mfi_evt_detail_obj.status == DMA_OBJ_ALLOCATED) {
2980 2980 (void) mrsas_free_dma_obj(instance,
2981 2981 instance->mfi_evt_detail_obj);
2982 2982 instance->mfi_evt_detail_obj.status = DMA_OBJ_FREED;
2983 2983 }
2984 2984 }
2985 2985
2986 2986 /*
2987 2987 * alloc_additional_dma_buffer
2988 2988 */
2989 2989 static int
2990 2990 alloc_additional_dma_buffer(struct mrsas_instance *instance)
2991 2991 {
2992 2992 uint32_t reply_q_sz;
2993 2993 uint32_t internal_buf_size = PAGESIZE*2;
2994 2994
2995 2995 /* max cmds plus 1 + producer & consumer */
2996 2996 reply_q_sz = sizeof (uint32_t) * (instance->max_fw_cmds + 1 + 2);
2997 2997
2998 2998 instance->mfi_internal_dma_obj.size = internal_buf_size;
2999 2999 instance->mfi_internal_dma_obj.dma_attr = mrsas_generic_dma_attr;
3000 3000 instance->mfi_internal_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
3001 3001 instance->mfi_internal_dma_obj.dma_attr.dma_attr_count_max =
3002 3002 0xFFFFFFFFU;
3003 3003 instance->mfi_internal_dma_obj.dma_attr.dma_attr_sgllen = 1;
3004 3004
3005 3005 if (mrsas_alloc_dma_obj(instance, &instance->mfi_internal_dma_obj,
3006 3006 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
3007 3007 dev_err(instance->dip, CE_WARN,
3008 3008 "could not alloc reply queue");
3009 3009 return (DDI_FAILURE);
3010 3010 }
3011 3011
3012 3012 bzero(instance->mfi_internal_dma_obj.buffer, internal_buf_size);
3013 3013
3014 3014 instance->mfi_internal_dma_obj.status |= DMA_OBJ_ALLOCATED;
3015 3015
3016 3016 instance->producer = (uint32_t *)((unsigned long)
3017 3017 instance->mfi_internal_dma_obj.buffer);
3018 3018 instance->consumer = (uint32_t *)((unsigned long)
3019 3019 instance->mfi_internal_dma_obj.buffer + 4);
3020 3020 instance->reply_queue = (uint32_t *)((unsigned long)
3021 3021 instance->mfi_internal_dma_obj.buffer + 8);
3022 3022 instance->internal_buf = (caddr_t)(((unsigned long)
3023 3023 instance->mfi_internal_dma_obj.buffer) + reply_q_sz + 8);
3024 3024 instance->internal_buf_dmac_add =
3025 3025 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address +
3026 3026 (reply_q_sz + 8);
3027 3027 instance->internal_buf_size = internal_buf_size -
3028 3028 (reply_q_sz + 8);
3029 3029
3030 3030 /* allocate evt_detail */
3031 3031 instance->mfi_evt_detail_obj.size = sizeof (struct mrsas_evt_detail);
3032 3032 instance->mfi_evt_detail_obj.dma_attr = mrsas_generic_dma_attr;
3033 3033 instance->mfi_evt_detail_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
3034 3034 instance->mfi_evt_detail_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
3035 3035 instance->mfi_evt_detail_obj.dma_attr.dma_attr_sgllen = 1;
3036 3036 instance->mfi_evt_detail_obj.dma_attr.dma_attr_align = 1;
3037 3037
3038 3038 if (mrsas_alloc_dma_obj(instance, &instance->mfi_evt_detail_obj,
3039 3039 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
3040 3040 dev_err(instance->dip, CE_WARN, "alloc_additional_dma_buffer: "
3041 3041 "could not allocate data transfer buffer.");
3042 3042 goto mrsas_undo_internal_buff;
3043 3043 }
3044 3044
3045 3045 bzero(instance->mfi_evt_detail_obj.buffer,
3046 3046 sizeof (struct mrsas_evt_detail));
3047 3047
3048 3048 instance->mfi_evt_detail_obj.status |= DMA_OBJ_ALLOCATED;
3049 3049
3050 3050 return (DDI_SUCCESS);
3051 3051
3052 3052 mrsas_undo_internal_buff:
3053 3053 if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) {
3054 3054 (void) mrsas_free_dma_obj(instance,
3055 3055 instance->mfi_internal_dma_obj);
3056 3056 instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED;
3057 3057 }
3058 3058
3059 3059 return (DDI_FAILURE);
3060 3060 }
3061 3061
3062 3062
3063 3063 void
3064 3064 mrsas_free_cmd_pool(struct mrsas_instance *instance)
3065 3065 {
3066 3066 int i;
3067 3067 uint32_t max_cmd;
3068 3068 size_t sz;
3069 3069
3070 3070 /* already freed */
3071 3071 if (instance->cmd_list == NULL) {
3072 3072 return;
3073 3073 }
3074 3074
3075 3075 max_cmd = instance->max_fw_cmds;
3076 3076
3077 3077 /* size of cmd_list array */
3078 3078 sz = sizeof (struct mrsas_cmd *) * max_cmd;
3079 3079
3080 3080 /* First free each cmd */
3081 3081 for (i = 0; i < max_cmd; i++) {
3082 3082 if (instance->cmd_list[i] != NULL) {
3083 3083 kmem_free(instance->cmd_list[i],
3084 3084 sizeof (struct mrsas_cmd));
3085 3085 }
3086 3086
3087 3087 instance->cmd_list[i] = NULL;
3088 3088 }
3089 3089
3090 3090 /* Now, free cmd_list array */
3091 3091 if (instance->cmd_list != NULL)
3092 3092 kmem_free(instance->cmd_list, sz);
3093 3093
3094 3094 instance->cmd_list = NULL;
3095 3095
3096 3096 INIT_LIST_HEAD(&instance->cmd_pool_list);
3097 3097 INIT_LIST_HEAD(&instance->cmd_pend_list);
3098 3098 if (instance->tbolt) {
3099 3099 INIT_LIST_HEAD(&instance->cmd_app_pool_list);
3100 3100 } else {
3101 3101 INIT_LIST_HEAD(&instance->app_cmd_pool_list);
3102 3102 }
3103 3103
3104 3104 }
3105 3105
3106 3106
3107 3107 /*
3108 3108 * mrsas_alloc_cmd_pool
3109 3109 */
3110 3110 int
3111 3111 mrsas_alloc_cmd_pool(struct mrsas_instance *instance)
3112 3112 {
3113 3113 int i;
3114 3114 int count;
3115 3115 uint32_t max_cmd;
3116 3116 uint32_t reserve_cmd;
3117 3117 size_t sz;
3118 3118
3119 3119 struct mrsas_cmd *cmd;
3120 3120
3121 3121 max_cmd = instance->max_fw_cmds;
3122 3122 con_log(CL_ANN1, (CE_NOTE, "mrsas_alloc_cmd_pool: "
3123 3123 "max_cmd %x", max_cmd));
3124 3124
3125 3125
3126 3126 sz = sizeof (struct mrsas_cmd *) * max_cmd;
3127 3127
3128 3128 /*
3129 3129 * instance->cmd_list is an array of struct mrsas_cmd pointers.
3130 3130 * Allocate the dynamic array first and then allocate individual
3131 3131 * commands.
3132 3132 */
3133 3133 instance->cmd_list = kmem_zalloc(sz, KM_SLEEP);
3134 3134 ASSERT(instance->cmd_list);
3135 3135
3136 3136 /* create a frame pool and assign one frame to each cmd */
3137 3137 for (count = 0; count < max_cmd; count++) {
3138 3138 instance->cmd_list[count] =
3139 3139 kmem_zalloc(sizeof (struct mrsas_cmd), KM_SLEEP);
3140 3140 ASSERT(instance->cmd_list[count]);
3141 3141 }
3142 3142
3143 3143 /* add all the commands to command pool */
3144 3144
3145 3145 INIT_LIST_HEAD(&instance->cmd_pool_list);
3146 3146 INIT_LIST_HEAD(&instance->cmd_pend_list);
3147 3147 INIT_LIST_HEAD(&instance->app_cmd_pool_list);
3148 3148
3149 3149 /*
3150 3150 * When max_cmd is lower than MRSAS_APP_RESERVED_CMDS, how do I split
3151 3151 * into app_cmd and regular cmd? For now, just take
3152 3152 * max(1/8th of max, 4);
3153 3153 */
3154 3154 reserve_cmd = min(MRSAS_APP_RESERVED_CMDS,
3155 3155 max(max_cmd >> 3, MRSAS_APP_MIN_RESERVED_CMDS));
3156 3156
3157 3157 for (i = 0; i < reserve_cmd; i++) {
3158 3158 cmd = instance->cmd_list[i];
3159 3159 cmd->index = i;
3160 3160 mlist_add_tail(&cmd->list, &instance->app_cmd_pool_list);
3161 3161 }
3162 3162
3163 3163
3164 3164 for (i = reserve_cmd; i < max_cmd; i++) {
3165 3165 cmd = instance->cmd_list[i];
3166 3166 cmd->index = i;
3167 3167 mlist_add_tail(&cmd->list, &instance->cmd_pool_list);
3168 3168 }
3169 3169
3170 3170 return (DDI_SUCCESS);
3171 3171
3172 3172 mrsas_undo_cmds:
3173 3173 if (count > 0) {
3174 3174 /* free each cmd */
3175 3175 for (i = 0; i < count; i++) {
3176 3176 if (instance->cmd_list[i] != NULL) {
3177 3177 kmem_free(instance->cmd_list[i],
3178 3178 sizeof (struct mrsas_cmd));
3179 3179 }
3180 3180 instance->cmd_list[i] = NULL;
3181 3181 }
3182 3182 }
3183 3183
3184 3184 mrsas_undo_cmd_list:
3185 3185 if (instance->cmd_list != NULL)
3186 3186 kmem_free(instance->cmd_list, sz);
3187 3187 instance->cmd_list = NULL;
3188 3188
3189 3189 return (DDI_FAILURE);
3190 3190 }
3191 3191
3192 3192
3193 3193 /*
3194 3194 * free_space_for_mfi
3195 3195 */
3196 3196 static void
3197 3197 free_space_for_mfi(struct mrsas_instance *instance)
3198 3198 {
3199 3199
3200 3200 /* already freed */
3201 3201 if (instance->cmd_list == NULL) {
3202 3202 return;
3203 3203 }
3204 3204
3205 3205 /* Free additional dma buffer */
3206 3206 free_additional_dma_buffer(instance);
3207 3207
3208 3208 /* Free the MFI frame pool */
3209 3209 destroy_mfi_frame_pool(instance);
3210 3210
3211 3211 /* Free all the commands in the cmd_list */
3212 3212 /* Free the cmd_list buffer itself */
3213 3213 mrsas_free_cmd_pool(instance);
3214 3214 }
3215 3215
3216 3216 /*
3217 3217 * alloc_space_for_mfi
3218 3218 */
3219 3219 static int
3220 3220 alloc_space_for_mfi(struct mrsas_instance *instance)
3221 3221 {
3222 3222 /* Allocate command pool (memory for cmd_list & individual commands) */
3223 3223 if (mrsas_alloc_cmd_pool(instance)) {
3224 3224 dev_err(instance->dip, CE_WARN, "error creating cmd pool");
3225 3225 return (DDI_FAILURE);
3226 3226 }
3227 3227
3228 3228 /* Allocate MFI Frame pool */
3229 3229 if (create_mfi_frame_pool(instance)) {
3230 3230 dev_err(instance->dip, CE_WARN,
3231 3231 "error creating frame DMA pool");
3232 3232 goto mfi_undo_cmd_pool;
3233 3233 }
3234 3234
3235 3235 /* Allocate additional DMA buffer */
3236 3236 if (alloc_additional_dma_buffer(instance)) {
3237 3237 dev_err(instance->dip, CE_WARN,
3238 3238 "error creating frame DMA pool");
3239 3239 goto mfi_undo_frame_pool;
3240 3240 }
3241 3241
3242 3242 return (DDI_SUCCESS);
3243 3243
3244 3244 mfi_undo_frame_pool:
3245 3245 destroy_mfi_frame_pool(instance);
3246 3246
3247 3247 mfi_undo_cmd_pool:
3248 3248 mrsas_free_cmd_pool(instance);
3249 3249
3250 3250 return (DDI_FAILURE);
3251 3251 }
3252 3252
3253 3253
3254 3254
3255 3255 /*
3256 3256 * get_ctrl_info
3257 3257 */
3258 3258 static int
3259 3259 get_ctrl_info(struct mrsas_instance *instance,
3260 3260 struct mrsas_ctrl_info *ctrl_info)
3261 3261 {
3262 3262 int ret = 0;
3263 3263
3264 3264 struct mrsas_cmd *cmd;
3265 3265 struct mrsas_dcmd_frame *dcmd;
3266 3266 struct mrsas_ctrl_info *ci;
3267 3267
3268 3268 if (instance->tbolt) {
3269 3269 cmd = get_raid_msg_mfi_pkt(instance);
3270 3270 } else {
3271 3271 cmd = mrsas_get_mfi_pkt(instance);
3272 3272 }
3273 3273
3274 3274 if (!cmd) {
3275 3275 con_log(CL_ANN, (CE_WARN,
3276 3276 "Failed to get a cmd for ctrl info"));
3277 3277 DTRACE_PROBE2(info_mfi_err, uint16_t, instance->fw_outstanding,
3278 3278 uint16_t, instance->max_fw_cmds);
3279 3279 return (DDI_FAILURE);
3280 3280 }
3281 3281
3282 3282 /* Clear the frame buffer and assign back the context id */
3283 3283 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
3284 3284 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
3285 3285 cmd->index);
3286 3286
3287 3287 dcmd = &cmd->frame->dcmd;
3288 3288
3289 3289 ci = (struct mrsas_ctrl_info *)instance->internal_buf;
3290 3290
3291 3291 if (!ci) {
3292 3292 dev_err(instance->dip, CE_WARN,
3293 3293 "Failed to alloc mem for ctrl info");
3294 3294 mrsas_return_mfi_pkt(instance, cmd);
3295 3295 return (DDI_FAILURE);
3296 3296 }
3297 3297
3298 3298 (void) memset(ci, 0, sizeof (struct mrsas_ctrl_info));
3299 3299
3300 3300 /* for( i = 0; i < DCMD_MBOX_SZ; i++ ) dcmd->mbox.b[i] = 0; */
3301 3301 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
3302 3302
3303 3303 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
3304 3304 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status,
3305 3305 MFI_CMD_STATUS_POLL_MODE);
3306 3306 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 1);
3307 3307 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
3308 3308 MFI_FRAME_DIR_READ);
3309 3309 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
3310 3310 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len,
3311 3311 sizeof (struct mrsas_ctrl_info));
3312 3312 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
3313 3313 MR_DCMD_CTRL_GET_INFO);
3314 3314 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].phys_addr,
3315 3315 instance->internal_buf_dmac_add);
3316 3316 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
3317 3317 sizeof (struct mrsas_ctrl_info));
3318 3318
3319 3319 cmd->frame_count = 1;
3320 3320
3321 3321 if (instance->tbolt) {
3322 3322 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
3323 3323 }
3324 3324
3325 3325 if (!instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
3326 3326 ret = 0;
3327 3327
3328 3328 ctrl_info->max_request_size = ddi_get32(
3329 3329 cmd->frame_dma_obj.acc_handle, &ci->max_request_size);
3330 3330
3331 3331 ctrl_info->ld_present_count = ddi_get16(
3332 3332 cmd->frame_dma_obj.acc_handle, &ci->ld_present_count);
3333 3333
3334 3334 ctrl_info->properties.on_off_properties = ddi_get32(
3335 3335 cmd->frame_dma_obj.acc_handle,
3336 3336 &ci->properties.on_off_properties);
3337 3337 ddi_rep_get8(cmd->frame_dma_obj.acc_handle,
3338 3338 (uint8_t *)(ctrl_info->product_name),
3339 3339 (uint8_t *)(ci->product_name), 80 * sizeof (char),
3340 3340 DDI_DEV_AUTOINCR);
3341 3341 /* should get more members of ci with ddi_get when needed */
3342 3342 } else {
3343 3343 dev_err(instance->dip, CE_WARN,
3344 3344 "get_ctrl_info: Ctrl info failed");
3345 3345 ret = -1;
3346 3346 }
3347 3347
3348 3348 if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
3349 3349 ret = -1;
3350 3350 }
3351 3351 if (instance->tbolt) {
3352 3352 return_raid_msg_mfi_pkt(instance, cmd);
3353 3353 } else {
3354 3354 mrsas_return_mfi_pkt(instance, cmd);
3355 3355 }
3356 3356
3357 3357 return (ret);
3358 3358 }
3359 3359
3360 3360 /*
3361 3361 * abort_aen_cmd
3362 3362 */
3363 3363 static int
3364 3364 abort_aen_cmd(struct mrsas_instance *instance,
3365 3365 struct mrsas_cmd *cmd_to_abort)
3366 3366 {
3367 3367 int ret = 0;
3368 3368
3369 3369 struct mrsas_cmd *cmd;
3370 3370 struct mrsas_abort_frame *abort_fr;
3371 3371
3372 3372 con_log(CL_ANN1, (CE_NOTE, "chkpnt: abort_aen:%d", __LINE__));
3373 3373
3374 3374 if (instance->tbolt) {
3375 3375 cmd = get_raid_msg_mfi_pkt(instance);
3376 3376 } else {
3377 3377 cmd = mrsas_get_mfi_pkt(instance);
3378 3378 }
3379 3379
3380 3380 if (!cmd) {
3381 3381 con_log(CL_ANN1, (CE_WARN,
3382 3382 "abort_aen_cmd():Failed to get a cmd for abort_aen_cmd"));
3383 3383 DTRACE_PROBE2(abort_mfi_err, uint16_t, instance->fw_outstanding,
3384 3384 uint16_t, instance->max_fw_cmds);
3385 3385 return (DDI_FAILURE);
3386 3386 }
3387 3387
3388 3388 /* Clear the frame buffer and assign back the context id */
3389 3389 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
3390 3390 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
3391 3391 cmd->index);
3392 3392
3393 3393 abort_fr = &cmd->frame->abort;
3394 3394
3395 3395 /* prepare and issue the abort frame */
3396 3396 ddi_put8(cmd->frame_dma_obj.acc_handle,
3397 3397 &abort_fr->cmd, MFI_CMD_OP_ABORT);
3398 3398 ddi_put8(cmd->frame_dma_obj.acc_handle, &abort_fr->cmd_status,
3399 3399 MFI_CMD_STATUS_SYNC_MODE);
3400 3400 ddi_put16(cmd->frame_dma_obj.acc_handle, &abort_fr->flags, 0);
3401 3401 ddi_put32(cmd->frame_dma_obj.acc_handle, &abort_fr->abort_context,
3402 3402 cmd_to_abort->index);
3403 3403 ddi_put32(cmd->frame_dma_obj.acc_handle,
3404 3404 &abort_fr->abort_mfi_phys_addr_lo, cmd_to_abort->frame_phys_addr);
3405 3405 ddi_put32(cmd->frame_dma_obj.acc_handle,
3406 3406 &abort_fr->abort_mfi_phys_addr_hi, 0);
3407 3407
3408 3408 instance->aen_cmd->abort_aen = 1;
3409 3409
3410 3410 cmd->frame_count = 1;
3411 3411
3412 3412 if (instance->tbolt) {
3413 3413 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
3414 3414 }
3415 3415
3416 3416 if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
3417 3417 con_log(CL_ANN1, (CE_WARN,
3418 3418 "abort_aen_cmd: issue_cmd_in_poll_mode failed"));
3419 3419 ret = -1;
3420 3420 } else {
3421 3421 ret = 0;
3422 3422 }
3423 3423
3424 3424 instance->aen_cmd->abort_aen = 1;
3425 3425 instance->aen_cmd = 0;
3426 3426
3427 3427 if (instance->tbolt) {
3428 3428 return_raid_msg_mfi_pkt(instance, cmd);
3429 3429 } else {
3430 3430 mrsas_return_mfi_pkt(instance, cmd);
3431 3431 }
3432 3432
3433 3433 atomic_add_16(&instance->fw_outstanding, (-1));
3434 3434
3435 3435 return (ret);
3436 3436 }
3437 3437
3438 3438
3439 3439 static int
3440 3440 mrsas_build_init_cmd(struct mrsas_instance *instance,
3441 3441 struct mrsas_cmd **cmd_ptr)
3442 3442 {
3443 3443 struct mrsas_cmd *cmd;
3444 3444 struct mrsas_init_frame *init_frame;
3445 3445 struct mrsas_init_queue_info *initq_info;
3446 3446 struct mrsas_drv_ver drv_ver_info;
3447 3447
3448 3448
3449 3449 /*
3450 3450 * Prepare a init frame. Note the init frame points to queue info
3451 3451 * structure. Each frame has SGL allocated after first 64 bytes. For
3452 3452 * this frame - since we don't need any SGL - we use SGL's space as
3453 3453 * queue info structure
3454 3454 */
3455 3455 cmd = *cmd_ptr;
3456 3456
3457 3457
3458 3458 /* Clear the frame buffer and assign back the context id */
3459 3459 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
3460 3460 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
3461 3461 cmd->index);
3462 3462
3463 3463 init_frame = (struct mrsas_init_frame *)cmd->frame;
3464 3464 initq_info = (struct mrsas_init_queue_info *)
3465 3465 ((unsigned long)init_frame + 64);
3466 3466
3467 3467 (void) memset(init_frame, 0, MRMFI_FRAME_SIZE);
3468 3468 (void) memset(initq_info, 0, sizeof (struct mrsas_init_queue_info));
3469 3469
3470 3470 ddi_put32(cmd->frame_dma_obj.acc_handle, &initq_info->init_flags, 0);
3471 3471
3472 3472 ddi_put32(cmd->frame_dma_obj.acc_handle,
3473 3473 &initq_info->reply_queue_entries, instance->max_fw_cmds + 1);
3474 3474
3475 3475 ddi_put32(cmd->frame_dma_obj.acc_handle,
3476 3476 &initq_info->producer_index_phys_addr_hi, 0);
3477 3477 ddi_put32(cmd->frame_dma_obj.acc_handle,
3478 3478 &initq_info->producer_index_phys_addr_lo,
3479 3479 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address);
3480 3480
3481 3481 ddi_put32(cmd->frame_dma_obj.acc_handle,
3482 3482 &initq_info->consumer_index_phys_addr_hi, 0);
3483 3483 ddi_put32(cmd->frame_dma_obj.acc_handle,
3484 3484 &initq_info->consumer_index_phys_addr_lo,
3485 3485 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 4);
3486 3486
3487 3487 ddi_put32(cmd->frame_dma_obj.acc_handle,
3488 3488 &initq_info->reply_queue_start_phys_addr_hi, 0);
3489 3489 ddi_put32(cmd->frame_dma_obj.acc_handle,
3490 3490 &initq_info->reply_queue_start_phys_addr_lo,
3491 3491 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 8);
3492 3492
3493 3493 ddi_put8(cmd->frame_dma_obj.acc_handle,
3494 3494 &init_frame->cmd, MFI_CMD_OP_INIT);
3495 3495 ddi_put8(cmd->frame_dma_obj.acc_handle, &init_frame->cmd_status,
3496 3496 MFI_CMD_STATUS_POLL_MODE);
3497 3497 ddi_put16(cmd->frame_dma_obj.acc_handle, &init_frame->flags, 0);
3498 3498 ddi_put32(cmd->frame_dma_obj.acc_handle,
3499 3499 &init_frame->queue_info_new_phys_addr_lo,
3500 3500 cmd->frame_phys_addr + 64);
3501 3501 ddi_put32(cmd->frame_dma_obj.acc_handle,
3502 3502 &init_frame->queue_info_new_phys_addr_hi, 0);
3503 3503
3504 3504
3505 3505 /* fill driver version information */
3506 3506 fill_up_drv_ver(&drv_ver_info);
3507 3507
3508 3508 /* allocate the driver version data transfer buffer */
3509 3509 instance->drv_ver_dma_obj.size = sizeof (drv_ver_info.drv_ver);
3510 3510 instance->drv_ver_dma_obj.dma_attr = mrsas_generic_dma_attr;
3511 3511 instance->drv_ver_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
3512 3512 instance->drv_ver_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
3513 3513 instance->drv_ver_dma_obj.dma_attr.dma_attr_sgllen = 1;
3514 3514 instance->drv_ver_dma_obj.dma_attr.dma_attr_align = 1;
3515 3515
3516 3516 if (mrsas_alloc_dma_obj(instance, &instance->drv_ver_dma_obj,
3517 3517 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
3518 3518 con_log(CL_ANN, (CE_WARN,
3519 3519 "init_mfi : Could not allocate driver version buffer."));
3520 3520 return (DDI_FAILURE);
3521 3521 }
3522 3522 /* copy driver version to dma buffer */
3523 3523 (void) memset(instance->drv_ver_dma_obj.buffer, 0,
3524 3524 sizeof (drv_ver_info.drv_ver));
3525 3525 ddi_rep_put8(cmd->frame_dma_obj.acc_handle,
3526 3526 (uint8_t *)drv_ver_info.drv_ver,
3527 3527 (uint8_t *)instance->drv_ver_dma_obj.buffer,
3528 3528 sizeof (drv_ver_info.drv_ver), DDI_DEV_AUTOINCR);
3529 3529
3530 3530
3531 3531 /* copy driver version physical address to init frame */
3532 3532 ddi_put64(cmd->frame_dma_obj.acc_handle, &init_frame->driverversion,
3533 3533 instance->drv_ver_dma_obj.dma_cookie[0].dmac_address);
3534 3534
3535 3535 ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->data_xfer_len,
3536 3536 sizeof (struct mrsas_init_queue_info));
3537 3537
3538 3538 cmd->frame_count = 1;
3539 3539
3540 3540 *cmd_ptr = cmd;
3541 3541
3542 3542 return (DDI_SUCCESS);
3543 3543 }
3544 3544
3545 3545
3546 3546 /*
3547 3547 * mrsas_init_adapter_ppc - Initialize MFI interface adapter.
3548 3548 */
3549 3549 int
3550 3550 mrsas_init_adapter_ppc(struct mrsas_instance *instance)
3551 3551 {
3552 3552 struct mrsas_cmd *cmd;
3553 3553
3554 3554 /*
3555 3555 * allocate memory for mfi adapter(cmd pool, individual commands, mfi
3556 3556 * frames etc
3557 3557 */
3558 3558 if (alloc_space_for_mfi(instance) != DDI_SUCCESS) {
3559 3559 con_log(CL_ANN, (CE_NOTE,
3560 3560 "Error, failed to allocate memory for MFI adapter"));
3561 3561 return (DDI_FAILURE);
3562 3562 }
3563 3563
3564 3564 /* Build INIT command */
3565 3565 cmd = mrsas_get_mfi_pkt(instance);
3566 3566 if (cmd == NULL) {
3567 3567 DTRACE_PROBE2(init_adapter_mfi_err, uint16_t,
3568 3568 instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
3569 3569 return (DDI_FAILURE);
3570 3570 }
3571 3571
3572 3572 if (mrsas_build_init_cmd(instance, &cmd) != DDI_SUCCESS) {
3573 3573 con_log(CL_ANN,
3574 3574 (CE_NOTE, "Error, failed to build INIT command"));
3575 3575
3576 3576 goto fail_undo_alloc_mfi_space;
3577 3577 }
3578 3578
3579 3579 /*
3580 3580 * Disable interrupt before sending init frame ( see linux driver code)
3581 3581 * send INIT MFI frame in polled mode
3582 3582 */
3583 3583 if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
3584 3584 con_log(CL_ANN, (CE_WARN, "failed to init firmware"));
3585 3585 goto fail_fw_init;
3586 3586 }
3587 3587
3588 3588 if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
3589 3589 goto fail_fw_init;
3590 3590 mrsas_return_mfi_pkt(instance, cmd);
3591 3591
3592 3592 if (ctio_enable &&
3593 3593 (instance->func_ptr->read_fw_status_reg(instance) & 0x04000000)) {
3594 3594 con_log(CL_ANN, (CE_NOTE, "mr_sas: IEEE SGL's supported"));
3595 3595 instance->flag_ieee = 1;
3596 3596 } else {
3597 3597 instance->flag_ieee = 0;
3598 3598 }
3599 3599
3600 3600 ASSERT(!instance->skinny || instance->flag_ieee);
3601 3601
3602 3602 instance->unroll.alloc_space_mfi = 1;
3603 3603 instance->unroll.verBuff = 1;
3604 3604
3605 3605 return (DDI_SUCCESS);
3606 3606
3607 3607
3608 3608 fail_fw_init:
3609 3609 (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
3610 3610
3611 3611 fail_undo_alloc_mfi_space:
3612 3612 mrsas_return_mfi_pkt(instance, cmd);
3613 3613 free_space_for_mfi(instance);
3614 3614
3615 3615 return (DDI_FAILURE);
3616 3616
3617 3617 }
3618 3618
3619 3619 /*
3620 3620 * mrsas_init_adapter - Initialize adapter.
3621 3621 */
3622 3622 int
3623 3623 mrsas_init_adapter(struct mrsas_instance *instance)
3624 3624 {
3625 3625 struct mrsas_ctrl_info ctrl_info;
3626 3626
3627 3627
3628 3628 /* we expect the FW state to be READY */
3629 3629 if (mfi_state_transition_to_ready(instance)) {
3630 3630 con_log(CL_ANN, (CE_WARN, "mr_sas: F/W is not ready"));
3631 3631 return (DDI_FAILURE);
3632 3632 }
3633 3633
3634 3634 /* get various operational parameters from status register */
3635 3635 instance->max_num_sge =
3636 3636 (instance->func_ptr->read_fw_status_reg(instance) &
3637 3637 0xFF0000) >> 0x10;
3638 3638 instance->max_num_sge =
3639 3639 (instance->max_num_sge > MRSAS_MAX_SGE_CNT) ?
3640 3640 MRSAS_MAX_SGE_CNT : instance->max_num_sge;
3641 3641
3642 3642 /*
3643 3643 * Reduce the max supported cmds by 1. This is to ensure that the
3644 3644 * reply_q_sz (1 more than the max cmd that driver may send)
3645 3645 * does not exceed max cmds that the FW can support
3646 3646 */
3647 3647 instance->max_fw_cmds =
3648 3648 instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF;
3649 3649 instance->max_fw_cmds = instance->max_fw_cmds - 1;
3650 3650
3651 3651
3652 3652
3653 3653 /* Initialize adapter */
3654 3654 if (instance->func_ptr->init_adapter(instance) != DDI_SUCCESS) {
3655 3655 con_log(CL_ANN,
3656 3656 (CE_WARN, "mr_sas: could not initialize adapter"));
3657 3657 return (DDI_FAILURE);
3658 3658 }
3659 3659
3660 3660 /* gather misc FW related information */
3661 3661 instance->disable_online_ctrl_reset = 0;
3662 3662
3663 3663 if (!get_ctrl_info(instance, &ctrl_info)) {
3664 3664 instance->max_sectors_per_req = ctrl_info.max_request_size;
3665 3665 con_log(CL_ANN1, (CE_NOTE,
3666 3666 "product name %s ld present %d",
3667 3667 ctrl_info.product_name, ctrl_info.ld_present_count));
3668 3668 } else {
3669 3669 instance->max_sectors_per_req = instance->max_num_sge *
3670 3670 PAGESIZE / 512;
3671 3671 }
3672 3672
3673 3673 if (ctrl_info.properties.on_off_properties & DISABLE_OCR_PROP_FLAG)
3674 3674 instance->disable_online_ctrl_reset = 1;
3675 3675
3676 3676 return (DDI_SUCCESS);
3677 3677
3678 3678 }
3679 3679
3680 3680
3681 3681
3682 3682 static int
3683 3683 mrsas_issue_init_mfi(struct mrsas_instance *instance)
3684 3684 {
3685 3685 struct mrsas_cmd *cmd;
3686 3686 struct mrsas_init_frame *init_frame;
3687 3687 struct mrsas_init_queue_info *initq_info;
3688 3688
3689 3689 /*
3690 3690 * Prepare a init frame. Note the init frame points to queue info
3691 3691 * structure. Each frame has SGL allocated after first 64 bytes. For
3692 3692 * this frame - since we don't need any SGL - we use SGL's space as
3693 3693 * queue info structure
3694 3694 */
3695 3695 con_log(CL_ANN1, (CE_NOTE,
3696 3696 "mrsas_issue_init_mfi: entry\n"));
3697 3697 cmd = get_mfi_app_pkt(instance);
3698 3698
3699 3699 if (!cmd) {
3700 3700 con_log(CL_ANN1, (CE_WARN,
3701 3701 "mrsas_issue_init_mfi: get_pkt failed\n"));
3702 3702 return (DDI_FAILURE);
3703 3703 }
3704 3704
3705 3705 /* Clear the frame buffer and assign back the context id */
3706 3706 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
3707 3707 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
3708 3708 cmd->index);
3709 3709
3710 3710 init_frame = (struct mrsas_init_frame *)cmd->frame;
3711 3711 initq_info = (struct mrsas_init_queue_info *)
3712 3712 ((unsigned long)init_frame + 64);
3713 3713
3714 3714 (void) memset(init_frame, 0, MRMFI_FRAME_SIZE);
3715 3715 (void) memset(initq_info, 0, sizeof (struct mrsas_init_queue_info));
3716 3716
3717 3717 ddi_put32(cmd->frame_dma_obj.acc_handle, &initq_info->init_flags, 0);
3718 3718
3719 3719 ddi_put32(cmd->frame_dma_obj.acc_handle,
3720 3720 &initq_info->reply_queue_entries, instance->max_fw_cmds + 1);
3721 3721 ddi_put32(cmd->frame_dma_obj.acc_handle,
3722 3722 &initq_info->producer_index_phys_addr_hi, 0);
3723 3723 ddi_put32(cmd->frame_dma_obj.acc_handle,
3724 3724 &initq_info->producer_index_phys_addr_lo,
3725 3725 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address);
3726 3726 ddi_put32(cmd->frame_dma_obj.acc_handle,
3727 3727 &initq_info->consumer_index_phys_addr_hi, 0);
3728 3728 ddi_put32(cmd->frame_dma_obj.acc_handle,
3729 3729 &initq_info->consumer_index_phys_addr_lo,
3730 3730 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 4);
3731 3731
3732 3732 ddi_put32(cmd->frame_dma_obj.acc_handle,
3733 3733 &initq_info->reply_queue_start_phys_addr_hi, 0);
3734 3734 ddi_put32(cmd->frame_dma_obj.acc_handle,
3735 3735 &initq_info->reply_queue_start_phys_addr_lo,
3736 3736 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 8);
3737 3737
3738 3738 ddi_put8(cmd->frame_dma_obj.acc_handle,
3739 3739 &init_frame->cmd, MFI_CMD_OP_INIT);
3740 3740 ddi_put8(cmd->frame_dma_obj.acc_handle, &init_frame->cmd_status,
3741 3741 MFI_CMD_STATUS_POLL_MODE);
3742 3742 ddi_put16(cmd->frame_dma_obj.acc_handle, &init_frame->flags, 0);
3743 3743 ddi_put32(cmd->frame_dma_obj.acc_handle,
3744 3744 &init_frame->queue_info_new_phys_addr_lo,
3745 3745 cmd->frame_phys_addr + 64);
3746 3746 ddi_put32(cmd->frame_dma_obj.acc_handle,
3747 3747 &init_frame->queue_info_new_phys_addr_hi, 0);
3748 3748
3749 3749 ddi_put32(cmd->frame_dma_obj.acc_handle, &init_frame->data_xfer_len,
3750 3750 sizeof (struct mrsas_init_queue_info));
3751 3751
3752 3752 cmd->frame_count = 1;
3753 3753
3754 3754 /* issue the init frame in polled mode */
3755 3755 if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
3756 3756 con_log(CL_ANN1, (CE_WARN,
3757 3757 "mrsas_issue_init_mfi():failed to "
3758 3758 "init firmware"));
3759 3759 return_mfi_app_pkt(instance, cmd);
3760 3760 return (DDI_FAILURE);
3761 3761 }
3762 3762
3763 3763 if (mrsas_common_check(instance, cmd) != DDI_SUCCESS) {
3764 3764 return_mfi_app_pkt(instance, cmd);
3765 3765 return (DDI_FAILURE);
3766 3766 }
3767 3767
3768 3768 return_mfi_app_pkt(instance, cmd);
3769 3769 con_log(CL_ANN1, (CE_CONT, "mrsas_issue_init_mfi: Done"));
3770 3770
3771 3771 return (DDI_SUCCESS);
3772 3772 }
3773 3773 /*
3774 3774 * mfi_state_transition_to_ready : Move the FW to READY state
3775 3775 *
3776 3776 * @reg_set : MFI register set
3777 3777 */
3778 3778 int
3779 3779 mfi_state_transition_to_ready(struct mrsas_instance *instance)
3780 3780 {
3781 3781 int i;
3782 3782 uint8_t max_wait;
3783 3783 uint32_t fw_ctrl = 0;
3784 3784 uint32_t fw_state;
3785 3785 uint32_t cur_state;
3786 3786 uint32_t cur_abs_reg_val;
3787 3787 uint32_t prev_abs_reg_val;
3788 3788 uint32_t status;
3789 3789
3790 3790 cur_abs_reg_val =
3791 3791 instance->func_ptr->read_fw_status_reg(instance);
3792 3792 fw_state =
3793 3793 cur_abs_reg_val & MFI_STATE_MASK;
3794 3794 con_log(CL_ANN1, (CE_CONT,
3795 3795 "mfi_state_transition_to_ready:FW state = 0x%x", fw_state));
3796 3796
3797 3797 while (fw_state != MFI_STATE_READY) {
3798 3798 con_log(CL_ANN, (CE_CONT,
3799 3799 "mfi_state_transition_to_ready:FW state%x", fw_state));
3800 3800
3801 3801 switch (fw_state) {
3802 3802 case MFI_STATE_FAULT:
3803 3803 con_log(CL_ANN, (CE_NOTE,
3804 3804 "mr_sas: FW in FAULT state!!"));
3805 3805
3806 3806 return (ENODEV);
3807 3807 case MFI_STATE_WAIT_HANDSHAKE:
3808 3808 /* set the CLR bit in IMR0 */
3809 3809 con_log(CL_ANN1, (CE_NOTE,
3810 3810 "mr_sas: FW waiting for HANDSHAKE"));
3811 3811 /*
3812 3812 * PCI_Hot Plug: MFI F/W requires
3813 3813 * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
3814 3814 * to be set
3815 3815 */
3816 3816 /* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */
3817 3817 if (!instance->tbolt && !instance->skinny) {
3818 3818 WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE |
3819 3819 MFI_INIT_HOTPLUG, instance);
3820 3820 } else {
3821 3821 WR_RESERVED0_REGISTER(MFI_INIT_CLEAR_HANDSHAKE |
3822 3822 MFI_INIT_HOTPLUG, instance);
3823 3823 }
3824 3824 max_wait = (instance->tbolt == 1) ? 180 : 2;
3825 3825 cur_state = MFI_STATE_WAIT_HANDSHAKE;
3826 3826 break;
3827 3827 case MFI_STATE_BOOT_MESSAGE_PENDING:
3828 3828 /* set the CLR bit in IMR0 */
3829 3829 con_log(CL_ANN1, (CE_NOTE,
3830 3830 "mr_sas: FW state boot message pending"));
3831 3831 /*
3832 3832 * PCI_Hot Plug: MFI F/W requires
3833 3833 * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG)
3834 3834 * to be set
3835 3835 */
3836 3836 if (!instance->tbolt && !instance->skinny) {
3837 3837 WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance);
3838 3838 } else {
3839 3839 WR_RESERVED0_REGISTER(MFI_INIT_HOTPLUG,
3840 3840 instance);
3841 3841 }
3842 3842 max_wait = (instance->tbolt == 1) ? 180 : 10;
3843 3843 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
3844 3844 break;
3845 3845 case MFI_STATE_OPERATIONAL:
3846 3846 /* bring it to READY state; assuming max wait 2 secs */
3847 3847 instance->func_ptr->disable_intr(instance);
3848 3848 con_log(CL_ANN1, (CE_NOTE,
3849 3849 "mr_sas: FW in OPERATIONAL state"));
3850 3850 /*
3851 3851 * PCI_Hot Plug: MFI F/W requires
3852 3852 * (MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT)
3853 3853 * to be set
3854 3854 */
3855 3855 /* WR_IB_DOORBELL(MFI_INIT_READY, instance); */
3856 3856 if (!instance->tbolt && !instance->skinny) {
3857 3857 WR_IB_DOORBELL(MFI_RESET_FLAGS, instance);
3858 3858 } else {
3859 3859 WR_RESERVED0_REGISTER(MFI_RESET_FLAGS,
3860 3860 instance);
3861 3861
3862 3862 for (i = 0; i < (10 * 1000); i++) {
3863 3863 status =
3864 3864 RD_RESERVED0_REGISTER(instance);
3865 3865 if (status & 1) {
3866 3866 delay(1 *
3867 3867 drv_usectohz(MILLISEC));
3868 3868 } else {
3869 3869 break;
3870 3870 }
3871 3871 }
3872 3872
3873 3873 }
3874 3874 max_wait = (instance->tbolt == 1) ? 180 : 10;
3875 3875 cur_state = MFI_STATE_OPERATIONAL;
3876 3876 break;
3877 3877 case MFI_STATE_UNDEFINED:
3878 3878 /* this state should not last for more than 2 seconds */
3879 3879 con_log(CL_ANN1, (CE_NOTE, "FW state undefined"));
3880 3880
3881 3881 max_wait = (instance->tbolt == 1) ? 180 : 2;
3882 3882 cur_state = MFI_STATE_UNDEFINED;
3883 3883 break;
3884 3884 case MFI_STATE_BB_INIT:
3885 3885 max_wait = (instance->tbolt == 1) ? 180 : 2;
3886 3886 cur_state = MFI_STATE_BB_INIT;
3887 3887 break;
3888 3888 case MFI_STATE_FW_INIT:
3889 3889 max_wait = (instance->tbolt == 1) ? 180 : 2;
3890 3890 cur_state = MFI_STATE_FW_INIT;
3891 3891 break;
3892 3892 case MFI_STATE_FW_INIT_2:
3893 3893 max_wait = 180;
3894 3894 cur_state = MFI_STATE_FW_INIT_2;
3895 3895 break;
3896 3896 case MFI_STATE_DEVICE_SCAN:
3897 3897 max_wait = 180;
3898 3898 cur_state = MFI_STATE_DEVICE_SCAN;
3899 3899 prev_abs_reg_val = cur_abs_reg_val;
3900 3900 con_log(CL_NONE, (CE_NOTE,
3901 3901 "Device scan in progress ...\n"));
3902 3902 break;
3903 3903 case MFI_STATE_FLUSH_CACHE:
3904 3904 max_wait = 180;
3905 3905 cur_state = MFI_STATE_FLUSH_CACHE;
3906 3906 break;
3907 3907 default:
3908 3908 con_log(CL_ANN1, (CE_NOTE,
3909 3909 "mr_sas: Unknown state 0x%x", fw_state));
3910 3910 return (ENODEV);
3911 3911 }
3912 3912
3913 3913 /* the cur_state should not last for more than max_wait secs */
3914 3914 for (i = 0; i < (max_wait * MILLISEC); i++) {
3915 3915 /* fw_state = RD_OB_MSG_0(instance) & MFI_STATE_MASK; */
3916 3916 cur_abs_reg_val =
3917 3917 instance->func_ptr->read_fw_status_reg(instance);
3918 3918 fw_state = cur_abs_reg_val & MFI_STATE_MASK;
3919 3919
3920 3920 if (fw_state == cur_state) {
3921 3921 delay(1 * drv_usectohz(MILLISEC));
3922 3922 } else {
3923 3923 break;
3924 3924 }
3925 3925 }
3926 3926 if (fw_state == MFI_STATE_DEVICE_SCAN) {
3927 3927 if (prev_abs_reg_val != cur_abs_reg_val) {
3928 3928 continue;
3929 3929 }
3930 3930 }
3931 3931
3932 3932 /* return error if fw_state hasn't changed after max_wait */
3933 3933 if (fw_state == cur_state) {
3934 3934 con_log(CL_ANN1, (CE_WARN,
3935 3935 "FW state hasn't changed in %d secs", max_wait));
3936 3936 return (ENODEV);
3937 3937 }
3938 3938 };
3939 3939
3940 3940 /* This may also need to apply to Skinny, but for now, don't worry. */
3941 3941 if (!instance->tbolt && !instance->skinny) {
3942 3942 fw_ctrl = RD_IB_DOORBELL(instance);
3943 3943 con_log(CL_ANN1, (CE_CONT,
3944 3944 "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl));
3945 3945
3946 3946 /*
3947 3947 * Write 0xF to the doorbell register to do the following.
3948 3948 * - Abort all outstanding commands (bit 0).
3949 3949 * - Transition from OPERATIONAL to READY state (bit 1).
3950 3950 * - Discard (possible) low MFA posted in 64-bit mode (bit-2).
3951 3951 * - Set to release FW to continue running (i.e. BIOS handshake
3952 3952 * (bit 3).
3953 3953 */
3954 3954 WR_IB_DOORBELL(0xF, instance);
3955 3955 }
3956 3956
3957 3957 if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
3958 3958 return (EIO);
3959 3959 }
3960 3960
3961 3961 return (DDI_SUCCESS);
3962 3962 }
3963 3963
3964 3964 /*
3965 3965 * get_seq_num
3966 3966 */
3967 3967 static int
3968 3968 get_seq_num(struct mrsas_instance *instance,
3969 3969 struct mrsas_evt_log_info *eli)
3970 3970 {
3971 3971 int ret = DDI_SUCCESS;
3972 3972
3973 3973 dma_obj_t dcmd_dma_obj;
3974 3974 struct mrsas_cmd *cmd;
3975 3975 struct mrsas_dcmd_frame *dcmd;
3976 3976 struct mrsas_evt_log_info *eli_tmp;
3977 3977 if (instance->tbolt) {
3978 3978 cmd = get_raid_msg_mfi_pkt(instance);
3979 3979 } else {
3980 3980 cmd = mrsas_get_mfi_pkt(instance);
3981 3981 }
3982 3982
3983 3983 if (!cmd) {
3984 3984 dev_err(instance->dip, CE_WARN, "failed to get a cmd");
3985 3985 DTRACE_PROBE2(seq_num_mfi_err, uint16_t,
3986 3986 instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
3987 3987 return (ENOMEM);
3988 3988 }
3989 3989
3990 3990 /* Clear the frame buffer and assign back the context id */
3991 3991 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
3992 3992 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
3993 3993 cmd->index);
3994 3994
3995 3995 dcmd = &cmd->frame->dcmd;
3996 3996
3997 3997 /* allocate the data transfer buffer */
3998 3998 dcmd_dma_obj.size = sizeof (struct mrsas_evt_log_info);
3999 3999 dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr;
4000 4000 dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
4001 4001 dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
4002 4002 dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
4003 4003 dcmd_dma_obj.dma_attr.dma_attr_align = 1;
4004 4004
4005 4005 if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj,
4006 4006 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
4007 4007 dev_err(instance->dip, CE_WARN,
4008 4008 "get_seq_num: could not allocate data transfer buffer.");
4009 4009 return (DDI_FAILURE);
4010 4010 }
4011 4011
4012 4012 (void) memset(dcmd_dma_obj.buffer, 0,
4013 4013 sizeof (struct mrsas_evt_log_info));
4014 4014
4015 4015 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
4016 4016
4017 4017 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
4018 4018 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status, 0);
4019 4019 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 1);
4020 4020 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
4021 4021 MFI_FRAME_DIR_READ);
4022 4022 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
4023 4023 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len,
4024 4024 sizeof (struct mrsas_evt_log_info));
4025 4025 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
4026 4026 MR_DCMD_CTRL_EVENT_GET_INFO);
4027 4027 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
4028 4028 sizeof (struct mrsas_evt_log_info));
4029 4029 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].phys_addr,
4030 4030 dcmd_dma_obj.dma_cookie[0].dmac_address);
4031 4031
4032 4032 cmd->sync_cmd = MRSAS_TRUE;
4033 4033 cmd->frame_count = 1;
4034 4034
4035 4035 if (instance->tbolt) {
4036 4036 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
4037 4037 }
4038 4038
4039 4039 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
4040 4040 dev_err(instance->dip, CE_WARN, "get_seq_num: "
4041 4041 "failed to issue MRSAS_DCMD_CTRL_EVENT_GET_INFO");
4042 4042 ret = DDI_FAILURE;
4043 4043 } else {
4044 4044 eli_tmp = (struct mrsas_evt_log_info *)dcmd_dma_obj.buffer;
4045 4045 eli->newest_seq_num = ddi_get32(cmd->frame_dma_obj.acc_handle,
4046 4046 &eli_tmp->newest_seq_num);
4047 4047 ret = DDI_SUCCESS;
4048 4048 }
4049 4049
4050 4050 if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
4051 4051 ret = DDI_FAILURE;
4052 4052
4053 4053 if (instance->tbolt) {
4054 4054 return_raid_msg_mfi_pkt(instance, cmd);
4055 4055 } else {
4056 4056 mrsas_return_mfi_pkt(instance, cmd);
4057 4057 }
4058 4058
4059 4059 return (ret);
4060 4060 }
4061 4061
4062 4062 /*
4063 4063 * start_mfi_aen
4064 4064 */
4065 4065 static int
4066 4066 start_mfi_aen(struct mrsas_instance *instance)
4067 4067 {
4068 4068 int ret = 0;
4069 4069
4070 4070 struct mrsas_evt_log_info eli;
4071 4071 union mrsas_evt_class_locale class_locale;
4072 4072
4073 4073 /* get the latest sequence number from FW */
4074 4074 (void) memset(&eli, 0, sizeof (struct mrsas_evt_log_info));
4075 4075
4076 4076 if (get_seq_num(instance, &eli)) {
4077 4077 dev_err(instance->dip, CE_WARN,
4078 4078 "start_mfi_aen: failed to get seq num");
4079 4079 return (-1);
4080 4080 }
4081 4081
4082 4082 /* register AEN with FW for latest sequence number plus 1 */
4083 4083 class_locale.members.reserved = 0;
4084 4084 class_locale.members.locale = LE_16(MR_EVT_LOCALE_ALL);
4085 4085 class_locale.members.class = MR_EVT_CLASS_INFO;
4086 4086 class_locale.word = LE_32(class_locale.word);
4087 4087 ret = register_mfi_aen(instance, eli.newest_seq_num + 1,
4088 4088 class_locale.word);
4089 4089
4090 4090 if (ret) {
4091 4091 dev_err(instance->dip, CE_WARN,
4092 4092 "start_mfi_aen: aen registration failed");
4093 4093 return (-1);
4094 4094 }
4095 4095
4096 4096
4097 4097 return (ret);
4098 4098 }
4099 4099
4100 4100 /*
4101 4101 * flush_cache
4102 4102 */
4103 4103 static void
4104 4104 flush_cache(struct mrsas_instance *instance)
4105 4105 {
4106 4106 struct mrsas_cmd *cmd = NULL;
4107 4107 struct mrsas_dcmd_frame *dcmd;
4108 4108 if (instance->tbolt) {
4109 4109 cmd = get_raid_msg_mfi_pkt(instance);
4110 4110 } else {
4111 4111 cmd = mrsas_get_mfi_pkt(instance);
4112 4112 }
4113 4113
4114 4114 if (!cmd) {
4115 4115 con_log(CL_ANN1, (CE_WARN,
4116 4116 "flush_cache():Failed to get a cmd for flush_cache"));
4117 4117 DTRACE_PROBE2(flush_cache_err, uint16_t,
4118 4118 instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
4119 4119 return;
4120 4120 }
4121 4121
4122 4122 /* Clear the frame buffer and assign back the context id */
4123 4123 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
4124 4124 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
4125 4125 cmd->index);
4126 4126
4127 4127 dcmd = &cmd->frame->dcmd;
4128 4128
4129 4129 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
4130 4130
4131 4131 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
4132 4132 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status, 0x0);
4133 4133 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 0);
4134 4134 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
4135 4135 MFI_FRAME_DIR_NONE);
4136 4136 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
4137 4137 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len, 0);
4138 4138 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
4139 4139 MR_DCMD_CTRL_CACHE_FLUSH);
4140 4140 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.b[0],
4141 4141 MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE);
4142 4142
4143 4143 cmd->frame_count = 1;
4144 4144
4145 4145 if (instance->tbolt) {
4146 4146 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
4147 4147 }
4148 4148
4149 4149 if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) {
4150 4150 con_log(CL_ANN1, (CE_WARN,
4151 4151 "flush_cache: failed to issue MFI_DCMD_CTRL_CACHE_FLUSH"));
4152 4152 }
4153 4153 con_log(CL_ANN1, (CE_CONT, "flush_cache done"));
4154 4154 if (instance->tbolt) {
4155 4155 return_raid_msg_mfi_pkt(instance, cmd);
4156 4156 } else {
4157 4157 mrsas_return_mfi_pkt(instance, cmd);
4158 4158 }
4159 4159
4160 4160 }
4161 4161
4162 4162 /*
4163 4163 * service_mfi_aen- Completes an AEN command
4164 4164 * @instance: Adapter soft state
4165 4165 * @cmd: Command to be completed
4166 4166 *
4167 4167 */
4168 4168 void
4169 4169 service_mfi_aen(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
4170 4170 {
4171 4171 uint32_t seq_num;
4172 4172 struct mrsas_evt_detail *evt_detail =
4173 4173 (struct mrsas_evt_detail *)instance->mfi_evt_detail_obj.buffer;
4174 4174 int rval = 0;
4175 4175 int tgt = 0;
4176 4176 uint8_t dtype;
4177 4177 #ifdef PDSUPPORT
4178 4178 mrsas_pd_address_t *pd_addr;
4179 4179 #endif
4180 4180 ddi_acc_handle_t acc_handle;
4181 4181
4182 4182 con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
4183 4183
4184 4184 acc_handle = cmd->frame_dma_obj.acc_handle;
4185 4185 cmd->cmd_status = ddi_get8(acc_handle, &cmd->frame->io.cmd_status);
4186 4186 if (cmd->cmd_status == ENODATA) {
4187 4187 cmd->cmd_status = 0;
4188 4188 }
4189 4189
4190 4190 /*
4191 4191 * log the MFI AEN event to the sysevent queue so that
4192 4192 * application will get noticed
4193 4193 */
4194 4194 if (ddi_log_sysevent(instance->dip, DDI_VENDOR_LSI, "LSIMEGA", "SAS",
4195 4195 NULL, NULL, DDI_NOSLEEP) != DDI_SUCCESS) {
4196 4196 int instance_no = ddi_get_instance(instance->dip);
4197 4197 con_log(CL_ANN, (CE_WARN,
4198 4198 "mr_sas%d: Failed to log AEN event", instance_no));
4199 4199 }
4200 4200 /*
4201 4201 * Check for any ld devices that has changed state. i.e. online
4202 4202 * or offline.
4203 4203 */
4204 4204 con_log(CL_ANN1, (CE_CONT,
4205 4205 "AEN: code = %x class = %x locale = %x args = %x",
4206 4206 ddi_get32(acc_handle, &evt_detail->code),
4207 4207 evt_detail->cl.members.class,
4208 4208 ddi_get16(acc_handle, &evt_detail->cl.members.locale),
4209 4209 ddi_get8(acc_handle, &evt_detail->arg_type)));
4210 4210
4211 4211 switch (ddi_get32(acc_handle, &evt_detail->code)) {
4212 4212 case MR_EVT_CFG_CLEARED: {
4213 4213 for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
4214 4214 if (instance->mr_ld_list[tgt].dip != NULL) {
4215 4215 mutex_enter(&instance->config_dev_mtx);
4216 4216 instance->mr_ld_list[tgt].flag =
4217 4217 (uint8_t)~MRDRV_TGT_VALID;
4218 4218 mutex_exit(&instance->config_dev_mtx);
4219 4219 rval = mrsas_service_evt(instance, tgt, 0,
4220 4220 MRSAS_EVT_UNCONFIG_TGT, NULL);
4221 4221 con_log(CL_ANN1, (CE_WARN,
4222 4222 "mr_sas: CFG CLEARED AEN rval = %d "
4223 4223 "tgt id = %d", rval, tgt));
4224 4224 }
4225 4225 }
4226 4226 break;
4227 4227 }
4228 4228
4229 4229 case MR_EVT_LD_DELETED: {
4230 4230 tgt = ddi_get16(acc_handle, &evt_detail->args.ld.target_id);
4231 4231 mutex_enter(&instance->config_dev_mtx);
4232 4232 instance->mr_ld_list[tgt].flag = (uint8_t)~MRDRV_TGT_VALID;
4233 4233 mutex_exit(&instance->config_dev_mtx);
4234 4234 rval = mrsas_service_evt(instance,
4235 4235 ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0,
4236 4236 MRSAS_EVT_UNCONFIG_TGT, NULL);
4237 4237 con_log(CL_ANN1, (CE_WARN, "mr_sas: LD DELETED AEN rval = %d "
4238 4238 "tgt id = %d index = %d", rval,
4239 4239 ddi_get16(acc_handle, &evt_detail->args.ld.target_id),
4240 4240 ddi_get8(acc_handle, &evt_detail->args.ld.ld_index)));
4241 4241 break;
4242 4242 } /* End of MR_EVT_LD_DELETED */
4243 4243
4244 4244 case MR_EVT_LD_CREATED: {
4245 4245 rval = mrsas_service_evt(instance,
4246 4246 ddi_get16(acc_handle, &evt_detail->args.ld.target_id), 0,
4247 4247 MRSAS_EVT_CONFIG_TGT, NULL);
4248 4248 con_log(CL_ANN1, (CE_WARN, "mr_sas: LD CREATED AEN rval = %d "
4249 4249 "tgt id = %d index = %d", rval,
4250 4250 ddi_get16(acc_handle, &evt_detail->args.ld.target_id),
4251 4251 ddi_get8(acc_handle, &evt_detail->args.ld.ld_index)));
4252 4252 break;
4253 4253 } /* End of MR_EVT_LD_CREATED */
4254 4254
4255 4255 #ifdef PDSUPPORT
4256 4256 case MR_EVT_PD_REMOVED_EXT: {
4257 4257 if (instance->tbolt || instance->skinny) {
4258 4258 pd_addr = &evt_detail->args.pd_addr;
4259 4259 dtype = pd_addr->scsi_dev_type;
4260 4260 con_log(CL_DLEVEL1, (CE_NOTE,
4261 4261 " MR_EVT_PD_REMOVED_EXT: dtype = %x,"
4262 4262 " arg_type = %d ", dtype, evt_detail->arg_type));
4263 4263 tgt = ddi_get16(acc_handle,
4264 4264 &evt_detail->args.pd.device_id);
4265 4265 mutex_enter(&instance->config_dev_mtx);
4266 4266 instance->mr_tbolt_pd_list[tgt].flag =
4267 4267 (uint8_t)~MRDRV_TGT_VALID;
4268 4268 mutex_exit(&instance->config_dev_mtx);
4269 4269 rval = mrsas_service_evt(instance, ddi_get16(
4270 4270 acc_handle, &evt_detail->args.pd.device_id),
4271 4271 1, MRSAS_EVT_UNCONFIG_TGT, NULL);
4272 4272 con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_REMOVED:"
4273 4273 "rval = %d tgt id = %d ", rval,
4274 4274 ddi_get16(acc_handle,
4275 4275 &evt_detail->args.pd.device_id)));
4276 4276 }
4277 4277 break;
4278 4278 } /* End of MR_EVT_PD_REMOVED_EXT */
4279 4279
4280 4280 case MR_EVT_PD_INSERTED_EXT: {
4281 4281 if (instance->tbolt || instance->skinny) {
4282 4282 rval = mrsas_service_evt(instance,
4283 4283 ddi_get16(acc_handle,
4284 4284 &evt_detail->args.pd.device_id),
4285 4285 1, MRSAS_EVT_CONFIG_TGT, NULL);
4286 4286 con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_INSERTEDi_EXT:"
4287 4287 "rval = %d tgt id = %d ", rval,
4288 4288 ddi_get16(acc_handle,
4289 4289 &evt_detail->args.pd.device_id)));
4290 4290 }
4291 4291 break;
4292 4292 } /* End of MR_EVT_PD_INSERTED_EXT */
4293 4293
4294 4294 case MR_EVT_PD_STATE_CHANGE: {
4295 4295 if (instance->tbolt || instance->skinny) {
4296 4296 tgt = ddi_get16(acc_handle,
4297 4297 &evt_detail->args.pd.device_id);
4298 4298 if ((evt_detail->args.pd_state.prevState ==
4299 4299 PD_SYSTEM) &&
4300 4300 (evt_detail->args.pd_state.newState != PD_SYSTEM)) {
4301 4301 mutex_enter(&instance->config_dev_mtx);
4302 4302 instance->mr_tbolt_pd_list[tgt].flag =
4303 4303 (uint8_t)~MRDRV_TGT_VALID;
4304 4304 mutex_exit(&instance->config_dev_mtx);
4305 4305 rval = mrsas_service_evt(instance,
4306 4306 ddi_get16(acc_handle,
4307 4307 &evt_detail->args.pd.device_id),
4308 4308 1, MRSAS_EVT_UNCONFIG_TGT, NULL);
4309 4309 con_log(CL_ANN1, (CE_WARN, "mr_sas: PD_REMOVED:"
4310 4310 "rval = %d tgt id = %d ", rval,
4311 4311 ddi_get16(acc_handle,
4312 4312 &evt_detail->args.pd.device_id)));
4313 4313 break;
4314 4314 }
4315 4315 if ((evt_detail->args.pd_state.prevState
4316 4316 == UNCONFIGURED_GOOD) &&
4317 4317 (evt_detail->args.pd_state.newState == PD_SYSTEM)) {
4318 4318 rval = mrsas_service_evt(instance,
4319 4319 ddi_get16(acc_handle,
4320 4320 &evt_detail->args.pd.device_id),
4321 4321 1, MRSAS_EVT_CONFIG_TGT, NULL);
4322 4322 con_log(CL_ANN1, (CE_WARN,
4323 4323 "mr_sas: PD_INSERTED: rval = %d "
4324 4324 " tgt id = %d ", rval,
4325 4325 ddi_get16(acc_handle,
4326 4326 &evt_detail->args.pd.device_id)));
4327 4327 break;
4328 4328 }
4329 4329 }
4330 4330 break;
4331 4331 }
4332 4332 #endif
4333 4333
4334 4334 } /* End of Main Switch */
4335 4335
4336 4336 /* get copy of seq_num and class/locale for re-registration */
4337 4337 seq_num = ddi_get32(acc_handle, &evt_detail->seq_num);
4338 4338 seq_num++;
4339 4339 (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
4340 4340 sizeof (struct mrsas_evt_detail));
4341 4341
4342 4342 ddi_put8(acc_handle, &cmd->frame->dcmd.cmd_status, 0x0);
4343 4343 ddi_put32(acc_handle, &cmd->frame->dcmd.mbox.w[0], seq_num);
4344 4344
4345 4345 instance->aen_seq_num = seq_num;
4346 4346
4347 4347 cmd->frame_count = 1;
4348 4348
4349 4349 cmd->retry_count_for_ocr = 0;
4350 4350 cmd->drv_pkt_time = 0;
4351 4351
4352 4352 /* Issue the aen registration frame */
4353 4353 instance->func_ptr->issue_cmd(cmd, instance);
4354 4354 }
4355 4355
4356 4356 /*
4357 4357 * complete_cmd_in_sync_mode - Completes an internal command
4358 4358 * @instance: Adapter soft state
4359 4359 * @cmd: Command to be completed
4360 4360 *
4361 4361 * The issue_cmd_in_sync_mode() function waits for a command to complete
4362 4362 * after it issues a command. This function wakes up that waiting routine by
4363 4363 * calling wake_up() on the wait queue.
4364 4364 */
4365 4365 static void
4366 4366 complete_cmd_in_sync_mode(struct mrsas_instance *instance,
4367 4367 struct mrsas_cmd *cmd)
4368 4368 {
4369 4369 cmd->cmd_status = ddi_get8(cmd->frame_dma_obj.acc_handle,
4370 4370 &cmd->frame->io.cmd_status);
4371 4371
4372 4372 cmd->sync_cmd = MRSAS_FALSE;
4373 4373
4374 4374 con_log(CL_ANN1, (CE_NOTE, "complete_cmd_in_sync_mode called %p \n",
4375 4375 (void *)cmd));
4376 4376
4377 4377 mutex_enter(&instance->int_cmd_mtx);
4378 4378 if (cmd->cmd_status == ENODATA) {
4379 4379 cmd->cmd_status = 0;
4380 4380 }
4381 4381 cv_broadcast(&instance->int_cmd_cv);
4382 4382 mutex_exit(&instance->int_cmd_mtx);
4383 4383
4384 4384 }
4385 4385
4386 4386 /*
4387 4387 * Call this function inside mrsas_softintr.
4388 4388 * mrsas_initiate_ocr_if_fw_is_faulty - Initiates OCR if FW status is faulty
4389 4389 * @instance: Adapter soft state
4390 4390 */
4391 4391
4392 4392 static uint32_t
4393 4393 mrsas_initiate_ocr_if_fw_is_faulty(struct mrsas_instance *instance)
4394 4394 {
4395 4395 uint32_t cur_abs_reg_val;
4396 4396 uint32_t fw_state;
4397 4397
4398 4398 cur_abs_reg_val = instance->func_ptr->read_fw_status_reg(instance);
4399 4399 fw_state = cur_abs_reg_val & MFI_STATE_MASK;
4400 4400 if (fw_state == MFI_STATE_FAULT) {
4401 4401 if (instance->disable_online_ctrl_reset == 1) {
4402 4402 dev_err(instance->dip, CE_WARN,
4403 4403 "mrsas_initiate_ocr_if_fw_is_faulty: "
4404 4404 "FW in Fault state, detected in ISR: "
4405 4405 "FW doesn't support ocr ");
4406 4406
4407 4407 return (ADAPTER_RESET_NOT_REQUIRED);
4408 4408 } else {
4409 4409 con_log(CL_ANN, (CE_NOTE,
4410 4410 "mrsas_initiate_ocr_if_fw_is_faulty: FW in Fault "
4411 4411 "state, detected in ISR: FW supports ocr "));
4412 4412
4413 4413 return (ADAPTER_RESET_REQUIRED);
4414 4414 }
4415 4415 }
4416 4416
4417 4417 return (ADAPTER_RESET_NOT_REQUIRED);
4418 4418 }
4419 4419
4420 4420 /*
4421 4421 * mrsas_softintr - The Software ISR
4422 4422 * @param arg : HBA soft state
4423 4423 *
4424 4424 * called from high-level interrupt if hi-level interrupt are not there,
4425 4425 * otherwise triggered as a soft interrupt
4426 4426 */
4427 4427 static uint_t
4428 4428 mrsas_softintr(struct mrsas_instance *instance)
4429 4429 {
4430 4430 struct scsi_pkt *pkt;
4431 4431 struct scsa_cmd *acmd;
4432 4432 struct mrsas_cmd *cmd;
4433 4433 struct mlist_head *pos, *next;
4434 4434 mlist_t process_list;
4435 4435 struct mrsas_header *hdr;
4436 4436 struct scsi_arq_status *arqstat;
4437 4437
4438 4438 con_log(CL_ANN1, (CE_NOTE, "mrsas_softintr() called."));
4439 4439
4440 4440 ASSERT(instance);
4441 4441
4442 4442 mutex_enter(&instance->completed_pool_mtx);
4443 4443
4444 4444 if (mlist_empty(&instance->completed_pool_list)) {
4445 4445 mutex_exit(&instance->completed_pool_mtx);
4446 4446 return (DDI_INTR_CLAIMED);
4447 4447 }
4448 4448
4449 4449 instance->softint_running = 1;
4450 4450
4451 4451 INIT_LIST_HEAD(&process_list);
4452 4452 mlist_splice(&instance->completed_pool_list, &process_list);
4453 4453 INIT_LIST_HEAD(&instance->completed_pool_list);
4454 4454
4455 4455 mutex_exit(&instance->completed_pool_mtx);
4456 4456
4457 4457 /* perform all callbacks first, before releasing the SCBs */
4458 4458 mlist_for_each_safe(pos, next, &process_list) {
4459 4459 cmd = mlist_entry(pos, struct mrsas_cmd, list);
4460 4460
4461 4461 /* syncronize the Cmd frame for the controller */
4462 4462 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle,
4463 4463 0, 0, DDI_DMA_SYNC_FORCPU);
4464 4464
4465 4465 if (mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
4466 4466 DDI_SUCCESS) {
4467 4467 mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
4468 4468 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
4469 4469 con_log(CL_ANN1, (CE_WARN,
4470 4470 "mrsas_softintr: "
4471 4471 "FMA check reports DMA handle failure"));
4472 4472 return (DDI_INTR_CLAIMED);
4473 4473 }
4474 4474
4475 4475 hdr = &cmd->frame->hdr;
4476 4476
4477 4477 /* remove the internal command from the process list */
4478 4478 mlist_del_init(&cmd->list);
4479 4479
4480 4480 switch (ddi_get8(cmd->frame_dma_obj.acc_handle, &hdr->cmd)) {
4481 4481 case MFI_CMD_OP_PD_SCSI:
4482 4482 case MFI_CMD_OP_LD_SCSI:
4483 4483 case MFI_CMD_OP_LD_READ:
4484 4484 case MFI_CMD_OP_LD_WRITE:
4485 4485 /*
4486 4486 * MFI_CMD_OP_PD_SCSI and MFI_CMD_OP_LD_SCSI
4487 4487 * could have been issued either through an
4488 4488 * IO path or an IOCTL path. If it was via IOCTL,
4489 4489 * we will send it to internal completion.
4490 4490 */
4491 4491 if (cmd->sync_cmd == MRSAS_TRUE) {
4492 4492 complete_cmd_in_sync_mode(instance, cmd);
4493 4493 break;
4494 4494 }
4495 4495
4496 4496 /* regular commands */
4497 4497 acmd = cmd->cmd;
4498 4498 pkt = CMD2PKT(acmd);
4499 4499
4500 4500 if (acmd->cmd_flags & CFLAG_DMAVALID) {
4501 4501 if (acmd->cmd_flags & CFLAG_CONSISTENT) {
4502 4502 (void) ddi_dma_sync(acmd->cmd_dmahandle,
4503 4503 acmd->cmd_dma_offset,
4504 4504 acmd->cmd_dma_len,
4505 4505 DDI_DMA_SYNC_FORCPU);
4506 4506 }
4507 4507 }
4508 4508
4509 4509 pkt->pkt_reason = CMD_CMPLT;
4510 4510 pkt->pkt_statistics = 0;
4511 4511 pkt->pkt_state = STATE_GOT_BUS
4512 4512 | STATE_GOT_TARGET | STATE_SENT_CMD
4513 4513 | STATE_XFERRED_DATA | STATE_GOT_STATUS;
4514 4514
4515 4515 con_log(CL_ANN, (CE_CONT,
4516 4516 "CDB[0] = %x completed for %s: size %lx context %x",
4517 4517 pkt->pkt_cdbp[0], ((acmd->islogical) ? "LD" : "PD"),
4518 4518 acmd->cmd_dmacount, hdr->context));
4519 4519 DTRACE_PROBE3(softintr_cdb, uint8_t, pkt->pkt_cdbp[0],
4520 4520 uint_t, acmd->cmd_cdblen, ulong_t,
4521 4521 acmd->cmd_dmacount);
4522 4522
4523 4523 if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) {
4524 4524 struct scsi_inquiry *inq;
4525 4525
4526 4526 if (acmd->cmd_dmacount != 0) {
4527 4527 bp_mapin(acmd->cmd_buf);
4528 4528 inq = (struct scsi_inquiry *)
4529 4529 acmd->cmd_buf->b_un.b_addr;
4530 4530
4531 4531 #ifdef PDSUPPORT
4532 4532 if (hdr->cmd_status == MFI_STAT_OK) {
4533 4533 display_scsi_inquiry(
4534 4534 (caddr_t)inq);
4535 4535 }
4536 4536 #else
4537 4537 /* don't expose physical drives to OS */
4538 4538 if (acmd->islogical &&
4539 4539 (hdr->cmd_status == MFI_STAT_OK)) {
4540 4540 display_scsi_inquiry(
4541 4541 (caddr_t)inq);
4542 4542 } else if ((hdr->cmd_status ==
4543 4543 MFI_STAT_OK) && inq->inq_dtype ==
4544 4544 DTYPE_DIRECT) {
4545 4545
4546 4546 display_scsi_inquiry(
4547 4547 (caddr_t)inq);
4548 4548
4549 4549 /* for physical disk */
4550 4550 hdr->cmd_status =
4551 4551 MFI_STAT_DEVICE_NOT_FOUND;
4552 4552 }
4553 4553 #endif /* PDSUPPORT */
4554 4554 }
4555 4555 }
4556 4556
4557 4557 DTRACE_PROBE2(softintr_done, uint8_t, hdr->cmd,
4558 4558 uint8_t, hdr->cmd_status);
4559 4559
4560 4560 switch (hdr->cmd_status) {
4561 4561 case MFI_STAT_OK:
4562 4562 pkt->pkt_scbp[0] = STATUS_GOOD;
4563 4563 break;
4564 4564 case MFI_STAT_LD_CC_IN_PROGRESS:
4565 4565 case MFI_STAT_LD_RECON_IN_PROGRESS:
4566 4566 pkt->pkt_scbp[0] = STATUS_GOOD;
4567 4567 break;
4568 4568 case MFI_STAT_LD_INIT_IN_PROGRESS:
4569 4569 con_log(CL_ANN,
4570 4570 (CE_WARN, "Initialization in Progress"));
4571 4571 pkt->pkt_reason = CMD_TRAN_ERR;
4572 4572
4573 4573 break;
4574 4574 case MFI_STAT_SCSI_DONE_WITH_ERROR:
4575 4575 con_log(CL_ANN, (CE_CONT, "scsi_done error"));
4576 4576
4577 4577 pkt->pkt_reason = CMD_CMPLT;
4578 4578 ((struct scsi_status *)
4579 4579 pkt->pkt_scbp)->sts_chk = 1;
4580 4580
4581 4581 if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) {
4582 4582 con_log(CL_ANN,
4583 4583 (CE_WARN, "TEST_UNIT_READY fail"));
4584 4584 } else {
4585 4585 pkt->pkt_state |= STATE_ARQ_DONE;
4586 4586 arqstat = (void *)(pkt->pkt_scbp);
4587 4587 arqstat->sts_rqpkt_reason = CMD_CMPLT;
4588 4588 arqstat->sts_rqpkt_resid = 0;
4589 4589 arqstat->sts_rqpkt_state |=
4590 4590 STATE_GOT_BUS | STATE_GOT_TARGET
4591 4591 | STATE_SENT_CMD
4592 4592 | STATE_XFERRED_DATA;
4593 4593 *(uint8_t *)&arqstat->sts_rqpkt_status =
4594 4594 STATUS_GOOD;
4595 4595 ddi_rep_get8(
4596 4596 cmd->frame_dma_obj.acc_handle,
4597 4597 (uint8_t *)
4598 4598 &(arqstat->sts_sensedata),
4599 4599 cmd->sense,
4600 4600 sizeof (struct scsi_extended_sense),
4601 4601 DDI_DEV_AUTOINCR);
4602 4602 }
4603 4603 break;
4604 4604 case MFI_STAT_LD_OFFLINE:
4605 4605 case MFI_STAT_DEVICE_NOT_FOUND:
4606 4606 con_log(CL_ANN, (CE_CONT,
4607 4607 "mrsas_softintr:device not found error"));
4608 4608 pkt->pkt_reason = CMD_DEV_GONE;
4609 4609 pkt->pkt_statistics = STAT_DISCON;
4610 4610 break;
4611 4611 case MFI_STAT_LD_LBA_OUT_OF_RANGE:
4612 4612 pkt->pkt_state |= STATE_ARQ_DONE;
4613 4613 pkt->pkt_reason = CMD_CMPLT;
4614 4614 ((struct scsi_status *)
4615 4615 pkt->pkt_scbp)->sts_chk = 1;
4616 4616
4617 4617 arqstat = (void *)(pkt->pkt_scbp);
4618 4618 arqstat->sts_rqpkt_reason = CMD_CMPLT;
4619 4619 arqstat->sts_rqpkt_resid = 0;
4620 4620 arqstat->sts_rqpkt_state |= STATE_GOT_BUS
4621 4621 | STATE_GOT_TARGET | STATE_SENT_CMD
4622 4622 | STATE_XFERRED_DATA;
4623 4623 *(uint8_t *)&arqstat->sts_rqpkt_status =
4624 4624 STATUS_GOOD;
4625 4625
4626 4626 arqstat->sts_sensedata.es_valid = 1;
4627 4627 arqstat->sts_sensedata.es_key =
4628 4628 KEY_ILLEGAL_REQUEST;
4629 4629 arqstat->sts_sensedata.es_class =
4630 4630 CLASS_EXTENDED_SENSE;
4631 4631
4632 4632 /*
4633 4633 * LOGICAL BLOCK ADDRESS OUT OF RANGE:
4634 4634 * ASC: 0x21h; ASCQ: 0x00h;
4635 4635 */
4636 4636 arqstat->sts_sensedata.es_add_code = 0x21;
4637 4637 arqstat->sts_sensedata.es_qual_code = 0x00;
4638 4638
4639 4639 break;
4640 4640
4641 4641 default:
4642 4642 con_log(CL_ANN, (CE_CONT, "Unknown status!"));
4643 4643 pkt->pkt_reason = CMD_TRAN_ERR;
4644 4644
4645 4645 break;
4646 4646 }
4647 4647
4648 4648 atomic_add_16(&instance->fw_outstanding, (-1));
4649 4649
4650 4650 (void) mrsas_common_check(instance, cmd);
4651 4651
4652 4652 if (acmd->cmd_dmahandle) {
4653 4653 if (mrsas_check_dma_handle(
4654 4654 acmd->cmd_dmahandle) != DDI_SUCCESS) {
4655 4655 ddi_fm_service_impact(instance->dip,
4656 4656 DDI_SERVICE_UNAFFECTED);
4657 4657 pkt->pkt_reason = CMD_TRAN_ERR;
4658 4658 pkt->pkt_statistics = 0;
4659 4659 }
4660 4660 }
4661 4661
4662 4662 mrsas_return_mfi_pkt(instance, cmd);
4663 4663
4664 4664 /* Call the callback routine */
4665 4665 if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
4666 4666 pkt->pkt_comp) {
4667 4667 (*pkt->pkt_comp)(pkt);
4668 4668 }
4669 4669
4670 4670 break;
4671 4671
4672 4672 case MFI_CMD_OP_SMP:
4673 4673 case MFI_CMD_OP_STP:
4674 4674 complete_cmd_in_sync_mode(instance, cmd);
4675 4675 break;
4676 4676
4677 4677 case MFI_CMD_OP_DCMD:
4678 4678 /* see if got an event notification */
4679 4679 if (ddi_get32(cmd->frame_dma_obj.acc_handle,
4680 4680 &cmd->frame->dcmd.opcode) ==
4681 4681 MR_DCMD_CTRL_EVENT_WAIT) {
4682 4682 if ((instance->aen_cmd == cmd) &&
4683 4683 (instance->aen_cmd->abort_aen)) {
4684 4684 con_log(CL_ANN, (CE_WARN,
4685 4685 "mrsas_softintr: "
4686 4686 "aborted_aen returned"));
4687 4687 } else {
4688 4688 atomic_add_16(&instance->fw_outstanding,
4689 4689 (-1));
4690 4690 service_mfi_aen(instance, cmd);
4691 4691 }
4692 4692 } else {
4693 4693 complete_cmd_in_sync_mode(instance, cmd);
4694 4694 }
4695 4695
4696 4696 break;
4697 4697
4698 4698 case MFI_CMD_OP_ABORT:
4699 4699 con_log(CL_ANN, (CE_NOTE, "MFI_CMD_OP_ABORT complete"));
4700 4700 /*
4701 4701 * MFI_CMD_OP_ABORT successfully completed
4702 4702 * in the synchronous mode
4703 4703 */
4704 4704 complete_cmd_in_sync_mode(instance, cmd);
4705 4705 break;
4706 4706
4707 4707 default:
4708 4708 mrsas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE);
4709 4709 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
4710 4710
4711 4711 if (cmd->pkt != NULL) {
4712 4712 pkt = cmd->pkt;
4713 4713 if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
4714 4714 pkt->pkt_comp) {
4715 4715
4716 4716 con_log(CL_ANN1, (CE_CONT, "posting to "
4717 4717 "scsa cmd %p index %x pkt %p"
4718 4718 "time %llx, default ", (void *)cmd,
4719 4719 cmd->index, (void *)pkt,
4720 4720 gethrtime()));
4721 4721
4722 4722 (*pkt->pkt_comp)(pkt);
4723 4723
4724 4724 }
4725 4725 }
4726 4726 con_log(CL_ANN, (CE_WARN, "Cmd type unknown !"));
4727 4727 break;
4728 4728 }
4729 4729 }
4730 4730
4731 4731 instance->softint_running = 0;
4732 4732
4733 4733 return (DDI_INTR_CLAIMED);
4734 4734 }
4735 4735
4736 4736 /*
4737 4737 * mrsas_alloc_dma_obj
4738 4738 *
4739 4739 * Allocate the memory and other resources for an dma object.
4740 4740 */
4741 4741 int
4742 4742 mrsas_alloc_dma_obj(struct mrsas_instance *instance, dma_obj_t *obj,
4743 4743 uchar_t endian_flags)
4744 4744 {
4745 4745 int i;
4746 4746 size_t alen = 0;
4747 4747 uint_t cookie_cnt;
4748 4748 struct ddi_device_acc_attr tmp_endian_attr;
4749 4749
4750 4750 tmp_endian_attr = endian_attr;
4751 4751 tmp_endian_attr.devacc_attr_endian_flags = endian_flags;
4752 4752 tmp_endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
4753 4753
4754 4754 i = ddi_dma_alloc_handle(instance->dip, &obj->dma_attr,
4755 4755 DDI_DMA_SLEEP, NULL, &obj->dma_handle);
4756 4756 if (i != DDI_SUCCESS) {
4757 4757
4758 4758 switch (i) {
4759 4759 case DDI_DMA_BADATTR :
4760 4760 con_log(CL_ANN, (CE_WARN,
4761 4761 "Failed ddi_dma_alloc_handle- Bad attribute"));
4762 4762 break;
4763 4763 case DDI_DMA_NORESOURCES :
4764 4764 con_log(CL_ANN, (CE_WARN,
4765 4765 "Failed ddi_dma_alloc_handle- No Resources"));
4766 4766 break;
4767 4767 default :
4768 4768 con_log(CL_ANN, (CE_WARN,
4769 4769 "Failed ddi_dma_alloc_handle: "
4770 4770 "unknown status %d", i));
4771 4771 break;
4772 4772 }
4773 4773
4774 4774 return (-1);
4775 4775 }
4776 4776
4777 4777 if ((ddi_dma_mem_alloc(obj->dma_handle, obj->size, &tmp_endian_attr,
4778 4778 DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL,
4779 4779 &obj->buffer, &alen, &obj->acc_handle) != DDI_SUCCESS) ||
4780 4780 alen < obj->size) {
4781 4781
4782 4782 ddi_dma_free_handle(&obj->dma_handle);
4783 4783
4784 4784 con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc"));
4785 4785
4786 4786 return (-1);
4787 4787 }
4788 4788
4789 4789 if (ddi_dma_addr_bind_handle(obj->dma_handle, NULL, obj->buffer,
4790 4790 obj->size, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP,
4791 4791 NULL, &obj->dma_cookie[0], &cookie_cnt) != DDI_SUCCESS) {
4792 4792
4793 4793 ddi_dma_mem_free(&obj->acc_handle);
4794 4794 ddi_dma_free_handle(&obj->dma_handle);
4795 4795
4796 4796 con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle"));
4797 4797
4798 4798 return (-1);
4799 4799 }
4800 4800
4801 4801 if (mrsas_check_dma_handle(obj->dma_handle) != DDI_SUCCESS) {
4802 4802 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
4803 4803 return (-1);
4804 4804 }
4805 4805
4806 4806 if (mrsas_check_acc_handle(obj->acc_handle) != DDI_SUCCESS) {
4807 4807 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
4808 4808 return (-1);
4809 4809 }
4810 4810
4811 4811 return (cookie_cnt);
4812 4812 }
4813 4813
4814 4814 /*
4815 4815 * mrsas_free_dma_obj(struct mrsas_instance *, dma_obj_t)
4816 4816 *
4817 4817 * De-allocate the memory and other resources for an dma object, which must
4818 4818 * have been alloated by a previous call to mrsas_alloc_dma_obj()
4819 4819 */
4820 4820 int
4821 4821 mrsas_free_dma_obj(struct mrsas_instance *instance, dma_obj_t obj)
4822 4822 {
4823 4823
4824 4824 if ((obj.dma_handle == NULL) || (obj.acc_handle == NULL)) {
4825 4825 return (DDI_SUCCESS);
4826 4826 }
4827 4827
4828 4828 /*
4829 4829 * NOTE: These check-handle functions fail if *_handle == NULL, but
4830 4830 * this function succeeds because of the previous check.
4831 4831 */
4832 4832 if (mrsas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) {
4833 4833 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
4834 4834 return (DDI_FAILURE);
4835 4835 }
4836 4836
4837 4837 if (mrsas_check_acc_handle(obj.acc_handle) != DDI_SUCCESS) {
4838 4838 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
4839 4839 return (DDI_FAILURE);
4840 4840 }
4841 4841
4842 4842 (void) ddi_dma_unbind_handle(obj.dma_handle);
4843 4843 ddi_dma_mem_free(&obj.acc_handle);
4844 4844 ddi_dma_free_handle(&obj.dma_handle);
4845 4845 obj.acc_handle = NULL;
4846 4846 return (DDI_SUCCESS);
4847 4847 }
4848 4848
4849 4849 /*
4850 4850 * mrsas_dma_alloc(instance_t *, struct scsi_pkt *, struct buf *,
4851 4851 * int, int (*)())
4852 4852 *
4853 4853 * Allocate dma resources for a new scsi command
4854 4854 */
4855 4855 int
4856 4856 mrsas_dma_alloc(struct mrsas_instance *instance, struct scsi_pkt *pkt,
4857 4857 struct buf *bp, int flags, int (*callback)())
4858 4858 {
4859 4859 int dma_flags;
4860 4860 int (*cb)(caddr_t);
4861 4861 int i;
4862 4862
4863 4863 ddi_dma_attr_t tmp_dma_attr = mrsas_generic_dma_attr;
4864 4864 struct scsa_cmd *acmd = PKT2CMD(pkt);
4865 4865
4866 4866 acmd->cmd_buf = bp;
4867 4867
4868 4868 if (bp->b_flags & B_READ) {
4869 4869 acmd->cmd_flags &= ~CFLAG_DMASEND;
4870 4870 dma_flags = DDI_DMA_READ;
4871 4871 } else {
4872 4872 acmd->cmd_flags |= CFLAG_DMASEND;
4873 4873 dma_flags = DDI_DMA_WRITE;
4874 4874 }
4875 4875
4876 4876 if (flags & PKT_CONSISTENT) {
4877 4877 acmd->cmd_flags |= CFLAG_CONSISTENT;
4878 4878 dma_flags |= DDI_DMA_CONSISTENT;
4879 4879 }
4880 4880
4881 4881 if (flags & PKT_DMA_PARTIAL) {
4882 4882 dma_flags |= DDI_DMA_PARTIAL;
4883 4883 }
4884 4884
4885 4885 dma_flags |= DDI_DMA_REDZONE;
4886 4886
4887 4887 cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
4888 4888
4889 4889 tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge;
4890 4890 tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull;
4891 4891 if (instance->tbolt) {
4892 4892 /* OCR-RESET FIX */
4893 4893 tmp_dma_attr.dma_attr_count_max =
4894 4894 (U64)mrsas_tbolt_max_cap_maxxfer; /* limit to 256K */
4895 4895 tmp_dma_attr.dma_attr_maxxfer =
4896 4896 (U64)mrsas_tbolt_max_cap_maxxfer; /* limit to 256K */
4897 4897 }
4898 4898
4899 4899 if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr,
4900 4900 cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) {
4901 4901 switch (i) {
4902 4902 case DDI_DMA_BADATTR:
4903 4903 bioerror(bp, EFAULT);
4904 4904 return (DDI_FAILURE);
4905 4905
4906 4906 case DDI_DMA_NORESOURCES:
4907 4907 bioerror(bp, 0);
4908 4908 return (DDI_FAILURE);
4909 4909
4910 4910 default:
4911 4911 con_log(CL_ANN, (CE_PANIC, "ddi_dma_alloc_handle: "
4912 4912 "impossible result (0x%x)", i));
4913 4913 bioerror(bp, EFAULT);
4914 4914 return (DDI_FAILURE);
4915 4915 }
4916 4916 }
4917 4917
4918 4918 i = ddi_dma_buf_bind_handle(acmd->cmd_dmahandle, bp, dma_flags,
4919 4919 cb, 0, &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies);
4920 4920
4921 4921 switch (i) {
4922 4922 case DDI_DMA_PARTIAL_MAP:
4923 4923 if ((dma_flags & DDI_DMA_PARTIAL) == 0) {
4924 4924 con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
4925 4925 "DDI_DMA_PARTIAL_MAP impossible"));
4926 4926 goto no_dma_cookies;
4927 4927 }
4928 4928
4929 4929 if (ddi_dma_numwin(acmd->cmd_dmahandle, &acmd->cmd_nwin) ==
4930 4930 DDI_FAILURE) {
4931 4931 con_log(CL_ANN, (CE_PANIC, "ddi_dma_numwin failed"));
4932 4932 goto no_dma_cookies;
4933 4933 }
4934 4934
4935 4935 if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
4936 4936 &acmd->cmd_dma_offset, &acmd->cmd_dma_len,
4937 4937 &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) ==
4938 4938 DDI_FAILURE) {
4939 4939
4940 4940 con_log(CL_ANN, (CE_PANIC, "ddi_dma_getwin failed"));
4941 4941 goto no_dma_cookies;
4942 4942 }
4943 4943
4944 4944 goto get_dma_cookies;
4945 4945 case DDI_DMA_MAPPED:
4946 4946 acmd->cmd_nwin = 1;
4947 4947 acmd->cmd_dma_len = 0;
4948 4948 acmd->cmd_dma_offset = 0;
4949 4949
4950 4950 get_dma_cookies:
4951 4951 i = 0;
4952 4952 acmd->cmd_dmacount = 0;
4953 4953 for (;;) {
4954 4954 acmd->cmd_dmacount +=
4955 4955 acmd->cmd_dmacookies[i++].dmac_size;
4956 4956
4957 4957 if (i == instance->max_num_sge ||
4958 4958 i == acmd->cmd_ncookies)
4959 4959 break;
4960 4960
4961 4961 ddi_dma_nextcookie(acmd->cmd_dmahandle,
4962 4962 &acmd->cmd_dmacookies[i]);
4963 4963 }
4964 4964
4965 4965 acmd->cmd_cookie = i;
4966 4966 acmd->cmd_cookiecnt = i;
4967 4967
4968 4968 acmd->cmd_flags |= CFLAG_DMAVALID;
4969 4969
4970 4970 if (bp->b_bcount >= acmd->cmd_dmacount) {
4971 4971 pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount;
4972 4972 } else {
4973 4973 pkt->pkt_resid = 0;
4974 4974 }
4975 4975
4976 4976 return (DDI_SUCCESS);
4977 4977 case DDI_DMA_NORESOURCES:
4978 4978 bioerror(bp, 0);
4979 4979 break;
4980 4980 case DDI_DMA_NOMAPPING:
4981 4981 bioerror(bp, EFAULT);
4982 4982 break;
4983 4983 case DDI_DMA_TOOBIG:
4984 4984 bioerror(bp, EINVAL);
4985 4985 break;
4986 4986 case DDI_DMA_INUSE:
4987 4987 con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle:"
4988 4988 " DDI_DMA_INUSE impossible"));
4989 4989 break;
4990 4990 default:
4991 4991 con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: "
4992 4992 "impossible result (0x%x)", i));
4993 4993 break;
4994 4994 }
4995 4995
4996 4996 no_dma_cookies:
4997 4997 ddi_dma_free_handle(&acmd->cmd_dmahandle);
4998 4998 acmd->cmd_dmahandle = NULL;
4999 4999 acmd->cmd_flags &= ~CFLAG_DMAVALID;
5000 5000 return (DDI_FAILURE);
5001 5001 }
5002 5002
5003 5003 /*
5004 5004 * mrsas_dma_move(struct mrsas_instance *, struct scsi_pkt *, struct buf *)
5005 5005 *
5006 5006 * move dma resources to next dma window
5007 5007 *
5008 5008 */
5009 5009 int
5010 5010 mrsas_dma_move(struct mrsas_instance *instance, struct scsi_pkt *pkt,
5011 5011 struct buf *bp)
5012 5012 {
5013 5013 int i = 0;
5014 5014
5015 5015 struct scsa_cmd *acmd = PKT2CMD(pkt);
5016 5016
5017 5017 /*
5018 5018 * If there are no more cookies remaining in this window,
5019 5019 * must move to the next window first.
5020 5020 */
5021 5021 if (acmd->cmd_cookie == acmd->cmd_ncookies) {
5022 5022 if (acmd->cmd_curwin == acmd->cmd_nwin && acmd->cmd_nwin == 1) {
5023 5023 return (DDI_SUCCESS);
5024 5024 }
5025 5025
5026 5026 /* at last window, cannot move */
5027 5027 if (++acmd->cmd_curwin >= acmd->cmd_nwin) {
5028 5028 return (DDI_FAILURE);
5029 5029 }
5030 5030
5031 5031 if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin,
5032 5032 &acmd->cmd_dma_offset, &acmd->cmd_dma_len,
5033 5033 &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) ==
5034 5034 DDI_FAILURE) {
5035 5035 return (DDI_FAILURE);
5036 5036 }
5037 5037
5038 5038 acmd->cmd_cookie = 0;
5039 5039 } else {
5040 5040 /* still more cookies in this window - get the next one */
5041 5041 ddi_dma_nextcookie(acmd->cmd_dmahandle,
5042 5042 &acmd->cmd_dmacookies[0]);
5043 5043 }
5044 5044
5045 5045 /* get remaining cookies in this window, up to our maximum */
5046 5046 for (;;) {
5047 5047 acmd->cmd_dmacount += acmd->cmd_dmacookies[i++].dmac_size;
5048 5048 acmd->cmd_cookie++;
5049 5049
5050 5050 if (i == instance->max_num_sge ||
5051 5051 acmd->cmd_cookie == acmd->cmd_ncookies) {
5052 5052 break;
5053 5053 }
5054 5054
5055 5055 ddi_dma_nextcookie(acmd->cmd_dmahandle,
5056 5056 &acmd->cmd_dmacookies[i]);
5057 5057 }
5058 5058
5059 5059 acmd->cmd_cookiecnt = i;
5060 5060
5061 5061 if (bp->b_bcount >= acmd->cmd_dmacount) {
5062 5062 pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount;
5063 5063 } else {
5064 5064 pkt->pkt_resid = 0;
5065 5065 }
5066 5066
5067 5067 return (DDI_SUCCESS);
5068 5068 }
5069 5069
5070 5070 /*
5071 5071 * build_cmd
5072 5072 */
5073 5073 static struct mrsas_cmd *
5074 5074 build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
5075 5075 struct scsi_pkt *pkt, uchar_t *cmd_done)
5076 5076 {
5077 5077 uint16_t flags = 0;
5078 5078 uint32_t i;
5079 5079 uint32_t context;
5080 5080 uint32_t sge_bytes;
5081 5081 uint32_t tmp_data_xfer_len;
5082 5082 ddi_acc_handle_t acc_handle;
5083 5083 struct mrsas_cmd *cmd;
5084 5084 struct mrsas_sge64 *mfi_sgl;
5085 5085 struct mrsas_sge_ieee *mfi_sgl_ieee;
5086 5086 struct scsa_cmd *acmd = PKT2CMD(pkt);
5087 5087 struct mrsas_pthru_frame *pthru;
5088 5088 struct mrsas_io_frame *ldio;
5089 5089
5090 5090 /* find out if this is logical or physical drive command. */
5091 5091 acmd->islogical = MRDRV_IS_LOGICAL(ap);
5092 5092 acmd->device_id = MAP_DEVICE_ID(instance, ap);
5093 5093 *cmd_done = 0;
5094 5094
5095 5095 /* get the command packet */
5096 5096 if (!(cmd = mrsas_get_mfi_pkt(instance))) {
5097 5097 DTRACE_PROBE2(build_cmd_mfi_err, uint16_t,
5098 5098 instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
5099 5099 return (NULL);
5100 5100 }
5101 5101
5102 5102 acc_handle = cmd->frame_dma_obj.acc_handle;
5103 5103
5104 5104 /* Clear the frame buffer and assign back the context id */
5105 5105 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
5106 5106 ddi_put32(acc_handle, &cmd->frame->hdr.context, cmd->index);
5107 5107
5108 5108 cmd->pkt = pkt;
5109 5109 cmd->cmd = acmd;
5110 5110 DTRACE_PROBE3(build_cmds, uint8_t, pkt->pkt_cdbp[0],
5111 5111 ulong_t, acmd->cmd_dmacount, ulong_t, acmd->cmd_dma_len);
5112 5112
5113 5113 /* lets get the command directions */
5114 5114 if (acmd->cmd_flags & CFLAG_DMASEND) {
5115 5115 flags = MFI_FRAME_DIR_WRITE;
5116 5116
5117 5117 if (acmd->cmd_flags & CFLAG_CONSISTENT) {
5118 5118 (void) ddi_dma_sync(acmd->cmd_dmahandle,
5119 5119 acmd->cmd_dma_offset, acmd->cmd_dma_len,
5120 5120 DDI_DMA_SYNC_FORDEV);
5121 5121 }
5122 5122 } else if (acmd->cmd_flags & ~CFLAG_DMASEND) {
5123 5123 flags = MFI_FRAME_DIR_READ;
5124 5124
5125 5125 if (acmd->cmd_flags & CFLAG_CONSISTENT) {
5126 5126 (void) ddi_dma_sync(acmd->cmd_dmahandle,
5127 5127 acmd->cmd_dma_offset, acmd->cmd_dma_len,
5128 5128 DDI_DMA_SYNC_FORCPU);
5129 5129 }
5130 5130 } else {
5131 5131 flags = MFI_FRAME_DIR_NONE;
5132 5132 }
5133 5133
5134 5134 if (instance->flag_ieee) {
5135 5135 flags |= MFI_FRAME_IEEE;
5136 5136 }
5137 5137 flags |= MFI_FRAME_SGL64;
5138 5138
5139 5139 switch (pkt->pkt_cdbp[0]) {
5140 5140
5141 5141 /*
5142 5142 * case SCMD_SYNCHRONIZE_CACHE:
5143 5143 * flush_cache(instance);
5144 5144 * mrsas_return_mfi_pkt(instance, cmd);
5145 5145 * *cmd_done = 1;
5146 5146 *
5147 5147 * return (NULL);
5148 5148 */
5149 5149
5150 5150 case SCMD_READ:
5151 5151 case SCMD_WRITE:
5152 5152 case SCMD_READ_G1:
5153 5153 case SCMD_WRITE_G1:
5154 5154 case SCMD_READ_G4:
5155 5155 case SCMD_WRITE_G4:
5156 5156 case SCMD_READ_G5:
5157 5157 case SCMD_WRITE_G5:
5158 5158 if (acmd->islogical) {
5159 5159 ldio = (struct mrsas_io_frame *)cmd->frame;
5160 5160
5161 5161 /*
5162 5162 * preare the Logical IO frame:
5163 5163 * 2nd bit is zero for all read cmds
5164 5164 */
5165 5165 ddi_put8(acc_handle, &ldio->cmd,
5166 5166 (pkt->pkt_cdbp[0] & 0x02) ? MFI_CMD_OP_LD_WRITE
5167 5167 : MFI_CMD_OP_LD_READ);
5168 5168 ddi_put8(acc_handle, &ldio->cmd_status, 0x0);
5169 5169 ddi_put8(acc_handle, &ldio->scsi_status, 0x0);
5170 5170 ddi_put8(acc_handle, &ldio->target_id, acmd->device_id);
5171 5171 ddi_put16(acc_handle, &ldio->timeout, 0);
5172 5172 ddi_put8(acc_handle, &ldio->reserved_0, 0);
5173 5173 ddi_put16(acc_handle, &ldio->pad_0, 0);
5174 5174 ddi_put16(acc_handle, &ldio->flags, flags);
5175 5175
5176 5176 /* Initialize sense Information */
5177 5177 bzero(cmd->sense, SENSE_LENGTH);
5178 5178 ddi_put8(acc_handle, &ldio->sense_len, SENSE_LENGTH);
5179 5179 ddi_put32(acc_handle, &ldio->sense_buf_phys_addr_hi, 0);
5180 5180 ddi_put32(acc_handle, &ldio->sense_buf_phys_addr_lo,
5181 5181 cmd->sense_phys_addr);
5182 5182 ddi_put32(acc_handle, &ldio->start_lba_hi, 0);
5183 5183 ddi_put8(acc_handle, &ldio->access_byte,
5184 5184 (acmd->cmd_cdblen != 6) ? pkt->pkt_cdbp[1] : 0);
5185 5185 ddi_put8(acc_handle, &ldio->sge_count,
5186 5186 acmd->cmd_cookiecnt);
5187 5187 if (instance->flag_ieee) {
5188 5188 mfi_sgl_ieee =
5189 5189 (struct mrsas_sge_ieee *)&ldio->sgl;
5190 5190 } else {
5191 5191 mfi_sgl = (struct mrsas_sge64 *)&ldio->sgl;
5192 5192 }
5193 5193
5194 5194 context = ddi_get32(acc_handle, &ldio->context);
5195 5195
5196 5196 if (acmd->cmd_cdblen == CDB_GROUP0) {
5197 5197 /* 6-byte cdb */
5198 5198 ddi_put32(acc_handle, &ldio->lba_count, (
5199 5199 (uint16_t)(pkt->pkt_cdbp[4])));
5200 5200
5201 5201 ddi_put32(acc_handle, &ldio->start_lba_lo, (
5202 5202 ((uint32_t)(pkt->pkt_cdbp[3])) |
5203 5203 ((uint32_t)(pkt->pkt_cdbp[2]) << 8) |
5204 5204 ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F)
5205 5205 << 16)));
5206 5206 } else if (acmd->cmd_cdblen == CDB_GROUP1) {
5207 5207 /* 10-byte cdb */
5208 5208 ddi_put32(acc_handle, &ldio->lba_count, (
5209 5209 ((uint16_t)(pkt->pkt_cdbp[8])) |
5210 5210 ((uint16_t)(pkt->pkt_cdbp[7]) << 8)));
5211 5211
5212 5212 ddi_put32(acc_handle, &ldio->start_lba_lo, (
5213 5213 ((uint32_t)(pkt->pkt_cdbp[5])) |
5214 5214 ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
5215 5215 ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
5216 5216 ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
5217 5217 } else if (acmd->cmd_cdblen == CDB_GROUP5) {
5218 5218 /* 12-byte cdb */
5219 5219 ddi_put32(acc_handle, &ldio->lba_count, (
5220 5220 ((uint32_t)(pkt->pkt_cdbp[9])) |
5221 5221 ((uint32_t)(pkt->pkt_cdbp[8]) << 8) |
5222 5222 ((uint32_t)(pkt->pkt_cdbp[7]) << 16) |
5223 5223 ((uint32_t)(pkt->pkt_cdbp[6]) << 24)));
5224 5224
5225 5225 ddi_put32(acc_handle, &ldio->start_lba_lo, (
5226 5226 ((uint32_t)(pkt->pkt_cdbp[5])) |
5227 5227 ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
5228 5228 ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
5229 5229 ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
5230 5230 } else if (acmd->cmd_cdblen == CDB_GROUP4) {
5231 5231 /* 16-byte cdb */
5232 5232 ddi_put32(acc_handle, &ldio->lba_count, (
5233 5233 ((uint32_t)(pkt->pkt_cdbp[13])) |
5234 5234 ((uint32_t)(pkt->pkt_cdbp[12]) << 8) |
5235 5235 ((uint32_t)(pkt->pkt_cdbp[11]) << 16) |
5236 5236 ((uint32_t)(pkt->pkt_cdbp[10]) << 24)));
5237 5237
5238 5238 ddi_put32(acc_handle, &ldio->start_lba_lo, (
5239 5239 ((uint32_t)(pkt->pkt_cdbp[9])) |
5240 5240 ((uint32_t)(pkt->pkt_cdbp[8]) << 8) |
5241 5241 ((uint32_t)(pkt->pkt_cdbp[7]) << 16) |
5242 5242 ((uint32_t)(pkt->pkt_cdbp[6]) << 24)));
5243 5243
5244 5244 ddi_put32(acc_handle, &ldio->start_lba_hi, (
5245 5245 ((uint32_t)(pkt->pkt_cdbp[5])) |
5246 5246 ((uint32_t)(pkt->pkt_cdbp[4]) << 8) |
5247 5247 ((uint32_t)(pkt->pkt_cdbp[3]) << 16) |
5248 5248 ((uint32_t)(pkt->pkt_cdbp[2]) << 24)));
5249 5249 }
5250 5250
5251 5251 break;
5252 5252 }
5253 5253 /* fall through For all non-rd/wr and physical disk cmds */
5254 5254 default:
5255 5255
5256 5256 switch (pkt->pkt_cdbp[0]) {
5257 5257 case SCMD_MODE_SENSE:
5258 5258 case SCMD_MODE_SENSE_G1: {
5259 5259 union scsi_cdb *cdbp;
5260 5260 uint16_t page_code;
5261 5261
5262 5262 cdbp = (void *)pkt->pkt_cdbp;
5263 5263 page_code = (uint16_t)cdbp->cdb_un.sg.scsi[0];
5264 5264 switch (page_code) {
5265 5265 case 0x3:
5266 5266 case 0x4:
5267 5267 (void) mrsas_mode_sense_build(pkt);
5268 5268 mrsas_return_mfi_pkt(instance, cmd);
5269 5269 *cmd_done = 1;
5270 5270 return (NULL);
5271 5271 }
5272 5272 break;
5273 5273 }
5274 5274 default:
5275 5275 break;
5276 5276 }
5277 5277
5278 5278 pthru = (struct mrsas_pthru_frame *)cmd->frame;
5279 5279
5280 5280 /* prepare the DCDB frame */
5281 5281 ddi_put8(acc_handle, &pthru->cmd, (acmd->islogical) ?
5282 5282 MFI_CMD_OP_LD_SCSI : MFI_CMD_OP_PD_SCSI);
5283 5283 ddi_put8(acc_handle, &pthru->cmd_status, 0x0);
5284 5284 ddi_put8(acc_handle, &pthru->scsi_status, 0x0);
5285 5285 ddi_put8(acc_handle, &pthru->target_id, acmd->device_id);
5286 5286 ddi_put8(acc_handle, &pthru->lun, 0);
5287 5287 ddi_put8(acc_handle, &pthru->cdb_len, acmd->cmd_cdblen);
5288 5288 ddi_put16(acc_handle, &pthru->timeout, 0);
5289 5289 ddi_put16(acc_handle, &pthru->flags, flags);
5290 5290 tmp_data_xfer_len = 0;
5291 5291 for (i = 0; i < acmd->cmd_cookiecnt; i++) {
5292 5292 tmp_data_xfer_len += acmd->cmd_dmacookies[i].dmac_size;
5293 5293 }
5294 5294 ddi_put32(acc_handle, &pthru->data_xfer_len,
5295 5295 tmp_data_xfer_len);
5296 5296 ddi_put8(acc_handle, &pthru->sge_count, acmd->cmd_cookiecnt);
5297 5297 if (instance->flag_ieee) {
5298 5298 mfi_sgl_ieee = (struct mrsas_sge_ieee *)&pthru->sgl;
5299 5299 } else {
5300 5300 mfi_sgl = (struct mrsas_sge64 *)&pthru->sgl;
5301 5301 }
5302 5302
5303 5303 bzero(cmd->sense, SENSE_LENGTH);
5304 5304 ddi_put8(acc_handle, &pthru->sense_len, SENSE_LENGTH);
5305 5305 ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0);
5306 5306 ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo,
5307 5307 cmd->sense_phys_addr);
5308 5308
5309 5309 context = ddi_get32(acc_handle, &pthru->context);
5310 5310 ddi_rep_put8(acc_handle, (uint8_t *)pkt->pkt_cdbp,
5311 5311 (uint8_t *)pthru->cdb, acmd->cmd_cdblen, DDI_DEV_AUTOINCR);
5312 5312
5313 5313 break;
5314 5314 }
5315 5315 #ifdef lint
5316 5316 context = context;
5317 5317 #endif
5318 5318 /* prepare the scatter-gather list for the firmware */
5319 5319 if (instance->flag_ieee) {
5320 5320 for (i = 0; i < acmd->cmd_cookiecnt; i++, mfi_sgl_ieee++) {
5321 5321 ddi_put64(acc_handle, &mfi_sgl_ieee->phys_addr,
5322 5322 acmd->cmd_dmacookies[i].dmac_laddress);
5323 5323 ddi_put32(acc_handle, &mfi_sgl_ieee->length,
5324 5324 acmd->cmd_dmacookies[i].dmac_size);
5325 5325 }
5326 5326 sge_bytes = sizeof (struct mrsas_sge_ieee)*acmd->cmd_cookiecnt;
5327 5327 } else {
5328 5328 for (i = 0; i < acmd->cmd_cookiecnt; i++, mfi_sgl++) {
5329 5329 ddi_put64(acc_handle, &mfi_sgl->phys_addr,
5330 5330 acmd->cmd_dmacookies[i].dmac_laddress);
5331 5331 ddi_put32(acc_handle, &mfi_sgl->length,
5332 5332 acmd->cmd_dmacookies[i].dmac_size);
5333 5333 }
5334 5334 sge_bytes = sizeof (struct mrsas_sge64)*acmd->cmd_cookiecnt;
5335 5335 }
5336 5336
5337 5337 cmd->frame_count = (sge_bytes / MRMFI_FRAME_SIZE) +
5338 5338 ((sge_bytes % MRMFI_FRAME_SIZE) ? 1 : 0) + 1;
5339 5339
5340 5340 if (cmd->frame_count >= 8) {
5341 5341 cmd->frame_count = 8;
5342 5342 }
5343 5343
5344 5344 return (cmd);
5345 5345 }
5346 5346
5347 5347 /*
5348 5348 * wait_for_outstanding - Wait for all outstanding cmds
5349 5349 * @instance: Adapter soft state
5350 5350 *
5351 5351 * This function waits for upto MRDRV_RESET_WAIT_TIME seconds for FW to
5352 5352 * complete all its outstanding commands. Returns error if one or more IOs
5353 5353 * are pending after this time period.
5354 5354 */
5355 5355 static int
5356 5356 wait_for_outstanding(struct mrsas_instance *instance)
5357 5357 {
5358 5358 int i;
5359 5359 uint32_t wait_time = 90;
5360 5360
5361 5361 for (i = 0; i < wait_time; i++) {
5362 5362 if (!instance->fw_outstanding) {
5363 5363 break;
5364 5364 }
5365 5365
5366 5366 drv_usecwait(MILLISEC); /* wait for 1000 usecs */;
5367 5367 }
5368 5368
5369 5369 if (instance->fw_outstanding) {
5370 5370 return (1);
5371 5371 }
5372 5372
5373 5373 return (0);
5374 5374 }
5375 5375
5376 5376 /*
5377 5377 * issue_mfi_pthru
5378 5378 */
5379 5379 static int
5380 5380 issue_mfi_pthru(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
5381 5381 struct mrsas_cmd *cmd, int mode)
5382 5382 {
5383 5383 void *ubuf;
5384 5384 uint32_t kphys_addr = 0;
5385 5385 uint32_t xferlen = 0;
5386 5386 uint32_t new_xfer_length = 0;
5387 5387 uint_t model;
5388 5388 ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
5389 5389 dma_obj_t pthru_dma_obj;
5390 5390 struct mrsas_pthru_frame *kpthru;
5391 5391 struct mrsas_pthru_frame *pthru;
5392 5392 int i;
5393 5393 pthru = &cmd->frame->pthru;
5394 5394 kpthru = (struct mrsas_pthru_frame *)&ioctl->frame[0];
5395 5395
5396 5396 if (instance->adapterresetinprogress) {
5397 5397 con_log(CL_ANN1, (CE_WARN, "issue_mfi_pthru: Reset flag set, "
5398 5398 "returning mfi_pkt and setting TRAN_BUSY\n"));
5399 5399 return (DDI_FAILURE);
5400 5400 }
5401 5401 model = ddi_model_convert_from(mode & FMODELS);
5402 5402 if (model == DDI_MODEL_ILP32) {
5403 5403 con_log(CL_ANN1, (CE_CONT, "issue_mfi_pthru: DDI_MODEL_LP32"));
5404 5404
5405 5405 xferlen = kpthru->sgl.sge32[0].length;
5406 5406
5407 5407 ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
5408 5408 } else {
5409 5409 #ifdef _ILP32
5410 5410 con_log(CL_ANN1, (CE_CONT, "issue_mfi_pthru: DDI_MODEL_LP32"));
5411 5411 xferlen = kpthru->sgl.sge32[0].length;
5412 5412 ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr;
5413 5413 #else
5414 5414 con_log(CL_ANN1, (CE_CONT, "issue_mfi_pthru: DDI_MODEL_LP64"));
5415 5415 xferlen = kpthru->sgl.sge64[0].length;
5416 5416 ubuf = (void *)(ulong_t)kpthru->sgl.sge64[0].phys_addr;
5417 5417 #endif
5418 5418 }
5419 5419
5420 5420 if (xferlen) {
5421 5421 /* means IOCTL requires DMA */
5422 5422 /* allocate the data transfer buffer */
5423 5423 /* pthru_dma_obj.size = xferlen; */
5424 5424 MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen, new_xfer_length,
5425 5425 PAGESIZE);
5426 5426 pthru_dma_obj.size = new_xfer_length;
5427 5427 pthru_dma_obj.dma_attr = mrsas_generic_dma_attr;
5428 5428 pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
5429 5429 pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
5430 5430 pthru_dma_obj.dma_attr.dma_attr_sgllen = 1;
5431 5431 pthru_dma_obj.dma_attr.dma_attr_align = 1;
5432 5432
5433 5433 /* allocate kernel buffer for DMA */
5434 5434 if (mrsas_alloc_dma_obj(instance, &pthru_dma_obj,
5435 5435 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
5436 5436 con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: "
5437 5437 "could not allocate data transfer buffer."));
5438 5438 return (DDI_FAILURE);
5439 5439 }
5440 5440 (void) memset(pthru_dma_obj.buffer, 0, xferlen);
5441 5441
5442 5442 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
5443 5443 if (kpthru->flags & MFI_FRAME_DIR_WRITE) {
5444 5444 for (i = 0; i < xferlen; i++) {
5445 5445 if (ddi_copyin((uint8_t *)ubuf+i,
5446 5446 (uint8_t *)pthru_dma_obj.buffer+i,
5447 5447 1, mode)) {
5448 5448 con_log(CL_ANN, (CE_WARN,
5449 5449 "issue_mfi_pthru : "
5450 5450 "copy from user space failed"));
5451 5451 return (DDI_FAILURE);
5452 5452 }
5453 5453 }
5454 5454 }
5455 5455
5456 5456 kphys_addr = pthru_dma_obj.dma_cookie[0].dmac_address;
5457 5457 }
5458 5458
5459 5459 ddi_put8(acc_handle, &pthru->cmd, kpthru->cmd);
5460 5460 ddi_put8(acc_handle, &pthru->sense_len, SENSE_LENGTH);
5461 5461 ddi_put8(acc_handle, &pthru->cmd_status, 0);
5462 5462 ddi_put8(acc_handle, &pthru->scsi_status, 0);
5463 5463 ddi_put8(acc_handle, &pthru->target_id, kpthru->target_id);
5464 5464 ddi_put8(acc_handle, &pthru->lun, kpthru->lun);
5465 5465 ddi_put8(acc_handle, &pthru->cdb_len, kpthru->cdb_len);
5466 5466 ddi_put8(acc_handle, &pthru->sge_count, kpthru->sge_count);
5467 5467 ddi_put16(acc_handle, &pthru->timeout, kpthru->timeout);
5468 5468 ddi_put32(acc_handle, &pthru->data_xfer_len, kpthru->data_xfer_len);
5469 5469
5470 5470 ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_hi, 0);
5471 5471 pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
5472 5472 /* ddi_put32(acc_handle, &pthru->sense_buf_phys_addr_lo, 0); */
5473 5473
5474 5474 ddi_rep_put8(acc_handle, (uint8_t *)kpthru->cdb, (uint8_t *)pthru->cdb,
5475 5475 pthru->cdb_len, DDI_DEV_AUTOINCR);
5476 5476
5477 5477 ddi_put16(acc_handle, &pthru->flags, kpthru->flags & ~MFI_FRAME_SGL64);
5478 5478 ddi_put32(acc_handle, &pthru->sgl.sge32[0].length, xferlen);
5479 5479 ddi_put32(acc_handle, &pthru->sgl.sge32[0].phys_addr, kphys_addr);
5480 5480
5481 5481 cmd->sync_cmd = MRSAS_TRUE;
5482 5482 cmd->frame_count = 1;
5483 5483
5484 5484 if (instance->tbolt) {
5485 5485 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
5486 5486 }
5487 5487
5488 5488 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
5489 5489 con_log(CL_ANN, (CE_WARN,
5490 5490 "issue_mfi_pthru: fw_ioctl failed"));
5491 5491 } else {
5492 5492 if (xferlen && kpthru->flags & MFI_FRAME_DIR_READ) {
5493 5493 for (i = 0; i < xferlen; i++) {
5494 5494 if (ddi_copyout(
5495 5495 (uint8_t *)pthru_dma_obj.buffer+i,
5496 5496 (uint8_t *)ubuf+i, 1, mode)) {
5497 5497 con_log(CL_ANN, (CE_WARN,
5498 5498 "issue_mfi_pthru : "
5499 5499 "copy to user space failed"));
5500 5500 return (DDI_FAILURE);
5501 5501 }
5502 5502 }
5503 5503 }
5504 5504 }
5505 5505
5506 5506 kpthru->cmd_status = ddi_get8(acc_handle, &pthru->cmd_status);
5507 5507 kpthru->scsi_status = ddi_get8(acc_handle, &pthru->scsi_status);
5508 5508
5509 5509 con_log(CL_ANN, (CE_CONT, "issue_mfi_pthru: cmd_status %x, "
5510 5510 "scsi_status %x", kpthru->cmd_status, kpthru->scsi_status));
5511 5511 DTRACE_PROBE3(issue_pthru, uint8_t, kpthru->cmd, uint8_t,
5512 5512 kpthru->cmd_status, uint8_t, kpthru->scsi_status);
5513 5513
5514 5514 if (kpthru->sense_len) {
5515 5515 uint_t sense_len = SENSE_LENGTH;
5516 5516 void *sense_ubuf =
5517 5517 (void *)(ulong_t)kpthru->sense_buf_phys_addr_lo;
5518 5518 if (kpthru->sense_len <= SENSE_LENGTH) {
5519 5519 sense_len = kpthru->sense_len;
5520 5520 }
5521 5521
5522 5522 for (i = 0; i < sense_len; i++) {
5523 5523 if (ddi_copyout(
5524 5524 (uint8_t *)cmd->sense+i,
5525 5525 (uint8_t *)sense_ubuf+i, 1, mode)) {
5526 5526 con_log(CL_ANN, (CE_WARN,
5527 5527 "issue_mfi_pthru : "
5528 5528 "copy to user space failed"));
5529 5529 }
5530 5530 con_log(CL_DLEVEL1, (CE_WARN,
5531 5531 "Copying Sense info sense_buff[%d] = 0x%X",
5532 5532 i, *((uint8_t *)cmd->sense + i)));
5533 5533 }
5534 5534 }
5535 5535 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0,
5536 5536 DDI_DMA_SYNC_FORDEV);
5537 5537
5538 5538 if (xferlen) {
5539 5539 /* free kernel buffer */
5540 5540 if (mrsas_free_dma_obj(instance, pthru_dma_obj) != DDI_SUCCESS)
5541 5541 return (DDI_FAILURE);
5542 5542 }
5543 5543
5544 5544 return (DDI_SUCCESS);
5545 5545 }
5546 5546
5547 5547 /*
5548 5548 * issue_mfi_dcmd
5549 5549 */
5550 5550 static int
5551 5551 issue_mfi_dcmd(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
5552 5552 struct mrsas_cmd *cmd, int mode)
5553 5553 {
5554 5554 void *ubuf;
5555 5555 uint32_t kphys_addr = 0;
5556 5556 uint32_t xferlen = 0;
5557 5557 uint32_t new_xfer_length = 0;
5558 5558 uint32_t model;
5559 5559 dma_obj_t dcmd_dma_obj;
5560 5560 struct mrsas_dcmd_frame *kdcmd;
5561 5561 struct mrsas_dcmd_frame *dcmd;
5562 5562 ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
5563 5563 int i;
5564 5564 dcmd = &cmd->frame->dcmd;
5565 5565 kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0];
5566 5566
5567 5567 if (instance->adapterresetinprogress) {
5568 5568 con_log(CL_ANN1, (CE_NOTE, "Reset flag set, "
5569 5569 "returning mfi_pkt and setting TRAN_BUSY"));
5570 5570 return (DDI_FAILURE);
5571 5571 }
5572 5572 model = ddi_model_convert_from(mode & FMODELS);
5573 5573 if (model == DDI_MODEL_ILP32) {
5574 5574 con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
5575 5575
5576 5576 xferlen = kdcmd->sgl.sge32[0].length;
5577 5577
5578 5578 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
5579 5579 } else {
5580 5580 #ifdef _ILP32
5581 5581 con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_ILP32"));
5582 5582 xferlen = kdcmd->sgl.sge32[0].length;
5583 5583 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
5584 5584 #else
5585 5585 con_log(CL_ANN1, (CE_CONT, "issue_mfi_dcmd: DDI_MODEL_LP64"));
5586 5586 xferlen = kdcmd->sgl.sge64[0].length;
5587 5587 ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
5588 5588 #endif
5589 5589 }
5590 5590 if (xferlen) {
5591 5591 /* means IOCTL requires DMA */
5592 5592 /* allocate the data transfer buffer */
5593 5593 /* dcmd_dma_obj.size = xferlen; */
5594 5594 MRSAS_GET_BOUNDARY_ALIGNED_LEN(xferlen, new_xfer_length,
5595 5595 PAGESIZE);
5596 5596 dcmd_dma_obj.size = new_xfer_length;
5597 5597 dcmd_dma_obj.dma_attr = mrsas_generic_dma_attr;
5598 5598 dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
5599 5599 dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
5600 5600 dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1;
5601 5601 dcmd_dma_obj.dma_attr.dma_attr_align = 1;
5602 5602
5603 5603 /* allocate kernel buffer for DMA */
5604 5604 if (mrsas_alloc_dma_obj(instance, &dcmd_dma_obj,
5605 5605 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
5606 5606 con_log(CL_ANN,
5607 5607 (CE_WARN, "issue_mfi_dcmd: could not "
5608 5608 "allocate data transfer buffer."));
5609 5609 return (DDI_FAILURE);
5610 5610 }
5611 5611 (void) memset(dcmd_dma_obj.buffer, 0, xferlen);
5612 5612
5613 5613 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
5614 5614 if (kdcmd->flags & MFI_FRAME_DIR_WRITE) {
5615 5615 for (i = 0; i < xferlen; i++) {
5616 5616 if (ddi_copyin((uint8_t *)ubuf + i,
5617 5617 (uint8_t *)dcmd_dma_obj.buffer + i,
5618 5618 1, mode)) {
5619 5619 con_log(CL_ANN, (CE_WARN,
5620 5620 "issue_mfi_dcmd : "
5621 5621 "copy from user space failed"));
5622 5622 return (DDI_FAILURE);
5623 5623 }
5624 5624 }
5625 5625 }
5626 5626
5627 5627 kphys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address;
5628 5628 }
5629 5629
5630 5630 ddi_put8(acc_handle, &dcmd->cmd, kdcmd->cmd);
5631 5631 ddi_put8(acc_handle, &dcmd->cmd_status, 0);
5632 5632 ddi_put8(acc_handle, &dcmd->sge_count, kdcmd->sge_count);
5633 5633 ddi_put16(acc_handle, &dcmd->timeout, kdcmd->timeout);
5634 5634 ddi_put32(acc_handle, &dcmd->data_xfer_len, kdcmd->data_xfer_len);
5635 5635 ddi_put32(acc_handle, &dcmd->opcode, kdcmd->opcode);
5636 5636
5637 5637 ddi_rep_put8(acc_handle, (uint8_t *)kdcmd->mbox.b,
5638 5638 (uint8_t *)dcmd->mbox.b, DCMD_MBOX_SZ, DDI_DEV_AUTOINCR);
5639 5639
5640 5640 ddi_put16(acc_handle, &dcmd->flags, kdcmd->flags & ~MFI_FRAME_SGL64);
5641 5641 ddi_put32(acc_handle, &dcmd->sgl.sge32[0].length, xferlen);
5642 5642 ddi_put32(acc_handle, &dcmd->sgl.sge32[0].phys_addr, kphys_addr);
5643 5643
5644 5644 cmd->sync_cmd = MRSAS_TRUE;
5645 5645 cmd->frame_count = 1;
5646 5646
5647 5647 if (instance->tbolt) {
5648 5648 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
5649 5649 }
5650 5650
5651 5651 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
5652 5652 con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: fw_ioctl failed"));
5653 5653 } else {
5654 5654 if (xferlen && (kdcmd->flags & MFI_FRAME_DIR_READ)) {
5655 5655 for (i = 0; i < xferlen; i++) {
5656 5656 if (ddi_copyout(
5657 5657 (uint8_t *)dcmd_dma_obj.buffer + i,
5658 5658 (uint8_t *)ubuf + i,
5659 5659 1, mode)) {
5660 5660 con_log(CL_ANN, (CE_WARN,
5661 5661 "issue_mfi_dcmd : "
5662 5662 "copy to user space failed"));
5663 5663 return (DDI_FAILURE);
5664 5664 }
5665 5665 }
5666 5666 }
5667 5667 }
5668 5668
5669 5669 kdcmd->cmd_status = ddi_get8(acc_handle, &dcmd->cmd_status);
5670 5670 con_log(CL_ANN,
5671 5671 (CE_CONT, "issue_mfi_dcmd: cmd_status %x", kdcmd->cmd_status));
5672 5672 DTRACE_PROBE3(issue_dcmd, uint32_t, kdcmd->opcode, uint8_t,
5673 5673 kdcmd->cmd, uint8_t, kdcmd->cmd_status);
5674 5674
5675 5675 if (xferlen) {
5676 5676 /* free kernel buffer */
5677 5677 if (mrsas_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS)
5678 5678 return (DDI_FAILURE);
5679 5679 }
5680 5680
5681 5681 return (DDI_SUCCESS);
5682 5682 }
5683 5683
5684 5684 /*
5685 5685 * issue_mfi_smp
5686 5686 */
5687 5687 static int
5688 5688 issue_mfi_smp(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
5689 5689 struct mrsas_cmd *cmd, int mode)
5690 5690 {
5691 5691 void *request_ubuf;
5692 5692 void *response_ubuf;
5693 5693 uint32_t request_xferlen = 0;
5694 5694 uint32_t response_xferlen = 0;
5695 5695 uint32_t new_xfer_length1 = 0;
5696 5696 uint32_t new_xfer_length2 = 0;
5697 5697 uint_t model;
5698 5698 dma_obj_t request_dma_obj;
5699 5699 dma_obj_t response_dma_obj;
5700 5700 ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
5701 5701 struct mrsas_smp_frame *ksmp;
5702 5702 struct mrsas_smp_frame *smp;
5703 5703 struct mrsas_sge32 *sge32;
5704 5704 #ifndef _ILP32
5705 5705 struct mrsas_sge64 *sge64;
5706 5706 #endif
5707 5707 int i;
5708 5708 uint64_t tmp_sas_addr;
5709 5709
5710 5710 smp = &cmd->frame->smp;
5711 5711 ksmp = (struct mrsas_smp_frame *)&ioctl->frame[0];
5712 5712
5713 5713 if (instance->adapterresetinprogress) {
5714 5714 con_log(CL_ANN1, (CE_WARN, "Reset flag set, "
5715 5715 "returning mfi_pkt and setting TRAN_BUSY\n"));
5716 5716 return (DDI_FAILURE);
5717 5717 }
5718 5718 model = ddi_model_convert_from(mode & FMODELS);
5719 5719 if (model == DDI_MODEL_ILP32) {
5720 5720 con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: DDI_MODEL_ILP32"));
5721 5721
5722 5722 sge32 = &ksmp->sgl[0].sge32[0];
5723 5723 response_xferlen = sge32[0].length;
5724 5724 request_xferlen = sge32[1].length;
5725 5725 con_log(CL_ANN, (CE_CONT, "issue_mfi_smp: "
5726 5726 "response_xferlen = %x, request_xferlen = %x",
5727 5727 response_xferlen, request_xferlen));
5728 5728
5729 5729 response_ubuf = (void *)(ulong_t)sge32[0].phys_addr;
5730 5730 request_ubuf = (void *)(ulong_t)sge32[1].phys_addr;
5731 5731 con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: "
5732 5732 "response_ubuf = %p, request_ubuf = %p",
5733 5733 response_ubuf, request_ubuf));
5734 5734 } else {
5735 5735 #ifdef _ILP32
5736 5736 con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: DDI_MODEL_ILP32"));
5737 5737
5738 5738 sge32 = &ksmp->sgl[0].sge32[0];
5739 5739 response_xferlen = sge32[0].length;
5740 5740 request_xferlen = sge32[1].length;
5741 5741 con_log(CL_ANN, (CE_CONT, "issue_mfi_smp: "
5742 5742 "response_xferlen = %x, request_xferlen = %x",
5743 5743 response_xferlen, request_xferlen));
5744 5744
5745 5745 response_ubuf = (void *)(ulong_t)sge32[0].phys_addr;
5746 5746 request_ubuf = (void *)(ulong_t)sge32[1].phys_addr;
5747 5747 con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: "
5748 5748 "response_ubuf = %p, request_ubuf = %p",
5749 5749 response_ubuf, request_ubuf));
5750 5750 #else
5751 5751 con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp: DDI_MODEL_LP64"));
5752 5752
5753 5753 sge64 = &ksmp->sgl[0].sge64[0];
5754 5754 response_xferlen = sge64[0].length;
5755 5755 request_xferlen = sge64[1].length;
5756 5756
5757 5757 response_ubuf = (void *)(ulong_t)sge64[0].phys_addr;
5758 5758 request_ubuf = (void *)(ulong_t)sge64[1].phys_addr;
5759 5759 #endif
5760 5760 }
5761 5761 if (request_xferlen) {
5762 5762 /* means IOCTL requires DMA */
5763 5763 /* allocate the data transfer buffer */
5764 5764 /* request_dma_obj.size = request_xferlen; */
5765 5765 MRSAS_GET_BOUNDARY_ALIGNED_LEN(request_xferlen,
5766 5766 new_xfer_length1, PAGESIZE);
5767 5767 request_dma_obj.size = new_xfer_length1;
5768 5768 request_dma_obj.dma_attr = mrsas_generic_dma_attr;
5769 5769 request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
5770 5770 request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
5771 5771 request_dma_obj.dma_attr.dma_attr_sgllen = 1;
5772 5772 request_dma_obj.dma_attr.dma_attr_align = 1;
5773 5773
5774 5774 /* allocate kernel buffer for DMA */
5775 5775 if (mrsas_alloc_dma_obj(instance, &request_dma_obj,
5776 5776 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
5777 5777 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
5778 5778 "could not allocate data transfer buffer."));
5779 5779 return (DDI_FAILURE);
5780 5780 }
5781 5781 (void) memset(request_dma_obj.buffer, 0, request_xferlen);
5782 5782
5783 5783 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
5784 5784 for (i = 0; i < request_xferlen; i++) {
5785 5785 if (ddi_copyin((uint8_t *)request_ubuf + i,
5786 5786 (uint8_t *)request_dma_obj.buffer + i,
5787 5787 1, mode)) {
5788 5788 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
5789 5789 "copy from user space failed"));
5790 5790 return (DDI_FAILURE);
5791 5791 }
5792 5792 }
5793 5793 }
5794 5794
5795 5795 if (response_xferlen) {
5796 5796 /* means IOCTL requires DMA */
5797 5797 /* allocate the data transfer buffer */
5798 5798 /* response_dma_obj.size = response_xferlen; */
5799 5799 MRSAS_GET_BOUNDARY_ALIGNED_LEN(response_xferlen,
5800 5800 new_xfer_length2, PAGESIZE);
5801 5801 response_dma_obj.size = new_xfer_length2;
5802 5802 response_dma_obj.dma_attr = mrsas_generic_dma_attr;
5803 5803 response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
5804 5804 response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
5805 5805 response_dma_obj.dma_attr.dma_attr_sgllen = 1;
5806 5806 response_dma_obj.dma_attr.dma_attr_align = 1;
5807 5807
5808 5808 /* allocate kernel buffer for DMA */
5809 5809 if (mrsas_alloc_dma_obj(instance, &response_dma_obj,
5810 5810 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
5811 5811 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
5812 5812 "could not allocate data transfer buffer."));
5813 5813 return (DDI_FAILURE);
5814 5814 }
5815 5815 (void) memset(response_dma_obj.buffer, 0, response_xferlen);
5816 5816
5817 5817 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
5818 5818 for (i = 0; i < response_xferlen; i++) {
5819 5819 if (ddi_copyin((uint8_t *)response_ubuf + i,
5820 5820 (uint8_t *)response_dma_obj.buffer + i,
5821 5821 1, mode)) {
5822 5822 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: "
5823 5823 "copy from user space failed"));
5824 5824 return (DDI_FAILURE);
5825 5825 }
5826 5826 }
5827 5827 }
5828 5828
5829 5829 ddi_put8(acc_handle, &smp->cmd, ksmp->cmd);
5830 5830 ddi_put8(acc_handle, &smp->cmd_status, 0);
5831 5831 ddi_put8(acc_handle, &smp->connection_status, 0);
5832 5832 ddi_put8(acc_handle, &smp->sge_count, ksmp->sge_count);
5833 5833 /* smp->context = ksmp->context; */
5834 5834 ddi_put16(acc_handle, &smp->timeout, ksmp->timeout);
5835 5835 ddi_put32(acc_handle, &smp->data_xfer_len, ksmp->data_xfer_len);
5836 5836
5837 5837 bcopy((void *)&ksmp->sas_addr, (void *)&tmp_sas_addr,
5838 5838 sizeof (uint64_t));
5839 5839 ddi_put64(acc_handle, &smp->sas_addr, tmp_sas_addr);
5840 5840
5841 5841 ddi_put16(acc_handle, &smp->flags, ksmp->flags & ~MFI_FRAME_SGL64);
5842 5842
5843 5843 model = ddi_model_convert_from(mode & FMODELS);
5844 5844 if (model == DDI_MODEL_ILP32) {
5845 5845 con_log(CL_ANN1, (CE_CONT,
5846 5846 "issue_mfi_smp: DDI_MODEL_ILP32"));
5847 5847
5848 5848 sge32 = &smp->sgl[0].sge32[0];
5849 5849 ddi_put32(acc_handle, &sge32[0].length, response_xferlen);
5850 5850 ddi_put32(acc_handle, &sge32[0].phys_addr,
5851 5851 response_dma_obj.dma_cookie[0].dmac_address);
5852 5852 ddi_put32(acc_handle, &sge32[1].length, request_xferlen);
5853 5853 ddi_put32(acc_handle, &sge32[1].phys_addr,
5854 5854 request_dma_obj.dma_cookie[0].dmac_address);
5855 5855 } else {
5856 5856 #ifdef _ILP32
5857 5857 con_log(CL_ANN1, (CE_CONT,
5858 5858 "issue_mfi_smp: DDI_MODEL_ILP32"));
5859 5859 sge32 = &smp->sgl[0].sge32[0];
5860 5860 ddi_put32(acc_handle, &sge32[0].length, response_xferlen);
5861 5861 ddi_put32(acc_handle, &sge32[0].phys_addr,
5862 5862 response_dma_obj.dma_cookie[0].dmac_address);
5863 5863 ddi_put32(acc_handle, &sge32[1].length, request_xferlen);
5864 5864 ddi_put32(acc_handle, &sge32[1].phys_addr,
5865 5865 request_dma_obj.dma_cookie[0].dmac_address);
5866 5866 #else
5867 5867 con_log(CL_ANN1, (CE_CONT,
5868 5868 "issue_mfi_smp: DDI_MODEL_LP64"));
5869 5869 sge64 = &smp->sgl[0].sge64[0];
5870 5870 ddi_put32(acc_handle, &sge64[0].length, response_xferlen);
5871 5871 ddi_put64(acc_handle, &sge64[0].phys_addr,
5872 5872 response_dma_obj.dma_cookie[0].dmac_address);
5873 5873 ddi_put32(acc_handle, &sge64[1].length, request_xferlen);
5874 5874 ddi_put64(acc_handle, &sge64[1].phys_addr,
5875 5875 request_dma_obj.dma_cookie[0].dmac_address);
5876 5876 #endif
5877 5877 }
5878 5878 con_log(CL_ANN1, (CE_CONT, "issue_mfi_smp : "
5879 5879 "smp->response_xferlen = %d, smp->request_xferlen = %d "
5880 5880 "smp->data_xfer_len = %d", ddi_get32(acc_handle, &sge32[0].length),
5881 5881 ddi_get32(acc_handle, &sge32[1].length),
5882 5882 ddi_get32(acc_handle, &smp->data_xfer_len)));
5883 5883
5884 5884 cmd->sync_cmd = MRSAS_TRUE;
5885 5885 cmd->frame_count = 1;
5886 5886
5887 5887 if (instance->tbolt) {
5888 5888 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
5889 5889 }
5890 5890
5891 5891 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
5892 5892 con_log(CL_ANN, (CE_WARN,
5893 5893 "issue_mfi_smp: fw_ioctl failed"));
5894 5894 } else {
5895 5895 con_log(CL_ANN1, (CE_CONT,
5896 5896 "issue_mfi_smp: copy to user space"));
5897 5897
5898 5898 if (request_xferlen) {
5899 5899 for (i = 0; i < request_xferlen; i++) {
5900 5900 if (ddi_copyout(
5901 5901 (uint8_t *)request_dma_obj.buffer +
5902 5902 i, (uint8_t *)request_ubuf + i,
5903 5903 1, mode)) {
5904 5904 con_log(CL_ANN, (CE_WARN,
5905 5905 "issue_mfi_smp : copy to user space"
5906 5906 " failed"));
5907 5907 return (DDI_FAILURE);
5908 5908 }
5909 5909 }
5910 5910 }
5911 5911
5912 5912 if (response_xferlen) {
5913 5913 for (i = 0; i < response_xferlen; i++) {
5914 5914 if (ddi_copyout(
5915 5915 (uint8_t *)response_dma_obj.buffer
5916 5916 + i, (uint8_t *)response_ubuf
5917 5917 + i, 1, mode)) {
5918 5918 con_log(CL_ANN, (CE_WARN,
5919 5919 "issue_mfi_smp : copy to "
5920 5920 "user space failed"));
5921 5921 return (DDI_FAILURE);
5922 5922 }
5923 5923 }
5924 5924 }
5925 5925 }
5926 5926
5927 5927 ksmp->cmd_status = ddi_get8(acc_handle, &smp->cmd_status);
5928 5928 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d",
5929 5929 ksmp->cmd_status));
5930 5930 DTRACE_PROBE2(issue_smp, uint8_t, ksmp->cmd, uint8_t, ksmp->cmd_status);
5931 5931
5932 5932 if (request_xferlen) {
5933 5933 /* free kernel buffer */
5934 5934 if (mrsas_free_dma_obj(instance, request_dma_obj) !=
5935 5935 DDI_SUCCESS)
5936 5936 return (DDI_FAILURE);
5937 5937 }
5938 5938
5939 5939 if (response_xferlen) {
5940 5940 /* free kernel buffer */
5941 5941 if (mrsas_free_dma_obj(instance, response_dma_obj) !=
5942 5942 DDI_SUCCESS)
5943 5943 return (DDI_FAILURE);
5944 5944 }
5945 5945
5946 5946 return (DDI_SUCCESS);
5947 5947 }
5948 5948
5949 5949 /*
5950 5950 * issue_mfi_stp
5951 5951 */
5952 5952 static int
5953 5953 issue_mfi_stp(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
5954 5954 struct mrsas_cmd *cmd, int mode)
5955 5955 {
5956 5956 void *fis_ubuf;
5957 5957 void *data_ubuf;
5958 5958 uint32_t fis_xferlen = 0;
5959 5959 uint32_t new_xfer_length1 = 0;
5960 5960 uint32_t new_xfer_length2 = 0;
5961 5961 uint32_t data_xferlen = 0;
5962 5962 uint_t model;
5963 5963 dma_obj_t fis_dma_obj;
5964 5964 dma_obj_t data_dma_obj;
5965 5965 struct mrsas_stp_frame *kstp;
5966 5966 struct mrsas_stp_frame *stp;
5967 5967 ddi_acc_handle_t acc_handle = cmd->frame_dma_obj.acc_handle;
5968 5968 int i;
5969 5969
5970 5970 stp = &cmd->frame->stp;
5971 5971 kstp = (struct mrsas_stp_frame *)&ioctl->frame[0];
5972 5972
5973 5973 if (instance->adapterresetinprogress) {
5974 5974 con_log(CL_ANN1, (CE_WARN, "Reset flag set, "
5975 5975 "returning mfi_pkt and setting TRAN_BUSY\n"));
5976 5976 return (DDI_FAILURE);
5977 5977 }
5978 5978 model = ddi_model_convert_from(mode & FMODELS);
5979 5979 if (model == DDI_MODEL_ILP32) {
5980 5980 con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_ILP32"));
5981 5981
5982 5982 fis_xferlen = kstp->sgl.sge32[0].length;
5983 5983 data_xferlen = kstp->sgl.sge32[1].length;
5984 5984
5985 5985 fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
5986 5986 data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
5987 5987 } else {
5988 5988 #ifdef _ILP32
5989 5989 con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_ILP32"));
5990 5990
5991 5991 fis_xferlen = kstp->sgl.sge32[0].length;
5992 5992 data_xferlen = kstp->sgl.sge32[1].length;
5993 5993
5994 5994 fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr;
5995 5995 data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr;
5996 5996 #else
5997 5997 con_log(CL_ANN1, (CE_CONT, "issue_mfi_stp: DDI_MODEL_LP64"));
5998 5998
5999 5999 fis_xferlen = kstp->sgl.sge64[0].length;
6000 6000 data_xferlen = kstp->sgl.sge64[1].length;
6001 6001
6002 6002 fis_ubuf = (void *)(ulong_t)kstp->sgl.sge64[0].phys_addr;
6003 6003 data_ubuf = (void *)(ulong_t)kstp->sgl.sge64[1].phys_addr;
6004 6004 #endif
6005 6005 }
6006 6006
6007 6007
6008 6008 if (fis_xferlen) {
6009 6009 con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: "
6010 6010 "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen));
6011 6011
6012 6012 /* means IOCTL requires DMA */
6013 6013 /* allocate the data transfer buffer */
6014 6014 /* fis_dma_obj.size = fis_xferlen; */
6015 6015 MRSAS_GET_BOUNDARY_ALIGNED_LEN(fis_xferlen,
6016 6016 new_xfer_length1, PAGESIZE);
6017 6017 fis_dma_obj.size = new_xfer_length1;
6018 6018 fis_dma_obj.dma_attr = mrsas_generic_dma_attr;
6019 6019 fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
6020 6020 fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6021 6021 fis_dma_obj.dma_attr.dma_attr_sgllen = 1;
6022 6022 fis_dma_obj.dma_attr.dma_attr_align = 1;
6023 6023
6024 6024 /* allocate kernel buffer for DMA */
6025 6025 if (mrsas_alloc_dma_obj(instance, &fis_dma_obj,
6026 6026 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
6027 6027 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp : "
6028 6028 "could not allocate data transfer buffer."));
6029 6029 return (DDI_FAILURE);
6030 6030 }
6031 6031 (void) memset(fis_dma_obj.buffer, 0, fis_xferlen);
6032 6032
6033 6033 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6034 6034 for (i = 0; i < fis_xferlen; i++) {
6035 6035 if (ddi_copyin((uint8_t *)fis_ubuf + i,
6036 6036 (uint8_t *)fis_dma_obj.buffer + i, 1, mode)) {
6037 6037 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6038 6038 "copy from user space failed"));
6039 6039 return (DDI_FAILURE);
6040 6040 }
6041 6041 }
6042 6042 }
6043 6043
6044 6044 if (data_xferlen) {
6045 6045 con_log(CL_ANN, (CE_CONT, "issue_mfi_stp: data_ubuf = %p "
6046 6046 "data_xferlen = %x", data_ubuf, data_xferlen));
6047 6047
6048 6048 /* means IOCTL requires DMA */
6049 6049 /* allocate the data transfer buffer */
6050 6050 /* data_dma_obj.size = data_xferlen; */
6051 6051 MRSAS_GET_BOUNDARY_ALIGNED_LEN(data_xferlen, new_xfer_length2,
6052 6052 PAGESIZE);
6053 6053 data_dma_obj.size = new_xfer_length2;
6054 6054 data_dma_obj.dma_attr = mrsas_generic_dma_attr;
6055 6055 data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU;
6056 6056 data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU;
6057 6057 data_dma_obj.dma_attr.dma_attr_sgllen = 1;
6058 6058 data_dma_obj.dma_attr.dma_attr_align = 1;
6059 6059
6060 6060 /* allocate kernel buffer for DMA */
6061 6061 if (mrsas_alloc_dma_obj(instance, &data_dma_obj,
6062 6062 (uchar_t)DDI_STRUCTURE_LE_ACC) != 1) {
6063 6063 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6064 6064 "could not allocate data transfer buffer."));
6065 6065 return (DDI_FAILURE);
6066 6066 }
6067 6067 (void) memset(data_dma_obj.buffer, 0, data_xferlen);
6068 6068
6069 6069 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */
6070 6070 for (i = 0; i < data_xferlen; i++) {
6071 6071 if (ddi_copyin((uint8_t *)data_ubuf + i,
6072 6072 (uint8_t *)data_dma_obj.buffer + i, 1, mode)) {
6073 6073 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: "
6074 6074 "copy from user space failed"));
6075 6075 return (DDI_FAILURE);
6076 6076 }
6077 6077 }
6078 6078 }
6079 6079
6080 6080 ddi_put8(acc_handle, &stp->cmd, kstp->cmd);
6081 6081 ddi_put8(acc_handle, &stp->cmd_status, 0);
6082 6082 ddi_put8(acc_handle, &stp->connection_status, 0);
6083 6083 ddi_put8(acc_handle, &stp->target_id, kstp->target_id);
6084 6084 ddi_put8(acc_handle, &stp->sge_count, kstp->sge_count);
6085 6085
6086 6086 ddi_put16(acc_handle, &stp->timeout, kstp->timeout);
6087 6087 ddi_put32(acc_handle, &stp->data_xfer_len, kstp->data_xfer_len);
6088 6088
6089 6089 ddi_rep_put8(acc_handle, (uint8_t *)kstp->fis, (uint8_t *)stp->fis, 10,
6090 6090 DDI_DEV_AUTOINCR);
6091 6091
6092 6092 ddi_put16(acc_handle, &stp->flags, kstp->flags & ~MFI_FRAME_SGL64);
6093 6093 ddi_put32(acc_handle, &stp->stp_flags, kstp->stp_flags);
6094 6094 ddi_put32(acc_handle, &stp->sgl.sge32[0].length, fis_xferlen);
6095 6095 ddi_put32(acc_handle, &stp->sgl.sge32[0].phys_addr,
6096 6096 fis_dma_obj.dma_cookie[0].dmac_address);
6097 6097 ddi_put32(acc_handle, &stp->sgl.sge32[1].length, data_xferlen);
6098 6098 ddi_put32(acc_handle, &stp->sgl.sge32[1].phys_addr,
6099 6099 data_dma_obj.dma_cookie[0].dmac_address);
6100 6100
6101 6101 cmd->sync_cmd = MRSAS_TRUE;
6102 6102 cmd->frame_count = 1;
6103 6103
6104 6104 if (instance->tbolt) {
6105 6105 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
6106 6106 }
6107 6107
6108 6108 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) {
6109 6109 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: fw_ioctl failed"));
6110 6110 } else {
6111 6111
6112 6112 if (fis_xferlen) {
6113 6113 for (i = 0; i < fis_xferlen; i++) {
6114 6114 if (ddi_copyout(
6115 6115 (uint8_t *)fis_dma_obj.buffer + i,
6116 6116 (uint8_t *)fis_ubuf + i, 1, mode)) {
6117 6117 con_log(CL_ANN, (CE_WARN,
6118 6118 "issue_mfi_stp : copy to "
6119 6119 "user space failed"));
6120 6120 return (DDI_FAILURE);
6121 6121 }
6122 6122 }
6123 6123 }
6124 6124 }
6125 6125 if (data_xferlen) {
6126 6126 for (i = 0; i < data_xferlen; i++) {
6127 6127 if (ddi_copyout(
6128 6128 (uint8_t *)data_dma_obj.buffer + i,
6129 6129 (uint8_t *)data_ubuf + i, 1, mode)) {
6130 6130 con_log(CL_ANN, (CE_WARN,
6131 6131 "issue_mfi_stp : copy to"
6132 6132 " user space failed"));
6133 6133 return (DDI_FAILURE);
6134 6134 }
6135 6135 }
6136 6136 }
6137 6137
6138 6138 kstp->cmd_status = ddi_get8(acc_handle, &stp->cmd_status);
6139 6139 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: stp->cmd_status = %d",
6140 6140 kstp->cmd_status));
6141 6141 DTRACE_PROBE2(issue_stp, uint8_t, kstp->cmd, uint8_t, kstp->cmd_status);
6142 6142
6143 6143 if (fis_xferlen) {
6144 6144 /* free kernel buffer */
6145 6145 if (mrsas_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS)
6146 6146 return (DDI_FAILURE);
6147 6147 }
6148 6148
6149 6149 if (data_xferlen) {
6150 6150 /* free kernel buffer */
6151 6151 if (mrsas_free_dma_obj(instance, data_dma_obj) != DDI_SUCCESS)
6152 6152 return (DDI_FAILURE);
6153 6153 }
6154 6154
6155 6155 return (DDI_SUCCESS);
6156 6156 }
6157 6157
6158 6158 /*
6159 6159 * fill_up_drv_ver
6160 6160 */
6161 6161 void
6162 6162 fill_up_drv_ver(struct mrsas_drv_ver *dv)
6163 6163 {
6164 6164 (void) memset(dv, 0, sizeof (struct mrsas_drv_ver));
6165 6165
6166 6166 (void) memcpy(dv->signature, "$LSI LOGIC$", strlen("$LSI LOGIC$"));
6167 6167 (void) memcpy(dv->os_name, "Solaris", strlen("Solaris"));
6168 6168 (void) memcpy(dv->drv_name, "mr_sas", strlen("mr_sas"));
6169 6169 (void) memcpy(dv->drv_ver, MRSAS_VERSION, strlen(MRSAS_VERSION));
6170 6170 (void) memcpy(dv->drv_rel_date, MRSAS_RELDATE,
6171 6171 strlen(MRSAS_RELDATE));
6172 6172
6173 6173 }
6174 6174
6175 6175 /*
6176 6176 * handle_drv_ioctl
6177 6177 */
6178 6178 static int
6179 6179 handle_drv_ioctl(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
6180 6180 int mode)
6181 6181 {
6182 6182 int i;
6183 6183 int rval = DDI_SUCCESS;
6184 6184 int *props = NULL;
6185 6185 void *ubuf;
6186 6186
6187 6187 uint8_t *pci_conf_buf;
6188 6188 uint32_t xferlen;
6189 6189 uint32_t num_props;
6190 6190 uint_t model;
6191 6191 struct mrsas_dcmd_frame *kdcmd;
6192 6192 struct mrsas_drv_ver dv;
6193 6193 struct mrsas_pci_information pi;
6194 6194
6195 6195 kdcmd = (struct mrsas_dcmd_frame *)&ioctl->frame[0];
6196 6196
6197 6197 model = ddi_model_convert_from(mode & FMODELS);
6198 6198 if (model == DDI_MODEL_ILP32) {
6199 6199 con_log(CL_ANN1, (CE_CONT,
6200 6200 "handle_drv_ioctl: DDI_MODEL_ILP32"));
6201 6201
6202 6202 xferlen = kdcmd->sgl.sge32[0].length;
6203 6203
6204 6204 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6205 6205 } else {
6206 6206 #ifdef _ILP32
6207 6207 con_log(CL_ANN1, (CE_CONT,
6208 6208 "handle_drv_ioctl: DDI_MODEL_ILP32"));
6209 6209 xferlen = kdcmd->sgl.sge32[0].length;
6210 6210 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr;
6211 6211 #else
6212 6212 con_log(CL_ANN1, (CE_CONT,
6213 6213 "handle_drv_ioctl: DDI_MODEL_LP64"));
6214 6214 xferlen = kdcmd->sgl.sge64[0].length;
6215 6215 ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr;
6216 6216 #endif
6217 6217 }
6218 6218 con_log(CL_ANN1, (CE_CONT, "handle_drv_ioctl: "
6219 6219 "dataBuf=%p size=%d bytes", ubuf, xferlen));
6220 6220
6221 6221 switch (kdcmd->opcode) {
6222 6222 case MRSAS_DRIVER_IOCTL_DRIVER_VERSION:
6223 6223 con_log(CL_ANN1, (CE_CONT, "handle_drv_ioctl: "
6224 6224 "MRSAS_DRIVER_IOCTL_DRIVER_VERSION"));
6225 6225
6226 6226 fill_up_drv_ver(&dv);
6227 6227
6228 6228 if (ddi_copyout(&dv, ubuf, xferlen, mode)) {
6229 6229 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6230 6230 "MRSAS_DRIVER_IOCTL_DRIVER_VERSION : "
6231 6231 "copy to user space failed"));
6232 6232 kdcmd->cmd_status = 1;
6233 6233 rval = 1;
6234 6234 } else {
6235 6235 kdcmd->cmd_status = 0;
6236 6236 }
6237 6237 break;
6238 6238 case MRSAS_DRIVER_IOCTL_PCI_INFORMATION:
6239 6239 con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: "
6240 6240 "MRSAS_DRIVER_IOCTL_PCI_INFORMAITON"));
6241 6241
6242 6242 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, instance->dip,
6243 6243 0, "reg", &props, &num_props)) {
6244 6244 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6245 6245 "MRSAS_DRIVER_IOCTL_PCI_INFORMATION : "
6246 6246 "ddi_prop_look_int_array failed"));
6247 6247 rval = DDI_FAILURE;
6248 6248 } else {
6249 6249
6250 6250 pi.busNumber = (props[0] >> 16) & 0xFF;
6251 6251 pi.deviceNumber = (props[0] >> 11) & 0x1f;
6252 6252 pi.functionNumber = (props[0] >> 8) & 0x7;
6253 6253 ddi_prop_free((void *)props);
6254 6254 }
6255 6255
6256 6256 pci_conf_buf = (uint8_t *)&pi.pciHeaderInfo;
6257 6257
6258 6258 for (i = 0; i < (sizeof (struct mrsas_pci_information) -
6259 6259 offsetof(struct mrsas_pci_information, pciHeaderInfo));
6260 6260 i++) {
6261 6261 pci_conf_buf[i] =
6262 6262 pci_config_get8(instance->pci_handle, i);
6263 6263 }
6264 6264
6265 6265 if (ddi_copyout(&pi, ubuf, xferlen, mode)) {
6266 6266 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6267 6267 "MRSAS_DRIVER_IOCTL_PCI_INFORMATION : "
6268 6268 "copy to user space failed"));
6269 6269 kdcmd->cmd_status = 1;
6270 6270 rval = 1;
6271 6271 } else {
6272 6272 kdcmd->cmd_status = 0;
6273 6273 }
6274 6274 break;
6275 6275 default:
6276 6276 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: "
6277 6277 "invalid driver specific IOCTL opcode = 0x%x",
6278 6278 kdcmd->opcode));
6279 6279 kdcmd->cmd_status = 1;
6280 6280 rval = DDI_FAILURE;
6281 6281 break;
6282 6282 }
6283 6283
6284 6284 return (rval);
6285 6285 }
6286 6286
6287 6287 /*
6288 6288 * handle_mfi_ioctl
6289 6289 */
6290 6290 static int
6291 6291 handle_mfi_ioctl(struct mrsas_instance *instance, struct mrsas_ioctl *ioctl,
6292 6292 int mode)
6293 6293 {
6294 6294 int rval = DDI_SUCCESS;
6295 6295
6296 6296 struct mrsas_header *hdr;
6297 6297 struct mrsas_cmd *cmd;
6298 6298
6299 6299 if (instance->tbolt) {
6300 6300 cmd = get_raid_msg_mfi_pkt(instance);
6301 6301 } else {
6302 6302 cmd = mrsas_get_mfi_pkt(instance);
6303 6303 }
6304 6304 if (!cmd) {
6305 6305 con_log(CL_ANN, (CE_WARN, "mr_sas: "
6306 6306 "failed to get a cmd packet"));
6307 6307 DTRACE_PROBE2(mfi_ioctl_err, uint16_t,
6308 6308 instance->fw_outstanding, uint16_t, instance->max_fw_cmds);
6309 6309 return (DDI_FAILURE);
6310 6310 }
6311 6311
6312 6312 /* Clear the frame buffer and assign back the context id */
6313 6313 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
6314 6314 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
6315 6315 cmd->index);
6316 6316
6317 6317 hdr = (struct mrsas_header *)&ioctl->frame[0];
6318 6318
6319 6319 switch (ddi_get8(cmd->frame_dma_obj.acc_handle, &hdr->cmd)) {
6320 6320 case MFI_CMD_OP_DCMD:
6321 6321 rval = issue_mfi_dcmd(instance, ioctl, cmd, mode);
6322 6322 break;
6323 6323 case MFI_CMD_OP_SMP:
6324 6324 rval = issue_mfi_smp(instance, ioctl, cmd, mode);
6325 6325 break;
6326 6326 case MFI_CMD_OP_STP:
6327 6327 rval = issue_mfi_stp(instance, ioctl, cmd, mode);
6328 6328 break;
6329 6329 case MFI_CMD_OP_LD_SCSI:
6330 6330 case MFI_CMD_OP_PD_SCSI:
6331 6331 rval = issue_mfi_pthru(instance, ioctl, cmd, mode);
6332 6332 break;
6333 6333 default:
6334 6334 con_log(CL_ANN, (CE_WARN, "handle_mfi_ioctl: "
6335 6335 "invalid mfi ioctl hdr->cmd = %d", hdr->cmd));
6336 6336 rval = DDI_FAILURE;
6337 6337 break;
6338 6338 }
6339 6339
6340 6340 if (mrsas_common_check(instance, cmd) != DDI_SUCCESS)
6341 6341 rval = DDI_FAILURE;
6342 6342
6343 6343 if (instance->tbolt) {
6344 6344 return_raid_msg_mfi_pkt(instance, cmd);
6345 6345 } else {
6346 6346 mrsas_return_mfi_pkt(instance, cmd);
6347 6347 }
6348 6348
6349 6349 return (rval);
6350 6350 }
6351 6351
6352 6352 /*
6353 6353 * AEN
6354 6354 */
6355 6355 static int
6356 6356 handle_mfi_aen(struct mrsas_instance *instance, struct mrsas_aen *aen)
6357 6357 {
6358 6358 int rval = 0;
6359 6359
6360 6360 rval = register_mfi_aen(instance, instance->aen_seq_num,
6361 6361 aen->class_locale_word);
6362 6362
6363 6363 aen->cmd_status = (uint8_t)rval;
6364 6364
6365 6365 return (rval);
6366 6366 }
6367 6367
6368 6368 static int
6369 6369 register_mfi_aen(struct mrsas_instance *instance, uint32_t seq_num,
6370 6370 uint32_t class_locale_word)
6371 6371 {
6372 6372 int ret_val;
6373 6373
6374 6374 struct mrsas_cmd *cmd, *aen_cmd;
6375 6375 struct mrsas_dcmd_frame *dcmd;
6376 6376 union mrsas_evt_class_locale curr_aen;
6377 6377 union mrsas_evt_class_locale prev_aen;
6378 6378
6379 6379 con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6380 6380 /*
6381 6381 * If there an AEN pending already (aen_cmd), check if the
6382 6382 * class_locale of that pending AEN is inclusive of the new
6383 6383 * AEN request we currently have. If it is, then we don't have
6384 6384 * to do anything. In other words, whichever events the current
6385 6385 * AEN request is subscribing to, have already been subscribed
6386 6386 * to.
6387 6387 *
6388 6388 * If the old_cmd is _not_ inclusive, then we have to abort
6389 6389 * that command, form a class_locale that is superset of both
6390 6390 * old and current and re-issue to the FW
6391 6391 */
6392 6392
6393 6393 curr_aen.word = LE_32(class_locale_word);
6394 6394 curr_aen.members.locale = LE_16(curr_aen.members.locale);
6395 6395 aen_cmd = instance->aen_cmd;
6396 6396 if (aen_cmd) {
6397 6397 prev_aen.word = ddi_get32(aen_cmd->frame_dma_obj.acc_handle,
6398 6398 &aen_cmd->frame->dcmd.mbox.w[1]);
6399 6399 prev_aen.word = LE_32(prev_aen.word);
6400 6400 prev_aen.members.locale = LE_16(prev_aen.members.locale);
6401 6401 /*
6402 6402 * A class whose enum value is smaller is inclusive of all
6403 6403 * higher values. If a PROGRESS (= -1) was previously
6404 6404 * registered, then a new registration requests for higher
6405 6405 * classes need not be sent to FW. They are automatically
6406 6406 * included.
6407 6407 *
6408 6408 * Locale numbers don't have such hierarchy. They are bitmap
6409 6409 * values
6410 6410 */
6411 6411 if ((prev_aen.members.class <= curr_aen.members.class) &&
6412 6412 !((prev_aen.members.locale & curr_aen.members.locale) ^
6413 6413 curr_aen.members.locale)) {
6414 6414 /*
6415 6415 * Previously issued event registration includes
6416 6416 * current request. Nothing to do.
6417 6417 */
6418 6418
6419 6419 return (0);
6420 6420 } else {
6421 6421 curr_aen.members.locale |= prev_aen.members.locale;
6422 6422
6423 6423 if (prev_aen.members.class < curr_aen.members.class)
6424 6424 curr_aen.members.class = prev_aen.members.class;
6425 6425
6426 6426 ret_val = abort_aen_cmd(instance, aen_cmd);
6427 6427
6428 6428 if (ret_val) {
6429 6429 con_log(CL_ANN, (CE_WARN, "register_mfi_aen: "
6430 6430 "failed to abort prevous AEN command"));
6431 6431
6432 6432 return (ret_val);
6433 6433 }
6434 6434 }
6435 6435 } else {
6436 6436 curr_aen.word = LE_32(class_locale_word);
6437 6437 curr_aen.members.locale = LE_16(curr_aen.members.locale);
6438 6438 }
6439 6439
6440 6440 if (instance->tbolt) {
6441 6441 cmd = get_raid_msg_mfi_pkt(instance);
6442 6442 } else {
6443 6443 cmd = mrsas_get_mfi_pkt(instance);
6444 6444 }
6445 6445
6446 6446 if (!cmd) {
6447 6447 DTRACE_PROBE2(mfi_aen_err, uint16_t, instance->fw_outstanding,
6448 6448 uint16_t, instance->max_fw_cmds);
6449 6449 return (ENOMEM);
6450 6450 }
6451 6451
6452 6452 /* Clear the frame buffer and assign back the context id */
6453 6453 (void) memset((char *)&cmd->frame[0], 0, sizeof (union mrsas_frame));
6454 6454 ddi_put32(cmd->frame_dma_obj.acc_handle, &cmd->frame->hdr.context,
6455 6455 cmd->index);
6456 6456
6457 6457 dcmd = &cmd->frame->dcmd;
6458 6458
6459 6459 /* for(i = 0; i < DCMD_MBOX_SZ; i++) dcmd->mbox.b[i] = 0; */
6460 6460 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ);
6461 6461
6462 6462 (void) memset(instance->mfi_evt_detail_obj.buffer, 0,
6463 6463 sizeof (struct mrsas_evt_detail));
6464 6464
6465 6465 /* Prepare DCMD for aen registration */
6466 6466 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd, MFI_CMD_OP_DCMD);
6467 6467 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->cmd_status, 0x0);
6468 6468 ddi_put8(cmd->frame_dma_obj.acc_handle, &dcmd->sge_count, 1);
6469 6469 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->flags,
6470 6470 MFI_FRAME_DIR_READ);
6471 6471 ddi_put16(cmd->frame_dma_obj.acc_handle, &dcmd->timeout, 0);
6472 6472 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->data_xfer_len,
6473 6473 sizeof (struct mrsas_evt_detail));
6474 6474 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->opcode,
6475 6475 MR_DCMD_CTRL_EVENT_WAIT);
6476 6476 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.w[0], seq_num);
6477 6477 curr_aen.members.locale = LE_16(curr_aen.members.locale);
6478 6478 curr_aen.word = LE_32(curr_aen.word);
6479 6479 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->mbox.w[1],
6480 6480 curr_aen.word);
6481 6481 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].phys_addr,
6482 6482 instance->mfi_evt_detail_obj.dma_cookie[0].dmac_address);
6483 6483 ddi_put32(cmd->frame_dma_obj.acc_handle, &dcmd->sgl.sge32[0].length,
6484 6484 sizeof (struct mrsas_evt_detail));
6485 6485
6486 6486 instance->aen_seq_num = seq_num;
6487 6487
6488 6488
6489 6489 /*
6490 6490 * Store reference to the cmd used to register for AEN. When an
6491 6491 * application wants us to register for AEN, we have to abort this
6492 6492 * cmd and re-register with a new EVENT LOCALE supplied by that app
6493 6493 */
6494 6494 instance->aen_cmd = cmd;
6495 6495
6496 6496 cmd->frame_count = 1;
6497 6497
6498 6498 /* Issue the aen registration frame */
6499 6499 /* atomic_add_16 (&instance->fw_outstanding, 1); */
6500 6500 if (instance->tbolt) {
6501 6501 mr_sas_tbolt_build_mfi_cmd(instance, cmd);
6502 6502 }
6503 6503 instance->func_ptr->issue_cmd(cmd, instance);
6504 6504
6505 6505 return (0);
6506 6506 }
6507 6507
6508 6508 void
6509 6509 display_scsi_inquiry(caddr_t scsi_inq)
6510 6510 {
6511 6511 #define MAX_SCSI_DEVICE_CODE 14
6512 6512 int i;
6513 6513 char inquiry_buf[256] = {0};
6514 6514 int len;
6515 6515 const char *const scsi_device_types[] = {
6516 6516 "Direct-Access ",
6517 6517 "Sequential-Access",
6518 6518 "Printer ",
6519 6519 "Processor ",
6520 6520 "WORM ",
6521 6521 "CD-ROM ",
6522 6522 "Scanner ",
6523 6523 "Optical Device ",
6524 6524 "Medium Changer ",
6525 6525 "Communications ",
6526 6526 "Unknown ",
6527 6527 "Unknown ",
6528 6528 "Unknown ",
6529 6529 "Enclosure ",
6530 6530 };
6531 6531
6532 6532 len = 0;
6533 6533
6534 6534 len += snprintf(inquiry_buf + len, 265 - len, " Vendor: ");
6535 6535 for (i = 8; i < 16; i++) {
6536 6536 len += snprintf(inquiry_buf + len, 265 - len, "%c",
6537 6537 scsi_inq[i]);
6538 6538 }
6539 6539
6540 6540 len += snprintf(inquiry_buf + len, 265 - len, " Model: ");
6541 6541
6542 6542 for (i = 16; i < 32; i++) {
6543 6543 len += snprintf(inquiry_buf + len, 265 - len, "%c",
6544 6544 scsi_inq[i]);
6545 6545 }
6546 6546
6547 6547 len += snprintf(inquiry_buf + len, 265 - len, " Rev: ");
6548 6548
6549 6549 for (i = 32; i < 36; i++) {
6550 6550 len += snprintf(inquiry_buf + len, 265 - len, "%c",
6551 6551 scsi_inq[i]);
6552 6552 }
6553 6553
6554 6554 len += snprintf(inquiry_buf + len, 265 - len, "\n");
6555 6555
6556 6556
6557 6557 i = scsi_inq[0] & 0x1f;
6558 6558
6559 6559
6560 6560 len += snprintf(inquiry_buf + len, 265 - len, " Type: %s ",
6561 6561 i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] :
6562 6562 "Unknown ");
6563 6563
6564 6564
6565 6565 len += snprintf(inquiry_buf + len, 265 - len,
6566 6566 " ANSI SCSI revision: %02x", scsi_inq[2] & 0x07);
6567 6567
6568 6568 if ((scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1) {
6569 6569 len += snprintf(inquiry_buf + len, 265 - len, " CCS\n");
6570 6570 } else {
6571 6571 len += snprintf(inquiry_buf + len, 265 - len, "\n");
6572 6572 }
6573 6573
6574 6574 con_log(CL_DLEVEL2, (CE_CONT, inquiry_buf));
6575 6575 }
6576 6576
6577 6577 static void
6578 6578 io_timeout_checker(void *arg)
6579 6579 {
6580 6580 struct scsi_pkt *pkt;
6581 6581 struct mrsas_instance *instance = arg;
6582 6582 struct mrsas_cmd *cmd = NULL;
6583 6583 struct mrsas_header *hdr;
6584 6584 int time = 0;
6585 6585 int counter = 0;
6586 6586 struct mlist_head *pos, *next;
6587 6587 mlist_t process_list;
6588 6588
6589 6589 if (instance->adapterresetinprogress == 1) {
6590 6590 con_log(CL_ANN, (CE_NOTE, "io_timeout_checker:"
6591 6591 " reset in progress"));
6592 6592
6593 6593 instance->timeout_id = timeout(io_timeout_checker,
6594 6594 (void *) instance, drv_usectohz(MRSAS_1_SECOND));
6595 6595 return;
6596 6596 }
6597 6597
6598 6598 /* See if this check needs to be in the beginning or last in ISR */
6599 6599 if (mrsas_initiate_ocr_if_fw_is_faulty(instance) == 1) {
6600 6600 dev_err(instance->dip, CE_WARN, "io_timeout_checker: "
6601 6601 "FW Fault, calling reset adapter");
6602 6602 dev_err(instance->dip, CE_CONT, "io_timeout_checker: "
6603 6603 "fw_outstanding 0x%X max_fw_cmds 0x%X",
6604 6604 instance->fw_outstanding, instance->max_fw_cmds);
6605 6605 if (instance->adapterresetinprogress == 0) {
6606 6606 instance->adapterresetinprogress = 1;
6607 6607 if (instance->tbolt)
6608 6608 (void) mrsas_tbolt_reset_ppc(instance);
6609 6609 else
6610 6610 (void) mrsas_reset_ppc(instance);
6611 6611 instance->adapterresetinprogress = 0;
6612 6612 }
6613 6613 instance->timeout_id = timeout(io_timeout_checker,
6614 6614 (void *) instance, drv_usectohz(MRSAS_1_SECOND));
6615 6615 return;
6616 6616 }
6617 6617
6618 6618 INIT_LIST_HEAD(&process_list);
6619 6619
6620 6620 mutex_enter(&instance->cmd_pend_mtx);
6621 6621 mlist_for_each_safe(pos, next, &instance->cmd_pend_list) {
6622 6622 cmd = mlist_entry(pos, struct mrsas_cmd, list);
6623 6623
6624 6624 if (cmd == NULL) {
6625 6625 continue;
6626 6626 }
6627 6627
6628 6628 if (cmd->sync_cmd == MRSAS_TRUE) {
6629 6629 hdr = (struct mrsas_header *)&cmd->frame->hdr;
6630 6630 if (hdr == NULL) {
6631 6631 continue;
6632 6632 }
6633 6633 time = --cmd->drv_pkt_time;
6634 6634 } else {
6635 6635 pkt = cmd->pkt;
6636 6636 if (pkt == NULL) {
6637 6637 continue;
6638 6638 }
6639 6639 time = --cmd->drv_pkt_time;
6640 6640 }
6641 6641 if (time <= 0) {
6642 6642 dev_err(instance->dip, CE_WARN, "%llx: "
6643 6643 "io_timeout_checker: TIMING OUT: pkt: %p, "
6644 6644 "cmd %p fw_outstanding 0x%X max_fw_cmds 0x%X",
6645 6645 gethrtime(), (void *)pkt, (void *)cmd,
6646 6646 instance->fw_outstanding, instance->max_fw_cmds);
6647 6647
6648 6648 counter++;
6649 6649 break;
6650 6650 }
6651 6651 }
6652 6652 mutex_exit(&instance->cmd_pend_mtx);
6653 6653
6654 6654 if (counter) {
6655 6655 if (instance->disable_online_ctrl_reset == 1) {
6656 6656 dev_err(instance->dip, CE_WARN, "%s(): OCR is NOT "
6657 6657 "supported by Firmware, KILL adapter!!!",
6658 6658 __func__);
6659 6659
6660 6660 if (instance->tbolt)
6661 6661 mrsas_tbolt_kill_adapter(instance);
6662 6662 else
6663 6663 (void) mrsas_kill_adapter(instance);
6664 6664
6665 6665 return;
6666 6666 } else {
6667 6667 if (cmd->retry_count_for_ocr <= IO_RETRY_COUNT) {
6668 6668 if (instance->adapterresetinprogress == 0) {
6669 6669 if (instance->tbolt) {
6670 6670 (void) mrsas_tbolt_reset_ppc(
6671 6671 instance);
6672 6672 } else {
6673 6673 (void) mrsas_reset_ppc(
6674 6674 instance);
6675 6675 }
6676 6676 }
6677 6677 } else {
6678 6678 dev_err(instance->dip, CE_WARN,
6679 6679 "io_timeout_checker: "
6680 6680 "cmd %p cmd->index %d "
6681 6681 "timed out even after 3 resets: "
6682 6682 "so KILL adapter", (void *)cmd, cmd->index);
6683 6683
6684 6684 mrsas_print_cmd_details(instance, cmd, 0xDD);
6685 6685
6686 6686 if (instance->tbolt)
6687 6687 mrsas_tbolt_kill_adapter(instance);
6688 6688 else
6689 6689 (void) mrsas_kill_adapter(instance);
6690 6690 return;
6691 6691 }
6692 6692 }
6693 6693 }
6694 6694 con_log(CL_ANN, (CE_NOTE, "mrsas: "
6695 6695 "schedule next timeout check: "
6696 6696 "do timeout \n"));
6697 6697 instance->timeout_id =
6698 6698 timeout(io_timeout_checker, (void *)instance,
6699 6699 drv_usectohz(MRSAS_1_SECOND));
6700 6700 }
6701 6701
6702 6702 static uint32_t
6703 6703 read_fw_status_reg_ppc(struct mrsas_instance *instance)
6704 6704 {
6705 6705 return ((uint32_t)RD_OB_SCRATCH_PAD_0(instance));
6706 6706 }
6707 6707
6708 6708 static void
6709 6709 issue_cmd_ppc(struct mrsas_cmd *cmd, struct mrsas_instance *instance)
6710 6710 {
6711 6711 struct scsi_pkt *pkt;
6712 6712 atomic_inc_16(&instance->fw_outstanding);
6713 6713
6714 6714 pkt = cmd->pkt;
6715 6715 if (pkt) {
6716 6716 con_log(CL_DLEVEL1, (CE_NOTE, "%llx : issue_cmd_ppc:"
6717 6717 "ISSUED CMD TO FW : called : cmd:"
6718 6718 ": %p instance : %p pkt : %p pkt_time : %x\n",
6719 6719 gethrtime(), (void *)cmd, (void *)instance,
6720 6720 (void *)pkt, cmd->drv_pkt_time));
6721 6721 if (instance->adapterresetinprogress) {
6722 6722 cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
6723 6723 con_log(CL_ANN1, (CE_NOTE, "Reset the scsi_pkt timer"));
6724 6724 } else {
6725 6725 push_pending_mfi_pkt(instance, cmd);
6726 6726 }
6727 6727
6728 6728 } else {
6729 6729 con_log(CL_DLEVEL1, (CE_NOTE, "%llx : issue_cmd_ppc:"
6730 6730 "ISSUED CMD TO FW : called : cmd : %p, instance: %p"
6731 6731 "(NO PKT)\n", gethrtime(), (void *)cmd, (void *)instance));
6732 6732 }
6733 6733
6734 6734 mutex_enter(&instance->reg_write_mtx);
6735 6735 /* Issue the command to the FW */
6736 6736 WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
6737 6737 (((cmd->frame_count - 1) << 1) | 1), instance);
6738 6738 mutex_exit(&instance->reg_write_mtx);
6739 6739
6740 6740 }
6741 6741
6742 6742 /*
6743 6743 * issue_cmd_in_sync_mode
6744 6744 */
6745 6745 static int
6746 6746 issue_cmd_in_sync_mode_ppc(struct mrsas_instance *instance,
6747 6747 struct mrsas_cmd *cmd)
6748 6748 {
6749 6749 int i;
6750 6750 uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
6751 6751 struct mrsas_header *hdr = &cmd->frame->hdr;
6752 6752
6753 6753 con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called"));
6754 6754
6755 6755 if (instance->adapterresetinprogress) {
6756 6756 cmd->drv_pkt_time = ddi_get16(
6757 6757 cmd->frame_dma_obj.acc_handle, &hdr->timeout);
6758 6758 if (cmd->drv_pkt_time < debug_timeout_g)
6759 6759 cmd->drv_pkt_time = (uint16_t)debug_timeout_g;
6760 6760
6761 6761 con_log(CL_ANN1, (CE_NOTE, "sync_mode_ppc: "
6762 6762 "issue and return in reset case\n"));
6763 6763 WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
6764 6764 (((cmd->frame_count - 1) << 1) | 1), instance);
6765 6765
6766 6766 return (DDI_SUCCESS);
6767 6767 } else {
6768 6768 con_log(CL_ANN1, (CE_NOTE, "sync_mode_ppc: pushing the pkt\n"));
6769 6769 push_pending_mfi_pkt(instance, cmd);
6770 6770 }
6771 6771
6772 6772 cmd->cmd_status = ENODATA;
6773 6773
6774 6774 mutex_enter(&instance->reg_write_mtx);
6775 6775 /* Issue the command to the FW */
6776 6776 WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
6777 6777 (((cmd->frame_count - 1) << 1) | 1), instance);
6778 6778 mutex_exit(&instance->reg_write_mtx);
6779 6779
6780 6780 mutex_enter(&instance->int_cmd_mtx);
6781 6781 for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) {
6782 6782 cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx);
6783 6783 }
6784 6784 mutex_exit(&instance->int_cmd_mtx);
6785 6785
6786 6786 con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: done"));
6787 6787
6788 6788 if (i < (msecs -1)) {
6789 6789 return (DDI_SUCCESS);
6790 6790 } else {
6791 6791 return (DDI_FAILURE);
6792 6792 }
6793 6793 }
6794 6794
6795 6795 /*
6796 6796 * issue_cmd_in_poll_mode
6797 6797 */
6798 6798 static int
6799 6799 issue_cmd_in_poll_mode_ppc(struct mrsas_instance *instance,
6800 6800 struct mrsas_cmd *cmd)
6801 6801 {
6802 6802 int i;
6803 6803 uint16_t flags;
6804 6804 uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC;
6805 6805 struct mrsas_header *frame_hdr;
6806 6806
6807 6807 con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode_ppc: called"));
6808 6808
6809 6809 frame_hdr = (struct mrsas_header *)cmd->frame;
6810 6810 ddi_put8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status,
6811 6811 MFI_CMD_STATUS_POLL_MODE);
6812 6812 flags = ddi_get16(cmd->frame_dma_obj.acc_handle, &frame_hdr->flags);
6813 6813 flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
6814 6814
6815 6815 ddi_put16(cmd->frame_dma_obj.acc_handle, &frame_hdr->flags, flags);
6816 6816
6817 6817 /* issue the frame using inbound queue port */
6818 6818 WR_IB_PICK_QPORT((cmd->frame_phys_addr) |
6819 6819 (((cmd->frame_count - 1) << 1) | 1), instance);
6820 6820
6821 6821 /* wait for cmd_status to change from 0xFF */
6822 6822 for (i = 0; i < msecs && (
6823 6823 ddi_get8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status)
6824 6824 == MFI_CMD_STATUS_POLL_MODE); i++) {
6825 6825 drv_usecwait(MILLISEC); /* wait for 1000 usecs */
6826 6826 }
6827 6827
6828 6828 if (ddi_get8(cmd->frame_dma_obj.acc_handle, &frame_hdr->cmd_status)
6829 6829 == MFI_CMD_STATUS_POLL_MODE) {
6830 6830 con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: "
6831 6831 "cmd polling timed out"));
6832 6832 return (DDI_FAILURE);
6833 6833 }
6834 6834
6835 6835 return (DDI_SUCCESS);
6836 6836 }
6837 6837
6838 6838 static void
6839 6839 enable_intr_ppc(struct mrsas_instance *instance)
6840 6840 {
6841 6841 uint32_t mask;
6842 6842
6843 6843 con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called"));
6844 6844
6845 6845 if (instance->skinny) {
6846 6846 /* For SKINNY, write ~0x1, from BSD's mfi driver. */
6847 6847 WR_OB_INTR_MASK(0xfffffffe, instance);
6848 6848 } else {
6849 6849 /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */
6850 6850 WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance);
6851 6851
6852 6852 /* WR_OB_INTR_MASK(~0x80000000, instance); */
6853 6853 WR_OB_INTR_MASK(~(MFI_REPLY_2108_MESSAGE_INTR_MASK), instance);
6854 6854 }
6855 6855
6856 6856 /* dummy read to force PCI flush */
6857 6857 mask = RD_OB_INTR_MASK(instance);
6858 6858
6859 6859 con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: "
6860 6860 "outbound_intr_mask = 0x%x", mask));
6861 6861 }
6862 6862
6863 6863 static void
6864 6864 disable_intr_ppc(struct mrsas_instance *instance)
6865 6865 {
6866 6866 uint32_t mask;
6867 6867
6868 6868 con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called"));
6869 6869
6870 6870 con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : "
6871 6871 "outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
6872 6872
6873 6873 /* For now, assume there are no extras needed for Skinny support. */
6874 6874
6875 6875 WR_OB_INTR_MASK(OB_INTR_MASK, instance);
6876 6876
6877 6877 con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : "
6878 6878 "outbound_intr_mask = 0x%x", RD_OB_INTR_MASK(instance)));
6879 6879
6880 6880 /* dummy read to force PCI flush */
6881 6881 mask = RD_OB_INTR_MASK(instance);
6882 6882 #ifdef lint
6883 6883 mask = mask;
6884 6884 #endif
6885 6885 }
6886 6886
6887 6887 static int
6888 6888 intr_ack_ppc(struct mrsas_instance *instance)
6889 6889 {
6890 6890 uint32_t status;
6891 6891 int ret = DDI_INTR_CLAIMED;
6892 6892
6893 6893 con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: called"));
6894 6894
6895 6895 /* check if it is our interrupt */
6896 6896 status = RD_OB_INTR_STATUS(instance);
6897 6897
6898 6898 con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x", status));
6899 6899
6900 6900 /*
6901 6901 * NOTE: Some drivers call out SKINNY here, but the return is the same
6902 6902 * for SKINNY and 2108.
6903 6903 */
6904 6904 if (!(status & MFI_REPLY_2108_MESSAGE_INTR)) {
6905 6905 ret = DDI_INTR_UNCLAIMED;
6906 6906 }
6907 6907
6908 6908 if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
6909 6909 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST);
6910 6910 ret = DDI_INTR_UNCLAIMED;
6911 6911 }
6912 6912
6913 6913 if (ret == DDI_INTR_UNCLAIMED) {
6914 6914 return (ret);
6915 6915 }
6916 6916
6917 6917 /*
6918 6918 * Clear the interrupt by writing back the same value.
6919 6919 * Another case where SKINNY is slightly different.
6920 6920 */
6921 6921 if (instance->skinny) {
6922 6922 WR_OB_INTR_STATUS(status, instance);
6923 6923 } else {
6924 6924 WR_OB_DOORBELL_CLEAR(status, instance);
6925 6925 }
6926 6926
6927 6927 /* dummy READ */
6928 6928 status = RD_OB_INTR_STATUS(instance);
6929 6929
6930 6930 con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared"));
6931 6931
6932 6932 return (ret);
6933 6933 }
6934 6934
6935 6935 /*
6936 6936 * Marks HBA as bad. This will be called either when an
6937 6937 * IO packet times out even after 3 FW resets
6938 6938 * or FW is found to be fault even after 3 continuous resets.
6939 6939 */
6940 6940
6941 6941 static int
6942 6942 mrsas_kill_adapter(struct mrsas_instance *instance)
6943 6943 {
6944 6944 if (instance->deadadapter == 1)
6945 6945 return (DDI_FAILURE);
6946 6946
6947 6947 con_log(CL_ANN1, (CE_NOTE, "mrsas_kill_adapter: "
6948 6948 "Writing to doorbell with MFI_STOP_ADP "));
6949 6949 mutex_enter(&instance->ocr_flags_mtx);
6950 6950 instance->deadadapter = 1;
6951 6951 mutex_exit(&instance->ocr_flags_mtx);
6952 6952 instance->func_ptr->disable_intr(instance);
6953 6953 WR_IB_DOORBELL(MFI_STOP_ADP, instance);
6954 6954 (void) mrsas_complete_pending_cmds(instance);
6955 6955 return (DDI_SUCCESS);
6956 6956 }
6957 6957
6958 6958
6959 6959 static int
6960 6960 mrsas_reset_ppc(struct mrsas_instance *instance)
6961 6961 {
6962 6962 uint32_t status;
6963 6963 uint32_t retry = 0;
6964 6964 uint32_t cur_abs_reg_val;
6965 6965 uint32_t fw_state;
6966 6966
6967 6967 con_log(CL_ANN, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__));
6968 6968
6969 6969 if (instance->deadadapter == 1) {
6970 6970 dev_err(instance->dip, CE_WARN, "mrsas_reset_ppc: "
6971 6971 "no more resets as HBA has been marked dead ");
6972 6972 return (DDI_FAILURE);
6973 6973 }
6974 6974 mutex_enter(&instance->ocr_flags_mtx);
6975 6975 instance->adapterresetinprogress = 1;
6976 6976 mutex_exit(&instance->ocr_flags_mtx);
6977 6977 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: adpterresetinprogress "
6978 6978 "flag set, time %llx", gethrtime()));
6979 6979
6980 6980 instance->func_ptr->disable_intr(instance);
6981 6981 retry_reset:
6982 6982 WR_IB_WRITE_SEQ(0, instance);
6983 6983 WR_IB_WRITE_SEQ(4, instance);
6984 6984 WR_IB_WRITE_SEQ(0xb, instance);
6985 6985 WR_IB_WRITE_SEQ(2, instance);
6986 6986 WR_IB_WRITE_SEQ(7, instance);
6987 6987 WR_IB_WRITE_SEQ(0xd, instance);
6988 6988 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: magic number written "
6989 6989 "to write sequence register\n"));
6990 6990 delay(100 * drv_usectohz(MILLISEC));
6991 6991 status = RD_OB_DRWE(instance);
6992 6992
6993 6993 while (!(status & DIAG_WRITE_ENABLE)) {
6994 6994 delay(100 * drv_usectohz(MILLISEC));
6995 6995 status = RD_OB_DRWE(instance);
6996 6996 if (retry++ == 100) {
6997 6997 dev_err(instance->dip, CE_WARN,
6998 6998 "mrsas_reset_ppc: DRWE bit "
6999 6999 "check retry count %d", retry);
7000 7000 return (DDI_FAILURE);
7001 7001 }
7002 7002 }
7003 7003 WR_IB_DRWE(status | DIAG_RESET_ADAPTER, instance);
7004 7004 delay(100 * drv_usectohz(MILLISEC));
7005 7005 status = RD_OB_DRWE(instance);
7006 7006 while (status & DIAG_RESET_ADAPTER) {
7007 7007 delay(100 * drv_usectohz(MILLISEC));
7008 7008 status = RD_OB_DRWE(instance);
7009 7009 if (retry++ == 100) {
7010 7010 dev_err(instance->dip, CE_WARN, "mrsas_reset_ppc: "
7011 7011 "RESET FAILED. KILL adapter called.");
7012 7012
7013 7013 (void) mrsas_kill_adapter(instance);
7014 7014 return (DDI_FAILURE);
7015 7015 }
7016 7016 }
7017 7017 con_log(CL_ANN, (CE_NOTE, "mrsas_reset_ppc: Adapter reset complete"));
7018 7018 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7019 7019 "Calling mfi_state_transition_to_ready"));
7020 7020
7021 7021 /* Mark HBA as bad, if FW is fault after 3 continuous resets */
7022 7022 if (mfi_state_transition_to_ready(instance) ||
7023 7023 debug_fw_faults_after_ocr_g == 1) {
7024 7024 cur_abs_reg_val =
7025 7025 instance->func_ptr->read_fw_status_reg(instance);
7026 7026 fw_state = cur_abs_reg_val & MFI_STATE_MASK;
7027 7027
7028 7028 #ifdef OCRDEBUG
7029 7029 con_log(CL_ANN1, (CE_NOTE,
7030 7030 "mrsas_reset_ppc :before fake: FW is not ready "
7031 7031 "FW state = 0x%x", fw_state));
7032 7032 if (debug_fw_faults_after_ocr_g == 1)
7033 7033 fw_state = MFI_STATE_FAULT;
7034 7034 #endif
7035 7035
7036 7036 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc : FW is not ready "
7037 7037 "FW state = 0x%x", fw_state));
7038 7038
7039 7039 if (fw_state == MFI_STATE_FAULT) {
7040 7040 /* increment the count */
7041 7041 instance->fw_fault_count_after_ocr++;
7042 7042 if (instance->fw_fault_count_after_ocr
7043 7043 < MAX_FW_RESET_COUNT) {
7044 7044 dev_err(instance->dip, CE_WARN,
7045 7045 "mrsas_reset_ppc: "
7046 7046 "FW is in fault after OCR count %d "
7047 7047 "Retry Reset",
7048 7048 instance->fw_fault_count_after_ocr);
7049 7049 goto retry_reset;
7050 7050
7051 7051 } else {
7052 7052 dev_err(instance->dip, CE_WARN,
7053 7053 "mrsas_reset_ppc: "
7054 7054 "Max Reset Count exceeded >%d"
7055 7055 "Mark HBA as bad, KILL adapter",
7056 7056 MAX_FW_RESET_COUNT);
7057 7057
7058 7058 (void) mrsas_kill_adapter(instance);
7059 7059 return (DDI_FAILURE);
7060 7060 }
7061 7061 }
7062 7062 }
7063 7063 /* reset the counter as FW is up after OCR */
7064 7064 instance->fw_fault_count_after_ocr = 0;
7065 7065
7066 7066
7067 7067 ddi_put32(instance->mfi_internal_dma_obj.acc_handle,
7068 7068 instance->producer, 0);
7069 7069
7070 7070 ddi_put32(instance->mfi_internal_dma_obj.acc_handle,
7071 7071 instance->consumer, 0);
7072 7072
7073 7073 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7074 7074 " after resetting produconsumer chck indexs:"
7075 7075 "producer %x consumer %x", *instance->producer,
7076 7076 *instance->consumer));
7077 7077
7078 7078 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7079 7079 "Calling mrsas_issue_init_mfi"));
7080 7080 (void) mrsas_issue_init_mfi(instance);
7081 7081 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7082 7082 "mrsas_issue_init_mfi Done"));
7083 7083
7084 7084 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7085 7085 "Calling mrsas_print_pending_cmd\n"));
7086 7086 (void) mrsas_print_pending_cmds(instance);
7087 7087 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7088 7088 "mrsas_print_pending_cmd done\n"));
7089 7089
7090 7090 instance->func_ptr->enable_intr(instance);
7091 7091 instance->fw_outstanding = 0;
7092 7092
7093 7093 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7094 7094 "Calling mrsas_issue_pending_cmds"));
7095 7095 (void) mrsas_issue_pending_cmds(instance);
7096 7096 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7097 7097 "issue_pending_cmds done.\n"));
7098 7098
7099 7099 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7100 7100 "Calling aen registration"));
7101 7101
7102 7102
7103 7103 instance->aen_cmd->retry_count_for_ocr = 0;
7104 7104 instance->aen_cmd->drv_pkt_time = 0;
7105 7105
7106 7106 instance->func_ptr->issue_cmd(instance->aen_cmd, instance);
7107 7107 con_log(CL_ANN1, (CE_NOTE, "Unsetting adpresetinprogress flag.\n"));
7108 7108
7109 7109 mutex_enter(&instance->ocr_flags_mtx);
7110 7110 instance->adapterresetinprogress = 0;
7111 7111 mutex_exit(&instance->ocr_flags_mtx);
7112 7112 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc: "
7113 7113 "adpterresetinprogress flag unset"));
7114 7114
7115 7115 con_log(CL_ANN1, (CE_NOTE, "mrsas_reset_ppc done\n"));
7116 7116 return (DDI_SUCCESS);
7117 7117 }
7118 7118
7119 7119 /*
7120 7120 * FMA functions.
7121 7121 */
7122 7122 int
7123 7123 mrsas_common_check(struct mrsas_instance *instance, struct mrsas_cmd *cmd)
7124 7124 {
7125 7125 int ret = DDI_SUCCESS;
7126 7126
7127 7127 if (cmd != NULL &&
7128 7128 mrsas_check_dma_handle(cmd->frame_dma_obj.dma_handle) !=
7129 7129 DDI_SUCCESS) {
7130 7130 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
7131 7131 if (cmd->pkt != NULL) {
7132 7132 cmd->pkt->pkt_reason = CMD_TRAN_ERR;
7133 7133 cmd->pkt->pkt_statistics = 0;
7134 7134 }
7135 7135 ret = DDI_FAILURE;
7136 7136 }
7137 7137 if (mrsas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle)
7138 7138 != DDI_SUCCESS) {
7139 7139 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
7140 7140 if (cmd != NULL && cmd->pkt != NULL) {
7141 7141 cmd->pkt->pkt_reason = CMD_TRAN_ERR;
7142 7142 cmd->pkt->pkt_statistics = 0;
7143 7143 }
7144 7144 ret = DDI_FAILURE;
7145 7145 }
7146 7146 if (mrsas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) !=
7147 7147 DDI_SUCCESS) {
7148 7148 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
7149 7149 if (cmd != NULL && cmd->pkt != NULL) {
7150 7150 cmd->pkt->pkt_reason = CMD_TRAN_ERR;
7151 7151 cmd->pkt->pkt_statistics = 0;
7152 7152 }
7153 7153 ret = DDI_FAILURE;
7154 7154 }
7155 7155 if (mrsas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) {
7156 7156 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED);
7157 7157
7158 7158 ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0);
7159 7159
7160 7160 if (cmd != NULL && cmd->pkt != NULL) {
7161 7161 cmd->pkt->pkt_reason = CMD_TRAN_ERR;
7162 7162 cmd->pkt->pkt_statistics = 0;
7163 7163 }
7164 7164 ret = DDI_FAILURE;
7165 7165 }
7166 7166
7167 7167 return (ret);
7168 7168 }
7169 7169
7170 7170 /*ARGSUSED*/
7171 7171 static int
7172 7172 mrsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
7173 7173 {
7174 7174 /*
7175 7175 * as the driver can always deal with an error in any dma or
7176 7176 * access handle, we can just return the fme_status value.
7177 7177 */
7178 7178 pci_ereport_post(dip, err, NULL);
7179 7179 return (err->fme_status);
7180 7180 }
7181 7181
7182 7182 static void
7183 7183 mrsas_fm_init(struct mrsas_instance *instance)
7184 7184 {
7185 7185 /* Need to change iblock to priority for new MSI intr */
7186 7186 ddi_iblock_cookie_t fm_ibc;
7187 7187
7188 7188 /* Only register with IO Fault Services if we have some capability */
7189 7189 if (instance->fm_capabilities) {
7190 7190 /* Adjust access and dma attributes for FMA */
7191 7191 endian_attr.devacc_attr_access = DDI_FLAGERR_ACC;
7192 7192 mrsas_generic_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
7193 7193
7194 7194 /*
7195 7195 * Register capabilities with IO Fault Services.
7196 7196 * fm_capabilities will be updated to indicate
7197 7197 * capabilities actually supported (not requested.)
7198 7198 */
7199 7199
7200 7200 ddi_fm_init(instance->dip, &instance->fm_capabilities, &fm_ibc);
7201 7201
7202 7202 /*
7203 7203 * Initialize pci ereport capabilities if ereport
7204 7204 * capable (should always be.)
7205 7205 */
7206 7206
7207 7207 if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
7208 7208 DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
7209 7209 pci_ereport_setup(instance->dip);
7210 7210 }
7211 7211
7212 7212 /*
7213 7213 * Register error callback if error callback capable.
7214 7214 */
7215 7215 if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
7216 7216 ddi_fm_handler_register(instance->dip,
7217 7217 mrsas_fm_error_cb, (void*) instance);
7218 7218 }
7219 7219 } else {
7220 7220 endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
7221 7221 mrsas_generic_dma_attr.dma_attr_flags = 0;
7222 7222 }
7223 7223 }
7224 7224
7225 7225 static void
7226 7226 mrsas_fm_fini(struct mrsas_instance *instance)
7227 7227 {
7228 7228 /* Only unregister FMA capabilities if registered */
7229 7229 if (instance->fm_capabilities) {
7230 7230 /*
7231 7231 * Un-register error callback if error callback capable.
7232 7232 */
7233 7233 if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
7234 7234 ddi_fm_handler_unregister(instance->dip);
7235 7235 }
7236 7236
7237 7237 /*
7238 7238 * Release any resources allocated by pci_ereport_setup()
7239 7239 */
7240 7240 if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) ||
7241 7241 DDI_FM_ERRCB_CAP(instance->fm_capabilities)) {
7242 7242 pci_ereport_teardown(instance->dip);
7243 7243 }
7244 7244
7245 7245 /* Unregister from IO Fault Services */
7246 7246 ddi_fm_fini(instance->dip);
7247 7247
7248 7248 /* Adjust access and dma attributes for FMA */
7249 7249 endian_attr.devacc_attr_access = DDI_DEFAULT_ACC;
7250 7250 mrsas_generic_dma_attr.dma_attr_flags = 0;
7251 7251 }
7252 7252 }
7253 7253
7254 7254 int
7255 7255 mrsas_check_acc_handle(ddi_acc_handle_t handle)
7256 7256 {
7257 7257 ddi_fm_error_t de;
7258 7258
7259 7259 if (handle == NULL) {
7260 7260 return (DDI_FAILURE);
7261 7261 }
7262 7262
7263 7263 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
7264 7264
7265 7265 return (de.fme_status);
7266 7266 }
7267 7267
7268 7268 int
7269 7269 mrsas_check_dma_handle(ddi_dma_handle_t handle)
7270 7270 {
7271 7271 ddi_fm_error_t de;
7272 7272
7273 7273 if (handle == NULL) {
7274 7274 return (DDI_FAILURE);
7275 7275 }
7276 7276
7277 7277 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
7278 7278
7279 7279 return (de.fme_status);
7280 7280 }
7281 7281
7282 7282 void
7283 7283 mrsas_fm_ereport(struct mrsas_instance *instance, char *detail)
7284 7284 {
7285 7285 uint64_t ena;
7286 7286 char buf[FM_MAX_CLASS];
7287 7287
7288 7288 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
7289 7289 ena = fm_ena_generate(0, FM_ENA_FMT1);
7290 7290 if (DDI_FM_EREPORT_CAP(instance->fm_capabilities)) {
7291 7291 ddi_fm_ereport_post(instance->dip, buf, ena, DDI_NOSLEEP,
7292 7292 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION, NULL);
7293 7293 }
7294 7294 }
7295 7295
7296 7296 static int
7297 7297 mrsas_add_intrs(struct mrsas_instance *instance, int intr_type)
7298 7298 {
7299 7299
7300 7300 dev_info_t *dip = instance->dip;
7301 7301 int avail, actual, count;
7302 7302 int i, flag, ret;
7303 7303
7304 7304 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: intr_type = %x",
7305 7305 intr_type));
7306 7306
7307 7307 /* Get number of interrupts */
7308 7308 ret = ddi_intr_get_nintrs(dip, intr_type, &count);
7309 7309 if ((ret != DDI_SUCCESS) || (count == 0)) {
7310 7310 con_log(CL_ANN, (CE_WARN, "ddi_intr_get_nintrs() failed:"
7311 7311 "ret %d count %d", ret, count));
7312 7312
7313 7313 return (DDI_FAILURE);
7314 7314 }
7315 7315
7316 7316 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: count = %d ", count));
7317 7317
7318 7318 /* Get number of available interrupts */
7319 7319 ret = ddi_intr_get_navail(dip, intr_type, &avail);
7320 7320 if ((ret != DDI_SUCCESS) || (avail == 0)) {
7321 7321 con_log(CL_ANN, (CE_WARN, "ddi_intr_get_navail() failed:"
7322 7322 "ret %d avail %d", ret, avail));
7323 7323
7324 7324 return (DDI_FAILURE);
7325 7325 }
7326 7326 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: avail = %d ", avail));
7327 7327
7328 7328 /* Only one interrupt routine. So limit the count to 1 */
7329 7329 if (count > 1) {
7330 7330 count = 1;
7331 7331 }
7332 7332
7333 7333 /*
7334 7334 * Allocate an array of interrupt handlers. Currently we support
7335 7335 * only one interrupt. The framework can be extended later.
7336 7336 */
7337 7337 instance->intr_htable_size = count * sizeof (ddi_intr_handle_t);
7338 7338 instance->intr_htable = kmem_zalloc(instance->intr_htable_size,
7339 7339 KM_SLEEP);
7340 7340 ASSERT(instance->intr_htable);
7341 7341
7342 7342 flag = ((intr_type == DDI_INTR_TYPE_MSI) ||
7343 7343 (intr_type == DDI_INTR_TYPE_MSIX)) ?
7344 7344 DDI_INTR_ALLOC_STRICT : DDI_INTR_ALLOC_NORMAL;
7345 7345
7346 7346 /* Allocate interrupt */
7347 7347 ret = ddi_intr_alloc(dip, instance->intr_htable, intr_type, 0,
7348 7348 count, &actual, flag);
7349 7349
7350 7350 if ((ret != DDI_SUCCESS) || (actual == 0)) {
7351 7351 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
7352 7352 "avail = %d", avail));
7353 7353 goto mrsas_free_htable;
7354 7354 }
7355 7355
7356 7356 if (actual < count) {
7357 7357 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
7358 7358 "Requested = %d Received = %d", count, actual));
7359 7359 }
7360 7360 instance->intr_cnt = actual;
7361 7361
7362 7362 /*
7363 7363 * Get the priority of the interrupt allocated.
7364 7364 */
7365 7365 if ((ret = ddi_intr_get_pri(instance->intr_htable[0],
7366 7366 &instance->intr_pri)) != DDI_SUCCESS) {
7367 7367 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
7368 7368 "get priority call failed"));
7369 7369 goto mrsas_free_handles;
7370 7370 }
7371 7371
7372 7372 /*
7373 7373 * Test for high level mutex. we don't support them.
7374 7374 */
7375 7375 if (instance->intr_pri >= ddi_intr_get_hilevel_pri()) {
7376 7376 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs: "
7377 7377 "High level interrupts not supported."));
7378 7378 goto mrsas_free_handles;
7379 7379 }
7380 7380
7381 7381 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_add_intrs: intr_pri = 0x%x ",
7382 7382 instance->intr_pri));
7383 7383
7384 7384 /* Call ddi_intr_add_handler() */
7385 7385 for (i = 0; i < actual; i++) {
7386 7386 ret = ddi_intr_add_handler(instance->intr_htable[i],
7387 7387 (ddi_intr_handler_t *)mrsas_isr, (caddr_t)instance,
7388 7388 (caddr_t)(uintptr_t)i);
7389 7389
7390 7390 if (ret != DDI_SUCCESS) {
7391 7391 con_log(CL_ANN, (CE_WARN, "mrsas_add_intrs:"
7392 7392 "failed %d", ret));
7393 7393 goto mrsas_free_handles;
7394 7394 }
7395 7395
7396 7396 }
7397 7397
7398 7398 con_log(CL_DLEVEL1, (CE_NOTE, " ddi_intr_add_handler done"));
7399 7399
7400 7400 if ((ret = ddi_intr_get_cap(instance->intr_htable[0],
7401 7401 &instance->intr_cap)) != DDI_SUCCESS) {
7402 7402 con_log(CL_ANN, (CE_WARN, "ddi_intr_get_cap() failed %d",
7403 7403 ret));
7404 7404 goto mrsas_free_handlers;
7405 7405 }
7406 7406
7407 7407 if (instance->intr_cap & DDI_INTR_FLAG_BLOCK) {
7408 7408 con_log(CL_ANN, (CE_WARN, "Calling ddi_intr_block _enable"));
7409 7409
7410 7410 (void) ddi_intr_block_enable(instance->intr_htable,
7411 7411 instance->intr_cnt);
7412 7412 } else {
7413 7413 con_log(CL_ANN, (CE_NOTE, " calling ddi_intr_enable"));
7414 7414
7415 7415 for (i = 0; i < instance->intr_cnt; i++) {
7416 7416 (void) ddi_intr_enable(instance->intr_htable[i]);
7417 7417 con_log(CL_ANN, (CE_NOTE, "ddi intr enable returns "
7418 7418 "%d", i));
7419 7419 }
7420 7420 }
7421 7421
7422 7422 return (DDI_SUCCESS);
7423 7423
7424 7424 mrsas_free_handlers:
7425 7425 for (i = 0; i < actual; i++)
7426 7426 (void) ddi_intr_remove_handler(instance->intr_htable[i]);
7427 7427
7428 7428 mrsas_free_handles:
7429 7429 for (i = 0; i < actual; i++)
7430 7430 (void) ddi_intr_free(instance->intr_htable[i]);
7431 7431
7432 7432 mrsas_free_htable:
7433 7433 if (instance->intr_htable != NULL)
7434 7434 kmem_free(instance->intr_htable, instance->intr_htable_size);
7435 7435
7436 7436 instance->intr_htable = NULL;
7437 7437 instance->intr_htable_size = 0;
7438 7438
7439 7439 return (DDI_FAILURE);
7440 7440
7441 7441 }
7442 7442
7443 7443
7444 7444 static void
7445 7445 mrsas_rem_intrs(struct mrsas_instance *instance)
7446 7446 {
7447 7447 int i;
7448 7448
7449 7449 con_log(CL_ANN, (CE_NOTE, "mrsas_rem_intrs called"));
7450 7450
7451 7451 /* Disable all interrupts first */
7452 7452 if (instance->intr_cap & DDI_INTR_FLAG_BLOCK) {
7453 7453 (void) ddi_intr_block_disable(instance->intr_htable,
7454 7454 instance->intr_cnt);
7455 7455 } else {
7456 7456 for (i = 0; i < instance->intr_cnt; i++) {
7457 7457 (void) ddi_intr_disable(instance->intr_htable[i]);
7458 7458 }
7459 7459 }
7460 7460
7461 7461 /* Remove all the handlers */
7462 7462
7463 7463 for (i = 0; i < instance->intr_cnt; i++) {
7464 7464 (void) ddi_intr_remove_handler(instance->intr_htable[i]);
7465 7465 (void) ddi_intr_free(instance->intr_htable[i]);
7466 7466 }
7467 7467
7468 7468 if (instance->intr_htable != NULL)
7469 7469 kmem_free(instance->intr_htable, instance->intr_htable_size);
7470 7470
7471 7471 instance->intr_htable = NULL;
7472 7472 instance->intr_htable_size = 0;
7473 7473
7474 7474 }
7475 7475
7476 7476 static int
7477 7477 mrsas_tran_bus_config(dev_info_t *parent, uint_t flags,
7478 7478 ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
7479 7479 {
7480 7480 struct mrsas_instance *instance;
7481 7481 int config;
7482 7482 int rval = NDI_SUCCESS;
7483 7483
7484 7484 char *ptr = NULL;
7485 7485 int tgt, lun;
7486 7486
7487 7487 con_log(CL_ANN1, (CE_NOTE, "Bus config called for op = %x", op));
7488 7488
7489 7489 if ((instance = ddi_get_soft_state(mrsas_state,
7490 7490 ddi_get_instance(parent))) == NULL) {
7491 7491 return (NDI_FAILURE);
7492 7492 }
7493 7493
7494 7494 /* Hold nexus during bus_config */
7495 7495 ndi_devi_enter(parent, &config);
7496 7496 switch (op) {
7497 7497 case BUS_CONFIG_ONE: {
7498 7498
7499 7499 /* parse wwid/target name out of name given */
7500 7500 if ((ptr = strchr((char *)arg, '@')) == NULL) {
7501 7501 rval = NDI_FAILURE;
7502 7502 break;
7503 7503 }
7504 7504 ptr++;
7505 7505
7506 7506 if (mrsas_parse_devname(arg, &tgt, &lun) != 0) {
7507 7507 rval = NDI_FAILURE;
7508 7508 break;
7509 7509 }
7510 7510
7511 7511 if (lun == 0) {
7512 7512 rval = mrsas_config_ld(instance, tgt, lun, childp);
7513 7513 #ifdef PDSUPPORT
7514 7514 } else if ((instance->tbolt || instance->skinny) && lun != 0) {
7515 7515 rval = mrsas_tbolt_config_pd(instance,
7516 7516 tgt, lun, childp);
7517 7517 #endif
7518 7518 } else {
7519 7519 rval = NDI_FAILURE;
7520 7520 }
7521 7521
7522 7522 break;
7523 7523 }
7524 7524 case BUS_CONFIG_DRIVER:
7525 7525 case BUS_CONFIG_ALL: {
7526 7526
7527 7527 rval = mrsas_config_all_devices(instance);
7528 7528
7529 7529 rval = NDI_SUCCESS;
7530 7530 break;
7531 7531 }
7532 7532 }
7533 7533
7534 7534 if (rval == NDI_SUCCESS) {
7535 7535 rval = ndi_busop_bus_config(parent, flags, op, arg, childp, 0);
7536 7536
7537 7537 }
7538 7538 ndi_devi_exit(parent, config);
7539 7539
7540 7540 con_log(CL_ANN1, (CE_NOTE, "mrsas_tran_bus_config: rval = %x",
7541 7541 rval));
7542 7542 return (rval);
7543 7543 }
7544 7544
7545 7545 static int
7546 7546 mrsas_config_all_devices(struct mrsas_instance *instance)
7547 7547 {
7548 7548 int rval, tgt;
7549 7549
7550 7550 for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
7551 7551 (void) mrsas_config_ld(instance, tgt, 0, NULL);
7552 7552
7553 7553 }
7554 7554
7555 7555 #ifdef PDSUPPORT
7556 7556 /* Config PD devices connected to the card */
7557 7557 if (instance->tbolt || instance->skinny) {
7558 7558 for (tgt = 0; tgt < instance->mr_tbolt_pd_max; tgt++) {
7559 7559 (void) mrsas_tbolt_config_pd(instance, tgt, 1, NULL);
7560 7560 }
7561 7561 }
7562 7562 #endif
7563 7563
7564 7564 rval = NDI_SUCCESS;
7565 7565 return (rval);
7566 7566 }
7567 7567
7568 7568 static int
7569 7569 mrsas_parse_devname(char *devnm, int *tgt, int *lun)
7570 7570 {
7571 7571 char devbuf[SCSI_MAXNAMELEN];
7572 7572 char *addr;
7573 7573 char *p, *tp, *lp;
7574 7574 long num;
7575 7575
7576 7576 /* Parse dev name and address */
7577 7577 (void) strcpy(devbuf, devnm);
7578 7578 addr = "";
7579 7579 for (p = devbuf; *p != '\0'; p++) {
7580 7580 if (*p == '@') {
7581 7581 addr = p + 1;
7582 7582 *p = '\0';
7583 7583 } else if (*p == ':') {
7584 7584 *p = '\0';
7585 7585 break;
7586 7586 }
7587 7587 }
7588 7588
7589 7589 /* Parse target and lun */
7590 7590 for (p = tp = addr, lp = NULL; *p != '\0'; p++) {
7591 7591 if (*p == ',') {
7592 7592 lp = p + 1;
7593 7593 *p = '\0';
7594 7594 break;
7595 7595 }
7596 7596 }
7597 7597 if (tgt && tp) {
7598 7598 if (ddi_strtol(tp, NULL, 0x10, &num)) {
7599 7599 return (DDI_FAILURE); /* Can declare this as constant */
7600 7600 }
7601 7601 *tgt = (int)num;
7602 7602 }
7603 7603 if (lun && lp) {
7604 7604 if (ddi_strtol(lp, NULL, 0x10, &num)) {
7605 7605 return (DDI_FAILURE);
7606 7606 }
7607 7607 *lun = (int)num;
7608 7608 }
7609 7609 return (DDI_SUCCESS); /* Success case */
7610 7610 }
7611 7611
7612 7612 static int
7613 7613 mrsas_config_ld(struct mrsas_instance *instance, uint16_t tgt,
7614 7614 uint8_t lun, dev_info_t **ldip)
7615 7615 {
7616 7616 struct scsi_device *sd;
7617 7617 dev_info_t *child;
7618 7618 int rval;
7619 7619
7620 7620 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_config_ld: t = %d l = %d",
7621 7621 tgt, lun));
7622 7622
7623 7623 if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
7624 7624 if (ldip) {
7625 7625 *ldip = child;
7626 7626 }
7627 7627 if (instance->mr_ld_list[tgt].flag != MRDRV_TGT_VALID) {
7628 7628 rval = mrsas_service_evt(instance, tgt, 0,
7629 7629 MRSAS_EVT_UNCONFIG_TGT, NULL);
7630 7630 con_log(CL_ANN1, (CE_WARN,
7631 7631 "mr_sas: DELETING STALE ENTRY rval = %d "
7632 7632 "tgt id = %d ", rval, tgt));
7633 7633 return (NDI_FAILURE);
7634 7634 }
7635 7635 return (NDI_SUCCESS);
7636 7636 }
7637 7637
7638 7638 sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
7639 7639 sd->sd_address.a_hba_tran = instance->tran;
7640 7640 sd->sd_address.a_target = (uint16_t)tgt;
7641 7641 sd->sd_address.a_lun = (uint8_t)lun;
7642 7642
7643 7643 if (scsi_hba_probe(sd, NULL) == SCSIPROBE_EXISTS)
7644 7644 rval = mrsas_config_scsi_device(instance, sd, ldip);
7645 7645 else
7646 7646 rval = NDI_FAILURE;
7647 7647
7648 7648 /* sd_unprobe is blank now. Free buffer manually */
7649 7649 if (sd->sd_inq) {
7650 7650 kmem_free(sd->sd_inq, SUN_INQSIZE);
7651 7651 sd->sd_inq = (struct scsi_inquiry *)NULL;
7652 7652 }
7653 7653
7654 7654 kmem_free(sd, sizeof (struct scsi_device));
7655 7655 con_log(CL_DLEVEL1, (CE_NOTE, "mrsas_config_ld: return rval = %d",
7656 7656 rval));
7657 7657 return (rval);
7658 7658 }
7659 7659
7660 7660 int
7661 7661 mrsas_config_scsi_device(struct mrsas_instance *instance,
7662 7662 struct scsi_device *sd, dev_info_t **dipp)
7663 7663 {
7664 7664 char *nodename = NULL;
7665 7665 char **compatible = NULL;
7666 7666 int ncompatible = 0;
7667 7667 char *childname;
7668 7668 dev_info_t *ldip = NULL;
7669 7669 int tgt = sd->sd_address.a_target;
7670 7670 int lun = sd->sd_address.a_lun;
7671 7671 int dtype = sd->sd_inq->inq_dtype & DTYPE_MASK;
7672 7672 int rval;
7673 7673
7674 7674 con_log(CL_DLEVEL1, (CE_NOTE, "mr_sas: scsi_device t%dL%d", tgt, lun));
7675 7675 scsi_hba_nodename_compatible_get(sd->sd_inq, NULL, dtype,
7676 7676 NULL, &nodename, &compatible, &ncompatible);
7677 7677
7678 7678 if (nodename == NULL) {
7679 7679 con_log(CL_ANN1, (CE_WARN, "mr_sas: Found no compatible driver "
7680 7680 "for t%dL%d", tgt, lun));
7681 7681 rval = NDI_FAILURE;
7682 7682 goto finish;
7683 7683 }
7684 7684
7685 7685 childname = (dtype == DTYPE_DIRECT) ? "sd" : nodename;
7686 7686 con_log(CL_DLEVEL1, (CE_NOTE,
7687 7687 "mr_sas: Childname = %2s nodename = %s", childname, nodename));
7688 7688
7689 7689 /* Create a dev node */
7690 7690 rval = ndi_devi_alloc(instance->dip, childname, DEVI_SID_NODEID, &ldip);
7691 7691 con_log(CL_DLEVEL1, (CE_NOTE,
7692 7692 "mr_sas_config_scsi_device: ndi_devi_alloc rval = %x", rval));
7693 7693 if (rval == NDI_SUCCESS) {
7694 7694 if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "target", tgt) !=
7695 7695 DDI_PROP_SUCCESS) {
7696 7696 con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "
7697 7697 "property for t%dl%d target", tgt, lun));
7698 7698 rval = NDI_FAILURE;
7699 7699 goto finish;
7700 7700 }
7701 7701 if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "lun", lun) !=
7702 7702 DDI_PROP_SUCCESS) {
7703 7703 con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "
7704 7704 "property for t%dl%d lun", tgt, lun));
7705 7705 rval = NDI_FAILURE;
7706 7706 goto finish;
7707 7707 }
7708 7708
7709 7709 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, ldip,
7710 7710 "compatible", compatible, ncompatible) !=
7711 7711 DDI_PROP_SUCCESS) {
7712 7712 con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to create "
7713 7713 "property for t%dl%d compatible", tgt, lun));
7714 7714 rval = NDI_FAILURE;
7715 7715 goto finish;
7716 7716 }
7717 7717
7718 7718 rval = ndi_devi_online(ldip, NDI_ONLINE_ATTACH);
7719 7719 if (rval != NDI_SUCCESS) {
7720 7720 con_log(CL_ANN1, (CE_WARN, "mr_sas: unable to online "
7721 7721 "t%dl%d", tgt, lun));
7722 7722 ndi_prop_remove_all(ldip);
7723 7723 (void) ndi_devi_free(ldip);
7724 7724 } else {
7725 7725 con_log(CL_ANN1, (CE_CONT, "mr_sas: online Done :"
7726 7726 "0 t%dl%d", tgt, lun));
7727 7727 }
7728 7728
7729 7729 }
7730 7730 finish:
7731 7731 if (dipp) {
7732 7732 *dipp = ldip;
7733 7733 }
7734 7734
7735 7735 con_log(CL_DLEVEL1, (CE_NOTE,
7736 7736 "mr_sas: config_scsi_device rval = %d t%dL%d",
7737 7737 rval, tgt, lun));
7738 7738 scsi_hba_nodename_compatible_free(nodename, compatible);
7739 7739 return (rval);
7740 7740 }
7741 7741
7742 7742 /*ARGSUSED*/
7743 7743 int
7744 7744 mrsas_service_evt(struct mrsas_instance *instance, int tgt, int lun, int event,
7745 7745 uint64_t wwn)
7746 7746 {
7747 7747 struct mrsas_eventinfo *mrevt = NULL;
7748 7748
7749 7749 con_log(CL_ANN1, (CE_NOTE,
7750 7750 "mrsas_service_evt called for t%dl%d event = %d",
7751 7751 tgt, lun, event));
7752 7752
7753 7753 if ((instance->taskq == NULL) || (mrevt =
7754 7754 kmem_zalloc(sizeof (struct mrsas_eventinfo), KM_NOSLEEP)) == NULL) {
7755 7755 return (ENOMEM);
7756 7756 }
7757 7757
7758 7758 mrevt->instance = instance;
7759 7759 mrevt->tgt = tgt;
7760 7760 mrevt->lun = lun;
7761 7761 mrevt->event = event;
7762 7762 mrevt->wwn = wwn;
7763 7763
7764 7764 if ((ddi_taskq_dispatch(instance->taskq,
7765 7765 (void (*)(void *))mrsas_issue_evt_taskq, mrevt, DDI_NOSLEEP)) !=
7766 7766 DDI_SUCCESS) {
7767 7767 con_log(CL_ANN1, (CE_NOTE,
7768 7768 "mr_sas: Event task failed for t%dl%d event = %d",
7769 7769 tgt, lun, event));
7770 7770 kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
7771 7771 return (DDI_FAILURE);
7772 7772 }
7773 7773 DTRACE_PROBE3(service_evt, int, tgt, int, lun, int, event);
7774 7774 return (DDI_SUCCESS);
7775 7775 }
7776 7776
7777 7777 static void
7778 7778 mrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt)
7779 7779 {
7780 7780 struct mrsas_instance *instance = mrevt->instance;
7781 7781 dev_info_t *dip, *pdip;
7782 7782 int circ1 = 0;
7783 7783 char *devname;
7784 7784
7785 7785 con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_evt_taskq: called for"
7786 7786 " tgt %d lun %d event %d",
7787 7787 mrevt->tgt, mrevt->lun, mrevt->event));
7788 7788
7789 7789 if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) {
7790 7790 mutex_enter(&instance->config_dev_mtx);
7791 7791 dip = instance->mr_ld_list[mrevt->tgt].dip;
7792 7792 mutex_exit(&instance->config_dev_mtx);
7793 7793 #ifdef PDSUPPORT
7794 7794 } else {
7795 7795 mutex_enter(&instance->config_dev_mtx);
7796 7796 dip = instance->mr_tbolt_pd_list[mrevt->tgt].dip;
7797 7797 mutex_exit(&instance->config_dev_mtx);
7798 7798 #endif
7799 7799 }
7800 7800
7801 7801
7802 7802 ndi_devi_enter(instance->dip, &circ1);
7803 7803 switch (mrevt->event) {
7804 7804 case MRSAS_EVT_CONFIG_TGT:
7805 7805 if (dip == NULL) {
7806 7806
7807 7807 if (mrevt->lun == 0) {
7808 7808 (void) mrsas_config_ld(instance, mrevt->tgt,
7809 7809 0, NULL);
7810 7810 #ifdef PDSUPPORT
7811 7811 } else if (instance->tbolt || instance->skinny) {
7812 7812 (void) mrsas_tbolt_config_pd(instance,
7813 7813 mrevt->tgt,
7814 7814 1, NULL);
7815 7815 #endif
7816 7816 }
7817 7817 con_log(CL_ANN1, (CE_NOTE,
7818 7818 "mr_sas: EVT_CONFIG_TGT called:"
7819 7819 " for tgt %d lun %d event %d",
7820 7820 mrevt->tgt, mrevt->lun, mrevt->event));
7821 7821
7822 7822 } else {
7823 7823 con_log(CL_ANN1, (CE_NOTE,
7824 7824 "mr_sas: EVT_CONFIG_TGT dip != NULL:"
7825 7825 " for tgt %d lun %d event %d",
7826 7826 mrevt->tgt, mrevt->lun, mrevt->event));
7827 7827 }
7828 7828 break;
7829 7829 case MRSAS_EVT_UNCONFIG_TGT:
7830 7830 if (dip) {
7831 7831 if (i_ddi_devi_attached(dip)) {
7832 7832
7833 7833 pdip = ddi_get_parent(dip);
7834 7834
7835 7835 devname = kmem_zalloc(MAXNAMELEN + 1, KM_SLEEP);
7836 7836 (void) ddi_deviname(dip, devname);
7837 7837
7838 7838 (void) devfs_clean(pdip, devname + 1,
7839 7839 DV_CLEAN_FORCE);
7840 7840 kmem_free(devname, MAXNAMELEN + 1);
7841 7841 }
7842 7842 (void) ndi_devi_offline(dip, NDI_DEVI_REMOVE);
7843 7843 con_log(CL_ANN1, (CE_NOTE,
7844 7844 "mr_sas: EVT_UNCONFIG_TGT called:"
7845 7845 " for tgt %d lun %d event %d",
7846 7846 mrevt->tgt, mrevt->lun, mrevt->event));
7847 7847 } else {
7848 7848 con_log(CL_ANN1, (CE_NOTE,
7849 7849 "mr_sas: EVT_UNCONFIG_TGT dip == NULL:"
7850 7850 " for tgt %d lun %d event %d",
7851 7851 mrevt->tgt, mrevt->lun, mrevt->event));
7852 7852 }
7853 7853 break;
7854 7854 }
7855 7855 kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
7856 7856 ndi_devi_exit(instance->dip, circ1);
7857 7857 }
7858 7858
7859 7859
7860 7860 int
7861 7861 mrsas_mode_sense_build(struct scsi_pkt *pkt)
7862 7862 {
7863 7863 union scsi_cdb *cdbp;
7864 7864 uint16_t page_code;
7865 7865 struct scsa_cmd *acmd;
7866 7866 struct buf *bp;
7867 7867 struct mode_header *modehdrp;
7868 7868
7869 7869 cdbp = (void *)pkt->pkt_cdbp;
7870 7870 page_code = cdbp->cdb_un.sg.scsi[0];
7871 7871 acmd = PKT2CMD(pkt);
7872 7872 bp = acmd->cmd_buf;
7873 7873 if ((!bp) && bp->b_un.b_addr && bp->b_bcount && acmd->cmd_dmacount) {
7874 7874 con_log(CL_ANN1, (CE_WARN, "Failing MODESENSE Command"));
7875 7875 /* ADD pkt statistics as Command failed. */
7876 7876 return (NULL);
7877 7877 }
7878 7878
7879 7879 bp_mapin(bp);
7880 7880 bzero(bp->b_un.b_addr, bp->b_bcount);
7881 7881
7882 7882 switch (page_code) {
7883 7883 case 0x3: {
7884 7884 struct mode_format *page3p = NULL;
7885 7885 modehdrp = (struct mode_header *)(bp->b_un.b_addr);
7886 7886 modehdrp->bdesc_length = MODE_BLK_DESC_LENGTH;
7887 7887
7888 7888 page3p = (void *)((caddr_t)modehdrp +
7889 7889 MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
7890 7890 page3p->mode_page.code = 0x3;
7891 7891 page3p->mode_page.length =
7892 7892 (uchar_t)(sizeof (struct mode_format));
7893 7893 page3p->data_bytes_sect = 512;
7894 7894 page3p->sect_track = 63;
7895 7895 break;
7896 7896 }
7897 7897 case 0x4: {
7898 7898 struct mode_geometry *page4p = NULL;
7899 7899 modehdrp = (struct mode_header *)(bp->b_un.b_addr);
7900 7900 modehdrp->bdesc_length = MODE_BLK_DESC_LENGTH;
7901 7901
7902 7902 page4p = (void *)((caddr_t)modehdrp +
7903 7903 MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
7904 7904 page4p->mode_page.code = 0x4;
7905 7905 page4p->mode_page.length =
7906 7906 (uchar_t)(sizeof (struct mode_geometry));
7907 7907 page4p->heads = 255;
7908 7908 page4p->rpm = 10000;
7909 7909 break;
7910 7910 }
7911 7911 default:
7912 7912 break;
7913 7913 }
7914 7914 return (NULL);
7915 7915 }
↓ open down ↓ |
7589 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX