7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  26  * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
  27  */
  28 
  29 /*
  30  * Copyright (c) 2000 to 2010, LSI Corporation.
  31  * All rights reserved.
  32  *
  33  * Redistribution and use in source and binary forms of all code within
  34  * this file that is exclusively owned by LSI, with or without
  35  * modification, is permitted provided that, in addition to the CDDL 1.0
  36  * License requirements, the following conditions are met:
  37  *
  38  *    Neither the name of the author nor the names of its contributors may be
  39  *    used to endorse or promote products derived from this software without
  40  *    specific prior written permission.
  41  *
  42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  45  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  46  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
 
 228     uchar_t reason, uint_t stat);
 229 
 230 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
 231 static void mptsas_process_intr(mptsas_t *mpt,
 232     pMpi2ReplyDescriptorsUnion_t reply_desc_union);
 233 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
 234     pMpi2ReplyDescriptorsUnion_t reply_desc);
 235 static void mptsas_handle_address_reply(mptsas_t *mpt,
 236     pMpi2ReplyDescriptorsUnion_t reply_desc);
 237 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
 238 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
 239     uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
 240 
 241 static void mptsas_watch(void *arg);
 242 static void mptsas_watchsubr(mptsas_t *mpt);
 243 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt);
 244 
 245 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
 246 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
 247     uint8_t *data, uint32_t request_size, uint32_t reply_size,
 248     uint32_t data_size, uint32_t direction, uint8_t *dataout,
 249     uint32_t dataout_size, short timeout, int mode);
 250 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
 251 
 252 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
 253     uint32_t unique_id);
 254 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
 255 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
 256     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
 257 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
 258     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
 259     uint32_t diag_type);
 260 static int mptsas_diag_register(mptsas_t *mpt,
 261     mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
 262 static int mptsas_diag_unregister(mptsas_t *mpt,
 263     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
 264 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
 265     uint32_t *return_code);
 266 static int mptsas_diag_read_buffer(mptsas_t *mpt,
 267     mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
 268     uint32_t *return_code, int ioctl_mode);
 
 
 474         512,            /* granularity - device transfer size   */
 475         0               /* flags, set to 0                      */
 476 };
 477 
 478 /*
 479  * This is used for data I/O DMA memory allocation. (full 64-bit DMA
 480  * physical addresses are supported.)
 481  */
 482 ddi_dma_attr_t mptsas_dma_attrs64 = {
 483         DMA_ATTR_V0,    /* attribute layout version             */
 484         0x0ull,         /* address low - should be 0 (longlong) */
 485         0xffffffffffffffffull,  /* address high - 64-bit max    */
 486         0x00ffffffull,  /* count max - max DMA object size      */
 487         4,              /* allocation alignment requirements    */
 488         0x78,           /* burstsizes - binary encoded values   */
 489         1,              /* minxfer - gran. of DMA engine        */
 490         0x00ffffffull,  /* maxxfer - gran. of DMA engine        */
 491         0xffffffffull,  /* max segment size (DMA boundary)      */
 492         MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length      */
 493         512,            /* granularity - device transfer size   */
 494         DDI_DMA_RELAXED_ORDERING        /* flags, enable relaxed ordering */
 495 };
 496 
 497 ddi_device_acc_attr_t mptsas_dev_attr = {
 498         DDI_DEVICE_ATTR_V1,
 499         DDI_STRUCTURE_LE_ACC,
 500         DDI_STRICTORDER_ACC,
 501         DDI_DEFAULT_ACC
 502 };
 503 
 504 static struct cb_ops mptsas_cb_ops = {
 505         scsi_hba_open,          /* open */
 506         scsi_hba_close,         /* close */
 507         nodev,                  /* strategy */
 508         nodev,                  /* print */
 509         nodev,                  /* dump */
 510         nodev,                  /* read */
 511         nodev,                  /* write */
 512         mptsas_ioctl,           /* ioctl */
 513         nodev,                  /* devmap */
 514         nodev,                  /* mmap */
 
 552         &mod_driverops,     /* Type of module. This one is a driver */
 553         MPTSAS_MOD_STRING, /* Name of the module. */
 554         &mptsas_ops,        /* driver ops */
 555 };
 556 
 557 static struct modlinkage modlinkage = {
 558         MODREV_1, &modldrv, NULL
 559 };
 560 #define TARGET_PROP     "target"
 561 #define LUN_PROP        "lun"
 562 #define LUN64_PROP      "lun64"
 563 #define SAS_PROP        "sas-mpt"
 564 #define MDI_GUID        "wwn"
 565 #define NDI_GUID        "guid"
 566 #define MPTSAS_DEV_GONE "mptsas_dev_gone"
 567 
 568 /*
 569  * Local static data
 570  */
 571 #if defined(MPTSAS_DEBUG)
 572 uint32_t mptsas_debug_flags = 0;
 573 #endif  /* defined(MPTSAS_DEBUG) */
 574 uint32_t mptsas_debug_resets = 0;
 575 
 576 static kmutex_t         mptsas_global_mutex;
 577 static void             *mptsas_state;          /* soft state ptr */
 578 static krwlock_t        mptsas_global_rwlock;
 579 
 580 static kmutex_t         mptsas_log_mutex;
 581 static char             mptsas_log_buf[256];
 582 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
 583 
 584 static mptsas_t *mptsas_head, *mptsas_tail;
 585 static clock_t mptsas_scsi_watchdog_tick;
 586 static clock_t mptsas_tick;
 587 static timeout_id_t mptsas_reset_watch;
 588 static timeout_id_t mptsas_timeout_id;
 589 static int mptsas_timeouts_enabled = 0;
 590 /*
 591  * warlock directives
 592  */
 593 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
 594         mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
 595 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
 596 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
 597 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
 598 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
 599 
 600 /*
 601  * SM - HBA statics
 602  */
 603 char    *mptsas_driver_rev = MPTSAS_MOD_STRING;
 604 
 605 #ifdef MPTSAS_DEBUG
 606 void debug_enter(char *);
 607 #endif
 608 
 609 /*
 610  * Notes:
 
1148                     "mptsas%d: cannot allocate soft state", instance);
1149                 goto fail;
1150         }
1151 
1152         mpt = ddi_get_soft_state(mptsas_state, instance);
1153 
1154         if (mpt == NULL) {
1155                 mptsas_log(NULL, CE_WARN,
1156                     "mptsas%d: cannot get soft state", instance);
1157                 goto fail;
1158         }
1159 
1160         /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
1161         scsi_size_clean(dip);
1162 
1163         mpt->m_dip = dip;
1164         mpt->m_instance = instance;
1165 
1166         /* Make a per-instance copy of the structures */
1167         mpt->m_io_dma_attr = mptsas_dma_attrs64;
1168         mpt->m_msg_dma_attr = mptsas_dma_attrs;
1169         mpt->m_reg_acc_attr = mptsas_dev_attr;
1170         mpt->m_dev_acc_attr = mptsas_dev_attr;
1171 
1172         /*
1173          * Initialize FMA
1174          */
1175         mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
1176             DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
1177             DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
1178             DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
1179 
1180         mptsas_fm_init(mpt);
1181 
1182         if (mptsas_alloc_handshake_msg(mpt,
1183             sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
1184                 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
1185                 goto fail;
1186         }
1187 
1188         /*
 
1244                             CV_DRIVER, NULL);
1245                         mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1246                             MUTEX_DRIVER, NULL);
1247                         mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1248                         mpt->m_doneq_thread_id[j].flag |=
1249                             MPTSAS_DONEQ_THREAD_ACTIVE;
1250                         mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1251                         mpt->m_doneq_thread_id[j].arg.t = j;
1252                         mpt->m_doneq_thread_id[j].threadp =
1253                             thread_create(NULL, 0, mptsas_doneq_thread,
1254                             &mpt->m_doneq_thread_id[j].arg,
1255                             0, &p0, TS_RUN, minclsyspri);
1256                         mpt->m_doneq_thread_id[j].donetail =
1257                             &mpt->m_doneq_thread_id[j].doneq;
1258                         mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1259                 }
1260                 mutex_exit(&mpt->m_doneq_mutex);
1261                 doneq_thread_create++;
1262         }
1263 
1264         /* Initialize mutex used in interrupt handler */
1265         mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1266             DDI_INTR_PRI(mpt->m_intr_pri));
1267         mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL);
1268         mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1269             DDI_INTR_PRI(mpt->m_intr_pri));
1270         for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1271                 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1272                     NULL, MUTEX_DRIVER,
1273                     DDI_INTR_PRI(mpt->m_intr_pri));
1274         }
1275 
1276         cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1277         cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1278         cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1279         cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1280         cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1281         mutex_init_done++;
1282 
1283         /*
1284          * Disable hardware interrupt since we're not ready to
1285          * handle it yet.
1286          */
1287         MPTSAS_DISABLE_INTR(mpt);
1288         if (mptsas_register_intrs(mpt) == FALSE)
1289                 goto fail;
1290         intr_added++;
1291 
1292         mutex_enter(&mpt->m_mutex);
1293         /*
1294          * Initialize power management component
1295          */
1296         if (mpt->m_options & MPTSAS_OPT_PM) {
1297                 if (mptsas_init_pm(mpt)) {
1298                         mutex_exit(&mpt->m_mutex);
1299                         mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1300                             "failed");
1301                         goto fail;
1302                 }
1303         }
1304 
1305         /*
1306          * Initialize chip using Message Unit Reset, if allowed
1307          */
1308         mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1309         if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1310                 mutex_exit(&mpt->m_mutex);
1311                 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
 
2205 {
2206         (void) smp_hba_detach(mpt->m_dip);
2207         if (mpt->m_smptran != NULL) {
2208                 smp_hba_tran_free(mpt->m_smptran);
2209                 mpt->m_smptran = NULL;
2210         }
2211         mpt->m_smp_devhdl = 0;
2212 }
2213 
2214 static int
2215 mptsas_cache_create(mptsas_t *mpt)
2216 {
2217         int instance = mpt->m_instance;
2218         char buf[64];
2219 
2220         /*
2221          * create kmem cache for packets
2222          */
2223         (void) sprintf(buf, "mptsas%d_cache", instance);
2224         mpt->m_kmem_cache = kmem_cache_create(buf,
2225             sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8,
2226             mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
2227             NULL, (void *)mpt, NULL, 0);
2228 
2229         if (mpt->m_kmem_cache == NULL) {
2230                 mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
2231                 return (FALSE);
2232         }
2233 
2234         /*
2235          * create kmem cache for extra SGL frames if SGL cannot
2236          * be accomodated into main request frame.
2237          */
2238         (void) sprintf(buf, "mptsas%d_cache_frames", instance);
2239         mpt->m_cache_frames = kmem_cache_create(buf,
2240             sizeof (mptsas_cache_frames_t), 8,
2241             mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
2242             NULL, (void *)mpt, NULL, 0);
2243 
2244         if (mpt->m_cache_frames == NULL) {
2245                 mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
2246                 return (FALSE);
2247         }
2248 
2249         return (TRUE);
2250 }
2251 
2252 static void
2253 mptsas_cache_destroy(mptsas_t *mpt)
2254 {
2255         /* deallocate in reverse order */
2256         if (mpt->m_cache_frames) {
2257                 kmem_cache_destroy(mpt->m_cache_frames);
2258                 mpt->m_cache_frames = NULL;
2259         }
2260         if (mpt->m_kmem_cache) {
 
3954                     " extra SGL.");
3955                 return (DDI_FAILURE);
3956         }
3957 
3958         if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
3959             alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
3960             &cookie, &ncookie) != DDI_DMA_MAPPED) {
3961                 (void) ddi_dma_mem_free(&p->m_acc_hdl);
3962                 ddi_dma_free_handle(&p->m_dma_hdl);
3963                 p->m_dma_hdl = NULL;
3964                 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
3965                     " extra SGL");
3966                 return (DDI_FAILURE);
3967         }
3968 
3969         /*
3970          * Store the SGL memory address.  This chip uses this
3971          * address to dma to and from the driver.  The second
3972          * address is the address mpt uses to fill in the SGL.
3973          */
3974         p->m_phys_addr = cookie.dmac_address;
3975 
3976         return (DDI_SUCCESS);
3977 }
3978 
3979 static void
3980 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
3981 {
3982 #ifndef __lock_lint
3983         _NOTE(ARGUNUSED(cdrarg))
3984 #endif
3985         mptsas_cache_frames_t   *p = buf;
3986         if (p->m_dma_hdl != NULL) {
3987                 (void) ddi_dma_unbind_handle(p->m_dma_hdl);
3988                 (void) ddi_dma_mem_free(&p->m_acc_hdl);
3989                 ddi_dma_free_handle(&p->m_dma_hdl);
3990                 p->m_phys_addr = NULL;
3991                 p->m_frames_addr = NULL;
3992                 p->m_dma_hdl = NULL;
3993                 p->m_acc_hdl = NULL;
3994         }
 
4161         if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4162                 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4163                 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID;
4164         }
4165 
4166         mptsas_free_extra_sgl_frame(mpt, cmd);
4167 }
4168 
4169 static void
4170 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4171 {
4172         if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4173             (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4174                 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4175                     DDI_DMA_SYNC_FORCPU);
4176         }
4177         (*pkt->pkt_comp)(pkt);
4178 }
4179 
4180 static void
4181 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
4182         pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4183 {
4184         uint_t                  cookiec;
4185         mptti_t                 *dmap;
4186         uint32_t                flags;
4187         pMpi2SGESimple64_t      sge;
4188         pMpi2SGEChain64_t       sgechain;
4189         ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
4190 
4191         /*
4192          * Save the number of entries in the DMA
4193          * Scatter/Gather list
4194          */
4195         cookiec = cmd->cmd_cookiec;
4196 
4197         NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec));
4198 
4199         /*
4200          * Set read/write bit in control.
4201          */
4202         if (cmd->cmd_flags & CFLAG_DMASEND) {
4203                 *control |= MPI2_SCSIIO_CONTROL_WRITE;
4204         } else {
4205                 *control |= MPI2_SCSIIO_CONTROL_READ;
4206         }
4207 
4208         ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
4209 
4210         /*
4211          * We have 2 cases here.  First where we can fit all the
4212          * SG elements into the main frame, and the case
4213          * where we can't.
4214          * If we have more cookies than we can attach to a frame
4215          * we will need to use a chain element to point
4216          * a location of memory where the rest of the S/G
4217          * elements reside.
4218          */
4219         if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
4220                 dmap = cmd->cmd_sg;
4221                 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4222                 while (cookiec--) {
4223                         ddi_put32(acc_hdl,
4224                             &sge->Address.Low, dmap->addr.address64.Low);
4225                         ddi_put32(acc_hdl,
4226                             &sge->Address.High, dmap->addr.address64.High);
4227                         ddi_put32(acc_hdl, &sge->FlagsLength,
4228                             dmap->count);
4229                         flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4230                         flags |= ((uint32_t)
4231                             (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4232                             MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4233                             MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4234                             MPI2_SGE_FLAGS_SHIFT);
4235 
4236                         /*
4237                          * If this is the last cookie, we set the flags
4238                          * to indicate so
4239                          */
4240                         if (cookiec == 0) {
4241                                 flags |=
4242                                     ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
4243                                     | MPI2_SGE_FLAGS_END_OF_BUFFER
4244                                     | MPI2_SGE_FLAGS_END_OF_LIST) <<
4245                                     MPI2_SGE_FLAGS_SHIFT);
4246                         }
4247                         if (cmd->cmd_flags & CFLAG_DMASEND) {
4248                                 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4249                                     MPI2_SGE_FLAGS_SHIFT);
4250                         } else {
4251                                 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4252                                     MPI2_SGE_FLAGS_SHIFT);
4253                         }
4254                         ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4255                         dmap++;
4256                         sge++;
4257                 }
4258         } else {
4259                 /*
4260                  * Hereby we start to deal with multiple frames.
4261                  * The process is as follows:
4262                  * 1. Determine how many frames are needed for SGL element
4263                  *    storage; Note that all frames are stored in contiguous
4264                  *    memory space and in 64-bit DMA mode each element is
4265                  *    3 double-words (12 bytes) long.
4266                  * 2. Fill up the main frame. We need to do this separately
4267                  *    since it contains the SCSI IO request header and needs
4268                  *    dedicated processing. Note that the last 4 double-words
4269                  *    of the SCSI IO header is for SGL element storage
4270                  *    (MPI2_SGE_IO_UNION).
4271                  * 3. Fill the chain element in the main frame, so the DMA
4272                  *    engine can use the following frames.
4273                  * 4. Enter a loop to fill the remaining frames. Note that the
4274                  *    last frame contains no chain element.  The remaining
4275                  *    frames go into the mpt SGL buffer allocated on the fly,
4276                  *    not immediately following the main message frame, as in
4277                  *    Gen1.
4278                  * Some restrictions:
4279                  * 1. For 64-bit DMA, the simple element and chain element
4280                  *    are both of 3 double-words (12 bytes) in size, even
4281                  *    though all frames are stored in the first 4G of mem
4282                  *    range and the higher 32-bits of the address are always 0.
4283                  * 2. On some controllers (like the 1064/1068), a frame can
4284                  *    hold SGL elements with the last 1 or 2 double-words
4285                  *    (4 or 8 bytes) un-used. On these controllers, we should
4286                  *    recognize that there's not enough room for another SGL
4287                  *    element and move the sge pointer to the next frame.
4288                  */
4289                 int             i, j, k, l, frames, sgemax;
4290                 int             temp;
4291                 uint8_t         chainflags;
4292                 uint16_t        chainlength;
4293                 mptsas_cache_frames_t *p;
4294 
4295                 /*
4296                  * Sgemax is the number of SGE's that will fit
4297                  * each extra frame and frames is total
4298                  * number of frames we'll need.  1 sge entry per
4299                  * frame is reseverd for the chain element thus the -1 below.
4300                  */
4301                 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4302                     - 1);
4303                 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4304 
4305                 /*
4306                  * A little check to see if we need to round up the number
4307                  * of frames we need
4308                  */
4309                 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4310                     sgemax) > 1) {
4311                         frames = (temp + 1);
4312                 } else {
4313                         frames = temp;
4314                 }
4315                 dmap = cmd->cmd_sg;
4316                 sge = (pMpi2SGESimple64_t)(&frame->SGL);
4317 
4318                 /*
4319                  * First fill in the main frame
4320                  */
4321                 for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) {
4322                         ddi_put32(acc_hdl, &sge->Address.Low,
4323                             dmap->addr.address64.Low);
4324                         ddi_put32(acc_hdl, &sge->Address.High,
4325                             dmap->addr.address64.High);
4326                         ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count);
4327                         flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4328                         flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4329                             MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4330                             MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4331                             MPI2_SGE_FLAGS_SHIFT);
4332 
4333                         /*
4334                          * If this is the last SGE of this frame
4335                          * we set the end of list flag
4336                          */
4337                         if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) {
4338                                 flags |= ((uint32_t)
4339                                     (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4340                                     MPI2_SGE_FLAGS_SHIFT);
4341                         }
4342                         if (cmd->cmd_flags & CFLAG_DMASEND) {
4343                                 flags |=
4344                                     (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4345                                     MPI2_SGE_FLAGS_SHIFT);
4346                         } else {
4347                                 flags |=
4348                                     (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4349                                     MPI2_SGE_FLAGS_SHIFT);
4350                         }
4351                         ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4352                         dmap++;
4353                         sge++;
4354                 }
4355 
4356                 /*
4357                  * Fill in the chain element in the main frame.
4358                  * About calculation on ChainOffset:
4359                  * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4360                  *    in the end reserved for SGL element storage
4361                  *    (MPI2_SGE_IO_UNION); we should count it in our
4362                  *    calculation.  See its definition in the header file.
4363                  * 2. Constant j is the counter of the current SGL element
4364                  *    that will be processed, and (j - 1) is the number of
4365                  *    SGL elements that have been processed (stored in the
4366                  *    main frame).
4367                  * 3. ChainOffset value should be in units of double-words (4
4368                  *    bytes) so the last value should be divided by 4.
4369                  */
4370                 ddi_put8(acc_hdl, &frame->ChainOffset,
4371                     (sizeof (MPI2_SCSI_IO_REQUEST) -
4372                     sizeof (MPI2_SGE_IO_UNION) +
4373                     (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4374                 sgechain = (pMpi2SGEChain64_t)sge;
4375                 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4376                     MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
 
4379 
4380                 /*
4381                  * The size of the next frame is the accurate size of space
4382                  * (in bytes) used to store the SGL elements. j is the counter
4383                  * of SGL elements. (j - 1) is the number of SGL elements that
4384                  * have been processed (stored in frames).
4385                  */
4386                 if (frames >= 2) {
4387                         chainlength = mpt->m_req_frame_size /
4388                             sizeof (MPI2_SGE_SIMPLE64) *
4389                             sizeof (MPI2_SGE_SIMPLE64);
4390                 } else {
4391                         chainlength = ((cookiec - (j - 1)) *
4392                             sizeof (MPI2_SGE_SIMPLE64));
4393                 }
4394 
4395                 p = cmd->cmd_extra_frames;
4396 
4397                 ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4398                 ddi_put32(acc_hdl, &sgechain->Address.Low,
4399                     p->m_phys_addr);
4400                 /* SGL is allocated in the first 4G mem range */
4401                 ddi_put32(acc_hdl, &sgechain->Address.High, 0);
4402 
4403                 /*
4404                  * If there are more than 2 frames left we have to
4405                  * fill in the next chain offset to the location of
4406                  * the chain element in the next frame.
4407                  * sgemax is the number of simple elements in an extra
4408                  * frame. Note that the value NextChainOffset should be
4409                  * in double-words (4 bytes).
4410                  */
4411                 if (frames >= 2) {
4412                         ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4413                             (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4414                 } else {
4415                         ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4416                 }
4417 
4418                 /*
4419                  * Jump to next frame;
4420                  * Starting here, chain buffers go into the per command SGL.
4421                  * This buffer is allocated when chain buffers are needed.
 
4439                                  * and we have more SGE's to fill in
4440                                  * we have to fill the final entry
4441                                  * with a chain element and then
4442                                  * continue to the next frame
4443                                  */
4444                                 if ((l == (sgemax + 1)) && (k != frames)) {
4445                                         sgechain = (pMpi2SGEChain64_t)sge;
4446                                         j--;
4447                                         chainflags = (
4448                                             MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4449                                             MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4450                                             MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4451                                         ddi_put8(p->m_acc_hdl,
4452                                             &sgechain->Flags, chainflags);
4453                                         /*
4454                                          * k is the frame counter and (k + 1)
4455                                          * is the number of the next frame.
4456                                          * Note that frames are in contiguous
4457                                          * memory space.
4458                                          */
4459                                         ddi_put32(p->m_acc_hdl,
4460                                             &sgechain->Address.Low,
4461                                             (p->m_phys_addr +
4462                                             (mpt->m_req_frame_size * k)));
4463                                         ddi_put32(p->m_acc_hdl,
4464                                             &sgechain->Address.High, 0);
4465 
4466                                         /*
4467                                          * If there are more than 2 frames left
4468                                          * we have to next chain offset to
4469                                          * the location of the chain element
4470                                          * in the next frame and fill in the
4471                                          * length of the next chain
4472                                          */
4473                                         if ((frames - k) >= 2) {
4474                                                 ddi_put8(p->m_acc_hdl,
4475                                                     &sgechain->NextChainOffset,
4476                                                     (sgemax *
4477                                                     sizeof (MPI2_SGE_SIMPLE64))
4478                                                     >> 2);
4479                                                 ddi_put16(p->m_acc_hdl,
4480                                                     &sgechain->Length,
4481                                                     mpt->m_req_frame_size /
4482                                                     sizeof (MPI2_SGE_SIMPLE64) *
4483                                                     sizeof (MPI2_SGE_SIMPLE64));
4484                                         } else {
 
4547                                 if (cmd->cmd_flags & CFLAG_DMASEND) {
4548                                         flags |=
4549                                             (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4550                                             MPI2_SGE_FLAGS_SHIFT);
4551                                 } else {
4552                                         flags |=
4553                                             (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4554                                             MPI2_SGE_FLAGS_SHIFT);
4555                                 }
4556                                 ddi_put32(p->m_acc_hdl,
4557                                     &sge->FlagsLength, flags);
4558                                 dmap++;
4559                                 sge++;
4560                         }
4561                 }
4562 
4563                 /*
4564                  * Sync DMA with the chain buffers that were just created
4565                  */
4566                 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4567         }
4568 }
4569 
4570 /*
4571  * Interrupt handling
4572  * Utility routine.  Poll for status of a command sent to HBA
4573  * without interrupts (a FLAG_NOINTR command).
4574  */
4575 int
4576 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4577 {
4578         int     rval = TRUE;
4579 
4580         NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4581 
4582         if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4583                 mptsas_restart_hba(mpt);
4584         }
4585 
4586         /*
4587          * Wait, using drv_usecwait(), long enough for the command to
4588          * reasonably return from the target if the target isn't
4589          * "dead".  A polled command may well be sent from scsi_poll, and
 
5474         mutex_exit(&mpt->m_mutex);
5475         return (DDI_INTR_CLAIMED);
5476 }
5477 
5478 static void
5479 mptsas_process_intr(mptsas_t *mpt,
5480     pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5481 {
5482         uint8_t reply_type;
5483 
5484         ASSERT(mutex_owned(&mpt->m_mutex));
5485 
5486         /*
5487          * The reply is valid, process it according to its
5488          * type.  Also, set a flag for updated the reply index
5489          * after they've all been processed.
5490          */
5491         reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5492             &reply_desc_union->Default.ReplyFlags);
5493         reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5494         if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
5495                 mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5496         } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5497                 mptsas_handle_address_reply(mpt, reply_desc_union);
5498         } else {
5499                 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5500                 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5501         }
5502 
5503         /*
5504          * Clear the reply descriptor for re-use and increment
5505          * index.
5506          */
5507         ddi_put64(mpt->m_acc_post_queue_hdl,
5508             &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
5509             0xFFFFFFFFFFFFFFFF);
5510         (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5511             DDI_DMA_SYNC_FORDEV);
5512 }
5513 
5514 /*
 
9288         mutex_exit(&mptsas_log_mutex);
9289 }
9290 
9291 #ifdef MPTSAS_DEBUG
9292 /*PRINTFLIKE1*/
9293 void
9294 mptsas_printf(char *fmt, ...)
9295 {
9296         dev_info_t      *dev = 0;
9297         va_list         ap;
9298 
9299         mutex_enter(&mptsas_log_mutex);
9300 
9301         va_start(ap, fmt);
9302         (void) vsprintf(mptsas_log_buf, fmt, ap);
9303         va_end(ap);
9304 
9305 #ifdef PROM_PRINTF
9306         prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
9307 #else
9308         scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf);
9309 #endif
9310         mutex_exit(&mptsas_log_mutex);
9311 }
9312 #endif
9313 
9314 /*
9315  * timeout handling
9316  */
9317 static void
9318 mptsas_watch(void *arg)
9319 {
9320 #ifndef __lock_lint
9321         _NOTE(ARGUNUSED(arg))
9322 #endif
9323 
9324         mptsas_t        *mpt;
9325         uint32_t        doorbell;
9326 
9327         NDBG30(("mptsas_watch"));
9328 
 
9650         uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9651         char    buf[128];
9652 
9653         buf[0] = '\0';
9654         NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
9655             Tgt(cmd), Lun(cmd)));
9656         (void) sprintf(&buf[0], "\tcdb=[");
9657         for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
9658                 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
9659         }
9660         (void) sprintf(&buf[strlen(buf)], " ]");
9661         NDBG25(("?%s\n", buf));
9662         NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
9663             cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
9664             cmd->cmd_pkt->pkt_state));
9665         NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ?
9666             *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags));
9667 }
9668 
9669 static void
9670 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
9671 {
9672         caddr_t                 memp;
9673         pMPI2RequestHeader_t    request_hdrp;
9674         struct scsi_pkt         *pkt = cmd->cmd_pkt;
9675         mptsas_pt_request_t     *pt = pkt->pkt_ha_private;
9676         uint32_t                request_size, data_size, dataout_size;
9677         uint32_t                direction;
9678         ddi_dma_cookie_t        data_cookie;
9679         ddi_dma_cookie_t        dataout_cookie;
9680         uint32_t                request_desc_low, request_desc_high = 0;
9681         uint32_t                i, sense_bufp;
9682         uint8_t                 desc_type;
9683         uint8_t                 *request, function;
9684         ddi_dma_handle_t        dma_hdl = mpt->m_dma_req_frame_hdl;
9685         ddi_acc_handle_t        acc_hdl = mpt->m_acc_req_frame_hdl;
9686 
9687         desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
9688 
9689         request = pt->request;
9690         direction = pt->direction;
9691         request_size = pt->request_size;
9692         data_size = pt->data_size;
9693         dataout_size = pt->dataout_size;
9694         data_cookie = pt->data_cookie;
9695         dataout_cookie = pt->dataout_cookie;
9696 
9697         /*
9698          * Store the passthrough message in memory location
9699          * corresponding to our slot number
9700          */
9701         memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
9702         request_hdrp = (pMPI2RequestHeader_t)memp;
9703         bzero(memp, mpt->m_req_frame_size);
9704 
9705         for (i = 0; i < request_size; i++) {
9706                 bcopy(request + i, memp + i, 1);
9707         }
9708 
9709         if (data_size || dataout_size) {
9710                 pMpi2SGESimple64_t      sgep;
9711                 uint32_t                sge_flags;
9712 
9713                 sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp +
9714                     request_size);
9715                 if (dataout_size) {
9716 
9717                         sge_flags = dataout_size |
9718                             ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9719                             MPI2_SGE_FLAGS_END_OF_BUFFER |
9720                             MPI2_SGE_FLAGS_HOST_TO_IOC |
9721                             MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9722                             MPI2_SGE_FLAGS_SHIFT);
9723                         ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
9724                         ddi_put32(acc_hdl, &sgep->Address.Low,
9725                             (uint32_t)(dataout_cookie.dmac_laddress &
9726                             0xffffffffull));
9727                         ddi_put32(acc_hdl, &sgep->Address.High,
9728                             (uint32_t)(dataout_cookie.dmac_laddress
9729                             >> 32));
9730                         sgep++;
9731                 }
9732                 sge_flags = data_size;
9733                 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9734                     MPI2_SGE_FLAGS_LAST_ELEMENT |
9735                     MPI2_SGE_FLAGS_END_OF_BUFFER |
9736                     MPI2_SGE_FLAGS_END_OF_LIST |
9737                     MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9738                     MPI2_SGE_FLAGS_SHIFT);
9739                 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9740                         sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
9741                             MPI2_SGE_FLAGS_SHIFT);
9742                 } else {
9743                         sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
9744                             MPI2_SGE_FLAGS_SHIFT);
9745                 }
9746                 ddi_put32(acc_hdl, &sgep->FlagsLength,
9747                     sge_flags);
9748                 ddi_put32(acc_hdl, &sgep->Address.Low,
9749                     (uint32_t)(data_cookie.dmac_laddress &
9750                     0xffffffffull));
9751                 ddi_put32(acc_hdl, &sgep->Address.High,
9752                     (uint32_t)(data_cookie.dmac_laddress >> 32));
9753         }
9754 
9755         function = request_hdrp->Function;
9756         if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9757             (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9758                 pMpi2SCSIIORequest_t    scsi_io_req;
9759 
9760                 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
9761                 /*
9762                  * Put SGE for data and data_out buffer at the end of
9763                  * scsi_io_request message header.(64 bytes in total)
9764                  * Following above SGEs, the residual space will be
9765                  * used by sense data.
9766                  */
9767                 ddi_put8(acc_hdl,
9768                     &scsi_io_req->SenseBufferLength,
9769                     (uint8_t)(request_size - 64));
9770 
9771                 sense_bufp = mpt->m_req_frame_dma_addr +
9772                     (mpt->m_req_frame_size * cmd->cmd_slot);
9773                 sense_bufp += 64;
9774                 ddi_put32(acc_hdl,
9775                     &scsi_io_req->SenseBufferLowAddress, sense_bufp);
9776 
9777                 /*
9778                  * Set SGLOffset0 value
9779                  */
9780                 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
9781                     offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
9782 
9783                 /*
9784                  * Setup descriptor info.  RAID passthrough must use the
9785                  * default request descriptor which is already set, so if this
9786                  * is a SCSI IO request, change the descriptor to SCSI IO.
9787                  */
9788                 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
9789                         desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
9790                         request_desc_high = (ddi_get16(acc_hdl,
9791                             &scsi_io_req->DevHandle) << 16);
9792                 }
9793         }
9794 
9795         /*
9796          * We must wait till the message has been completed before
9797          * beginning the next message so we wait for this one to
9798          * finish.
9799          */
9800         (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
9801         request_desc_low = (cmd->cmd_slot << 16) + desc_type;
9802         cmd->cmd_rfm = NULL;
9803         MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
9804         if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
9805             (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
9806                 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9807         }
9808 }
9809 
9810 
9811 
9812 static int
9813 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
9814     uint8_t *data, uint32_t request_size, uint32_t reply_size,
9815     uint32_t data_size, uint32_t direction, uint8_t *dataout,
9816     uint32_t dataout_size, short timeout, int mode)
9817 {
9818         mptsas_pt_request_t             pt;
9819         mptsas_dma_alloc_state_t        data_dma_state;
9820         mptsas_dma_alloc_state_t        dataout_dma_state;
9821         caddr_t                         memp;
9822         mptsas_cmd_t                    *cmd = NULL;
9823         struct scsi_pkt                 *pkt;
9824         uint32_t                        reply_len = 0, sense_len = 0;
9825         pMPI2RequestHeader_t            request_hdrp;
9826         pMPI2RequestHeader_t            request_msg;
9827         pMPI2DefaultReply_t             reply_msg;
9828         Mpi2SCSIIOReply_t               rep_msg;
9829         int                             i, status = 0, pt_flags = 0, rv = 0;
9830         int                             rvalue;
9831         uint8_t                         function;
9832 
9833         ASSERT(mutex_owned(&mpt->m_mutex));
9834 
9835         reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
 
9872                         mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9873                             "resource");
9874                         goto out;
9875                 }
9876                 pt_flags |= MPTSAS_DATA_ALLOCATED;
9877                 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9878                         mutex_exit(&mpt->m_mutex);
9879                         for (i = 0; i < data_size; i++) {
9880                                 if (ddi_copyin(data + i, (uint8_t *)
9881                                     data_dma_state.memp + i, 1, mode)) {
9882                                         mutex_enter(&mpt->m_mutex);
9883                                         status = EFAULT;
9884                                         mptsas_log(mpt, CE_WARN, "failed to "
9885                                             "copy read data");
9886                                         goto out;
9887                                 }
9888                         }
9889                         mutex_enter(&mpt->m_mutex);
9890                 }
9891         }
9892 
9893         if (dataout_size != 0) {
9894                 dataout_dma_state.size = dataout_size;
9895                 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
9896                         status = ENOMEM;
9897                         mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9898                             "resource");
9899                         goto out;
9900                 }
9901                 pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
9902                 mutex_exit(&mpt->m_mutex);
9903                 for (i = 0; i < dataout_size; i++) {
9904                         if (ddi_copyin(dataout + i, (uint8_t *)
9905                             dataout_dma_state.memp + i, 1, mode)) {
9906                                 mutex_enter(&mpt->m_mutex);
9907                                 mptsas_log(mpt, CE_WARN, "failed to copy out"
9908                                     " data");
9909                                 status = EFAULT;
9910                                 goto out;
9911                         }
9912                 }
9913                 mutex_enter(&mpt->m_mutex);
9914         }
9915 
9916         if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
9917                 status = EAGAIN;
9918                 mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
9919                 goto out;
9920         }
9921         pt_flags |= MPTSAS_REQUEST_POOL_CMD;
9922 
9923         bzero((caddr_t)cmd, sizeof (*cmd));
9924         bzero((caddr_t)pkt, scsi_pkt_size());
9925         bzero((caddr_t)&pt, sizeof (pt));
9926 
9927         cmd->ioc_cmd_slot = (uint32_t)(rvalue);
9928 
9929         pt.request = (uint8_t *)request_msg;
9930         pt.direction = direction;
9931         pt.request_size = request_size;
9932         pt.data_size = data_size;
9933         pt.dataout_size = dataout_size;
9934         pt.data_cookie = data_dma_state.cookie;
9935         pt.dataout_cookie = dataout_dma_state.cookie;
9936 
9937         /*
9938          * Form a blank cmd/pkt to store the acknowledgement message
9939          */
9940         pkt->pkt_cdbp                = (opaque_t)&cmd->cmd_cdb[0];
9941         pkt->pkt_scbp                = (opaque_t)&cmd->cmd_scb;
9942         pkt->pkt_ha_private  = (opaque_t)&pt;
9943         pkt->pkt_flags               = FLAG_HEAD;
9944         pkt->pkt_time                = timeout;
9945         cmd->cmd_pkt         = pkt;
9946         cmd->cmd_flags               = CFLAG_CMDIOC | CFLAG_PASSTHRU;
9947 
9948         /*
9949          * Save the command in a slot
9950          */
9951         if (mptsas_save_cmd(mpt, cmd) == TRUE) {
9952                 /*
9953                  * Once passthru command get slot, set cmd_flags
9954                  * CFLAG_PREPARED.
9955                  */
 
10128         if (((data->DataSize == 0) &&
10129             (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
10130             ((data->DataSize != 0) &&
10131             ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
10132             (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
10133             ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
10134             (data->DataOutSize != 0))))) {
10135                 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
10136                         data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
10137                 } else {
10138                         data->DataOutSize = 0;
10139                 }
10140                 /*
10141                  * Send passthru request messages
10142                  */
10143                 return (mptsas_do_passthru(mpt,
10144                     (uint8_t *)((uintptr_t)data->PtrRequest),
10145                     (uint8_t *)((uintptr_t)data->PtrReply),
10146                     (uint8_t *)((uintptr_t)data->PtrData),
10147                     data->RequestSize, data->ReplySize,
10148                     data->DataSize, data->DataDirection,
10149                     (uint8_t *)((uintptr_t)data->PtrDataOut),
10150                     data->DataOutSize, data->Timeout, mode));
10151         } else {
10152                 return (EINVAL);
10153         }
10154 }
10155 
10156 static uint8_t
10157 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
10158 {
10159         uint8_t index;
10160 
10161         for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
10162                 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
10163                         return (index);
10164                 }
10165         }
10166 
10167         return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
10168 }
 
