Print this page
    
NEX-17006 backport mpt_sas tri-mode parts support change
9044 Need support for mpt_sas tri-mode parts
9045 Clean up mpt_sas compiler warnings
9046 mptsas_handle_topo_change can return without its locks held
9047 workaround SAS3408 firmware issue
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com>
Reviewed by: Albert Lee <trisk@forkgnu.org>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-16174 scsi error messages should go to system log only
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9450 NMI panic with SAS9305-16e HBA installed and JBOD connected
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-2103 12G mpt_sas needs additional minor enhancements
NEX-1889 mpt_sas should support 12G HBAs
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_init.c
          +++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_init.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
       25 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
  25   26   * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
  26   27   * Copyright (c) 2017, Joyent, Inc.
  27   28   */
  28   29  
  29   30  /*
  30   31   * Copyright (c) 2000 to 2009, LSI Corporation.
  31   32   * All rights reserved.
  32   33   *
  33   34   * Redistribution and use in source and binary forms of all code within
  34   35   * this file that is exclusively owned by LSI, with or without
  35   36   * modification, is permitted provided that, in addition to the CDDL 1.0
  36   37   * License requirements, the following conditions are met:
  37   38   *
  38   39   *    Neither the name of the author nor the names of its contributors may be
  39   40   *    used to endorse or promote products derived from this software without
  40   41   *    specific prior written permission.
  41   42   *
  42   43   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  43   44   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  44   45   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  45   46   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  46   47   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  47   48   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  48   49   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  49   50   * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  50   51   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  51   52   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  52   53   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  53   54   * DAMAGE.
  54   55   */
  55   56  
  56   57  /*
  57   58   * mptsas_init - This file contains all the functions used to initialize
  58   59   * MPT2.0 based hardware.
  59   60   */
  60   61  
  61   62  #if defined(lint) || defined(DEBUG)
  62   63  #define MPTSAS_DEBUG
  63   64  #endif
  64   65  
  65   66  /*
  66   67   * standard header files
  67   68   */
  68   69  #include <sys/note.h>
  69   70  #include <sys/scsi/scsi.h>
  70   71  
  71   72  #pragma pack(1)
  72   73  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  73   74  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  74   75  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  75   76  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  76   77  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  77   78  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
  78   79  #pragma pack()
  79   80  /*
  80   81   * private header files.
  81   82   */
  82   83  #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  83   84  
  84   85  static int mptsas_ioc_do_get_facts(mptsas_t *mpt, caddr_t memp, int var,
  85   86          ddi_acc_handle_t accessp);
  86   87  static int mptsas_ioc_do_get_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
  87   88          ddi_acc_handle_t accessp);
  88   89  static int mptsas_ioc_do_get_port_facts(mptsas_t *mpt, caddr_t memp, int var,
  89   90          ddi_acc_handle_t accessp);
  90   91  static int mptsas_ioc_do_get_port_facts_reply(mptsas_t *mpt, caddr_t memp,
  91   92      int var, ddi_acc_handle_t accessp);
  92   93  static int mptsas_ioc_do_enable_port(mptsas_t *mpt, caddr_t memp, int var,
  93   94          ddi_acc_handle_t accessp);
  94   95  static int mptsas_ioc_do_enable_port_reply(mptsas_t *mpt, caddr_t memp, int var,
  95   96          ddi_acc_handle_t accessp);
  96   97  static int mptsas_ioc_do_enable_event_notification(mptsas_t *mpt, caddr_t memp,
  97   98          int var, ddi_acc_handle_t accessp);
  98   99  static int mptsas_ioc_do_enable_event_notification_reply(mptsas_t *mpt,
  99  100      caddr_t memp, int var, ddi_acc_handle_t accessp);
 100  101  static int mptsas_do_ioc_init(mptsas_t *mpt, caddr_t memp, int var,
 101  102          ddi_acc_handle_t accessp);
 102  103  static int mptsas_do_ioc_init_reply(mptsas_t *mpt, caddr_t memp, int var,
 103  104          ddi_acc_handle_t accessp);
 104  105  
 105  106  static const char *
 106  107  mptsas_devid_type_string(mptsas_t *mpt)
 107  108  {
 108  109          switch (mpt->m_devid) {
 109  110          case MPI2_MFGPAGE_DEVID_SAS2008:
 110  111                  return ("SAS2008");
 111  112          case MPI2_MFGPAGE_DEVID_SAS2004:
 112  113                  return ("SAS2004");
 113  114          case MPI2_MFGPAGE_DEVID_SAS2108_1:
 114  115          case MPI2_MFGPAGE_DEVID_SAS2108_2:
 115  116          case MPI2_MFGPAGE_DEVID_SAS2108_3:
 116  117                  return ("SAS2108");
 117  118          case MPI2_MFGPAGE_DEVID_SAS2116_1:
 118  119          case MPI2_MFGPAGE_DEVID_SAS2116_2:
 119  120                  return ("SAS2116");
 120  121          case MPI2_MFGPAGE_DEVID_SAS2208_1:
 121  122          case MPI2_MFGPAGE_DEVID_SAS2208_2:
 122  123          case MPI2_MFGPAGE_DEVID_SAS2208_3:
 123  124          case MPI2_MFGPAGE_DEVID_SAS2208_4:
 124  125          case MPI2_MFGPAGE_DEVID_SAS2208_5:
 125  126          case MPI2_MFGPAGE_DEVID_SAS2208_6:
 126  127                  return ("SAS2208");
 127  128          case MPI2_MFGPAGE_DEVID_SAS2308_1:
 128  129          case MPI2_MFGPAGE_DEVID_SAS2308_2:
 129  130          case MPI2_MFGPAGE_DEVID_SAS2308_3:
  
    | 
      ↓ open down ↓ | 
    95 lines elided | 
    
      ↑ open up ↑ | 
  
 130  131                  return ("SAS2308");
 131  132          case MPI25_MFGPAGE_DEVID_SAS3004:
 132  133                  return ("SAS3004");
 133  134          case MPI25_MFGPAGE_DEVID_SAS3008:
 134  135                  return ("SAS3008");
 135  136          case MPI25_MFGPAGE_DEVID_SAS3108_1:
 136  137          case MPI25_MFGPAGE_DEVID_SAS3108_2:
 137  138          case MPI25_MFGPAGE_DEVID_SAS3108_5:
 138  139          case MPI25_MFGPAGE_DEVID_SAS3108_6:
 139  140                  return ("SAS3108");
      141 +        case MPI26_MFGPAGE_DEVID_SAS3216:
      142 +        case MPI26_MFGPAGE_DEVID_SAS3316_1:
      143 +        case MPI26_MFGPAGE_DEVID_SAS3316_2:
      144 +        case MPI26_MFGPAGE_DEVID_SAS3316_3:
      145 +        case MPI26_MFGPAGE_DEVID_SAS3316_4:
      146 +                return ("SAS3216");
      147 +        case MPI26_MFGPAGE_DEVID_SAS3224:
      148 +        case MPI26_MFGPAGE_DEVID_SAS3324_1:
      149 +        case MPI26_MFGPAGE_DEVID_SAS3324_2:
      150 +        case MPI26_MFGPAGE_DEVID_SAS3324_3:
      151 +        case MPI26_MFGPAGE_DEVID_SAS3324_4:
      152 +                return ("SAS3224");
      153 +        case MPI26_MFGPAGE_DEVID_SAS3408:
      154 +                return ("SAS3408");
      155 +        case MPI26_MFGPAGE_DEVID_SAS3416:
      156 +                return ("SAS3416");
      157 +        case MPI26_MFGPAGE_DEVID_SAS3508:
      158 +        case MPI26_MFGPAGE_DEVID_SAS3508_1:
      159 +                return ("SAS3508");
      160 +        case MPI26_MFGPAGE_DEVID_SAS3516:
      161 +        case MPI26_MFGPAGE_DEVID_SAS3516_1:
      162 +                return ("SAS3516");
      163 +        case MPI26_MFGPAGE_DEVID_SAS3616:
      164 +                return ("SAS3616");
      165 +        case MPI26_MFGPAGE_DEVID_SAS3708:
      166 +                return ("SAS3708");
      167 +        case MPI26_MFGPAGE_DEVID_SAS3716:
      168 +                return ("SAS3716");
      169 +        case MPI26_MFGPAGE_DEVID_SAS4008:
      170 +                return ("SAS4008");
 140  171          default:
 141  172                  return ("?");
 142  173          }
 143  174  }
 144  175  
 145  176  int
 146  177  mptsas_ioc_get_facts(mptsas_t *mpt)
 147  178  {
 148  179          /*
 149  180           * Send get facts messages
 150  181           */
 151  182          if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_FACTS_REQUEST), NULL,
 152  183              mptsas_ioc_do_get_facts)) {
 153  184                  return (DDI_FAILURE);
 154  185          }
 155  186  
 156  187          /*
 157  188           * Get facts reply messages
 158  189           */
 159  190          if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_FACTS_REPLY), NULL,
 160  191              mptsas_ioc_do_get_facts_reply)) {
 161  192                  return (DDI_FAILURE);
 162  193          }
 163  194  
 164  195          return (DDI_SUCCESS);
 165  196  }
 166  197  
 167  198  static int
 168  199  mptsas_ioc_do_get_facts(mptsas_t *mpt, caddr_t memp, int var,
 169  200      ddi_acc_handle_t accessp)
 170  201  {
 171  202  #ifndef __lock_lint
 172  203          _NOTE(ARGUNUSED(var))
 173  204  #endif
 174  205          pMpi2IOCFactsRequest_t  facts;
 175  206          int                     numbytes;
 176  207  
 177  208          bzero(memp, sizeof (*facts));
 178  209          facts = (void *)memp;
 179  210          ddi_put8(accessp, &facts->Function, MPI2_FUNCTION_IOC_FACTS);
 180  211          numbytes = sizeof (*facts);
 181  212  
 182  213          /*
 183  214           * Post message via handshake
 184  215           */
 185  216          if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
 186  217                  return (DDI_FAILURE);
 187  218          }
 188  219  
 189  220          return (DDI_SUCCESS);
 190  221  }
 191  222  
 192  223  static int
 193  224  mptsas_ioc_do_get_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
 194  225      ddi_acc_handle_t accessp)
 195  226  {
 196  227  #ifndef __lock_lint
 197  228          _NOTE(ARGUNUSED(var))
 198  229  #endif
 199  230  
 200  231          pMpi2IOCFactsReply_t    factsreply;
 201  232          int                     numbytes;
 202  233          uint_t                  iocstatus;
 203  234          char                    buf[32];
 204  235          uint16_t                numReplyFrames;
 205  236          uint16_t                queueSize, queueDiff;
 206  237          int                     simple_sge_main;
 207  238          int                     simple_sge_next;
 208  239          uint32_t                capabilities;
 209  240          uint16_t                msgversion;
 210  241  
 211  242          bzero(memp, sizeof (*factsreply));
  
    | 
      ↓ open down ↓ | 
    62 lines elided | 
    
      ↑ open up ↑ | 
  
 212  243          factsreply = (void *)memp;
 213  244          numbytes = sizeof (*factsreply);
 214  245  
 215  246          /*
 216  247           * get ioc facts reply message
 217  248           */
 218  249          if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
 219  250                  return (DDI_FAILURE);
 220  251          }
 221  252  
 222      -        if (iocstatus = ddi_get16(accessp, &factsreply->IOCStatus)) {
      253 +        if ((iocstatus = ddi_get16(accessp, &factsreply->IOCStatus)) != 0) {
 223  254                  mptsas_log(mpt, CE_WARN, "mptsas_ioc_do_get_facts_reply: "
 224  255                      "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
 225  256                      ddi_get32(accessp, &factsreply->IOCLogInfo));
 226  257                  return (DDI_FAILURE);
 227  258          }
 228  259  
 229  260          /*
 230  261           * store key values from reply to mpt structure
 231  262           */
 232  263          mpt->m_fwversion = ddi_get32(accessp, &factsreply->FWVersion.Word);
 233  264          mpt->m_productid = ddi_get16(accessp, &factsreply->ProductID);
 234  265  
 235  266  
 236  267          (void) sprintf(buf, "%u.%u.%u.%u",
 237  268              ddi_get8(accessp, &factsreply->FWVersion.Struct.Major),
 238  269              ddi_get8(accessp, &factsreply->FWVersion.Struct.Minor),
 239  270              ddi_get8(accessp, &factsreply->FWVersion.Struct.Unit),
 240  271              ddi_get8(accessp, &factsreply->FWVersion.Struct.Dev));
 241      -        mptsas_log(mpt, CE_NOTE, "?MPT Firmware version v%s (%s)\n",
      272 +        mptsas_log(mpt, CE_NOTE, "MPT Firmware version v%s (%s)",
 242  273              buf, mptsas_devid_type_string(mpt));
 243  274          (void) ddi_prop_update_string(DDI_DEV_T_NONE, mpt->m_dip,
 244  275              "firmware-version", buf);
 245  276  
 246  277          /*
 247  278           * Set up request info.
 248  279           */
 249  280          mpt->m_max_requests = ddi_get16(accessp,
 250  281              &factsreply->RequestCredit) - 1;
 251  282          mpt->m_req_frame_size = ddi_get16(accessp,
 252  283              &factsreply->IOCRequestFrameSize) * 4;
 253  284  
 254  285          /*
 255  286           * Size of reply free queue should be the number of requests
 256  287           * plus some additional for events (32).  Make sure number of
 257  288           * reply frames is not a multiple of 16 so that the queue sizes
 258  289           * are calculated correctly later to be a multiple of 16.
 259  290           */
 260  291          mpt->m_reply_frame_size = ddi_get8(accessp,
 261  292              &factsreply->ReplyFrameSize) * 4;
 262  293          numReplyFrames = mpt->m_max_requests + 32;
 263  294          if (!(numReplyFrames % 16)) {
 264  295                  numReplyFrames--;
 265  296          }
 266  297          mpt->m_max_replies = numReplyFrames;
 267  298          queueSize = numReplyFrames;
 268  299          queueSize += 16 - (queueSize % 16);
 269  300          mpt->m_free_queue_depth = queueSize;
 270  301  
 271  302          /*
 272  303           * Size of reply descriptor post queue should be the number of
 273  304           * request frames + the number of reply frames + 1 and needs to
 274  305           * be a multiple of 16.  This size can be no larger than
 275  306           * MaxReplyDescriptorPostQueueDepth from IOCFacts.  If the
 276  307           * calculated queue size is larger than allowed, subtract a
 277  308           * multiple of 16 from m_max_requests, m_max_replies, and
 278  309           * m_reply_free_depth.
 279  310           */
 280  311          queueSize = mpt->m_max_requests + numReplyFrames + 1;
 281  312          if (queueSize % 16) {
 282  313                  queueSize += 16 - (queueSize % 16);
 283  314          }
 284  315          mpt->m_post_queue_depth = ddi_get16(accessp,
 285  316              &factsreply->MaxReplyDescriptorPostQueueDepth);
 286  317          if (queueSize > mpt->m_post_queue_depth) {
 287  318                  queueDiff = queueSize - mpt->m_post_queue_depth;
 288  319                  if (queueDiff % 16) {
 289  320                          queueDiff += 16 - (queueDiff % 16);
 290  321                  }
 291  322                  mpt->m_max_requests -= queueDiff;
 292  323                  mpt->m_max_replies -= queueDiff;
 293  324                  mpt->m_free_queue_depth -= queueDiff;
 294  325                  queueSize -= queueDiff;
 295  326          }
 296  327          mpt->m_post_queue_depth = queueSize;
 297  328  
 298  329          /*
 299  330           * Set up max chain depth.
 300  331           */
  
    | 
      ↓ open down ↓ | 
    49 lines elided | 
    
      ↑ open up ↑ | 
  
 301  332          mpt->m_max_chain_depth = ddi_get8(accessp,
 302  333              &factsreply->MaxChainDepth);
 303  334          mpt->m_ioc_capabilities = ddi_get32(accessp,
 304  335              &factsreply->IOCCapabilities);
 305  336  
 306  337          /*
 307  338           * Set flag to check for SAS3 support.
 308  339           */
 309  340          msgversion = ddi_get16(accessp, &factsreply->MsgVersion);
 310  341          if (msgversion >= MPI2_VERSION_02_05) {
 311      -                mptsas_log(mpt, CE_NOTE, "?mpt_sas%d SAS 3 Supported\n",
 312      -                    mpt->m_instance);
      342 +                mptsas_log(mpt, CE_NOTE, "SAS 3 supported Version (0x%x)",
      343 +                    msgversion);
 313  344                  mpt->m_MPI25 = TRUE;
 314  345          } else {
 315      -                mptsas_log(mpt, CE_NOTE, "?mpt_sas%d MPI Version 0x%x\n",
 316      -                    mpt->m_instance, msgversion);
      346 +                mptsas_log(mpt, CE_NOTE, "MPI Version 0x%x", msgversion);
 317  347          }
 318  348  
 319  349          /*
 320  350           * Calculate max frames per request based on DMA S/G length.
 321  351           */
 322  352          simple_sge_main = MPTSAS_MAX_FRAME_SGES64(mpt) - 1;
 323  353          simple_sge_next = mpt->m_req_frame_size / MPTSAS_SGE_SIZE(mpt) - 1;
 324  354  
 325  355          mpt->m_max_request_frames = (MPTSAS_MAX_DMA_SEGS -
 326  356              simple_sge_main) / simple_sge_next + 1;
 327  357          if (((MPTSAS_MAX_DMA_SEGS - simple_sge_main) %
 328  358              simple_sge_next) > 1) {
 329  359                  mpt->m_max_request_frames++;
 330  360          }
 331  361  
 332  362          /*
 333  363           * Check if controller supports FW diag buffers and set flag to enable
 334  364           * each type.
 335  365           */
 336  366          capabilities = ddi_get32(accessp, &factsreply->IOCCapabilities);
 337  367          if (capabilities & MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) {
 338  368                  mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_TRACE].enabled =
 339  369                      TRUE;
 340  370          }
 341  371          if (capabilities & MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) {
 342  372                  mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_SNAPSHOT].
 343  373                      enabled = TRUE;
 344  374          }
 345  375          if (capabilities & MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) {
 346  376                  mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_EXTENDED].
 347  377                      enabled = TRUE;
 348  378          }
 349  379  
 350  380          /*
 351  381           * Check if controller supports replaying events when issuing Message
 352  382           * Unit Reset and set flag to enable MUR.
 353  383           */
 354  384          if (capabilities & MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY) {
 355  385                  mpt->m_event_replay = TRUE;
 356  386          }
 357  387  
 358  388          /*
 359  389           * Check if controller supports IR.
 360  390           */
 361  391          if (capabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
 362  392                  mpt->m_ir_capable = TRUE;
 363  393          }
 364  394  
 365  395          return (DDI_SUCCESS);
 366  396  }
 367  397  
 368  398  int
 369  399  mptsas_ioc_get_port_facts(mptsas_t *mpt, int port)
 370  400  {
 371  401          /*
 372  402           * Send get port facts message
 373  403           */
 374  404          if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_FACTS_REQUEST), port,
 375  405              mptsas_ioc_do_get_port_facts)) {
 376  406                  return (DDI_FAILURE);
 377  407          }
 378  408  
 379  409          /*
 380  410           * Get port facts reply message
 381  411           */
 382  412          if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_FACTS_REPLY), port,
 383  413              mptsas_ioc_do_get_port_facts_reply)) {
 384  414                  return (DDI_FAILURE);
 385  415          }
 386  416  
 387  417          return (DDI_SUCCESS);
 388  418  }
 389  419  
 390  420  static int
 391  421  mptsas_ioc_do_get_port_facts(mptsas_t *mpt, caddr_t memp, int var,
 392  422      ddi_acc_handle_t accessp)
 393  423  {
 394  424          pMpi2PortFactsRequest_t facts;
 395  425          int                     numbytes;
 396  426  
 397  427          bzero(memp, sizeof (*facts));
 398  428          facts = (void *)memp;
 399  429          ddi_put8(accessp, &facts->Function, MPI2_FUNCTION_PORT_FACTS);
 400  430          ddi_put8(accessp, &facts->PortNumber, var);
 401  431          numbytes = sizeof (*facts);
 402  432  
 403  433          /*
 404  434           * Send port facts message via handshake
 405  435           */
 406  436          if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
 407  437                  return (DDI_FAILURE);
 408  438          }
 409  439  
 410  440          return (DDI_SUCCESS);
 411  441  }
 412  442  
 413  443  static int
 414  444  mptsas_ioc_do_get_port_facts_reply(mptsas_t *mpt, caddr_t memp, int var,
 415  445      ddi_acc_handle_t accessp)
 416  446  {
 417  447  #ifndef __lock_lint
 418  448          _NOTE(ARGUNUSED(var))
 419  449  #endif
 420  450          pMpi2PortFactsReply_t   factsreply;
 421  451          int                     numbytes;
 422  452          uint_t                  iocstatus;
 423  453  
 424  454          bzero(memp, sizeof (*factsreply));
  
    | 
      ↓ open down ↓ | 
    98 lines elided | 
    
      ↑ open up ↑ | 
  
 425  455          factsreply = (void *)memp;
 426  456          numbytes = sizeof (*factsreply);
 427  457  
 428  458          /*
 429  459           * Get port facts reply message via handshake
 430  460           */
 431  461          if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
 432  462                  return (DDI_FAILURE);
 433  463          }
 434  464  
 435      -        if (iocstatus = ddi_get16(accessp, &factsreply->IOCStatus)) {
      465 +        if ((iocstatus = ddi_get16(accessp, &factsreply->IOCStatus)) != 0) {
 436  466                  mptsas_log(mpt, CE_WARN, "mptsas_ioc_do_get_port_facts_reply: "
 437  467                      "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
 438  468                      ddi_get32(accessp, &factsreply->IOCLogInfo));
 439  469                  return (DDI_FAILURE);
 440  470          }
 441  471  
 442  472          return (DDI_SUCCESS);
 443  473  }
 444  474  
 445  475  int
 446  476  mptsas_ioc_enable_port(mptsas_t *mpt)
 447  477  {
 448  478          /*
 449  479           * Send enable port message
 450  480           */
 451  481          if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_ENABLE_REQUEST), 0,
 452  482              mptsas_ioc_do_enable_port)) {
 453  483                  return (DDI_FAILURE);
 454  484          }
 455  485  
 456  486          /*
 457  487           * Get enable port reply message
 458  488           */
 459  489          if (mptsas_do_dma(mpt, sizeof (MPI2_PORT_ENABLE_REPLY), 0,
 460  490              mptsas_ioc_do_enable_port_reply)) {
 461  491                  return (DDI_FAILURE);
 462  492          }
 463  493  
 464  494          return (DDI_SUCCESS);
 465  495  }
 466  496  
 467  497  static int
 468  498  mptsas_ioc_do_enable_port(mptsas_t *mpt, caddr_t memp, int var,
 469  499      ddi_acc_handle_t accessp)
 470  500  {
 471  501  #ifndef __lock_lint
 472  502          _NOTE(ARGUNUSED(var))
 473  503  #endif
 474  504          pMpi2PortEnableRequest_t        enable;
 475  505          int                             numbytes;
 476  506  
 477  507          bzero(memp, sizeof (*enable));
 478  508          enable = (void *)memp;
 479  509          ddi_put8(accessp, &enable->Function, MPI2_FUNCTION_PORT_ENABLE);
 480  510          numbytes = sizeof (*enable);
 481  511  
 482  512          /*
 483  513           * Send message via handshake
 484  514           */
 485  515          if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
 486  516                  return (DDI_FAILURE);
 487  517          }
 488  518  
 489  519          return (DDI_SUCCESS);
 490  520  }
 491  521  
 492  522  static int
 493  523  mptsas_ioc_do_enable_port_reply(mptsas_t *mpt, caddr_t memp, int var,
 494  524      ddi_acc_handle_t accessp)
 495  525  {
 496  526  #ifndef __lock_lint
 497  527          _NOTE(ARGUNUSED(var))
 498  528  #endif
 499  529  
 500  530          int                     numbytes;
 501  531          uint_t                  iocstatus;
 502  532          pMpi2PortEnableReply_t  portreply;
 503  533  
 504  534          numbytes = sizeof (MPI2_PORT_ENABLE_REPLY);
  
    | 
      ↓ open down ↓ | 
    59 lines elided | 
    
      ↑ open up ↑ | 
  
 505  535          bzero(memp, numbytes);
 506  536          portreply = (void *)memp;
 507  537  
 508  538          /*
 509  539           * Get message via handshake
 510  540           */
 511  541          if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
 512  542                  return (DDI_FAILURE);
 513  543          }
 514  544  
 515      -        if (iocstatus = ddi_get16(accessp, &portreply->IOCStatus)) {
      545 +        if ((iocstatus = ddi_get16(accessp, &portreply->IOCStatus)) != 0) {
 516  546                  mptsas_log(mpt, CE_WARN, "mptsas_ioc_do_enable_port_reply: "
 517  547                      "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
 518  548                      ddi_get32(accessp, &portreply->IOCLogInfo));
 519  549                  return (DDI_FAILURE);
 520  550          }
 521  551  
 522  552          return (DDI_SUCCESS);
 523  553  }
 524  554  
 525  555  int
 526  556  mptsas_ioc_enable_event_notification(mptsas_t *mpt)
 527  557  {
 528  558          ASSERT(mutex_owned(&mpt->m_mutex));
 529  559  
 530  560          /*
 531  561           * Send enable event notification message
 532  562           */
 533  563          if (mptsas_do_dma(mpt, sizeof (MPI2_EVENT_NOTIFICATION_REQUEST), NULL,
 534  564              mptsas_ioc_do_enable_event_notification)) {
 535  565                  return (DDI_FAILURE);
 536  566          }
 537  567  
 538  568          /*
 539  569           * Get enable event reply message
 540  570           */
 541  571          if (mptsas_do_dma(mpt, sizeof (MPI2_EVENT_NOTIFICATION_REPLY), NULL,
 542  572              mptsas_ioc_do_enable_event_notification_reply)) {
 543  573                  return (DDI_FAILURE);
 544  574          }
 545  575  
 546  576          return (DDI_SUCCESS);
 547  577  }
 548  578  
 549  579  static int
 550  580  mptsas_ioc_do_enable_event_notification(mptsas_t *mpt, caddr_t memp, int var,
 551  581      ddi_acc_handle_t accessp)
 552  582  {
 553  583  #ifndef __lock_lint
 554  584          _NOTE(ARGUNUSED(var))
 555  585  #endif
 556  586  
 557  587          pMpi2EventNotificationRequest_t event;
 558  588          int                             numbytes;
 559  589  
 560  590          bzero(memp, sizeof (*event));
 561  591          event = (void *)memp;
 562  592          ddi_put8(accessp, &event->Function, MPI2_FUNCTION_EVENT_NOTIFICATION);
 563  593          numbytes = sizeof (*event);
 564  594  
 565  595          /*
 566  596           * Send message via handshake
 567  597           */
 568  598          if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
 569  599                  return (DDI_FAILURE);
 570  600          }
 571  601  
 572  602          return (DDI_SUCCESS);
 573  603  }
 574  604  
 575  605  static int
 576  606  mptsas_ioc_do_enable_event_notification_reply(mptsas_t *mpt, caddr_t memp,
 577  607      int var, ddi_acc_handle_t accessp)
 578  608  {
 579  609  #ifndef __lock_lint
 580  610          _NOTE(ARGUNUSED(var))
 581  611  #endif
 582  612          int                             numbytes;
 583  613          uint_t                          iocstatus;
 584  614          pMpi2EventNotificationReply_t   eventsreply;
 585  615  
 586  616          numbytes = sizeof (MPI2_EVENT_NOTIFICATION_REPLY);
  
    | 
      ↓ open down ↓ | 
    61 lines elided | 
    
      ↑ open up ↑ | 
  
 587  617          bzero(memp, numbytes);
 588  618          eventsreply = (void *)memp;
 589  619  
 590  620          /*
 591  621           * Get message via handshake
 592  622           */
 593  623          if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
 594  624                  return (DDI_FAILURE);
 595  625          }
 596  626  
 597      -        if (iocstatus = ddi_get16(accessp, &eventsreply->IOCStatus)) {
      627 +        if ((iocstatus = ddi_get16(accessp, &eventsreply->IOCStatus)) != 0) {
 598  628                  mptsas_log(mpt, CE_WARN,
 599  629                      "mptsas_ioc_do_enable_event_notification_reply: "
 600  630                      "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
 601  631                      ddi_get32(accessp, &eventsreply->IOCLogInfo));
 602  632                  return (DDI_FAILURE);
 603  633          }
 604  634  
 605  635          return (DDI_SUCCESS);
 606  636  }
 607  637  
 608  638  int
 609  639  mptsas_ioc_init(mptsas_t *mpt)
 610  640  {
 611  641          /*
 612  642           * Send ioc init message
 613  643           */
 614  644          if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_INIT_REQUEST), NULL,
 615  645              mptsas_do_ioc_init)) {
 616  646                  return (DDI_FAILURE);
 617  647          }
 618  648  
 619  649          /*
 620  650           * Get ioc init reply message
 621  651           */
 622  652          if (mptsas_do_dma(mpt, sizeof (MPI2_IOC_INIT_REPLY), NULL,
 623  653              mptsas_do_ioc_init_reply)) {
 624  654                  return (DDI_FAILURE);
 625  655          }
 626  656  
 627  657          return (DDI_SUCCESS);
 628  658  }
 629  659  
 630  660  static int
 631  661  mptsas_do_ioc_init(mptsas_t *mpt, caddr_t memp, int var,
 632  662      ddi_acc_handle_t accessp)
 633  663  {
 634  664  #ifndef __lock_lint
 635  665          _NOTE(ARGUNUSED(var))
 636  666  #endif
 637  667  
 638  668          pMpi2IOCInitRequest_t   init;
 639  669          int                     numbytes;
 640  670          timespec_t              time;
 641  671          uint64_t                mSec;
 642  672  
 643  673          bzero(memp, sizeof (*init));
 644  674          init = (void *)memp;
 645  675          ddi_put8(accessp, &init->Function, MPI2_FUNCTION_IOC_INIT);
 646  676          ddi_put8(accessp, &init->WhoInit, MPI2_WHOINIT_HOST_DRIVER);
 647  677          ddi_put16(accessp, &init->MsgVersion, MPI2_VERSION);
 648  678          ddi_put16(accessp, &init->HeaderVersion, MPI2_HEADER_VERSION);
 649  679          ddi_put16(accessp, &init->SystemRequestFrameSize,
 650  680              mpt->m_req_frame_size / 4);
 651  681          ddi_put16(accessp, &init->ReplyDescriptorPostQueueDepth,
 652  682              mpt->m_post_queue_depth);
 653  683          ddi_put16(accessp, &init->ReplyFreeQueueDepth,
 654  684              mpt->m_free_queue_depth);
 655  685  
 656  686          /*
 657  687           * These addresses are set using the DMA cookie addresses from when the
 658  688           * memory was allocated.  Sense buffer hi address should be 0.
 659  689           */
 660  690          ddi_put32(accessp, &init->SenseBufferAddressHigh,
 661  691              (uint32_t)(mpt->m_req_sense_dma_addr >> 32));
 662  692          ddi_put32(accessp, &init->SystemReplyAddressHigh,
 663  693              (uint32_t)(mpt->m_reply_frame_dma_addr >> 32));
 664  694          ddi_put32(accessp, &init->SystemRequestFrameBaseAddress.High,
 665  695              (uint32_t)(mpt->m_req_frame_dma_addr >> 32));
 666  696          ddi_put32(accessp, &init->SystemRequestFrameBaseAddress.Low,
 667  697              (uint32_t)mpt->m_req_frame_dma_addr);
 668  698          ddi_put32(accessp, &init->ReplyDescriptorPostQueueAddress.High,
 669  699              (uint32_t)(mpt->m_post_queue_dma_addr >> 32));
 670  700          ddi_put32(accessp, &init->ReplyDescriptorPostQueueAddress.Low,
 671  701              (uint32_t)mpt->m_post_queue_dma_addr);
 672  702          ddi_put32(accessp, &init->ReplyFreeQueueAddress.High,
 673  703              (uint32_t)(mpt->m_free_queue_dma_addr >> 32));
 674  704          ddi_put32(accessp, &init->ReplyFreeQueueAddress.Low,
 675  705              (uint32_t)mpt->m_free_queue_dma_addr);
 676  706  
 677  707          /*
 678  708           * Fill in the timestamp with the number of milliseconds since midnight
 679  709           * of January 1, 1970 UT (Greenwich Mean Time).  Time is returned in
 680  710           * seconds and nanoseconds.  Translate both to milliseconds and add
 681  711           * them together to get total milliseconds.
 682  712           */
 683  713          gethrestime(&time);
 684  714          mSec = time.tv_sec * MILLISEC;
 685  715          mSec += (time.tv_nsec / MICROSEC);
 686  716          ddi_put32(accessp, &init->TimeStamp.High, (uint32_t)(mSec >> 32));
 687  717          ddi_put32(accessp, &init->TimeStamp.Low, (uint32_t)mSec);
 688  718  
 689  719          numbytes = sizeof (*init);
 690  720  
 691  721          /*
 692  722           * Post message via handshake
 693  723           */
 694  724          if (mptsas_send_handshake_msg(mpt, memp, numbytes, accessp)) {
 695  725                  return (DDI_FAILURE);
 696  726          }
 697  727  
 698  728          return (DDI_SUCCESS);
 699  729  }
 700  730  
 701  731  static int
 702  732  mptsas_do_ioc_init_reply(mptsas_t *mpt, caddr_t memp, int var,
 703  733      ddi_acc_handle_t accessp)
 704  734  {
 705  735  #ifndef __lock_lint
 706  736          _NOTE(ARGUNUSED(var))
 707  737  #endif
 708  738  
 709  739          pMpi2IOCInitReply_t     initreply;
 710  740          int                     numbytes;
 711  741          uint_t                  iocstatus;
 712  742  
 713  743          numbytes = sizeof (MPI2_IOC_INIT_REPLY);
  
    | 
      ↓ open down ↓ | 
    106 lines elided | 
    
      ↑ open up ↑ | 
  
 714  744          bzero(memp, numbytes);
 715  745          initreply = (void *)memp;
 716  746  
 717  747          /*
 718  748           * Get reply message via handshake
 719  749           */
 720  750          if (mptsas_get_handshake_msg(mpt, memp, numbytes, accessp)) {
 721  751                  return (DDI_FAILURE);
 722  752          }
 723  753  
 724      -        if (iocstatus = ddi_get16(accessp, &initreply->IOCStatus)) {
      754 +        if ((iocstatus = ddi_get16(accessp, &initreply->IOCStatus)) != 0) {
 725  755                  mptsas_log(mpt, CE_WARN, "mptsas_do_ioc_init_reply: "
 726  756                      "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
 727  757                      ddi_get32(accessp, &initreply->IOCLogInfo));
 728  758                  return (DDI_FAILURE);
 729  759          }
 730  760  
 731  761          if ((ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell)) &
 732  762              MPI2_IOC_STATE_OPERATIONAL) {
 733      -                mptsas_log(mpt, CE_NOTE,
 734      -                    "?mpt%d: IOC Operational.\n", mpt->m_instance);
      763 +                mptsas_log(mpt, CE_NOTE, "IOC Operational");
 735  764          } else {
 736  765                  return (DDI_FAILURE);
 737  766          }
 738  767  
 739  768          return (DDI_SUCCESS);
 740  769  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX