|
@@ -233,6 +233,9 @@ static struct pci_device_id scsih_pci_table[] = {
|
|
|
PCI_ANY_ID, PCI_ANY_ID },
|
|
|
{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
|
|
|
PCI_ANY_ID, PCI_ANY_ID },
|
|
|
+ /* SSS6200 */
|
|
|
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
|
|
|
+ PCI_ANY_ID, PCI_ANY_ID },
|
|
|
{0} /* Terminating entry */
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(pci, scsih_pci_table);
|
|
@@ -1256,6 +1259,7 @@ _scsih_target_alloc(struct scsi_target *starget)
|
|
|
sas_target_priv_data->handle = raid_device->handle;
|
|
|
sas_target_priv_data->sas_address = raid_device->wwid;
|
|
|
sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
|
|
|
+ sas_target_priv_data->raid_device = raid_device;
|
|
|
raid_device->starget = starget;
|
|
|
}
|
|
|
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
|
@@ -1455,7 +1459,10 @@ static int
|
|
|
_scsih_is_raid(struct device *dev)
|
|
|
{
|
|
|
struct scsi_device *sdev = to_scsi_device(dev);
|
|
|
+ struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
|
|
|
|
|
|
+ if (ioc->is_warpdrive)
|
|
|
+ return 0;
|
|
|
return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
|
|
|
}
|
|
|
|
|
@@ -1480,7 +1487,7 @@ _scsih_get_resync(struct device *dev)
|
|
|
sdev->channel);
|
|
|
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
|
|
|
|
|
- if (!raid_device)
|
|
|
+ if (!raid_device || ioc->is_warpdrive)
|
|
|
goto out;
|
|
|
|
|
|
if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
|
|
@@ -1640,6 +1647,212 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
|
|
|
|
|
|
kfree(vol_pg0);
|
|
|
}
|
|
|
+/**
|
|
|
+ * _scsih_disable_ddio - Disable direct I/O for all the volumes
|
|
|
+ * @ioc: per adapter object
|
|
|
+ */
|
|
|
+static void
|
|
|
+_scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc)
|
|
|
+{
|
|
|
+ Mpi2RaidVolPage1_t vol_pg1;
|
|
|
+ Mpi2ConfigReply_t mpi_reply;
|
|
|
+ struct _raid_device *raid_device;
|
|
|
+ u16 handle;
|
|
|
+ u16 ioc_status;
|
|
|
+
|
|
|
+ handle = 0xFFFF;
|
|
|
+ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
|
|
+ &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
+ break;
|
|
|
+ handle = le16_to_cpu(vol_pg1.DevHandle);
|
|
|
+ raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
|
|
|
+ if (raid_device)
|
|
|
+ raid_device->direct_io_enabled = 0;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * _scsih_get_num_volumes - Get number of volumes in the ioc
|
|
|
+ * @ioc: per adapter object
|
|
|
+ */
|
|
|
+static u8
|
|
|
+_scsih_get_num_volumes(struct MPT2SAS_ADAPTER *ioc)
|
|
|
+{
|
|
|
+ Mpi2RaidVolPage1_t vol_pg1;
|
|
|
+ Mpi2ConfigReply_t mpi_reply;
|
|
|
+ u16 handle;
|
|
|
+ u8 vol_cnt = 0;
|
|
|
+ u16 ioc_status;
|
|
|
+
|
|
|
+ handle = 0xFFFF;
|
|
|
+ while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
|
|
+ &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
+ break;
|
|
|
+ vol_cnt++;
|
|
|
+ handle = le16_to_cpu(vol_pg1.DevHandle);
|
|
|
+ }
|
|
|
+ return vol_cnt;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O.
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @raid_device: the raid_device object
|
|
|
+ */
|
|
|
+static void
|
|
|
+_scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
|
|
|
+ struct _raid_device *raid_device)
|
|
|
+{
|
|
|
+ Mpi2RaidVolPage0_t *vol_pg0;
|
|
|
+ Mpi2RaidPhysDiskPage0_t pd_pg0;
|
|
|
+ Mpi2ConfigReply_t mpi_reply;
|
|
|
+ u16 sz;
|
|
|
+ u8 num_pds, count;
|
|
|
+ u64 mb = 1024 * 1024;
|
|
|
+ u64 tb_2 = 2 * mb * mb;
|
|
|
+ u64 capacity;
|
|
|
+ u32 stripe_sz;
|
|
|
+ u8 i, stripe_exp;
|
|
|
+
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "globally as drives are exposed\n", ioc->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (_scsih_get_num_volumes(ioc) > 1) {
|
|
|
+ _scsih_disable_ddio(ioc);
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "globally as number of drives > 1\n", ioc->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
|
|
|
+ &num_pds)) || !num_pds) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "Failure in computing number of drives\n", ioc->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
|
|
|
+ sizeof(Mpi2RaidVol0PhysDisk_t));
|
|
|
+ vol_pg0 = kzalloc(sz, GFP_KERNEL);
|
|
|
+ if (!vol_pg0) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "Memory allocation failure for RVPG0\n", ioc->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
|
|
|
+ MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "Failure in retrieving RVPG0\n", ioc->name);
|
|
|
+ kfree(vol_pg0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * WARPDRIVE:If number of physical disks in a volume exceeds the max pds
|
|
|
+ * assumed for WARPDRIVE, disable direct I/O
|
|
|
+ */
|
|
|
+ if (num_pds > MPT_MAX_WARPDRIVE_PDS) {
|
|
|
+ printk(MPT2SAS_WARN_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "for the drive with handle(0x%04x): num_mem=%d, "
|
|
|
+ "max_mem_allowed=%d\n", ioc->name, raid_device->handle,
|
|
|
+ num_pds, MPT_MAX_WARPDRIVE_PDS);
|
|
|
+ kfree(vol_pg0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (count = 0; count < num_pds; count++) {
|
|
|
+ if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
|
|
|
+ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
|
|
|
+ vol_pg0->PhysDisk[count].PhysDiskNum) ||
|
|
|
+ pd_pg0.DevHandle == MPT2SAS_INVALID_DEVICE_HANDLE) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
|
|
|
+ "disabled for the drive with handle(0x%04x) member"
|
|
|
+ "handle retrieval failed for member number=%d\n",
|
|
|
+ ioc->name, raid_device->handle,
|
|
|
+ vol_pg0->PhysDisk[count].PhysDiskNum);
|
|
|
+ goto out_error;
|
|
|
+ }
|
|
|
+ raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Assumption for WD: Direct I/O is not supported if the volume is
|
|
|
+ * not RAID0, if the stripe size is not 64KB, if the block size is
|
|
|
+ * not 512 and if the volume size is >2TB
|
|
|
+ */
|
|
|
+ if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 ||
|
|
|
+ le16_to_cpu(vol_pg0->BlockSize) != 512) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "for the drive with handle(0x%04x): type=%d, "
|
|
|
+ "s_sz=%uK, blk_size=%u\n", ioc->name,
|
|
|
+ raid_device->handle, raid_device->volume_type,
|
|
|
+ le32_to_cpu(vol_pg0->StripeSize)/2,
|
|
|
+ le16_to_cpu(vol_pg0->BlockSize));
|
|
|
+ goto out_error;
|
|
|
+ }
|
|
|
+
|
|
|
+ capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) *
|
|
|
+ (le64_to_cpu(vol_pg0->MaxLBA) + 1);
|
|
|
+
|
|
|
+ if (capacity > tb_2) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "for the drive with handle(0x%04x) since drive sz > 2TB\n",
|
|
|
+ ioc->name, raid_device->handle);
|
|
|
+ goto out_error;
|
|
|
+ }
|
|
|
+
|
|
|
+ stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
|
|
|
+ stripe_exp = 0;
|
|
|
+ for (i = 0; i < 32; i++) {
|
|
|
+ if (stripe_sz & 1)
|
|
|
+ break;
|
|
|
+ stripe_exp++;
|
|
|
+ stripe_sz >>= 1;
|
|
|
+ }
|
|
|
+ if (i == 32) {
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
|
|
|
+ "for the drive with handle(0x%04x) invalid stripe sz %uK\n",
|
|
|
+ ioc->name, raid_device->handle,
|
|
|
+ le32_to_cpu(vol_pg0->StripeSize)/2);
|
|
|
+ goto out_error;
|
|
|
+ }
|
|
|
+ raid_device->stripe_exponent = stripe_exp;
|
|
|
+ raid_device->direct_io_enabled = 1;
|
|
|
+
|
|
|
+ printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive"
|
|
|
+ " with handle(0x%04x)\n", ioc->name, raid_device->handle);
|
|
|
+ /*
|
|
|
+ * WARPDRIVE: Though the following fields are not used for direct IO,
|
|
|
+ * stored for future purpose:
|
|
|
+ */
|
|
|
+ raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
|
|
|
+ raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
|
|
|
+ raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);
|
|
|
+
|
|
|
+
|
|
|
+ kfree(vol_pg0);
|
|
|
+ return;
|
|
|
+
|
|
|
+out_error:
|
|
|
+ raid_device->direct_io_enabled = 0;
|
|
|
+ for (count = 0; count < num_pds; count++)
|
|
|
+ raid_device->pd_handle[count] = 0;
|
|
|
+ kfree(vol_pg0);
|
|
|
+ return;
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
* _scsih_enable_tlr - setting TLR flags
|
|
@@ -1710,6 +1923,11 @@ _scsih_slave_configure(struct scsi_device *sdev)
|
|
|
|
|
|
_scsih_get_volume_capabilities(ioc, raid_device);
|
|
|
|
|
|
+ /*
|
|
|
+ * WARPDRIVE: Initialize the required data for Direct IO
|
|
|
+ */
|
|
|
+ _scsih_init_warpdrive_properties(ioc, raid_device);
|
|
|
+
|
|
|
/* RAID Queue Depth Support
|
|
|
* IS volume = underlying qdepth of drive type, either
|
|
|
* MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH
|
|
@@ -1757,14 +1975,16 @@ _scsih_slave_configure(struct scsi_device *sdev)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- sdev_printk(KERN_INFO, sdev, "%s: "
|
|
|
- "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n",
|
|
|
- r_level, raid_device->handle,
|
|
|
- (unsigned long long)raid_device->wwid,
|
|
|
- raid_device->num_pds, ds);
|
|
|
+ if (!ioc->hide_ir_msg)
|
|
|
+ sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
|
|
|
+ "wwid(0x%016llx), pd_count(%d), type(%s)\n",
|
|
|
+ r_level, raid_device->handle,
|
|
|
+ (unsigned long long)raid_device->wwid,
|
|
|
+ raid_device->num_pds, ds);
|
|
|
_scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
|
|
|
/* raid transport support */
|
|
|
- _scsih_set_level(sdev, raid_device);
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ _scsih_set_level(sdev, raid_device);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2181,16 +2401,20 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
|
|
|
struct MPT2SAS_TARGET *priv_target = starget->hostdata;
|
|
|
struct _sas_device *sas_device = NULL;
|
|
|
unsigned long flags;
|
|
|
+ char *device_str = NULL;
|
|
|
|
|
|
if (!priv_target)
|
|
|
return;
|
|
|
+ if (ioc->hide_ir_msg)
|
|
|
+ device_str = "WarpDrive";
|
|
|
+ else
|
|
|
+ device_str = "volume";
|
|
|
|
|
|
scsi_print_command(scmd);
|
|
|
if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
|
|
|
- starget_printk(KERN_INFO, starget, "volume handle(0x%04x), "
|
|
|
- "volume wwid(0x%016llx)\n",
|
|
|
- priv_target->handle,
|
|
|
- (unsigned long long)priv_target->sas_address);
|
|
|
+ starget_printk(KERN_INFO, starget, "%s handle(0x%04x), "
|
|
|
+ "%s wwid(0x%016llx)\n", device_str, priv_target->handle,
|
|
|
+ device_str, (unsigned long long)priv_target->sas_address);
|
|
|
} else {
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
|
|
@@ -3129,6 +3353,9 @@ _scsih_check_ir_config_unhide_events(struct MPT2SAS_ADAPTER *ioc,
|
|
|
a = 0;
|
|
|
b = 0;
|
|
|
|
|
|
+ if (ioc->is_warpdrive)
|
|
|
+ return;
|
|
|
+
|
|
|
/* Volume Resets for Deleted or Removed */
|
|
|
element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
|
|
|
for (i = 0; i < event_data->NumElements; i++, element++) {
|
|
@@ -3345,6 +3572,105 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
|
|
|
SAM_STAT_CHECK_CONDITION;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * _scsih_scsi_direct_io_get - returns direct io flag
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @smid: system request message index
|
|
|
+ *
|
|
|
+ * Returns the smid stored scmd pointer.
|
|
|
+ */
|
|
|
+static inline u8
|
|
|
+_scsih_scsi_direct_io_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
|
|
|
+{
|
|
|
+ return ioc->scsi_lookup[smid - 1].direct_io;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _scsih_scsi_direct_io_set - sets direct io flag
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @smid: system request message index
|
|
|
+ * @direct_io: Zero or non-zero value to set in the direct_io flag
|
|
|
+ *
|
|
|
+ * Returns Nothing.
|
|
|
+ */
|
|
|
+static inline void
|
|
|
+_scsih_scsi_direct_io_set(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
|
|
|
+{
|
|
|
+ ioc->scsi_lookup[smid - 1].direct_io = direct_io;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
|
|
|
+ * @ioc: per adapter object
|
|
|
+ * @scmd: pointer to scsi command object
|
|
|
+ * @raid_device: pointer to raid device data structure
|
|
|
+ * @mpi_request: pointer to the SCSI_IO reqest message frame
|
|
|
+ * @smid: system request message index
|
|
|
+ *
|
|
|
+ * Returns nothing
|
|
|
+ */
|
|
|
+static void
|
|
|
+_scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
|
|
+ struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
|
|
|
+ u16 smid)
|
|
|
+{
|
|
|
+ u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size;
|
|
|
+ u32 stripe_sz, stripe_exp;
|
|
|
+ u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2;
|
|
|
+ u8 cdb0 = scmd->cmnd[0];
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Try Direct I/O to RAID memeber disks
|
|
|
+ */
|
|
|
+ if (cdb0 == READ_16 || cdb0 == READ_10 ||
|
|
|
+ cdb0 == WRITE_16 || cdb0 == WRITE_10) {
|
|
|
+ cdb_ptr = mpi_request->CDB.CDB32;
|
|
|
+
|
|
|
+ if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4]
|
|
|
+ | cdb_ptr[5])) {
|
|
|
+ io_size = scsi_bufflen(scmd) >> 9;
|
|
|
+ /* get virtual lba */
|
|
|
+ lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] :
|
|
|
+ &cdb_ptr[6];
|
|
|
+ tmp_ptr = (u8 *)&v_lba + 3;
|
|
|
+ *tmp_ptr-- = *lba_ptr1++;
|
|
|
+ *tmp_ptr-- = *lba_ptr1++;
|
|
|
+ *tmp_ptr-- = *lba_ptr1++;
|
|
|
+ *tmp_ptr = *lba_ptr1;
|
|
|
+
|
|
|
+ if (((u64)v_lba + (u64)io_size - 1) <=
|
|
|
+ (u32)raid_device->max_lba) {
|
|
|
+ stripe_sz = raid_device->stripe_sz;
|
|
|
+ stripe_exp = raid_device->stripe_exponent;
|
|
|
+ stripe_off = v_lba & (stripe_sz - 1);
|
|
|
+
|
|
|
+ /* Check whether IO falls within a stripe */
|
|
|
+ if ((stripe_off + io_size) <= stripe_sz) {
|
|
|
+ num_pds = raid_device->num_pds;
|
|
|
+ p_lba = v_lba >> stripe_exp;
|
|
|
+ stripe_unit = p_lba / num_pds;
|
|
|
+ column = p_lba % num_pds;
|
|
|
+ p_lba = (stripe_unit << stripe_exp) +
|
|
|
+ stripe_off;
|
|
|
+ mpi_request->DevHandle =
|
|
|
+ cpu_to_le16(raid_device->
|
|
|
+ pd_handle[column]);
|
|
|
+ tmp_ptr = (u8 *)&p_lba + 3;
|
|
|
+ *lba_ptr2++ = *tmp_ptr--;
|
|
|
+ *lba_ptr2++ = *tmp_ptr--;
|
|
|
+ *lba_ptr2++ = *tmp_ptr--;
|
|
|
+ *lba_ptr2 = *tmp_ptr;
|
|
|
+ /*
|
|
|
+ * WD: To indicate this I/O is directI/O
|
|
|
+ */
|
|
|
+ _scsih_scsi_direct_io_set(ioc, smid, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* _scsih_qcmd - main scsi request entry point
|
|
|
* @scmd: pointer to scsi command object
|
|
@@ -3362,6 +3688,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
|
|
struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
|
|
struct MPT2SAS_DEVICE *sas_device_priv_data;
|
|
|
struct MPT2SAS_TARGET *sas_target_priv_data;
|
|
|
+ struct _raid_device *raid_device;
|
|
|
Mpi2SCSIIORequest_t *mpi_request;
|
|
|
u32 mpi_control;
|
|
|
u16 smid;
|
|
@@ -3423,8 +3750,10 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
|
|
|
|
|
} else
|
|
|
mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
|
|
|
- /* Make sure Device is not raid volume */
|
|
|
- if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
|
|
|
+ /* Make sure Device is not raid volume.
|
|
|
+ * We do not expose raid functionality to upper layer for warpdrive.
|
|
|
+ */
|
|
|
+ if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
|
|
|
sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
|
|
|
mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
|
|
|
|
|
@@ -3472,9 +3801,14 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ raid_device = sas_target_priv_data->raid_device;
|
|
|
+ if (raid_device && raid_device->direct_io_enabled)
|
|
|
+ _scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request,
|
|
|
+ smid);
|
|
|
+
|
|
|
if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST))
|
|
|
mpt2sas_base_put_smid_scsi_io(ioc, smid,
|
|
|
- sas_device_priv_data->sas_target->handle);
|
|
|
+ le16_to_cpu(mpi_request->DevHandle));
|
|
|
else
|
|
|
mpt2sas_base_put_smid_default(ioc, smid);
|
|
|
return 0;
|
|
@@ -3539,10 +3873,16 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
|
|
unsigned long flags;
|
|
|
struct scsi_target *starget = scmd->device->sdev_target;
|
|
|
struct MPT2SAS_TARGET *priv_target = starget->hostdata;
|
|
|
+ char *device_str = NULL;
|
|
|
|
|
|
if (!priv_target)
|
|
|
return;
|
|
|
|
|
|
+ if (ioc->hide_ir_msg)
|
|
|
+ device_str = "WarpDrive";
|
|
|
+ else
|
|
|
+ device_str = "volume";
|
|
|
+
|
|
|
if (log_info == 0x31170000)
|
|
|
return;
|
|
|
|
|
@@ -3659,8 +3999,8 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
|
|
scsi_print_command(scmd);
|
|
|
|
|
|
if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
|
|
|
- printk(MPT2SAS_WARN_FMT "\tvolume wwid(0x%016llx)\n", ioc->name,
|
|
|
- (unsigned long long)priv_target->sas_address);
|
|
|
+ printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
|
|
|
+ device_str, (unsigned long long)priv_target->sas_address);
|
|
|
} else {
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
|
|
@@ -3839,6 +4179,20 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
scmd->result = DID_NO_CONNECT << 16;
|
|
|
goto out;
|
|
|
}
|
|
|
+ /*
|
|
|
+ * WARPDRIVE: If direct_io is set then it is directIO,
|
|
|
+ * the failed direct I/O should be redirected to volume
|
|
|
+ */
|
|
|
+ if (_scsih_scsi_direct_io_get(ioc, smid)) {
|
|
|
+ _scsih_scsi_direct_io_set(ioc, smid, 0);
|
|
|
+ memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
|
|
|
+ mpi_request->DevHandle =
|
|
|
+ cpu_to_le16(sas_device_priv_data->sas_target->handle);
|
|
|
+ mpt2sas_base_put_smid_scsi_io(ioc, smid,
|
|
|
+ sas_device_priv_data->sas_target->handle);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/* turning off TLR */
|
|
|
scsi_state = mpi_reply->SCSIState;
|
|
@@ -3847,7 +4201,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|
|
le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
|
|
|
if (!sas_device_priv_data->tlr_snoop_check) {
|
|
|
sas_device_priv_data->tlr_snoop_check++;
|
|
|
- if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
|
|
|
+ /* Make sure Device is not raid volume.
|
|
|
+ * We do not expose raid functionality to upper layer for warpdrive.
|
|
|
+ */
|
|
|
+ if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
|
|
|
sas_is_tlr_enabled(scmd->device) &&
|
|
|
response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
|
|
|
sas_disable_tlr(scmd->device);
|
|
@@ -4680,8 +5037,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
|
|
|
|
|
|
_scsih_ublock_io_device(ioc, sas_device_backup.handle);
|
|
|
|
|
|
- mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address,
|
|
|
- sas_device_backup.sas_address_parent);
|
|
|
+ if (!ioc->hide_drives)
|
|
|
+ mpt2sas_transport_port_remove(ioc,
|
|
|
+ sas_device_backup.sas_address,
|
|
|
+ sas_device_backup.sas_address_parent);
|
|
|
|
|
|
printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
|
|
|
"(0x%016llx)\n", ioc->name, sas_device_backup.handle,
|
|
@@ -5412,6 +5771,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
|
|
|
&sas_device->volume_wwid);
|
|
|
set_bit(handle, ioc->pd_handles);
|
|
|
_scsih_reprobe_target(sas_device->starget, 1);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -5590,7 +5950,8 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
|
|
|
Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
|
|
|
|
|
|
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
|
|
|
- if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
|
|
|
+ if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
|
|
|
+ && !ioc->hide_ir_msg)
|
|
|
_scsih_sas_ir_config_change_event_debug(ioc, event_data);
|
|
|
|
|
|
#endif
|
|
@@ -5613,16 +5974,20 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
|
|
|
le16_to_cpu(element->VolDevHandle));
|
|
|
break;
|
|
|
case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
|
|
|
- _scsih_sas_pd_hide(ioc, element);
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ _scsih_sas_pd_hide(ioc, element);
|
|
|
break;
|
|
|
case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
|
|
|
- _scsih_sas_pd_expose(ioc, element);
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ _scsih_sas_pd_expose(ioc, element);
|
|
|
break;
|
|
|
case MPI2_EVENT_IR_CHANGE_RC_HIDE:
|
|
|
- _scsih_sas_pd_add(ioc, element);
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ _scsih_sas_pd_add(ioc, element);
|
|
|
break;
|
|
|
case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
|
|
|
- _scsih_sas_pd_delete(ioc, element);
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ _scsih_sas_pd_delete(ioc, element);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -5653,9 +6018,10 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
|
|
|
|
|
|
handle = le16_to_cpu(event_data->VolDevHandle);
|
|
|
state = le32_to_cpu(event_data->NewValue);
|
|
|
- dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
|
|
|
- "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
|
|
|
- le32_to_cpu(event_data->PreviousValue), state));
|
|
|
+ if (!ioc->hide_ir_msg)
|
|
|
+ dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
|
|
|
+ "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
|
|
|
+ le32_to_cpu(event_data->PreviousValue), state));
|
|
|
|
|
|
switch (state) {
|
|
|
case MPI2_RAID_VOL_STATE_MISSING:
|
|
@@ -5735,9 +6101,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
|
|
|
handle = le16_to_cpu(event_data->PhysDiskDevHandle);
|
|
|
state = le32_to_cpu(event_data->NewValue);
|
|
|
|
|
|
- dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
|
|
|
- "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
|
|
|
- le32_to_cpu(event_data->PreviousValue), state));
|
|
|
+ if (!ioc->hide_ir_msg)
|
|
|
+ dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
|
|
|
+ "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
|
|
|
+ le32_to_cpu(event_data->PreviousValue), state));
|
|
|
|
|
|
switch (state) {
|
|
|
case MPI2_RAID_PD_STATE_ONLINE:
|
|
@@ -5746,7 +6113,8 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
|
|
|
case MPI2_RAID_PD_STATE_OPTIMAL:
|
|
|
case MPI2_RAID_PD_STATE_HOT_SPARE:
|
|
|
|
|
|
- set_bit(handle, ioc->pd_handles);
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ set_bit(handle, ioc->pd_handles);
|
|
|
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
|
@@ -5850,7 +6218,8 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
|
|
|
u16 handle;
|
|
|
|
|
|
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
|
|
|
- if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
|
|
|
+ if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
|
|
|
+ && !ioc->hide_ir_msg)
|
|
|
_scsih_sas_ir_operation_status_event_debug(ioc,
|
|
|
event_data);
|
|
|
#endif
|
|
@@ -5909,7 +6278,7 @@ static void
|
|
|
_scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
|
|
|
u16 slot, u16 handle)
|
|
|
{
|
|
|
- struct MPT2SAS_TARGET *sas_target_priv_data;
|
|
|
+ struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
|
|
|
struct scsi_target *starget;
|
|
|
struct _sas_device *sas_device;
|
|
|
unsigned long flags;
|
|
@@ -5917,7 +6286,7 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
|
|
|
if (sas_device->sas_address == sas_address &&
|
|
|
- sas_device->slot == slot && sas_device->starget) {
|
|
|
+ sas_device->slot == slot) {
|
|
|
sas_device->responding = 1;
|
|
|
starget = sas_device->starget;
|
|
|
if (starget && starget->hostdata) {
|
|
@@ -5926,13 +6295,15 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
|
|
|
sas_target_priv_data->deleted = 0;
|
|
|
} else
|
|
|
sas_target_priv_data = NULL;
|
|
|
- starget_printk(KERN_INFO, sas_device->starget,
|
|
|
- "handle(0x%04x), sas_addr(0x%016llx), enclosure "
|
|
|
- "logical id(0x%016llx), slot(%d)\n", handle,
|
|
|
- (unsigned long long)sas_device->sas_address,
|
|
|
- (unsigned long long)
|
|
|
- sas_device->enclosure_logical_id,
|
|
|
- sas_device->slot);
|
|
|
+ if (starget)
|
|
|
+ starget_printk(KERN_INFO, starget,
|
|
|
+ "handle(0x%04x), sas_addr(0x%016llx), "
|
|
|
+ "enclosure logical id(0x%016llx), "
|
|
|
+ "slot(%d)\n", handle,
|
|
|
+ (unsigned long long)sas_device->sas_address,
|
|
|
+ (unsigned long long)
|
|
|
+ sas_device->enclosure_logical_id,
|
|
|
+ sas_device->slot);
|
|
|
if (sas_device->handle == handle)
|
|
|
goto out;
|
|
|
printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
|
|
@@ -6024,6 +6395,12 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
|
|
|
starget_printk(KERN_INFO, raid_device->starget,
|
|
|
"handle(0x%04x), wwid(0x%016llx)\n", handle,
|
|
|
(unsigned long long)raid_device->wwid);
|
|
|
+ /*
|
|
|
+ * WARPDRIVE: The handles of the PDs might have changed
|
|
|
+ * across the host reset so re-initialize the
|
|
|
+ * required data for Direct IO
|
|
|
+ */
|
|
|
+ _scsih_init_warpdrive_properties(ioc, raid_device);
|
|
|
if (raid_device->handle == handle)
|
|
|
goto out;
|
|
|
printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
|
|
@@ -6085,18 +6462,20 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
}
|
|
|
|
|
|
/* refresh the pd_handles */
|
|
|
- phys_disk_num = 0xFF;
|
|
|
- memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
|
|
|
- while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
|
|
|
- &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
|
|
|
- phys_disk_num))) {
|
|
|
- ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
- MPI2_IOCSTATUS_MASK;
|
|
|
- if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
- break;
|
|
|
- phys_disk_num = pd_pg0.PhysDiskNum;
|
|
|
- handle = le16_to_cpu(pd_pg0.DevHandle);
|
|
|
- set_bit(handle, ioc->pd_handles);
|
|
|
+ if (!ioc->is_warpdrive) {
|
|
|
+ phys_disk_num = 0xFF;
|
|
|
+ memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
|
|
|
+ while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
|
|
|
+ &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
|
|
|
+ phys_disk_num))) {
|
|
|
+ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
|
|
+ MPI2_IOCSTATUS_MASK;
|
|
|
+ if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
|
|
+ break;
|
|
|
+ phys_disk_num = pd_pg0.PhysDiskNum;
|
|
|
+ handle = le16_to_cpu(pd_pg0.DevHandle);
|
|
|
+ set_bit(handle, ioc->pd_handles);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -6241,6 +6620,50 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * _scsih_hide_unhide_sas_devices - add/remove device to/from OS
|
|
|
+ * @ioc: per adapter object
|
|
|
+ *
|
|
|
+ * Return nothing.
|
|
|
+ */
|
|
|
+static void
|
|
|
+_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
+{
|
|
|
+ struct _sas_device *sas_device, *sas_device_next;
|
|
|
+
|
|
|
+ if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag !=
|
|
|
+ MFG_PAGE10_HIDE_IF_VOL_PRESENT)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (ioc->hide_drives) {
|
|
|
+ if (_scsih_get_num_volumes(ioc))
|
|
|
+ return;
|
|
|
+ ioc->hide_drives = 0;
|
|
|
+ list_for_each_entry_safe(sas_device, sas_device_next,
|
|
|
+ &ioc->sas_device_list, list) {
|
|
|
+ if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
|
|
|
+ sas_device->sas_address_parent)) {
|
|
|
+ _scsih_sas_device_remove(ioc, sas_device);
|
|
|
+ } else if (!sas_device->starget) {
|
|
|
+ mpt2sas_transport_port_remove(ioc,
|
|
|
+ sas_device->sas_address,
|
|
|
+ sas_device->sas_address_parent);
|
|
|
+ _scsih_sas_device_remove(ioc, sas_device);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!_scsih_get_num_volumes(ioc))
|
|
|
+ return;
|
|
|
+ ioc->hide_drives = 1;
|
|
|
+ list_for_each_entry_safe(sas_device, sas_device_next,
|
|
|
+ &ioc->sas_device_list, list) {
|
|
|
+ mpt2sas_transport_port_remove(ioc,
|
|
|
+ sas_device->sas_address,
|
|
|
+ sas_device->sas_address_parent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
|
|
|
* @ioc: per adapter object
|
|
@@ -6325,6 +6748,7 @@ _firmware_event_work(struct work_struct *work)
|
|
|
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
|
|
|
flags);
|
|
|
_scsih_remove_unresponding_sas_devices(ioc);
|
|
|
+ _scsih_hide_unhide_sas_devices(ioc);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -6424,6 +6848,53 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
|
|
(Mpi2EventDataIrVolume_t *)
|
|
|
mpi_reply->EventData);
|
|
|
break;
|
|
|
+ case MPI2_EVENT_LOG_ENTRY_ADDED:
|
|
|
+ {
|
|
|
+ Mpi2EventDataLogEntryAdded_t *log_entry;
|
|
|
+ u32 *log_code;
|
|
|
+
|
|
|
+ if (!ioc->is_warpdrive)
|
|
|
+ break;
|
|
|
+
|
|
|
+ log_entry = (Mpi2EventDataLogEntryAdded_t *)
|
|
|
+ mpi_reply->EventData;
|
|
|
+ log_code = (u32 *)log_entry->LogData;
|
|
|
+
|
|
|
+ if (le16_to_cpu(log_entry->LogEntryQualifier)
|
|
|
+ != MPT2_WARPDRIVE_LOGENTRY)
|
|
|
+ break;
|
|
|
+
|
|
|
+ switch (le32_to_cpu(*log_code)) {
|
|
|
+ case MPT2_WARPDRIVE_LC_SSDT:
|
|
|
+ printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
|
|
|
+ "IO Throttling has occurred in the WarpDrive "
|
|
|
+ "subsystem. Check WarpDrive documentation for "
|
|
|
+ "additional details.\n", ioc->name);
|
|
|
+ break;
|
|
|
+ case MPT2_WARPDRIVE_LC_SSDLW:
|
|
|
+ printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
|
|
|
+ "Program/Erase Cycles for the WarpDrive subsystem "
|
|
|
+ "in degraded range. Check WarpDrive documentation "
|
|
|
+ "for additional details.\n", ioc->name);
|
|
|
+ break;
|
|
|
+ case MPT2_WARPDRIVE_LC_SSDLF:
|
|
|
+ printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
|
|
|
+ "There are no Program/Erase Cycles for the "
|
|
|
+ "WarpDrive subsystem. The storage device will be "
|
|
|
+ "in read-only mode. Check WarpDrive documentation "
|
|
|
+ "for additional details.\n", ioc->name);
|
|
|
+ break;
|
|
|
+ case MPT2_WARPDRIVE_LC_BRMF:
|
|
|
+ printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
|
|
|
+ "The Backup Rail Monitor has failed on the "
|
|
|
+ "WarpDrive subsystem. Check WarpDrive "
|
|
|
+ "documentation for additional details.\n",
|
|
|
+ ioc->name);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
|
|
case MPI2_EVENT_IR_OPERATION_STATUS:
|
|
|
case MPI2_EVENT_SAS_DISCOVERY:
|
|
@@ -6582,7 +7053,8 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
|
|
|
mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
|
|
|
mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
|
|
|
|
|
|
- printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
|
|
|
+ if (!ioc->hide_ir_msg)
|
|
|
+ printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
|
|
|
init_completion(&ioc->scsih_cmds.done);
|
|
|
mpt2sas_base_put_smid_default(ioc, smid);
|
|
|
wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
|
|
@@ -6596,10 +7068,11 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
|
|
|
if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
|
|
|
mpi_reply = ioc->scsih_cmds.reply;
|
|
|
|
|
|
- printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
|
|
|
- "ioc_status(0x%04x), loginfo(0x%08x)\n",
|
|
|
- ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
|
|
|
- le32_to_cpu(mpi_reply->IOCLogInfo));
|
|
|
+ if (!ioc->hide_ir_msg)
|
|
|
+ printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
|
|
|
+ "ioc_status(0x%04x), loginfo(0x%08x)\n",
|
|
|
+ ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
|
|
|
+ le32_to_cpu(mpi_reply->IOCLogInfo));
|
|
|
}
|
|
|
|
|
|
out:
|
|
@@ -6758,6 +7231,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
|
|
|
spin_lock_irqsave(&ioc->sas_device_lock, flags);
|
|
|
list_move_tail(&sas_device->list, &ioc->sas_device_list);
|
|
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
|
+
|
|
|
+ if (ioc->hide_drives)
|
|
|
+ return;
|
|
|
if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
|
|
|
sas_device->sas_address_parent)) {
|
|
|
_scsih_sas_device_remove(ioc, sas_device);
|
|
@@ -6811,6 +7287,9 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
|
|
|
list_move_tail(&sas_device->list, &ioc->sas_device_list);
|
|
|
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
|
|
|
|
|
|
+ if (ioc->hide_drives)
|
|
|
+ continue;
|
|
|
+
|
|
|
if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
|
|
|
sas_device->sas_address_parent)) {
|
|
|
_scsih_sas_device_remove(ioc, sas_device);
|
|
@@ -6881,6 +7360,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
ioc->id = mpt_ids++;
|
|
|
sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id);
|
|
|
ioc->pdev = pdev;
|
|
|
+ if (id->device == MPI2_MFGPAGE_DEVID_SSS6200) {
|
|
|
+ ioc->is_warpdrive = 1;
|
|
|
+ ioc->hide_ir_msg = 1;
|
|
|
+ } else
|
|
|
+ ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
|
|
|
ioc->scsi_io_cb_idx = scsi_io_cb_idx;
|
|
|
ioc->tm_cb_idx = tm_cb_idx;
|
|
|
ioc->ctl_cb_idx = ctl_cb_idx;
|
|
@@ -6946,6 +7430,20 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
}
|
|
|
|
|
|
ioc->wait_for_port_enable_to_complete = 0;
|
|
|
+ if (ioc->is_warpdrive) {
|
|
|
+ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
|
|
|
+ ioc->hide_drives = 0;
|
|
|
+ else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS)
|
|
|
+ ioc->hide_drives = 1;
|
|
|
+ else {
|
|
|
+ if (_scsih_get_num_volumes(ioc))
|
|
|
+ ioc->hide_drives = 1;
|
|
|
+ else
|
|
|
+ ioc->hide_drives = 0;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ ioc->hide_drives = 0;
|
|
|
+
|
|
|
_scsih_probe_devices(ioc);
|
|
|
return 0;
|
|
|
|