Print this page
Update tx waitq's code.
Create 2 threads, divide the workflow and deliver
to the hardware from the threads.
Enable Fast Path for capable devices.
Lint and cstyle fixes.
Fix problem with running against 64bit msgaddr attributes for DMA.
Default is now to run like this.
Major rework of mutexes.
During normal operation do not grab m_mutex during interrupt.
Use reply post queues instead.
Fixes to some address arithmetic using 32bit values.
Merge fixes for "4403 mpt_sas panic when pulling a drive", commit f7d0d869a9ae78d
Initial modifications using the code changes present between
the LSI source code for FreeBSD drivers. Specifically the changes
between from mpslsi-source-17.00.00.00 -> mpslsi-source-03.00.00.00.
This mainly involves using a different scatter/gather element in
frame setup.
Changes to enable driver to compile.
Header paths, object lists, etc.

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/scsi/adapters/mpt_sas3/mptsas3_impl.c
          +++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas3/mptsas3_impl.c
↓ 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
       25 + * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
       26 + * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
  25   27   */
  26   28  
  27   29  /*
  28   30   * Copyright (c) 2000 to 2010, LSI Corporation.
  29   31   * All rights reserved.
  30   32   *
  31   33   * Redistribution and use in source and binary forms of all code within
  32   34   * this file that is exclusively owned by LSI, with or without
  33   35   * modification, is permitted provided that, in addition to the CDDL 1.0
  34   36   * License requirements, the following conditions are met:
↓ open down ↓ 26 lines elided ↑ open up ↑
  61   63  #endif
  62   64  
  63   65  /*
  64   66   * standard header files
  65   67   */
  66   68  #include <sys/note.h>
  67   69  #include <sys/scsi/scsi.h>
  68   70  #include <sys/pci.h>
  69   71  
  70   72  #pragma pack(1)
  71      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  72      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  73      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  74      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  75      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  76      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  77      -#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
       73 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_type.h>
       74 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2.h>
       75 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_cnfg.h>
       76 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_init.h>
       77 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_ioc.h>
       78 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_sas.h>
       79 +#include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_tool.h>
  78   80  #pragma pack()
  79   81  
  80   82  /*
  81   83   * private header files.
  82   84   */
  83      -#include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  84      -#include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
       85 +#include <sys/scsi/adapters/mpt_sas3/mptsas3_var.h>
       86 +#include <sys/scsi/adapters/mpt_sas3/mptsas3_smhba.h>
  85   87  
  86   88  /*
  87   89   * FMA header files.
  88   90   */
  89   91  #include <sys/fm/io/ddi.h>
  90   92  
  91   93  #if defined(MPTSAS_DEBUG)
  92   94  extern uint32_t mptsas_debug_flags;
       95 +extern uint32_t mptsas_dbglog_imask;
  93   96  #endif
  94   97  
  95   98  /*
  96   99   *  prototypes
  97  100   */
  98  101  static void mptsas_ioc_event_cmdq_add(mptsas_t *mpt, m_event_struct_t *cmd);
  99  102  static void mptsas_ioc_event_cmdq_delete(mptsas_t *mpt, m_event_struct_t *cmd);
 100  103  static m_event_struct_t *mptsas_ioc_event_find_by_cmd(mptsas_t *mpt,
 101  104      struct mptsas_cmd *cmd);
 102  105  
↓ open down ↓ 95 lines elided ↑ open up ↑
 198  201  }
 199  202  
 200  203  void
 201  204  mptsas_start_config_page_access(mptsas_t *mpt, mptsas_cmd_t *cmd)
 202  205  {
 203  206          pMpi2ConfigRequest_t    request;
 204  207          pMpi2SGESimple64_t      sge;
 205  208          struct scsi_pkt         *pkt = cmd->cmd_pkt;
 206  209          mptsas_config_request_t *config = pkt->pkt_ha_private;
 207  210          uint8_t                 direction;
 208      -        uint32_t                length, flagslength, request_desc_low;
      211 +        uint32_t                length, flagslength;
      212 +        uint64_t                request_desc;
 209  213  
 210  214          ASSERT(mutex_owned(&mpt->m_mutex));
 211  215  
 212  216          /*
 213  217           * Point to the correct message and clear it as well as the global
 214  218           * config page memory.
 215  219           */
 216  220          request = (pMpi2ConfigRequest_t)(mpt->m_req_frame +
 217  221              (mpt->m_req_frame_size * cmd->cmd_slot));
 218  222          bzero(request, mpt->m_req_frame_size);
↓ open down ↓ 33 lines elided ↑ open up ↑
 252  256                      MPI2_CONFIG_PAGETYPE_EXTENDED) {
 253  257                          length = config->ext_page_length * 4;
 254  258                  } else {
 255  259                          length = config->page_length * 4;
 256  260                  }
 257  261  
 258  262                  if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
 259  263                          direction = MPI2_SGE_FLAGS_HOST_TO_IOC;
 260  264                  }
 261  265                  ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
 262      -                    (uint32_t)cmd->cmd_dma_addr);
      266 +                    (uint32_t)(cmd->cmd_dma_addr&0xfffffffful));
 263  267                  ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
 264  268                      (uint32_t)(cmd->cmd_dma_addr >> 32));
 265  269          }
 266  270          ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber,
 267  271              config->page_number);
 268  272          ddi_put32(mpt->m_acc_req_frame_hdl, &request->PageAddress,
 269  273              config->page_address);
 270  274          flagslength = ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
 271  275              MPI2_SGE_FLAGS_END_OF_BUFFER |
 272  276              MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
 273  277              MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
 274  278              MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
 275  279              direction |
 276  280              MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
 277  281          flagslength |= length;
 278  282          ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
 279  283  
 280  284          (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
 281  285              DDI_DMA_SYNC_FORDEV);
 282      -        request_desc_low = (cmd->cmd_slot << 16) +
      286 +        request_desc = (cmd->cmd_slot << 16) +
 283  287              MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 284  288          cmd->cmd_rfm = NULL;
 285      -        MPTSAS_START_CMD(mpt, request_desc_low, 0);
      289 +        MPTSAS_START_CMD(mpt, request_desc);
 286  290          if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
 287  291              DDI_SUCCESS) ||
 288  292              (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
 289  293              DDI_SUCCESS)) {
 290  294                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
 291  295          }
 292  296  }
 293  297  
 294  298  int
 295  299  mptsas_access_config_page(mptsas_t *mpt, uint8_t action, uint8_t page_type,
↓ open down ↓ 6 lines elided ↑ open up ↑
 302  306          ddi_acc_handle_t        accessp;
 303  307          size_t                  len = 0;
 304  308          mptsas_config_request_t config;
 305  309          int                     rval = DDI_SUCCESS, config_flags = 0;
 306  310          mptsas_cmd_t            *cmd;
 307  311          struct scsi_pkt         *pkt;
 308  312          pMpi2ConfigReply_t      reply;
 309  313          uint16_t                iocstatus = 0;
 310  314          uint32_t                iocloginfo;
 311  315          caddr_t                 page_memp;
      316 +        boolean_t               free_dma = B_FALSE;
 312  317  
 313  318          va_start(ap, callback);
 314  319          ASSERT(mutex_owned(&mpt->m_mutex));
 315  320  
 316  321          /*
 317  322           * Get a command from the pool.
 318  323           */
 319  324          if ((rval = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
 320  325                  mptsas_log(mpt, CE_NOTE, "command pool is full for config "
 321  326                      "page request");
↓ open down ↓ 62 lines elided ↑ open up ↑
 384  389  
 385  390          /*
 386  391           * cmd_rfm points to the reply message if a reply was given.  Check the
 387  392           * IOCStatus to make sure everything went OK with the header request.
 388  393           */
 389  394          if (cmd->cmd_rfm) {
 390  395                  config_flags |= MPTSAS_ADDRESS_REPLY;
 391  396                  (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
 392  397                      DDI_DMA_SYNC_FORCPU);
 393  398                  reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
 394      -                    - mpt->m_reply_frame_dma_addr));
      399 +                    - (mpt->m_reply_frame_dma_addr&0xfffffffful)));
 395  400                  config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
 396  401                      &reply->Header.PageType);
 397  402                  config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl,
 398  403                      &reply->Header.PageNumber);
 399  404                  config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl,
 400  405                      &reply->Header.PageLength);
 401  406                  config.page_version = ddi_get8(mpt->m_acc_reply_frame_hdl,
 402  407                      &reply->Header.PageVersion);
 403  408                  config.ext_page_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
 404  409                      &reply->ExtPageType);
↓ open down ↓ 53 lines elided ↑ open up ↑
 458  463           * de-allocated after the command completes.  The size of the reply
 459  464           * will not be larger than the reply frame size.
 460  465           */
 461  466          attrs = mpt->m_msg_dma_attr;
 462  467          attrs.dma_attr_sgllen = 1;
 463  468          attrs.dma_attr_granular = (uint32_t)len;
 464  469  
 465  470          if (mptsas_dma_addr_create(mpt, attrs,
 466  471              &cmd->cmd_dmahandle, &accessp, &page_memp,
 467  472              len, &cookie) == FALSE) {
      473 +                mptsas_log(mpt, CE_WARN,
      474 +                    "mptsas_dma_addr_create(len=0x%x) failed", (int)len);
      475 +                rval = DDI_FAILURE;
 468  476                  goto page_done;
 469  477          }
      478 +        /* NOW we can safely call mptsas_dma_addr_destroy(). */
      479 +        free_dma = B_TRUE;
      480 +
 470  481          cmd->cmd_dma_addr = cookie.dmac_laddress;
 471  482          bzero(page_memp, len);
 472  483  
 473  484          /*
 474  485           * Save the data for this request to be used in the call to start the
 475  486           * config page read
 476  487           */
 477  488          config.action = action;
 478  489          config.page_address = page_address;
 479  490  
↓ open down ↓ 43 lines elided ↑ open up ↑
 523  534           * frame and the config page are returned from this function in the
 524  535           * param list.
 525  536           */
 526  537          if (cmd->cmd_rfm) {
 527  538                  config_flags |= MPTSAS_ADDRESS_REPLY;
 528  539                  (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
 529  540                      DDI_DMA_SYNC_FORCPU);
 530  541                  (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
 531  542                      DDI_DMA_SYNC_FORCPU);
 532  543                  reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm
 533      -                    - mpt->m_reply_frame_dma_addr));
      544 +                    - (mpt->m_reply_frame_dma_addr&0xfffffffful)));
 534  545                  iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
 535  546                      &reply->IOCStatus);
 536  547                  iocstatus = MPTSAS_IOCSTATUS(iocstatus);
 537  548                  iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
 538  549                      &reply->IOCLogInfo);
 539  550          }
 540  551  
 541  552          if (callback(mpt, page_memp, accessp, iocstatus, iocloginfo, ap)) {
 542  553                  rval = DDI_FAILURE;
 543  554                  goto page_done;
↓ open down ↓ 33 lines elided ↑ open up ↑
 577  588                      cmd->cmd_rfm);
 578  589                  (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
 579  590                      DDI_DMA_SYNC_FORDEV);
 580  591                  if (++mpt->m_free_index == mpt->m_free_queue_depth) {
 581  592                          mpt->m_free_index = 0;
 582  593                  }
 583  594                  ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
 584  595                      mpt->m_free_index);
 585  596          }
 586  597  
 587      -        mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp);
      598 +        if (free_dma)
      599 +                mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp);
 588  600  
 589  601          if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
 590  602                  mptsas_remove_cmd(mpt, cmd);
 591  603                  config_flags &= (~MPTSAS_REQUEST_POOL_CMD);
 592  604          }
 593  605          if (config_flags & MPTSAS_REQUEST_POOL_CMD)
 594  606                  mptsas_return_to_pool(mpt, cmd);
 595  607  
 596  608          if (config_flags & MPTSAS_CMD_TIMEOUT) {
 597  609                  mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
↓ open down ↓ 1 lines elided ↑ open up ↑
 599  611                          mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
 600  612                  }
 601  613          }
 602  614  
 603  615          return (rval);
 604  616  }
 605  617  
 606  618  int
 607  619  mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype,
 608  620          uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion,
 609      -        uint8_t pagelength, uint32_t SGEflagslength, uint32_t SGEaddress32)
      621 +        uint8_t pagelength, uint32_t SGEflagslength, uint64_t SGEaddress)
 610  622  {
 611  623          pMpi2ConfigRequest_t    config;
 612  624          int                     send_numbytes;
 613  625  
 614  626          bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
 615  627          config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
 616  628          ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
 617  629          ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
 618  630          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
 619  631          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType, pagetype);
 620  632          ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
 621  633          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
 622  634          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength);
 623  635          ddi_put32(mpt->m_hshk_acc_hdl,
 624  636              &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
 625  637          ddi_put32(mpt->m_hshk_acc_hdl,
 626      -            &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
      638 +            &config->PageBufferSGE.MpiSimple.u.Address64.Low,
      639 +            SGEaddress&0xfffffffful);
      640 +        ddi_put32(mpt->m_hshk_acc_hdl,
      641 +            &config->PageBufferSGE.MpiSimple.u.Address64.High,
      642 +            SGEaddress >> 32);
 627  643          send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
 628  644  
 629  645          /*
 630  646           * Post message via handshake
 631  647           */
 632  648          if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
 633  649              mpt->m_hshk_acc_hdl)) {
 634  650                  return (-1);
 635  651          }
 636  652          return (0);
 637  653  }
 638  654  
 639  655  int
 640  656  mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action,
 641  657          uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber,
 642  658          uint8_t pageversion, uint16_t extpagelength,
 643      -        uint32_t SGEflagslength, uint32_t SGEaddress32)
      659 +        uint32_t SGEflagslength, uint64_t SGEaddress)
 644  660  {
 645  661          pMpi2ConfigRequest_t    config;
 646  662          int                     send_numbytes;
 647  663  
 648  664          bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
 649  665          config = (pMpi2ConfigRequest_t)mpt->m_hshk_memp;
 650  666          ddi_put8(mpt->m_hshk_acc_hdl, &config->Function, MPI2_FUNCTION_CONFIG);
 651  667          ddi_put8(mpt->m_hshk_acc_hdl, &config->Action, action);
 652  668          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageNumber, pagenumber);
 653  669          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageType,
 654  670              MPI2_CONFIG_PAGETYPE_EXTENDED);
 655  671          ddi_put8(mpt->m_hshk_acc_hdl, &config->ExtPageType, extpagetype);
 656  672          ddi_put32(mpt->m_hshk_acc_hdl, &config->PageAddress, pageaddress);
 657  673          ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion);
 658  674          ddi_put16(mpt->m_hshk_acc_hdl, &config->ExtPageLength, extpagelength);
 659  675          ddi_put32(mpt->m_hshk_acc_hdl,
 660  676              &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength);
 661  677          ddi_put32(mpt->m_hshk_acc_hdl,
 662      -            &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32);
      678 +            &config->PageBufferSGE.MpiSimple.u.Address64.Low,
      679 +            SGEaddress&0xfffffffful);
      680 +        ddi_put32(mpt->m_hshk_acc_hdl,
      681 +            &config->PageBufferSGE.MpiSimple.u.Address64.High,
      682 +            SGEaddress >> 32);
 663  683          send_numbytes = sizeof (MPI2_CONFIG_REQUEST);
 664  684  
 665  685          /*
 666  686           * Post message via handshake
 667  687           */
 668  688          if (mptsas_send_handshake_msg(mpt, (caddr_t)config, send_numbytes,
 669  689              mpt->m_hshk_acc_hdl)) {
 670  690                  return (-1);
 671  691          }
 672  692          return (0);
↓ open down ↓ 407 lines elided ↑ open up ↑
1080 1100           * we make use of the pre-existing mptsas_cmd_t and
1081 1101           * scsi_pkt which are included in the mptsas_t which
1082 1102           * is passed to this routine.
1083 1103           */
1084 1104  
1085 1105          pMpi2SCSITaskManagementRequest_t        task;
1086 1106          int                                     rval = FALSE;
1087 1107          mptsas_cmd_t                            *cmd;
1088 1108          struct scsi_pkt                         *pkt;
1089 1109          mptsas_slots_t                          *slots = mpt->m_active;
1090      -        uint32_t                                request_desc_low, i;
     1110 +        uint32_t                                i;
     1111 +        uint64_t                                request_desc;
1091 1112          pMPI2DefaultReply_t                     reply_msg;
1092 1113  
1093 1114          /*
1094 1115           * Can't start another task management routine.
1095 1116           */
1096 1117          if (slots->m_slot[MPTSAS_TM_SLOT(mpt)] != NULL) {
1097 1118                  mptsas_log(mpt, CE_WARN, "Can only start 1 task management"
1098 1119                      " command at a time\n");
1099 1120                  return (FALSE);
1100 1121          }
↓ open down ↓ 35 lines elided ↑ open up ↑
1136 1157          /*
1137 1158           * Set the task type
1138 1159           */
1139 1160          ddi_put8(mpt->m_acc_req_frame_hdl, &task->TaskType, task_type);
1140 1161  
1141 1162          /*
1142 1163           * Send TM request using High Priority Queue.
1143 1164           */
1144 1165          (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
1145 1166              DDI_DMA_SYNC_FORDEV);
1146      -        request_desc_low = (cmd->cmd_slot << 16) +
     1167 +        request_desc = (cmd->cmd_slot << 16) +
1147 1168              MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
1148      -        MPTSAS_START_CMD(mpt, request_desc_low, 0);
     1169 +        MPTSAS_START_CMD(mpt, request_desc);
1149 1170          rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
1150 1171  
1151 1172          if (pkt->pkt_reason == CMD_INCOMPLETE)
1152 1173                  rval = FALSE;
1153 1174  
1154 1175          /*
1155 1176           * If a reply frame was used and there is a reply buffer to copy the
1156 1177           * reply data into, copy it.  If this fails, log a message, but don't
1157 1178           * fail the TM request.
1158 1179           */
1159 1180          if (cmd->cmd_rfm && reply) {
1160 1181                  (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
1161 1182                      DDI_DMA_SYNC_FORCPU);
1162 1183                  reply_msg = (pMPI2DefaultReply_t)
1163 1184                      (mpt->m_reply_frame + (cmd->cmd_rfm -
1164      -                    mpt->m_reply_frame_dma_addr));
     1185 +                    (mpt->m_reply_frame_dma_addr&0xfffffffful)));
1165 1186                  if (reply_size > sizeof (MPI2_SCSI_TASK_MANAGE_REPLY)) {
1166 1187                          reply_size = sizeof (MPI2_SCSI_TASK_MANAGE_REPLY);
1167 1188                  }
1168 1189                  mutex_exit(&mpt->m_mutex);
1169 1190                  for (i = 0; i < reply_size; i++) {
1170 1191                          if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
1171 1192                              mode)) {
1172 1193                                  mptsas_log(mpt, CE_WARN, "failed to copy out "
1173 1194                                      "reply data for TM request");
1174 1195                                  break;
↓ open down ↓ 17 lines elided ↑ open up ↑
1192 1213                  mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
1193 1214                  if (mptsas_restart_ioc(mpt)) {
1194 1215                          mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
1195 1216                          rval = FAILED;
1196 1217                  }
1197 1218          }
1198 1219  
1199 1220          return (rval);
1200 1221  }
1201 1222  
     1223 +/*
     1224 + * Complete firmware download frame for v2.0 cards.
     1225 + */
     1226 +static void
     1227 +mptsas_uflash2(pMpi2FWDownloadRequest fwdownload,
     1228 +    ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type,
     1229 +    ddi_dma_cookie_t flsh_cookie)
     1230 +{
     1231 +        pMpi2FWDownloadTCSGE_t  tcsge;
     1232 +        pMpi2SGESimple64_t      sge;
     1233 +        uint32_t                flagslength;
     1234 +
     1235 +        ddi_put8(acc_hdl, &fwdownload->Function,
     1236 +            MPI2_FUNCTION_FW_DOWNLOAD);
     1237 +        ddi_put8(acc_hdl, &fwdownload->ImageType, type);
     1238 +        ddi_put8(acc_hdl, &fwdownload->MsgFlags,
     1239 +            MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
     1240 +        ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size);
     1241 +
     1242 +        tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL;
     1243 +        ddi_put8(acc_hdl, &tcsge->ContextSize, 0);
     1244 +        ddi_put8(acc_hdl, &tcsge->DetailsLength, 12);
     1245 +        ddi_put8(acc_hdl, &tcsge->Flags, 0);
     1246 +        ddi_put32(acc_hdl, &tcsge->ImageOffset, 0);
     1247 +        ddi_put32(acc_hdl, &tcsge->ImageSize, size);
     1248 +
     1249 +        sge = (pMpi2SGESimple64_t)(tcsge + 1);
     1250 +        flagslength = size;
     1251 +        flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
     1252 +            MPI2_SGE_FLAGS_END_OF_BUFFER |
     1253 +            MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
     1254 +            MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
     1255 +            MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
     1256 +            MPI2_SGE_FLAGS_HOST_TO_IOC |
     1257 +            MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
     1258 +        ddi_put32(acc_hdl, &sge->FlagsLength, flagslength);
     1259 +        ddi_put32(acc_hdl, &sge->Address.Low,
     1260 +            flsh_cookie.dmac_address);
     1261 +        ddi_put32(acc_hdl, &sge->Address.High,
     1262 +            (uint32_t)(flsh_cookie.dmac_laddress >> 32));
     1263 +}
     1264 +
     1265 +/*
     1266 + * Complete firmware download frame for v2.5 cards.
     1267 + */
     1268 +static void
     1269 +mptsas_uflash25(pMpi25FWDownloadRequest fwdownload,
     1270 +    ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type,
     1271 +    ddi_dma_cookie_t flsh_cookie)
     1272 +{
     1273 +        pMpi2IeeeSgeSimple64_t  sge;
     1274 +        uint8_t                 flags;
     1275 +
     1276 +        ddi_put8(acc_hdl, &fwdownload->Function,
     1277 +            MPI2_FUNCTION_FW_DOWNLOAD);
     1278 +        ddi_put8(acc_hdl, &fwdownload->ImageType, type);
     1279 +        ddi_put8(acc_hdl, &fwdownload->MsgFlags,
     1280 +            MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
     1281 +        ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size);
     1282 +
     1283 +        ddi_put32(acc_hdl, &fwdownload->ImageOffset, 0);
     1284 +        ddi_put32(acc_hdl, &fwdownload->ImageSize, size);
     1285 +
     1286 +        sge = (pMpi2IeeeSgeSimple64_t)&fwdownload->SGL;
     1287 +        flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
     1288 +            MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
     1289 +            MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
     1290 +        ddi_put8(acc_hdl, &sge->Flags, flags);
     1291 +        ddi_put32(acc_hdl, &sge->Length, size);
     1292 +        ddi_put32(acc_hdl, &sge->Address.Low,
     1293 +            flsh_cookie.dmac_address);
     1294 +        ddi_put32(acc_hdl, &sge->Address.High,
     1295 +            (uint32_t)(flsh_cookie.dmac_laddress >> 32));
     1296 +}
     1297 +
     1298 +static int mptsas_enable_mpi25_flashupdate = 0;
     1299 +
1202 1300  int
1203 1301  mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size,
1204 1302      uint8_t type, int mode)
1205 1303  {
1206 1304  
1207 1305          /*
1208 1306           * In order to avoid allocating variables on the stack,
1209 1307           * we make use of the pre-existing mptsas_cmd_t and
1210 1308           * scsi_pkt which are included in the mptsas_t which
1211 1309           * is passed to this routine.
1212 1310           */
1213 1311  
1214 1312          ddi_dma_attr_t          flsh_dma_attrs;
1215 1313          ddi_dma_cookie_t        flsh_cookie;
1216 1314          ddi_dma_handle_t        flsh_dma_handle;
1217 1315          ddi_acc_handle_t        flsh_accessp;
1218 1316          caddr_t                 memp, flsh_memp;
1219      -        uint32_t                flagslength;
1220      -        pMpi2FWDownloadRequest  fwdownload;
1221      -        pMpi2FWDownloadTCSGE_t  tcsge;
1222      -        pMpi2SGESimple64_t      sge;
1223 1317          mptsas_cmd_t            *cmd;
1224 1318          struct scsi_pkt         *pkt;
1225 1319          int                     i;
1226 1320          int                     rvalue = 0;
1227      -        uint32_t                request_desc_low;
     1321 +        uint64_t                request_desc;
     1322 +
     1323 +        if (mpt->m_MPI25) {
     1324 +                /*
     1325 +                 * The code is there but not tested yet.
     1326 +                 * User has to know there are risks here.
     1327 +                 */
     1328 +                mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): "
     1329 +                    "Updating firmware through MPI 2.5 has not been "
     1330 +                    "tested yet!\n"
     1331 +                    "To enable set mptsas_enable_mpi25_flashupdate to 1\n");
     1332 +                if (!mptsas_enable_mpi25_flashupdate)
     1333 +                        return (-1);
     1334 +        }
1228 1335  
1229 1336          if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
1230 1337                  mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation "
1231 1338                      "failed. event ack command pool is full\n");
1232 1339                  return (rvalue);
1233 1340          }
1234 1341  
1235 1342          bzero((caddr_t)cmd, sizeof (*cmd));
1236 1343          bzero((caddr_t)pkt, scsi_pkt_size());
1237 1344          cmd->ioc_cmd_slot = (uint32_t)rvalue;
↓ open down ↓ 40 lines elided ↑ open up ↑
1278 1385                  mptsas_return_to_pool(mpt, cmd);
1279 1386                  return (-1);
1280 1387          }
1281 1388  
1282 1389          /*
1283 1390           * Fill in fw download message
1284 1391           */
1285 1392          ASSERT(cmd->cmd_slot != 0);
1286 1393          memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
1287 1394          bzero(memp, mpt->m_req_frame_size);
1288      -        fwdownload = (void *)memp;
1289      -        ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->Function,
1290      -            MPI2_FUNCTION_FW_DOWNLOAD);
1291      -        ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->ImageType, type);
1292      -        ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->MsgFlags,
1293      -            MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT);
1294      -        ddi_put32(mpt->m_acc_req_frame_hdl, &fwdownload->TotalImageSize, size);
1295 1395  
1296      -        tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL;
1297      -        ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->ContextSize, 0);
1298      -        ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->DetailsLength, 12);
1299      -        ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->Flags, 0);
1300      -        ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageOffset, 0);
1301      -        ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageSize, size);
1302      -
1303      -        sge = (pMpi2SGESimple64_t)(tcsge + 1);
1304      -        flagslength = size;
1305      -        flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
1306      -            MPI2_SGE_FLAGS_END_OF_BUFFER |
1307      -            MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1308      -            MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
1309      -            MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
1310      -            MPI2_SGE_FLAGS_HOST_TO_IOC |
1311      -            MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
1312      -        ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength);
1313      -        ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low,
1314      -            flsh_cookie.dmac_address);
1315      -        ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High,
1316      -            (uint32_t)(flsh_cookie.dmac_laddress >> 32));
     1396 +        if (mpt->m_MPI25)
     1397 +                mptsas_uflash25((pMpi25FWDownloadRequest)memp,
     1398 +                    mpt->m_acc_req_frame_hdl, size, type, flsh_cookie);
     1399 +        else
     1400 +                mptsas_uflash2((pMpi2FWDownloadRequest)memp,
     1401 +                    mpt->m_acc_req_frame_hdl, size, type, flsh_cookie);
1317 1402  
1318 1403          /*
1319 1404           * Start command
1320 1405           */
1321 1406          (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
1322 1407              DDI_DMA_SYNC_FORDEV);
1323      -        request_desc_low = (cmd->cmd_slot << 16) +
     1408 +        request_desc = (cmd->cmd_slot << 16) +
1324 1409              MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1325 1410          cmd->cmd_rfm = NULL;
1326      -        MPTSAS_START_CMD(mpt, request_desc_low, 0);
     1411 +        MPTSAS_START_CMD(mpt, request_desc);
1327 1412  
1328 1413          rvalue = 0;
1329 1414          (void) cv_reltimedwait(&mpt->m_fw_cv, &mpt->m_mutex,
1330 1415              drv_usectohz(60 * MICROSEC), TR_CLOCK_TICK);
1331 1416          if (!(cmd->cmd_flags & CFLAG_FINISHED)) {
1332 1417                  mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
1333 1418                  if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
1334 1419                          mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
1335 1420                  }
1336 1421                  rvalue = -1;
↓ open down ↓ 13 lines elided ↑ open up ↑
1350 1435          _NOTE(ARGUNUSED(ap))
1351 1436  #endif
1352 1437          pMpi2SasDevicePage0_t   sasdevpage;
1353 1438          int                     rval = DDI_SUCCESS, i;
1354 1439          uint8_t                 *sas_addr = NULL;
1355 1440          uint8_t                 tmp_sas_wwn[SAS_WWN_BYTE_SIZE];
1356 1441          uint16_t                *devhdl, *bay_num, *enclosure;
1357 1442          uint64_t                *sas_wwn;
1358 1443          uint32_t                *dev_info;
1359 1444          uint8_t                 *physport, *phynum;
1360      -        uint16_t                *pdevhdl;
     1445 +        uint16_t                *pdevhdl, *io_flags;
1361 1446          uint32_t                page_address;
1362 1447  
1363 1448          if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) &&
1364 1449              (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) {
1365 1450                  mptsas_log(mpt, CE_WARN, "mptsas_get_sas_device_page0 "
1366 1451                      "header: IOCStatus=0x%x, IOCLogInfo=0x%x",
1367 1452                      iocstatus, iocloginfo);
1368 1453                  rval = DDI_FAILURE;
1369 1454                  return (rval);
1370 1455          }
↓ open down ↓ 13 lines elided ↑ open up ↑
1384 1469                  return (rval);
1385 1470          }
1386 1471          devhdl = va_arg(ap, uint16_t *);
1387 1472          sas_wwn = va_arg(ap, uint64_t *);
1388 1473          dev_info = va_arg(ap, uint32_t *);
1389 1474          physport = va_arg(ap, uint8_t *);
1390 1475          phynum = va_arg(ap, uint8_t *);
1391 1476          pdevhdl = va_arg(ap, uint16_t *);
1392 1477          bay_num = va_arg(ap, uint16_t *);
1393 1478          enclosure = va_arg(ap, uint16_t *);
1394      -
     1479 +        io_flags = va_arg(ap, uint16_t *);
1395 1480  
1396 1481          sasdevpage = (pMpi2SasDevicePage0_t)page_memp;
1397 1482  
1398 1483          *dev_info = ddi_get32(accessp, &sasdevpage->DeviceInfo);
1399 1484          *devhdl = ddi_get16(accessp, &sasdevpage->DevHandle);
1400 1485          sas_addr = (uint8_t *)(&sasdevpage->SASAddress);
1401 1486          for (i = 0; i < SAS_WWN_BYTE_SIZE; i++) {
1402 1487                  tmp_sas_wwn[i] = ddi_get8(accessp, sas_addr + i);
1403 1488          }
1404 1489          bcopy(tmp_sas_wwn, sas_wwn, SAS_WWN_BYTE_SIZE);
1405 1490          *sas_wwn = LE_64(*sas_wwn);
1406 1491          *physport = ddi_get8(accessp, &sasdevpage->PhysicalPort);
1407 1492          *phynum = ddi_get8(accessp, &sasdevpage->PhyNum);
1408 1493          *pdevhdl = ddi_get16(accessp, &sasdevpage->ParentDevHandle);
1409 1494          *bay_num = ddi_get16(accessp, &sasdevpage->Slot);
1410 1495          *enclosure = ddi_get16(accessp, &sasdevpage->EnclosureHandle);
     1496 +        *io_flags = ddi_get16(accessp, &sasdevpage->Flags);
     1497 +
     1498 +        if (*io_flags & MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) {
     1499 +                /*
     1500 +                 * Leave a messages about FP cabability in the log.
     1501 +                 */
     1502 +                mptsas_log(mpt, CE_CONT,
     1503 +                    "!w%016"PRIx64" FastPath Capable%s", *sas_wwn,
     1504 +                    (*io_flags &
     1505 +                    MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)?
     1506 +                    " and Enabled":" but Disabled");
     1507 +        }
     1508 +
1411 1509          return (rval);
1412 1510  }
1413 1511  
1414 1512  /*
1415 1513   * Request MPI configuration page SAS device page 0 to get DevHandle, device
1416 1514   * info and SAS address.
1417 1515   */
1418 1516  int
1419 1517  mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address,
1420 1518      uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info,
1421 1519      uint8_t *physport, uint8_t *phynum, uint16_t *pdev_handle,
1422      -    uint16_t *bay_num, uint16_t *enclosure)
     1520 +    uint16_t *bay_num, uint16_t *enclosure, uint16_t *io_flags)
1423 1521  {
1424 1522          int rval = DDI_SUCCESS;
1425 1523  
1426 1524          ASSERT(mutex_owned(&mpt->m_mutex));
1427 1525  
1428 1526          /*
1429 1527           * Get the header and config page.  reply contains the reply frame,
1430 1528           * which holds status info for the request.
1431 1529           */
1432 1530          rval = mptsas_access_config_page(mpt,
1433 1531              MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
1434 1532              MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address,
1435 1533              mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn,
1436 1534              dev_info, physport, phynum, pdev_handle,
1437      -            bay_num, enclosure);
     1535 +            bay_num, enclosure, io_flags);
1438 1536  
1439 1537          return (rval);
1440 1538  }
1441 1539  
1442 1540  static int
1443 1541  mptsas_sasexpdpage_0_cb(mptsas_t *mpt, caddr_t page_memp,
1444 1542      ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
1445 1543      va_list ap)
1446 1544  {
1447 1545  #ifndef __lock_lint
↓ open down ↓ 402 lines elided ↑ open up ↑
1850 1948              sizeof (MPI2_CONFIG_PAGE_SASIOUNIT_1) +
1851 1949              (sizeof (MPI2_SAS_IO_UNIT1_PHY_DATA) * (MPTSAS_MAX_PHYS - 1));
1852 1950          uint32_t                flags_length;
1853 1951          uint32_t                cpdi[MPTSAS_MAX_PHYS];
1854 1952          uint32_t                readpage1 = 0, retrypage0 = 0;
1855 1953          uint16_t                iocstatus;
1856 1954          uint8_t                 port_flags, page_number, action;
1857 1955          uint32_t                reply_size = 256; /* Big enough for any page */
1858 1956          uint_t                  state;
1859 1957          int                     rval = DDI_FAILURE;
     1958 +        boolean_t               free_recv = B_FALSE, free_page = B_FALSE;
1860 1959  
1861 1960          /*
1862 1961           * Initialize our "state machine".  This is a bit convoluted,
1863 1962           * but it keeps us from having to do the ddi allocations numerous
1864 1963           * times.
1865 1964           */
1866 1965  
1867 1966          NDBG20(("mptsas_get_sas_io_unit_page_hndshk enter"));
1868 1967          ASSERT(mutex_owned(&mpt->m_mutex));
1869 1968          state = IOUC_READ_PAGE0;
↓ open down ↓ 6 lines elided ↑ open up ↑
1876 1975          recv_dma_attrs.dma_attr_sgllen = 1;
1877 1976          recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
1878 1977  
1879 1978          if (mptsas_dma_addr_create(mpt, recv_dma_attrs,
1880 1979              &recv_dma_handle, &recv_accessp, &recv_memp,
1881 1980              (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) {
1882 1981                  mptsas_log(mpt, CE_WARN,
1883 1982                      "mptsas_get_sas_io_unit_page_hndshk: recv dma failed");
1884 1983                  goto cleanup;
1885 1984          }
     1985 +        /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */
     1986 +        free_recv = B_TRUE;
1886 1987  
1887 1988          page_dma_attrs = mpt->m_msg_dma_attr;
1888 1989          page_dma_attrs.dma_attr_sgllen = 1;
1889 1990          page_dma_attrs.dma_attr_granular = reply_size;
1890 1991  
1891 1992          if (mptsas_dma_addr_create(mpt, page_dma_attrs,
1892 1993              &page_dma_handle, &page_accessp, &page_memp,
1893 1994              reply_size, &page_cookie) == FALSE) {
1894 1995                  mptsas_log(mpt, CE_WARN,
1895 1996                      "mptsas_get_sas_io_unit_page_hndshk: page dma failed");
1896 1997                  goto cleanup;
1897 1998          }
     1999 +        /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */
     2000 +        free_page = B_TRUE;
1898 2001  
1899 2002          /*
1900 2003           * Now we cycle through the state machine.  Here's what happens:
1901 2004           * 1. Read IO unit page 0 and set phy information
1902 2005           * 2. See if Read IO unit page1 is needed because of port configuration
1903 2006           * 3. Read IO unit page 1 and update phy information.
1904 2007           */
1905 2008  
1906 2009          sasioupage0 = (pMpi2SasIOUnitPage0_t)page_memp;
1907 2010          sasioupage1 = (pMpi2SasIOUnitPage1_t)page_memp;
↓ open down ↓ 2 lines elided ↑ open up ↑
1910 2013                  switch (state) {
1911 2014                  case IOUC_READ_PAGE0:
1912 2015                          page_number = 0;
1913 2016                          action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1914 2017                          flags_length = (uint32_t)page0_size;
1915 2018                          flags_length |= ((uint32_t)(
1916 2019                              MPI2_SGE_FLAGS_LAST_ELEMENT |
1917 2020                              MPI2_SGE_FLAGS_END_OF_BUFFER |
1918 2021                              MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1919 2022                              MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
1920      -                            MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
     2023 +                            MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
1921 2024                              MPI2_SGE_FLAGS_IOC_TO_HOST |
1922 2025                              MPI2_SGE_FLAGS_END_OF_LIST) <<
1923 2026                              MPI2_SGE_FLAGS_SHIFT);
1924 2027  
1925 2028                          break;
1926 2029  
1927 2030                  case IOUC_READ_PAGE1:
1928 2031                          page_number = 1;
1929 2032                          action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1930 2033                          flags_length = (uint32_t)page1_size;
1931 2034                          flags_length |= ((uint32_t)(
1932 2035                              MPI2_SGE_FLAGS_LAST_ELEMENT |
1933 2036                              MPI2_SGE_FLAGS_END_OF_BUFFER |
1934 2037                              MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
1935 2038                              MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
1936      -                            MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
     2039 +                            MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
1937 2040                              MPI2_SGE_FLAGS_IOC_TO_HOST |
1938 2041                              MPI2_SGE_FLAGS_END_OF_LIST) <<
1939 2042                              MPI2_SGE_FLAGS_SHIFT);
1940 2043  
1941 2044                          break;
1942 2045                  default:
1943 2046                          break;
1944 2047                  }
1945 2048  
1946 2049                  bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
↓ open down ↓ 23 lines elided ↑ open up ↑
1970 2073                  }
1971 2074  
1972 2075                  if (action != MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) {
1973 2076                          bzero(page_memp, reply_size);
1974 2077                  }
1975 2078  
1976 2079                  if (mptsas_send_extended_config_request_msg(mpt, action,
1977 2080                      MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number,
1978 2081                      ddi_get8(recv_accessp, &configreply->Header.PageVersion),
1979 2082                      ddi_get16(recv_accessp, &configreply->ExtPageLength),
1980      -                    flags_length, page_cookie.dmac_address)) {
     2083 +                    flags_length, page_cookie.dmac_laddress)) {
1981 2084                          goto cleanup;
1982 2085                  }
1983 2086  
1984 2087                  if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
1985 2088                      recv_accessp)) {
1986 2089                          goto cleanup;
1987 2090                  }
1988 2091  
1989 2092                  iocstatus = ddi_get16(recv_accessp, &configreply->IOCStatus);
1990 2093                  iocstatus = MPTSAS_IOCSTATUS(iocstatus);
↓ open down ↓ 132 lines elided ↑ open up ↑
2123 2226                  goto cleanup;
2124 2227          }
2125 2228          if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
2126 2229              (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
2127 2230                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2128 2231                  rval = DDI_FAILURE;
2129 2232                  goto cleanup;
2130 2233          }
2131 2234  
2132 2235  cleanup:
2133      -        mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
2134      -        mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
     2236 +        if (free_recv)
     2237 +                mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
     2238 +        if (free_page)
     2239 +                mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
2135 2240          if (rval != DDI_SUCCESS) {
2136 2241                  mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
2137 2242                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
2138 2243          }
2139 2244          return (rval);
2140 2245  }
2141 2246  
2142 2247  /*
2143 2248   * mptsas_get_manufacture_page5
2144 2249   *
↓ open down ↓ 7 lines elided ↑ open up ↑
2152 2257          ddi_dma_cookie_t                page_cookie;
2153 2258          ddi_dma_handle_t                recv_dma_handle, page_dma_handle;
2154 2259          ddi_acc_handle_t                recv_accessp, page_accessp;
2155 2260          pMpi2ConfigReply_t              configreply;
2156 2261          caddr_t                         recv_memp, page_memp;
2157 2262          int                             recv_numbytes;
2158 2263          pMpi2ManufacturingPage5_t       m5;
2159 2264          uint32_t                        flagslength;
2160 2265          int                             rval = DDI_SUCCESS;
2161 2266          uint_t                          iocstatus;
     2267 +        boolean_t               free_recv = B_FALSE, free_page = B_FALSE;
2162 2268  
2163 2269          MPTSAS_DISABLE_INTR(mpt);
2164 2270  
2165 2271          if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER,
2166 2272              MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, 0, 0, 0, 0)) {
2167 2273                  rval = DDI_FAILURE;
2168 2274                  goto done;
2169 2275          }
2170 2276  
2171 2277          /*
2172 2278           * dynamically create a customized dma attribute structure
2173 2279           * that describes the MPT's config reply page request structure.
2174 2280           */
2175 2281          recv_dma_attrs = mpt->m_msg_dma_attr;
2176 2282          recv_dma_attrs.dma_attr_sgllen = 1;
2177 2283          recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
2178 2284  
2179 2285          if (mptsas_dma_addr_create(mpt, recv_dma_attrs,
2180 2286              &recv_dma_handle, &recv_accessp, &recv_memp,
2181 2287              (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) {
     2288 +                rval = DDI_FAILURE;
2182 2289                  goto done;
2183 2290          }
     2291 +        /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */
     2292 +        free_recv = B_TRUE;
2184 2293  
2185 2294          bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
2186 2295          configreply = (pMpi2ConfigReply_t)recv_memp;
2187 2296          recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
2188 2297  
2189 2298          /*
2190 2299           * get config reply message
2191 2300           */
2192 2301          if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2193 2302              recv_accessp)) {
↓ open down ↓ 12 lines elided ↑ open up ↑
2206 2315           * dynamically create a customized dma attribute structure
2207 2316           * that describes the MPT's config page structure.
2208 2317           */
2209 2318          page_dma_attrs = mpt->m_msg_dma_attr;
2210 2319          page_dma_attrs.dma_attr_sgllen = 1;
2211 2320          page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_5));
2212 2321  
2213 2322          if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle,
2214 2323              &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_5)),
2215 2324              &page_cookie) == FALSE) {
     2325 +                rval = DDI_FAILURE;
2216 2326                  goto done;
2217 2327          }
     2328 +        /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */
     2329 +        free_page = B_TRUE;
     2330 +
2218 2331          bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5));
2219 2332          m5 = (pMpi2ManufacturingPage5_t)page_memp;
     2333 +        NDBG20(("mptsas_get_manufacture_page5: paddr 0x%x%08x",
     2334 +            (uint32_t)(page_cookie.dmac_laddress>>32),
     2335 +            (uint32_t)(page_cookie.dmac_laddress&0xfffffffful)));
2220 2336  
2221 2337          /*
2222 2338           * Give reply address to IOC to store config page in and send
2223 2339           * config request out.
2224 2340           */
2225 2341  
2226 2342          flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5);
2227 2343          flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
2228 2344              MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2229      -            MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
     2345 +            MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
2230 2346              MPI2_SGE_FLAGS_IOC_TO_HOST |
2231 2347              MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
2232 2348  
2233 2349          if (mptsas_send_config_request_msg(mpt,
2234 2350              MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
2235 2351              MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5,
2236 2352              ddi_get8(recv_accessp, &configreply->Header.PageVersion),
2237 2353              ddi_get8(recv_accessp, &configreply->Header.PageLength),
2238      -            flagslength, page_cookie.dmac_address)) {
     2354 +            flagslength, page_cookie.dmac_laddress)) {
2239 2355                  rval = DDI_FAILURE;
2240 2356                  goto done;
2241 2357          }
2242 2358  
2243 2359          /*
2244 2360           * get reply view handshake
2245 2361           */
2246 2362          if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2247 2363              recv_accessp)) {
2248 2364                  rval = DDI_FAILURE;
↓ open down ↓ 47 lines elided ↑ open up ↑
2296 2412          }
2297 2413          if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
2298 2414              (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
2299 2415                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2300 2416                  rval = DDI_FAILURE;
2301 2417          }
2302 2418  done:
2303 2419          /*
2304 2420           * free up memory
2305 2421           */
2306      -        mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
2307      -        mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
     2422 +        if (free_recv)
     2423 +                mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
     2424 +        if (free_page)
     2425 +                mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
2308 2426          MPTSAS_ENABLE_INTR(mpt);
2309 2427  
2310 2428          return (rval);
2311 2429  }
2312 2430  
2313 2431  static int
2314 2432  mptsas_sasphypage_0_cb(mptsas_t *mpt, caddr_t page_memp,
2315 2433      ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo,
2316 2434      va_list ap)
2317 2435  {
↓ open down ↓ 200 lines elided ↑ open up ↑
2518 2636          ddi_dma_handle_t                recv_dma_handle, page_dma_handle;
2519 2637          ddi_acc_handle_t                recv_accessp, page_accessp;
2520 2638          pMpi2ConfigReply_t              configreply;
2521 2639          caddr_t                         recv_memp, page_memp;
2522 2640          int                             recv_numbytes;
2523 2641          pMpi2ManufacturingPage0_t       m0;
2524 2642          uint32_t                        flagslength;
2525 2643          int                             rval = DDI_SUCCESS;
2526 2644          uint_t                          iocstatus;
2527 2645          uint8_t                         i = 0;
     2646 +        boolean_t               free_recv = B_FALSE, free_page = B_FALSE;
2528 2647  
2529 2648          MPTSAS_DISABLE_INTR(mpt);
2530 2649  
2531 2650          if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER,
2532 2651              MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0, 0, 0, 0, 0)) {
2533 2652                  rval = DDI_FAILURE;
2534 2653                  goto done;
2535 2654          }
2536 2655  
2537 2656          /*
2538 2657           * dynamically create a customized dma attribute structure
2539 2658           * that describes the MPT's config reply page request structure.
2540 2659           */
2541 2660          recv_dma_attrs = mpt->m_msg_dma_attr;
2542 2661          recv_dma_attrs.dma_attr_sgllen = 1;
2543 2662          recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY));
2544 2663  
2545 2664          if (mptsas_dma_addr_create(mpt, recv_dma_attrs, &recv_dma_handle,
2546 2665              &recv_accessp, &recv_memp, (sizeof (MPI2_CONFIG_REPLY)),
2547 2666              NULL) == FALSE) {
     2667 +                rval = DDI_FAILURE;
2548 2668                  goto done;
2549 2669          }
     2670 +        /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */
     2671 +        free_recv = B_TRUE;
     2672 +
2550 2673          bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY));
2551 2674          configreply = (pMpi2ConfigReply_t)recv_memp;
2552 2675          recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
2553 2676  
2554 2677          /*
2555 2678           * get config reply message
2556 2679           */
2557 2680          if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2558 2681              recv_accessp)) {
2559 2682                  rval = DDI_FAILURE;
↓ open down ↓ 11 lines elided ↑ open up ↑
2571 2694           * dynamically create a customized dma attribute structure
2572 2695           * that describes the MPT's config page structure.
2573 2696           */
2574 2697          page_dma_attrs = mpt->m_msg_dma_attr;
2575 2698          page_dma_attrs.dma_attr_sgllen = 1;
2576 2699          page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_0));
2577 2700  
2578 2701          if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle,
2579 2702              &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_0)),
2580 2703              &page_cookie) == FALSE) {
     2704 +                rval = DDI_FAILURE;
2581 2705                  goto done;
2582 2706          }
     2707 +        /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */
     2708 +        free_page = B_TRUE;
     2709 +
2583 2710          bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_0));
2584 2711          m0 = (pMpi2ManufacturingPage0_t)page_memp;
2585 2712  
2586 2713          /*
2587 2714           * Give reply address to IOC to store config page in and send
2588 2715           * config request out.
2589 2716           */
2590 2717  
2591 2718          flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_0);
2592 2719          flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT |
2593 2720              MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
2594      -            MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING |
     2721 +            MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING |
2595 2722              MPI2_SGE_FLAGS_IOC_TO_HOST |
2596 2723              MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
2597 2724  
2598 2725          if (mptsas_send_config_request_msg(mpt,
2599 2726              MPI2_CONFIG_ACTION_PAGE_READ_CURRENT,
2600 2727              MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0,
2601 2728              ddi_get8(recv_accessp, &configreply->Header.PageVersion),
2602 2729              ddi_get8(recv_accessp, &configreply->Header.PageLength),
2603      -            flagslength, page_cookie.dmac_address)) {
     2730 +            flagslength, page_cookie.dmac_laddress)) {
2604 2731                  rval = DDI_FAILURE;
2605 2732                  goto done;
2606 2733          }
2607 2734  
2608 2735          /*
2609 2736           * get reply view handshake
2610 2737           */
2611 2738          if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes,
2612 2739              recv_accessp)) {
2613 2740                  rval = DDI_FAILURE;
↓ open down ↓ 52 lines elided ↑ open up ↑
2666 2793          }
2667 2794          if ((mptsas_check_acc_handle(recv_accessp) != DDI_SUCCESS) ||
2668 2795              (mptsas_check_acc_handle(page_accessp) != DDI_SUCCESS)) {
2669 2796                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2670 2797                  rval = DDI_FAILURE;
2671 2798          }
2672 2799  done:
2673 2800          /*
2674 2801           * free up memory
2675 2802           */
2676      -        mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
2677      -        mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
     2803 +        if (free_recv)
     2804 +                mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp);
     2805 +        if (free_page)
     2806 +                mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp);
2678 2807          MPTSAS_ENABLE_INTR(mpt);
2679 2808  
2680 2809          return (rval);
2681 2810  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX