aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorSumit.Saxena@avagotech.com <Sumit.Saxena@avagotech.com>2015-01-05 09:36:03 -0500
committerChristoph Hellwig <hch@lst.de>2015-01-09 09:44:34 -0500
commit7497cde883b184ead109652f236df98d78090a90 (patch)
treec4c46695bbe9d9cf17e423785a61ce062e5db1c0 /drivers/scsi/megaraid
parent200aed582d6170a2687cd69095469b663f69f16f (diff)
megaraid_sas: add support for secure JBOD
This patch adds support for Secure Encrypting Drives (SED) in JBOD mode: 1) If the firmware supports SED JBOD, all non read/write commands to JBODs will be sent via firmware path, and read/write commands to JBODs will be sent via fastpath. 2) If the firmware does not support SED JBOD, driver will fall back to the old design, i.e. send all JBOD I/O via fastpath. Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com> Signed-off-by: Chaitra Basappa <chaitra.basappa@avagotech.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h57
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c28
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c73
3 files changed, 107 insertions, 51 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 0d44d91c2fce..b8b378dec7ec 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -969,7 +969,20 @@ struct megasas_ctrl_info {
969 969
970 struct { 970 struct {
971#if defined(__BIG_ENDIAN_BITFIELD) 971#if defined(__BIG_ENDIAN_BITFIELD)
972 u32 reserved:25; 972 u32 reserved:12;
973 u32 discardCacheDuringLDDelete:1;
974 u32 supportSecurityonJBOD:1;
975 u32 supportCacheBypassModes:1;
976 u32 supportDisableSESMonitoring:1;
977 u32 supportForceFlash:1;
978 u32 supportNVDRAM:1;
979 u32 supportDrvActivityLEDSetting:1;
980 u32 supportAllowedOpsforDrvRemoval:1;
981 u32 supportHOQRebuild:1;
982 u32 supportForceTo512e:1;
983 u32 supportNVCacheErase:1;
984 u32 supportDebugQueue:1;
985 u32 supportSwZone:1;
973 u32 supportCrashDump:1; 986 u32 supportCrashDump:1;
974 u32 supportMaxExtLDs:1; 987 u32 supportMaxExtLDs:1;
975 u32 supportT10RebuildAssist:1; 988 u32 supportT10RebuildAssist:1;
@@ -981,9 +994,22 @@ struct megasas_ctrl_info {
981 u32 supportThermalPollInterval:1; 994 u32 supportThermalPollInterval:1;
982 u32 supportDisableImmediateIO:1; 995 u32 supportDisableImmediateIO:1;
983 u32 supportT10RebuildAssist:1; 996 u32 supportT10RebuildAssist:1;
984 u32 supportMaxExtLDs:1; 997 u32 supportMaxExtLDs:1;
985 u32 supportCrashDump:1; 998 u32 supportCrashDump:1;
986 u32 reserved:25; 999 u32 supportSwZone:1;
1000 u32 supportDebugQueue:1;
1001 u32 supportNVCacheErase:1;
1002 u32 supportForceTo512e:1;
1003 u32 supportHOQRebuild:1;
1004 u32 supportAllowedOpsforDrvRemoval:1;
1005 u32 supportDrvActivityLEDSetting:1;
1006 u32 supportNVDRAM:1;
1007 u32 supportForceFlash:1;
1008 u32 supportDisableSESMonitoring:1;
1009 u32 supportCacheBypassModes:1;
1010 u32 supportSecurityonJBOD:1;
1011 u32 discardCacheDuringLDDelete:1;
1012 u32 reserved:12;
987#endif 1013#endif
988 } adapterOperations3; 1014 } adapterOperations3;
989 1015
@@ -1022,6 +1048,13 @@ enum MR_MFI_MPT_PTHR_FLAGS {
1022 MFI_MPT_ATTACHED = 2, 1048 MFI_MPT_ATTACHED = 2,
1023}; 1049};
1024 1050
1051enum MR_SCSI_CMD_TYPE {
1052 READ_WRITE_LDIO = 0,
1053 NON_READ_WRITE_LDIO = 1,
1054 READ_WRITE_SYSPDIO = 2,
1055 NON_READ_WRITE_SYSPDIO = 3,
1056};
1057
1025/* Frame Type */ 1058/* Frame Type */
1026#define IO_FRAME 0 1059#define IO_FRAME 0
1027#define PTHRU_FRAME 1 1060#define PTHRU_FRAME 1
@@ -1194,19 +1227,23 @@ union megasas_sgl_frame {
1194typedef union _MFI_CAPABILITIES { 1227typedef union _MFI_CAPABILITIES {
1195 struct { 1228 struct {
1196#if defined(__BIG_ENDIAN_BITFIELD) 1229#if defined(__BIG_ENDIAN_BITFIELD)
1197 u32 reserved:27; 1230 u32 reserved:25;
1231 u32 security_protocol_cmds_fw:1;
1232 u32 support_core_affinity:1;
1198 u32 support_ndrive_r1_lb:1; 1233 u32 support_ndrive_r1_lb:1;
1199 u32 support_max_255lds:1; 1234 u32 support_max_255lds:1;
1200 u32 reserved1:1; 1235 u32 support_fastpath_wb:1;
1201 u32 support_additional_msix:1; 1236 u32 support_additional_msix:1;
1202 u32 support_fp_remote_lun:1; 1237 u32 support_fp_remote_lun:1;
1203#else 1238#else
1204 u32 support_fp_remote_lun:1; 1239 u32 support_fp_remote_lun:1;
1205 u32 support_additional_msix:1; 1240 u32 support_additional_msix:1;
1206 u32 reserved1:1; 1241 u32 support_fastpath_wb:1;
1207 u32 support_max_255lds:1; 1242 u32 support_max_255lds:1;
1208 u32 support_ndrive_r1_lb:1; 1243 u32 support_ndrive_r1_lb:1;
1209 u32 reserved:27; 1244 u32 support_core_affinity:1;
1245 u32 security_protocol_cmds_fw:1;
1246 u32 reserved:25;
1210#endif 1247#endif
1211 } mfi_capabilities; 1248 } mfi_capabilities;
1212 u32 reg; 1249 u32 reg;
@@ -1638,13 +1675,14 @@ struct megasas_instance {
1638 u32 crash_dump_fw_support; 1675 u32 crash_dump_fw_support;
1639 u32 crash_dump_drv_support; 1676 u32 crash_dump_drv_support;
1640 u32 crash_dump_app_support; 1677 u32 crash_dump_app_support;
1678 u32 secure_jbod_support;
1641 spinlock_t crashdump_lock; 1679 spinlock_t crashdump_lock;
1642 1680
1643 struct megasas_register_set __iomem *reg_set; 1681 struct megasas_register_set __iomem *reg_set;
1644 u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; 1682 u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
1645 struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; 1683 struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
1646 struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD]; 1684 struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD];
1647 u8 ld_ids[MEGASAS_MAX_LD_IDS]; 1685 u8 ld_ids[MEGASAS_MAX_LD_IDS];
1648 s8 init_id; 1686 s8 init_id;
1649 1687
1650 u16 max_num_sge; 1688 u16 max_num_sge;
@@ -1946,5 +1984,6 @@ void __megasas_return_cmd(struct megasas_instance *instance,
1946 1984
1947void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance, 1985void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
1948 struct megasas_cmd *cmd_mfi, struct megasas_cmd_fusion *cmd_fusion); 1986 struct megasas_cmd *cmd_mfi, struct megasas_cmd_fusion *cmd_fusion);
1987int megasas_cmd_type(struct scsi_cmnd *cmd);
1949 1988
1950#endif /*LSI_MEGARAID_SAS_H */ 1989#endif /*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 401ed67cf4c1..9f37ddee4d8c 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1417,16 +1417,15 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1417} 1417}
1418 1418
1419/** 1419/**
1420 * megasas_is_ldio - Checks if the cmd is for logical drive 1420 * megasas_cmd_type - Checks if the cmd is for logical drive/sysPD
1421 * and whether it's RW or non RW
1421 * @scmd: SCSI command 1422 * @scmd: SCSI command
1422 * 1423 *
1423 * Called by megasas_queue_command to find out if the command to be queued
1424 * is a logical drive command
1425 */ 1424 */
1426inline int megasas_is_ldio(struct scsi_cmnd *cmd) 1425inline int megasas_cmd_type(struct scsi_cmnd *cmd)
1427{ 1426{
1428 if (!MEGASAS_IS_LOGICAL(cmd)) 1427 int ret;
1429 return 0; 1428
1430 switch (cmd->cmnd[0]) { 1429 switch (cmd->cmnd[0]) {
1431 case READ_10: 1430 case READ_10:
1432 case WRITE_10: 1431 case WRITE_10:
@@ -1436,10 +1435,14 @@ inline int megasas_is_ldio(struct scsi_cmnd *cmd)
1436 case WRITE_6: 1435 case WRITE_6:
1437 case READ_16: 1436 case READ_16:
1438 case WRITE_16: 1437 case WRITE_16:
1439 return 1; 1438 ret = (MEGASAS_IS_LOGICAL(cmd)) ?
1439 READ_WRITE_LDIO : READ_WRITE_SYSPDIO;
1440 break;
1440 default: 1441 default:
1441 return 0; 1442 ret = (MEGASAS_IS_LOGICAL(cmd)) ?
1443 NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO;
1442 } 1444 }
1445 return ret;
1443} 1446}
1444 1447
1445 /** 1448 /**
@@ -1471,7 +1474,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
1471 if(!cmd->scmd) 1474 if(!cmd->scmd)
1472 continue; 1475 continue;
1473 printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr); 1476 printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
1474 if (megasas_is_ldio(cmd->scmd)){ 1477 if (megasas_cmd_type(cmd->scmd) == READ_WRITE_LDIO) {
1475 ldio = (struct megasas_io_frame *)cmd->frame; 1478 ldio = (struct megasas_io_frame *)cmd->frame;
1476 mfi_sgl = &ldio->sgl; 1479 mfi_sgl = &ldio->sgl;
1477 sgcount = ldio->sge_count; 1480 sgcount = ldio->sge_count;
@@ -1531,7 +1534,7 @@ megasas_build_and_issue_cmd(struct megasas_instance *instance,
1531 /* 1534 /*
1532 * Logical drive command 1535 * Logical drive command
1533 */ 1536 */
1534 if (megasas_is_ldio(scmd)) 1537 if (megasas_cmd_type(scmd) == READ_WRITE_LDIO)
1535 frame_count = megasas_build_ldio(instance, scmd, cmd); 1538 frame_count = megasas_build_ldio(instance, scmd, cmd);
1536 else 1539 else
1537 frame_count = megasas_build_dcdb(instance, scmd, cmd); 1540 frame_count = megasas_build_dcdb(instance, scmd, cmd);
@@ -4629,6 +4632,11 @@ static int megasas_init_fw(struct megasas_instance *instance)
4629 instance->crash_dump_h); 4632 instance->crash_dump_h);
4630 instance->crash_dump_buf = NULL; 4633 instance->crash_dump_buf = NULL;
4631 } 4634 }
4635
4636 instance->secure_jbod_support =
4637 ctrl_info->adapterOperations3.supportSecurityonJBOD;
4638 if (instance->secure_jbod_support)
4639 dev_info(&instance->pdev->dev, "Firmware supports Secure JBOD\n");
4632 instance->max_sectors_per_req = instance->max_num_sge * 4640 instance->max_sectors_per_req = instance->max_num_sge *
4633 PAGE_SIZE / 512; 4641 PAGE_SIZE / 512;
4634 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) 4642 if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index b5362c196000..af5ab9e5e8e5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -63,7 +63,6 @@ extern struct megasas_cmd *megasas_get_cmd(struct megasas_instance
63extern void 63extern void
64megasas_complete_cmd(struct megasas_instance *instance, 64megasas_complete_cmd(struct megasas_instance *instance,
65 struct megasas_cmd *cmd, u8 alt_status); 65 struct megasas_cmd *cmd, u8 alt_status);
66int megasas_is_ldio(struct scsi_cmnd *cmd);
67int 66int
68wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd, 67wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
69 int seconds); 68 int seconds);
@@ -196,6 +195,7 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
196 195
197 cmd->scmd = NULL; 196 cmd->scmd = NULL;
198 cmd->sync_cmd_idx = (u32)ULONG_MAX; 197 cmd->sync_cmd_idx = (u32)ULONG_MAX;
198 memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
199 list_add(&cmd->list, (&fusion->cmd_pool)->next); 199 list_add(&cmd->list, (&fusion->cmd_pool)->next);
200 200
201 spin_unlock_irqrestore(&fusion->mpt_pool_lock, flags); 201 spin_unlock_irqrestore(&fusion->mpt_pool_lock, flags);
@@ -689,6 +689,8 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
689 = 1; 689 = 1;
690 init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb 690 init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb
691 = 1; 691 = 1;
692 init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw
693 = 1;
692 /* Convert capability to LE32 */ 694 /* Convert capability to LE32 */
693 cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities); 695 cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
694 696
@@ -1284,6 +1286,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance,
1284 1286
1285 sgl_ptr = 1287 sgl_ptr =
1286 (struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame; 1288 (struct MPI25_IEEE_SGE_CHAIN64 *)cmd->sg_frame;
1289 memset(sgl_ptr, 0, MEGASAS_MAX_SZ_CHAIN_FRAME);
1287 } 1290 }
1288 } 1291 }
1289 1292
@@ -1657,6 +1660,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
1657 u32 device_id; 1660 u32 device_id;
1658 struct MPI2_RAID_SCSI_IO_REQUEST *io_request; 1661 struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
1659 u16 pd_index = 0; 1662 u16 pd_index = 0;
1663 u16 os_timeout_value;
1664 u16 timeout_limit;
1660 struct MR_DRV_RAID_MAP_ALL *local_map_ptr; 1665 struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
1661 struct fusion_context *fusion = instance->ctrl_context; 1666 struct fusion_context *fusion = instance->ctrl_context;
1662 u8 span, physArm; 1667 u8 span, physArm;
@@ -1673,44 +1678,48 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
1673 1678
1674 io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); 1679 io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
1675 1680
1676
1677 /* Check if this is a system PD I/O */
1678 if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS && 1681 if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS &&
1679 instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { 1682 instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
1680 io_request->Function = 0;
1681 if (fusion->fast_path_io) 1683 if (fusion->fast_path_io)
1682 io_request->DevHandle = 1684 io_request->DevHandle =
1683 local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; 1685 local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
1684 io_request->RaidContext.timeoutValue =
1685 local_map_ptr->raidMap.fpPdIoTimeoutSec;
1686 io_request->RaidContext.regLockFlags = 0;
1687 io_request->RaidContext.regLockRowLBA = 0;
1688 io_request->RaidContext.regLockLength = 0;
1689 io_request->RaidContext.RAIDFlags = 1686 io_request->RaidContext.RAIDFlags =
1690 MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD << 1687 MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
1691 MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT; 1688 << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
1692 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) || 1689 cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
1693 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
1694 io_request->IoFlags |= cpu_to_le16(
1695 MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
1696 cmd->request_desc->SCSIIO.RequestFlags =
1697 (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
1698 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1699 cmd->request_desc->SCSIIO.DevHandle =
1700 local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
1701 cmd->request_desc->SCSIIO.MSIxIndex = 1690 cmd->request_desc->SCSIIO.MSIxIndex =
1702 instance->msix_vectors ? smp_processor_id() % instance->msix_vectors : 0; 1691 instance->msix_vectors ? smp_processor_id() % instance->msix_vectors : 0;
1703 /* 1692 os_timeout_value = scmd->request->timeout / HZ;
1704 * If the command is for the tape device, set the 1693
1705 * FP timeout to the os layer timeout value. 1694 if (instance->secure_jbod_support &&
1706 */ 1695 (megasas_cmd_type(scmd) == NON_READ_WRITE_SYSPDIO)) {
1707 if (scmd->device->type == TYPE_TAPE) { 1696 /* system pd firmware path */
1708 if ((scmd->request->timeout / HZ) > 0xFFFF) 1697 io_request->Function =
1709 io_request->RaidContext.timeoutValue = 1698 MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
1710 0xFFFF; 1699 cmd->request_desc->SCSIIO.RequestFlags =
1711 else 1700 (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
1712 io_request->RaidContext.timeoutValue = 1701 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1713 scmd->request->timeout / HZ; 1702 io_request->RaidContext.timeoutValue =
1703 cpu_to_le16(os_timeout_value);
1704 } else {
1705 /* system pd Fast Path */
1706 io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
1707 io_request->RaidContext.regLockFlags = 0;
1708 io_request->RaidContext.regLockRowLBA = 0;
1709 io_request->RaidContext.regLockLength = 0;
1710 timeout_limit = (scmd->device->type == TYPE_DISK) ?
1711 255 : 0xFFFF;
1712 io_request->RaidContext.timeoutValue =
1713 cpu_to_le16((os_timeout_value > timeout_limit) ?
1714 timeout_limit : os_timeout_value);
1715 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
1716 (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
1717 io_request->IoFlags |=
1718 cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
1719
1720 cmd->request_desc->SCSIIO.RequestFlags =
1721 (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
1722 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1714 } 1723 }
1715 } else { 1724 } else {
1716 if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS) 1725 if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS)
@@ -1810,7 +1819,7 @@ megasas_build_io_fusion(struct megasas_instance *instance,
1810 */ 1819 */
1811 io_request->IoFlags = cpu_to_le16(scp->cmd_len); 1820 io_request->IoFlags = cpu_to_le16(scp->cmd_len);
1812 1821
1813 if (megasas_is_ldio(scp)) 1822 if (megasas_cmd_type(scp) == READ_WRITE_LDIO)
1814 megasas_build_ldio_fusion(instance, scp, cmd); 1823 megasas_build_ldio_fusion(instance, scp, cmd);
1815 else 1824 else
1816 megasas_build_dcdb_fusion(instance, scp, cmd); 1825 megasas_build_dcdb_fusion(instance, scp, cmd);