Commit 0bdccdb0 authored by Kashyap, Desai's avatar Kashyap, Desai Committed by James Bottomley

[SCSI] mpt2sas : WarpDrive New product SSS6200 support added

This patch has Support for the new solid state device product SSS6200
from LSI and relavent features w.r.t SSS6200.

The major feature added in this driver is supporting Direct-I/O to the
SSS6200 storage.There are some additional changes done to avoid exposing
the RAID member disks to the OS and hiding/exposing drives based on the
OEM Specific Flag in Manufacturing Page10 (this is required to handle
specific changes in the SSS6200 firmware).

Each and every changes are listed below.
1. Hiding IR related messages.
For SSS6200, the driver is modified not to print IR related events.
Even if the debugging is enabled the IR related messages will not be displayed.
In some places if there is a need to display a message related to IR the
string "IR" is replaced with string "DD" and the string "volume" is replaced
with "direct drive". But the function names are not changed hence there are
some places where the reference to volume can be seen if debug level is set.

2. Removed RAID transport support
In Linux the user can retrieve RAID volume information from the sysfs directory.
This support is removed for SSS6200.

3. Direct I/O support.
The driver tries to enable direct I/O when a volume is reported to the driver
by the firmware through IRCC events and the driver does this just before
reporting to the OS, hence all the OS issued I/O can go through direct path
if they can, The first validation is to see whether the manufacturing page10
flag is set to expose all drives always. If that is set, the driver will not
enable direct I/O and displays the message "DDIO" is disabled globally as
drives are exposed. The driver checks whether there is more than one volume
in the controller, if so the direct I/O will be disabled globally for all
volumes in the controller and the message displayed will be "DDIO is disabled
globally as number of drives > 1.
If retrieving number of PD is failed the driver will not enable direct I/O
and displays the message Failure in computing number of drives DDIO disabled.
If memory allocation for RAIDVolumePage0 is failed, the driver will not enable
direct I/O and displays the message Memory allocation failure for
RVPG0 DDIO disabled.  If retrieving RAIDVolumePage0 is failed the driver will
not enable direct I/O and displays the message Failure in retrieving
RVPG0 DDIO disabled

If the number of PD in a volume is greater than 8, then the direct I/O will
be disabled.
If any of individual drives handle retrieval is failed then the DD-IO will
be disabled.
If the volume is not RAID0 or if the block size is not 512 then the DD-IO will
be disabled.
If the volume size is greater than 2TB then the DD-IO will be disabled.
If the driver is not able to find a valid stripe exponent using the configured
stripe size then the DD-IO will be disabled

When the DD-IO is enabled the driver will check every I/O request issued to
the storage and checks whether the request is either
READ6/WRITE6/READ10/WRITE10, if it is and if the complete I/O transfer
is within a stripe size then the I/O is redirected to
the drive directly instead of the volume.

On completion of every I/O, if the completion is failure means if the reply
is address reply with a reply frame associated with it, then the type of I/O
will be checked, if the I/O is direct then the I/O will be retried to
the volume once.
Signed-off-by: default avatarKashyap Desai <kashyap.desai@lsi.com>
Reviewed-by: default avatarEric Moore <eric.moore@lsi.com>
Reviewed-by: default avatarSathya Prakash <sathya.prakash@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent aeaeb5ce
...@@ -522,6 +522,7 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, ...@@ -522,6 +522,7 @@ _base_display_event_data(struct MPT2SAS_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:
...@@ -553,15 +554,19 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc, ...@@ -553,15 +554,19 @@ _base_display_event_data(struct MPT2SAS_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;
} }
...@@ -616,7 +621,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) ...@@ -616,7 +621,10 @@ _base_sas_log_info(struct MPT2SAS_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;
} }
...@@ -1508,6 +1516,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid) ...@@ -1508,6 +1516,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_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_tail(&ioc->scsi_lookup[i].tracker_list, list_add_tail(&ioc->scsi_lookup[i].tracker_list,
&ioc->free_list); &ioc->free_list);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
...@@ -1844,11 +1853,13 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) ...@@ -1844,11 +1853,13 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
printk("), "); printk("), ");
printk("Capabilities=("); printk("Capabilities=(");
if (!ioc->hide_ir_msg) {
if (ioc->facts.IOCCapabilities & if (ioc->facts.IOCCapabilities &
MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
printk("Raid"); printk("Raid");
i++; i++;
} }
}
if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
printk("%sTLR", i ? "," : ""); printk("%sTLR", i ? "," : "");
...@@ -3680,6 +3691,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -3680,6 +3691,7 @@ _base_make_ioc_operational(struct MPT2SAS_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;
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
__func__)); __func__));
...@@ -3706,6 +3718,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -3706,6 +3718,7 @@ _base_make_ioc_operational(struct MPT2SAS_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);
} }
...@@ -3766,6 +3779,15 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -3766,6 +3779,15 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
if (sleep_flag == CAN_SLEEP) if (sleep_flag == CAN_SLEEP)
_base_static_config_pages(ioc); _base_static_config_pages(ioc);
if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) {
if (ioc->manu_pg10.OEMIdentifier == 0x80) {
hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
MFG_PAGE10_HIDE_SSDS_MASK);
if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
ioc->mfg_pg10_hide_flag = hide_flag;
}
}
if (ioc->wait_for_port_enable_to_complete) { if (ioc->wait_for_port_enable_to_complete) {
if (diag_buffer_enable != 0) if (diag_buffer_enable != 0)
mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
......
...@@ -69,11 +69,11 @@ ...@@ -69,11 +69,11 @@
#define MPT2SAS_DRIVER_NAME "mpt2sas" #define MPT2SAS_DRIVER_NAME "mpt2sas"
#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" #define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
#define MPT2SAS_DRIVER_VERSION "08.100.00.00" #define MPT2SAS_DRIVER_VERSION "08.100.00.01"
#define MPT2SAS_MAJOR_VERSION 08 #define MPT2SAS_MAJOR_VERSION 08
#define MPT2SAS_MINOR_VERSION 100 #define MPT2SAS_MINOR_VERSION 100
#define MPT2SAS_BUILD_VERSION 00 #define MPT2SAS_BUILD_VERSION 00
#define MPT2SAS_RELEASE_VERSION 00 #define MPT2SAS_RELEASE_VERSION 01
/* /*
* Set MPT2SAS_SG_DEPTH value based on user input. * Set MPT2SAS_SG_DEPTH value based on user input.
...@@ -188,6 +188,16 @@ ...@@ -188,6 +188,16 @@
#define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID 0x0044 #define MPT2SAS_HP_EMBEDDED_2_4_INTERNAL_SSDID 0x0044
#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 #define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046
/*
* 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
*/ */
...@@ -199,6 +209,7 @@ ...@@ -199,6 +209,7 @@
* struct MPT2SAS_TARGET - starget private hostdata * struct MPT2SAS_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
...@@ -208,6 +219,7 @@ ...@@ -208,6 +219,7 @@
struct MPT2SAS_TARGET { struct MPT2SAS_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;
...@@ -215,6 +227,7 @@ struct MPT2SAS_TARGET { ...@@ -215,6 +227,7 @@ struct MPT2SAS_TARGET {
u8 tm_busy; u8 tm_busy;
}; };
/* /*
* per device private data * per device private data
*/ */
...@@ -262,6 +275,12 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_10 { ...@@ -262,6 +275,12 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_10 {
MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10,
Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t; Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t;
#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 MPT2SAS_DEVICE { struct MPT2SAS_DEVICE {
struct MPT2SAS_TARGET *sas_target; struct MPT2SAS_TARGET *sas_target;
unsigned int lun; unsigned int lun;
...@@ -341,6 +360,7 @@ struct _sas_device { ...@@ -341,6 +360,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
...@@ -348,20 +368,33 @@ struct _sas_device { ...@@ -348,20 +368,33 @@ 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
* @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
struct _raid_device { struct _raid_device {
struct list_head list; struct list_head list;
struct scsi_target *starget; struct scsi_target *starget;
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;
u32 device_info;
u8 num_pds; u8 num_pds;
u8 responding; u8 responding;
u8 percent_complete; u8 percent_complete;
u8 direct_io_enabled;
u8 stripe_exponent;
u64 max_lba;
u32 stripe_sz;
u32 device_info;
u16 pd_handle[MPT_MAX_WARPDRIVE_PDS];
}; };
/** /**
...@@ -470,6 +503,7 @@ struct chain_tracker { ...@@ -470,6 +503,7 @@ 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)
* @chain_list: list of chains associated to this IO * @chain_list: list of chains associated to this IO
* @tracker_list: list of free request (ioc->free_list) * @tracker_list: list of free request (ioc->free_list)
*/ */
...@@ -477,14 +511,14 @@ struct scsiio_tracker { ...@@ -477,14 +511,14 @@ 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;
}; };
/** /**
* struct request_tracker - misc mf request tracker * struct request_tracker - firmware request tracker
* @smid: system message id * @smid: system message id
* @scmd: scsi request pointer
* @cb_idx: callback index * @cb_idx: callback index
* @tracker_list: list of free request (ioc->free_list) * @tracker_list: list of free request (ioc->free_list)
*/ */
...@@ -832,6 +866,11 @@ struct MPT2SAS_ADAPTER { ...@@ -832,6 +866,11 @@ struct MPT2SAS_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;
}; };
typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
......
...@@ -1034,6 +1034,9 @@ _ctl_getiocinfo(void __user *arg) ...@@ -1034,6 +1034,9 @@ _ctl_getiocinfo(void __user *arg)
__func__)); __func__));
memset(&karg, 0 , sizeof(karg)); memset(&karg, 0 , sizeof(karg));
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;
if (ioc->pfacts) if (ioc->pfacts)
karg.port_number = ioc->pfacts[0].PortNumber; karg.port_number = ioc->pfacts[0].PortNumber;
......
...@@ -133,6 +133,7 @@ struct mpt2_ioctl_pci_info { ...@@ -133,6 +133,7 @@ struct mpt2_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 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