11213                  * If we can't determine the PCI data then we fill in FF's for
11214                  * the data to indicate this.
11215                  */
11216                 adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
11217                 adapter_data->MpiPortNumber = 0xFFFFFFFF;
11218                 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF;
11219         }
11220 
11221         /*
11222          * Saved in the mpt->m_fwversion
11223          */
11224         adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
11225 }
11226 
11227 static void
11228 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
11229 {
11230         char    *driver_verstr = MPTSAS_MOD_STRING;
11231 
11232         mptsas_lookup_pci_data(mpt, adapter_data);
11233         adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2;
11234         adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
11235         adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
11236         adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
11237         adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
11238         (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
11239         adapter_data->BiosVersion = 0;
11240         (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
11241 }
11242 
11243 static void
11244 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
11245 {
11246         int     *reg_data, i;
11247         uint_t  reglen;
11248 
11249         /*
11250          * Lookup the 'reg' property and extract the other data
11251          */
11252         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
11253             DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
 
14965                 /*
14966                  * If success set rtn flag, else unwire alloc'd lun
14967                  */
14968                 if (ndi_rtn != NDI_SUCCESS) {
14969                         NDBG12(("mptsas unable to online "
14970                             "SMP target %s", wwn_str));
14971                         ndi_prop_remove_all(*smp_dip);
14972                         (void) ndi_devi_free(*smp_dip);
14973                 }
14974         }
14975 
14976         return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
14977 }
14978 
14979 /* smp transport routine */
14980 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
14981 {
14982         uint64_t                        wwn;
14983         Mpi2SmpPassthroughRequest_t     req;
14984         Mpi2SmpPassthroughReply_t       rep;
14985         uint32_t                        direction = 0;
14986         mptsas_t                        *mpt;
14987         int                             ret;
14988         uint64_t                        tmp64;
14989 
14990         mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
14991             smp_a_hba_tran->smp_tran_hba_private;
14992 
14993         bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
14994         /*
14995          * Need to compose a SMP request message
14996          * and call mptsas_do_passthru() function
14997          */
14998         bzero(&req, sizeof (req));
14999         bzero(&rep, sizeof (rep));
15000         req.PassthroughFlags = 0;
15001         req.PhysicalPort = 0xff;
15002         req.ChainOffset = 0;
15003         req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
15004 
15005         if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
 
 | 
 
 
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  26  * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
  27  * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
  28  */
  29 
  30 /*
  31  * Copyright (c) 2000 to 2010, LSI Corporation.
  32  * All rights reserved.
  33  *
  34  * Redistribution and use in source and binary forms of all code within
  35  * this file that is exclusively owned by LSI, with or without
  36  * modification, is permitted provided that, in addition to the CDDL 1.0
  37  * License requirements, the following conditions are met:
  38  *
  39  *    Neither the name of the author nor the names of its contributors may be
  40  *    used to endorse or promote products derived from this software without
  41  *    specific prior written permission.
  42  *
  43  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  44  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  45  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  46  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  47  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
 
 229     uchar_t reason, uint_t stat);
 230 
 231 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
 232 static void mptsas_process_intr(mptsas_t *mpt,
 233     pMpi2ReplyDescriptorsUnion_t reply_desc_union);
 234 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
 235     pMpi2ReplyDescriptorsUnion_t reply_desc);
 236 static void mptsas_handle_address_reply(mptsas_t *mpt,
 237     pMpi2ReplyDescriptorsUnion_t reply_desc);
 238 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
 239 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
 240     uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
 241 
 242 static void mptsas_watch(void *arg);
 243 static void mptsas_watchsubr(mptsas_t *mpt);
 244 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt);
 245 
 246 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
 247 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
 248     uint8_t *data, uint32_t request_size, uint32_t reply_size,
 249     uint32_t data_size, uint8_t direction, uint8_t *dataout,
 250     uint32_t dataout_size, short timeout, int mode);
 251 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
 252 
 253 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
 254     uint32_t unique_id);
 255 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
 256 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
 257     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
 258 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
 259     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
 260     uint32_t diag_type);
 261 static int mptsas_diag_register(mptsas_t *mpt,
 262     mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
 263 static int mptsas_diag_unregister(mptsas_t *mpt,
 264     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
 265 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
 266     uint32_t *return_code);
 267 static int mptsas_diag_read_buffer(mptsas_t *mpt,
 268     mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
 269     uint32_t *return_code, int ioctl_mode);
 
 
 475         512,            /* granularity - device transfer size   */
 476         0               /* flags, set to 0                      */
 477 };
 478 
 479 /*
 480  * This is used for data I/O DMA memory allocation. (full 64-bit DMA
 481  * physical addresses are supported.)
 482  */
 483 ddi_dma_attr_t mptsas_dma_attrs64 = {
 484         DMA_ATTR_V0,    /* attribute layout version             */
 485         0x0ull,         /* address low - should be 0 (longlong) */
 486         0xffffffffffffffffull,  /* address high - 64-bit max    */
 487         0x00ffffffull,  /* count max - max DMA object size      */
 488         4,              /* allocation alignment requirements    */
 489         0x78,           /* burstsizes - binary encoded values   */
 490         1,              /* minxfer - gran. of DMA engine        */
 491         0x00ffffffull,  /* maxxfer - gran. of DMA engine        */
 492         0xffffffffull,  /* max segment size (DMA boundary)      */
 493         MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length      */
 494         512,            /* granularity - device transfer size   */
 495         0               /* flags, set to 0 */
 496 };
 497 
 498 ddi_device_acc_attr_t mptsas_dev_attr = {
 499         DDI_DEVICE_ATTR_V1,
 500         DDI_STRUCTURE_LE_ACC,
 501         DDI_STRICTORDER_ACC,
 502         DDI_DEFAULT_ACC
 503 };
 504 
 505 static struct cb_ops mptsas_cb_ops = {
 506         scsi_hba_open,          /* open */
 507         scsi_hba_close,         /* close */
 508         nodev,                  /* strategy */
 509         nodev,                  /* print */
 510         nodev,                  /* dump */
 511         nodev,                  /* read */
 512         nodev,                  /* write */
 513         mptsas_ioctl,           /* ioctl */
 514         nodev,                  /* devmap */
 515         nodev,                  /* mmap */
 
 553         &mod_driverops,     /* Type of module. This one is a driver */
 554         MPTSAS_MOD_STRING, /* Name of the module. */
 555         &mptsas_ops,        /* driver ops */
 556 };
 557 
 558 static struct modlinkage modlinkage = {
 559         MODREV_1, &modldrv, NULL
 560 };
 561 #define TARGET_PROP     "target"
 562 #define LUN_PROP        "lun"
 563 #define LUN64_PROP      "lun64"
 564 #define SAS_PROP        "sas-mpt"
 565 #define MDI_GUID        "wwn"
 566 #define NDI_GUID        "guid"
 567 #define MPTSAS_DEV_GONE "mptsas_dev_gone"
 568 
 569 /*
 570  * Local static data
 571  */
 572 #if defined(MPTSAS_DEBUG)
 573 uint32_t mptsas_debug_flags = 0x0;
 574 #endif  /* defined(MPTSAS_DEBUG) */
 575 uint32_t mptsas_debug_resets = 0;
 576 
 577 static kmutex_t         mptsas_global_mutex;
 578 static void             *mptsas_state;          /* soft state ptr */
 579 static krwlock_t        mptsas_global_rwlock;
 580 
 581 static kmutex_t         mptsas_log_mutex;
 582 static char             mptsas_log_buf[256];
 583 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
 584 
 585 static mptsas_t *mptsas_head, *mptsas_tail;
 586 static clock_t mptsas_scsi_watchdog_tick;
 587 static clock_t mptsas_tick;
 588 static timeout_id_t mptsas_reset_watch;
 589 static timeout_id_t mptsas_timeout_id;
 590 static int mptsas_timeouts_enabled = 0;
 591 
 592 /*
 593  * The only software retriction on switching msg buffers to 64 bit seems to
 594  * be the Auto Request Sense interface. The high 32 bits for all such
 595  * requests appear to be required to sit in the same 4G segment.
 596  * See initialization of SenseBufferAddressHigh in mptsas_init.c, and
 597  * the use of SenseBufferLowAddress in requests. Note that there is
 598  * currently a dependency on scsi_alloc_consistent_buf() adhering to
 599  * this requirement.
 600  * There is also a question about improved performance over PCI/PCIX
 601  * if transfers are within the first 4Gb.
 602  */
 603 static int mptsas_use_64bit_msgaddr = 0;
 604 
 605 /*
 606  * warlock directives
 607  */
 608 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
 609         mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
 610 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
 611 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
 612 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
 613 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
 614 
 615 /*
 616  * SM - HBA statics
 617  */
 618 char    *mptsas_driver_rev = MPTSAS_MOD_STRING;
 619 
 620 #ifdef MPTSAS_DEBUG
 621 void debug_enter(char *);
 622 #endif
 623 
 624 /*
 625  * Notes:
 
1163                     "mptsas%d: cannot allocate soft state", instance);
1164                 goto fail;
1165         }
1166 
1167         mpt = ddi_get_soft_state(mptsas_state, instance);
1168 
1169         if (mpt == NULL) {
1170                 mptsas_log(NULL, CE_WARN,
1171                     "mptsas%d: cannot get soft state", instance);
1172                 goto fail;
1173         }
1174 
1175         /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
1176         scsi_size_clean(dip);
1177 
1178         mpt->m_dip = dip;
1179         mpt->m_instance = instance;
1180 
1181         /* Make a per-instance copy of the structures */
1182         mpt->m_io_dma_attr = mptsas_dma_attrs64;
1183         if (mptsas_use_64bit_msgaddr) {
1184                 mpt->m_msg_dma_attr = mptsas_dma_attrs64;
1185         } else {
1186                 mpt->m_msg_dma_attr = mptsas_dma_attrs;
1187         }
1188         mpt->m_reg_acc_attr = mptsas_dev_attr;
1189         mpt->m_dev_acc_attr = mptsas_dev_attr;
1190 
1191         /*
1192          * Initialize FMA
1193          */
1194         mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
1195             DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
1196             DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
1197             DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
1198 
1199         mptsas_fm_init(mpt);
1200 
1201         if (mptsas_alloc_handshake_msg(mpt,
1202             sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
1203                 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
1204                 goto fail;
1205         }
1206 
1207         /*
 
1263                             CV_DRIVER, NULL);
1264                         mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1265                             MUTEX_DRIVER, NULL);
1266                         mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1267                         mpt->m_doneq_thread_id[j].flag |=
1268                             MPTSAS_DONEQ_THREAD_ACTIVE;
1269                         mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1270                         mpt->m_doneq_thread_id[j].arg.t = j;
1271                         mpt->m_doneq_thread_id[j].threadp =
1272                             thread_create(NULL, 0, mptsas_doneq_thread,
1273                             &mpt->m_doneq_thread_id[j].arg,
1274                             0, &p0, TS_RUN, minclsyspri);
1275                         mpt->m_doneq_thread_id[j].donetail =
1276                             &mpt->m_doneq_thread_id[j].doneq;
1277                         mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1278                 }
1279                 mutex_exit(&mpt->m_doneq_mutex);
1280                 doneq_thread_create++;
1281         }
1282 
1283         /*
1284          * Disable hardware interrupt since we're not ready to
1285          * handle it yet.
1286          */
1287         MPTSAS_DISABLE_INTR(mpt);
1288         if (mptsas_register_intrs(mpt) == FALSE)
1289                 goto fail;
1290         intr_added++;
1291 
1292         /* Initialize mutex used in interrupt handler */
1293         mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1294             DDI_INTR_PRI(mpt->m_intr_pri));
1295         mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL);
1296         mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1297             DDI_INTR_PRI(mpt->m_intr_pri));
1298         for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1299                 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1300                     NULL, MUTEX_DRIVER,
1301                     DDI_INTR_PRI(mpt->m_intr_pri));
1302         }
1303 
1304         cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1305         cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1306         cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1307         cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1308         cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1309         mutex_init_done++;
1310 
1311         mutex_enter(&mpt->m_mutex);
1312         /*
1313          * Initialize power management component
1314          */
1315         if (mpt->m_options & MPTSAS_OPT_PM) {
1316                 if (mptsas_init_pm(mpt)) {
1317                         mutex_exit(&mpt->m_mutex);
1318                         mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1319                             "failed");
1320                         goto fail;
1321                 }
1322         }
1323 
1324         /*
1325          * Initialize chip using Message Unit Reset, if allowed
1326          */
1327         mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET;
1328         if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1329                 mutex_exit(&mpt->m_mutex);
1330                 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
 
2224 {
2225         (void) smp_hba_detach(mpt->m_dip);
2226         if (mpt->m_smptran != NULL) {
2227                 smp_hba_tran_free(mpt->m_smptran);
2228                 mpt->m_smptran = NULL;
2229         }
2230         mpt->m_smp_devhdl = 0;
2231 }
2232 
2233 static int
2234 mptsas_cache_create(mptsas_t *mpt)
2235 {
2236         int instance = mpt->m_instance;
2237         char buf[64];
2238 
2239         /*
2240          * create kmem cache for packets
2241          */
2242         (void) sprintf(buf, "mptsas%d_cache", instance);
2243         mpt->m_kmem_cache = kmem_cache_create(buf,
2244             sizeof (struct mptsas_cmd) + scsi_pkt_size(), 16,
2245             mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
2246             NULL, (void *)mpt, NULL, 0);
2247 
2248         if (mpt->m_kmem_cache == NULL) {
2249                 mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
2250                 return (FALSE);
2251         }
2252 
2253         /*
2254          * create kmem cache for extra SGL frames if SGL cannot
2255          * be accomodated into main request frame.
2256          */
2257         (void) sprintf(buf, "mptsas%d_cache_frames", instance);
2258         mpt->m_cache_frames = kmem_cache_create(buf,
2259             sizeof (mptsas_cache_frames_t), 16,
2260             mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
2261             NULL, (void *)mpt, NULL, 0);
2262 
2263         if (mpt->m_cache_frames == NULL) {
2264                 mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
2265                 return (FALSE);
2266         }
2267 
2268         return (TRUE);
2269 }
2270 
2271 static void
2272 mptsas_cache_destroy(mptsas_t *mpt)
2273 {
2274         /* deallocate in reverse order */
2275         if (mpt->m_cache_frames) {
2276                 kmem_cache_destroy(mpt->m_cache_frames);
2277                 mpt->m_cache_frames = NULL;
2278         }
2279         if (mpt->m_kmem_cache) {
 
3973                     " extra SGL.");
3974                 return (DDI_FAILURE);
3975         }
3976 
3977         if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
3978             alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
3979             &cookie, &ncookie) != DDI_DMA_MAPPED) {
3980                 (void) ddi_dma_mem_free(&p->m_acc_hdl);
3981                 ddi_dma_free_handle(&p->m_dma_hdl);
3982                 p->m_dma_hdl = NULL;
3983                 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
3984                     " extra SGL");
3985                 return (DDI_FAILURE);
3986         }
3987 
3988         /*
3989          * Store the SGL memory address.  This chip uses this
3990          * address to dma to and from the driver.  The second
3991          * address is the address mpt uses to fill in the SGL.
3992          */
3993         p->m_phys_addr = cookie.dmac_laddress;
3994 
3995         return (DDI_SUCCESS);
3996 }
3997 
3998 static void
3999 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
4000 {
4001 #ifndef __lock_lint
4002         _NOTE(ARGUNUSED(cdrarg))
4003 #endif
4004         mptsas_cache_frames_t   *p = buf;
4005         if (p->m_dma_hdl != NULL) {
4006                 (void) ddi_dma_unbind_handle(p->m_dma_hdl);
4007                 (void) ddi_dma_mem_free(&p->m_acc_hdl);
4008                 ddi_dma_free_handle(&p->m_dma_hdl);
4009                 p->m_phys_addr = NULL;
4010                 p->m_frames_addr = NULL;
4011                 p->m_dma_hdl = NULL;
4012                 p->m_acc_hdl = NULL;
4013         }
 
4180         if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4181                 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4182                 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID;
4183         }
4184 
4185         mptsas_free_extra_sgl_frame(mpt, cmd);
4186 }
4187 
4188 static void
4189 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4190 {
4191         if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4192             (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4193                 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4194                     DDI_DMA_SYNC_FORCPU);
4195         }
4196         (*pkt->pkt_comp)(pkt);
4197 }
4198 
4199 static void
4200 mptsas_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4201                 ddi_acc_handle_t acc_hdl, uint_t cookiec,
4202                 uint32_t end_flags)
4203 {
4204         pMpi2SGESimple64_t      sge;
4205         mptti_t                 *dmap;
4206         uint32_t                flags;
4207 
4208         dmap = cmd->cmd_sg;
4209 
4210         sge = (pMpi2SGESimple64_t)(&frame->SGL);
4211         while (cookiec--) {
4212                 ddi_put32(acc_hdl, &sge->Address.Low,
4213                     dmap->addr.address64.Low);
4214                 ddi_put32(acc_hdl, &sge->Address.High,
4215                     dmap->addr.address64.High);
4216                 ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count);
4217                 flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4218                 flags |= ((uint32_t)
4219                     (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4220                     MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4221                     MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4222                     MPI2_SGE_FLAGS_SHIFT);
4223 
4224                 /*
4225                  * If this is the last cookie, we set the flags
4226                  * to indicate so
4227                  */
4228                 if (cookiec == 0) {
4229                         flags |= end_flags;
4230                 }
4231                 if (cmd->cmd_flags & CFLAG_DMASEND) {
4232                         flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4233                             MPI2_SGE_FLAGS_SHIFT);
4234                 } else {
4235                         flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4236                             MPI2_SGE_FLAGS_SHIFT);
4237                 }
4238                 ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4239                 dmap++;
4240                 sge++;
4241         }
4242 }
4243 
4244 static void
4245 mptsas_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4246     pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4247 {
4248         pMpi2SGESimple64_t      sge;
4249         pMpi2SGEChain64_t       sgechain;
4250         uint64_t                nframe_phys_addr;
4251         uint_t                  cookiec;
4252         mptti_t                 *dmap;
4253         uint32_t                flags;
4254         int                     i, j, k, l, frames, sgemax;
4255         int                     temp, maxframe_sges;
4256         uint8_t                 chainflags;
4257         uint16_t                chainlength;
4258         mptsas_cache_frames_t   *p;
4259 
4260         cookiec = cmd->cmd_cookiec;
4261 
4262         /*
4263          * Hereby we start to deal with multiple frames.
4264          * The process is as follows:
4265          * 1. Determine how many frames are needed for SGL element
4266          *    storage; Note that all frames are stored in contiguous
4267          *    memory space and in 64-bit DMA mode each element is
4268          *    3 double-words (12 bytes) long.
4269          * 2. Fill up the main frame. We need to do this separately
4270          *    since it contains the SCSI IO request header and needs
4271          *    dedicated processing. Note that the last 4 double-words
4272          *    of the SCSI IO header is for SGL element storage
4273          *    (MPI2_SGE_IO_UNION).
4274          * 3. Fill the chain element in the main frame, so the DMA
4275          *    engine can use the following frames.
4276          * 4. Enter a loop to fill the remaining frames. Note that the
4277          *    last frame contains no chain element.  The remaining
4278          *    frames go into the mpt SGL buffer allocated on the fly,
4279          *    not immediately following the main message frame, as in
4280          *    Gen1.
4281          * Some restrictions:
4282          * 1. For 64-bit DMA, the simple element and chain element
4283          *    are both of 3 double-words (12 bytes) in size, even
4284          *    though all frames are stored in the first 4G of mem
4285          *    range and the higher 32-bits of the address are always 0.
4286          * 2. On some controllers (like the 1064/1068), a frame can
4287          *    hold SGL elements with the last 1 or 2 double-words
4288          *    (4 or 8 bytes) un-used. On these controllers, we should
4289          *    recognize that there's not enough room for another SGL
4290          *    element and move the sge pointer to the next frame.
4291          */
4292 
4293         /*
4294          * Sgemax is the number of SGE's that will fit
4295          * each extra frame and frames is total
4296          * number of frames we'll need.  1 sge entry per
4297          * frame is reseverd for the chain element thus the -1 below.
4298          */
4299         sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) - 1);
4300         maxframe_sges = MPTSAS_MAX_FRAME_SGES64(mpt);
4301         temp = (cookiec - (maxframe_sges - 1)) / sgemax;
4302 
4303         /*
4304          * A little check to see if we need to round up the number
4305          * of frames we need
4306          */
4307         if ((cookiec - (maxframe_sges - 1)) - (temp * sgemax) > 1) {
4308                 frames = (temp + 1);
4309         } else {
4310                 frames = temp;
4311         }
4312         dmap = cmd->cmd_sg;
4313         sge = (pMpi2SGESimple64_t)(&frame->SGL);
4314 
4315         /*
4316          * First fill in the main frame
4317          */
4318         j = maxframe_sges - 1;
4319         mptsas_sge_mainframe(cmd, frame, acc_hdl, j,
4320             ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4321             MPI2_SGE_FLAGS_SHIFT));
4322         dmap += j;
4323         sge += j;
4324         j++;
4325 
4326         /*
4327          * Fill in the chain element in the main frame.
4328          * About calculation on ChainOffset:
4329          * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4330          *    in the end reserved for SGL element storage
4331          *    (MPI2_SGE_IO_UNION); we should count it in our
4332          *    calculation.  See its definition in the header file.
4333          * 2. Constant j is the counter of the current SGL element
4334          *    that will be processed, and (j - 1) is the number of
4335          *    SGL elements that have been processed (stored in the
4336          *    main frame).
4337          * 3. ChainOffset value should be in units of double-words (4
4338          *    bytes) so the last value should be divided by 4.
4339          */
4340         ddi_put8(acc_hdl, &frame->ChainOffset,
4341             (sizeof (MPI2_SCSI_IO_REQUEST) -
4342             sizeof (MPI2_SGE_IO_UNION) +
4343             (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4344         sgechain = (pMpi2SGEChain64_t)sge;
4345         chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4346             MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
 
4349 
4350         /*
4351          * The size of the next frame is the accurate size of space
4352          * (in bytes) used to store the SGL elements. j is the counter
4353          * of SGL elements. (j - 1) is the number of SGL elements that
4354          * have been processed (stored in frames).
4355          */
4356         if (frames >= 2) {
4357                 chainlength = mpt->m_req_frame_size /
4358                     sizeof (MPI2_SGE_SIMPLE64) *
4359                     sizeof (MPI2_SGE_SIMPLE64);
4360         } else {
4361                 chainlength = ((cookiec - (j - 1)) *
4362                     sizeof (MPI2_SGE_SIMPLE64));
4363         }
4364 
4365         p = cmd->cmd_extra_frames;
4366 
4367         ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4368         ddi_put32(acc_hdl, &sgechain->Address.Low,
4369             (p->m_phys_addr&0xffffffffull));
4370         ddi_put32(acc_hdl, &sgechain->Address.High, p->m_phys_addr>>32);
4371 
4372         /*
4373          * If there are more than 2 frames left we have to
4374          * fill in the next chain offset to the location of
4375          * the chain element in the next frame.
4376          * sgemax is the number of simple elements in an extra
4377          * frame. Note that the value NextChainOffset should be
4378          * in double-words (4 bytes).
4379          */
4380         if (frames >= 2) {
4381                 ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4382                     (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4383         } else {
4384                 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4385         }
4386 
4387         /*
4388          * Jump to next frame;
4389          * Starting here, chain buffers go into the per command SGL.
4390          * This buffer is allocated when chain buffers are needed.
 
4408                          * and we have more SGE's to fill in
4409                          * we have to fill the final entry
4410                          * with a chain element and then
4411                          * continue to the next frame
4412                          */
4413                         if ((l == (sgemax + 1)) && (k != frames)) {
4414                                 sgechain = (pMpi2SGEChain64_t)sge;
4415                                 j--;
4416                                 chainflags = (
4417                                     MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4418                                     MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4419                                     MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4420                                 ddi_put8(p->m_acc_hdl,
4421                                     &sgechain->Flags, chainflags);
4422                                 /*
4423                                  * k is the frame counter and (k + 1)
4424                                  * is the number of the next frame.
4425                                  * Note that frames are in contiguous
4426                                  * memory space.
4427                                  */
4428                                 nframe_phys_addr = p->m_phys_addr +
4429                                     (mpt->m_req_frame_size * k);
4430                                 ddi_put32(p->m_acc_hdl,
4431                                     &sgechain->Address.Low,
4432                                     nframe_phys_addr&0xffffffffull);
4433                                 ddi_put32(p->m_acc_hdl,
4434                                     &sgechain->Address.High,
4435                                     nframe_phys_addr>>32);
4436 
4437                                 /*
4438                                  * If there are more than 2 frames left
4439                                  * we have to next chain offset to
4440                                  * the location of the chain element
4441                                  * in the next frame and fill in the
4442                                  * length of the next chain
4443                                  */
4444                                 if ((frames - k) >= 2) {
4445                                         ddi_put8(p->m_acc_hdl,
4446                                             &sgechain->NextChainOffset,
4447                                             (sgemax *
4448                                             sizeof (MPI2_SGE_SIMPLE64))
4449                                             >> 2);
4450                                         ddi_put16(p->m_acc_hdl,
4451                                             &sgechain->Length,
4452                                             mpt->m_req_frame_size /
4453                                             sizeof (MPI2_SGE_SIMPLE64) *
4454                                             sizeof (MPI2_SGE_SIMPLE64));
4455                                 } else {
 
4518                         if (cmd->cmd_flags & CFLAG_DMASEND) {
4519                                 flags |=
4520                                     (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4521                                     MPI2_SGE_FLAGS_SHIFT);
4522                         } else {
4523                                 flags |=
4524                                     (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4525                                     MPI2_SGE_FLAGS_SHIFT);
4526                         }
4527                         ddi_put32(p->m_acc_hdl,
4528                             &sge->FlagsLength, flags);
4529                         dmap++;
4530                         sge++;
4531                 }
4532         }
4533 
4534         /*
4535          * Sync DMA with the chain buffers that were just created
4536          */
4537         (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4538 }
4539 
4540 static void
4541 mptsas_ieee_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame,
4542     ddi_acc_handle_t acc_hdl, uint_t cookiec,
4543     uint8_t end_flag)
4544 {
4545         pMpi2IeeeSgeSimple64_t  ieeesge;
4546         mptti_t                 *dmap;
4547         uint8_t                 flags;
4548 
4549         dmap = cmd->cmd_sg;
4550 
4551         NDBG1(("mptsas_ieee_sge_mainframe: cookiec=%d, %s", cookiec,
4552             cmd->cmd_flags & CFLAG_DMASEND?"Out":"In"));
4553 
4554         ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4555         while (cookiec--) {
4556                 ddi_put32(acc_hdl, &ieeesge->Address.Low,
4557                     dmap->addr.address64.Low);
4558                 ddi_put32(acc_hdl, &ieeesge->Address.High,
4559                     dmap->addr.address64.High);
4560                 ddi_put32(acc_hdl, &ieeesge->Length, dmap->count);
4561                 NDBG1(("mptsas_ieee_sge_mainframe: len=%d", dmap->count));
4562                 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
4563                     MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4564 
4565                 /*
4566                  * If this is the last cookie, we set the flags
4567                  * to indicate so
4568                  */
4569                 if (cookiec == 0) {
4570                         flags |= end_flag;
4571                 }
4572 
4573                 /*
4574                  * XXX: Hmmm, what about the direction based on
4575                  * cmd->cmd_flags & CFLAG_DMASEND?
4576                  */
4577                 ddi_put8(acc_hdl, &ieeesge->Flags, flags);
4578                 dmap++;
4579                 ieeesge++;
4580         }
4581 }
4582 
4583 static void
4584 mptsas_ieee_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd,
4585     pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4586 {
4587         pMpi2IeeeSgeSimple64_t  ieeesge;
4588         pMpi25IeeeSgeChain64_t  ieeesgechain;
4589         uint64_t                nframe_phys_addr;
4590         uint_t                  cookiec;
4591         mptti_t                 *dmap;
4592         uint8_t                 flags;
4593         int                     i, j, k, l, frames, sgemax;
4594         int                     temp, maxframe_sges;
4595         uint8_t                 chainflags;
4596         uint32_t                chainlength;
4597         mptsas_cache_frames_t   *p;
4598 
4599         cookiec = cmd->cmd_cookiec;
4600 
4601         NDBG1(("mptsas_ieee_sge_chain: cookiec=%d", cookiec));
4602 
4603         /*
4604          * Hereby we start to deal with multiple frames.
4605          * The process is as follows:
4606          * 1. Determine how many frames are needed for SGL element
4607          *    storage; Note that all frames are stored in contiguous
4608          *    memory space and in 64-bit DMA mode each element is
4609          *    4 double-words (16 bytes) long.
4610          * 2. Fill up the main frame. We need to do this separately
4611          *    since it contains the SCSI IO request header and needs
4612          *    dedicated processing. Note that the last 4 double-words
4613          *    of the SCSI IO header is for SGL element storage
4614          *    (MPI2_SGE_IO_UNION).
4615          * 3. Fill the chain element in the main frame, so the DMA
4616          *    engine can use the following frames.
4617          * 4. Enter a loop to fill the remaining frames. Note that the
4618          *    last frame contains no chain element.  The remaining
4619          *    frames go into the mpt SGL buffer allocated on the fly,
4620          *    not immediately following the main message frame, as in
4621          *    Gen1.
4622          * Some restrictions:
4623          * 1. For 64-bit DMA, the simple element and chain element
4624          *    are both of 4 double-words (16 bytes) in size, even
4625          *    though all frames are stored in the first 4G of mem
4626          *    range and the higher 32-bits of the address are always 0.
4627          * 2. On some controllers (like the 1064/1068), a frame can
4628          *    hold SGL elements with the last 1 or 2 double-words
4629          *    (4 or 8 bytes) un-used. On these controllers, we should
4630          *    recognize that there's not enough room for another SGL
4631          *    element and move the sge pointer to the next frame.
4632          */
4633 
4634         /*
4635          * Sgemax is the number of SGE's that will fit
4636          * each extra frame and frames is total
4637          * number of frames we'll need.  1 sge entry per
4638          * frame is reseverd for the chain element thus the -1 below.
4639          */
4640         sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_IEEE_SGE_SIMPLE64))
4641             - 1);
4642         maxframe_sges = MPTSAS_MAX_FRAME_SGES64(mpt);
4643         temp = (cookiec - (maxframe_sges - 1)) / sgemax;
4644 
4645         /*
4646          * A little check to see if we need to round up the number
4647          * of frames we need
4648          */
4649         if ((cookiec - (maxframe_sges - 1)) - (temp * sgemax) > 1) {
4650                 frames = (temp + 1);
4651         } else {
4652                 frames = temp;
4653         }
4654         NDBG1(("mptsas_ieee_sge_chain: temp=%d, frames=%d", temp, frames));
4655         dmap = cmd->cmd_sg;
4656         ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL);
4657 
4658         /*
4659          * First fill in the main frame
4660          */
4661         j = maxframe_sges - 1;
4662         mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, j, 0);
4663         dmap += j;
4664         ieeesge += j;
4665         j++;
4666 
4667         /*
4668          * Fill in the chain element in the main frame.
4669          * About calculation on ChainOffset:
4670          * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4671          *    in the end reserved for SGL element storage
4672          *    (MPI2_SGE_IO_UNION); we should count it in our
4673          *    calculation.  See its definition in the header file.
4674          * 2. Constant j is the counter of the current SGL element
4675          *    that will be processed, and (j - 1) is the number of
4676          *    SGL elements that have been processed (stored in the
4677          *    main frame).
4678          * 3. ChainOffset value should be in units of quad-words (16
4679          *    bytes) so the last value should be divided by 16.
4680          */
4681         ddi_put8(acc_hdl, &frame->ChainOffset,
4682             (sizeof (MPI2_SCSI_IO_REQUEST) -
4683             sizeof (MPI2_SGE_IO_UNION) +
4684             (j - 1) * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4685         ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4686         chainflags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4687             MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4688         ddi_put8(acc_hdl, &ieeesgechain->Flags, chainflags);
4689 
4690         /*
4691          * The size of the next frame is the accurate size of space
4692          * (in bytes) used to store the SGL elements. j is the counter
4693          * of SGL elements. (j - 1) is the number of SGL elements that
4694          * have been processed (stored in frames).
4695          */
4696         if (frames >= 2) {
4697                 chainlength = mpt->m_req_frame_size /
4698                     sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4699                     sizeof (MPI2_IEEE_SGE_SIMPLE64);
4700         } else {
4701                 chainlength = ((cookiec - (j - 1)) *
4702                     sizeof (MPI2_IEEE_SGE_SIMPLE64));
4703         }
4704 
4705         p = cmd->cmd_extra_frames;
4706 
4707         ddi_put32(acc_hdl, &ieeesgechain->Length, chainlength);
4708         ddi_put32(acc_hdl, &ieeesgechain->Address.Low,
4709             p->m_phys_addr&0xffffffffull);
4710         ddi_put32(acc_hdl, &ieeesgechain->Address.High, p->m_phys_addr>>32);
4711 
4712         /*
4713          * If there are more than 2 frames left we have to
4714          * fill in the next chain offset to the location of
4715          * the chain element in the next frame.
4716          * sgemax is the number of simple elements in an extra
4717          * frame. Note that the value NextChainOffset should be
4718          * in double-words (4 bytes).
4719          */
4720         if (frames >= 2) {
4721                 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset,
4722                     (sgemax * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4);
4723         } else {
4724                 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 0);
4725         }
4726 
4727         /*
4728          * Jump to next frame;
4729          * Starting here, chain buffers go into the per command SGL.
4730          * This buffer is allocated when chain buffers are needed.
4731          */
4732         ieeesge = (pMpi2IeeeSgeSimple64_t)p->m_frames_addr;
4733         i = cookiec;
4734 
4735         /*
4736          * Start filling in frames with SGE's.  If we
4737          * reach the end of frame and still have SGE's
4738          * to fill we need to add a chain element and
4739          * use another frame.  j will be our counter
4740          * for what cookie we are at and i will be
4741          * the total cookiec. k is the current frame
4742          */
4743         for (k = 1; k <= frames; k++) {
4744                 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4745 
4746                         /*
4747                          * If we have reached the end of frame
4748                          * and we have more SGE's to fill in
4749                          * we have to fill the final entry
4750                          * with a chain element and then
4751                          * continue to the next frame
4752                          */
4753                         if ((l == (sgemax + 1)) && (k != frames)) {
4754                                 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge;
4755                                 j--;
4756                                 chainflags =
4757                                     MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
4758                                     MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR;
4759                                 ddi_put8(p->m_acc_hdl,
4760                                     &ieeesgechain->Flags, chainflags);
4761                                 /*
4762                                  * k is the frame counter and (k + 1)
4763                                  * is the number of the next frame.
4764                                  * Note that frames are in contiguous
4765                                  * memory space.
4766                                  */
4767                                 nframe_phys_addr = p->m_phys_addr +
4768                                     (mpt->m_req_frame_size * k);
4769                                 ddi_put32(p->m_acc_hdl,
4770                                     &ieeesgechain->Address.Low,
4771                                     nframe_phys_addr&0xffffffffull);
4772                                 ddi_put32(p->m_acc_hdl,
4773                                     &ieeesgechain->Address.High,
4774                                     nframe_phys_addr>>32);
4775 
4776                                 /*
4777                                  * If there are more than 2 frames left
4778                                  * we have to next chain offset to
4779                                  * the location of the chain element
4780                                  * in the next frame and fill in the
4781                                  * length of the next chain
4782                                  */
4783                                 if ((frames - k) >= 2) {
4784                                         ddi_put8(p->m_acc_hdl,
4785                                             &ieeesgechain->NextChainOffset,
4786                                             (sgemax *
4787                                             sizeof (MPI2_IEEE_SGE_SIMPLE64))
4788                                             >> 4);
4789                                         ddi_put32(p->m_acc_hdl,
4790                                             &ieeesgechain->Length,
4791                                             mpt->m_req_frame_size /
4792                                             sizeof (MPI2_IEEE_SGE_SIMPLE64) *
4793                                             sizeof (MPI2_IEEE_SGE_SIMPLE64));
4794                                 } else {
4795                                         /*
4796                                          * This is the last frame. Set
4797                                          * the NextChainOffset to 0 and
4798                                          * Length is the total size of
4799                                          * all remaining simple elements
4800                                          */
4801                                         ddi_put8(p->m_acc_hdl,
4802                                             &ieeesgechain->NextChainOffset,
4803                                             0);
4804                                         ddi_put32(p->m_acc_hdl,
4805                                             &ieeesgechain->Length,
4806                                             (cookiec - j) *
4807                                             sizeof (MPI2_IEEE_SGE_SIMPLE64));
4808                                 }
4809 
4810                                 /* Jump to the next frame */
4811                                 ieeesge = (pMpi2IeeeSgeSimple64_t)
4812                                     ((char *)p->m_frames_addr +
4813                                     (int)mpt->m_req_frame_size * k);
4814 
4815                                 continue;
4816                         }
4817 
4818                         ddi_put32(p->m_acc_hdl,
4819                             &ieeesge->Address.Low,
4820                             dmap->addr.address64.Low);
4821                         ddi_put32(p->m_acc_hdl,
4822                             &ieeesge->Address.High,
4823                             dmap->addr.address64.High);
4824                         ddi_put32(p->m_acc_hdl,
4825                             &ieeesge->Length, dmap->count);
4826                         flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
4827                             MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
4828 
4829                         /*
4830                          * If we are at the end of the frame and
4831                          * there is another frame to fill in
4832                          * do we need to do anything?
4833                          * if ((l == sgemax) && (k != frames)) {
4834                          * }
4835                          */
4836 
4837                         /*
4838                          * If this is the final cookie set end of list.
4839                          */
4840                         if (j == i) {
4841                                 flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
4842                         }
4843 
4844                         ddi_put8(p->m_acc_hdl, &ieeesge->Flags, flags);
4845                         dmap++;
4846                         ieeesge++;
4847                 }
4848         }
4849 
4850         /*
4851          * Sync DMA with the chain buffers that were just created
4852          */
4853         (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4854 }
4855 
4856 static void
4857 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
4858     pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4859 {
4860         ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
4861 
4862         NDBG1(("mptsas_sge_setup: cookiec=%d", cmd->cmd_cookiec));
4863 
4864         /*
4865          * Set read/write bit in control.
4866          */
4867         if (cmd->cmd_flags & CFLAG_DMASEND) {
4868                 *control |= MPI2_SCSIIO_CONTROL_WRITE;
4869         } else {
4870                 *control |= MPI2_SCSIIO_CONTROL_READ;
4871         }
4872 
4873         ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
4874 
4875         /*
4876          * We have 4 cases here.  First where we can fit all the
4877          * SG elements into the main frame, and the case
4878          * where we can't. The SG element is also different when using
4879          * MPI2.5 interface.
4880          * If we have more cookies than we can attach to a frame
4881          * we will need to use a chain element to point
4882          * a location of memory where the rest of the S/G
4883          * elements reside.
4884          */
4885         if (cmd->cmd_cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
4886                 if (mpt->m_MPI25) {
4887                         mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl,
4888                             cmd->cmd_cookiec,
4889                             MPI25_IEEE_SGE_FLAGS_END_OF_LIST);
4890                 } else {
4891                         mptsas_sge_mainframe(cmd, frame, acc_hdl,
4892                             cmd->cmd_cookiec,
4893                             ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
4894                             | MPI2_SGE_FLAGS_END_OF_BUFFER
4895                             | MPI2_SGE_FLAGS_END_OF_LIST) <<
4896                             MPI2_SGE_FLAGS_SHIFT));
4897                 }
4898         } else {
4899                 if (mpt->m_MPI25) {
4900                         mptsas_ieee_sge_chain(mpt, cmd, frame, acc_hdl);
4901                 } else {
4902                         mptsas_sge_chain(mpt, cmd, frame, acc_hdl);
4903                 }
4904         }
4905 }
4906 
4907 /*
4908  * Interrupt handling
4909  * Utility routine.  Poll for status of a command sent to HBA
4910  * without interrupts (a FLAG_NOINTR command).
4911  */
4912 int
4913 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4914 {
4915         int     rval = TRUE;
4916 
4917         NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4918 
4919         if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4920                 mptsas_restart_hba(mpt);
4921         }
4922 
4923         /*
4924          * Wait, using drv_usecwait(), long enough for the command to
4925          * reasonably return from the target if the target isn't
4926          * "dead".  A polled command may well be sent from scsi_poll, and
 
5811         mutex_exit(&mpt->m_mutex);
5812         return (DDI_INTR_CLAIMED);
5813 }
5814 
5815 static void
5816 mptsas_process_intr(mptsas_t *mpt,
5817     pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5818 {
5819         uint8_t reply_type;
5820 
5821         ASSERT(mutex_owned(&mpt->m_mutex));
5822 
5823         /*
5824          * The reply is valid, process it according to its
5825          * type.  Also, set a flag for updated the reply index
5826          * after they've all been processed.
5827          */
5828         reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5829             &reply_desc_union->Default.ReplyFlags);
5830         reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5831         if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
5832             reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) {
5833                 mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5834         } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5835                 mptsas_handle_address_reply(mpt, reply_desc_union);
5836         } else {
5837                 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5838                 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5839         }
5840 
5841         /*
5842          * Clear the reply descriptor for re-use and increment
5843          * index.
5844          */
5845         ddi_put64(mpt->m_acc_post_queue_hdl,
5846             &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
5847             0xFFFFFFFFFFFFFFFF);
5848         (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5849             DDI_DMA_SYNC_FORDEV);
5850 }
5851 
5852 /*
 
9626         mutex_exit(&mptsas_log_mutex);
9627 }
9628 
9629 #ifdef MPTSAS_DEBUG
9630 /*PRINTFLIKE1*/
9631 void
9632 mptsas_printf(char *fmt, ...)
9633 {
9634         dev_info_t      *dev = 0;
9635         va_list         ap;
9636 
9637         mutex_enter(&mptsas_log_mutex);
9638 
9639         va_start(ap, fmt);
9640         (void) vsprintf(mptsas_log_buf, fmt, ap);
9641         va_end(ap);
9642 
9643 #ifdef PROM_PRINTF
9644         prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
9645 #else
9646         scsi_log(dev, mptsas_label, CE_CONT, "!%s\n", mptsas_log_buf);
9647 #endif
9648         mutex_exit(&mptsas_log_mutex);
9649 }
9650 #endif
9651 
9652 /*
9653  * timeout handling
9654  */
9655 static void
9656 mptsas_watch(void *arg)
9657 {
9658 #ifndef __lock_lint
9659         _NOTE(ARGUNUSED(arg))
9660 #endif
9661 
9662         mptsas_t        *mpt;
9663         uint32_t        doorbell;
9664 
9665         NDBG30(("mptsas_watch"));
9666 
 
9988         uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9989         char    buf[128];
9990 
9991         buf[0] = '\0';
9992         NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
9993             Tgt(cmd), Lun(cmd)));
9994         (void) sprintf(&buf[0], "\tcdb=[");
9995         for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
9996                 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
9997         }
9998         (void) sprintf(&buf[strlen(buf)], " ]");
9999         NDBG25(("?%s\n", buf));
10000         NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
10001             cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
10002             cmd->cmd_pkt->pkt_state));
10003         NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ?
10004             *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags));
10005 }
10006 
10007 static void
10008 mptsas_passthru_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10009     pMpi2SGESimple64_t sgep)
10010 {
10011         uint32_t                sge_flags;
10012         uint32_t                data_size, dataout_size;
10013         ddi_dma_cookie_t        data_cookie;
10014         ddi_dma_cookie_t        dataout_cookie;
10015 
10016         data_size = pt->data_size;
10017         dataout_size = pt->dataout_size;
10018         data_cookie = pt->data_cookie;
10019         dataout_cookie = pt->dataout_cookie;
10020 
10021         if (dataout_size) {
10022                 sge_flags = dataout_size |
10023                     ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10024                     MPI2_SGE_FLAGS_END_OF_BUFFER |
10025                     MPI2_SGE_FLAGS_HOST_TO_IOC |
10026                     MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10027                     MPI2_SGE_FLAGS_SHIFT);
10028                 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
10029                 ddi_put32(acc_hdl, &sgep->Address.Low,
10030                     (uint32_t)(dataout_cookie.dmac_laddress & 0xffffffffull));
10031                 ddi_put32(acc_hdl, &sgep->Address.High,
10032                     (uint32_t)(dataout_cookie.dmac_laddress >> 32));
10033                 sgep++;
10034         }
10035         sge_flags = data_size;
10036         sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
10037             MPI2_SGE_FLAGS_LAST_ELEMENT |
10038             MPI2_SGE_FLAGS_END_OF_BUFFER |
10039             MPI2_SGE_FLAGS_END_OF_LIST |
10040             MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
10041             MPI2_SGE_FLAGS_SHIFT);
10042         if (pt->direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10043                 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
10044                     MPI2_SGE_FLAGS_SHIFT);
10045         } else {
10046                 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
10047                     MPI2_SGE_FLAGS_SHIFT);
10048         }
10049         ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
10050         ddi_put32(acc_hdl, &sgep->Address.Low,
10051             (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull));
10052         ddi_put32(acc_hdl, &sgep->Address.High,
10053             (uint32_t)(data_cookie.dmac_laddress >> 32));
10054 }
10055 
10056 static void
10057 mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt,
10058     pMpi2IeeeSgeSimple64_t ieeesgep)
10059 {
10060         uint8_t                 sge_flags;
10061         uint32_t                data_size, dataout_size;
10062         ddi_dma_cookie_t        data_cookie;
10063         ddi_dma_cookie_t        dataout_cookie;
10064 
10065         data_size = pt->data_size;
10066         dataout_size = pt->dataout_size;
10067         data_cookie = pt->data_cookie;
10068         dataout_cookie = pt->dataout_cookie;
10069 
10070         sge_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT |
10071             MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR);
10072         if (dataout_size) {
10073                 ddi_put32(acc_hdl, &ieeesgep->Length, dataout_size);
10074                 ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10075                     (uint32_t)(dataout_cookie.dmac_laddress &
10076                     0xffffffffull));
10077                 ddi_put32(acc_hdl, &ieeesgep->Address.High,
10078                     (uint32_t)(dataout_cookie.dmac_laddress >> 32));
10079                 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10080                 ieeesgep++;
10081         }
10082         sge_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST;
10083         ddi_put32(acc_hdl, &ieeesgep->Length, data_size);
10084         ddi_put32(acc_hdl, &ieeesgep->Address.Low,
10085             (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull));
10086         ddi_put32(acc_hdl, &ieeesgep->Address.High,
10087             (uint32_t)(data_cookie.dmac_laddress >> 32));
10088         ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags);
10089 }
10090 
10091 static void
10092 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
10093 {
10094         caddr_t                 memp;
10095         pMPI2RequestHeader_t    request_hdrp;
10096         struct scsi_pkt         *pkt = cmd->cmd_pkt;
10097         mptsas_pt_request_t     *pt = pkt->pkt_ha_private;
10098         uint32_t                request_size;
10099         uint32_t                request_desc_low, request_desc_high = 0;
10100         uint64_t                sense_bufp;
10101         uint8_t                 desc_type;
10102         uint8_t                 *request, function;
10103         ddi_dma_handle_t        dma_hdl = mpt->m_dma_req_frame_hdl;
10104         ddi_acc_handle_t        acc_hdl = mpt->m_acc_req_frame_hdl;
10105 
10106         desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
10107 
10108         request = pt->request;
10109         request_size = pt->request_size;
10110 
10111         /*
10112          * Store the passthrough message in memory location
10113          * corresponding to our slot number
10114          */
10115         memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
10116         request_hdrp = (pMPI2RequestHeader_t)memp;
10117         bzero(memp, mpt->m_req_frame_size);
10118 
10119         bcopy(request, memp, request_size);
10120 
10121         NDBG15(("mptsas_start_passthru: Func 0x%x, MsgFlags 0x%x, "
10122             "size=%d, in %d, out %d", request_hdrp->Function,
10123             request_hdrp->MsgFlags, request_size,
10124             pt->data_size, pt->dataout_size));
10125 
10126         /*
10127          * Add an SGE, even if the length is zero.
10128          */
10129         if (mpt->m_MPI25 && pt->simple == 0) {
10130                 mptsas_passthru_ieee_sge(acc_hdl, pt,
10131                     (pMpi2IeeeSgeSimple64_t)
10132                     ((uint8_t *)request_hdrp + pt->sgl_offset));
10133         } else {
10134                 mptsas_passthru_sge(acc_hdl, pt,
10135                     (pMpi2SGESimple64_t)
10136                     ((uint8_t *)request_hdrp + pt->sgl_offset));
10137         }
10138 
10139         function = request_hdrp->Function;
10140         if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
10141             (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
10142                 pMpi2SCSIIORequest_t    scsi_io_req;
10143 
10144                 NDBG15(("mptsas_start_passthru: Is SCSI IO Req"));
10145                 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
10146                 /*
10147                  * Put SGE for data and data_out buffer at the end of
10148                  * scsi_io_request message header.(64 bytes in total)
10149                  * Following above SGEs, the residual space will be
10150                  * used by sense data.
10151                  */
10152                 ddi_put8(acc_hdl,
10153                     &scsi_io_req->SenseBufferLength,
10154                     (uint8_t)(request_size - 64));
10155 
10156                 sense_bufp = (uint32_t)(mpt->m_req_frame_dma_addr +
10157                     (mpt->m_req_frame_size * cmd->cmd_slot) & 0xffffffffull);
10158                 sense_bufp += 64;
10159                 ddi_put32(acc_hdl,
10160                     &scsi_io_req->SenseBufferLowAddress, sense_bufp);
10161 
10162                 /*
10163                  * Set SGLOffset0 value
10164                  */
10165                 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
10166                     offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
10167 
10168                 /*
10169                  * Setup descriptor info.  RAID passthrough must use the
10170                  * default request descriptor which is already set, so if this
10171                  * is a SCSI IO request, change the descriptor to SCSI IO.
10172                  */
10173                 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
10174                         desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
10175                         request_desc_high = (ddi_get16(acc_hdl,
10176                             &scsi_io_req->DevHandle) << 16);
10177                 }
10178         }
10179 
10180         /*
10181          * We must wait till the message has been completed before
10182          * beginning the next message so we wait for this one to
10183          * finish.
10184          */
10185         (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
10186         request_desc_low = (cmd->cmd_slot << 16) + desc_type;
10187         cmd->cmd_rfm = NULL;
10188         MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
10189         if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
10190             (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
10191                 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10192         }
10193 }
10194 
10195 typedef void (mptsas_pre_f)(mptsas_t *, mptsas_pt_request_t *);
10196 static mptsas_pre_f     mpi_pre_ioc_facts;
10197 static mptsas_pre_f     mpi_pre_port_facts;
10198 static mptsas_pre_f     mpi_pre_fw_download;
10199 static mptsas_pre_f     mpi_pre_fw_25_download;
10200 static mptsas_pre_f     mpi_pre_fw_upload;
10201 static mptsas_pre_f     mpi_pre_fw_25_upload;
10202 static mptsas_pre_f     mpi_pre_sata_passthrough;
10203 static mptsas_pre_f     mpi_pre_smp_passthrough;
10204 static mptsas_pre_f     mpi_pre_config;
10205 static mptsas_pre_f     mpi_pre_sas_io_unit_control;
10206 static mptsas_pre_f     mpi_pre_scsi_io_req;
10207 
10208 /*
10209  * Prepare the pt for a SAS2 FW_DOWNLOAD request.
10210  */
10211 static void
10212 mpi_pre_fw_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10213 {
10214         pMpi2FWDownloadTCSGE_t tcsge;
10215         pMpi2FWDownloadRequest req;
10216 
10217         /*
10218          * If SAS3, call separate function.
10219          */
10220         if (mpt->m_MPI25) {
10221                 mpi_pre_fw_25_download(mpt, pt);
10222                 return;
10223         }
10224 
10225         /*
10226          * User requests should come in with the Transaction
10227          * context element where the SGL will go. Putting the
10228          * SGL after that seems to work, but don't really know
10229          * why. Other drivers tend to create an extra SGL and
10230          * refer to the TCE through that.
10231          */
10232         req = (pMpi2FWDownloadRequest)pt->request;
10233         tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL;
10234         if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10235             tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10236                 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10237         }
10238 
10239         pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) +
10240             sizeof (*tcsge);
10241         if (pt->request_size != pt->sgl_offset)
10242                 NDBG15(("mpi_pre_fw_download(): Incorrect req size, "
10243                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10244                     (int)pt->request_size, (int)pt->sgl_offset,
10245                     (int)pt->dataout_size));
10246         if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
10247                 NDBG15(("mpi_pre_fw_download(): Incorrect rep size, "
10248                     "0x%x, should be 0x%x", pt->data_size,
10249                     (int)sizeof (MPI2_FW_DOWNLOAD_REPLY)));
10250 }
10251 
10252 /*
10253  * Prepare the pt for a SAS3 FW_DOWNLOAD request.
10254  */
10255 static void
10256 mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10257 {
10258         pMpi2FWDownloadTCSGE_t tcsge;
10259         pMpi2FWDownloadRequest req2;
10260         pMpi25FWDownloadRequest req25;
10261 
10262         /*
10263          * User requests should come in with the Transaction
10264          * context element where the SGL will go. The new firmware
10265          * Doesn't use TCE and has space in the main request for
10266          * this information. So move to the right place.
10267          */
10268         req2 = (pMpi2FWDownloadRequest)pt->request;
10269         req25 = (pMpi25FWDownloadRequest)pt->request;
10270         tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL;
10271         if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10272             tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10273                 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10274         }
10275         req25->ImageOffset = tcsge->ImageOffset;
10276         req25->ImageSize = tcsge->ImageSize;
10277 
10278         pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL);
10279         if (pt->request_size != pt->sgl_offset)
10280                 NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, "
10281                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10282                     pt->request_size, pt->sgl_offset,
10283                     pt->dataout_size));
10284         if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
10285                 NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, "
10286                     "0x%x, should be 0x%x", pt->data_size,
10287                     (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10288 }
10289 
10290 /*
10291  * Prepare the pt for a SAS2 FW_UPLOAD request.
10292  */
10293 static void
10294 mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10295 {
10296         pMpi2FWUploadTCSGE_t tcsge;
10297         pMpi2FWUploadRequest_t req;
10298 
10299         /*
10300          * If SAS3, call separate function.
10301          */
10302         if (mpt->m_MPI25) {
10303                 mpi_pre_fw_25_upload(mpt, pt);
10304                 return;
10305         }
10306 
10307         /*
10308          * User requests should come in with the Transaction
10309          * context element where the SGL will go. Putting the
10310          * SGL after that seems to work, but don't really know
10311          * why. Other drivers tend to create an extra SGL and
10312          * refer to the TCE through that.
10313          */
10314         req = (pMpi2FWUploadRequest_t)pt->request;
10315         tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL;
10316         if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10317             tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10318                 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10319         }
10320 
10321         pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) +
10322             sizeof (*tcsge);
10323         if (pt->request_size != pt->sgl_offset)
10324                 NDBG15(("mpi_pre_fw_upload(): Incorrect req size, "
10325                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10326                     pt->request_size, pt->sgl_offset,
10327                     pt->dataout_size));
10328         if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
10329                 NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, "
10330                     "0x%x, should be 0x%x", pt->data_size,
10331                     (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10332 }
10333 
10334 /*
10335  * Prepare the pt a SAS3 FW_UPLOAD request.
10336  */
10337 static void
10338 mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10339 {
10340         pMpi2FWUploadTCSGE_t tcsge;
10341         pMpi2FWUploadRequest_t req2;
10342         pMpi25FWUploadRequest_t req25;
10343 
10344         /*
10345          * User requests should come in with the Transaction
10346          * context element where the SGL will go. The new firmware
10347          * Doesn't use TCE and has space in the main request for
10348          * this information. So move to the right place.
10349          */
10350         req2 = (pMpi2FWUploadRequest_t)pt->request;
10351         req25 = (pMpi25FWUploadRequest_t)pt->request;
10352         tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL;
10353         if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10354             tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10355                 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10356         }
10357         req25->ImageOffset = tcsge->ImageOffset;
10358         req25->ImageSize = tcsge->ImageSize;
10359 
10360         pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL);
10361         if (pt->request_size != pt->sgl_offset)
10362                 NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, "
10363                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10364                     pt->request_size, pt->sgl_offset,
10365                     pt->dataout_size));
10366         if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
10367                 NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, "
10368                     "0x%x, should be 0x%x", pt->data_size,
10369                     (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
10370 }
10371 
10372 /*
10373  * Prepare the pt for an IOC_FACTS request.
10374  */
10375 static void
10376 mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10377 {
10378 #ifndef __lock_lint
10379         _NOTE(ARGUNUSED(mpt))
10380 #endif
10381         if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST))
10382                 NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, "
10383                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10384                     pt->request_size,
10385                     (int)sizeof (MPI2_IOC_FACTS_REQUEST),
10386                     pt->dataout_size));
10387         if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY))
10388                 NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, "
10389                     "0x%x, should be 0x%x", pt->data_size,
10390                     (int)sizeof (MPI2_IOC_FACTS_REPLY)));
10391         pt->sgl_offset = (uint16_t)pt->request_size;
10392 }
10393 
10394 /*
10395  * Prepare the pt for a PORT_FACTS request.
10396  */
10397 static void
10398 mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10399 {
10400 #ifndef __lock_lint
10401         _NOTE(ARGUNUSED(mpt))
10402 #endif
10403         if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST))
10404                 NDBG15(("mpi_pre_port_facts(): Incorrect req size, "
10405                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10406                     pt->request_size,
10407                     (int)sizeof (MPI2_PORT_FACTS_REQUEST),
10408                     pt->dataout_size));
10409         if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY))
10410                 NDBG15(("mpi_pre_port_facts(): Incorrect rep size, "
10411                     "0x%x, should be 0x%x", pt->data_size,
10412                     (int)sizeof (MPI2_PORT_FACTS_REPLY)));
10413         pt->sgl_offset = (uint16_t)pt->request_size;
10414 }
10415 
10416 /*
10417  * Prepare pt for a SATA_PASSTHROUGH request.
10418  */
10419 static void
10420 mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10421 {
10422 #ifndef __lock_lint
10423         _NOTE(ARGUNUSED(mpt))
10424 #endif
10425         pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL);
10426         if (pt->request_size != pt->sgl_offset)
10427                 NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, "
10428                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10429                     pt->request_size, pt->sgl_offset,
10430                     pt->dataout_size));
10431         if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY))
10432                 NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, "
10433                     "0x%x, should be 0x%x", pt->data_size,
10434                     (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY)));
10435 }
10436 
10437 static void
10438 mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10439 {
10440 #ifndef __lock_lint
10441         _NOTE(ARGUNUSED(mpt))
10442 #endif
10443         pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL);
10444         if (pt->request_size != pt->sgl_offset)
10445                 NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, "
10446                     "0x%x, should be 0x%x, dataoutsz 0x%x",
10447                     pt->request_size, pt->sgl_offset,
10448                     pt->dataout_size));
10449         if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY))
10450                 NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, "
10451                     "0x%x, should be 0x%x", pt->data_size,
10452                     (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY)));
10453 }
10454 
10455 /*
10456  * Prepare pt for a CONFIG request.
10457  */
10458 static void
10459 mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt)
10460 {
10461 #ifndef __lock_lint
10462         _NOTE(ARGUNUSED(mpt))
10463 #endif
10464         pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE);
10465         if (pt->request_size != pt->sgl_offset)
10466                 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10467                     "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10468                     pt->sgl_offset, pt->dataout_size));
10469         if (pt->data_size != sizeof (MPI2_CONFIG_REPLY))
10470                 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10471                     "should be 0x%x", pt->data_size,
10472                     (int)sizeof (MPI2_CONFIG_REPLY)));
10473         pt->simple = 1;
10474 }
10475 
10476 /*
10477  * Prepare pt for a SCSI_IO_REQ request.
10478  */
10479 static void
10480 mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt)
10481 {
10482 #ifndef __lock_lint
10483         _NOTE(ARGUNUSED(mpt))
10484 #endif
10485         pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL);
10486         if (pt->request_size != pt->sgl_offset)
10487                 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10488                     "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10489                     pt->sgl_offset,
10490                     pt->dataout_size));
10491         if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY))
10492                 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10493                     "should be 0x%x", pt->data_size,
10494                     (int)sizeof (MPI2_SCSI_IO_REPLY)));
10495 }
10496 
10497 /*
10498  * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request.
10499  */
10500 static void
10501 mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt)
10502 {
10503 #ifndef __lock_lint
10504         _NOTE(ARGUNUSED(mpt))
10505 #endif
10506         pt->sgl_offset = (uint16_t)pt->request_size;
10507 }
10508 
10509 /*
10510  * A set of functions to prepare an mptsas_cmd for the various
10511  * supported requests.
10512  */
10513 static struct mptsas_func {
10514         U8              Function;
10515         char            *Name;
10516         mptsas_pre_f    *f_pre;
10517 } mptsas_func_list[] = {
10518         { MPI2_FUNCTION_IOC_FACTS, "IOC_FACTS",         mpi_pre_ioc_facts },
10519         { MPI2_FUNCTION_PORT_FACTS, "PORT_FACTS",       mpi_pre_port_facts },
10520         { MPI2_FUNCTION_FW_DOWNLOAD, "FW_DOWNLOAD",     mpi_pre_fw_download },
10521         { MPI2_FUNCTION_FW_UPLOAD, "FW_UPLOAD",         mpi_pre_fw_upload },
10522         { MPI2_FUNCTION_SATA_PASSTHROUGH, "SATA_PASSTHROUGH",
10523             mpi_pre_sata_passthrough },
10524         { MPI2_FUNCTION_SMP_PASSTHROUGH, "SMP_PASSTHROUGH",
10525             mpi_pre_smp_passthrough},
10526         { MPI2_FUNCTION_SCSI_IO_REQUEST, "SCSI_IO_REQUEST",
10527             mpi_pre_scsi_io_req},
10528         { MPI2_FUNCTION_CONFIG, "CONFIG",               mpi_pre_config},
10529         { MPI2_FUNCTION_SAS_IO_UNIT_CONTROL, "SAS_IO_UNIT_CONTROL",
10530             mpi_pre_sas_io_unit_control },
10531         { 0xFF, NULL,                           NULL } /* list end */
10532 };
10533 
10534 static void
10535 mptsas_prep_sgl_offset(mptsas_t *mpt, mptsas_pt_request_t *pt)
10536 {
10537         pMPI2RequestHeader_t    hdr;
10538         struct mptsas_func      *f;
10539 
10540         hdr = (pMPI2RequestHeader_t)pt->request;
10541 
10542         for (f = mptsas_func_list; f->f_pre != NULL; f++) {
10543                 if (hdr->Function == f->Function) {
10544                         f->f_pre(mpt, pt);
10545                         NDBG15(("mptsas_prep_sgl_offset: Function %s,"
10546                             " sgl_offset 0x%x", f->Name,
10547                             pt->sgl_offset));
10548                         return;
10549                 }
10550         }
10551         NDBG15(("mptsas_prep_sgl_offset: Unknown Function 0x%02x,"
10552             " returning req_size 0x%x for sgl_offset",
10553             hdr->Function, pt->request_size));
10554         pt->sgl_offset = (uint16_t)pt->request_size;
10555 }
10556 
10557 
10558 static int
10559 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
10560     uint8_t *data, uint32_t request_size, uint32_t reply_size,
10561     uint32_t data_size, uint8_t direction, uint8_t *dataout,
10562     uint32_t dataout_size, short timeout, int mode)
10563 {
10564         mptsas_pt_request_t             pt;
10565         mptsas_dma_alloc_state_t        data_dma_state;
10566         mptsas_dma_alloc_state_t        dataout_dma_state;
10567         caddr_t                         memp;
10568         mptsas_cmd_t                    *cmd = NULL;
10569         struct scsi_pkt                 *pkt;
10570         uint32_t                        reply_len = 0, sense_len = 0;
10571         pMPI2RequestHeader_t            request_hdrp;
10572         pMPI2RequestHeader_t            request_msg;
10573         pMPI2DefaultReply_t             reply_msg;
10574         Mpi2SCSIIOReply_t               rep_msg;
10575         int                             i, status = 0, pt_flags = 0, rv = 0;
10576         int                             rvalue;
10577         uint8_t                         function;
10578 
10579         ASSERT(mutex_owned(&mpt->m_mutex));
10580 
10581         reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
 
10618                         mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
10619                             "resource");
10620                         goto out;
10621                 }
10622                 pt_flags |= MPTSAS_DATA_ALLOCATED;
10623                 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
10624                         mutex_exit(&mpt->m_mutex);
10625                         for (i = 0; i < data_size; i++) {
10626                                 if (ddi_copyin(data + i, (uint8_t *)
10627                                     data_dma_state.memp + i, 1, mode)) {
10628                                         mutex_enter(&mpt->m_mutex);
10629                                         status = EFAULT;
10630                                         mptsas_log(mpt, CE_WARN, "failed to "
10631                                             "copy read data");
10632                                         goto out;
10633                                 }
10634                         }
10635                         mutex_enter(&mpt->m_mutex);
10636                 }
10637         }
10638         else
10639                 bzero(&data_dma_state, sizeof (data_dma_state));
10640 
10641         if (dataout_size != 0) {
10642                 dataout_dma_state.size = dataout_size;
10643                 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
10644                         status = ENOMEM;
10645                         mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
10646                             "resource");
10647                         goto out;
10648                 }
10649                 pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
10650                 mutex_exit(&mpt->m_mutex);
10651                 for (i = 0; i < dataout_size; i++) {
10652                         if (ddi_copyin(dataout + i, (uint8_t *)
10653                             dataout_dma_state.memp + i, 1, mode)) {
10654                                 mutex_enter(&mpt->m_mutex);
10655                                 mptsas_log(mpt, CE_WARN, "failed to copy out"
10656                                     " data");
10657                                 status = EFAULT;
10658                                 goto out;
10659                         }
10660                 }
10661                 mutex_enter(&mpt->m_mutex);
10662         }
10663         else
10664                 bzero(&dataout_dma_state, sizeof (dataout_dma_state));
10665 
10666         if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
10667                 status = EAGAIN;
10668                 mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
10669                 goto out;
10670         }
10671         pt_flags |= MPTSAS_REQUEST_POOL_CMD;
10672 
10673         bzero((caddr_t)cmd, sizeof (*cmd));
10674         bzero((caddr_t)pkt, scsi_pkt_size());
10675         bzero((caddr_t)&pt, sizeof (pt));
10676 
10677         cmd->ioc_cmd_slot = (uint32_t)(rvalue);
10678 
10679         pt.request = (uint8_t *)request_msg;
10680         pt.direction = direction;
10681         pt.simple = 0;
10682         pt.request_size = request_size;
10683         pt.data_size = data_size;
10684         pt.dataout_size = dataout_size;
10685         pt.data_cookie = data_dma_state.cookie;
10686         pt.dataout_cookie = dataout_dma_state.cookie;
10687         mptsas_prep_sgl_offset(mpt, &pt);
10688 
10689         /*
10690          * Form a blank cmd/pkt to store the acknowledgement message
10691          */
10692         pkt->pkt_cdbp                = (opaque_t)&cmd->cmd_cdb[0];
10693         pkt->pkt_scbp                = (opaque_t)&cmd->cmd_scb;
10694         pkt->pkt_ha_private  = (opaque_t)&pt;
10695         pkt->pkt_flags               = FLAG_HEAD;
10696         pkt->pkt_time                = timeout;
10697         cmd->cmd_pkt         = pkt;
10698         cmd->cmd_flags               = CFLAG_CMDIOC | CFLAG_PASSTHRU;
10699 
10700         /*
10701          * Save the command in a slot
10702          */
10703         if (mptsas_save_cmd(mpt, cmd) == TRUE) {
10704                 /*
10705                  * Once passthru command get slot, set cmd_flags
10706                  * CFLAG_PREPARED.
10707                  */
 
10880         if (((data->DataSize == 0) &&
10881             (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
10882             ((data->DataSize != 0) &&
10883             ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
10884             (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
10885             ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
10886             (data->DataOutSize != 0))))) {
10887                 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
10888                         data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
10889                 } else {
10890                         data->DataOutSize = 0;
10891                 }
10892                 /*
10893                  * Send passthru request messages
10894                  */
10895                 return (mptsas_do_passthru(mpt,
10896                     (uint8_t *)((uintptr_t)data->PtrRequest),
10897                     (uint8_t *)((uintptr_t)data->PtrReply),
10898                     (uint8_t *)((uintptr_t)data->PtrData),
10899                     data->RequestSize, data->ReplySize,
10900                     data->DataSize, (uint8_t)data->DataDirection,
10901                     (uint8_t *)((uintptr_t)data->PtrDataOut),
10902                     data->DataOutSize, data->Timeout, mode));
10903         } else {
10904                 return (EINVAL);
10905         }
10906 }
10907 
10908 static uint8_t
10909 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
10910 {
10911         uint8_t index;
10912 
10913         for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
10914                 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
10915                         return (index);
10916                 }
10917         }
10918 
10919         return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
10920 }
 
11965                  * If we can't determine the PCI data then we fill in FF's for
11966                  * the data to indicate this.
11967                  */
11968                 adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
11969                 adapter_data->MpiPortNumber = 0xFFFFFFFF;
11970                 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF;
11971         }
11972 
11973         /*
11974          * Saved in the mpt->m_fwversion
11975          */
11976         adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
11977 }
11978 
11979 static void
11980 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
11981 {
11982         char    *driver_verstr = MPTSAS_MOD_STRING;
11983 
11984         mptsas_lookup_pci_data(mpt, adapter_data);
11985         adapter_data->AdapterType = mpt->m_MPI25 ?
11986             MPTIOCTL_ADAPTER_TYPE_SAS3 :
11987             MPTIOCTL_ADAPTER_TYPE_SAS2;
11988         adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
11989         adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
11990         adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
11991         adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
11992         (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
11993         adapter_data->BiosVersion = 0;
11994         (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
11995 }
11996 
11997 static void
11998 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
11999 {
12000         int     *reg_data, i;
12001         uint_t  reglen;
12002 
12003         /*
12004          * Lookup the 'reg' property and extract the other data
12005          */
12006         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
12007             DDI_PROP_DONTPASS, "reg", ®_data, ®len) ==
 
15719                 /*
15720                  * If success set rtn flag, else unwire alloc'd lun
15721                  */
15722                 if (ndi_rtn != NDI_SUCCESS) {
15723                         NDBG12(("mptsas unable to online "
15724                             "SMP target %s", wwn_str));
15725                         ndi_prop_remove_all(*smp_dip);
15726                         (void) ndi_devi_free(*smp_dip);
15727                 }
15728         }
15729 
15730         return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
15731 }
15732 
15733 /* smp transport routine */
15734 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
15735 {
15736         uint64_t                        wwn;
15737         Mpi2SmpPassthroughRequest_t     req;
15738         Mpi2SmpPassthroughReply_t       rep;
15739         uint8_t                         direction = 0;
15740         mptsas_t                        *mpt;
15741         int                             ret;
15742         uint64_t                        tmp64;
15743 
15744         mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
15745             smp_a_hba_tran->smp_tran_hba_private;
15746 
15747         bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
15748         /*
15749          * Need to compose a SMP request message
15750          * and call mptsas_do_passthru() function
15751          */
15752         bzero(&req, sizeof (req));
15753         bzero(&rep, sizeof (rep));
15754         req.PassthroughFlags = 0;
15755         req.PhysicalPort = 0xff;
15756         req.ChainOffset = 0;
15757         req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
15758 
15759         if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
 
 |