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 =
|