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