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