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