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