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