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