Commit 7786ab6a authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen

mpt3sas: Ported WarpDrive product SSS6200 support

Ported the following list of WarpDrive-specific patches:

1. commit 0bdccdb0 ("mpt2sas: WarpDrive
   New product SSS6200 support added")

2. commit 82a45258 ("mpt2sas: WarpDrive
   Infinite command retries due to wrong scsi command entry in MPI
   message")

3. commit ba96bd0b ("mpt2sas: Support
   for greater than 2TB capacity WarpDrive")

4. commit 4da7af94 ("mpt2sas: Do not
   retry a timed out direct IO for Warpdrive")

5. commit daeaa9df ("mpt2sas: Avoid type
   casting for direct I/O commands").

Also set the mpt2_ioctl_iocinfo adapter_type to:

1. MPT3_IOCTL_INTERFACE_SAS3 for Gen3 HBAs

2. MPT2_IOCTL_INTERFACE_SAS2_SSS6200 for Warp Drive

3. MPT2_IOCTL_INTERFACE_SAS2  for other Gen2 HBAs
Signed-off-by: default avatarSreekanth Reddy <Sreekanth.Reddy@avagotech.com>
Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 16e179bd
This diff is collapsed.
...@@ -593,6 +593,7 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc, ...@@ -593,6 +593,7 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
desc = "Device Status Change"; desc = "Device Status Change";
break; break;
case MPI2_EVENT_IR_OPERATION_STATUS: case MPI2_EVENT_IR_OPERATION_STATUS:
if (!ioc->hide_ir_msg)
desc = "IR Operation Status"; desc = "IR Operation Status";
break; break;
case MPI2_EVENT_SAS_DISCOVERY: case MPI2_EVENT_SAS_DISCOVERY:
...@@ -624,15 +625,19 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc, ...@@ -624,15 +625,19 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
desc = "SAS Enclosure Device Status Change"; desc = "SAS Enclosure Device Status Change";
break; break;
case MPI2_EVENT_IR_VOLUME: case MPI2_EVENT_IR_VOLUME:
if (!ioc->hide_ir_msg)
desc = "IR Volume"; desc = "IR Volume";
break; break;
case MPI2_EVENT_IR_PHYSICAL_DISK: case MPI2_EVENT_IR_PHYSICAL_DISK:
if (!ioc->hide_ir_msg)
desc = "IR Physical Disk"; desc = "IR Physical Disk";
break; break;
case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
if (!ioc->hide_ir_msg)
desc = "IR Configuration Change List"; desc = "IR Configuration Change List";
break; break;
case MPI2_EVENT_LOG_ENTRY_ADDED: case MPI2_EVENT_LOG_ENTRY_ADDED:
if (!ioc->hide_ir_msg)
desc = "Log Entry Added"; desc = "Log Entry Added";
break; break;
case MPI2_EVENT_TEMP_THRESHOLD: case MPI2_EVENT_TEMP_THRESHOLD:
...@@ -689,7 +694,10 @@ _base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info) ...@@ -689,7 +694,10 @@ _base_sas_log_info(struct MPT3SAS_ADAPTER *ioc , u32 log_info)
originator_str = "PL"; originator_str = "PL";
break; break;
case 2: case 2:
if (!ioc->hide_ir_msg)
originator_str = "IR"; originator_str = "IR";
else
originator_str = "WarpDrive";
break; break;
} }
...@@ -1023,6 +1031,12 @@ _base_interrupt(int irq, void *bus_id) ...@@ -1023,6 +1031,12 @@ _base_interrupt(int irq, void *bus_id)
} }
wmb(); wmb();
if (ioc->is_warpdrive) {
writel(reply_q->reply_post_host_index,
ioc->reply_post_host_index[msix_index]);
atomic_dec(&reply_q->busy);
return IRQ_HANDLED;
}
/* Update Reply Post Host Index. /* Update Reply Post Host Index.
* For those HBA's which support combined reply queue feature * For those HBA's which support combined reply queue feature
...@@ -2333,6 +2347,7 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid) ...@@ -2333,6 +2347,7 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid)
} }
ioc->scsi_lookup[i].cb_idx = 0xFF; ioc->scsi_lookup[i].cb_idx = 0xFF;
ioc->scsi_lookup[i].scmd = NULL; ioc->scsi_lookup[i].scmd = NULL;
ioc->scsi_lookup[i].direct_io = 0;
list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list); list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
...@@ -2683,11 +2698,13 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) ...@@ -2683,11 +2698,13 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc)
pr_info("), "); pr_info("), ");
pr_info("Capabilities=("); pr_info("Capabilities=(");
if (!ioc->hide_ir_msg) {
if (ioc->facts.IOCCapabilities & if (ioc->facts.IOCCapabilities &
MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
pr_info("Raid"); pr_info("Raid");
i++; i++;
} }
}
if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
pr_info("%sTLR", i ? "," : ""); pr_info("%sTLR", i ? "," : "");
...@@ -4834,6 +4851,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ...@@ -4834,6 +4851,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
u32 reply_address; u32 reply_address;
u16 smid; u16 smid;
struct _tr_list *delayed_tr, *delayed_tr_next; struct _tr_list *delayed_tr, *delayed_tr_next;
u8 hide_flag;
struct adapter_reply_queue *reply_q; struct adapter_reply_queue *reply_q;
long reply_post_free; long reply_post_free;
u32 reply_post_free_sz, index = 0; u32 reply_post_free_sz, index = 0;
...@@ -4864,6 +4882,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ...@@ -4864,6 +4882,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
ioc->scsi_lookup[i].cb_idx = 0xFF; ioc->scsi_lookup[i].cb_idx = 0xFF;
ioc->scsi_lookup[i].smid = smid; ioc->scsi_lookup[i].smid = smid;
ioc->scsi_lookup[i].scmd = NULL; ioc->scsi_lookup[i].scmd = NULL;
ioc->scsi_lookup[i].direct_io = 0;
list_add_tail(&ioc->scsi_lookup[i].tracker_list, list_add_tail(&ioc->scsi_lookup[i].tracker_list,
&ioc->free_list); &ioc->free_list);
} }
...@@ -4966,6 +4985,16 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) ...@@ -4966,6 +4985,16 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
if (ioc->is_driver_loading) { if (ioc->is_driver_loading) {
if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier
== 0x80) {
hide_flag = (u8) (
le32_to_cpu(ioc->manu_pg10.OEMSpecificFlags0) &
MFG_PAGE10_HIDE_SSDS_MASK);
if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
ioc->mfg_pg10_hide_flag = hide_flag;
}
ioc->wait_for_discovery_to_complete = ioc->wait_for_discovery_to_complete =
_base_determine_wait_on_discovery(ioc); _base_determine_wait_on_discovery(ioc);
...@@ -5032,12 +5061,33 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ...@@ -5032,12 +5061,33 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
goto out_free_resources; goto out_free_resources;
} }
if (ioc->is_warpdrive) {
ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz,
sizeof(resource_size_t *), GFP_KERNEL);
if (!ioc->reply_post_host_index) {
dfailprintk(ioc, pr_info(MPT3SAS_FMT "allocation "
"for cpu_msix_table failed!!!\n", ioc->name));
r = -ENOMEM;
goto out_free_resources;
}
}
ioc->rdpq_array_enable_assigned = 0; ioc->rdpq_array_enable_assigned = 0;
ioc->dma_mask = 0; ioc->dma_mask = 0;
r = mpt3sas_base_map_resources(ioc); r = mpt3sas_base_map_resources(ioc);
if (r) if (r)
goto out_free_resources; goto out_free_resources;
if (ioc->is_warpdrive) {
ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
&ioc->chip->ReplyPostHostIndex;
for (i = 1; i < ioc->cpu_msix_table_sz; i++)
ioc->reply_post_host_index[i] =
(resource_size_t __iomem *)
((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
* 4)));
}
pci_set_drvdata(ioc->pdev, ioc->shost); pci_set_drvdata(ioc->pdev, ioc->shost);
r = _base_get_ioc_facts(ioc, CAN_SLEEP); r = _base_get_ioc_facts(ioc, CAN_SLEEP);
...@@ -5189,6 +5239,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ...@@ -5189,6 +5239,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_release_memory_pools(ioc); _base_release_memory_pools(ioc);
pci_set_drvdata(ioc->pdev, NULL); pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table); kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
kfree(ioc->reply_post_host_index);
kfree(ioc->pd_handles); kfree(ioc->pd_handles);
kfree(ioc->blocking_handles); kfree(ioc->blocking_handles);
kfree(ioc->tm_cmds.reply); kfree(ioc->tm_cmds.reply);
...@@ -5228,6 +5280,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc) ...@@ -5228,6 +5280,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
_base_release_memory_pools(ioc); _base_release_memory_pools(ioc);
pci_set_drvdata(ioc->pdev, NULL); pci_set_drvdata(ioc->pdev, NULL);
kfree(ioc->cpu_msix_table); kfree(ioc->cpu_msix_table);
if (ioc->is_warpdrive)
kfree(ioc->reply_post_host_index);
kfree(ioc->pd_handles); kfree(ioc->pd_handles);
kfree(ioc->blocking_handles); kfree(ioc->blocking_handles);
kfree(ioc->pfacts); kfree(ioc->pfacts);
......
...@@ -134,6 +134,16 @@ ...@@ -134,6 +134,16 @@
*/ */
#define MPT3SAS_FMT "%s: " #define MPT3SAS_FMT "%s: "
/*
* WarpDrive Specific Log codes
*/
#define MPT2_WARPDRIVE_LOGENTRY (0x8002)
#define MPT2_WARPDRIVE_LC_SSDT (0x41)
#define MPT2_WARPDRIVE_LC_SSDLW (0x43)
#define MPT2_WARPDRIVE_LC_SSDLF (0x44)
#define MPT2_WARPDRIVE_LC_BRMF (0x4D)
/* /*
* per target private data * per target private data
*/ */
...@@ -257,6 +267,7 @@ struct Mpi2ManufacturingPage11_t { ...@@ -257,6 +267,7 @@ struct Mpi2ManufacturingPage11_t {
* struct MPT3SAS_TARGET - starget private hostdata * struct MPT3SAS_TARGET - starget private hostdata
* @starget: starget object * @starget: starget object
* @sas_address: target sas address * @sas_address: target sas address
* @raid_device: raid_device pointer to access volume data
* @handle: device handle * @handle: device handle
* @num_luns: number luns * @num_luns: number luns
* @flags: MPT_TARGET_FLAGS_XXX flags * @flags: MPT_TARGET_FLAGS_XXX flags
...@@ -266,6 +277,7 @@ struct Mpi2ManufacturingPage11_t { ...@@ -266,6 +277,7 @@ struct Mpi2ManufacturingPage11_t {
struct MPT3SAS_TARGET { struct MPT3SAS_TARGET {
struct scsi_target *starget; struct scsi_target *starget;
u64 sas_address; u64 sas_address;
struct _raid_device *raid_device;
u16 handle; u16 handle;
int num_luns; int num_luns;
u32 flags; u32 flags;
...@@ -280,6 +292,11 @@ struct MPT3SAS_TARGET { ...@@ -280,6 +292,11 @@ struct MPT3SAS_TARGET {
#define MPT_DEVICE_FLAGS_INIT 0x01 #define MPT_DEVICE_FLAGS_INIT 0x01
#define MPT_DEVICE_TLR_ON 0x02 #define MPT_DEVICE_TLR_ON 0x02
#define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003)
#define MFG_PAGE10_HIDE_ALL_DISKS (0x00)
#define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01)
#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02)
/** /**
* struct MPT3SAS_DEVICE - sdev private hostdata * struct MPT3SAS_DEVICE - sdev private hostdata
* @sas_target: starget private hostdata * @sas_target: starget private hostdata
...@@ -381,6 +398,7 @@ struct _sas_device { ...@@ -381,6 +398,7 @@ struct _sas_device {
* @sdev: scsi device struct (volumes are single lun) * @sdev: scsi device struct (volumes are single lun)
* @wwid: unique identifier for the volume * @wwid: unique identifier for the volume
* @handle: device handle * @handle: device handle
* @block_size: Block size of the volume
* @id: target id * @id: target id
* @channel: target channel * @channel: target channel
* @volume_type: the raid level * @volume_type: the raid level
...@@ -388,6 +406,13 @@ struct _sas_device { ...@@ -388,6 +406,13 @@ struct _sas_device {
* @num_pds: number of hidden raid components * @num_pds: number of hidden raid components
* @responding: used in _scsih_raid_device_mark_responding * @responding: used in _scsih_raid_device_mark_responding
* @percent_complete: resync percent complete * @percent_complete: resync percent complete
* @direct_io_enabled: Whether direct io to PDs are allowed or not
* @stripe_exponent: X where 2powX is the stripe sz in blocks
* @block_exponent: X where 2powX is the block sz in bytes
* @max_lba: Maximum number of LBA in the volume
* @stripe_sz: Stripe Size of the volume
* @device_info: Device info of the volume member disk
* @pd_handle: Array of handles of the physical drives for direct I/O in le16
*/ */
#define MPT_MAX_WARPDRIVE_PDS 8 #define MPT_MAX_WARPDRIVE_PDS 8
struct _raid_device { struct _raid_device {
...@@ -396,13 +421,20 @@ struct _raid_device { ...@@ -396,13 +421,20 @@ struct _raid_device {
struct scsi_device *sdev; struct scsi_device *sdev;
u64 wwid; u64 wwid;
u16 handle; u16 handle;
u16 block_sz;
int id; int id;
int channel; int channel;
u8 volume_type; u8 volume_type;
u8 num_pds; u8 num_pds;
u8 responding; u8 responding;
u8 percent_complete; u8 percent_complete;
u8 direct_io_enabled;
u8 stripe_exponent;
u8 block_exponent;
u64 max_lba;
u32 stripe_sz;
u32 device_info; u32 device_info;
u16 pd_handle[MPT_MAX_WARPDRIVE_PDS];
}; };
/** /**
...@@ -511,12 +543,14 @@ struct chain_tracker { ...@@ -511,12 +543,14 @@ struct chain_tracker {
* @smid: system message id * @smid: system message id
* @scmd: scsi request pointer * @scmd: scsi request pointer
* @cb_idx: callback index * @cb_idx: callback index
* @direct_io: To indicate whether I/O is direct (WARPDRIVE)
* @tracker_list: list of free request (ioc->free_list) * @tracker_list: list of free request (ioc->free_list)
*/ */
struct scsiio_tracker { struct scsiio_tracker {
u16 smid; u16 smid;
struct scsi_cmnd *scmd; struct scsi_cmnd *scmd;
u8 cb_idx; u8 cb_idx;
u8 direct_io;
struct list_head chain_list; struct list_head chain_list;
struct list_head tracker_list; struct list_head tracker_list;
}; };
...@@ -843,6 +877,7 @@ struct MPT3SAS_ADAPTER { ...@@ -843,6 +877,7 @@ struct MPT3SAS_ADAPTER {
u16 msix_vector_count; u16 msix_vector_count;
u8 *cpu_msix_table; u8 *cpu_msix_table;
u16 cpu_msix_table_sz; u16 cpu_msix_table_sz;
resource_size_t __iomem **reply_post_host_index;
u32 ioc_reset_count; u32 ioc_reset_count;
MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
u32 non_operational_loop; u32 non_operational_loop;
...@@ -1014,6 +1049,10 @@ struct MPT3SAS_ADAPTER { ...@@ -1014,6 +1049,10 @@ struct MPT3SAS_ADAPTER {
u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
u32 ring_buffer_offset; u32 ring_buffer_offset;
u32 ring_buffer_sz; u32 ring_buffer_sz;
u8 is_warpdrive;
u8 hide_ir_msg;
u8 mfg_pg10_hide_flag;
u8 hide_drives;
spinlock_t diag_trigger_lock; spinlock_t diag_trigger_lock;
u8 diag_trigger_active; u8 diag_trigger_active;
struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; struct SL_WH_MASTER_TRIGGER_T diag_trigger_master;
......
...@@ -1030,6 +1030,9 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) ...@@ -1030,6 +1030,9 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
strcat(karg.driver_version, "-"); strcat(karg.driver_version, "-");
switch (ioc->hba_mpi_version_belonged) { switch (ioc->hba_mpi_version_belonged) {
case MPI2_VERSION: case MPI2_VERSION:
if (ioc->is_warpdrive)
karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;
else
karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
break; break;
......
...@@ -141,6 +141,7 @@ struct mpt3_ioctl_pci_info { ...@@ -141,6 +141,7 @@ struct mpt3_ioctl_pci_info {
#define MPT2_IOCTL_INTERFACE_FC_IP (0x02) #define MPT2_IOCTL_INTERFACE_FC_IP (0x02)
#define MPT2_IOCTL_INTERFACE_SAS (0x03) #define MPT2_IOCTL_INTERFACE_SAS (0x03)
#define MPT2_IOCTL_INTERFACE_SAS2 (0x04) #define MPT2_IOCTL_INTERFACE_SAS2 (0x04)
#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05)
#define MPT3_IOCTL_INTERFACE_SAS3 (0x06) #define MPT3_IOCTL_INTERFACE_SAS3 (0x06)
#define MPT2_IOCTL_VERSION_LENGTH (32) #define MPT2_IOCTL_VERSION_LENGTH (32)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment