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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 * 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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