Print this page
5719 Add support for LSI Fury adapters
   1 /*
   2  * mr_sas_tbolt.c: source for mr_sas driver for New Generation.
   3  * i.e. Thunderbolt and Invader
   4  *
   5  * Solaris MegaRAID device driver for SAS2.0 controllers
   6  * Copyright (c) 2008-2012, LSI Logic Corporation.
   7  * All rights reserved.
   8  *
   9  * Version:
  10  * Author:
  11  *              Swaminathan K S
  12  *              Arun Chandrashekhar
  13  *              Manju R
  14  *              Rasheed
  15  *              Shakeel Bukhari
  16  */
  17 
  18 /*
  19  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.

  20  */
  21 
  22 
  23 #include <sys/types.h>
  24 #include <sys/file.h>
  25 #include <sys/atomic.h>
  26 #include <sys/scsi/scsi.h>
  27 #include <sys/byteorder.h>
  28 #include "ld_pd_map.h"
  29 #include "mr_sas.h"
  30 #include "fusion.h"
  31 
  32 /*
  33  * FMA header files
  34  */
  35 #include <sys/ddifm.h>
  36 #include <sys/fm/protocol.h>
  37 #include <sys/fm/util.h>
  38 #include <sys/fm/io/ddi.h>
  39 


1214 
1215         return (0);
1216 }
1217 
1218 
1219 int
1220 mr_sas_tbolt_build_sgl(struct mrsas_instance *instance,
1221     struct scsa_cmd *acmd,
1222     struct mrsas_cmd *cmd,
1223     Mpi2RaidSCSIIORequest_t *scsi_raid_io,
1224     uint32_t *datalen)
1225 {
1226         uint32_t                MaxSGEs;
1227         int                     sg_to_process;
1228         uint32_t                i, j;
1229         uint32_t                numElements, endElement;
1230         Mpi25IeeeSgeChain64_t   *ieeeChainElement = NULL;
1231         Mpi25IeeeSgeChain64_t   *scsi_raid_io_sgl_ieee = NULL;
1232         ddi_acc_handle_t acc_handle =
1233             instance->mpi2_frame_pool_dma_obj.acc_handle;

1234 
1235         con_log(CL_ANN1, (CE_NOTE,
1236             "chkpnt: Building Chained SGL :%d", __LINE__));
1237 
1238         /* Calulate SGE size in number of Words(32bit) */
1239         /* Clear the datalen before updating it. */
1240         *datalen = 0;
1241 
1242         MaxSGEs = instance->max_sge_in_main_msg;
1243 
1244         ddi_put16(acc_handle, &scsi_raid_io->SGLFlags,
1245             MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
1246 
1247         /* set data transfer flag. */
1248         if (acmd->cmd_flags & CFLAG_DMASEND) {
1249                 ddi_put32(acc_handle, &scsi_raid_io->Control,
1250                     MPI2_SCSIIO_CONTROL_WRITE);
1251         } else {
1252                 ddi_put32(acc_handle, &scsi_raid_io->Control,
1253                     MPI2_SCSIIO_CONTROL_READ);


1257         numElements = acmd->cmd_cookiecnt;
1258 
1259         con_log(CL_DLEVEL1, (CE_NOTE, "[SGE Count]:%x", numElements));
1260 
1261         if (numElements > instance->max_num_sge) {
1262                 con_log(CL_ANN, (CE_NOTE,
1263                     "[Max SGE Count Exceeded]:%x", numElements));
1264                 return (numElements);
1265         }
1266 
1267         ddi_put8(acc_handle, &scsi_raid_io->RaidContext.numSGE,
1268             (uint8_t)numElements);
1269 
1270         /* set end element in main message frame */
1271         endElement = (numElements <= MaxSGEs) ? numElements : (MaxSGEs - 1);
1272 
1273         /* prepare the scatter-gather list for the firmware */
1274         scsi_raid_io_sgl_ieee =
1275             (Mpi25IeeeSgeChain64_t *)&scsi_raid_io->SGL.IeeeChain;
1276 
1277         if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1278                 Mpi25IeeeSgeChain64_t *sgl_ptr_end = scsi_raid_io_sgl_ieee;
1279                 sgl_ptr_end += instance->max_sge_in_main_msg - 1;
1280 
1281                 ddi_put8(acc_handle, &sgl_ptr_end->Flags, 0);
1282         }
1283 
1284         for (i = 0; i < endElement; i++, scsi_raid_io_sgl_ieee++) {
1285                 ddi_put64(acc_handle, &scsi_raid_io_sgl_ieee->Address,
1286                     acmd->cmd_dmacookies[i].dmac_laddress);
1287 
1288                 ddi_put32(acc_handle, &scsi_raid_io_sgl_ieee->Length,
1289                     acmd->cmd_dmacookies[i].dmac_size);
1290 
1291                 ddi_put8(acc_handle, &scsi_raid_io_sgl_ieee->Flags, 0);
1292 
1293                 if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1294                         if (i == (numElements - 1)) {
1295                                 ddi_put8(acc_handle,
1296                                     &scsi_raid_io_sgl_ieee->Flags,
1297                                     IEEE_SGE_FLAGS_END_OF_LIST);
1298                         }
1299                 }
1300 
1301                 *datalen += acmd->cmd_dmacookies[i].dmac_size;
1302 
1303 #ifdef DEBUG
1304                 con_log(CL_DLEVEL1, (CE_NOTE, "[SGL Address]: %" PRIx64,
1305                     scsi_raid_io_sgl_ieee->Address));
1306                 con_log(CL_DLEVEL1, (CE_NOTE, "[SGL Length]:%x",
1307                     scsi_raid_io_sgl_ieee->Length));
1308                 con_log(CL_DLEVEL1, (CE_NOTE, "[SGL Flags]:%x",
1309                     scsi_raid_io_sgl_ieee->Flags));
1310 #endif
1311 
1312         }
1313 
1314         ddi_put8(acc_handle, &scsi_raid_io->ChainOffset, 0);
1315 
1316         /* check if chained SGL required */
1317         if (i < numElements) {
1318 
1319                 con_log(CL_ANN1, (CE_NOTE, "[Chain Element index]:%x", i));
1320 
1321                 if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1322                         uint16_t ioFlags =
1323                             ddi_get16(acc_handle, &scsi_raid_io->IoFlags);
1324 
1325                         if ((ioFlags &
1326                             MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
1327                             MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) {
1328                                 ddi_put8(acc_handle, &scsi_raid_io->ChainOffset,
1329                                     (U8)instance->chain_offset_io_req);
1330                         } else {
1331                                 ddi_put8(acc_handle,
1332                                     &scsi_raid_io->ChainOffset, 0);
1333                         }
1334                 } else {
1335                         ddi_put8(acc_handle, &scsi_raid_io->ChainOffset,
1336                             (U8)instance->chain_offset_io_req);
1337                 }
1338 
1339                 /* prepare physical chain element */
1340                 ieeeChainElement = scsi_raid_io_sgl_ieee;
1341 
1342                 ddi_put8(acc_handle, &ieeeChainElement->NextChainOffset, 0);
1343 
1344                 if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1345                         ddi_put8(acc_handle, &ieeeChainElement->Flags,
1346                             IEEE_SGE_FLAGS_CHAIN_ELEMENT);
1347                 } else {
1348                         ddi_put8(acc_handle, &ieeeChainElement->Flags,
1349                             (IEEE_SGE_FLAGS_CHAIN_ELEMENT |
1350                             MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR));
1351                 }
1352 
1353                 ddi_put32(acc_handle, &ieeeChainElement->Length,
1354                     (sizeof (MPI2_SGE_IO_UNION) * (numElements - i)));
1355 
1356                 ddi_put64(acc_handle, &ieeeChainElement->Address,
1357                     (U64)cmd->sgl_phys_addr);
1358 
1359                 sg_to_process = numElements - i;
1360 
1361                 con_log(CL_ANN1, (CE_NOTE,
1362                     "[Additional SGE Count]:%x", endElement));
1363 
1364                 /* point to the chained SGL buffer */
1365                 scsi_raid_io_sgl_ieee = (Mpi25IeeeSgeChain64_t *)cmd->sgl;
1366 
1367                 /* build rest of the SGL in chained buffer */
1368                 for (j = 0; j < sg_to_process; j++, scsi_raid_io_sgl_ieee++) {
1369                         con_log(CL_DLEVEL3, (CE_NOTE, "[remaining SGL]:%x", i));
1370 
1371                         ddi_put64(acc_handle, &scsi_raid_io_sgl_ieee->Address,
1372                             acmd->cmd_dmacookies[i].dmac_laddress);
1373 
1374                         ddi_put32(acc_handle, &scsi_raid_io_sgl_ieee->Length,
1375                             acmd->cmd_dmacookies[i].dmac_size);
1376 
1377                         ddi_put8(acc_handle, &scsi_raid_io_sgl_ieee->Flags, 0);
1378 
1379                         if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1380                                 if (i == (numElements - 1)) {
1381                                         ddi_put8(acc_handle,
1382                                             &scsi_raid_io_sgl_ieee->Flags,
1383                                             IEEE_SGE_FLAGS_END_OF_LIST);
1384                                 }
1385                         }
1386 
1387                         *datalen += acmd->cmd_dmacookies[i].dmac_size;
1388 
1389 #if DEBUG
1390                         con_log(CL_DLEVEL1, (CE_NOTE,
1391                             "[SGL Address]: %" PRIx64,
1392                             scsi_raid_io_sgl_ieee->Address));
1393                         con_log(CL_DLEVEL1, (CE_NOTE,
1394                             "[SGL Length]:%x", scsi_raid_io_sgl_ieee->Length));
1395                         con_log(CL_DLEVEL1, (CE_NOTE,
1396                             "[SGL Flags]:%x", scsi_raid_io_sgl_ieee->Flags));
1397 #endif
1398 
1399                         i++;
1400                 }
1401         }
1402 
1403         return (0);
1404 } /*end of BuildScatterGather */
1405 
1406 
1407 /*
1408  * build_cmd
1409  */
1410 static struct mrsas_cmd *
1411 mrsas_tbolt_build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
1412     struct scsi_pkt *pkt, uchar_t *cmd_done)
1413 {
1414         uint8_t         fp_possible = 0;
1415         uint32_t        index;
1416         uint32_t        lba_count = 0;
1417         uint32_t        start_lba_hi = 0;
1418         uint32_t        start_lba_lo = 0;

1419         ddi_acc_handle_t acc_handle =
1420             instance->mpi2_frame_pool_dma_obj.acc_handle;
1421         struct mrsas_cmd                *cmd = NULL;
1422         struct scsa_cmd                 *acmd = PKT2CMD(pkt);
1423         MRSAS_REQUEST_DESCRIPTOR_UNION  *ReqDescUnion;
1424         Mpi2RaidSCSIIORequest_t         *scsi_raid_io;
1425         uint32_t                        datalen;
1426         struct IO_REQUEST_INFO io_info;
1427         MR_FW_RAID_MAP_ALL *local_map_ptr;
1428         uint16_t pd_cmd_cdblen;
1429 
1430         con_log(CL_DLEVEL1, (CE_NOTE,
1431             "chkpnt: Entered mrsas_tbolt_build_cmd:%d", __LINE__));
1432 
1433         /* find out if this is logical or physical drive command.  */
1434         acmd->islogical = MRDRV_IS_LOGICAL(ap);
1435         acmd->device_id = MAP_DEVICE_ID(instance, ap);
1436 
1437         *cmd_done = 0;
1438 


1624                         if (MR_CheckDIF(acmd->device_id, local_map_ptr)) {
1625                                 /* Prepare 32 Byte CDB for DIF capable Disk */
1626                                 mrsas_tbolt_prepare_cdb(instance,
1627                                     scsi_raid_io->CDB.CDB32,
1628                                     &io_info, scsi_raid_io, start_lba_lo);
1629                         } else {
1630                                 mrsas_tbolt_set_pd_lba(scsi_raid_io->CDB.CDB32,
1631                                     (uint8_t *)&pd_cmd_cdblen,
1632                                     io_info.pdBlock, io_info.numBlocks);
1633                                 ddi_put16(acc_handle,
1634                                     &scsi_raid_io->IoFlags, pd_cmd_cdblen);
1635                         }
1636 
1637                         ddi_put8(acc_handle, &scsi_raid_io->Function,
1638                             MPI2_FUNCTION_SCSI_IO_REQUEST);
1639 
1640                         ReqDescUnion->SCSIIO.RequestFlags =
1641                             (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
1642                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1643 
1644                         if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1645                                 uint8_t regLockFlags = ddi_get8(acc_handle,
1646                                     &scsi_raid_io->RaidContext.regLockFlags);
1647                                 uint16_t IoFlags = ddi_get16(acc_handle,
1648                                     &scsi_raid_io->IoFlags);
1649 
1650                                 if (regLockFlags == REGION_TYPE_UNUSED)
1651                                         ReqDescUnion->SCSIIO.RequestFlags =
1652                                             (MPI2_REQ_DESCRIPT_FLAGS_NO_LOCK <<
1653                                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1654 
1655                                 IoFlags |=
1656                                     MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
1657                                 regLockFlags |=
1658                                     (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
1659                                     MR_RL_FLAGS_SEQ_NUM_ENABLE);
1660 
1661                                 ddi_put8(acc_handle,
1662                                     &scsi_raid_io->ChainOffset, 0);
1663                                 ddi_put8(acc_handle,
1664                                     &scsi_raid_io->RaidContext.nsegType,


1687 
1688                         ReqDescUnion->SCSIIO.DevHandle = io_info.devHandle;
1689                         ddi_put16(acc_handle, &scsi_raid_io->DevHandle,
1690                             io_info.devHandle);
1691 
1692                 } else {
1693                         ddi_put8(acc_handle, &scsi_raid_io->Function,
1694                             MPI2_FUNCTION_LD_IO_REQUEST);
1695 
1696                         ddi_put16(acc_handle,
1697                             &scsi_raid_io->DevHandle, acmd->device_id);
1698 
1699                         ReqDescUnion->SCSIIO.RequestFlags =
1700                             (MPI2_REQ_DESCRIPT_FLAGS_LD_IO <<
1701                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1702 
1703                         ddi_put16(acc_handle,
1704                             &scsi_raid_io->RaidContext.timeoutValue,
1705                             local_map_ptr->raidMap.fpPdIoTimeoutSec);
1706 
1707                         if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

1708                                 uint8_t regLockFlags = ddi_get8(acc_handle,
1709                                     &scsi_raid_io->RaidContext.regLockFlags);
1710 
1711                                 if (regLockFlags == REGION_TYPE_UNUSED) {
1712                                         ReqDescUnion->SCSIIO.RequestFlags =
1713                                             (MPI2_REQ_DESCRIPT_FLAGS_NO_LOCK <<
1714                                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1715                                 }
1716 
1717                                 regLockFlags |=
1718                                     (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
1719                                     MR_RL_FLAGS_SEQ_NUM_ENABLE);
1720 
1721                                 ddi_put8(acc_handle,
1722                                     &scsi_raid_io->RaidContext.nsegType,
1723                                     ((0x01 << MPI2_NSEG_FLAGS_SHIFT) |
1724                                     MPI2_TYPE_CUDA));
1725                                 ddi_put8(acc_handle,
1726                                     &scsi_raid_io->RaidContext.regLockFlags,
1727                                     regLockFlags);


2238         if (!ReqDescUnion) {
2239                 con_log(CL_ANN1, (CE_NOTE, "[NULL REQDESC]"));
2240                 return;
2241         }
2242 
2243         con_log(CL_ANN1, (CE_NOTE, "[SMID]%x", cmd->SMID));
2244 
2245         ReqDescUnion->Words = 0;
2246 
2247         ReqDescUnion->SCSIIO.RequestFlags =
2248             (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
2249             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
2250 
2251         ReqDescUnion->SCSIIO.SMID = cmd->SMID;
2252 
2253         cmd->request_desc = ReqDescUnion;
2254 
2255         /* get raid message frame pointer */
2256         scsi_raid_io = (Mpi2RaidSCSIIORequest_t *)cmd->scsi_io_request;
2257 
2258         if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

2259                 Mpi25IeeeSgeChain64_t *sgl_ptr_end = (Mpi25IeeeSgeChain64_t *)
2260                     &scsi_raid_io->SGL.IeeeChain;
2261                 sgl_ptr_end += instance->max_sge_in_main_msg - 1;
2262                 ddi_put8(acc_handle, &sgl_ptr_end->Flags, 0);
2263         }
2264 
2265         ddi_put8(acc_handle, &scsi_raid_io->Function,
2266             MPI2_FUNCTION_PASSTHRU_IO_REQUEST);
2267 
2268         ddi_put8(acc_handle, &scsi_raid_io->SGLOffset0,
2269             offsetof(MPI2_RAID_SCSI_IO_REQUEST, SGL) / 4);
2270 
2271         ddi_put8(acc_handle, &scsi_raid_io->ChainOffset,
2272             (U8)offsetof(MPI2_RAID_SCSI_IO_REQUEST, SGL) / 16);
2273 
2274         ddi_put32(acc_handle, &scsi_raid_io->SenseBufferLowAddress,
2275             cmd->sense_phys_addr1);
2276 
2277 
2278         scsi_raid_io_sgl_ieee =


   1 /*
   2  * mr_sas_tbolt.c: source for mr_sas driver for New Generation.
   3  * i.e. Thunderbolt and Invader
   4  *
   5  * Solaris MegaRAID device driver for SAS2.0 controllers
   6  * Copyright (c) 2008-2012, LSI Logic Corporation.
   7  * All rights reserved.
   8  *
   9  * Version:
  10  * Author:
  11  *              Swaminathan K S
  12  *              Arun Chandrashekhar
  13  *              Manju R
  14  *              Rasheed
  15  *              Shakeel Bukhari
  16  */
  17 
  18 /*
  19  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  20  * Copyright 2015 Garrett D'Amore <garrett@damore.org>
  21  */
  22 
  23 
  24 #include <sys/types.h>
  25 #include <sys/file.h>
  26 #include <sys/atomic.h>
  27 #include <sys/scsi/scsi.h>
  28 #include <sys/byteorder.h>
  29 #include "ld_pd_map.h"
  30 #include "mr_sas.h"
  31 #include "fusion.h"
  32 
  33 /*
  34  * FMA header files
  35  */
  36 #include <sys/ddifm.h>
  37 #include <sys/fm/protocol.h>
  38 #include <sys/fm/util.h>
  39 #include <sys/fm/io/ddi.h>
  40 


1215 
1216         return (0);
1217 }
1218 
1219 
1220 int
1221 mr_sas_tbolt_build_sgl(struct mrsas_instance *instance,
1222     struct scsa_cmd *acmd,
1223     struct mrsas_cmd *cmd,
1224     Mpi2RaidSCSIIORequest_t *scsi_raid_io,
1225     uint32_t *datalen)
1226 {
1227         uint32_t                MaxSGEs;
1228         int                     sg_to_process;
1229         uint32_t                i, j;
1230         uint32_t                numElements, endElement;
1231         Mpi25IeeeSgeChain64_t   *ieeeChainElement = NULL;
1232         Mpi25IeeeSgeChain64_t   *scsi_raid_io_sgl_ieee = NULL;
1233         ddi_acc_handle_t acc_handle =
1234             instance->mpi2_frame_pool_dma_obj.acc_handle;
1235         uint16_t                devid = instance->device_id;
1236 
1237         con_log(CL_ANN1, (CE_NOTE,
1238             "chkpnt: Building Chained SGL :%d", __LINE__));
1239 
1240         /* Calulate SGE size in number of Words(32bit) */
1241         /* Clear the datalen before updating it. */
1242         *datalen = 0;
1243 
1244         MaxSGEs = instance->max_sge_in_main_msg;
1245 
1246         ddi_put16(acc_handle, &scsi_raid_io->SGLFlags,
1247             MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
1248 
1249         /* set data transfer flag. */
1250         if (acmd->cmd_flags & CFLAG_DMASEND) {
1251                 ddi_put32(acc_handle, &scsi_raid_io->Control,
1252                     MPI2_SCSIIO_CONTROL_WRITE);
1253         } else {
1254                 ddi_put32(acc_handle, &scsi_raid_io->Control,
1255                     MPI2_SCSIIO_CONTROL_READ);


1259         numElements = acmd->cmd_cookiecnt;
1260 
1261         con_log(CL_DLEVEL1, (CE_NOTE, "[SGE Count]:%x", numElements));
1262 
1263         if (numElements > instance->max_num_sge) {
1264                 con_log(CL_ANN, (CE_NOTE,
1265                     "[Max SGE Count Exceeded]:%x", numElements));
1266                 return (numElements);
1267         }
1268 
1269         ddi_put8(acc_handle, &scsi_raid_io->RaidContext.numSGE,
1270             (uint8_t)numElements);
1271 
1272         /* set end element in main message frame */
1273         endElement = (numElements <= MaxSGEs) ? numElements : (MaxSGEs - 1);
1274 
1275         /* prepare the scatter-gather list for the firmware */
1276         scsi_raid_io_sgl_ieee =
1277             (Mpi25IeeeSgeChain64_t *)&scsi_raid_io->SGL.IeeeChain;
1278 
1279         if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1280             (devid == PCI_DEVICE_ID_LSI_FURY)) {
1281                 Mpi25IeeeSgeChain64_t *sgl_ptr_end = scsi_raid_io_sgl_ieee;
1282                 sgl_ptr_end += instance->max_sge_in_main_msg - 1;
1283 
1284                 ddi_put8(acc_handle, &sgl_ptr_end->Flags, 0);
1285         }
1286 
1287         for (i = 0; i < endElement; i++, scsi_raid_io_sgl_ieee++) {
1288                 ddi_put64(acc_handle, &scsi_raid_io_sgl_ieee->Address,
1289                     acmd->cmd_dmacookies[i].dmac_laddress);
1290 
1291                 ddi_put32(acc_handle, &scsi_raid_io_sgl_ieee->Length,
1292                     acmd->cmd_dmacookies[i].dmac_size);
1293 
1294                 ddi_put8(acc_handle, &scsi_raid_io_sgl_ieee->Flags, 0);
1295 
1296                 if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1297                     (devid == PCI_DEVICE_ID_LSI_FURY)) {
1298                         if (i == (numElements - 1)) {
1299                                 ddi_put8(acc_handle,
1300                                     &scsi_raid_io_sgl_ieee->Flags,
1301                                     IEEE_SGE_FLAGS_END_OF_LIST);
1302                         }
1303                 }
1304 
1305                 *datalen += acmd->cmd_dmacookies[i].dmac_size;
1306 
1307 #ifdef DEBUG
1308                 con_log(CL_DLEVEL1, (CE_NOTE, "[SGL Address]: %" PRIx64,
1309                     scsi_raid_io_sgl_ieee->Address));
1310                 con_log(CL_DLEVEL1, (CE_NOTE, "[SGL Length]:%x",
1311                     scsi_raid_io_sgl_ieee->Length));
1312                 con_log(CL_DLEVEL1, (CE_NOTE, "[SGL Flags]:%x",
1313                     scsi_raid_io_sgl_ieee->Flags));
1314 #endif
1315 
1316         }
1317 
1318         ddi_put8(acc_handle, &scsi_raid_io->ChainOffset, 0);
1319 
1320         /* check if chained SGL required */
1321         if (i < numElements) {
1322 
1323                 con_log(CL_ANN1, (CE_NOTE, "[Chain Element index]:%x", i));
1324 
1325                 if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1326                     (devid == PCI_DEVICE_ID_LSI_FURY)) {
1327                         uint16_t ioFlags =
1328                             ddi_get16(acc_handle, &scsi_raid_io->IoFlags);
1329 
1330                         if ((ioFlags &
1331                             MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
1332                             MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) {
1333                                 ddi_put8(acc_handle, &scsi_raid_io->ChainOffset,
1334                                     (U8)instance->chain_offset_io_req);
1335                         } else {
1336                                 ddi_put8(acc_handle,
1337                                     &scsi_raid_io->ChainOffset, 0);
1338                         }
1339                 } else {
1340                         ddi_put8(acc_handle, &scsi_raid_io->ChainOffset,
1341                             (U8)instance->chain_offset_io_req);
1342                 }
1343 
1344                 /* prepare physical chain element */
1345                 ieeeChainElement = scsi_raid_io_sgl_ieee;
1346 
1347                 ddi_put8(acc_handle, &ieeeChainElement->NextChainOffset, 0);
1348 
1349                 if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1350                     (devid == PCI_DEVICE_ID_LSI_FURY)) {
1351                         ddi_put8(acc_handle, &ieeeChainElement->Flags,
1352                             IEEE_SGE_FLAGS_CHAIN_ELEMENT);
1353                 } else {
1354                         ddi_put8(acc_handle, &ieeeChainElement->Flags,
1355                             (IEEE_SGE_FLAGS_CHAIN_ELEMENT |
1356                             MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR));
1357                 }
1358 
1359                 ddi_put32(acc_handle, &ieeeChainElement->Length,
1360                     (sizeof (MPI2_SGE_IO_UNION) * (numElements - i)));
1361 
1362                 ddi_put64(acc_handle, &ieeeChainElement->Address,
1363                     (U64)cmd->sgl_phys_addr);
1364 
1365                 sg_to_process = numElements - i;
1366 
1367                 con_log(CL_ANN1, (CE_NOTE,
1368                     "[Additional SGE Count]:%x", endElement));
1369 
1370                 /* point to the chained SGL buffer */
1371                 scsi_raid_io_sgl_ieee = (Mpi25IeeeSgeChain64_t *)cmd->sgl;
1372 
1373                 /* build rest of the SGL in chained buffer */
1374                 for (j = 0; j < sg_to_process; j++, scsi_raid_io_sgl_ieee++) {
1375                         con_log(CL_DLEVEL3, (CE_NOTE, "[remaining SGL]:%x", i));
1376 
1377                         ddi_put64(acc_handle, &scsi_raid_io_sgl_ieee->Address,
1378                             acmd->cmd_dmacookies[i].dmac_laddress);
1379 
1380                         ddi_put32(acc_handle, &scsi_raid_io_sgl_ieee->Length,
1381                             acmd->cmd_dmacookies[i].dmac_size);
1382 
1383                         ddi_put8(acc_handle, &scsi_raid_io_sgl_ieee->Flags, 0);
1384 
1385                         if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1386                             (devid == PCI_DEVICE_ID_LSI_FURY)) {
1387                                 if (i == (numElements - 1)) {
1388                                         ddi_put8(acc_handle,
1389                                             &scsi_raid_io_sgl_ieee->Flags,
1390                                             IEEE_SGE_FLAGS_END_OF_LIST);
1391                                 }
1392                         }
1393 
1394                         *datalen += acmd->cmd_dmacookies[i].dmac_size;
1395 
1396 #if DEBUG
1397                         con_log(CL_DLEVEL1, (CE_NOTE,
1398                             "[SGL Address]: %" PRIx64,
1399                             scsi_raid_io_sgl_ieee->Address));
1400                         con_log(CL_DLEVEL1, (CE_NOTE,
1401                             "[SGL Length]:%x", scsi_raid_io_sgl_ieee->Length));
1402                         con_log(CL_DLEVEL1, (CE_NOTE,
1403                             "[SGL Flags]:%x", scsi_raid_io_sgl_ieee->Flags));
1404 #endif
1405 
1406                         i++;
1407                 }
1408         }
1409 
1410         return (0);
1411 } /*end of BuildScatterGather */
1412 
1413 
1414 /*
1415  * build_cmd
1416  */
1417 static struct mrsas_cmd *
1418 mrsas_tbolt_build_cmd(struct mrsas_instance *instance, struct scsi_address *ap,
1419     struct scsi_pkt *pkt, uchar_t *cmd_done)
1420 {
1421         uint8_t         fp_possible = 0;
1422         uint32_t        index;
1423         uint32_t        lba_count = 0;
1424         uint32_t        start_lba_hi = 0;
1425         uint32_t        start_lba_lo = 0;
1426         uint16_t        devid = instance->device_id;
1427         ddi_acc_handle_t acc_handle =
1428             instance->mpi2_frame_pool_dma_obj.acc_handle;
1429         struct mrsas_cmd                *cmd = NULL;
1430         struct scsa_cmd                 *acmd = PKT2CMD(pkt);
1431         MRSAS_REQUEST_DESCRIPTOR_UNION  *ReqDescUnion;
1432         Mpi2RaidSCSIIORequest_t         *scsi_raid_io;
1433         uint32_t                        datalen;
1434         struct IO_REQUEST_INFO io_info;
1435         MR_FW_RAID_MAP_ALL *local_map_ptr;
1436         uint16_t pd_cmd_cdblen;
1437 
1438         con_log(CL_DLEVEL1, (CE_NOTE,
1439             "chkpnt: Entered mrsas_tbolt_build_cmd:%d", __LINE__));
1440 
1441         /* find out if this is logical or physical drive command.  */
1442         acmd->islogical = MRDRV_IS_LOGICAL(ap);
1443         acmd->device_id = MAP_DEVICE_ID(instance, ap);
1444 
1445         *cmd_done = 0;
1446 


1632                         if (MR_CheckDIF(acmd->device_id, local_map_ptr)) {
1633                                 /* Prepare 32 Byte CDB for DIF capable Disk */
1634                                 mrsas_tbolt_prepare_cdb(instance,
1635                                     scsi_raid_io->CDB.CDB32,
1636                                     &io_info, scsi_raid_io, start_lba_lo);
1637                         } else {
1638                                 mrsas_tbolt_set_pd_lba(scsi_raid_io->CDB.CDB32,
1639                                     (uint8_t *)&pd_cmd_cdblen,
1640                                     io_info.pdBlock, io_info.numBlocks);
1641                                 ddi_put16(acc_handle,
1642                                     &scsi_raid_io->IoFlags, pd_cmd_cdblen);
1643                         }
1644 
1645                         ddi_put8(acc_handle, &scsi_raid_io->Function,
1646                             MPI2_FUNCTION_SCSI_IO_REQUEST);
1647 
1648                         ReqDescUnion->SCSIIO.RequestFlags =
1649                             (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
1650                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1651 
1652                         if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1653                             (devid == PCI_DEVICE_ID_LSI_FURY)) {
1654                                 uint8_t regLockFlags = ddi_get8(acc_handle,
1655                                     &scsi_raid_io->RaidContext.regLockFlags);
1656                                 uint16_t IoFlags = ddi_get16(acc_handle,
1657                                     &scsi_raid_io->IoFlags);
1658 
1659                                 if (regLockFlags == REGION_TYPE_UNUSED)
1660                                         ReqDescUnion->SCSIIO.RequestFlags =
1661                                             (MPI2_REQ_DESCRIPT_FLAGS_NO_LOCK <<
1662                                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1663 
1664                                 IoFlags |=
1665                                     MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
1666                                 regLockFlags |=
1667                                     (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
1668                                     MR_RL_FLAGS_SEQ_NUM_ENABLE);
1669 
1670                                 ddi_put8(acc_handle,
1671                                     &scsi_raid_io->ChainOffset, 0);
1672                                 ddi_put8(acc_handle,
1673                                     &scsi_raid_io->RaidContext.nsegType,


1696 
1697                         ReqDescUnion->SCSIIO.DevHandle = io_info.devHandle;
1698                         ddi_put16(acc_handle, &scsi_raid_io->DevHandle,
1699                             io_info.devHandle);
1700 
1701                 } else {
1702                         ddi_put8(acc_handle, &scsi_raid_io->Function,
1703                             MPI2_FUNCTION_LD_IO_REQUEST);
1704 
1705                         ddi_put16(acc_handle,
1706                             &scsi_raid_io->DevHandle, acmd->device_id);
1707 
1708                         ReqDescUnion->SCSIIO.RequestFlags =
1709                             (MPI2_REQ_DESCRIPT_FLAGS_LD_IO <<
1710                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1711 
1712                         ddi_put16(acc_handle,
1713                             &scsi_raid_io->RaidContext.timeoutValue,
1714                             local_map_ptr->raidMap.fpPdIoTimeoutSec);
1715 
1716                         if ((devid == PCI_DEVICE_ID_LSI_INVADER) ||
1717                             (devid == PCI_DEVICE_ID_LSI_FURY)) {
1718                                 uint8_t regLockFlags = ddi_get8(acc_handle,
1719                                     &scsi_raid_io->RaidContext.regLockFlags);
1720 
1721                                 if (regLockFlags == REGION_TYPE_UNUSED) {
1722                                         ReqDescUnion->SCSIIO.RequestFlags =
1723                                             (MPI2_REQ_DESCRIPT_FLAGS_NO_LOCK <<
1724                                             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1725                                 }
1726 
1727                                 regLockFlags |=
1728                                     (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
1729                                     MR_RL_FLAGS_SEQ_NUM_ENABLE);
1730 
1731                                 ddi_put8(acc_handle,
1732                                     &scsi_raid_io->RaidContext.nsegType,
1733                                     ((0x01 << MPI2_NSEG_FLAGS_SHIFT) |
1734                                     MPI2_TYPE_CUDA));
1735                                 ddi_put8(acc_handle,
1736                                     &scsi_raid_io->RaidContext.regLockFlags,
1737                                     regLockFlags);


2248         if (!ReqDescUnion) {
2249                 con_log(CL_ANN1, (CE_NOTE, "[NULL REQDESC]"));
2250                 return;
2251         }
2252 
2253         con_log(CL_ANN1, (CE_NOTE, "[SMID]%x", cmd->SMID));
2254 
2255         ReqDescUnion->Words = 0;
2256 
2257         ReqDescUnion->SCSIIO.RequestFlags =
2258             (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
2259             MPI2_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
2260 
2261         ReqDescUnion->SCSIIO.SMID = cmd->SMID;
2262 
2263         cmd->request_desc = ReqDescUnion;
2264 
2265         /* get raid message frame pointer */
2266         scsi_raid_io = (Mpi2RaidSCSIIORequest_t *)cmd->scsi_io_request;
2267 
2268         if ((instance->device_id == PCI_DEVICE_ID_LSI_INVADER) ||
2269             (instance->device_id == PCI_DEVICE_ID_LSI_FURY)) {
2270                 Mpi25IeeeSgeChain64_t *sgl_ptr_end = (Mpi25IeeeSgeChain64_t *)
2271                     &scsi_raid_io->SGL.IeeeChain;
2272                 sgl_ptr_end += instance->max_sge_in_main_msg - 1;
2273                 ddi_put8(acc_handle, &sgl_ptr_end->Flags, 0);
2274         }
2275 
2276         ddi_put8(acc_handle, &scsi_raid_io->Function,
2277             MPI2_FUNCTION_PASSTHRU_IO_REQUEST);
2278 
2279         ddi_put8(acc_handle, &scsi_raid_io->SGLOffset0,
2280             offsetof(MPI2_RAID_SCSI_IO_REQUEST, SGL) / 4);
2281 
2282         ddi_put8(acc_handle, &scsi_raid_io->ChainOffset,
2283             (U8)offsetof(MPI2_RAID_SCSI_IO_REQUEST, SGL) / 16);
2284 
2285         ddi_put32(acc_handle, &scsi_raid_io->SenseBufferLowAddress,
2286             cmd->sense_phys_addr1);
2287 
2288 
2289         scsi_raid_io_sgl_ieee =