1 /* 2 * megaraid_sas.c: source for mega_sas driver 3 * 4 * MegaRAID device driver for SAS controllers 5 * Copyright (c) 2005-2008, LSI Logic Corporation. 6 * All rights reserved. 7 * 8 * Version: 9 * Author: 10 * Rajesh Prabhakaran<Rajesh.Prabhakaran@lsil.com> 11 * Seokmann Ju 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions are met: 15 * 16 * 1. Redistributions of source code must retain the above copyright notice, 17 * this list of conditions and the following disclaimer. 18 * 19 * 2. Redistributions in binary form must reproduce the above copyright notice, 20 * this list of conditions and the following disclaimer in the documentation 21 * and/or other materials provided with the distribution. 22 * 23 * 3. Neither the name of the author nor the names of its contributors may be 24 * used to endorse or promote products derived from this software without 25 * specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 34 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 35 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 37 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 38 * DAMAGE. 39 */ 40 41 /* 42 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 43 * Use is subject to license terms. 44 */ 45 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/file.h> 49 #include <sys/errno.h> 50 #include <sys/open.h> 51 #include <sys/cred.h> 52 #include <sys/modctl.h> 53 #include <sys/conf.h> 54 #include <sys/devops.h> 55 #include <sys/cmn_err.h> 56 #include <sys/kmem.h> 57 #include <sys/stat.h> 58 #include <sys/mkdev.h> 59 #include <sys/pci.h> 60 #include <sys/scsi/scsi.h> 61 #include <sys/ddi.h> 62 #include <sys/sunddi.h> 63 #include <sys/atomic.h> 64 #include <sys/signal.h> 65 66 #include "megaraid_sas.h" 67 68 /* 69 * FMA header files 70 */ 71 #include <sys/ddifm.h> 72 #include <sys/fm/protocol.h> 73 #include <sys/fm/util.h> 74 #include <sys/fm/io/ddi.h> 75 76 /* 77 * Local static data 78 */ 79 static void *megasas_state = NULL; 80 static int debug_level_g = CL_ANN; 81 82 #pragma weak scsi_hba_open 83 #pragma weak scsi_hba_close 84 #pragma weak scsi_hba_ioctl 85 86 static ddi_dma_attr_t megasas_generic_dma_attr = { 87 DMA_ATTR_V0, /* dma_attr_version */ 88 0, /* low DMA address range */ 89 0xFFFFFFFFU, /* high DMA address range */ 90 0xFFFFFFFFU, /* DMA counter register */ 91 8, /* DMA address alignment */ 92 0x07, /* DMA burstsizes */ 93 1, /* min DMA size */ 94 0xFFFFFFFFU, /* max DMA size */ 95 0xFFFFFFFFU, /* segment boundary */ 96 MEGASAS_MAX_SGE_CNT, /* dma_attr_sglen */ 97 512, /* granularity of device */ 98 0 /* bus specific DMA flags */ 99 }; 100 101 int32_t megasas_max_cap_maxxfer = 0x1000000; 102 103 /* 104 * cb_ops contains base level routines 105 */ 106 static struct cb_ops megasas_cb_ops = { 107 megasas_open, /* open */ 108 megasas_close, /* close */ 109 nodev, /* strategy */ 110 nodev, /* print */ 111 nodev, /* dump */ 112 nodev, /* read */ 113 nodev, /* write */ 114 megasas_ioctl, /* ioctl */ 115 nodev, /* devmap */ 116 nodev, /* mmap */ 117 nodev, /* segmap */ 118 nochpoll, /* poll */ 119 nodev, /* cb_prop_op */ 120 0, /* streamtab */ 121 D_NEW | D_HOTPLUG, /* cb_flag */ 122 CB_REV, /* cb_rev */ 123 nodev, /* cb_aread */ 124 nodev /* cb_awrite */ 125 }; 126 127 /* 128 * dev_ops contains configuration routines 129 */ 130 static struct dev_ops megasas_ops = { 131 DEVO_REV, /* rev, */ 132 0, /* refcnt */ 133 megasas_getinfo, /* getinfo */ 134 nulldev, /* identify */ 135 nulldev, /* probe */ 136 megasas_attach, /* attach */ 137 megasas_detach, /* detach */ 138 megasas_reset, /* reset */ 139 &megasas_cb_ops, /* char/block ops */ 140 NULL, /* bus ops */ 141 NULL, /* power */ 142 ddi_quiesce_not_supported, /* devo_quiesce */ 143 }; 144 145 char _depends_on[] = "misc/scsi"; 146 147 static struct modldrv modldrv = { 148 &mod_driverops, /* module type - driver */ 149 MEGASAS_VERSION, 150 &megasas_ops, /* driver ops */ 151 }; 152 153 static struct modlinkage modlinkage = { 154 MODREV_1, /* ml_rev - must be MODREV_1 */ 155 &modldrv, /* ml_linkage */ 156 NULL /* end of driver linkage */ 157 }; 158 159 static struct ddi_device_acc_attr endian_attr = { 160 DDI_DEVICE_ATTR_V0, 161 DDI_STRUCTURE_LE_ACC, 162 DDI_STRICTORDER_ACC 163 }; 164 165 166 /* 167 * ************************************************************************** * 168 * * 169 * common entry points - for loadable kernel modules * 170 * * 171 * ************************************************************************** * 172 */ 173 174 /* 175 * _init - initialize a loadable module 176 * @void 177 * 178 * The driver should perform any one-time resource allocation or data 179 * initialization during driver loading in _init(). For example, the driver 180 * should initialize any mutexes global to the driver in this routine. 181 * The driver should not, however, use _init() to allocate or initialize 182 * anything that has to do with a particular instance of the device. 183 * Per-instance initialization must be done in attach(). 184 */ 185 int 186 _init(void) 187 { 188 int ret; 189 190 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 191 192 ret = ddi_soft_state_init(&megasas_state, 193 sizeof (struct megasas_instance), 0); 194 195 if (ret != 0) { 196 con_log(CL_ANN, (CE_WARN, "megaraid: could not init state")); 197 return (ret); 198 } 199 200 if ((ret = scsi_hba_init(&modlinkage)) != 0) { 201 con_log(CL_ANN, (CE_WARN, "megaraid: could not init scsi hba")); 202 ddi_soft_state_fini(&megasas_state); 203 return (ret); 204 } 205 206 ret = mod_install(&modlinkage); 207 208 if (ret != 0) { 209 con_log(CL_ANN, (CE_WARN, "megaraid: mod_install failed")); 210 scsi_hba_fini(&modlinkage); 211 ddi_soft_state_fini(&megasas_state); 212 } 213 214 return (ret); 215 } 216 217 /* 218 * _info - returns information about a loadable module. 219 * @void 220 * 221 * _info() is called to return module information. This is a typical entry 222 * point that does predefined role. It simply calls mod_info(). 223 */ 224 int 225 _info(struct modinfo *modinfop) 226 { 227 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 228 229 return (mod_info(&modlinkage, modinfop)); 230 } 231 232 /* 233 * _fini - prepare a loadable module for unloading 234 * @void 235 * 236 * In _fini(), the driver should release any resources that were allocated in 237 * _init(). The driver must remove itself from the system module list. 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)) != 0) 247 return (ret); 248 249 scsi_hba_fini(&modlinkage); 250 251 ddi_soft_state_fini(&megasas_state); 252 253 return (ret); 254 } 255 256 257 /* 258 * ************************************************************************** * 259 * * 260 * common entry points - for autoconfiguration * 261 * * 262 * ************************************************************************** * 263 */ 264 /* 265 * attach - adds a device to the system as part of initialization 266 * @dip: 267 * @cmd: 268 * 269 * The kernel calls a driver's attach() entry point to attach an instance of 270 * a device (for MegaRAID, it is instance of a controller) or to resume 271 * operation for an instance of a device that has been suspended or has been 272 * shut down by the power management framework 273 * The attach() entry point typically includes the following types of 274 * processing: 275 * - allocate a soft-state structure for the device instance (for MegaRAID, 276 * controller instance) 277 * - initialize per-instance mutexes 278 * - initialize condition variables 279 * - register the device's interrupts (for MegaRAID, controller's interrupts) 280 * - map the registers and memory of the device instance (for MegaRAID, 281 * controller instance) 282 * - create minor device nodes for the device instance (for MegaRAID, 283 * controller instance) 284 * - report that the device instance (for MegaRAID, controller instance) has 285 * attached 286 */ 287 static int 288 megasas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 289 { 290 int instance_no; 291 int nregs; 292 uint8_t added_isr_f = 0; 293 uint8_t added_soft_isr_f = 0; 294 uint8_t create_devctl_node_f = 0; 295 uint8_t create_scsi_node_f = 0; 296 uint8_t create_ioc_node_f = 0; 297 uint8_t tran_alloc_f = 0; 298 uint8_t irq; 299 uint16_t vendor_id; 300 uint16_t device_id; 301 uint16_t subsysvid; 302 uint16_t subsysid; 303 uint16_t command; 304 305 scsi_hba_tran_t *tran; 306 ddi_dma_attr_t tran_dma_attr; 307 struct megasas_instance *instance; 308 309 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 310 311 /* CONSTCOND */ 312 ASSERT(NO_COMPETING_THREADS); 313 314 instance_no = ddi_get_instance(dip); 315 316 /* 317 * Since we know that some instantiations of this device can be 318 * plugged into slave-only SBus slots, check to see whether this is 319 * one such. 320 */ 321 if (ddi_slaveonly(dip) == DDI_SUCCESS) { 322 con_log(CL_ANN, (CE_WARN, 323 "mega%d: Device in slave-only slot, unused", instance_no)); 324 return (DDI_FAILURE); 325 } 326 327 switch (cmd) { 328 case DDI_ATTACH: 329 con_log(CL_DLEVEL1, (CE_NOTE, "megasas: DDI_ATTACH")); 330 /* allocate the soft state for the instance */ 331 if (ddi_soft_state_zalloc(megasas_state, instance_no) 332 != DDI_SUCCESS) { 333 con_log(CL_ANN, (CE_WARN, 334 "mega%d: Failed to allocate soft state", 335 instance_no)); 336 337 return (DDI_FAILURE); 338 } 339 340 instance = (struct megasas_instance *)ddi_get_soft_state 341 (megasas_state, instance_no); 342 343 if (instance == NULL) { 344 con_log(CL_ANN, (CE_WARN, 345 "mega%d: Bad soft state", instance_no)); 346 347 ddi_soft_state_free(megasas_state, instance_no); 348 349 return (DDI_FAILURE); 350 } 351 352 bzero((caddr_t)instance, 353 sizeof (struct megasas_instance)); 354 355 instance->func_ptr = kmem_zalloc( 356 sizeof (struct megasas_func_ptr), KM_SLEEP); 357 ASSERT(instance->func_ptr); 358 359 /* Setup the PCI configuration space handles */ 360 if (pci_config_setup(dip, &instance->pci_handle) != 361 DDI_SUCCESS) { 362 con_log(CL_ANN, (CE_WARN, 363 "mega%d: pci config setup failed ", 364 instance_no)); 365 366 kmem_free(instance->func_ptr, 367 sizeof (struct megasas_func_ptr)); 368 ddi_soft_state_free(megasas_state, instance_no); 369 370 return (DDI_FAILURE); 371 } 372 373 if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS) { 374 con_log(CL_ANN, (CE_WARN, 375 "megaraid: failed to get registers.")); 376 377 pci_config_teardown(&instance->pci_handle); 378 kmem_free(instance->func_ptr, 379 sizeof (struct megasas_func_ptr)); 380 ddi_soft_state_free(megasas_state, instance_no); 381 382 return (DDI_FAILURE); 383 } 384 385 vendor_id = pci_config_get16(instance->pci_handle, 386 PCI_CONF_VENID); 387 device_id = pci_config_get16(instance->pci_handle, 388 PCI_CONF_DEVID); 389 390 subsysvid = pci_config_get16(instance->pci_handle, 391 PCI_CONF_SUBVENID); 392 subsysid = pci_config_get16(instance->pci_handle, 393 PCI_CONF_SUBSYSID); 394 395 pci_config_put16(instance->pci_handle, PCI_CONF_COMM, 396 (pci_config_get16(instance->pci_handle, 397 PCI_CONF_COMM) | PCI_COMM_ME)); 398 irq = pci_config_get8(instance->pci_handle, 399 PCI_CONF_ILINE); 400 401 con_log(CL_DLEVEL1, (CE_CONT, "megasas%d: " 402 "0x%x:0x%x 0x%x:0x%x, irq:%d drv-ver:%s\n", 403 instance_no, vendor_id, device_id, subsysvid, 404 subsysid, irq, MEGASAS_VERSION)); 405 406 /* enable bus-mastering */ 407 command = pci_config_get16(instance->pci_handle, 408 PCI_CONF_COMM); 409 410 if (!(command & PCI_COMM_ME)) { 411 command |= PCI_COMM_ME; 412 413 pci_config_put16(instance->pci_handle, 414 PCI_CONF_COMM, command); 415 416 con_log(CL_ANN, (CE_CONT, "megaraid%d: " 417 "enable bus-mastering\n", instance_no)); 418 } else { 419 con_log(CL_DLEVEL1, (CE_CONT, "megaraid%d: " 420 "bus-mastering already set\n", instance_no)); 421 } 422 423 /* initialize function pointers */ 424 if ((device_id == PCI_DEVICE_ID_LSI_1078) || 425 (device_id == PCI_DEVICE_ID_LSI_1078DE)) { 426 con_log(CL_DLEVEL1, (CE_CONT, "megasas%d: " 427 "1078R/DE detected\n", instance_no)); 428 instance->func_ptr->read_fw_status_reg = 429 read_fw_status_reg_ppc; 430 instance->func_ptr->issue_cmd = issue_cmd_ppc; 431 instance->func_ptr->issue_cmd_in_sync_mode = 432 issue_cmd_in_sync_mode_ppc; 433 instance->func_ptr->issue_cmd_in_poll_mode = 434 issue_cmd_in_poll_mode_ppc; 435 instance->func_ptr->enable_intr = 436 enable_intr_ppc; 437 instance->func_ptr->disable_intr = 438 disable_intr_ppc; 439 instance->func_ptr->intr_ack = intr_ack_ppc; 440 } else { 441 con_log(CL_DLEVEL1, (CE_CONT, "megasas%d: " 442 "1064/8R detected\n", instance_no)); 443 instance->func_ptr->read_fw_status_reg = 444 read_fw_status_reg_xscale; 445 instance->func_ptr->issue_cmd = 446 issue_cmd_xscale; 447 instance->func_ptr->issue_cmd_in_sync_mode = 448 issue_cmd_in_sync_mode_xscale; 449 instance->func_ptr->issue_cmd_in_poll_mode = 450 issue_cmd_in_poll_mode_xscale; 451 instance->func_ptr->enable_intr = 452 enable_intr_xscale; 453 instance->func_ptr->disable_intr = 454 disable_intr_xscale; 455 instance->func_ptr->intr_ack = 456 intr_ack_xscale; 457 } 458 459 instance->baseaddress = pci_config_get32( 460 instance->pci_handle, PCI_CONF_BASE0); 461 instance->baseaddress &= 0x0fffc; 462 463 instance->dip = dip; 464 instance->vendor_id = vendor_id; 465 instance->device_id = device_id; 466 instance->subsysvid = subsysvid; 467 instance->subsysid = subsysid; 468 469 /* Initialize FMA */ 470 instance->fm_capabilities = ddi_prop_get_int( 471 DDI_DEV_T_ANY, instance->dip, DDI_PROP_DONTPASS, 472 "fm-capable", DDI_FM_EREPORT_CAPABLE | 473 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE 474 | DDI_FM_ERRCB_CAPABLE); 475 476 megasas_fm_init(instance); 477 478 /* setup the mfi based low level driver */ 479 if (init_mfi(instance) != DDI_SUCCESS) { 480 con_log(CL_ANN, (CE_WARN, "megaraid: " 481 "could not initialize the low level driver")); 482 483 goto fail_attach; 484 } 485 486 /* 487 * Allocate the interrupt blocking cookie. 488 * It represents the information the framework 489 * needs to block interrupts. This cookie will 490 * be used by the locks shared accross our ISR. 491 * These locks must be initialized before we 492 * register our ISR. 493 * ddi_add_intr(9F) 494 */ 495 if (ddi_get_iblock_cookie(dip, 0, 496 &instance->iblock_cookie) != DDI_SUCCESS) { 497 498 goto fail_attach; 499 } 500 501 if (ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_HIGH, 502 &instance->soft_iblock_cookie) != DDI_SUCCESS) { 503 504 goto fail_attach; 505 } 506 507 /* 508 * Initialize the driver mutexes common to 509 * normal/high level isr 510 */ 511 if (ddi_intr_hilevel(dip, 0)) { 512 instance->isr_level = HIGH_LEVEL_INTR; 513 mutex_init(&instance->cmd_pool_mtx, 514 "cmd_pool_mtx", MUTEX_DRIVER, 515 instance->soft_iblock_cookie); 516 mutex_init(&instance->cmd_pend_mtx, 517 "cmd_pend_mtx", MUTEX_DRIVER, 518 instance->soft_iblock_cookie); 519 } else { 520 /* 521 * Initialize the driver mutexes 522 * specific to soft-isr 523 */ 524 instance->isr_level = NORMAL_LEVEL_INTR; 525 mutex_init(&instance->cmd_pool_mtx, 526 "cmd_pool_mtx", MUTEX_DRIVER, 527 instance->iblock_cookie); 528 mutex_init(&instance->cmd_pend_mtx, 529 "cmd_pend_mtx", MUTEX_DRIVER, 530 instance->iblock_cookie); 531 } 532 533 mutex_init(&instance->completed_pool_mtx, 534 "completed_pool_mtx", MUTEX_DRIVER, 535 instance->iblock_cookie); 536 mutex_init(&instance->int_cmd_mtx, "int_cmd_mtx", 537 MUTEX_DRIVER, instance->iblock_cookie); 538 mutex_init(&instance->aen_cmd_mtx, "aen_cmd_mtx", 539 MUTEX_DRIVER, instance->iblock_cookie); 540 mutex_init(&instance->abort_cmd_mtx, "abort_cmd_mtx", 541 MUTEX_DRIVER, instance->iblock_cookie); 542 543 cv_init(&instance->int_cmd_cv, NULL, CV_DRIVER, NULL); 544 cv_init(&instance->abort_cmd_cv, NULL, CV_DRIVER, NULL); 545 546 INIT_LIST_HEAD(&instance->completed_pool_list); 547 548 /* Register our isr. */ 549 if (ddi_add_intr(dip, 0, NULL, NULL, megasas_isr, 550 (caddr_t)instance) != DDI_SUCCESS) { 551 con_log(CL_ANN, (CE_WARN, 552 " ISR did not register")); 553 554 goto fail_attach; 555 } 556 557 added_isr_f = 1; 558 559 /* Register our soft-isr for highlevel interrupts. */ 560 if (instance->isr_level == HIGH_LEVEL_INTR) { 561 if (ddi_add_softintr(dip, DDI_SOFTINT_HIGH, 562 &instance->soft_intr_id, NULL, NULL, 563 megasas_softintr, (caddr_t)instance) != 564 DDI_SUCCESS) { 565 con_log(CL_ANN, (CE_WARN, 566 " Software ISR did not register")); 567 568 goto fail_attach; 569 } 570 571 added_soft_isr_f = 1; 572 } 573 574 /* Allocate a transport structure */ 575 tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP); 576 577 if (tran == NULL) { 578 con_log(CL_ANN, (CE_WARN, 579 "scsi_hba_tran_alloc failed")); 580 goto fail_attach; 581 } 582 583 tran_alloc_f = 1; 584 585 instance->tran = tran; 586 587 tran->tran_hba_private = instance; 588 tran->tran_tgt_private = NULL; 589 tran->tran_tgt_init = megasas_tran_tgt_init; 590 tran->tran_tgt_probe = scsi_hba_probe; 591 tran->tran_tgt_free = (void (*)())NULL; 592 tran->tran_init_pkt = megasas_tran_init_pkt; 593 tran->tran_start = megasas_tran_start; 594 tran->tran_abort = megasas_tran_abort; 595 tran->tran_reset = megasas_tran_reset; 596 tran->tran_bus_reset = megasas_tran_bus_reset; 597 tran->tran_getcap = megasas_tran_getcap; 598 tran->tran_setcap = megasas_tran_setcap; 599 tran->tran_destroy_pkt = megasas_tran_destroy_pkt; 600 tran->tran_dmafree = megasas_tran_dmafree; 601 tran->tran_sync_pkt = megasas_tran_sync_pkt; 602 tran->tran_reset_notify = NULL; 603 tran->tran_quiesce = megasas_tran_quiesce; 604 tran->tran_unquiesce = megasas_tran_unquiesce; 605 606 tran_dma_attr = megasas_generic_dma_attr; 607 tran_dma_attr.dma_attr_sgllen = instance->max_num_sge; 608 609 /* Attach this instance of the hba */ 610 if (scsi_hba_attach_setup(dip, &tran_dma_attr, tran, 0) 611 != DDI_SUCCESS) { 612 con_log(CL_ANN, (CE_WARN, 613 "scsi_hba_attach failed\n")); 614 615 goto fail_attach; 616 } 617 618 /* create devctl node for cfgadm command */ 619 if (ddi_create_minor_node(dip, "devctl", 620 S_IFCHR, INST2DEVCTL(instance_no), 621 DDI_NT_SCSI_NEXUS, 0) == DDI_FAILURE) { 622 con_log(CL_ANN, (CE_WARN, 623 "megaraid: failed to create devctl node.")); 624 625 goto fail_attach; 626 } 627 628 create_devctl_node_f = 1; 629 630 /* create scsi node for cfgadm command */ 631 if (ddi_create_minor_node(dip, "scsi", S_IFCHR, 632 INST2SCSI(instance_no), 633 DDI_NT_SCSI_ATTACHMENT_POINT, 0) == 634 DDI_FAILURE) { 635 con_log(CL_ANN, (CE_WARN, 636 "megaraid: failed to create scsi node.")); 637 638 goto fail_attach; 639 } 640 641 create_scsi_node_f = 1; 642 643 (void) sprintf(instance->iocnode, "%d:lsirdctl", 644 instance_no); 645 646 /* 647 * Create a node for applications 648 * for issuing ioctl to the driver. 649 */ 650 if (ddi_create_minor_node(dip, instance->iocnode, 651 S_IFCHR, INST2LSIRDCTL(instance_no), 652 DDI_PSEUDO, 0) == DDI_FAILURE) { 653 con_log(CL_ANN, (CE_WARN, 654 "megaraid: failed to create ioctl node.")); 655 656 goto fail_attach; 657 } 658 659 create_ioc_node_f = 1; 660 661 /* enable interrupt */ 662 instance->func_ptr->enable_intr(instance); 663 664 /* initiate AEN */ 665 if (start_mfi_aen(instance)) { 666 con_log(CL_ANN, (CE_WARN, 667 "megaraid: failed to initiate AEN.")); 668 goto fail_initiate_aen; 669 } 670 671 con_log(CL_DLEVEL1, (CE_NOTE, 672 "AEN started for instance %d.", instance_no)); 673 674 /* Finally! We are on the air. */ 675 ddi_report_dev(dip); 676 677 if (megasas_check_acc_handle(instance->regmap_handle) != 678 DDI_SUCCESS) { 679 goto fail_attach; 680 } 681 if (megasas_check_acc_handle(instance->pci_handle) != 682 DDI_SUCCESS) { 683 goto fail_attach; 684 } 685 break; 686 case DDI_PM_RESUME: 687 con_log(CL_ANN, (CE_NOTE, 688 "megasas: DDI_PM_RESUME")); 689 break; 690 case DDI_RESUME: 691 con_log(CL_ANN, (CE_NOTE, 692 "megasas: DDI_RESUME")); 693 break; 694 default: 695 con_log(CL_ANN, (CE_WARN, 696 "megasas: invalid attach cmd=%x", cmd)); 697 return (DDI_FAILURE); 698 } 699 700 return (DDI_SUCCESS); 701 702 fail_initiate_aen: 703 fail_attach: 704 if (create_devctl_node_f) { 705 ddi_remove_minor_node(dip, "devctl"); 706 } 707 708 if (create_scsi_node_f) { 709 ddi_remove_minor_node(dip, "scsi"); 710 } 711 712 if (create_ioc_node_f) { 713 ddi_remove_minor_node(dip, instance->iocnode); 714 } 715 716 if (tran_alloc_f) { 717 scsi_hba_tran_free(tran); 718 } 719 720 721 if (added_soft_isr_f) { 722 ddi_remove_softintr(instance->soft_intr_id); 723 } 724 725 if (added_isr_f) { 726 ddi_remove_intr(dip, 0, instance->iblock_cookie); 727 } 728 729 megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); 730 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); 731 732 megasas_fm_fini(instance); 733 734 pci_config_teardown(&instance->pci_handle); 735 736 ddi_soft_state_free(megasas_state, instance_no); 737 738 con_log(CL_ANN, (CE_NOTE, 739 "megasas: return failure from mega_attach\n")); 740 741 return (DDI_FAILURE); 742 } 743 744 /* 745 * getinfo - gets device information 746 * @dip: 747 * @cmd: 748 * @arg: 749 * @resultp: 750 * 751 * The system calls getinfo() to obtain configuration information that only 752 * the driver knows. The mapping of minor numbers to device instance is 753 * entirely under the control of the driver. The system sometimes needs to ask 754 * the driver which device a particular dev_t represents. 755 * Given the device number return the devinfo pointer from the scsi_device 756 * structure. 757 */ 758 /*ARGSUSED*/ 759 static int 760 megasas_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) 761 { 762 int rval; 763 int megasas_minor = getminor((dev_t)arg); 764 765 struct megasas_instance *instance; 766 767 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 768 769 switch (cmd) { 770 case DDI_INFO_DEVT2DEVINFO: 771 instance = (struct megasas_instance *) 772 ddi_get_soft_state(megasas_state, 773 MINOR2INST(megasas_minor)); 774 775 if (instance == NULL) { 776 *resultp = NULL; 777 rval = DDI_FAILURE; 778 } else { 779 *resultp = instance->dip; 780 rval = DDI_SUCCESS; 781 } 782 break; 783 case DDI_INFO_DEVT2INSTANCE: 784 *resultp = (void *)instance; 785 rval = DDI_SUCCESS; 786 break; 787 default: 788 *resultp = NULL; 789 rval = DDI_FAILURE; 790 } 791 792 return (rval); 793 } 794 795 /* 796 * detach - detaches a device from the system 797 * @dip: pointer to the device's dev_info structure 798 * @cmd: type of detach 799 * 800 * A driver's detach() entry point is called to detach an instance of a device 801 * that is bound to the driver. The entry point is called with the instance of 802 * the device node to be detached and with DDI_DETACH, which is specified as 803 * the cmd argument to the entry point. 804 * This routine is called during driver unload. We free all the allocated 805 * resources and call the corresponding LLD so that it can also release all 806 * its resources. 807 */ 808 static int 809 megasas_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 810 { 811 int instance_no; 812 813 struct megasas_instance *instance; 814 815 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 816 817 /* CONSTCOND */ 818 ASSERT(NO_COMPETING_THREADS); 819 820 instance_no = ddi_get_instance(dip); 821 822 instance = (struct megasas_instance *)ddi_get_soft_state(megasas_state, 823 instance_no); 824 825 if (!instance) { 826 con_log(CL_ANN, (CE_WARN, 827 "megasas:%d could not get instance in detach", 828 instance_no)); 829 830 return (DDI_FAILURE); 831 } 832 833 con_log(CL_ANN, (CE_NOTE, 834 "megasas%d: detaching device 0x%4x:0x%4x:0x%4x:0x%4x\n", 835 instance_no, instance->vendor_id, instance->device_id, 836 instance->subsysvid, instance->subsysid)); 837 838 switch (cmd) { 839 case DDI_DETACH: 840 con_log(CL_ANN, (CE_NOTE, 841 "megasas_detach: DDI_DETACH\n")); 842 843 if (scsi_hba_detach(dip) != DDI_SUCCESS) { 844 con_log(CL_ANN, (CE_WARN, 845 "megasas:%d failed to detach", 846 instance_no)); 847 848 return (DDI_FAILURE); 849 } 850 851 scsi_hba_tran_free(instance->tran); 852 853 if (abort_aen_cmd(instance, instance->aen_cmd)) { 854 con_log(CL_ANN, (CE_WARN, "megasas_detach: " 855 "failed to abort prevous AEN command\n")); 856 857 return (DDI_FAILURE); 858 } 859 860 instance->func_ptr->disable_intr(instance); 861 862 if (instance->isr_level == HIGH_LEVEL_INTR) { 863 ddi_remove_softintr(instance->soft_intr_id); 864 } 865 866 ddi_remove_intr(dip, 0, instance->iblock_cookie); 867 868 free_space_for_mfi(instance); 869 870 megasas_fm_fini(instance); 871 872 pci_config_teardown(&instance->pci_handle); 873 874 kmem_free(instance->func_ptr, 875 sizeof (struct megasas_func_ptr)); 876 877 ddi_soft_state_free(megasas_state, instance_no); 878 break; 879 case DDI_PM_SUSPEND: 880 con_log(CL_ANN, (CE_NOTE, 881 "megasas_detach: DDI_PM_SUSPEND\n")); 882 883 break; 884 case DDI_SUSPEND: 885 con_log(CL_ANN, (CE_NOTE, 886 "megasas_detach: DDI_SUSPEND\n")); 887 888 break; 889 default: 890 con_log(CL_ANN, (CE_WARN, 891 "invalid detach command:0x%x", cmd)); 892 return (DDI_FAILURE); 893 } 894 895 return (DDI_SUCCESS); 896 } 897 898 /* 899 * ************************************************************************** * 900 * * 901 * common entry points - for character driver types * 902 * * 903 * ************************************************************************** * 904 */ 905 /* 906 * open - gets access to a device 907 * @dev: 908 * @openflags: 909 * @otyp: 910 * @credp: 911 * 912 * Access to a device by one or more application programs is controlled 913 * through the open() and close() entry points. The primary function of 914 * open() is to verify that the open request is allowed. 915 */ 916 static int 917 megasas_open(dev_t *dev, int openflags, int otyp, cred_t *credp) 918 { 919 int rval = 0; 920 921 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 922 923 /* Check root permissions */ 924 if (drv_priv(credp) != 0) { 925 con_log(CL_ANN, (CE_WARN, 926 "megaraid: Non-root ioctl access tried!")); 927 return (EPERM); 928 } 929 930 /* Verify we are being opened as a character device */ 931 if (otyp != OTYP_CHR) { 932 con_log(CL_ANN, (CE_WARN, 933 "megaraid: ioctl node must be a char node\n")); 934 return (EINVAL); 935 } 936 937 if (ddi_get_soft_state(megasas_state, MINOR2INST(getminor(*dev))) 938 == NULL) { 939 return (ENXIO); 940 } 941 942 if (scsi_hba_open) { 943 rval = scsi_hba_open(dev, openflags, otyp, credp); 944 } 945 946 return (rval); 947 } 948 949 /* 950 * close - gives up access to a device 951 * @dev: 952 * @openflags: 953 * @otyp: 954 * @credp: 955 * 956 * close() should perform any cleanup necessary to finish using the minor 957 * device, and prepare the device (and driver) to be opened again. 958 */ 959 static int 960 megasas_close(dev_t dev, int openflags, int otyp, cred_t *credp) 961 { 962 int rval = 0; 963 964 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 965 966 /* no need for locks! */ 967 968 if (scsi_hba_close) { 969 rval = scsi_hba_close(dev, openflags, otyp, credp); 970 } 971 972 return (rval); 973 } 974 975 /* 976 * ioctl - performs a range of I/O commands for character drivers 977 * @dev: 978 * @cmd: 979 * @arg: 980 * @mode: 981 * @credp: 982 * @rvalp: 983 * 984 * ioctl() routine must make sure that user data is copied into or out of the 985 * kernel address space explicitly using copyin(), copyout(), ddi_copyin(), 986 * and ddi_copyout(), as appropriate. 987 * This is a wrapper routine to serialize access to the actual ioctl routine. 988 * ioctl() should return 0 on success, or the appropriate error number. The 989 * driver may also set the value returned to the calling process through rvalp. 990 */ 991 static int 992 megasas_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 993 int *rvalp) 994 { 995 int rval = 0; 996 997 struct megasas_instance *instance; 998 struct megasas_ioctl ioctl; 999 struct megasas_aen aen; 1000 1001 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1002 1003 instance = ddi_get_soft_state(megasas_state, MINOR2INST(getminor(dev))); 1004 1005 if (instance == NULL) { 1006 /* invalid minor number */ 1007 con_log(CL_ANN, (CE_WARN, "megaraid: adapter not found.")); 1008 return (ENXIO); 1009 } 1010 1011 switch ((uint_t)cmd) { 1012 case MEGASAS_IOCTL_FIRMWARE: 1013 if (ddi_copyin((void *) arg, &ioctl, 1014 sizeof (struct megasas_ioctl), mode)) { 1015 con_log(CL_ANN, (CE_WARN, "megasas_ioctl: " 1016 "ERROR IOCTL copyin")); 1017 return (EFAULT); 1018 } 1019 1020 if (ioctl.control_code == MR_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 megasas_ioctl) - 1), mode)) { 1028 con_log(CL_ANN, (CE_WARN, 1029 "megasas_ioctl: copy_to_user failed\n")); 1030 rval = 1; 1031 } 1032 1033 break; 1034 case MEGASAS_IOCTL_AEN: 1035 if (ddi_copyin((void *) arg, &aen, 1036 sizeof (struct megasas_aen), mode)) { 1037 con_log(CL_ANN, (CE_WARN, 1038 "megasas_ioctl: ERROR AEN copyin")); 1039 return (EFAULT); 1040 } 1041 1042 rval = handle_mfi_aen(instance, &aen); 1043 1044 if (ddi_copyout((void *) &aen, (void *)arg, 1045 sizeof (struct megasas_aen), mode)) { 1046 con_log(CL_ANN, (CE_WARN, 1047 "megasas_ioctl: copy_to_user failed\n")); 1048 rval = 1; 1049 } 1050 1051 break; 1052 default: 1053 rval = scsi_hba_ioctl(dev, cmd, arg, 1054 mode, credp, rvalp); 1055 1056 con_log(CL_DLEVEL1, (CE_NOTE, "megasas_ioctl: " 1057 "scsi_hba_ioctl called, ret = %x.", rval)); 1058 } 1059 1060 return (rval); 1061 } 1062 1063 /* 1064 * ************************************************************************** * 1065 * * 1066 * common entry points - for block driver types * 1067 * * 1068 * ************************************************************************** * 1069 */ 1070 /* 1071 * reset - TBD 1072 * @dip: 1073 * @cmd: 1074 * 1075 * TBD 1076 */ 1077 /*ARGSUSED*/ 1078 static int 1079 megasas_reset(dev_info_t *dip, ddi_reset_cmd_t cmd) 1080 { 1081 int instance_no; 1082 1083 struct megasas_instance *instance; 1084 1085 instance_no = ddi_get_instance(dip); 1086 instance = (struct megasas_instance *)ddi_get_soft_state 1087 (megasas_state, instance_no); 1088 1089 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1090 1091 if (!instance) { 1092 con_log(CL_ANN, (CE_WARN, 1093 "megaraid:%d could not get adapter in reset", 1094 instance_no)); 1095 return (DDI_FAILURE); 1096 } 1097 1098 con_log(CL_ANN, (CE_NOTE, "flushing cache for instance %d ..", 1099 instance_no)); 1100 1101 flush_cache(instance); 1102 1103 return (DDI_SUCCESS); 1104 } 1105 1106 1107 /* 1108 * ************************************************************************** * 1109 * * 1110 * entry points (SCSI HBA) * 1111 * * 1112 * ************************************************************************** * 1113 */ 1114 /* 1115 * tran_tgt_init - initialize a target device instance 1116 * @hba_dip: 1117 * @tgt_dip: 1118 * @tran: 1119 * @sd: 1120 * 1121 * The tran_tgt_init() entry point enables the HBA to allocate and initialize 1122 * any per-target resources. tran_tgt_init() also enables the HBA to qualify 1123 * the device's address as valid and supportable for that particular HBA. 1124 * By returning DDI_FAILURE, the instance of the target driver for that device 1125 * is not probed or attached. 1126 */ 1127 /*ARGSUSED*/ 1128 static int 1129 megasas_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 1130 scsi_hba_tran_t *tran, struct scsi_device *sd) 1131 { 1132 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1133 1134 return (DDI_SUCCESS); 1135 } 1136 1137 /* 1138 * tran_init_pkt - allocate & initialize a scsi_pkt structure 1139 * @ap: 1140 * @pkt: 1141 * @bp: 1142 * @cmdlen: 1143 * @statuslen: 1144 * @tgtlen: 1145 * @flags: 1146 * @callback: 1147 * 1148 * The tran_init_pkt() entry point allocates and initializes a scsi_pkt 1149 * structure and DMA resources for a target driver request. The 1150 * tran_init_pkt() entry point is called when the target driver calls the 1151 * SCSA function scsi_init_pkt(). Each call of the tran_init_pkt() entry point 1152 * is a request to perform one or more of three possible services: 1153 * - allocation and initialization of a scsi_pkt structure 1154 * - allocation of DMA resources for data transfer 1155 * - reallocation of DMA resources for the next portion of the data transfer 1156 */ 1157 static struct scsi_pkt * 1158 megasas_tran_init_pkt(struct scsi_address *ap, register struct scsi_pkt *pkt, 1159 struct buf *bp, int cmdlen, int statuslen, int tgtlen, 1160 int flags, int (*callback)(), caddr_t arg) 1161 { 1162 struct scsa_cmd *acmd; 1163 struct megasas_instance *instance; 1164 struct scsi_pkt *new_pkt; 1165 1166 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1167 1168 instance = ADDR2MEGA(ap); 1169 1170 /* step #1 : pkt allocation */ 1171 if (pkt == NULL) { 1172 pkt = scsi_hba_pkt_alloc(instance->dip, ap, cmdlen, statuslen, 1173 tgtlen, sizeof (struct scsa_cmd), callback, arg); 1174 if (pkt == NULL) { 1175 return (NULL); 1176 } 1177 1178 acmd = PKT2CMD(pkt); 1179 1180 /* 1181 * Initialize the new pkt - we redundantly initialize 1182 * all the fields for illustrative purposes. 1183 */ 1184 acmd->cmd_pkt = pkt; 1185 acmd->cmd_flags = 0; 1186 acmd->cmd_scblen = statuslen; 1187 acmd->cmd_cdblen = cmdlen; 1188 acmd->cmd_dmahandle = NULL; 1189 acmd->cmd_ncookies = 0; 1190 acmd->cmd_cookie = 0; 1191 acmd->cmd_cookiecnt = 0; 1192 acmd->cmd_nwin = 0; 1193 1194 pkt->pkt_address = *ap; 1195 pkt->pkt_comp = (void (*)())NULL; 1196 pkt->pkt_flags = 0; 1197 pkt->pkt_time = 0; 1198 pkt->pkt_resid = 0; 1199 pkt->pkt_state = 0; 1200 pkt->pkt_statistics = 0; 1201 pkt->pkt_reason = 0; 1202 new_pkt = pkt; 1203 } else { 1204 acmd = PKT2CMD(pkt); 1205 new_pkt = NULL; 1206 } 1207 1208 /* step #2 : dma allocation/move */ 1209 if (bp && bp->b_bcount != 0) { 1210 if (acmd->cmd_dmahandle == NULL) { 1211 if (megasas_dma_alloc(instance, pkt, bp, flags, 1212 callback) == -1) { 1213 if (new_pkt) { 1214 scsi_hba_pkt_free(ap, new_pkt); 1215 } 1216 1217 return ((struct scsi_pkt *)NULL); 1218 } 1219 } else { 1220 if (megasas_dma_move(instance, pkt, bp) == -1) { 1221 return ((struct scsi_pkt *)NULL); 1222 } 1223 } 1224 } 1225 1226 return (pkt); 1227 } 1228 1229 /* 1230 * tran_start - transport a SCSI command to the addressed target 1231 * @ap: 1232 * @pkt: 1233 * 1234 * The tran_start() entry point for a SCSI HBA driver is called to transport a 1235 * SCSI command to the addressed target. The SCSI command is described 1236 * entirely within the scsi_pkt structure, which the target driver allocated 1237 * through the HBA driver's tran_init_pkt() entry point. If the command 1238 * involves a data transfer, DMA resources must also have been allocated for 1239 * the scsi_pkt structure. 1240 * 1241 * Return Values : 1242 * TRAN_BUSY - request queue is full, no more free scbs 1243 * TRAN_ACCEPT - pkt has been submitted to the instance 1244 */ 1245 static int 1246 megasas_tran_start(struct scsi_address *ap, register struct scsi_pkt *pkt) 1247 { 1248 uchar_t cmd_done = 0; 1249 1250 struct megasas_instance *instance = ADDR2MEGA(ap); 1251 struct megasas_cmd *cmd; 1252 1253 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d:SCSI CDB[0]=0x%x", 1254 __func__, __LINE__, pkt->pkt_cdbp[0])); 1255 1256 pkt->pkt_reason = CMD_CMPLT; 1257 *pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */ 1258 1259 cmd = build_cmd(instance, ap, pkt, &cmd_done); 1260 1261 /* 1262 * Check if the command is already completed by the mega_build_cmd() 1263 * routine. In which case the busy_flag would be clear and scb will be 1264 * NULL and appropriate reason provided in pkt_reason field 1265 */ 1266 if (cmd_done) { 1267 if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && pkt->pkt_comp) { 1268 (*pkt->pkt_comp)(pkt); 1269 } 1270 pkt->pkt_reason = CMD_CMPLT; 1271 pkt->pkt_scbp[0] = STATUS_GOOD; 1272 pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET 1273 | STATE_SENT_CMD; 1274 return (TRAN_ACCEPT); 1275 } 1276 1277 if (cmd == NULL) { 1278 return (TRAN_BUSY); 1279 } 1280 1281 if ((pkt->pkt_flags & FLAG_NOINTR) == 0) { 1282 if (instance->fw_outstanding > instance->max_fw_cmds) { 1283 con_log(CL_ANN, (CE_CONT, "megasas:Firmware busy")); 1284 return_mfi_pkt(instance, cmd); 1285 return (TRAN_BUSY); 1286 } 1287 1288 /* Syncronize the Cmd frame for the controller */ 1289 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 0, 0, 1290 DDI_DMA_SYNC_FORDEV); 1291 1292 instance->func_ptr->issue_cmd(cmd, instance); 1293 1294 } else { 1295 struct megasas_header *hdr = &cmd->frame->hdr; 1296 1297 cmd->sync_cmd = MEGASAS_TRUE; 1298 1299 instance->func_ptr-> issue_cmd_in_poll_mode(instance, cmd); 1300 1301 pkt->pkt_reason = CMD_CMPLT; 1302 pkt->pkt_statistics = 0; 1303 pkt->pkt_state |= STATE_XFERRED_DATA | STATE_GOT_STATUS; 1304 1305 switch (hdr->cmd_status) { 1306 case MFI_STAT_OK: 1307 pkt->pkt_scbp[0] = STATUS_GOOD; 1308 break; 1309 1310 case MFI_STAT_SCSI_DONE_WITH_ERROR: 1311 1312 pkt->pkt_reason = CMD_CMPLT; 1313 pkt->pkt_statistics = 0; 1314 1315 ((struct scsi_status *)pkt->pkt_scbp)->sts_chk = 1; 1316 break; 1317 1318 case MFI_STAT_DEVICE_NOT_FOUND: 1319 pkt->pkt_reason = CMD_DEV_GONE; 1320 pkt->pkt_statistics = STAT_DISCON; 1321 break; 1322 1323 default: 1324 ((struct scsi_status *)pkt->pkt_scbp)->sts_busy = 1; 1325 } 1326 1327 return_mfi_pkt(instance, cmd); 1328 (void) megasas_common_check(instance, cmd); 1329 1330 if (pkt->pkt_comp) { 1331 (*pkt->pkt_comp)(pkt); 1332 } 1333 1334 } 1335 1336 return (TRAN_ACCEPT); 1337 } 1338 1339 /* 1340 * tran_abort - Abort any commands that are currently in transport 1341 * @ap: 1342 * @pkt: 1343 * 1344 * The tran_abort() entry point for a SCSI HBA driver is called to abort any 1345 * commands that are currently in transport for a particular target. This entry 1346 * point is called when a target driver calls scsi_abort(). The tran_abort() 1347 * entry point should attempt to abort the command denoted by the pkt 1348 * parameter. If the pkt parameter is NULL, tran_abort() should attempt to 1349 * abort all outstanding commands in the transport layer for the particular 1350 * target or logical unit. 1351 */ 1352 /*ARGSUSED*/ 1353 static int 1354 megasas_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 1355 { 1356 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1357 1358 /* aborting command not supported by H/W */ 1359 1360 return (DDI_FAILURE); 1361 } 1362 1363 /* 1364 * tran_reset - reset either the SCSI bus or target 1365 * @ap: 1366 * @level: 1367 * 1368 * The tran_reset() entry point for a SCSI HBA driver is called to reset either 1369 * the SCSI bus or a particular SCSI target device. This entry point is called 1370 * when a target driver calls scsi_reset(). The tran_reset() entry point must 1371 * reset the SCSI bus if level is RESET_ALL. If level is RESET_TARGET, just the 1372 * particular target or logical unit must be reset. 1373 */ 1374 /*ARGSUSED*/ 1375 static int 1376 megasas_tran_reset(struct scsi_address *ap, int level) 1377 { 1378 struct megasas_instance *instance = ADDR2MEGA(ap); 1379 1380 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1381 1382 if (wait_for_outstanding(instance)) { 1383 return (DDI_FAILURE); 1384 } else { 1385 return (DDI_SUCCESS); 1386 } 1387 } 1388 1389 /* 1390 * tran_bus_reset - reset the SCSI bus 1391 * @dip: 1392 * @level: 1393 * 1394 * The tran_bus_reset() vector in the scsi_hba_tran structure should be 1395 * initialized during the HBA driver's attach(). The vector should point to 1396 * an HBA entry point that is to be called when a user initiates a bus reset. 1397 * Implementation is hardware specific. If the HBA driver cannot reset the 1398 * SCSI bus without affecting the targets, the driver should fail RESET_BUS 1399 * or not initialize this vector. 1400 */ 1401 /*ARGSUSED*/ 1402 static int 1403 megasas_tran_bus_reset(dev_info_t *dip, int level) 1404 { 1405 int instance_no = ddi_get_instance(dip); 1406 1407 struct megasas_instance *instance = ddi_get_soft_state(megasas_state, 1408 instance_no); 1409 1410 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1411 1412 if (wait_for_outstanding(instance)) { 1413 return (DDI_FAILURE); 1414 } else { 1415 return (DDI_SUCCESS); 1416 } 1417 } 1418 1419 /* 1420 * tran_getcap - get one of a set of SCSA-defined capabilities 1421 * @ap: 1422 * @cap: 1423 * @whom: 1424 * 1425 * The target driver can request the current setting of the capability for a 1426 * particular target by setting the whom parameter to nonzero. A whom value of 1427 * zero indicates a request for the current setting of the general capability 1428 * for the SCSI bus or for adapter hardware. The tran_getcap() should return -1 1429 * for undefined capabilities or the current value of the requested capability. 1430 */ 1431 /*ARGSUSED*/ 1432 static int 1433 megasas_tran_getcap(struct scsi_address *ap, char *cap, int whom) 1434 { 1435 int rval = 0; 1436 1437 struct megasas_instance *instance = ADDR2MEGA(ap); 1438 1439 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1440 1441 /* we do allow inquiring about capabilities for other targets */ 1442 if (cap == NULL) { 1443 return (-1); 1444 } 1445 1446 switch (scsi_hba_lookup_capstr(cap)) { 1447 case SCSI_CAP_DMA_MAX: 1448 /* Limit to 16MB max transfer */ 1449 rval = megasas_max_cap_maxxfer; 1450 break; 1451 case SCSI_CAP_MSG_OUT: 1452 rval = 1; 1453 break; 1454 case SCSI_CAP_DISCONNECT: 1455 rval = 0; 1456 break; 1457 case SCSI_CAP_SYNCHRONOUS: 1458 rval = 0; 1459 break; 1460 case SCSI_CAP_WIDE_XFER: 1461 rval = 1; 1462 break; 1463 case SCSI_CAP_TAGGED_QING: 1464 rval = 1; 1465 break; 1466 case SCSI_CAP_UNTAGGED_QING: 1467 rval = 1; 1468 break; 1469 case SCSI_CAP_PARITY: 1470 rval = 1; 1471 break; 1472 case SCSI_CAP_INITIATOR_ID: 1473 rval = instance->init_id; 1474 break; 1475 case SCSI_CAP_ARQ: 1476 rval = 1; 1477 break; 1478 case SCSI_CAP_LINKED_CMDS: 1479 rval = 0; 1480 break; 1481 case SCSI_CAP_RESET_NOTIFICATION: 1482 rval = 1; 1483 break; 1484 case SCSI_CAP_GEOMETRY: 1485 rval = -1; 1486 1487 break; 1488 default: 1489 con_log(CL_DLEVEL2, (CE_NOTE, "Default cap coming 0x%x", 1490 scsi_hba_lookup_capstr(cap))); 1491 rval = -1; 1492 break; 1493 } 1494 1495 return (rval); 1496 } 1497 1498 /* 1499 * tran_setcap - set one of a set of SCSA-defined capabilities 1500 * @ap: 1501 * @cap: 1502 * @value: 1503 * @whom: 1504 * 1505 * The target driver might request that the new value be set for a particular 1506 * target by setting the whom parameter to nonzero. A whom value of zero 1507 * means that request is to set the new value for the SCSI bus or for adapter 1508 * hardware in general. 1509 * The tran_setcap() should return the following values as appropriate: 1510 * - -1 for undefined capabilities 1511 * - 0 if the HBA driver cannot set the capability to the requested value 1512 * - 1 if the HBA driver is able to set the capability to the requested value 1513 */ 1514 /*ARGSUSED*/ 1515 static int 1516 megasas_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom) 1517 { 1518 int rval = 1; 1519 1520 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1521 1522 /* We don't allow setting capabilities for other targets */ 1523 if (cap == NULL || whom == 0) { 1524 return (-1); 1525 } 1526 1527 switch (scsi_hba_lookup_capstr(cap)) { 1528 case SCSI_CAP_DMA_MAX: 1529 case SCSI_CAP_MSG_OUT: 1530 case SCSI_CAP_PARITY: 1531 case SCSI_CAP_LINKED_CMDS: 1532 case SCSI_CAP_RESET_NOTIFICATION: 1533 case SCSI_CAP_DISCONNECT: 1534 case SCSI_CAP_SYNCHRONOUS: 1535 case SCSI_CAP_UNTAGGED_QING: 1536 case SCSI_CAP_WIDE_XFER: 1537 case SCSI_CAP_INITIATOR_ID: 1538 case SCSI_CAP_ARQ: 1539 /* 1540 * None of these are settable via 1541 * the capability interface. 1542 */ 1543 break; 1544 case SCSI_CAP_TAGGED_QING: 1545 rval = 1; 1546 break; 1547 case SCSI_CAP_SECTOR_SIZE: 1548 rval = 1; 1549 break; 1550 1551 case SCSI_CAP_TOTAL_SECTORS: 1552 rval = 1; 1553 break; 1554 default: 1555 rval = -1; 1556 break; 1557 } 1558 1559 return (rval); 1560 } 1561 1562 /* 1563 * tran_destroy_pkt - deallocate scsi_pkt structure 1564 * @ap: 1565 * @pkt: 1566 * 1567 * The tran_destroy_pkt() entry point is the HBA driver function that 1568 * deallocates scsi_pkt structures. The tran_destroy_pkt() entry point is 1569 * called when the target driver calls scsi_destroy_pkt(). The 1570 * tran_destroy_pkt() entry point must free any DMA resources that have been 1571 * allocated for the packet. An implicit DMA synchronization occurs if the 1572 * DMA resources are freed and any cached data remains after the completion 1573 * of the transfer. 1574 */ 1575 static void 1576 megasas_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1577 { 1578 struct scsa_cmd *acmd = PKT2CMD(pkt); 1579 1580 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1581 1582 if (acmd->cmd_flags & CFLAG_DMAVALID) { 1583 acmd->cmd_flags &= ~CFLAG_DMAVALID; 1584 1585 (void) ddi_dma_unbind_handle(acmd->cmd_dmahandle); 1586 1587 ddi_dma_free_handle(&acmd->cmd_dmahandle); 1588 1589 acmd->cmd_dmahandle = NULL; 1590 } 1591 1592 /* free the pkt */ 1593 scsi_hba_pkt_free(ap, pkt); 1594 } 1595 1596 /* 1597 * tran_dmafree - deallocates DMA resources 1598 * @ap: 1599 * @pkt: 1600 * 1601 * The tran_dmafree() entry point deallocates DMAQ resources that have been 1602 * allocated for a scsi_pkt structure. The tran_dmafree() entry point is 1603 * called when the target driver calls scsi_dmafree(). The tran_dmafree() must 1604 * free only DMA resources allocated for a scsi_pkt structure, not the 1605 * scsi_pkt itself. When DMA resources are freed, a DMA synchronization is 1606 * implicitly performed. 1607 */ 1608 /*ARGSUSED*/ 1609 static void 1610 megasas_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 /* 1628 * tran_sync_pkt - synchronize the DMA object allocated 1629 * @ap: 1630 * @pkt: 1631 * 1632 * The tran_sync_pkt() entry point synchronizes the DMA object allocated for 1633 * the scsi_pkt structure before or after a DMA transfer. The tran_sync_pkt() 1634 * entry point is called when the target driver calls scsi_sync_pkt(). If the 1635 * data transfer direction is a DMA read from device to memory, tran_sync_pkt() 1636 * must synchronize the CPU's view of the data. If the data transfer direction 1637 * is a DMA write from memory to device, tran_sync_pkt() must synchronize the 1638 * device's view of the data. 1639 */ 1640 /*ARGSUSED*/ 1641 static void 1642 megasas_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1643 { 1644 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1645 1646 /* 1647 * following 'ddi_dma_sync()' API call 1648 * already called for each I/O in the ISR 1649 */ 1650 #if 0 1651 int i; 1652 1653 register struct scsa_cmd *acmd = PKT2CMD(pkt); 1654 1655 if (acmd->cmd_flags & CFLAG_DMAVALID) { 1656 (void) ddi_dma_sync(acmd->cmd_dmahandle, acmd->cmd_dma_offset, 1657 acmd->cmd_dma_len, (acmd->cmd_flags & CFLAG_DMASEND) ? 1658 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 1659 } 1660 #endif 1661 } 1662 1663 /*ARGSUSED*/ 1664 static int 1665 megasas_tran_quiesce(dev_info_t *dip) 1666 { 1667 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1668 1669 return (1); 1670 } 1671 1672 /*ARGSUSED*/ 1673 static int 1674 megasas_tran_unquiesce(dev_info_t *dip) 1675 { 1676 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1677 1678 return (1); 1679 } 1680 1681 /* 1682 * megasas_isr(caddr_t) 1683 * 1684 * The Interrupt Service Routine 1685 * 1686 * Collect status for all completed commands and do callback 1687 * 1688 */ 1689 static uint_t 1690 megasas_isr(struct megasas_instance *instance) 1691 { 1692 int need_softintr; 1693 uint32_t producer; 1694 uint32_t consumer; 1695 uint32_t context; 1696 1697 struct megasas_cmd *cmd; 1698 1699 con_log(CL_ANN1, (CE_NOTE, "chkpnt:%s:%d", __func__, __LINE__)); 1700 1701 ASSERT(instance); 1702 if (!instance->func_ptr->intr_ack(instance)) { 1703 return (DDI_INTR_UNCLAIMED); 1704 } 1705 1706 (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle, 1707 0, 0, DDI_DMA_SYNC_FORCPU); 1708 1709 if (megasas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle) 1710 != DDI_SUCCESS) { 1711 megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); 1712 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); 1713 return (DDI_INTR_UNCLAIMED); 1714 } 1715 1716 producer = *instance->producer; 1717 consumer = *instance->consumer; 1718 1719 con_log(CL_ANN1, (CE_CONT, " producer %x consumer %x ", 1720 producer, consumer)); 1721 1722 mutex_enter(&instance->completed_pool_mtx); 1723 1724 while (consumer != producer) { 1725 context = instance->reply_queue[consumer]; 1726 cmd = instance->cmd_list[context]; 1727 mlist_add_tail(&cmd->list, &instance->completed_pool_list); 1728 1729 consumer++; 1730 if (consumer == (instance->max_fw_cmds + 1)) { 1731 consumer = 0; 1732 } 1733 } 1734 1735 mutex_exit(&instance->completed_pool_mtx); 1736 1737 *instance->consumer = consumer; 1738 (void) ddi_dma_sync(instance->mfi_internal_dma_obj.dma_handle, 1739 0, 0, DDI_DMA_SYNC_FORDEV); 1740 1741 if (instance->softint_running) { 1742 need_softintr = 0; 1743 } else { 1744 need_softintr = 1; 1745 } 1746 1747 if (instance->isr_level == HIGH_LEVEL_INTR) { 1748 if (need_softintr) { 1749 ddi_trigger_softintr(instance->soft_intr_id); 1750 } 1751 } else { 1752 /* 1753 * Not a high-level interrupt, therefore call the soft level 1754 * interrupt explicitly 1755 */ 1756 (void) megasas_softintr(instance); 1757 } 1758 1759 return (DDI_INTR_CLAIMED); 1760 } 1761 1762 1763 /* 1764 * ************************************************************************** * 1765 * * 1766 * libraries * 1767 * * 1768 * ************************************************************************** * 1769 */ 1770 /* 1771 * get_mfi_pkt : Get a command from the free pool 1772 */ 1773 static struct megasas_cmd * 1774 get_mfi_pkt(struct megasas_instance *instance) 1775 { 1776 mlist_t *head = &instance->cmd_pool_list; 1777 struct megasas_cmd *cmd = NULL; 1778 1779 mutex_enter(&instance->cmd_pool_mtx); 1780 ASSERT(mutex_owned(&instance->cmd_pool_mtx)); 1781 1782 if (!mlist_empty(head)) { 1783 cmd = mlist_entry(head->next, struct megasas_cmd, list); 1784 mlist_del_init(head->next); 1785 } 1786 if (cmd != NULL) 1787 cmd->pkt = NULL; 1788 mutex_exit(&instance->cmd_pool_mtx); 1789 1790 return (cmd); 1791 } 1792 1793 /* 1794 * return_mfi_pkt : Return a cmd to free command pool 1795 */ 1796 static void 1797 return_mfi_pkt(struct megasas_instance *instance, struct megasas_cmd *cmd) 1798 { 1799 mutex_enter(&instance->cmd_pool_mtx); 1800 ASSERT(mutex_owned(&instance->cmd_pool_mtx)); 1801 1802 mlist_add(&cmd->list, &instance->cmd_pool_list); 1803 1804 mutex_exit(&instance->cmd_pool_mtx); 1805 } 1806 1807 /* 1808 * destroy_mfi_frame_pool 1809 */ 1810 static void 1811 destroy_mfi_frame_pool(struct megasas_instance *instance) 1812 { 1813 int i; 1814 uint32_t max_cmd = instance->max_fw_cmds; 1815 1816 struct megasas_cmd *cmd; 1817 1818 /* return all frames to pool */ 1819 for (i = 0; i < max_cmd; i++) { 1820 1821 cmd = instance->cmd_list[i]; 1822 1823 if (cmd->frame_dma_obj_status == DMA_OBJ_ALLOCATED) 1824 (void) mega_free_dma_obj(instance, cmd->frame_dma_obj); 1825 1826 cmd->frame_dma_obj_status = DMA_OBJ_FREED; 1827 } 1828 1829 } 1830 1831 /* 1832 * create_mfi_frame_pool 1833 */ 1834 static int 1835 create_mfi_frame_pool(struct megasas_instance *instance) 1836 { 1837 int i = 0; 1838 int cookie_cnt; 1839 uint16_t max_cmd; 1840 uint16_t sge_sz; 1841 uint32_t sgl_sz; 1842 uint32_t tot_frame_size; 1843 1844 struct megasas_cmd *cmd; 1845 1846 max_cmd = instance->max_fw_cmds; 1847 1848 sge_sz = sizeof (struct megasas_sge64); 1849 1850 /* calculated the number of 64byte frames required for SGL */ 1851 sgl_sz = sge_sz * instance->max_num_sge; 1852 tot_frame_size = sgl_sz + MEGAMFI_FRAME_SIZE + SENSE_LENGTH; 1853 1854 con_log(CL_DLEVEL3, (CE_NOTE, "create_mfi_frame_pool: " 1855 "sgl_sz %x tot_frame_size %x", sgl_sz, tot_frame_size)); 1856 1857 while (i < max_cmd) { 1858 cmd = instance->cmd_list[i]; 1859 1860 cmd->frame_dma_obj.size = tot_frame_size; 1861 cmd->frame_dma_obj.dma_attr = megasas_generic_dma_attr; 1862 cmd->frame_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 1863 cmd->frame_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 1864 cmd->frame_dma_obj.dma_attr.dma_attr_sgllen = 1; 1865 cmd->frame_dma_obj.dma_attr.dma_attr_align = 64; 1866 1867 1868 cookie_cnt = mega_alloc_dma_obj(instance, &cmd->frame_dma_obj); 1869 1870 if (cookie_cnt == -1 || cookie_cnt > 1) { 1871 con_log(CL_ANN, (CE_WARN, 1872 "create_mfi_frame_pool: could not alloc.")); 1873 return (DDI_FAILURE); 1874 } 1875 1876 bzero(cmd->frame_dma_obj.buffer, tot_frame_size); 1877 1878 cmd->frame_dma_obj_status = DMA_OBJ_ALLOCATED; 1879 cmd->frame = (union megasas_frame *)cmd->frame_dma_obj.buffer; 1880 cmd->frame_phys_addr = 1881 cmd->frame_dma_obj.dma_cookie[0].dmac_address; 1882 1883 cmd->sense = (uint8_t *)(((unsigned long) 1884 cmd->frame_dma_obj.buffer) + 1885 tot_frame_size - SENSE_LENGTH); 1886 cmd->sense_phys_addr = 1887 cmd->frame_dma_obj.dma_cookie[0].dmac_address + 1888 tot_frame_size - SENSE_LENGTH; 1889 1890 if (!cmd->frame || !cmd->sense) { 1891 con_log(CL_ANN, (CE_NOTE, 1892 "megasas: pci_pool_alloc failed \n")); 1893 1894 return (-ENOMEM); 1895 } 1896 1897 cmd->frame->io.context = cmd->index; 1898 i++; 1899 1900 con_log(CL_DLEVEL3, (CE_NOTE, "[%x]-%x", 1901 cmd->frame->io.context, cmd->frame_phys_addr)); 1902 } 1903 1904 return (DDI_SUCCESS); 1905 } 1906 1907 /* 1908 * free_additional_dma_buffer 1909 */ 1910 static void 1911 free_additional_dma_buffer(struct megasas_instance *instance) 1912 { 1913 if (instance->mfi_internal_dma_obj.status == DMA_OBJ_ALLOCATED) { 1914 (void) mega_free_dma_obj(instance, 1915 instance->mfi_internal_dma_obj); 1916 instance->mfi_internal_dma_obj.status = DMA_OBJ_FREED; 1917 } 1918 1919 if (instance->mfi_evt_detail_obj.status == DMA_OBJ_ALLOCATED) { 1920 (void) mega_free_dma_obj(instance, 1921 instance->mfi_evt_detail_obj); 1922 instance->mfi_evt_detail_obj.status = DMA_OBJ_FREED; 1923 } 1924 } 1925 1926 /* 1927 * alloc_additional_dma_buffer 1928 */ 1929 static int 1930 alloc_additional_dma_buffer(struct megasas_instance *instance) 1931 { 1932 uint32_t reply_q_sz; 1933 uint32_t internal_buf_size = PAGESIZE*2; 1934 1935 /* max cmds plus 1 + producer & consumer */ 1936 reply_q_sz = sizeof (uint32_t) * (instance->max_fw_cmds + 1 + 2); 1937 1938 instance->mfi_internal_dma_obj.size = internal_buf_size; 1939 instance->mfi_internal_dma_obj.dma_attr = megasas_generic_dma_attr; 1940 instance->mfi_internal_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 1941 instance->mfi_internal_dma_obj.dma_attr.dma_attr_count_max = 1942 0xFFFFFFFFU; 1943 instance->mfi_internal_dma_obj.dma_attr.dma_attr_sgllen = 1; 1944 1945 if (mega_alloc_dma_obj(instance, &instance->mfi_internal_dma_obj) 1946 != 1) { 1947 con_log(CL_ANN, (CE_WARN, "megaraid: could not alloc reply Q")); 1948 return (DDI_FAILURE); 1949 } 1950 1951 bzero(instance->mfi_internal_dma_obj.buffer, internal_buf_size); 1952 1953 instance->mfi_internal_dma_obj.status |= DMA_OBJ_ALLOCATED; 1954 1955 instance->producer = (uint32_t *)((unsigned long) 1956 instance->mfi_internal_dma_obj.buffer); 1957 instance->consumer = (uint32_t *)((unsigned long) 1958 instance->mfi_internal_dma_obj.buffer + 4); 1959 instance->reply_queue = (uint32_t *)((unsigned long) 1960 instance->mfi_internal_dma_obj.buffer + 8); 1961 instance->internal_buf = (caddr_t)(((unsigned long) 1962 instance->mfi_internal_dma_obj.buffer) + reply_q_sz + 8); 1963 instance->internal_buf_dmac_add = 1964 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 1965 reply_q_sz; 1966 instance->internal_buf_size = internal_buf_size - 1967 (reply_q_sz + 8); 1968 1969 /* allocate evt_detail */ 1970 instance->mfi_evt_detail_obj.size = sizeof (struct megasas_evt_detail); 1971 instance->mfi_evt_detail_obj.dma_attr = megasas_generic_dma_attr; 1972 instance->mfi_evt_detail_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 1973 instance->mfi_evt_detail_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 1974 instance->mfi_evt_detail_obj.dma_attr.dma_attr_sgllen = 1; 1975 instance->mfi_evt_detail_obj.dma_attr.dma_attr_align = 1; 1976 1977 if (mega_alloc_dma_obj(instance, &instance->mfi_evt_detail_obj) != 1) { 1978 con_log(CL_ANN, (CE_WARN, "alloc_additional_dma_buffer: " 1979 "could not data transfer buffer alloc.")); 1980 return (DDI_FAILURE); 1981 } 1982 1983 bzero(instance->mfi_evt_detail_obj.buffer, 1984 sizeof (struct megasas_evt_detail)); 1985 1986 instance->mfi_evt_detail_obj.status |= DMA_OBJ_ALLOCATED; 1987 1988 return (DDI_SUCCESS); 1989 } 1990 1991 /* 1992 * free_space_for_mfi 1993 */ 1994 static void 1995 free_space_for_mfi(struct megasas_instance *instance) 1996 { 1997 int i; 1998 uint32_t max_cmd = instance->max_fw_cmds; 1999 2000 /* already freed */ 2001 if (instance->cmd_list == NULL) { 2002 return; 2003 } 2004 2005 free_additional_dma_buffer(instance); 2006 2007 /* first free the MFI frame pool */ 2008 destroy_mfi_frame_pool(instance); 2009 2010 /* free all the commands in the cmd_list */ 2011 for (i = 0; i < instance->max_fw_cmds; i++) { 2012 kmem_free(instance->cmd_list[i], 2013 sizeof (struct megasas_cmd)); 2014 2015 instance->cmd_list[i] = NULL; 2016 } 2017 2018 /* free the cmd_list buffer itself */ 2019 kmem_free(instance->cmd_list, 2020 sizeof (struct megasas_cmd *) * max_cmd); 2021 2022 instance->cmd_list = NULL; 2023 2024 INIT_LIST_HEAD(&instance->cmd_pool_list); 2025 } 2026 2027 /* 2028 * alloc_space_for_mfi 2029 */ 2030 static int 2031 alloc_space_for_mfi(struct megasas_instance *instance) 2032 { 2033 int i; 2034 uint32_t max_cmd; 2035 size_t sz; 2036 2037 struct megasas_cmd *cmd; 2038 2039 max_cmd = instance->max_fw_cmds; 2040 sz = sizeof (struct megasas_cmd *) * max_cmd; 2041 2042 /* 2043 * instance->cmd_list is an array of struct megasas_cmd pointers. 2044 * Allocate the dynamic array first and then allocate individual 2045 * commands. 2046 */ 2047 instance->cmd_list = kmem_zalloc(sz, KM_SLEEP); 2048 ASSERT(instance->cmd_list); 2049 2050 for (i = 0; i < max_cmd; i++) { 2051 instance->cmd_list[i] = kmem_zalloc(sizeof (struct megasas_cmd), 2052 KM_SLEEP); 2053 ASSERT(instance->cmd_list[i]); 2054 } 2055 2056 INIT_LIST_HEAD(&instance->cmd_pool_list); 2057 2058 /* add all the commands to command pool (instance->cmd_pool) */ 2059 for (i = 0; i < max_cmd; i++) { 2060 cmd = instance->cmd_list[i]; 2061 cmd->index = i; 2062 2063 mlist_add_tail(&cmd->list, &instance->cmd_pool_list); 2064 } 2065 2066 /* create a frame pool and assign one frame to each cmd */ 2067 if (create_mfi_frame_pool(instance)) { 2068 con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool\n")); 2069 return (DDI_FAILURE); 2070 } 2071 2072 /* create a frame pool and assign one frame to each cmd */ 2073 if (alloc_additional_dma_buffer(instance)) { 2074 con_log(CL_ANN, (CE_NOTE, "error creating frame DMA pool\n")); 2075 return (DDI_FAILURE); 2076 } 2077 2078 return (DDI_SUCCESS); 2079 } 2080 2081 /* 2082 * get_ctrl_info 2083 */ 2084 static int 2085 get_ctrl_info(struct megasas_instance *instance, 2086 struct megasas_ctrl_info *ctrl_info) 2087 { 2088 int ret = 0; 2089 2090 struct megasas_cmd *cmd; 2091 struct megasas_dcmd_frame *dcmd; 2092 struct megasas_ctrl_info *ci; 2093 2094 cmd = get_mfi_pkt(instance); 2095 2096 if (!cmd) { 2097 con_log(CL_ANN, (CE_WARN, 2098 "Failed to get a cmd for ctrl info\n")); 2099 return (DDI_FAILURE); 2100 } 2101 2102 dcmd = &cmd->frame->dcmd; 2103 2104 ci = (struct megasas_ctrl_info *)instance->internal_buf; 2105 2106 if (!ci) { 2107 con_log(CL_ANN, (CE_WARN, 2108 "Failed to alloc mem for ctrl info\n")); 2109 return_mfi_pkt(instance, cmd); 2110 return (DDI_FAILURE); 2111 } 2112 2113 (void) memset(ci, 0, sizeof (struct megasas_ctrl_info)); 2114 2115 /* for( i = 0; i < DCMD_MBOX_SZ; i++ ) dcmd->mbox.b[i] = 0; */ 2116 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ); 2117 2118 dcmd->cmd = MFI_CMD_OP_DCMD; 2119 dcmd->cmd_status = MFI_CMD_STATUS_POLL_MODE; 2120 dcmd->sge_count = 1; 2121 dcmd->flags = MFI_FRAME_DIR_READ; 2122 dcmd->timeout = 0; 2123 dcmd->data_xfer_len = sizeof (struct megasas_ctrl_info); 2124 dcmd->opcode = MR_DCMD_CTRL_GET_INFO; 2125 dcmd->sgl.sge32[0].phys_addr = instance->internal_buf_dmac_add; 2126 dcmd->sgl.sge32[0].length = sizeof (struct megasas_ctrl_info); 2127 2128 cmd->frame_count = 1; 2129 2130 if (!instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) { 2131 ret = 0; 2132 (void) memcpy(ctrl_info, ci, sizeof (struct megasas_ctrl_info)); 2133 } else { 2134 con_log(CL_ANN, (CE_WARN, "get_ctrl_info: Ctrl info failed\n")); 2135 ret = -1; 2136 } 2137 2138 return_mfi_pkt(instance, cmd); 2139 if (megasas_common_check(instance, cmd) != DDI_SUCCESS) { 2140 ret = -1; 2141 } 2142 2143 return (ret); 2144 } 2145 2146 /* 2147 * abort_aen_cmd 2148 */ 2149 static int 2150 abort_aen_cmd(struct megasas_instance *instance, 2151 struct megasas_cmd *cmd_to_abort) 2152 { 2153 int ret = 0; 2154 2155 struct megasas_cmd *cmd; 2156 struct megasas_abort_frame *abort_fr; 2157 2158 cmd = get_mfi_pkt(instance); 2159 2160 if (!cmd) { 2161 con_log(CL_ANN, (CE_WARN, 2162 "Failed to get a cmd for ctrl info\n")); 2163 return (DDI_FAILURE); 2164 } 2165 2166 abort_fr = &cmd->frame->abort; 2167 2168 /* prepare and issue the abort frame */ 2169 abort_fr->cmd = MFI_CMD_OP_ABORT; 2170 abort_fr->cmd_status = MFI_CMD_STATUS_SYNC_MODE; 2171 abort_fr->flags = 0; 2172 abort_fr->abort_context = cmd_to_abort->index; 2173 abort_fr->abort_mfi_phys_addr_lo = cmd_to_abort->frame_phys_addr; 2174 abort_fr->abort_mfi_phys_addr_hi = 0; 2175 2176 instance->aen_cmd->abort_aen = 1; 2177 2178 cmd->sync_cmd = MEGASAS_TRUE; 2179 cmd->frame_count = 1; 2180 2181 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) { 2182 con_log(CL_ANN, (CE_WARN, 2183 "abort_aen_cmd: issue_cmd_in_sync_mode failed\n")); 2184 ret = -1; 2185 } else { 2186 ret = 0; 2187 } 2188 2189 instance->aen_cmd->abort_aen = 1; 2190 instance->aen_cmd = 0; 2191 2192 return_mfi_pkt(instance, cmd); 2193 (void) megasas_common_check(instance, cmd); 2194 2195 return (ret); 2196 } 2197 2198 /* 2199 * init_mfi 2200 */ 2201 static int 2202 init_mfi(struct megasas_instance *instance) 2203 { 2204 off_t reglength; 2205 struct megasas_cmd *cmd; 2206 struct megasas_ctrl_info ctrl_info; 2207 struct megasas_init_frame *init_frame; 2208 struct megasas_init_queue_info *initq_info; 2209 2210 if ((ddi_dev_regsize(instance->dip, REGISTER_SET_IO, ®length) 2211 != DDI_SUCCESS) || reglength < MINIMUM_MFI_MEM_SZ) { 2212 return (DDI_FAILURE); 2213 } 2214 2215 if (reglength > DEFAULT_MFI_MEM_SZ) { 2216 reglength = DEFAULT_MFI_MEM_SZ; 2217 con_log(CL_DLEVEL1, (CE_NOTE, 2218 "mega: register length to map is 0x%lx bytes", reglength)); 2219 } 2220 2221 if (ddi_regs_map_setup(instance->dip, REGISTER_SET_IO, 2222 &instance->regmap, 0, reglength, &endian_attr, 2223 &instance->regmap_handle) != DDI_SUCCESS) { 2224 con_log(CL_ANN, (CE_NOTE, 2225 "megaraid: couldn't map control registers")); 2226 2227 goto fail_mfi_reg_setup; 2228 } 2229 2230 /* we expect the FW state to be READY */ 2231 if (mfi_state_transition_to_ready(instance)) { 2232 con_log(CL_ANN, (CE_WARN, "megaraid: F/W is not ready")); 2233 goto fail_ready_state; 2234 } 2235 2236 /* get various operational parameters from status register */ 2237 instance->max_num_sge = 2238 (instance->func_ptr->read_fw_status_reg(instance) & 2239 0xFF0000) >> 0x10; 2240 /* 2241 * Reduce the max supported cmds by 1. This is to ensure that the 2242 * reply_q_sz (1 more than the max cmd that driver may send) 2243 * does not exceed max cmds that the FW can support 2244 */ 2245 instance->max_fw_cmds = 2246 instance->func_ptr->read_fw_status_reg(instance) & 0xFFFF; 2247 instance->max_fw_cmds = instance->max_fw_cmds - 1; 2248 2249 instance->max_num_sge = 2250 (instance->max_num_sge > MEGASAS_MAX_SGE_CNT) ? 2251 MEGASAS_MAX_SGE_CNT : instance->max_num_sge; 2252 2253 /* create a pool of commands */ 2254 if (alloc_space_for_mfi(instance)) 2255 goto fail_alloc_fw_space; 2256 2257 /* disable interrupt for initial preparation */ 2258 instance->func_ptr->disable_intr(instance); 2259 2260 /* 2261 * Prepare a init frame. Note the init frame points to queue info 2262 * structure. Each frame has SGL allocated after first 64 bytes. For 2263 * this frame - since we don't need any SGL - we use SGL's space as 2264 * queue info structure 2265 */ 2266 cmd = get_mfi_pkt(instance); 2267 2268 init_frame = (struct megasas_init_frame *)cmd->frame; 2269 initq_info = (struct megasas_init_queue_info *) 2270 ((unsigned long)init_frame + 64); 2271 2272 (void) memset(init_frame, 0, MEGAMFI_FRAME_SIZE); 2273 (void) memset(initq_info, 0, sizeof (struct megasas_init_queue_info)); 2274 2275 initq_info->init_flags = 0; 2276 2277 initq_info->reply_queue_entries = instance->max_fw_cmds + 1; 2278 2279 initq_info->producer_index_phys_addr_hi = 0; 2280 initq_info->producer_index_phys_addr_lo = 2281 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address; 2282 2283 initq_info->consumer_index_phys_addr_hi = 0; 2284 initq_info->consumer_index_phys_addr_lo = 2285 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 4; 2286 2287 initq_info->reply_queue_start_phys_addr_hi = 0; 2288 initq_info->reply_queue_start_phys_addr_lo = 2289 instance->mfi_internal_dma_obj.dma_cookie[0].dmac_address + 8; 2290 2291 init_frame->cmd = MFI_CMD_OP_INIT; 2292 init_frame->cmd_status = MFI_CMD_STATUS_POLL_MODE; 2293 init_frame->flags = 0; 2294 init_frame->queue_info_new_phys_addr_lo = 2295 cmd->frame_phys_addr + 64; 2296 init_frame->queue_info_new_phys_addr_hi = 0; 2297 2298 init_frame->data_xfer_len = sizeof (struct megasas_init_queue_info); 2299 2300 cmd->frame_count = 1; 2301 2302 /* issue the init frame in polled mode */ 2303 if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) { 2304 con_log(CL_ANN, (CE_WARN, "failed to init firmware")); 2305 goto fail_fw_init; 2306 } 2307 2308 return_mfi_pkt(instance, cmd); 2309 if (megasas_common_check(instance, cmd) != DDI_SUCCESS) { 2310 goto fail_fw_init; 2311 } 2312 2313 /* gather misc FW related information */ 2314 if (!get_ctrl_info(instance, &ctrl_info)) { 2315 instance->max_sectors_per_req = ctrl_info.max_request_size; 2316 con_log(CL_ANN1, (CE_NOTE, "product name %s ld present %d", 2317 ctrl_info.product_name, ctrl_info.ld_present_count)); 2318 } else { 2319 instance->max_sectors_per_req = instance->max_num_sge * 2320 PAGESIZE / 512; 2321 } 2322 2323 if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) { 2324 goto fail_fw_init; 2325 } 2326 2327 return (0); 2328 2329 fail_fw_init: 2330 fail_alloc_fw_space: 2331 2332 free_space_for_mfi(instance); 2333 2334 fail_ready_state: 2335 ddi_regs_map_free(&instance->regmap_handle); 2336 2337 fail_mfi_reg_setup: 2338 return (DDI_FAILURE); 2339 } 2340 2341 /* 2342 * mfi_state_transition_to_ready : Move the FW to READY state 2343 * 2344 * @reg_set : MFI register set 2345 */ 2346 static int 2347 mfi_state_transition_to_ready(struct megasas_instance *instance) 2348 { 2349 int i; 2350 uint8_t max_wait; 2351 uint32_t fw_ctrl; 2352 uint32_t fw_state; 2353 uint32_t cur_state; 2354 2355 fw_state = 2356 instance->func_ptr->read_fw_status_reg(instance) & MFI_STATE_MASK; 2357 con_log(CL_ANN1, (CE_NOTE, 2358 "mfi_state_transition_to_ready:FW state = 0x%x", fw_state)); 2359 2360 while (fw_state != MFI_STATE_READY) { 2361 con_log(CL_ANN, (CE_NOTE, 2362 "mfi_state_transition_to_ready:FW state%x", fw_state)); 2363 2364 switch (fw_state) { 2365 case MFI_STATE_FAULT: 2366 con_log(CL_ANN, (CE_NOTE, 2367 "megasas: FW in FAULT state!!")); 2368 2369 return (-ENODEV); 2370 case MFI_STATE_WAIT_HANDSHAKE: 2371 /* set the CLR bit in IMR0 */ 2372 con_log(CL_ANN, (CE_NOTE, 2373 "megasas: FW waiting for HANDSHAKE")); 2374 /* 2375 * PCI_Hot Plug: MFI F/W requires 2376 * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG) 2377 * to be set 2378 */ 2379 /* WR_IB_MSG_0(MFI_INIT_CLEAR_HANDSHAKE, instance); */ 2380 WR_IB_DOORBELL(MFI_INIT_CLEAR_HANDSHAKE | 2381 MFI_INIT_HOTPLUG, instance); 2382 2383 max_wait = 2; 2384 cur_state = MFI_STATE_WAIT_HANDSHAKE; 2385 break; 2386 case MFI_STATE_BOOT_MESSAGE_PENDING: 2387 /* set the CLR bit in IMR0 */ 2388 con_log(CL_ANN, (CE_NOTE, 2389 "megasas: FW state boot message pending")); 2390 /* 2391 * PCI_Hot Plug: MFI F/W requires 2392 * (MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG) 2393 * to be set 2394 */ 2395 WR_IB_DOORBELL(MFI_INIT_HOTPLUG, instance); 2396 2397 max_wait = 10; 2398 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; 2399 break; 2400 case MFI_STATE_OPERATIONAL: 2401 /* bring it to READY state; assuming max wait 2 secs */ 2402 instance->func_ptr->disable_intr(instance); 2403 con_log(CL_ANN1, (CE_NOTE, 2404 "megasas: FW in OPERATIONAL state")); 2405 /* 2406 * PCI_Hot Plug: MFI F/W requires 2407 * (MFI_INIT_READY | MFI_INIT_MFIMODE | MFI_INIT_ABORT) 2408 * to be set 2409 */ 2410 /* WR_IB_DOORBELL(MFI_INIT_READY, instance); */ 2411 WR_IB_DOORBELL(MFI_RESET_FLAGS, instance); 2412 2413 max_wait = 10; 2414 cur_state = MFI_STATE_OPERATIONAL; 2415 break; 2416 case MFI_STATE_UNDEFINED: 2417 /* this state should not last for more than 2 seconds */ 2418 con_log(CL_ANN, (CE_NOTE, "FW state undefined\n")); 2419 2420 max_wait = 2; 2421 cur_state = MFI_STATE_UNDEFINED; 2422 break; 2423 case MFI_STATE_BB_INIT: 2424 max_wait = 2; 2425 cur_state = MFI_STATE_BB_INIT; 2426 break; 2427 case MFI_STATE_FW_INIT: 2428 max_wait = 2; 2429 cur_state = MFI_STATE_FW_INIT; 2430 break; 2431 case MFI_STATE_DEVICE_SCAN: 2432 max_wait = 10; 2433 cur_state = MFI_STATE_DEVICE_SCAN; 2434 break; 2435 default: 2436 con_log(CL_ANN, (CE_NOTE, 2437 "megasas: Unknown state 0x%x\n", fw_state)); 2438 return (-ENODEV); 2439 } 2440 2441 /* the cur_state should not last for more than max_wait secs */ 2442 for (i = 0; i < (max_wait * MILLISEC); i++) { 2443 /* fw_state = RD_OB_MSG_0(instance) & MFI_STATE_MASK; */ 2444 fw_state = 2445 instance->func_ptr->read_fw_status_reg(instance) & 2446 MFI_STATE_MASK; 2447 2448 if (fw_state == cur_state) { 2449 delay(1 * drv_usectohz(MILLISEC)); 2450 } else { 2451 break; 2452 } 2453 } 2454 2455 /* return error if fw_state hasn't changed after max_wait */ 2456 if (fw_state == cur_state) { 2457 con_log(CL_ANN, (CE_NOTE, 2458 "FW state hasn't changed in %d secs\n", max_wait)); 2459 return (-ENODEV); 2460 } 2461 }; 2462 2463 fw_ctrl = RD_IB_DOORBELL(instance); 2464 2465 con_log(CL_ANN1, (CE_NOTE, 2466 "mfi_state_transition_to_ready:FW ctrl = 0x%x", fw_ctrl)); 2467 2468 /* 2469 * Write 0xF to the doorbell register to do the following. 2470 * - Abort all outstanding commands (bit 0). 2471 * - Transition from OPERATIONAL to READY state (bit 1). 2472 * - Discard (possible) low MFA posted in 64-bit mode (bit-2). 2473 * - Set to release FW to continue running (i.e. BIOS handshake 2474 * (bit 3). 2475 */ 2476 WR_IB_DOORBELL(0xF, instance); 2477 2478 if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) { 2479 return (-ENODEV); 2480 } 2481 return (0); 2482 } 2483 2484 /* 2485 * get_seq_num 2486 */ 2487 static int 2488 get_seq_num(struct megasas_instance *instance, 2489 struct megasas_evt_log_info *eli) 2490 { 2491 int ret = 0; 2492 2493 dma_obj_t dcmd_dma_obj; 2494 struct megasas_cmd *cmd; 2495 struct megasas_dcmd_frame *dcmd; 2496 2497 cmd = get_mfi_pkt(instance); 2498 2499 if (!cmd) { 2500 cmn_err(CE_WARN, "megasas: failed to get a cmd\n"); 2501 return (-ENOMEM); 2502 } 2503 2504 dcmd = &cmd->frame->dcmd; 2505 2506 /* allocate the data transfer buffer */ 2507 dcmd_dma_obj.size = sizeof (struct megasas_evt_log_info); 2508 dcmd_dma_obj.dma_attr = megasas_generic_dma_attr; 2509 dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 2510 dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 2511 dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1; 2512 dcmd_dma_obj.dma_attr.dma_attr_align = 1; 2513 2514 if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) { 2515 con_log(CL_ANN, (CE_WARN, 2516 "get_seq_num: could not data transfer buffer alloc.")); 2517 return (DDI_FAILURE); 2518 } 2519 2520 (void) memset(dcmd_dma_obj.buffer, 0, 2521 sizeof (struct megasas_evt_log_info)); 2522 2523 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ); 2524 2525 dcmd->cmd = MFI_CMD_OP_DCMD; 2526 dcmd->cmd_status = 0; 2527 dcmd->sge_count = 1; 2528 dcmd->flags = MFI_FRAME_DIR_READ; 2529 dcmd->timeout = 0; 2530 dcmd->data_xfer_len = sizeof (struct megasas_evt_log_info); 2531 dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO; 2532 dcmd->sgl.sge32[0].length = sizeof (struct megasas_evt_log_info); 2533 dcmd->sgl.sge32[0].phys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address; 2534 2535 cmd->sync_cmd = MEGASAS_TRUE; 2536 cmd->frame_count = 1; 2537 2538 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) { 2539 cmn_err(CE_WARN, "get_seq_num: " 2540 "failed to issue MR_DCMD_CTRL_EVENT_GET_INFO\n"); 2541 ret = -1; 2542 } else { 2543 /* copy the data back into callers buffer */ 2544 bcopy(dcmd_dma_obj.buffer, eli, 2545 sizeof (struct megasas_evt_log_info)); 2546 ret = 0; 2547 } 2548 2549 if (mega_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS) 2550 ret = -1; 2551 2552 return_mfi_pkt(instance, cmd); 2553 if (megasas_common_check(instance, cmd) != DDI_SUCCESS) { 2554 ret = -1; 2555 } 2556 return (ret); 2557 } 2558 2559 /* 2560 * start_mfi_aen 2561 */ 2562 static int 2563 start_mfi_aen(struct megasas_instance *instance) 2564 { 2565 int ret = 0; 2566 2567 struct megasas_evt_log_info eli; 2568 union megasas_evt_class_locale class_locale; 2569 2570 /* get the latest sequence number from FW */ 2571 (void) memset(&eli, 0, sizeof (struct megasas_evt_log_info)); 2572 2573 if (get_seq_num(instance, &eli)) { 2574 cmn_err(CE_WARN, "start_mfi_aen: failed to get seq num\n"); 2575 return (-1); 2576 } 2577 2578 /* register AEN with FW for latest sequence number plus 1 */ 2579 class_locale.members.reserved = 0; 2580 class_locale.members.locale = MR_EVT_LOCALE_ALL; 2581 class_locale.members.class = MR_EVT_CLASS_CRITICAL; 2582 2583 ret = register_mfi_aen(instance, eli.newest_seq_num + 1, 2584 class_locale.word); 2585 2586 if (ret) { 2587 cmn_err(CE_WARN, "start_mfi_aen: aen registration failed\n"); 2588 return (-1); 2589 } 2590 2591 return (ret); 2592 } 2593 2594 /* 2595 * flush_cache 2596 */ 2597 static void 2598 flush_cache(struct megasas_instance *instance) 2599 { 2600 struct megasas_cmd *cmd; 2601 struct megasas_dcmd_frame *dcmd; 2602 2603 if (!(cmd = get_mfi_pkt(instance))) 2604 return; 2605 2606 dcmd = &cmd->frame->dcmd; 2607 2608 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ); 2609 2610 dcmd->cmd = MFI_CMD_OP_DCMD; 2611 dcmd->cmd_status = 0x0; 2612 dcmd->sge_count = 0; 2613 dcmd->flags = MFI_FRAME_DIR_NONE; 2614 dcmd->timeout = 0; 2615 dcmd->data_xfer_len = 0; 2616 dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH; 2617 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 2618 2619 cmd->frame_count = 1; 2620 2621 if (instance->func_ptr->issue_cmd_in_poll_mode(instance, cmd)) { 2622 cmn_err(CE_WARN, 2623 "flush_cache: failed to issue MFI_DCMD_CTRL_CACHE_FLUSH\n"); 2624 } 2625 con_log(CL_DLEVEL1, (CE_NOTE, "done")); 2626 return_mfi_pkt(instance, cmd); 2627 (void) megasas_common_check(instance, cmd); 2628 } 2629 2630 /* 2631 * service_mfi_aen- Completes an AEN command 2632 * @instance: Adapter soft state 2633 * @cmd: Command to be completed 2634 * 2635 */ 2636 static void 2637 service_mfi_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) 2638 { 2639 uint32_t seq_num; 2640 struct megasas_evt_detail *evt_detail = 2641 (struct megasas_evt_detail *)instance->mfi_evt_detail_obj.buffer; 2642 2643 cmd->cmd_status = cmd->frame->io.cmd_status; 2644 2645 if (cmd->cmd_status == ENODATA) { 2646 cmd->cmd_status = 0; 2647 } 2648 2649 /* 2650 * log the MFI AEN event to the sysevent queue so that 2651 * application will get noticed 2652 */ 2653 if (ddi_log_sysevent(instance->dip, DDI_VENDOR_LSI, "LSIMEGA", "SAS", 2654 NULL, NULL, DDI_NOSLEEP) != DDI_SUCCESS) { 2655 int instance_no = ddi_get_instance(instance->dip); 2656 con_log(CL_ANN, (CE_WARN, 2657 "mega%d: Failed to log AEN event", instance_no)); 2658 } 2659 2660 /* get copy of seq_num and class/locale for re-registration */ 2661 seq_num = evt_detail->seq_num; 2662 seq_num++; 2663 (void) memset(instance->mfi_evt_detail_obj.buffer, 0, 2664 sizeof (struct megasas_evt_detail)); 2665 2666 cmd->frame->dcmd.cmd_status = 0x0; 2667 cmd->frame->dcmd.mbox.w[0] = seq_num; 2668 2669 instance->aen_seq_num = seq_num; 2670 2671 cmd->frame_count = 1; 2672 2673 /* Issue the aen registration frame */ 2674 instance->func_ptr->issue_cmd(cmd, instance); 2675 } 2676 2677 /* 2678 * complete_cmd_in_sync_mode - Completes an internal command 2679 * @instance: Adapter soft state 2680 * @cmd: Command to be completed 2681 * 2682 * The issue_cmd_in_sync_mode() function waits for a command to complete 2683 * after it issues a command. This function wakes up that waiting routine by 2684 * calling wake_up() on the wait queue. 2685 */ 2686 static void 2687 complete_cmd_in_sync_mode(struct megasas_instance *instance, 2688 struct megasas_cmd *cmd) 2689 { 2690 cmd->cmd_status = cmd->frame->io.cmd_status; 2691 2692 cmd->sync_cmd = MEGASAS_FALSE; 2693 2694 if (cmd->cmd_status == ENODATA) { 2695 cmd->cmd_status = 0; 2696 } 2697 2698 cv_broadcast(&instance->int_cmd_cv); 2699 } 2700 2701 /* 2702 * megasas_softintr - The Software ISR 2703 * @param arg : HBA soft state 2704 * 2705 * called from high-level interrupt if hi-level interrupt are not there, 2706 * otherwise triggered as a soft interrupt 2707 */ 2708 static uint_t 2709 megasas_softintr(struct megasas_instance *instance) 2710 { 2711 struct scsi_pkt *pkt; 2712 struct scsa_cmd *acmd; 2713 struct megasas_cmd *cmd; 2714 struct mlist_head *pos, *next; 2715 mlist_t process_list; 2716 struct megasas_header *hdr; 2717 struct scsi_arq_status *arqstat; 2718 2719 con_log(CL_ANN1, (CE_CONT, "megasas_softintr called")); 2720 2721 ASSERT(instance); 2722 mutex_enter(&instance->completed_pool_mtx); 2723 2724 if (mlist_empty(&instance->completed_pool_list)) { 2725 mutex_exit(&instance->completed_pool_mtx); 2726 return (DDI_INTR_UNCLAIMED); 2727 } 2728 2729 instance->softint_running = 1; 2730 2731 INIT_LIST_HEAD(&process_list); 2732 mlist_splice(&instance->completed_pool_list, &process_list); 2733 INIT_LIST_HEAD(&instance->completed_pool_list); 2734 2735 mutex_exit(&instance->completed_pool_mtx); 2736 2737 /* perform all callbacks first, before releasing the SCBs */ 2738 mlist_for_each_safe(pos, next, &process_list) { 2739 cmd = mlist_entry(pos, struct megasas_cmd, list); 2740 2741 /* syncronize the Cmd frame for the controller */ 2742 (void) ddi_dma_sync(cmd->frame_dma_obj.dma_handle, 2743 0, 0, DDI_DMA_SYNC_FORCPU); 2744 2745 if (megasas_check_dma_handle(cmd->frame_dma_obj.dma_handle) != 2746 DDI_SUCCESS) { 2747 megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); 2748 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); 2749 return (DDI_INTR_UNCLAIMED); 2750 } 2751 2752 hdr = &cmd->frame->hdr; 2753 2754 /* remove the internal command from the process list */ 2755 mlist_del_init(&cmd->list); 2756 2757 switch (hdr->cmd) { 2758 case MFI_CMD_OP_PD_SCSI: 2759 case MFI_CMD_OP_LD_SCSI: 2760 case MFI_CMD_OP_LD_READ: 2761 case MFI_CMD_OP_LD_WRITE: 2762 /* 2763 * MFI_CMD_OP_PD_SCSI and MFI_CMD_OP_LD_SCSI 2764 * could have been issued either through an 2765 * IO path or an IOCTL path. If it was via IOCTL, 2766 * we will send it to internal completion. 2767 */ 2768 if (cmd->sync_cmd == MEGASAS_TRUE) { 2769 complete_cmd_in_sync_mode(instance, cmd); 2770 break; 2771 } 2772 2773 /* regular commands */ 2774 acmd = cmd->cmd; 2775 pkt = CMD2PKT(acmd); 2776 2777 if (acmd->cmd_flags & CFLAG_DMAVALID) { 2778 if (acmd->cmd_flags & CFLAG_CONSISTENT) { 2779 (void) ddi_dma_sync(acmd->cmd_dmahandle, 2780 acmd->cmd_dma_offset, 2781 acmd->cmd_dma_len, 2782 DDI_DMA_SYNC_FORCPU); 2783 } 2784 } 2785 2786 pkt->pkt_reason = CMD_CMPLT; 2787 pkt->pkt_statistics = 0; 2788 pkt->pkt_state = STATE_GOT_BUS 2789 | STATE_GOT_TARGET | STATE_SENT_CMD 2790 | STATE_XFERRED_DATA | STATE_GOT_STATUS; 2791 2792 con_log(CL_ANN1, (CE_CONT, 2793 "CDB[0] = %x completed for %s: size %lx context %x", 2794 pkt->pkt_cdbp[0], ((acmd->islogical) ? "LD" : "PD"), 2795 acmd->cmd_dmacount, hdr->context)); 2796 2797 if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) { 2798 struct scsi_inquiry *inq; 2799 2800 if (acmd->cmd_dmacount != 0) { 2801 bp_mapin(acmd->cmd_buf); 2802 inq = (struct scsi_inquiry *) 2803 acmd->cmd_buf->b_un.b_addr; 2804 2805 /* don't expose physical drives to OS */ 2806 if (acmd->islogical && 2807 (hdr->cmd_status == MFI_STAT_OK)) { 2808 display_scsi_inquiry( 2809 (caddr_t)inq); 2810 } else if ((hdr->cmd_status == 2811 MFI_STAT_OK) && inq->inq_dtype == 2812 DTYPE_DIRECT) { 2813 2814 display_scsi_inquiry( 2815 (caddr_t)inq); 2816 2817 /* for physical disk */ 2818 hdr->cmd_status = 2819 MFI_STAT_DEVICE_NOT_FOUND; 2820 } 2821 } 2822 } 2823 2824 switch (hdr->cmd_status) { 2825 case MFI_STAT_OK: 2826 pkt->pkt_scbp[0] = STATUS_GOOD; 2827 break; 2828 case MFI_STAT_LD_CC_IN_PROGRESS: 2829 case MFI_STAT_LD_RECON_IN_PROGRESS: 2830 /* SJ - these are not correct way */ 2831 pkt->pkt_scbp[0] = STATUS_GOOD; 2832 break; 2833 case MFI_STAT_LD_INIT_IN_PROGRESS: 2834 con_log(CL_ANN, 2835 (CE_WARN, "Initialization in Progress")); 2836 pkt->pkt_reason = CMD_TRAN_ERR; 2837 2838 break; 2839 case MFI_STAT_SCSI_DONE_WITH_ERROR: 2840 con_log(CL_ANN1, (CE_CONT, "scsi_done error")); 2841 2842 pkt->pkt_reason = CMD_CMPLT; 2843 ((struct scsi_status *) 2844 pkt->pkt_scbp)->sts_chk = 1; 2845 2846 if (pkt->pkt_cdbp[0] == SCMD_TEST_UNIT_READY) { 2847 2848 con_log(CL_ANN, 2849 (CE_WARN, "TEST_UNIT_READY fail")); 2850 2851 } else { 2852 pkt->pkt_state |= STATE_ARQ_DONE; 2853 arqstat = (void *)(pkt->pkt_scbp); 2854 arqstat->sts_rqpkt_reason = CMD_CMPLT; 2855 arqstat->sts_rqpkt_resid = 0; 2856 arqstat->sts_rqpkt_state |= 2857 STATE_GOT_BUS | STATE_GOT_TARGET 2858 | STATE_SENT_CMD 2859 | STATE_XFERRED_DATA; 2860 *(uint8_t *)&arqstat->sts_rqpkt_status = 2861 STATUS_GOOD; 2862 2863 bcopy(cmd->sense, 2864 &(arqstat->sts_sensedata), 2865 acmd->cmd_scblen - 2866 offsetof(struct scsi_arq_status, 2867 sts_sensedata)); 2868 } 2869 break; 2870 case MFI_STAT_LD_OFFLINE: 2871 case MFI_STAT_DEVICE_NOT_FOUND: 2872 con_log(CL_ANN1, (CE_CONT, 2873 "device not found error")); 2874 pkt->pkt_reason = CMD_DEV_GONE; 2875 pkt->pkt_statistics = STAT_DISCON; 2876 break; 2877 case MFI_STAT_LD_LBA_OUT_OF_RANGE: 2878 pkt->pkt_state |= STATE_ARQ_DONE; 2879 pkt->pkt_reason = CMD_CMPLT; 2880 ((struct scsi_status *) 2881 pkt->pkt_scbp)->sts_chk = 1; 2882 2883 arqstat = (void *)(pkt->pkt_scbp); 2884 arqstat->sts_rqpkt_reason = CMD_CMPLT; 2885 arqstat->sts_rqpkt_resid = 0; 2886 arqstat->sts_rqpkt_state |= STATE_GOT_BUS 2887 | STATE_GOT_TARGET | STATE_SENT_CMD 2888 | STATE_XFERRED_DATA; 2889 *(uint8_t *)&arqstat->sts_rqpkt_status = 2890 STATUS_GOOD; 2891 2892 arqstat->sts_sensedata.es_valid = 1; 2893 arqstat->sts_sensedata.es_key = 2894 KEY_ILLEGAL_REQUEST; 2895 arqstat->sts_sensedata.es_class = 2896 CLASS_EXTENDED_SENSE; 2897 2898 /* 2899 * LOGICAL BLOCK ADDRESS OUT OF RANGE: 2900 * ASC: 0x21h; ASCQ: 0x00h; 2901 */ 2902 arqstat->sts_sensedata.es_add_code = 0x21; 2903 arqstat->sts_sensedata.es_qual_code = 0x00; 2904 2905 break; 2906 2907 default: 2908 con_log(CL_ANN, (CE_CONT, "Unknown status!")); 2909 pkt->pkt_reason = CMD_TRAN_ERR; 2910 2911 break; 2912 } 2913 2914 atomic_add_16(&instance->fw_outstanding, (-1)); 2915 2916 return_mfi_pkt(instance, cmd); 2917 2918 (void) megasas_common_check(instance, cmd); 2919 2920 if (acmd->cmd_dmahandle) { 2921 if (megasas_check_dma_handle( 2922 acmd->cmd_dmahandle) != DDI_SUCCESS) { 2923 ddi_fm_service_impact(instance->dip, 2924 DDI_SERVICE_UNAFFECTED); 2925 pkt->pkt_reason = CMD_TRAN_ERR; 2926 pkt->pkt_statistics = 0; 2927 } 2928 } 2929 2930 /* Call the callback routine */ 2931 if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && 2932 pkt->pkt_comp) { 2933 (*pkt->pkt_comp)(pkt); 2934 } 2935 2936 break; 2937 case MFI_CMD_OP_SMP: 2938 case MFI_CMD_OP_STP: 2939 complete_cmd_in_sync_mode(instance, cmd); 2940 break; 2941 case MFI_CMD_OP_DCMD: 2942 /* see if got an event notification */ 2943 if (cmd->frame->dcmd.opcode == 2944 MR_DCMD_CTRL_EVENT_WAIT) { 2945 if ((instance->aen_cmd == cmd) && 2946 (instance->aen_cmd->abort_aen)) { 2947 con_log(CL_ANN, (CE_WARN, 2948 "megasas_softintr: " 2949 "aborted_aen returned")); 2950 } else { 2951 service_mfi_aen(instance, cmd); 2952 } 2953 } else { 2954 complete_cmd_in_sync_mode(instance, cmd); 2955 } 2956 2957 break; 2958 case MFI_CMD_OP_ABORT: 2959 con_log(CL_ANN, (CE_WARN, "MFI_CMD_OP_ABORT complete")); 2960 /* 2961 * MFI_CMD_OP_ABORT successfully completed 2962 * in the synchronous mode 2963 */ 2964 complete_cmd_in_sync_mode(instance, cmd); 2965 break; 2966 default: 2967 megasas_fm_ereport(instance, DDI_FM_DEVICE_NO_RESPONSE); 2968 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); 2969 2970 if (cmd->pkt != NULL) { 2971 pkt = cmd->pkt; 2972 if (((pkt->pkt_flags & FLAG_NOINTR) == 0) && 2973 pkt->pkt_comp) { 2974 (*pkt->pkt_comp)(pkt); 2975 } 2976 } 2977 con_log(CL_ANN, (CE_WARN, "Cmd type unknown !!")); 2978 break; 2979 } 2980 } 2981 2982 instance->softint_running = 0; 2983 2984 return (DDI_INTR_CLAIMED); 2985 } 2986 2987 /* 2988 * mega_alloc_dma_obj 2989 * 2990 * Allocate the memory and other resources for an dma object. 2991 */ 2992 static int 2993 mega_alloc_dma_obj(struct megasas_instance *instance, dma_obj_t *obj) 2994 { 2995 int i; 2996 size_t alen = 0; 2997 uint_t cookie_cnt; 2998 2999 i = ddi_dma_alloc_handle(instance->dip, &obj->dma_attr, 3000 DDI_DMA_SLEEP, NULL, &obj->dma_handle); 3001 if (i != DDI_SUCCESS) { 3002 3003 switch (i) { 3004 case DDI_DMA_BADATTR : 3005 con_log(CL_ANN, (CE_WARN, 3006 "Failed ddi_dma_alloc_handle- Bad atrib")); 3007 break; 3008 case DDI_DMA_NORESOURCES : 3009 con_log(CL_ANN, (CE_WARN, 3010 "Failed ddi_dma_alloc_handle- No Resources")); 3011 break; 3012 default : 3013 con_log(CL_ANN, (CE_WARN, 3014 "Failed ddi_dma_alloc_handle :unknown %d", i)); 3015 break; 3016 } 3017 3018 return (-1); 3019 } 3020 3021 if ((ddi_dma_mem_alloc(obj->dma_handle, obj->size, &endian_attr, 3022 DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, NULL, 3023 &obj->buffer, &alen, &obj->acc_handle) != DDI_SUCCESS) || 3024 alen < obj->size) { 3025 3026 ddi_dma_free_handle(&obj->dma_handle); 3027 3028 con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_mem_alloc")); 3029 3030 return (-1); 3031 } 3032 3033 if (ddi_dma_addr_bind_handle(obj->dma_handle, NULL, obj->buffer, 3034 obj->size, DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 3035 NULL, &obj->dma_cookie[0], &cookie_cnt) != DDI_SUCCESS) { 3036 3037 ddi_dma_mem_free(&obj->acc_handle); 3038 ddi_dma_free_handle(&obj->dma_handle); 3039 3040 con_log(CL_ANN, (CE_WARN, "Failed : ddi_dma_addr_bind_handle")); 3041 3042 return (-1); 3043 } 3044 3045 if (megasas_check_dma_handle(obj->dma_handle) != DDI_SUCCESS) { 3046 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); 3047 return (-1); 3048 } 3049 3050 if (megasas_check_acc_handle(obj->acc_handle) != DDI_SUCCESS) { 3051 ddi_fm_service_impact(instance->dip, DDI_SERVICE_LOST); 3052 return (-1); 3053 } 3054 3055 return (cookie_cnt); 3056 } 3057 3058 /* 3059 * mega_free_dma_obj(struct megasas_instance *, dma_obj_t) 3060 * 3061 * De-allocate the memory and other resources for an dma object, which must 3062 * have been alloated by a previous call to mega_alloc_dma_obj() 3063 */ 3064 static int 3065 mega_free_dma_obj(struct megasas_instance *instance, dma_obj_t obj) 3066 { 3067 3068 if (megasas_check_dma_handle(obj.dma_handle) != DDI_SUCCESS) { 3069 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); 3070 return (DDI_FAILURE); 3071 } 3072 3073 if (megasas_check_acc_handle(obj.acc_handle) != DDI_SUCCESS) { 3074 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); 3075 return (DDI_FAILURE); 3076 } 3077 3078 (void) ddi_dma_unbind_handle(obj.dma_handle); 3079 ddi_dma_mem_free(&obj.acc_handle); 3080 ddi_dma_free_handle(&obj.dma_handle); 3081 3082 return (DDI_SUCCESS); 3083 } 3084 3085 /* 3086 * megasas_dma_alloc(instance_t *, struct scsi_pkt *, struct buf *, 3087 * int, int (*)()) 3088 * 3089 * Allocate dma resources for a new scsi command 3090 */ 3091 static int 3092 megasas_dma_alloc(struct megasas_instance *instance, struct scsi_pkt *pkt, 3093 struct buf *bp, int flags, int (*callback)()) 3094 { 3095 int dma_flags; 3096 int (*cb)(caddr_t); 3097 int i; 3098 3099 ddi_dma_attr_t tmp_dma_attr = megasas_generic_dma_attr; 3100 struct scsa_cmd *acmd = PKT2CMD(pkt); 3101 3102 acmd->cmd_buf = bp; 3103 3104 if (bp->b_flags & B_READ) { 3105 acmd->cmd_flags &= ~CFLAG_DMASEND; 3106 dma_flags = DDI_DMA_READ; 3107 } else { 3108 acmd->cmd_flags |= CFLAG_DMASEND; 3109 dma_flags = DDI_DMA_WRITE; 3110 } 3111 3112 if (flags & PKT_CONSISTENT) { 3113 acmd->cmd_flags |= CFLAG_CONSISTENT; 3114 dma_flags |= DDI_DMA_CONSISTENT; 3115 } 3116 3117 if (flags & PKT_DMA_PARTIAL) { 3118 dma_flags |= DDI_DMA_PARTIAL; 3119 } 3120 3121 dma_flags |= DDI_DMA_REDZONE; 3122 3123 cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP; 3124 3125 tmp_dma_attr.dma_attr_sgllen = instance->max_num_sge; 3126 tmp_dma_attr.dma_attr_addr_hi = 0xffffffffffffffffull; 3127 3128 if ((i = ddi_dma_alloc_handle(instance->dip, &tmp_dma_attr, 3129 cb, 0, &acmd->cmd_dmahandle)) != DDI_SUCCESS) { 3130 switch (i) { 3131 case DDI_DMA_BADATTR: 3132 bioerror(bp, EFAULT); 3133 return (-1); 3134 3135 case DDI_DMA_NORESOURCES: 3136 bioerror(bp, 0); 3137 return (-1); 3138 3139 default: 3140 con_log(CL_ANN, (CE_PANIC, "ddi_dma_alloc_handle: " 3141 "0x%x impossible\n", i)); 3142 bioerror(bp, EFAULT); 3143 return (-1); 3144 } 3145 } 3146 3147 i = ddi_dma_buf_bind_handle(acmd->cmd_dmahandle, bp, dma_flags, 3148 cb, 0, &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies); 3149 3150 switch (i) { 3151 case DDI_DMA_PARTIAL_MAP: 3152 if ((dma_flags & DDI_DMA_PARTIAL) == 0) { 3153 con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: " 3154 "DDI_DMA_PARTIAL_MAP impossible\n")); 3155 goto no_dma_cookies; 3156 } 3157 3158 if (ddi_dma_numwin(acmd->cmd_dmahandle, &acmd->cmd_nwin) == 3159 DDI_FAILURE) { 3160 con_log(CL_ANN, (CE_PANIC, "ddi_dma_numwin failed\n")); 3161 goto no_dma_cookies; 3162 } 3163 3164 if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin, 3165 &acmd->cmd_dma_offset, &acmd->cmd_dma_len, 3166 &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) == 3167 DDI_FAILURE) { 3168 3169 con_log(CL_ANN, (CE_PANIC, "ddi_dma_getwin failed\n")); 3170 goto no_dma_cookies; 3171 } 3172 3173 goto get_dma_cookies; 3174 case DDI_DMA_MAPPED: 3175 acmd->cmd_nwin = 1; 3176 acmd->cmd_dma_len = 0; 3177 acmd->cmd_dma_offset = 0; 3178 3179 get_dma_cookies: 3180 i = 0; 3181 acmd->cmd_dmacount = 0; 3182 for (;;) { 3183 acmd->cmd_dmacount += 3184 acmd->cmd_dmacookies[i++].dmac_size; 3185 3186 if (i == instance->max_num_sge || 3187 i == acmd->cmd_ncookies) 3188 break; 3189 3190 ddi_dma_nextcookie(acmd->cmd_dmahandle, 3191 &acmd->cmd_dmacookies[i]); 3192 } 3193 3194 acmd->cmd_cookie = i; 3195 acmd->cmd_cookiecnt = i; 3196 3197 acmd->cmd_flags |= CFLAG_DMAVALID; 3198 3199 if (bp->b_bcount >= acmd->cmd_dmacount) { 3200 pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount; 3201 } else { 3202 pkt->pkt_resid = 0; 3203 } 3204 3205 return (0); 3206 case DDI_DMA_NORESOURCES: 3207 bioerror(bp, 0); 3208 break; 3209 case DDI_DMA_NOMAPPING: 3210 bioerror(bp, EFAULT); 3211 break; 3212 case DDI_DMA_TOOBIG: 3213 bioerror(bp, EINVAL); 3214 break; 3215 case DDI_DMA_INUSE: 3216 con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle:" 3217 " DDI_DMA_INUSE impossible\n")); 3218 break; 3219 default: 3220 con_log(CL_ANN, (CE_PANIC, "ddi_dma_buf_bind_handle: " 3221 "0x%x impossible\n", i)); 3222 break; 3223 } 3224 3225 no_dma_cookies: 3226 ddi_dma_free_handle(&acmd->cmd_dmahandle); 3227 acmd->cmd_dmahandle = NULL; 3228 acmd->cmd_flags &= ~CFLAG_DMAVALID; 3229 return (-1); 3230 } 3231 3232 /* 3233 * megasas_dma_move(struct megasas_instance *, struct scsi_pkt *, struct buf *) 3234 * 3235 * move dma resources to next dma window 3236 * 3237 */ 3238 static int 3239 megasas_dma_move(struct megasas_instance *instance, struct scsi_pkt *pkt, 3240 struct buf *bp) 3241 { 3242 int i = 0; 3243 3244 struct scsa_cmd *acmd = PKT2CMD(pkt); 3245 3246 /* 3247 * If there are no more cookies remaining in this window, 3248 * must move to the next window first. 3249 */ 3250 if (acmd->cmd_cookie == acmd->cmd_ncookies) { 3251 if (acmd->cmd_curwin == acmd->cmd_nwin && acmd->cmd_nwin == 1) { 3252 return (0); 3253 } 3254 3255 /* at last window, cannot move */ 3256 if (++acmd->cmd_curwin >= acmd->cmd_nwin) { 3257 return (-1); 3258 } 3259 3260 if (ddi_dma_getwin(acmd->cmd_dmahandle, acmd->cmd_curwin, 3261 &acmd->cmd_dma_offset, &acmd->cmd_dma_len, 3262 &acmd->cmd_dmacookies[0], &acmd->cmd_ncookies) == 3263 DDI_FAILURE) { 3264 return (-1); 3265 } 3266 3267 acmd->cmd_cookie = 0; 3268 } else { 3269 /* still more cookies in this window - get the next one */ 3270 ddi_dma_nextcookie(acmd->cmd_dmahandle, 3271 &acmd->cmd_dmacookies[0]); 3272 } 3273 3274 /* get remaining cookies in this window, up to our maximum */ 3275 for (;;) { 3276 acmd->cmd_dmacount += acmd->cmd_dmacookies[i++].dmac_size; 3277 acmd->cmd_cookie++; 3278 3279 if (i == instance->max_num_sge || 3280 acmd->cmd_cookie == acmd->cmd_ncookies) { 3281 break; 3282 } 3283 3284 ddi_dma_nextcookie(acmd->cmd_dmahandle, 3285 &acmd->cmd_dmacookies[i]); 3286 } 3287 3288 acmd->cmd_cookiecnt = i; 3289 3290 if (bp->b_bcount >= acmd->cmd_dmacount) { 3291 pkt->pkt_resid = bp->b_bcount - acmd->cmd_dmacount; 3292 } else { 3293 pkt->pkt_resid = 0; 3294 } 3295 3296 return (0); 3297 } 3298 3299 /* 3300 * build_cmd 3301 */ 3302 static struct megasas_cmd * 3303 build_cmd(struct megasas_instance *instance, struct scsi_address *ap, 3304 struct scsi_pkt *pkt, uchar_t *cmd_done) 3305 { 3306 uint16_t flags = 0; 3307 uint32_t i; 3308 uint32_t context; 3309 uint32_t sge_bytes; 3310 3311 struct megasas_cmd *cmd; 3312 struct megasas_sge64 *mfi_sgl; 3313 struct scsa_cmd *acmd = PKT2CMD(pkt); 3314 struct megasas_pthru_frame *pthru; 3315 struct megasas_io_frame *ldio; 3316 3317 /* find out if this is logical or physical drive command. */ 3318 acmd->islogical = MEGADRV_IS_LOGICAL(ap); 3319 acmd->device_id = MAP_DEVICE_ID(instance, ap); 3320 *cmd_done = 0; 3321 3322 /* get the command packet */ 3323 if (!(cmd = get_mfi_pkt(instance))) { 3324 return (NULL); 3325 } 3326 3327 cmd->pkt = pkt; 3328 cmd->cmd = acmd; 3329 3330 /* lets get the command directions */ 3331 if (acmd->cmd_flags & CFLAG_DMASEND) { 3332 flags = MFI_FRAME_DIR_WRITE; 3333 3334 if (acmd->cmd_flags & CFLAG_CONSISTENT) { 3335 (void) ddi_dma_sync(acmd->cmd_dmahandle, 3336 acmd->cmd_dma_offset, acmd->cmd_dma_len, 3337 DDI_DMA_SYNC_FORDEV); 3338 } 3339 } else if (acmd->cmd_flags & ~CFLAG_DMASEND) { 3340 flags = MFI_FRAME_DIR_READ; 3341 3342 if (acmd->cmd_flags & CFLAG_CONSISTENT) { 3343 (void) ddi_dma_sync(acmd->cmd_dmahandle, 3344 acmd->cmd_dma_offset, acmd->cmd_dma_len, 3345 DDI_DMA_SYNC_FORCPU); 3346 } 3347 } else { 3348 flags = MFI_FRAME_DIR_NONE; 3349 } 3350 3351 flags |= MFI_FRAME_SGL64; 3352 3353 switch (pkt->pkt_cdbp[0]) { 3354 3355 /* 3356 * case SCMD_SYNCHRONIZE_CACHE: 3357 * flush_cache(instance); 3358 * return_mfi_pkt(instance, cmd); 3359 * *cmd_done = 1; 3360 * 3361 * return (NULL); 3362 */ 3363 3364 case SCMD_READ: 3365 case SCMD_WRITE: 3366 case SCMD_READ_G1: 3367 case SCMD_WRITE_G1: 3368 if (acmd->islogical) { 3369 ldio = (struct megasas_io_frame *)cmd->frame; 3370 3371 /* 3372 * preare the Logical IO frame: 3373 * 2nd bit is zero for all read cmds 3374 */ 3375 ldio->cmd = (pkt->pkt_cdbp[0] & 0x02) ? 3376 MFI_CMD_OP_LD_WRITE : MFI_CMD_OP_LD_READ; 3377 ldio->cmd_status = 0x0; 3378 ldio->scsi_status = 0x0; 3379 ldio->target_id = acmd->device_id; 3380 ldio->timeout = 0; 3381 ldio->reserved_0 = 0; 3382 ldio->pad_0 = 0; 3383 ldio->flags = flags; 3384 3385 /* Initialize sense Information */ 3386 bzero(cmd->sense, SENSE_LENGTH); 3387 ldio->sense_len = SENSE_LENGTH; 3388 ldio->sense_buf_phys_addr_hi = 0; 3389 ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr; 3390 3391 ldio->start_lba_hi = 0; 3392 ldio->access_byte = (acmd->cmd_cdblen != 6) ? 3393 pkt->pkt_cdbp[1] : 0; 3394 ldio->sge_count = acmd->cmd_cookiecnt; 3395 mfi_sgl = (struct megasas_sge64 *)&ldio->sgl; 3396 3397 context = ldio->context; 3398 3399 if (acmd->cmd_cdblen == CDB_GROUP0) { 3400 ldio->lba_count = host_to_le16( 3401 (uint16_t)(pkt->pkt_cdbp[4])); 3402 3403 ldio->start_lba_lo = host_to_le32( 3404 ((uint32_t)(pkt->pkt_cdbp[3])) | 3405 ((uint32_t)(pkt->pkt_cdbp[2]) << 8) | 3406 ((uint32_t)((pkt->pkt_cdbp[1]) & 0x1F) 3407 << 16)); 3408 } else if (acmd->cmd_cdblen == CDB_GROUP1) { 3409 ldio->lba_count = host_to_le16( 3410 ((uint16_t)(pkt->pkt_cdbp[8])) | 3411 ((uint16_t)(pkt->pkt_cdbp[7]) << 8)); 3412 3413 ldio->start_lba_lo = host_to_le32( 3414 ((uint32_t)(pkt->pkt_cdbp[5])) | 3415 ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | 3416 ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | 3417 ((uint32_t)(pkt->pkt_cdbp[2]) << 24)); 3418 } else if (acmd->cmd_cdblen == CDB_GROUP2) { 3419 ldio->lba_count = host_to_le16( 3420 ((uint16_t)(pkt->pkt_cdbp[9])) | 3421 ((uint16_t)(pkt->pkt_cdbp[8]) << 8) | 3422 ((uint16_t)(pkt->pkt_cdbp[7]) << 16) | 3423 ((uint16_t)(pkt->pkt_cdbp[6]) << 24)); 3424 3425 ldio->start_lba_lo = host_to_le32( 3426 ((uint32_t)(pkt->pkt_cdbp[5])) | 3427 ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | 3428 ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | 3429 ((uint32_t)(pkt->pkt_cdbp[2]) << 24)); 3430 } else if (acmd->cmd_cdblen == CDB_GROUP3) { 3431 ldio->lba_count = host_to_le16( 3432 ((uint16_t)(pkt->pkt_cdbp[13])) | 3433 ((uint16_t)(pkt->pkt_cdbp[12]) << 8) | 3434 ((uint16_t)(pkt->pkt_cdbp[11]) << 16) | 3435 ((uint16_t)(pkt->pkt_cdbp[10]) << 24)); 3436 3437 ldio->start_lba_lo = host_to_le32( 3438 ((uint32_t)(pkt->pkt_cdbp[9])) | 3439 ((uint32_t)(pkt->pkt_cdbp[8]) << 8) | 3440 ((uint32_t)(pkt->pkt_cdbp[7]) << 16) | 3441 ((uint32_t)(pkt->pkt_cdbp[6]) << 24)); 3442 3443 ldio->start_lba_lo = host_to_le32( 3444 ((uint32_t)(pkt->pkt_cdbp[5])) | 3445 ((uint32_t)(pkt->pkt_cdbp[4]) << 8) | 3446 ((uint32_t)(pkt->pkt_cdbp[3]) << 16) | 3447 ((uint32_t)(pkt->pkt_cdbp[2]) << 24)); 3448 } 3449 3450 break; 3451 } 3452 /* fall through For all non-rd/wr cmds */ 3453 default: 3454 pthru = (struct megasas_pthru_frame *)cmd->frame; 3455 3456 /* prepare the DCDB frame */ 3457 pthru->cmd = (acmd->islogical) ? 3458 MFI_CMD_OP_LD_SCSI : MFI_CMD_OP_PD_SCSI; 3459 pthru->cmd_status = 0x0; 3460 pthru->scsi_status = 0x0; 3461 pthru->target_id = acmd->device_id; 3462 pthru->lun = 0; 3463 pthru->cdb_len = acmd->cmd_cdblen; 3464 pthru->timeout = 0; 3465 pthru->flags = flags; 3466 pthru->data_xfer_len = acmd->cmd_dmacount; 3467 pthru->sge_count = acmd->cmd_cookiecnt; 3468 mfi_sgl = (struct megasas_sge64 *)&pthru->sgl; 3469 3470 bzero(cmd->sense, SENSE_LENGTH); 3471 pthru->sense_len = SENSE_LENGTH; 3472 pthru->sense_buf_phys_addr_hi = 0; 3473 pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; 3474 3475 context = pthru->context; 3476 3477 bcopy(pkt->pkt_cdbp, pthru->cdb, acmd->cmd_cdblen); 3478 3479 break; 3480 } 3481 #ifdef lint 3482 context = context; 3483 #endif 3484 /* bzero(mfi_sgl, sizeof (struct megasas_sge64) * MAX_SGL); */ 3485 3486 /* prepare the scatter-gather list for the firmware */ 3487 for (i = 0; i < acmd->cmd_cookiecnt; i++, mfi_sgl++) { 3488 mfi_sgl->phys_addr = acmd->cmd_dmacookies[i].dmac_laddress; 3489 mfi_sgl->length = acmd->cmd_dmacookies[i].dmac_size; 3490 } 3491 3492 sge_bytes = sizeof (struct megasas_sge64)*acmd->cmd_cookiecnt; 3493 3494 cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) + 3495 ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1; 3496 3497 if (cmd->frame_count >= 8) { 3498 cmd->frame_count = 8; 3499 } 3500 3501 return (cmd); 3502 } 3503 3504 /* 3505 * wait_for_outstanding - Wait for all outstanding cmds 3506 * @instance: Adapter soft state 3507 * 3508 * This function waits for upto MEGASAS_RESET_WAIT_TIME seconds for FW to 3509 * complete all its outstanding commands. Returns error if one or more IOs 3510 * are pending after this time period. 3511 */ 3512 static int 3513 wait_for_outstanding(struct megasas_instance *instance) 3514 { 3515 int i; 3516 uint32_t wait_time = 90; 3517 3518 for (i = 0; i < wait_time; i++) { 3519 if (!instance->fw_outstanding) { 3520 break; 3521 } 3522 3523 drv_usecwait(MILLISEC); /* wait for 1000 usecs */; 3524 } 3525 3526 if (instance->fw_outstanding) { 3527 return (1); 3528 } 3529 3530 ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VERSION); 3531 3532 return (0); 3533 } 3534 3535 /* 3536 * issue_mfi_pthru 3537 */ 3538 static int 3539 issue_mfi_pthru(struct megasas_instance *instance, struct megasas_ioctl *ioctl, 3540 struct megasas_cmd *cmd, int mode) 3541 { 3542 void *ubuf; 3543 uint32_t kphys_addr = 0; 3544 uint32_t xferlen = 0; 3545 uint_t model; 3546 3547 dma_obj_t pthru_dma_obj; 3548 struct megasas_pthru_frame *kpthru; 3549 struct megasas_pthru_frame *pthru; 3550 3551 pthru = &cmd->frame->pthru; 3552 kpthru = (struct megasas_pthru_frame *)&ioctl->frame[0]; 3553 3554 model = ddi_model_convert_from(mode & FMODELS); 3555 if (model == DDI_MODEL_ILP32) { 3556 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32")); 3557 3558 xferlen = kpthru->sgl.sge32[0].length; 3559 3560 /* SJ! - ubuf needs to be virtual address. */ 3561 ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr; 3562 } else { 3563 #ifdef _ILP32 3564 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP32")); 3565 xferlen = kpthru->sgl.sge32[0].length; 3566 /* SJ! - ubuf needs to be virtual address. */ 3567 ubuf = (void *)(ulong_t)kpthru->sgl.sge32[0].phys_addr; 3568 #else 3569 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_pthru: DDI_MODEL_LP64")); 3570 xferlen = kpthru->sgl.sge64[0].length; 3571 /* SJ! - ubuf needs to be virtual address. */ 3572 ubuf = (void *)(ulong_t)kpthru->sgl.sge64[0].phys_addr; 3573 #endif 3574 } 3575 3576 if (xferlen) { 3577 /* means IOCTL requires DMA */ 3578 /* allocate the data transfer buffer */ 3579 pthru_dma_obj.size = xferlen; 3580 pthru_dma_obj.dma_attr = megasas_generic_dma_attr; 3581 pthru_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 3582 pthru_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 3583 pthru_dma_obj.dma_attr.dma_attr_sgllen = 1; 3584 pthru_dma_obj.dma_attr.dma_attr_align = 1; 3585 3586 /* allocate kernel buffer for DMA */ 3587 if (mega_alloc_dma_obj(instance, &pthru_dma_obj) != 1) { 3588 con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: " 3589 "could not data transfer buffer alloc.")); 3590 return (DDI_FAILURE); 3591 } 3592 3593 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ 3594 if (kpthru->flags & MFI_FRAME_DIR_WRITE) { 3595 if (ddi_copyin(ubuf, (void *)pthru_dma_obj.buffer, 3596 xferlen, mode)) { 3597 con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: " 3598 "copy from user space failed\n")); 3599 return (1); 3600 } 3601 } 3602 3603 kphys_addr = pthru_dma_obj.dma_cookie[0].dmac_address; 3604 } 3605 3606 pthru->cmd = kpthru->cmd; 3607 pthru->sense_len = kpthru->sense_len; 3608 pthru->cmd_status = kpthru->cmd_status; 3609 pthru->scsi_status = kpthru->scsi_status; 3610 pthru->target_id = kpthru->target_id; 3611 pthru->lun = kpthru->lun; 3612 pthru->cdb_len = kpthru->cdb_len; 3613 pthru->sge_count = kpthru->sge_count; 3614 pthru->timeout = kpthru->timeout; 3615 pthru->data_xfer_len = kpthru->data_xfer_len; 3616 3617 pthru->sense_buf_phys_addr_hi = 0; 3618 /* pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr; */ 3619 pthru->sense_buf_phys_addr_lo = 0; 3620 3621 bcopy((void *)kpthru->cdb, (void *)pthru->cdb, pthru->cdb_len); 3622 3623 pthru->flags = kpthru->flags & ~MFI_FRAME_SGL64; 3624 pthru->sgl.sge32[0].length = xferlen; 3625 pthru->sgl.sge32[0].phys_addr = kphys_addr; 3626 3627 cmd->sync_cmd = MEGASAS_TRUE; 3628 cmd->frame_count = 1; 3629 3630 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) { 3631 con_log(CL_ANN, (CE_WARN, 3632 "issue_mfi_pthru: fw_ioctl failed\n")); 3633 } else { 3634 if (xferlen && (kpthru->flags & MFI_FRAME_DIR_READ)) { 3635 3636 if (ddi_copyout(pthru_dma_obj.buffer, ubuf, 3637 xferlen, mode)) { 3638 con_log(CL_ANN, (CE_WARN, "issue_mfi_pthru: " 3639 "copy to user space failed\n")); 3640 return (1); 3641 } 3642 } 3643 } 3644 3645 kpthru->cmd_status = pthru->cmd_status; 3646 kpthru->scsi_status = pthru->scsi_status; 3647 3648 con_log(CL_ANN, (CE_NOTE, "issue_mfi_pthru: cmd_status %x, " 3649 "scsi_status %x\n", pthru->cmd_status, pthru->scsi_status)); 3650 3651 if (xferlen) { 3652 /* free kernel buffer */ 3653 if (mega_free_dma_obj(instance, pthru_dma_obj) != DDI_SUCCESS) 3654 return (1); 3655 } 3656 3657 return (0); 3658 } 3659 3660 /* 3661 * issue_mfi_dcmd 3662 */ 3663 static int 3664 issue_mfi_dcmd(struct megasas_instance *instance, struct megasas_ioctl *ioctl, 3665 struct megasas_cmd *cmd, int mode) 3666 { 3667 void *ubuf; 3668 uint32_t kphys_addr = 0; 3669 uint32_t xferlen = 0; 3670 uint32_t model; 3671 dma_obj_t dcmd_dma_obj; 3672 struct megasas_dcmd_frame *kdcmd; 3673 struct megasas_dcmd_frame *dcmd; 3674 3675 dcmd = &cmd->frame->dcmd; 3676 kdcmd = (struct megasas_dcmd_frame *)&ioctl->frame[0]; 3677 3678 model = ddi_model_convert_from(mode & FMODELS); 3679 if (model == DDI_MODEL_ILP32) { 3680 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32")); 3681 3682 xferlen = kdcmd->sgl.sge32[0].length; 3683 3684 /* SJ! - ubuf needs to be virtual address. */ 3685 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr; 3686 } 3687 else 3688 { 3689 #ifdef _ILP32 3690 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_ILP32")); 3691 xferlen = kdcmd->sgl.sge32[0].length; 3692 /* SJ! - ubuf needs to be virtual address. */ 3693 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr; 3694 #else 3695 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_dcmd: DDI_MODEL_LP64")); 3696 xferlen = kdcmd->sgl.sge64[0].length; 3697 /* SJ! - ubuf needs to be virtual address. */ 3698 ubuf = (void *)(ulong_t)dcmd->sgl.sge64[0].phys_addr; 3699 #endif 3700 } 3701 if (xferlen) { 3702 /* means IOCTL requires DMA */ 3703 /* allocate the data transfer buffer */ 3704 dcmd_dma_obj.size = xferlen; 3705 dcmd_dma_obj.dma_attr = megasas_generic_dma_attr; 3706 dcmd_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 3707 dcmd_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 3708 dcmd_dma_obj.dma_attr.dma_attr_sgllen = 1; 3709 dcmd_dma_obj.dma_attr.dma_attr_align = 1; 3710 3711 /* allocate kernel buffer for DMA */ 3712 if (mega_alloc_dma_obj(instance, &dcmd_dma_obj) != 1) { 3713 con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: " 3714 "could not data transfer buffer alloc.")); 3715 return (DDI_FAILURE); 3716 } 3717 3718 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ 3719 if (kdcmd->flags & MFI_FRAME_DIR_WRITE) { 3720 if (ddi_copyin(ubuf, (void *)dcmd_dma_obj.buffer, 3721 xferlen, mode)) { 3722 con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: " 3723 "copy from user space failed\n")); 3724 return (1); 3725 } 3726 } 3727 3728 kphys_addr = dcmd_dma_obj.dma_cookie[0].dmac_address; 3729 } 3730 3731 dcmd->cmd = kdcmd->cmd; 3732 dcmd->cmd_status = kdcmd->cmd_status; 3733 dcmd->sge_count = kdcmd->sge_count; 3734 dcmd->timeout = kdcmd->timeout; 3735 dcmd->data_xfer_len = kdcmd->data_xfer_len; 3736 dcmd->opcode = kdcmd->opcode; 3737 3738 bcopy((void *)kdcmd->mbox.b, (void *)dcmd->mbox.b, DCMD_MBOX_SZ); 3739 3740 dcmd->flags = kdcmd->flags & ~MFI_FRAME_SGL64; 3741 dcmd->sgl.sge32[0].length = xferlen; 3742 dcmd->sgl.sge32[0].phys_addr = kphys_addr; 3743 3744 cmd->sync_cmd = MEGASAS_TRUE; 3745 cmd->frame_count = 1; 3746 3747 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) { 3748 con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: fw_ioctl failed\n")); 3749 } else { 3750 if (xferlen && (kdcmd->flags & MFI_FRAME_DIR_READ)) { 3751 3752 if (ddi_copyout(dcmd_dma_obj.buffer, ubuf, 3753 xferlen, mode)) { 3754 con_log(CL_ANN, (CE_WARN, "issue_mfi_dcmd: " 3755 "copy to user space failed\n")); 3756 return (1); 3757 } 3758 } 3759 } 3760 3761 kdcmd->cmd_status = dcmd->cmd_status; 3762 3763 if (xferlen) { 3764 /* free kernel buffer */ 3765 if (mega_free_dma_obj(instance, dcmd_dma_obj) != DDI_SUCCESS) 3766 return (1); 3767 } 3768 3769 return (0); 3770 } 3771 3772 /* 3773 * issue_mfi_smp 3774 */ 3775 static int 3776 issue_mfi_smp(struct megasas_instance *instance, struct megasas_ioctl *ioctl, 3777 struct megasas_cmd *cmd, int mode) 3778 { 3779 void *request_ubuf; 3780 void *response_ubuf; 3781 uint32_t request_xferlen = 0; 3782 uint32_t response_xferlen = 0; 3783 uint_t model; 3784 dma_obj_t request_dma_obj; 3785 dma_obj_t response_dma_obj; 3786 struct megasas_smp_frame *ksmp; 3787 struct megasas_smp_frame *smp; 3788 struct megasas_sge32 *sge32; 3789 #ifndef _ILP32 3790 struct megasas_sge64 *sge64; 3791 #endif 3792 3793 smp = &cmd->frame->smp; 3794 ksmp = (struct megasas_smp_frame *)&ioctl->frame[0]; 3795 3796 model = ddi_model_convert_from(mode & FMODELS); 3797 if (model == DDI_MODEL_ILP32) { 3798 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32")); 3799 3800 sge32 = &ksmp->sgl[0].sge32[0]; 3801 response_xferlen = sge32[0].length; 3802 request_xferlen = sge32[1].length; 3803 con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: " 3804 "response_xferlen = %x, request_xferlen = %x", 3805 response_xferlen, request_xferlen)); 3806 3807 /* SJ! - ubuf needs to be virtual address. */ 3808 3809 response_ubuf = (void *)(ulong_t)sge32[0].phys_addr; 3810 request_ubuf = (void *)(ulong_t)sge32[1].phys_addr; 3811 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: " 3812 "response_ubuf = %p, request_ubuf = %p", 3813 response_ubuf, request_ubuf)); 3814 } else { 3815 #ifdef _ILP32 3816 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_ILP32")); 3817 3818 sge32 = &ksmp->sgl[0].sge32[0]; 3819 response_xferlen = sge32[0].length; 3820 request_xferlen = sge32[1].length; 3821 con_log(CL_ANN, (CE_NOTE, "issue_mfi_smp: " 3822 "response_xferlen = %x, request_xferlen = %x", 3823 response_xferlen, request_xferlen)); 3824 3825 /* SJ! - ubuf needs to be virtual address. */ 3826 3827 response_ubuf = (void *)(ulong_t)sge32[0].phys_addr; 3828 request_ubuf = (void *)(ulong_t)sge32[1].phys_addr; 3829 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: " 3830 "response_ubuf = %p, request_ubuf = %p", 3831 response_ubuf, request_ubuf)); 3832 #else 3833 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: DDI_MODEL_LP64")); 3834 3835 sge64 = &ksmp->sgl[0].sge64[0]; 3836 response_xferlen = sge64[0].length; 3837 request_xferlen = sge64[1].length; 3838 3839 /* SJ! - ubuf needs to be virtual address. */ 3840 response_ubuf = (void *)(ulong_t)sge64[0].phys_addr; 3841 request_ubuf = (void *)(ulong_t)sge64[1].phys_addr; 3842 #endif 3843 } 3844 if (request_xferlen) { 3845 /* means IOCTL requires DMA */ 3846 /* allocate the data transfer buffer */ 3847 request_dma_obj.size = request_xferlen; 3848 request_dma_obj.dma_attr = megasas_generic_dma_attr; 3849 request_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 3850 request_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 3851 request_dma_obj.dma_attr.dma_attr_sgllen = 1; 3852 request_dma_obj.dma_attr.dma_attr_align = 1; 3853 3854 /* allocate kernel buffer for DMA */ 3855 if (mega_alloc_dma_obj(instance, &request_dma_obj) != 1) { 3856 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: " 3857 "could not data transfer buffer alloc.")); 3858 return (DDI_FAILURE); 3859 } 3860 3861 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ 3862 if (ddi_copyin(request_ubuf, (void *) request_dma_obj.buffer, 3863 request_xferlen, mode)) { 3864 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: " 3865 "copy from user space failed\n")); 3866 return (1); 3867 } 3868 } 3869 3870 if (response_xferlen) { 3871 /* means IOCTL requires DMA */ 3872 /* allocate the data transfer buffer */ 3873 response_dma_obj.size = response_xferlen; 3874 response_dma_obj.dma_attr = megasas_generic_dma_attr; 3875 response_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 3876 response_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 3877 response_dma_obj.dma_attr.dma_attr_sgllen = 1; 3878 response_dma_obj.dma_attr.dma_attr_align = 1; 3879 3880 /* allocate kernel buffer for DMA */ 3881 if (mega_alloc_dma_obj(instance, &response_dma_obj) != 1) { 3882 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: " 3883 "could not data transfer buffer alloc.")); 3884 return (DDI_FAILURE); 3885 } 3886 3887 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ 3888 if (ddi_copyin(response_ubuf, (void *) response_dma_obj.buffer, 3889 response_xferlen, mode)) { 3890 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: " 3891 "copy from user space failed\n")); 3892 return (1); 3893 } 3894 } 3895 3896 smp->cmd = ksmp->cmd; 3897 smp->cmd_status = ksmp->cmd_status; 3898 smp->connection_status = ksmp->connection_status; 3899 smp->sge_count = ksmp->sge_count; 3900 /* smp->context = ksmp->context; */ 3901 smp->timeout = ksmp->timeout; 3902 smp->data_xfer_len = ksmp->data_xfer_len; 3903 3904 bcopy((void *)&ksmp->sas_addr, (void *)&smp->sas_addr, 3905 sizeof (uint64_t)); 3906 3907 smp->flags = ksmp->flags & ~MFI_FRAME_SGL64; 3908 3909 model = ddi_model_convert_from(mode & FMODELS); 3910 if (model == DDI_MODEL_ILP32) { 3911 con_log(CL_ANN1, (CE_NOTE, 3912 "handle_drv_ioctl: DDI_MODEL_ILP32")); 3913 3914 sge32 = &smp->sgl[0].sge32[0]; 3915 sge32[0].length = response_xferlen; 3916 sge32[0].phys_addr = 3917 response_dma_obj.dma_cookie[0].dmac_address; 3918 sge32[1].length = request_xferlen; 3919 sge32[1].phys_addr = 3920 request_dma_obj.dma_cookie[0].dmac_address; 3921 } else { 3922 #ifdef _ILP32 3923 con_log(CL_ANN1, (CE_NOTE, 3924 "handle_drv_ioctl: DDI_MODEL_ILP32")); 3925 sge32 = &smp->sgl[0].sge32[0]; 3926 sge32[0].length = response_xferlen; 3927 sge32[0].phys_addr = 3928 response_dma_obj.dma_cookie[0].dmac_address; 3929 sge32[1].length = request_xferlen; 3930 sge32[1].phys_addr = 3931 request_dma_obj.dma_cookie[0].dmac_address; 3932 #else 3933 con_log(CL_ANN1, (CE_NOTE, 3934 "issue_mfi_smp: DDI_MODEL_LP64")); 3935 sge64 = &smp->sgl[0].sge64[0]; 3936 sge64[0].length = response_xferlen; 3937 sge64[0].phys_addr = 3938 response_dma_obj.dma_cookie[0].dmac_address; 3939 sge64[1].length = request_xferlen; 3940 sge64[1].phys_addr = 3941 request_dma_obj.dma_cookie[0].dmac_address; 3942 #endif 3943 } 3944 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: " 3945 "smp->response_xferlen = %d, smp->request_xferlen = %d " 3946 "smp->data_xfer_len = %d", sge32[0].length, sge32[1].length, 3947 smp->data_xfer_len)); 3948 3949 cmd->sync_cmd = MEGASAS_TRUE; 3950 cmd->frame_count = 1; 3951 3952 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) { 3953 con_log(CL_ANN, (CE_WARN, 3954 "issue_mfi_smp: fw_ioctl failed\n")); 3955 } else { 3956 con_log(CL_ANN1, (CE_NOTE, 3957 "issue_mfi_smp: copy to user space\n")); 3958 3959 if (request_xferlen) { 3960 if (ddi_copyout(request_dma_obj.buffer, request_ubuf, 3961 request_xferlen, mode)) { 3962 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: " 3963 "copy to user space failed\n")); 3964 return (1); 3965 } 3966 } 3967 3968 if (response_xferlen) { 3969 if (ddi_copyout(response_dma_obj.buffer, response_ubuf, 3970 response_xferlen, mode)) { 3971 con_log(CL_ANN, (CE_WARN, "issue_mfi_smp: " 3972 "copy to user space failed\n")); 3973 return (1); 3974 } 3975 } 3976 } 3977 3978 ksmp->cmd_status = smp->cmd_status; 3979 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_smp: smp->cmd_status = %d", 3980 smp->cmd_status)); 3981 3982 3983 if (request_xferlen) { 3984 /* free kernel buffer */ 3985 if (mega_free_dma_obj(instance, request_dma_obj) != DDI_SUCCESS) 3986 return (1); 3987 } 3988 3989 if (response_xferlen) { 3990 /* free kernel buffer */ 3991 if (mega_free_dma_obj(instance, response_dma_obj) != 3992 DDI_SUCCESS) 3993 return (1); 3994 } 3995 3996 return (0); 3997 } 3998 3999 /* 4000 * issue_mfi_stp 4001 */ 4002 static int 4003 issue_mfi_stp(struct megasas_instance *instance, struct megasas_ioctl *ioctl, 4004 struct megasas_cmd *cmd, int mode) 4005 { 4006 void *fis_ubuf; 4007 void *data_ubuf; 4008 uint32_t fis_xferlen = 0; 4009 uint32_t data_xferlen = 0; 4010 uint_t model; 4011 dma_obj_t fis_dma_obj; 4012 dma_obj_t data_dma_obj; 4013 struct megasas_stp_frame *kstp; 4014 struct megasas_stp_frame *stp; 4015 4016 stp = &cmd->frame->stp; 4017 kstp = (struct megasas_stp_frame *)&ioctl->frame[0]; 4018 4019 model = ddi_model_convert_from(mode & FMODELS); 4020 if (model == DDI_MODEL_ILP32) { 4021 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32")); 4022 4023 fis_xferlen = kstp->sgl.sge32[0].length; 4024 data_xferlen = kstp->sgl.sge32[1].length; 4025 4026 /* SJ! - ubuf needs to be virtual address. */ 4027 fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr; 4028 data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr; 4029 } 4030 else 4031 { 4032 #ifdef _ILP32 4033 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_ILP32")); 4034 4035 fis_xferlen = kstp->sgl.sge32[0].length; 4036 data_xferlen = kstp->sgl.sge32[1].length; 4037 4038 /* SJ! - ubuf needs to be virtual address. */ 4039 fis_ubuf = (void *)(ulong_t)kstp->sgl.sge32[0].phys_addr; 4040 data_ubuf = (void *)(ulong_t)kstp->sgl.sge32[1].phys_addr; 4041 #else 4042 con_log(CL_ANN1, (CE_NOTE, "issue_mfi_stp: DDI_MODEL_LP64")); 4043 4044 fis_xferlen = kstp->sgl.sge64[0].length; 4045 data_xferlen = kstp->sgl.sge64[1].length; 4046 4047 /* SJ! - ubuf needs to be virtual address. */ 4048 fis_ubuf = (void *)(ulong_t)kstp->sgl.sge64[0].phys_addr; 4049 data_ubuf = (void *)(ulong_t)kstp->sgl.sge64[1].phys_addr; 4050 #endif 4051 } 4052 4053 4054 if (fis_xferlen) { 4055 con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: " 4056 "fis_ubuf = %p fis_xferlen = %x", fis_ubuf, fis_xferlen)); 4057 4058 /* means IOCTL requires DMA */ 4059 /* allocate the data transfer buffer */ 4060 fis_dma_obj.size = fis_xferlen; 4061 fis_dma_obj.dma_attr = megasas_generic_dma_attr; 4062 fis_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 4063 fis_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 4064 fis_dma_obj.dma_attr.dma_attr_sgllen = 1; 4065 fis_dma_obj.dma_attr.dma_attr_align = 1; 4066 4067 /* allocate kernel buffer for DMA */ 4068 if (mega_alloc_dma_obj(instance, &fis_dma_obj) != 1) { 4069 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " 4070 "could not data transfer buffer alloc.")); 4071 return (DDI_FAILURE); 4072 } 4073 4074 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ 4075 if (ddi_copyin(fis_ubuf, (void *)fis_dma_obj.buffer, 4076 fis_xferlen, mode)) { 4077 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " 4078 "copy from user space failed\n")); 4079 return (1); 4080 } 4081 } 4082 4083 if (data_xferlen) { 4084 con_log(CL_ANN, (CE_NOTE, "issue_mfi_stp: data_ubuf = %p " 4085 "data_xferlen = %x", data_ubuf, data_xferlen)); 4086 4087 /* means IOCTL requires DMA */ 4088 /* allocate the data transfer buffer */ 4089 data_dma_obj.size = data_xferlen; 4090 data_dma_obj.dma_attr = megasas_generic_dma_attr; 4091 data_dma_obj.dma_attr.dma_attr_addr_hi = 0xFFFFFFFFU; 4092 data_dma_obj.dma_attr.dma_attr_count_max = 0xFFFFFFFFU; 4093 data_dma_obj.dma_attr.dma_attr_sgllen = 1; 4094 data_dma_obj.dma_attr.dma_attr_align = 1; 4095 4096 /* allocate kernel buffer for DMA */ 4097 if (mega_alloc_dma_obj(instance, &data_dma_obj) != 1) { 4098 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " 4099 "could not data transfer buffer alloc.")); 4100 return (DDI_FAILURE); 4101 } 4102 4103 /* If IOCTL requires DMA WRITE, do ddi_copyin IOCTL data copy */ 4104 if (ddi_copyin(data_ubuf, (void *) data_dma_obj.buffer, 4105 data_xferlen, mode)) { 4106 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " 4107 "copy from user space failed\n")); 4108 return (1); 4109 } 4110 } 4111 4112 stp->cmd = kstp->cmd; 4113 stp->cmd_status = kstp->cmd_status; 4114 stp->connection_status = kstp->connection_status; 4115 stp->target_id = kstp->target_id; 4116 stp->sge_count = kstp->sge_count; 4117 /* stp->context = kstp->context; */ 4118 stp->timeout = kstp->timeout; 4119 stp->data_xfer_len = kstp->data_xfer_len; 4120 4121 bcopy((void *)kstp->fis, (void *)stp->fis, 10); 4122 4123 stp->flags = kstp->flags & ~MFI_FRAME_SGL64; 4124 stp->stp_flags = kstp->stp_flags; 4125 stp->sgl.sge32[0].length = fis_xferlen; 4126 stp->sgl.sge32[0].phys_addr = fis_dma_obj.dma_cookie[0].dmac_address; 4127 stp->sgl.sge32[1].length = data_xferlen; 4128 stp->sgl.sge32[1].phys_addr = data_dma_obj.dma_cookie[0].dmac_address; 4129 4130 cmd->sync_cmd = MEGASAS_TRUE; 4131 cmd->frame_count = 1; 4132 4133 if (instance->func_ptr->issue_cmd_in_sync_mode(instance, cmd)) { 4134 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: fw_ioctl failed\n")); 4135 } else { 4136 4137 if (fis_xferlen) { 4138 if (ddi_copyout(fis_dma_obj.buffer, fis_ubuf, 4139 fis_xferlen, mode)) { 4140 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " 4141 "copy to user space failed\n")); 4142 return (1); 4143 } 4144 } 4145 4146 if (data_xferlen) { 4147 if (ddi_copyout(data_dma_obj.buffer, data_ubuf, 4148 data_xferlen, mode)) { 4149 con_log(CL_ANN, (CE_WARN, "issue_mfi_stp: " 4150 "copy to user space failed\n")); 4151 return (1); 4152 } 4153 } 4154 } 4155 4156 kstp->cmd_status = stp->cmd_status; 4157 4158 if (fis_xferlen) { 4159 /* free kernel buffer */ 4160 if (mega_free_dma_obj(instance, fis_dma_obj) != DDI_SUCCESS) 4161 return (1); 4162 } 4163 4164 if (data_xferlen) { 4165 /* free kernel buffer */ 4166 if (mega_free_dma_obj(instance, data_dma_obj) != DDI_SUCCESS) 4167 return (1); 4168 } 4169 4170 return (0); 4171 } 4172 4173 /* 4174 * fill_up_drv_ver 4175 */ 4176 static void 4177 fill_up_drv_ver(struct megasas_drv_ver *dv) 4178 { 4179 (void) memset(dv, 0, sizeof (struct megasas_drv_ver)); 4180 4181 (void) memcpy(dv->signature, "$LSI LOGIC$", strlen("$LSI LOGIC$")); 4182 (void) memcpy(dv->os_name, "Solaris", strlen("Solaris")); 4183 (void) memcpy(dv->drv_name, "megaraid_sas", strlen("megaraid_sas")); 4184 (void) memcpy(dv->drv_ver, MEGASAS_VERSION, strlen(MEGASAS_VERSION)); 4185 (void) memcpy(dv->drv_rel_date, MEGASAS_RELDATE, 4186 strlen(MEGASAS_RELDATE)); 4187 } 4188 4189 /* 4190 * handle_drv_ioctl 4191 */ 4192 static int 4193 handle_drv_ioctl(struct megasas_instance *instance, struct megasas_ioctl *ioctl, 4194 int mode) 4195 { 4196 int i; 4197 int rval = 0; 4198 int *props = NULL; 4199 void *ubuf; 4200 4201 uint8_t *pci_conf_buf; 4202 uint32_t xferlen; 4203 uint32_t num_props; 4204 uint_t model; 4205 struct megasas_dcmd_frame *kdcmd; 4206 struct megasas_drv_ver dv; 4207 struct megasas_pci_information pi; 4208 4209 kdcmd = (struct megasas_dcmd_frame *)&ioctl->frame[0]; 4210 4211 model = ddi_model_convert_from(mode & FMODELS); 4212 if (model == DDI_MODEL_ILP32) { 4213 con_log(CL_ANN1, (CE_NOTE, 4214 "handle_drv_ioctl: DDI_MODEL_ILP32")); 4215 4216 xferlen = kdcmd->sgl.sge32[0].length; 4217 4218 /* SJ! - ubuf needs to be virtual address. */ 4219 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr; 4220 } else { 4221 #ifdef _ILP32 4222 con_log(CL_ANN1, (CE_NOTE, 4223 "handle_drv_ioctl: DDI_MODEL_ILP32")); 4224 xferlen = kdcmd->sgl.sge32[0].length; 4225 /* SJ! - ubuf needs to be virtual address. */ 4226 ubuf = (void *)(ulong_t)kdcmd->sgl.sge32[0].phys_addr; 4227 #else 4228 con_log(CL_ANN1, (CE_NOTE, 4229 "handle_drv_ioctl: DDI_MODEL_LP64")); 4230 xferlen = kdcmd->sgl.sge64[0].length; 4231 /* SJ! - ubuf needs to be virtual address. */ 4232 ubuf = (void *)(ulong_t)kdcmd->sgl.sge64[0].phys_addr; 4233 #endif 4234 } 4235 con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: " 4236 "dataBuf=%p size=%d bytes", ubuf, xferlen)); 4237 4238 switch (kdcmd->opcode) { 4239 case MR_DRIVER_IOCTL_DRIVER_VERSION: 4240 con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: " 4241 "MR_DRIVER_IOCTL_DRIVER_VERSION")); 4242 4243 fill_up_drv_ver(&dv); 4244 4245 if (ddi_copyout(&dv, ubuf, xferlen, mode)) { 4246 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: " 4247 "MR_DRIVER_IOCTL_DRIVER_VERSION : " 4248 "copy to user space failed\n")); 4249 kdcmd->cmd_status = 1; 4250 rval = 1; 4251 } else { 4252 kdcmd->cmd_status = 0; 4253 } 4254 break; 4255 case MR_DRIVER_IOCTL_PCI_INFORMATION: 4256 con_log(CL_ANN1, (CE_NOTE, "handle_drv_ioctl: " 4257 "MR_DRIVER_IOCTL_PCI_INFORMAITON")); 4258 4259 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, instance->dip, 4260 0, "reg", &props, &num_props)) { 4261 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: " 4262 "MR_DRIVER_IOCTL_PCI_INFORMATION : " 4263 "ddi_prop_look_int_array failed\n")); 4264 rval = 1; 4265 } else { 4266 4267 pi.busNumber = (props[0] >> 16) & 0xFF; 4268 pi.deviceNumber = (props[0] >> 11) & 0x1f; 4269 pi.functionNumber = (props[0] >> 8) & 0x7; 4270 ddi_prop_free((void *)props); 4271 } 4272 4273 pci_conf_buf = (uint8_t *)&pi.pciHeaderInfo; 4274 4275 for (i = 0; i < (sizeof (struct megasas_pci_information) - 4276 offsetof(struct megasas_pci_information, pciHeaderInfo)); 4277 i++) { 4278 pci_conf_buf[i] = 4279 pci_config_get8(instance->pci_handle, i); 4280 } 4281 4282 if (ddi_copyout(&pi, ubuf, xferlen, mode)) { 4283 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: " 4284 "MR_DRIVER_IOCTL_PCI_INFORMATION : " 4285 "copy to user space failed\n")); 4286 kdcmd->cmd_status = 1; 4287 rval = 1; 4288 } else { 4289 kdcmd->cmd_status = 0; 4290 } 4291 break; 4292 default: 4293 con_log(CL_ANN, (CE_WARN, "handle_drv_ioctl: " 4294 "invalid driver specific IOCTL opcode = 0x%x", 4295 kdcmd->opcode)); 4296 kdcmd->cmd_status = 1; 4297 rval = 1; 4298 break; 4299 } 4300 4301 return (rval); 4302 } 4303 4304 /* 4305 * handle_mfi_ioctl 4306 */ 4307 static int 4308 handle_mfi_ioctl(struct megasas_instance *instance, struct megasas_ioctl *ioctl, 4309 int mode) 4310 { 4311 int rval = 0; 4312 4313 struct megasas_header *hdr; 4314 struct megasas_cmd *cmd; 4315 4316 cmd = get_mfi_pkt(instance); 4317 4318 if (!cmd) { 4319 con_log(CL_ANN, (CE_WARN, "megasas: " 4320 "failed to get a cmd packet\n")); 4321 return (1); 4322 } 4323 4324 hdr = (struct megasas_header *)&ioctl->frame[0]; 4325 4326 switch (hdr->cmd) { 4327 case MFI_CMD_OP_DCMD: 4328 rval = issue_mfi_dcmd(instance, ioctl, cmd, mode); 4329 break; 4330 case MFI_CMD_OP_SMP: 4331 rval = issue_mfi_smp(instance, ioctl, cmd, mode); 4332 break; 4333 case MFI_CMD_OP_STP: 4334 rval = issue_mfi_stp(instance, ioctl, cmd, mode); 4335 break; 4336 case MFI_CMD_OP_LD_SCSI: 4337 case MFI_CMD_OP_PD_SCSI: 4338 rval = issue_mfi_pthru(instance, ioctl, cmd, mode); 4339 break; 4340 default: 4341 con_log(CL_ANN, (CE_WARN, "handle_mfi_ioctl: " 4342 "invalid mfi ioctl hdr->cmd = %d\n", hdr->cmd)); 4343 rval = 1; 4344 break; 4345 } 4346 4347 4348 return_mfi_pkt(instance, cmd); 4349 if (megasas_common_check(instance, cmd) != DDI_SUCCESS) 4350 rval = 1; 4351 return (rval); 4352 } 4353 4354 /* 4355 * AEN 4356 */ 4357 static int 4358 handle_mfi_aen(struct megasas_instance *instance, struct megasas_aen *aen) 4359 { 4360 int rval = 0; 4361 4362 rval = register_mfi_aen(instance, instance->aen_seq_num, 4363 aen->class_locale_word); 4364 4365 aen->cmd_status = (uint8_t)rval; 4366 4367 return (rval); 4368 } 4369 4370 static int 4371 register_mfi_aen(struct megasas_instance *instance, uint32_t seq_num, 4372 uint32_t class_locale_word) 4373 { 4374 int ret_val; 4375 4376 struct megasas_cmd *cmd; 4377 struct megasas_dcmd_frame *dcmd; 4378 union megasas_evt_class_locale curr_aen; 4379 union megasas_evt_class_locale prev_aen; 4380 4381 /* 4382 * If there an AEN pending already (aen_cmd), check if the 4383 * class_locale of that pending AEN is inclusive of the new 4384 * AEN request we currently have. If it is, then we don't have 4385 * to do anything. In other words, whichever events the current 4386 * AEN request is subscribing to, have already been subscribed 4387 * to. 4388 * 4389 * If the old_cmd is _not_ inclusive, then we have to abort 4390 * that command, form a class_locale that is superset of both 4391 * old and current and re-issue to the FW 4392 */ 4393 4394 curr_aen.word = class_locale_word; 4395 4396 if (instance->aen_cmd) { 4397 prev_aen.word = instance->aen_cmd->frame->dcmd.mbox.w[1]; 4398 4399 /* 4400 * A class whose enum value is smaller is inclusive of all 4401 * higher values. If a PROGRESS (= -1) was previously 4402 * registered, then a new registration requests for higher 4403 * classes need not be sent to FW. They are automatically 4404 * included. 4405 * 4406 * Locale numbers don't have such hierarchy. They are bitmap 4407 * values 4408 */ 4409 if ((prev_aen.members.class <= curr_aen.members.class) && 4410 !((prev_aen.members.locale & curr_aen.members.locale) ^ 4411 curr_aen.members.locale)) { 4412 /* 4413 * Previously issued event registration includes 4414 * current request. Nothing to do. 4415 */ 4416 4417 return (0); 4418 } else { 4419 curr_aen.members.locale |= prev_aen.members.locale; 4420 4421 if (prev_aen.members.class < curr_aen.members.class) 4422 curr_aen.members.class = prev_aen.members.class; 4423 4424 ret_val = abort_aen_cmd(instance, instance->aen_cmd); 4425 4426 if (ret_val) { 4427 con_log(CL_ANN, (CE_WARN, "register_mfi_aen: " 4428 "failed to abort prevous AEN command\n")); 4429 4430 return (ret_val); 4431 } 4432 } 4433 } else { 4434 curr_aen.word = class_locale_word; 4435 } 4436 4437 cmd = get_mfi_pkt(instance); 4438 4439 if (!cmd) 4440 return (-ENOMEM); 4441 4442 dcmd = &cmd->frame->dcmd; 4443 4444 /* for(i = 0; i < DCMD_MBOX_SZ; i++) dcmd->mbox.b[i] = 0; */ 4445 (void) memset(dcmd->mbox.b, 0, DCMD_MBOX_SZ); 4446 4447 (void) memset(instance->mfi_evt_detail_obj.buffer, 0, 4448 sizeof (struct megasas_evt_detail)); 4449 4450 /* Prepare DCMD for aen registration */ 4451 dcmd->cmd = MFI_CMD_OP_DCMD; 4452 dcmd->cmd_status = 0x0; 4453 dcmd->sge_count = 1; 4454 dcmd->flags = MFI_FRAME_DIR_READ; 4455 dcmd->timeout = 0; 4456 dcmd->data_xfer_len = sizeof (struct megasas_evt_detail); 4457 dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT; 4458 dcmd->mbox.w[0] = seq_num; 4459 dcmd->mbox.w[1] = curr_aen.word; 4460 dcmd->sgl.sge32[0].phys_addr = 4461 instance->mfi_evt_detail_obj.dma_cookie[0].dmac_address; 4462 dcmd->sgl.sge32[0].length = sizeof (struct megasas_evt_detail); 4463 4464 instance->aen_seq_num = seq_num; 4465 4466 /* 4467 * Store reference to the cmd used to register for AEN. When an 4468 * application wants us to register for AEN, we have to abort this 4469 * cmd and re-register with a new EVENT LOCALE supplied by that app 4470 */ 4471 instance->aen_cmd = cmd; 4472 4473 cmd->frame_count = 1; 4474 4475 /* Issue the aen registration frame */ 4476 /* atomic_add_16 (&instance->fw_outstanding, 1); */ 4477 instance->func_ptr->issue_cmd(cmd, instance); 4478 4479 return (0); 4480 } 4481 4482 static void 4483 display_scsi_inquiry(caddr_t scsi_inq) 4484 { 4485 #define MAX_SCSI_DEVICE_CODE 14 4486 int i; 4487 char inquiry_buf[256] = {0}; 4488 int len; 4489 const char *const scsi_device_types[] = { 4490 "Direct-Access ", 4491 "Sequential-Access", 4492 "Printer ", 4493 "Processor ", 4494 "WORM ", 4495 "CD-ROM ", 4496 "Scanner ", 4497 "Optical Device ", 4498 "Medium Changer ", 4499 "Communications ", 4500 "Unknown ", 4501 "Unknown ", 4502 "Unknown ", 4503 "Enclosure ", 4504 }; 4505 4506 len = 0; 4507 4508 len += snprintf(inquiry_buf + len, 265 - len, " Vendor: "); 4509 for (i = 8; i < 16; i++) { 4510 len += snprintf(inquiry_buf + len, 265 - len, "%c", 4511 scsi_inq[i]); 4512 } 4513 4514 len += snprintf(inquiry_buf + len, 265 - len, " Model: "); 4515 4516 for (i = 16; i < 32; i++) { 4517 len += snprintf(inquiry_buf + len, 265 - len, "%c", 4518 scsi_inq[i]); 4519 } 4520 4521 len += snprintf(inquiry_buf + len, 265 - len, " Rev: "); 4522 4523 for (i = 32; i < 36; i++) { 4524 len += snprintf(inquiry_buf + len, 265 - len, "%c", 4525 scsi_inq[i]); 4526 } 4527 4528 len += snprintf(inquiry_buf + len, 265 - len, "\n"); 4529 4530 4531 i = scsi_inq[0] & 0x1f; 4532 4533 4534 len += snprintf(inquiry_buf + len, 265 - len, " Type: %s ", 4535 i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : 4536 "Unknown "); 4537 4538 4539 len += snprintf(inquiry_buf + len, 265 - len, 4540 " ANSI SCSI revision: %02x", scsi_inq[2] & 0x07); 4541 4542 if ((scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1) { 4543 len += snprintf(inquiry_buf + len, 265 - len, " CCS\n"); 4544 } else { 4545 len += snprintf(inquiry_buf + len, 265 - len, "\n"); 4546 } 4547 4548 con_log(CL_ANN1, (CE_CONT, inquiry_buf)); 4549 } 4550 4551 static int 4552 read_fw_status_reg_xscale(struct megasas_instance *instance) 4553 { 4554 return ((int)RD_OB_MSG_0(instance)); 4555 } 4556 4557 static int 4558 read_fw_status_reg_ppc(struct megasas_instance *instance) 4559 { 4560 return ((int)RD_OB_SCRATCH_PAD_0(instance)); 4561 } 4562 4563 static void 4564 issue_cmd_xscale(struct megasas_cmd *cmd, struct megasas_instance *instance) 4565 { 4566 atomic_add_16(&instance->fw_outstanding, 1); 4567 4568 /* Issue the command to the FW */ 4569 WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) | 4570 (cmd->frame_count - 1), instance); 4571 } 4572 4573 static void 4574 issue_cmd_ppc(struct megasas_cmd *cmd, struct megasas_instance *instance) 4575 { 4576 atomic_add_16(&instance->fw_outstanding, 1); 4577 4578 /* Issue the command to the FW */ 4579 WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr)) | 4580 (((cmd->frame_count - 1) << 1) | 1), instance); 4581 } 4582 4583 /* 4584 * issue_cmd_in_sync_mode 4585 */ 4586 static int 4587 issue_cmd_in_sync_mode_xscale(struct megasas_instance *instance, 4588 struct megasas_cmd *cmd) 4589 { 4590 int i; 4591 uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC); 4592 4593 cmd->cmd_status = ENODATA; 4594 4595 WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) | 4596 (cmd->frame_count - 1), instance); 4597 4598 mutex_enter(&instance->int_cmd_mtx); 4599 4600 for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) { 4601 cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx); 4602 } 4603 4604 mutex_exit(&instance->int_cmd_mtx); 4605 4606 if (i < (msecs -1)) { 4607 return (0); 4608 } else { 4609 return (1); 4610 } 4611 } 4612 4613 static int 4614 issue_cmd_in_sync_mode_ppc(struct megasas_instance *instance, 4615 struct megasas_cmd *cmd) 4616 { 4617 int i; 4618 uint32_t msecs = MFI_POLL_TIMEOUT_SECS * (10 * MILLISEC); 4619 4620 con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: called\n")); 4621 4622 cmd->cmd_status = ENODATA; 4623 4624 WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr)) | 4625 (((cmd->frame_count - 1) << 1) | 1), instance); 4626 4627 mutex_enter(&instance->int_cmd_mtx); 4628 4629 for (i = 0; i < msecs && (cmd->cmd_status == ENODATA); i++) { 4630 cv_wait(&instance->int_cmd_cv, &instance->int_cmd_mtx); 4631 } 4632 4633 mutex_exit(&instance->int_cmd_mtx); 4634 4635 con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_sync_mode_ppc: done\n")); 4636 4637 if (i < (msecs -1)) { 4638 return (0); 4639 } else { 4640 return (1); 4641 } 4642 } 4643 4644 /* 4645 * issue_cmd_in_poll_mode 4646 */ 4647 static int 4648 issue_cmd_in_poll_mode_xscale(struct megasas_instance *instance, 4649 struct megasas_cmd *cmd) 4650 { 4651 int i; 4652 uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC; 4653 struct megasas_header *frame_hdr; 4654 4655 frame_hdr = (struct megasas_header *)cmd->frame; 4656 frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE; 4657 frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 4658 4659 /* issue the frame using inbound queue port */ 4660 WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr) >> 3) | 4661 (cmd->frame_count - 1), instance); 4662 4663 /* wait for cmd_status to change from 0xFF */ 4664 for (i = 0; i < msecs && (frame_hdr->cmd_status == 4665 MFI_CMD_STATUS_POLL_MODE); i++) { 4666 drv_usecwait(MILLISEC); /* wait for 1000 usecs */ 4667 } 4668 4669 if (frame_hdr->cmd_status == MFI_CMD_STATUS_POLL_MODE) { 4670 con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: " 4671 "cmd polling timed out")); 4672 return (DDI_FAILURE); 4673 } 4674 4675 return (DDI_SUCCESS); 4676 } 4677 4678 static int 4679 issue_cmd_in_poll_mode_ppc(struct megasas_instance *instance, 4680 struct megasas_cmd *cmd) 4681 { 4682 int i; 4683 uint32_t msecs = MFI_POLL_TIMEOUT_SECS * MILLISEC; 4684 struct megasas_header *frame_hdr; 4685 4686 con_log(CL_ANN1, (CE_NOTE, "issue_cmd_in_poll_mode_ppc: called\n")); 4687 4688 frame_hdr = (struct megasas_header *)cmd->frame; 4689 frame_hdr->cmd_status = MFI_CMD_STATUS_POLL_MODE; 4690 frame_hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 4691 4692 /* issue the frame using inbound queue port */ 4693 WR_IB_QPORT((host_to_le32(cmd->frame_phys_addr)) | 4694 (((cmd->frame_count - 1) << 1) | 1), instance); 4695 4696 /* wait for cmd_status to change from 0xFF */ 4697 for (i = 0; i < msecs && (frame_hdr->cmd_status == 4698 MFI_CMD_STATUS_POLL_MODE); i++) { 4699 drv_usecwait(MILLISEC); /* wait for 1000 usecs */ 4700 } 4701 4702 if (frame_hdr->cmd_status == MFI_CMD_STATUS_POLL_MODE) { 4703 con_log(CL_ANN, (CE_NOTE, "issue_cmd_in_poll_mode: " 4704 "cmd polling timed out")); 4705 return (DDI_FAILURE); 4706 } 4707 4708 return (DDI_SUCCESS); 4709 } 4710 4711 static void 4712 enable_intr_xscale(struct megasas_instance *instance) 4713 { 4714 MFI_ENABLE_INTR(instance); 4715 } 4716 4717 static void 4718 enable_intr_ppc(struct megasas_instance *instance) 4719 { 4720 uint32_t mask; 4721 4722 con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: called\n")); 4723 4724 /* WR_OB_DOORBELL_CLEAR(0xFFFFFFFF, instance); */ 4725 WR_OB_DOORBELL_CLEAR(OB_DOORBELL_CLEAR_MASK, instance); 4726 4727 /* 4728 * As 1078DE is same as 1078 chip, the interrupt mask 4729 * remains the same. 4730 */ 4731 /* WR_OB_INTR_MASK(~0x80000000, instance); */ 4732 WR_OB_INTR_MASK(~(MFI_REPLY_1078_MESSAGE_INTR), instance); 4733 4734 /* dummy read to force PCI flush */ 4735 mask = RD_OB_INTR_MASK(instance); 4736 4737 con_log(CL_ANN1, (CE_NOTE, "enable_intr_ppc: " 4738 "outbound_intr_mask = 0x%x\n", mask)); 4739 } 4740 4741 static void 4742 disable_intr_xscale(struct megasas_instance *instance) 4743 { 4744 MFI_DISABLE_INTR(instance); 4745 } 4746 4747 static void 4748 disable_intr_ppc(struct megasas_instance *instance) 4749 { 4750 uint32_t mask; 4751 4752 con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: called\n")); 4753 4754 con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: before : " 4755 "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance))); 4756 4757 /* WR_OB_INTR_MASK(0xFFFFFFFF, instance); */ 4758 WR_OB_INTR_MASK(OB_INTR_MASK, instance); 4759 4760 con_log(CL_ANN1, (CE_NOTE, "disable_intr_ppc: after : " 4761 "outbound_intr_mask = 0x%x\n", RD_OB_INTR_MASK(instance))); 4762 4763 /* dummy read to force PCI flush */ 4764 mask = RD_OB_INTR_MASK(instance); 4765 #ifdef lint 4766 mask = mask; 4767 #endif 4768 } 4769 4770 static int 4771 intr_ack_xscale(struct megasas_instance *instance) 4772 { 4773 uint32_t status; 4774 4775 /* check if it is our interrupt */ 4776 status = RD_OB_INTR_STATUS(instance); 4777 4778 if (!(status & MFI_OB_INTR_STATUS_MASK)) { 4779 return (DDI_INTR_UNCLAIMED); 4780 } 4781 4782 /* clear the interrupt by writing back the same value */ 4783 WR_OB_INTR_STATUS(status, instance); 4784 4785 return (DDI_INTR_CLAIMED); 4786 } 4787 4788 static int 4789 intr_ack_ppc(struct megasas_instance *instance) 4790 { 4791 uint32_t status; 4792 4793 con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: called\n")); 4794 4795 /* check if it is our interrupt */ 4796 status = RD_OB_INTR_STATUS(instance); 4797 4798 con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: status = 0x%x\n", status)); 4799 4800 /* 4801 * As 1078DE is same as 1078 chip, the status field 4802 * remains the same. 4803 */ 4804 if (!(status & MFI_REPLY_1078_MESSAGE_INTR)) { 4805 return (DDI_INTR_UNCLAIMED); 4806 } 4807 4808 /* clear the interrupt by writing back the same value */ 4809 WR_OB_DOORBELL_CLEAR(status, instance); 4810 4811 /* dummy READ */ 4812 status = RD_OB_INTR_STATUS(instance); 4813 4814 con_log(CL_ANN1, (CE_NOTE, "intr_ack_ppc: interrupt cleared\n")); 4815 4816 return (DDI_INTR_CLAIMED); 4817 } 4818 4819 static int 4820 megasas_common_check(struct megasas_instance *instance, 4821 struct megasas_cmd *cmd) 4822 { 4823 int ret = DDI_SUCCESS; 4824 4825 if (megasas_check_dma_handle(cmd->frame_dma_obj.dma_handle) != 4826 DDI_SUCCESS) { 4827 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); 4828 if (cmd->pkt != NULL) { 4829 cmd->pkt->pkt_reason = CMD_TRAN_ERR; 4830 cmd->pkt->pkt_statistics = 0; 4831 } 4832 ret = DDI_FAILURE; 4833 } 4834 if (megasas_check_dma_handle(instance->mfi_internal_dma_obj.dma_handle) 4835 != DDI_SUCCESS) { 4836 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); 4837 if (cmd->pkt != NULL) { 4838 cmd->pkt->pkt_reason = CMD_TRAN_ERR; 4839 cmd->pkt->pkt_statistics = 0; 4840 } 4841 ret = DDI_FAILURE; 4842 } 4843 if (megasas_check_dma_handle(instance->mfi_evt_detail_obj.dma_handle) != 4844 DDI_SUCCESS) { 4845 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); 4846 if (cmd->pkt != NULL) { 4847 cmd->pkt->pkt_reason = CMD_TRAN_ERR; 4848 cmd->pkt->pkt_statistics = 0; 4849 } 4850 ret = DDI_FAILURE; 4851 } 4852 if (megasas_check_acc_handle(instance->regmap_handle) != DDI_SUCCESS) { 4853 ddi_fm_service_impact(instance->dip, DDI_SERVICE_UNAFFECTED); 4854 ddi_fm_acc_err_clear(instance->regmap_handle, DDI_FME_VER0); 4855 if (cmd->pkt != NULL) { 4856 cmd->pkt->pkt_reason = CMD_TRAN_ERR; 4857 cmd->pkt->pkt_statistics = 0; 4858 } 4859 ret = DDI_FAILURE; 4860 } 4861 4862 return (ret); 4863 } 4864 4865 /*ARGSUSED*/ 4866 static int 4867 megasas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 4868 { 4869 /* 4870 * as the driver can always deal with an error in any dma or 4871 * access handle, we can just return the fme_status value. 4872 */ 4873 pci_ereport_post(dip, err, NULL); 4874 return (err->fme_status); 4875 } 4876 4877 static void 4878 megasas_fm_init(struct megasas_instance *instance) 4879 { 4880 /* Need to change iblock to priority for new MSI intr */ 4881 ddi_iblock_cookie_t fm_ibc; 4882 4883 /* Only register with IO Fault Services if we have some capability */ 4884 if (instance->fm_capabilities) { 4885 /* Adjust access and dma attributes for FMA */ 4886 endian_attr.devacc_attr_access = DDI_FLAGERR_ACC; 4887 megasas_generic_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR; 4888 4889 /* 4890 * Register capabilities with IO Fault Services. 4891 * fm_capabilities will be updated to indicate 4892 * capabilities actually supported (not requested.) 4893 */ 4894 4895 ddi_fm_init(instance->dip, &instance->fm_capabilities, &fm_ibc); 4896 4897 /* 4898 * Initialize pci ereport capabilities if ereport 4899 * capable (should always be.) 4900 */ 4901 4902 if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) || 4903 DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { 4904 pci_ereport_setup(instance->dip); 4905 } 4906 4907 /* 4908 * Register error callback if error callback capable. 4909 */ 4910 if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { 4911 ddi_fm_handler_register(instance->dip, 4912 megasas_fm_error_cb, (void*) instance); 4913 } 4914 } else { 4915 endian_attr.devacc_attr_access = DDI_DEFAULT_ACC; 4916 megasas_generic_dma_attr.dma_attr_flags = 0; 4917 } 4918 } 4919 4920 static void 4921 megasas_fm_fini(struct megasas_instance *instance) 4922 { 4923 /* Only unregister FMA capabilities if registered */ 4924 if (instance->fm_capabilities) { 4925 /* 4926 * Un-register error callback if error callback capable. 4927 */ 4928 if (DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { 4929 ddi_fm_handler_unregister(instance->dip); 4930 } 4931 4932 /* 4933 * Release any resources allocated by pci_ereport_setup() 4934 */ 4935 if (DDI_FM_EREPORT_CAP(instance->fm_capabilities) || 4936 DDI_FM_ERRCB_CAP(instance->fm_capabilities)) { 4937 pci_ereport_teardown(instance->dip); 4938 } 4939 4940 /* Unregister from IO Fault Services */ 4941 ddi_fm_fini(instance->dip); 4942 4943 /* Adjust access and dma attributes for FMA */ 4944 endian_attr.devacc_attr_access = DDI_DEFAULT_ACC; 4945 megasas_generic_dma_attr.dma_attr_flags = 0; 4946 } 4947 } 4948 4949 int 4950 megasas_check_acc_handle(ddi_acc_handle_t handle) 4951 { 4952 ddi_fm_error_t de; 4953 4954 if (handle == NULL) { 4955 return (DDI_FAILURE); 4956 } 4957 4958 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION); 4959 4960 return (de.fme_status); 4961 } 4962 4963 int 4964 megasas_check_dma_handle(ddi_dma_handle_t handle) 4965 { 4966 ddi_fm_error_t de; 4967 4968 if (handle == NULL) { 4969 return (DDI_FAILURE); 4970 } 4971 4972 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION); 4973 4974 return (de.fme_status); 4975 } 4976 4977 void 4978 megasas_fm_ereport(struct megasas_instance *instance, char *detail) 4979 { 4980 uint64_t ena; 4981 char buf[FM_MAX_CLASS]; 4982 4983 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 4984 ena = fm_ena_generate(0, FM_ENA_FMT1); 4985 if (DDI_FM_EREPORT_CAP(instance->fm_capabilities)) { 4986 ddi_fm_ereport_post(instance->dip, buf, ena, DDI_NOSLEEP, 4987 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION, NULL); 4988 } 4989 } 4990