aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2011-04-07 03:02:49 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-05-01 11:36:54 -0400
commit0bdccdb0a090ad8dc5f851cad5e843244c410ee8 (patch)
tree9380059a38551f6b4e208f897a6f04760e6f101f
parentaeaeb5cec5a5477b392e627883fdb46d8a5dcc1f (diff)
[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: Kashyap Desai <kashyap.desai@lsi.com> Reviewed-by: Eric Moore <eric.moore@lsi.com> Reviewed-by: Sathya Prakash <sathya.prakash@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c42
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h49
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c5
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h1
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c614
5 files changed, 637 insertions, 74 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 3346357031e..efa0255491c 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -522,7 +522,8 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
522 desc = "Device Status Change"; 522 desc = "Device Status Change";
523 break; 523 break;
524 case MPI2_EVENT_IR_OPERATION_STATUS: 524 case MPI2_EVENT_IR_OPERATION_STATUS:
525 desc = "IR Operation Status"; 525 if (!ioc->hide_ir_msg)
526 desc = "IR Operation Status";
526 break; 527 break;
527 case MPI2_EVENT_SAS_DISCOVERY: 528 case MPI2_EVENT_SAS_DISCOVERY:
528 { 529 {
@@ -553,16 +554,20 @@ _base_display_event_data(struct MPT2SAS_ADAPTER *ioc,
553 desc = "SAS Enclosure Device Status Change"; 554 desc = "SAS Enclosure Device Status Change";
554 break; 555 break;
555 case MPI2_EVENT_IR_VOLUME: 556 case MPI2_EVENT_IR_VOLUME:
556 desc = "IR Volume"; 557 if (!ioc->hide_ir_msg)
558 desc = "IR Volume";
557 break; 559 break;
558 case MPI2_EVENT_IR_PHYSICAL_DISK: 560 case MPI2_EVENT_IR_PHYSICAL_DISK:
559 desc = "IR Physical Disk"; 561 if (!ioc->hide_ir_msg)
562 desc = "IR Physical Disk";
560 break; 563 break;
561 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 564 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
562 desc = "IR Configuration Change List"; 565 if (!ioc->hide_ir_msg)
566 desc = "IR Configuration Change List";
563 break; 567 break;
564 case MPI2_EVENT_LOG_ENTRY_ADDED: 568 case MPI2_EVENT_LOG_ENTRY_ADDED:
565 desc = "Log Entry Added"; 569 if (!ioc->hide_ir_msg)
570 desc = "Log Entry Added";
566 break; 571 break;
567 } 572 }
568 573
@@ -616,7 +621,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
616 originator_str = "PL"; 621 originator_str = "PL";
617 break; 622 break;
618 case 2: 623 case 2:
619 originator_str = "IR"; 624 if (!ioc->hide_ir_msg)
625 originator_str = "IR";
626 else
627 originator_str = "WarpDrive";
620 break; 628 break;
621 } 629 }
622 630
@@ -1508,6 +1516,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1508 } 1516 }
1509 ioc->scsi_lookup[i].cb_idx = 0xFF; 1517 ioc->scsi_lookup[i].cb_idx = 0xFF;
1510 ioc->scsi_lookup[i].scmd = NULL; 1518 ioc->scsi_lookup[i].scmd = NULL;
1519 ioc->scsi_lookup[i].direct_io = 0;
1511 list_add_tail(&ioc->scsi_lookup[i].tracker_list, 1520 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
1512 &ioc->free_list); 1521 &ioc->free_list);
1513 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 1522 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -1844,10 +1853,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
1844 printk("), "); 1853 printk("), ");
1845 printk("Capabilities=("); 1854 printk("Capabilities=(");
1846 1855
1847 if (ioc->facts.IOCCapabilities & 1856 if (!ioc->hide_ir_msg) {
1848 MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { 1857 if (ioc->facts.IOCCapabilities &
1849 printk("Raid"); 1858 MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
1850 i++; 1859 printk("Raid");
1860 i++;
1861 }
1851 } 1862 }
1852 1863
1853 if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) { 1864 if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
@@ -3680,6 +3691,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3680 u32 reply_address; 3691 u32 reply_address;
3681 u16 smid; 3692 u16 smid;
3682 struct _tr_list *delayed_tr, *delayed_tr_next; 3693 struct _tr_list *delayed_tr, *delayed_tr_next;
3694 u8 hide_flag;
3683 3695
3684 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, 3696 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3685 __func__)); 3697 __func__));
@@ -3706,6 +3718,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3706 ioc->scsi_lookup[i].cb_idx = 0xFF; 3718 ioc->scsi_lookup[i].cb_idx = 0xFF;
3707 ioc->scsi_lookup[i].smid = smid; 3719 ioc->scsi_lookup[i].smid = smid;
3708 ioc->scsi_lookup[i].scmd = NULL; 3720 ioc->scsi_lookup[i].scmd = NULL;
3721 ioc->scsi_lookup[i].direct_io = 0;
3709 list_add_tail(&ioc->scsi_lookup[i].tracker_list, 3722 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
3710 &ioc->free_list); 3723 &ioc->free_list);
3711 } 3724 }
@@ -3766,6 +3779,15 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3766 if (sleep_flag == CAN_SLEEP) 3779 if (sleep_flag == CAN_SLEEP)
3767 _base_static_config_pages(ioc); 3780 _base_static_config_pages(ioc);
3768 3781
3782 if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) {
3783 if (ioc->manu_pg10.OEMIdentifier == 0x80) {
3784 hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
3785 MFG_PAGE10_HIDE_SSDS_MASK);
3786 if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
3787 ioc->mfg_pg10_hide_flag = hide_flag;
3788 }
3789 }
3790
3769 if (ioc->wait_for_port_enable_to_complete) { 3791 if (ioc->wait_for_port_enable_to_complete) {
3770 if (diag_buffer_enable != 0) 3792 if (diag_buffer_enable != 0)
3771 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); 3793 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 500328245f6..2a3c05f6db8 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,11 +69,11 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "08.100.00.00" 72#define MPT2SAS_DRIVER_VERSION "08.100.00.01"
73#define MPT2SAS_MAJOR_VERSION 08 73#define MPT2SAS_MAJOR_VERSION 08
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 00 75#define MPT2SAS_BUILD_VERSION 00
76#define MPT2SAS_RELEASE_VERSION 00 76#define MPT2SAS_RELEASE_VERSION 01
77 77
78/* 78/*
79 * Set MPT2SAS_SG_DEPTH value based on user input. 79 * Set MPT2SAS_SG_DEPTH value based on user input.
@@ -189,6 +189,16 @@
189#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046 189#define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID 0x0046
190 190
191/* 191/*
192 * WarpDrive Specific Log codes
193 */
194
195#define MPT2_WARPDRIVE_LOGENTRY (0x8002)
196#define MPT2_WARPDRIVE_LC_SSDT (0x41)
197#define MPT2_WARPDRIVE_LC_SSDLW (0x43)
198#define MPT2_WARPDRIVE_LC_SSDLF (0x44)
199#define MPT2_WARPDRIVE_LC_BRMF (0x4D)
200
201/*
192 * per target private data 202 * per target private data
193 */ 203 */
194#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01 204#define MPT_TARGET_FLAGS_RAID_COMPONENT 0x01
@@ -199,6 +209,7 @@
199 * struct MPT2SAS_TARGET - starget private hostdata 209 * struct MPT2SAS_TARGET - starget private hostdata
200 * @starget: starget object 210 * @starget: starget object
201 * @sas_address: target sas address 211 * @sas_address: target sas address
212 * @raid_device: raid_device pointer to access volume data
202 * @handle: device handle 213 * @handle: device handle
203 * @num_luns: number luns 214 * @num_luns: number luns
204 * @flags: MPT_TARGET_FLAGS_XXX flags 215 * @flags: MPT_TARGET_FLAGS_XXX flags
@@ -208,6 +219,7 @@
208struct MPT2SAS_TARGET { 219struct MPT2SAS_TARGET {
209 struct scsi_target *starget; 220 struct scsi_target *starget;
210 u64 sas_address; 221 u64 sas_address;
222 struct _raid_device *raid_device;
211 u16 handle; 223 u16 handle;
212 int num_luns; 224 int num_luns;
213 u32 flags; 225 u32 flags;
@@ -215,6 +227,7 @@ struct MPT2SAS_TARGET {
215 u8 tm_busy; 227 u8 tm_busy;
216}; 228};
217 229
230
218/* 231/*
219 * per device private data 232 * per device private data
220 */ 233 */
@@ -262,6 +275,12 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_10 {
262 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10, 275 MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10,
263 Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t; 276 Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t;
264 277
278#define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003)
279#define MFG_PAGE10_HIDE_ALL_DISKS (0x00)
280#define MFG_PAGE10_EXPOSE_ALL_DISKS (0x01)
281#define MFG_PAGE10_HIDE_IF_VOL_PRESENT (0x02)
282
283
265struct MPT2SAS_DEVICE { 284struct MPT2SAS_DEVICE {
266 struct MPT2SAS_TARGET *sas_target; 285 struct MPT2SAS_TARGET *sas_target;
267 unsigned int lun; 286 unsigned int lun;
@@ -341,6 +360,7 @@ struct _sas_device {
341 * @sdev: scsi device struct (volumes are single lun) 360 * @sdev: scsi device struct (volumes are single lun)
342 * @wwid: unique identifier for the volume 361 * @wwid: unique identifier for the volume
343 * @handle: device handle 362 * @handle: device handle
363 * @block_size: Block size of the volume
344 * @id: target id 364 * @id: target id
345 * @channel: target channel 365 * @channel: target channel
346 * @volume_type: the raid level 366 * @volume_type: the raid level
@@ -348,20 +368,33 @@ struct _sas_device {
348 * @num_pds: number of hidden raid components 368 * @num_pds: number of hidden raid components
349 * @responding: used in _scsih_raid_device_mark_responding 369 * @responding: used in _scsih_raid_device_mark_responding
350 * @percent_complete: resync percent complete 370 * @percent_complete: resync percent complete
371 * @direct_io_enabled: Whether direct io to PDs are allowed or not
372 * @stripe_exponent: X where 2powX is the stripe sz in blocks
373 * @max_lba: Maximum number of LBA in the volume
374 * @stripe_sz: Stripe Size of the volume
375 * @device_info: Device info of the volume member disk
376 * @pd_handle: Array of handles of the physical drives for direct I/O in le16
351 */ 377 */
378#define MPT_MAX_WARPDRIVE_PDS 8
352struct _raid_device { 379struct _raid_device {
353 struct list_head list; 380 struct list_head list;
354 struct scsi_target *starget; 381 struct scsi_target *starget;
355 struct scsi_device *sdev; 382 struct scsi_device *sdev;
356 u64 wwid; 383 u64 wwid;
357 u16 handle; 384 u16 handle;
385 u16 block_sz;
358 int id; 386 int id;
359 int channel; 387 int channel;
360 u8 volume_type; 388 u8 volume_type;
361 u32 device_info;
362 u8 num_pds; 389 u8 num_pds;
363 u8 responding; 390 u8 responding;
364 u8 percent_complete; 391 u8 percent_complete;
392 u8 direct_io_enabled;
393 u8 stripe_exponent;
394 u64 max_lba;
395 u32 stripe_sz;
396 u32 device_info;
397 u16 pd_handle[MPT_MAX_WARPDRIVE_PDS];
365}; 398};
366 399
367/** 400/**
@@ -470,6 +503,7 @@ struct chain_tracker {
470 * @smid: system message id 503 * @smid: system message id
471 * @scmd: scsi request pointer 504 * @scmd: scsi request pointer
472 * @cb_idx: callback index 505 * @cb_idx: callback index
506 * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
473 * @chain_list: list of chains associated to this IO 507 * @chain_list: list of chains associated to this IO
474 * @tracker_list: list of free request (ioc->free_list) 508 * @tracker_list: list of free request (ioc->free_list)
475 */ 509 */
@@ -477,14 +511,14 @@ struct scsiio_tracker {
477 u16 smid; 511 u16 smid;
478 struct scsi_cmnd *scmd; 512 struct scsi_cmnd *scmd;
479 u8 cb_idx; 513 u8 cb_idx;
514 u8 direct_io;
480 struct list_head chain_list; 515 struct list_head chain_list;
481 struct list_head tracker_list; 516 struct list_head tracker_list;
482}; 517};
483 518
484/** 519/**
485 * struct request_tracker - misc mf request tracker 520 * struct request_tracker - firmware request tracker
486 * @smid: system message id 521 * @smid: system message id
487 * @scmd: scsi request pointer
488 * @cb_idx: callback index 522 * @cb_idx: callback index
489 * @tracker_list: list of free request (ioc->free_list) 523 * @tracker_list: list of free request (ioc->free_list)
490 */ 524 */
@@ -832,6 +866,11 @@ struct MPT2SAS_ADAPTER {
832 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; 866 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
833 u32 ring_buffer_offset; 867 u32 ring_buffer_offset;
834 u32 ring_buffer_sz; 868 u32 ring_buffer_sz;
869 u8 is_warpdrive;
870 u8 hide_ir_msg;
871 u8 mfg_pg10_hide_flag;
872 u8 hide_drives;
873
835}; 874};
836 875
837typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 876typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 1c6d2b405ee..2661e4fe935 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -1034,7 +1034,10 @@ _ctl_getiocinfo(void __user *arg)
1034 __func__)); 1034 __func__));
1035 1035
1036 memset(&karg, 0 , sizeof(karg)); 1036 memset(&karg, 0 , sizeof(karg));
1037 karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; 1037 if (ioc->is_warpdrive)
1038 karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;
1039 else
1040 karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
1038 if (ioc->pfacts) 1041 if (ioc->pfacts)
1039 karg.port_number = ioc->pfacts[0].PortNumber; 1042 karg.port_number = ioc->pfacts[0].PortNumber;
1040 pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); 1043 pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 69916e46e04..11ff1d5fb8f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -133,6 +133,7 @@ struct mpt2_ioctl_pci_info {
133#define MPT2_IOCTL_INTERFACE_FC_IP (0x02) 133#define MPT2_IOCTL_INTERFACE_FC_IP (0x02)
134#define MPT2_IOCTL_INTERFACE_SAS (0x03) 134#define MPT2_IOCTL_INTERFACE_SAS (0x03)
135#define MPT2_IOCTL_INTERFACE_SAS2 (0x04) 135#define MPT2_IOCTL_INTERFACE_SAS2 (0x04)
136#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05)
136#define MPT2_IOCTL_VERSION_LENGTH (32) 137#define MPT2_IOCTL_VERSION_LENGTH (32)
137 138
138/** 139/**
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 33723ed488e..f12e02358d6 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -233,6 +233,9 @@ static struct pci_device_id scsih_pci_table[] = {
233 PCI_ANY_ID, PCI_ANY_ID }, 233 PCI_ANY_ID, PCI_ANY_ID },
234 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, 234 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
235 PCI_ANY_ID, PCI_ANY_ID }, 235 PCI_ANY_ID, PCI_ANY_ID },
236 /* SSS6200 */
237 { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
238 PCI_ANY_ID, PCI_ANY_ID },
236 {0} /* Terminating entry */ 239 {0} /* Terminating entry */
237}; 240};
238MODULE_DEVICE_TABLE(pci, scsih_pci_table); 241MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -1256,6 +1259,7 @@ _scsih_target_alloc(struct scsi_target *starget)
1256 sas_target_priv_data->handle = raid_device->handle; 1259 sas_target_priv_data->handle = raid_device->handle;
1257 sas_target_priv_data->sas_address = raid_device->wwid; 1260 sas_target_priv_data->sas_address = raid_device->wwid;
1258 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; 1261 sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
1262 sas_target_priv_data->raid_device = raid_device;
1259 raid_device->starget = starget; 1263 raid_device->starget = starget;
1260 } 1264 }
1261 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1265 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
@@ -1455,7 +1459,10 @@ static int
1455_scsih_is_raid(struct device *dev) 1459_scsih_is_raid(struct device *dev)
1456{ 1460{
1457 struct scsi_device *sdev = to_scsi_device(dev); 1461 struct scsi_device *sdev = to_scsi_device(dev);
1462 struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
1458 1463
1464 if (ioc->is_warpdrive)
1465 return 0;
1459 return (sdev->channel == RAID_CHANNEL) ? 1 : 0; 1466 return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
1460} 1467}
1461 1468
@@ -1480,7 +1487,7 @@ _scsih_get_resync(struct device *dev)
1480 sdev->channel); 1487 sdev->channel);
1481 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1488 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1482 1489
1483 if (!raid_device) 1490 if (!raid_device || ioc->is_warpdrive)
1484 goto out; 1491 goto out;
1485 1492
1486 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0, 1493 if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
@@ -1640,6 +1647,212 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
1640 1647
1641 kfree(vol_pg0); 1648 kfree(vol_pg0);
1642} 1649}
1650/**
1651 * _scsih_disable_ddio - Disable direct I/O for all the volumes
1652 * @ioc: per adapter object
1653 */
1654static void
1655_scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc)
1656{
1657 Mpi2RaidVolPage1_t vol_pg1;
1658 Mpi2ConfigReply_t mpi_reply;
1659 struct _raid_device *raid_device;
1660 u16 handle;
1661 u16 ioc_status;
1662
1663 handle = 0xFFFF;
1664 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1665 &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
1666 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1667 MPI2_IOCSTATUS_MASK;
1668 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
1669 break;
1670 handle = le16_to_cpu(vol_pg1.DevHandle);
1671 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
1672 if (raid_device)
1673 raid_device->direct_io_enabled = 0;
1674 }
1675 return;
1676}
1677
1678
1679/**
1680 * _scsih_get_num_volumes - Get number of volumes in the ioc
1681 * @ioc: per adapter object
1682 */
1683static u8
1684_scsih_get_num_volumes(struct MPT2SAS_ADAPTER *ioc)
1685{
1686 Mpi2RaidVolPage1_t vol_pg1;
1687 Mpi2ConfigReply_t mpi_reply;
1688 u16 handle;
1689 u8 vol_cnt = 0;
1690 u16 ioc_status;
1691
1692 handle = 0xFFFF;
1693 while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
1694 &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
1695 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1696 MPI2_IOCSTATUS_MASK;
1697 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
1698 break;
1699 vol_cnt++;
1700 handle = le16_to_cpu(vol_pg1.DevHandle);
1701 }
1702 return vol_cnt;
1703}
1704
1705
1706/**
1707 * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O.
1708 * @ioc: per adapter object
1709 * @raid_device: the raid_device object
1710 */
1711static void
1712_scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
1713 struct _raid_device *raid_device)
1714{
1715 Mpi2RaidVolPage0_t *vol_pg0;
1716 Mpi2RaidPhysDiskPage0_t pd_pg0;
1717 Mpi2ConfigReply_t mpi_reply;
1718 u16 sz;
1719 u8 num_pds, count;
1720 u64 mb = 1024 * 1024;
1721 u64 tb_2 = 2 * mb * mb;
1722 u64 capacity;
1723 u32 stripe_sz;
1724 u8 i, stripe_exp;
1725
1726 if (!ioc->is_warpdrive)
1727 return;
1728
1729 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS) {
1730 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1731 "globally as drives are exposed\n", ioc->name);
1732 return;
1733 }
1734 if (_scsih_get_num_volumes(ioc) > 1) {
1735 _scsih_disable_ddio(ioc);
1736 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1737 "globally as number of drives > 1\n", ioc->name);
1738 return;
1739 }
1740 if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
1741 &num_pds)) || !num_pds) {
1742 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1743 "Failure in computing number of drives\n", ioc->name);
1744 return;
1745 }
1746
1747 sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
1748 sizeof(Mpi2RaidVol0PhysDisk_t));
1749 vol_pg0 = kzalloc(sz, GFP_KERNEL);
1750 if (!vol_pg0) {
1751 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1752 "Memory allocation failure for RVPG0\n", ioc->name);
1753 return;
1754 }
1755
1756 if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
1757 MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
1758 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1759 "Failure in retrieving RVPG0\n", ioc->name);
1760 kfree(vol_pg0);
1761 return;
1762 }
1763
1764 /*
1765 * WARPDRIVE:If number of physical disks in a volume exceeds the max pds
1766 * assumed for WARPDRIVE, disable direct I/O
1767 */
1768 if (num_pds > MPT_MAX_WARPDRIVE_PDS) {
1769 printk(MPT2SAS_WARN_FMT "WarpDrive : Direct IO is disabled "
1770 "for the drive with handle(0x%04x): num_mem=%d, "
1771 "max_mem_allowed=%d\n", ioc->name, raid_device->handle,
1772 num_pds, MPT_MAX_WARPDRIVE_PDS);
1773 kfree(vol_pg0);
1774 return;
1775 }
1776 for (count = 0; count < num_pds; count++) {
1777 if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
1778 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
1779 vol_pg0->PhysDisk[count].PhysDiskNum) ||
1780 pd_pg0.DevHandle == MPT2SAS_INVALID_DEVICE_HANDLE) {
1781 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
1782 "disabled for the drive with handle(0x%04x) member"
1783 "handle retrieval failed for member number=%d\n",
1784 ioc->name, raid_device->handle,
1785 vol_pg0->PhysDisk[count].PhysDiskNum);
1786 goto out_error;
1787 }
1788 raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
1789 }
1790
1791 /*
1792 * Assumption for WD: Direct I/O is not supported if the volume is
1793 * not RAID0, if the stripe size is not 64KB, if the block size is
1794 * not 512 and if the volume size is >2TB
1795 */
1796 if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 ||
1797 le16_to_cpu(vol_pg0->BlockSize) != 512) {
1798 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1799 "for the drive with handle(0x%04x): type=%d, "
1800 "s_sz=%uK, blk_size=%u\n", ioc->name,
1801 raid_device->handle, raid_device->volume_type,
1802 le32_to_cpu(vol_pg0->StripeSize)/2,
1803 le16_to_cpu(vol_pg0->BlockSize));
1804 goto out_error;
1805 }
1806
1807 capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) *
1808 (le64_to_cpu(vol_pg0->MaxLBA) + 1);
1809
1810 if (capacity > tb_2) {
1811 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1812 "for the drive with handle(0x%04x) since drive sz > 2TB\n",
1813 ioc->name, raid_device->handle);
1814 goto out_error;
1815 }
1816
1817 stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
1818 stripe_exp = 0;
1819 for (i = 0; i < 32; i++) {
1820 if (stripe_sz & 1)
1821 break;
1822 stripe_exp++;
1823 stripe_sz >>= 1;
1824 }
1825 if (i == 32) {
1826 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1827 "for the drive with handle(0x%04x) invalid stripe sz %uK\n",
1828 ioc->name, raid_device->handle,
1829 le32_to_cpu(vol_pg0->StripeSize)/2);
1830 goto out_error;
1831 }
1832 raid_device->stripe_exponent = stripe_exp;
1833 raid_device->direct_io_enabled = 1;
1834
1835 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive"
1836 " with handle(0x%04x)\n", ioc->name, raid_device->handle);
1837 /*
1838 * WARPDRIVE: Though the following fields are not used for direct IO,
1839 * stored for future purpose:
1840 */
1841 raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
1842 raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
1843 raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);
1844
1845
1846 kfree(vol_pg0);
1847 return;
1848
1849out_error:
1850 raid_device->direct_io_enabled = 0;
1851 for (count = 0; count < num_pds; count++)
1852 raid_device->pd_handle[count] = 0;
1853 kfree(vol_pg0);
1854 return;
1855}
1643 1856
1644/** 1857/**
1645 * _scsih_enable_tlr - setting TLR flags 1858 * _scsih_enable_tlr - setting TLR flags
@@ -1710,6 +1923,11 @@ _scsih_slave_configure(struct scsi_device *sdev)
1710 1923
1711 _scsih_get_volume_capabilities(ioc, raid_device); 1924 _scsih_get_volume_capabilities(ioc, raid_device);
1712 1925
1926 /*
1927 * WARPDRIVE: Initialize the required data for Direct IO
1928 */
1929 _scsih_init_warpdrive_properties(ioc, raid_device);
1930
1713 /* RAID Queue Depth Support 1931 /* RAID Queue Depth Support
1714 * IS volume = underlying qdepth of drive type, either 1932 * IS volume = underlying qdepth of drive type, either
1715 * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH 1933 * MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH
@@ -1757,14 +1975,16 @@ _scsih_slave_configure(struct scsi_device *sdev)
1757 break; 1975 break;
1758 } 1976 }
1759 1977
1760 sdev_printk(KERN_INFO, sdev, "%s: " 1978 if (!ioc->hide_ir_msg)
1761 "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n", 1979 sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
1762 r_level, raid_device->handle, 1980 "wwid(0x%016llx), pd_count(%d), type(%s)\n",
1763 (unsigned long long)raid_device->wwid, 1981 r_level, raid_device->handle,
1764 raid_device->num_pds, ds); 1982 (unsigned long long)raid_device->wwid,
1983 raid_device->num_pds, ds);
1765 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); 1984 _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
1766 /* raid transport support */ 1985 /* raid transport support */
1767 _scsih_set_level(sdev, raid_device); 1986 if (!ioc->is_warpdrive)
1987 _scsih_set_level(sdev, raid_device);
1768 return 0; 1988 return 0;
1769 } 1989 }
1770 1990
@@ -2181,16 +2401,20 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd)
2181 struct MPT2SAS_TARGET *priv_target = starget->hostdata; 2401 struct MPT2SAS_TARGET *priv_target = starget->hostdata;
2182 struct _sas_device *sas_device = NULL; 2402 struct _sas_device *sas_device = NULL;
2183 unsigned long flags; 2403 unsigned long flags;
2404 char *device_str = NULL;
2184 2405
2185 if (!priv_target) 2406 if (!priv_target)
2186 return; 2407 return;
2408 if (ioc->hide_ir_msg)
2409 device_str = "WarpDrive";
2410 else
2411 device_str = "volume";
2187 2412
2188 scsi_print_command(scmd); 2413 scsi_print_command(scmd);
2189 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { 2414 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
2190 starget_printk(KERN_INFO, starget, "volume handle(0x%04x), " 2415 starget_printk(KERN_INFO, starget, "%s handle(0x%04x), "
2191 "volume wwid(0x%016llx)\n", 2416 "%s wwid(0x%016llx)\n", device_str, priv_target->handle,
2192 priv_target->handle, 2417 device_str, (unsigned long long)priv_target->sas_address);
2193 (unsigned long long)priv_target->sas_address);
2194 } else { 2418 } else {
2195 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2419 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2196 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 2420 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,
3129 a = 0; 3353 a = 0;
3130 b = 0; 3354 b = 0;
3131 3355
3356 if (ioc->is_warpdrive)
3357 return;
3358
3132 /* Volume Resets for Deleted or Removed */ 3359 /* Volume Resets for Deleted or Removed */
3133 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0]; 3360 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3134 for (i = 0; i < event_data->NumElements; i++, element++) { 3361 for (i = 0; i < event_data->NumElements; i++, element++) {
@@ -3346,6 +3573,105 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
3346} 3573}
3347 3574
3348/** 3575/**
3576 * _scsih_scsi_direct_io_get - returns direct io flag
3577 * @ioc: per adapter object
3578 * @smid: system request message index
3579 *
3580 * Returns the smid stored scmd pointer.
3581 */
3582static inline u8
3583_scsih_scsi_direct_io_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
3584{
3585 return ioc->scsi_lookup[smid - 1].direct_io;
3586}
3587
3588/**
3589 * _scsih_scsi_direct_io_set - sets direct io flag
3590 * @ioc: per adapter object
3591 * @smid: system request message index
3592 * @direct_io: Zero or non-zero value to set in the direct_io flag
3593 *
3594 * Returns Nothing.
3595 */
3596static inline void
3597_scsih_scsi_direct_io_set(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
3598{
3599 ioc->scsi_lookup[smid - 1].direct_io = direct_io;
3600}
3601
3602
3603/**
3604 * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
3605 * @ioc: per adapter object
3606 * @scmd: pointer to scsi command object
3607 * @raid_device: pointer to raid device data structure
3608 * @mpi_request: pointer to the SCSI_IO reqest message frame
3609 * @smid: system request message index
3610 *
3611 * Returns nothing
3612 */
3613static void
3614_scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3615 struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
3616 u16 smid)
3617{
3618 u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size;
3619 u32 stripe_sz, stripe_exp;
3620 u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2;
3621 u8 cdb0 = scmd->cmnd[0];
3622
3623 /*
3624 * Try Direct I/O to RAID memeber disks
3625 */
3626 if (cdb0 == READ_16 || cdb0 == READ_10 ||
3627 cdb0 == WRITE_16 || cdb0 == WRITE_10) {
3628 cdb_ptr = mpi_request->CDB.CDB32;
3629
3630 if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4]
3631 | cdb_ptr[5])) {
3632 io_size = scsi_bufflen(scmd) >> 9;
3633 /* get virtual lba */
3634 lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] :
3635 &cdb_ptr[6];
3636 tmp_ptr = (u8 *)&v_lba + 3;
3637 *tmp_ptr-- = *lba_ptr1++;
3638 *tmp_ptr-- = *lba_ptr1++;
3639 *tmp_ptr-- = *lba_ptr1++;
3640 *tmp_ptr = *lba_ptr1;
3641
3642 if (((u64)v_lba + (u64)io_size - 1) <=
3643 (u32)raid_device->max_lba) {
3644 stripe_sz = raid_device->stripe_sz;
3645 stripe_exp = raid_device->stripe_exponent;
3646 stripe_off = v_lba & (stripe_sz - 1);
3647
3648 /* Check whether IO falls within a stripe */
3649 if ((stripe_off + io_size) <= stripe_sz) {
3650 num_pds = raid_device->num_pds;
3651 p_lba = v_lba >> stripe_exp;
3652 stripe_unit = p_lba / num_pds;
3653 column = p_lba % num_pds;
3654 p_lba = (stripe_unit << stripe_exp) +
3655 stripe_off;
3656 mpi_request->DevHandle =
3657 cpu_to_le16(raid_device->
3658 pd_handle[column]);
3659 tmp_ptr = (u8 *)&p_lba + 3;
3660 *lba_ptr2++ = *tmp_ptr--;
3661 *lba_ptr2++ = *tmp_ptr--;
3662 *lba_ptr2++ = *tmp_ptr--;
3663 *lba_ptr2 = *tmp_ptr;
3664 /*
3665 * WD: To indicate this I/O is directI/O
3666 */
3667 _scsih_scsi_direct_io_set(ioc, smid, 1);
3668 }
3669 }
3670 }
3671 }
3672}
3673
3674/**
3349 * _scsih_qcmd - main scsi request entry point 3675 * _scsih_qcmd - main scsi request entry point
3350 * @scmd: pointer to scsi command object 3676 * @scmd: pointer to scsi command object
3351 * @done: function pointer to be invoked on completion 3677 * @done: function pointer to be invoked on completion
@@ -3362,6 +3688,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
3362 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); 3688 struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
3363 struct MPT2SAS_DEVICE *sas_device_priv_data; 3689 struct MPT2SAS_DEVICE *sas_device_priv_data;
3364 struct MPT2SAS_TARGET *sas_target_priv_data; 3690 struct MPT2SAS_TARGET *sas_target_priv_data;
3691 struct _raid_device *raid_device;
3365 Mpi2SCSIIORequest_t *mpi_request; 3692 Mpi2SCSIIORequest_t *mpi_request;
3366 u32 mpi_control; 3693 u32 mpi_control;
3367 u16 smid; 3694 u16 smid;
@@ -3423,8 +3750,10 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
3423 3750
3424 } else 3751 } else
3425 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 3752 mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
3426 /* Make sure Device is not raid volume */ 3753 /* Make sure Device is not raid volume.
3427 if (!_scsih_is_raid(&scmd->device->sdev_gendev) && 3754 * We do not expose raid functionality to upper layer for warpdrive.
3755 */
3756 if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
3428 sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32) 3757 sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
3429 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; 3758 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
3430 3759
@@ -3472,9 +3801,14 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
3472 } 3801 }
3473 } 3802 }
3474 3803
3804 raid_device = sas_target_priv_data->raid_device;
3805 if (raid_device && raid_device->direct_io_enabled)
3806 _scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request,
3807 smid);
3808
3475 if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)) 3809 if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST))
3476 mpt2sas_base_put_smid_scsi_io(ioc, smid, 3810 mpt2sas_base_put_smid_scsi_io(ioc, smid,
3477 sas_device_priv_data->sas_target->handle); 3811 le16_to_cpu(mpi_request->DevHandle));
3478 else 3812 else
3479 mpt2sas_base_put_smid_default(ioc, smid); 3813 mpt2sas_base_put_smid_default(ioc, smid);
3480 return 0; 3814 return 0;
@@ -3539,10 +3873,16 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3539 unsigned long flags; 3873 unsigned long flags;
3540 struct scsi_target *starget = scmd->device->sdev_target; 3874 struct scsi_target *starget = scmd->device->sdev_target;
3541 struct MPT2SAS_TARGET *priv_target = starget->hostdata; 3875 struct MPT2SAS_TARGET *priv_target = starget->hostdata;
3876 char *device_str = NULL;
3542 3877
3543 if (!priv_target) 3878 if (!priv_target)
3544 return; 3879 return;
3545 3880
3881 if (ioc->hide_ir_msg)
3882 device_str = "WarpDrive";
3883 else
3884 device_str = "volume";
3885
3546 if (log_info == 0x31170000) 3886 if (log_info == 0x31170000)
3547 return; 3887 return;
3548 3888
@@ -3659,8 +3999,8 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3659 scsi_print_command(scmd); 3999 scsi_print_command(scmd);
3660 4000
3661 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) { 4001 if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
3662 printk(MPT2SAS_WARN_FMT "\tvolume wwid(0x%016llx)\n", ioc->name, 4002 printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
3663 (unsigned long long)priv_target->sas_address); 4003 device_str, (unsigned long long)priv_target->sas_address);
3664 } else { 4004 } else {
3665 spin_lock_irqsave(&ioc->sas_device_lock, flags); 4005 spin_lock_irqsave(&ioc->sas_device_lock, flags);
3666 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 4006 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)
3839 scmd->result = DID_NO_CONNECT << 16; 4179 scmd->result = DID_NO_CONNECT << 16;
3840 goto out; 4180 goto out;
3841 } 4181 }
4182 /*
4183 * WARPDRIVE: If direct_io is set then it is directIO,
4184 * the failed direct I/O should be redirected to volume
4185 */
4186 if (_scsih_scsi_direct_io_get(ioc, smid)) {
4187 _scsih_scsi_direct_io_set(ioc, smid, 0);
4188 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
4189 mpi_request->DevHandle =
4190 cpu_to_le16(sas_device_priv_data->sas_target->handle);
4191 mpt2sas_base_put_smid_scsi_io(ioc, smid,
4192 sas_device_priv_data->sas_target->handle);
4193 return 0;
4194 }
4195
3842 4196
3843 /* turning off TLR */ 4197 /* turning off TLR */
3844 scsi_state = mpi_reply->SCSIState; 4198 scsi_state = mpi_reply->SCSIState;
@@ -3847,7 +4201,10 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
3847 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; 4201 le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
3848 if (!sas_device_priv_data->tlr_snoop_check) { 4202 if (!sas_device_priv_data->tlr_snoop_check) {
3849 sas_device_priv_data->tlr_snoop_check++; 4203 sas_device_priv_data->tlr_snoop_check++;
3850 if (!_scsih_is_raid(&scmd->device->sdev_gendev) && 4204 /* Make sure Device is not raid volume.
4205 * We do not expose raid functionality to upper layer for warpdrive.
4206 */
4207 if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
3851 sas_is_tlr_enabled(scmd->device) && 4208 sas_is_tlr_enabled(scmd->device) &&
3852 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { 4209 response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) {
3853 sas_disable_tlr(scmd->device); 4210 sas_disable_tlr(scmd->device);
@@ -4680,8 +5037,10 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
4680 5037
4681 _scsih_ublock_io_device(ioc, sas_device_backup.handle); 5038 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
4682 5039
4683 mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address, 5040 if (!ioc->hide_drives)
4684 sas_device_backup.sas_address_parent); 5041 mpt2sas_transport_port_remove(ioc,
5042 sas_device_backup.sas_address,
5043 sas_device_backup.sas_address_parent);
4685 5044
4686 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" 5045 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
4687 "(0x%016llx)\n", ioc->name, sas_device_backup.handle, 5046 "(0x%016llx)\n", ioc->name, sas_device_backup.handle,
@@ -5412,6 +5771,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
5412 &sas_device->volume_wwid); 5771 &sas_device->volume_wwid);
5413 set_bit(handle, ioc->pd_handles); 5772 set_bit(handle, ioc->pd_handles);
5414 _scsih_reprobe_target(sas_device->starget, 1); 5773 _scsih_reprobe_target(sas_device->starget, 1);
5774
5415} 5775}
5416 5776
5417/** 5777/**
@@ -5590,7 +5950,8 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
5590 Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data; 5950 Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
5591 5951
5592#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 5952#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5593 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 5953 if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
5954 && !ioc->hide_ir_msg)
5594 _scsih_sas_ir_config_change_event_debug(ioc, event_data); 5955 _scsih_sas_ir_config_change_event_debug(ioc, event_data);
5595 5956
5596#endif 5957#endif
@@ -5613,16 +5974,20 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
5613 le16_to_cpu(element->VolDevHandle)); 5974 le16_to_cpu(element->VolDevHandle));
5614 break; 5975 break;
5615 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 5976 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
5616 _scsih_sas_pd_hide(ioc, element); 5977 if (!ioc->is_warpdrive)
5978 _scsih_sas_pd_hide(ioc, element);
5617 break; 5979 break;
5618 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 5980 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
5619 _scsih_sas_pd_expose(ioc, element); 5981 if (!ioc->is_warpdrive)
5982 _scsih_sas_pd_expose(ioc, element);
5620 break; 5983 break;
5621 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 5984 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
5622 _scsih_sas_pd_add(ioc, element); 5985 if (!ioc->is_warpdrive)
5986 _scsih_sas_pd_add(ioc, element);
5623 break; 5987 break;
5624 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 5988 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
5625 _scsih_sas_pd_delete(ioc, element); 5989 if (!ioc->is_warpdrive)
5990 _scsih_sas_pd_delete(ioc, element);
5626 break; 5991 break;
5627 } 5992 }
5628 } 5993 }
@@ -5653,9 +6018,10 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
5653 6018
5654 handle = le16_to_cpu(event_data->VolDevHandle); 6019 handle = le16_to_cpu(event_data->VolDevHandle);
5655 state = le32_to_cpu(event_data->NewValue); 6020 state = le32_to_cpu(event_data->NewValue);
5656 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " 6021 if (!ioc->hide_ir_msg)
5657 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, 6022 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
5658 le32_to_cpu(event_data->PreviousValue), state)); 6023 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
6024 le32_to_cpu(event_data->PreviousValue), state));
5659 6025
5660 switch (state) { 6026 switch (state) {
5661 case MPI2_RAID_VOL_STATE_MISSING: 6027 case MPI2_RAID_VOL_STATE_MISSING:
@@ -5735,9 +6101,10 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5735 handle = le16_to_cpu(event_data->PhysDiskDevHandle); 6101 handle = le16_to_cpu(event_data->PhysDiskDevHandle);
5736 state = le32_to_cpu(event_data->NewValue); 6102 state = le32_to_cpu(event_data->NewValue);
5737 6103
5738 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), " 6104 if (!ioc->hide_ir_msg)
5739 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, 6105 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
5740 le32_to_cpu(event_data->PreviousValue), state)); 6106 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
6107 le32_to_cpu(event_data->PreviousValue), state));
5741 6108
5742 switch (state) { 6109 switch (state) {
5743 case MPI2_RAID_PD_STATE_ONLINE: 6110 case MPI2_RAID_PD_STATE_ONLINE:
@@ -5746,7 +6113,8 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5746 case MPI2_RAID_PD_STATE_OPTIMAL: 6113 case MPI2_RAID_PD_STATE_OPTIMAL:
5747 case MPI2_RAID_PD_STATE_HOT_SPARE: 6114 case MPI2_RAID_PD_STATE_HOT_SPARE:
5748 6115
5749 set_bit(handle, ioc->pd_handles); 6116 if (!ioc->is_warpdrive)
6117 set_bit(handle, ioc->pd_handles);
5750 6118
5751 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6119 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5752 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 6120 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -5850,7 +6218,8 @@ _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
5850 u16 handle; 6218 u16 handle;
5851 6219
5852#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 6220#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
5853 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 6221 if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
6222 && !ioc->hide_ir_msg)
5854 _scsih_sas_ir_operation_status_event_debug(ioc, 6223 _scsih_sas_ir_operation_status_event_debug(ioc,
5855 event_data); 6224 event_data);
5856#endif 6225#endif
@@ -5909,7 +6278,7 @@ static void
5909_scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 6278_scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5910 u16 slot, u16 handle) 6279 u16 slot, u16 handle)
5911{ 6280{
5912 struct MPT2SAS_TARGET *sas_target_priv_data; 6281 struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
5913 struct scsi_target *starget; 6282 struct scsi_target *starget;
5914 struct _sas_device *sas_device; 6283 struct _sas_device *sas_device;
5915 unsigned long flags; 6284 unsigned long flags;
@@ -5917,7 +6286,7 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5917 spin_lock_irqsave(&ioc->sas_device_lock, flags); 6286 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5918 list_for_each_entry(sas_device, &ioc->sas_device_list, list) { 6287 list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
5919 if (sas_device->sas_address == sas_address && 6288 if (sas_device->sas_address == sas_address &&
5920 sas_device->slot == slot && sas_device->starget) { 6289 sas_device->slot == slot) {
5921 sas_device->responding = 1; 6290 sas_device->responding = 1;
5922 starget = sas_device->starget; 6291 starget = sas_device->starget;
5923 if (starget && starget->hostdata) { 6292 if (starget && starget->hostdata) {
@@ -5926,13 +6295,15 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
5926 sas_target_priv_data->deleted = 0; 6295 sas_target_priv_data->deleted = 0;
5927 } else 6296 } else
5928 sas_target_priv_data = NULL; 6297 sas_target_priv_data = NULL;
5929 starget_printk(KERN_INFO, sas_device->starget, 6298 if (starget)
5930 "handle(0x%04x), sas_addr(0x%016llx), enclosure " 6299 starget_printk(KERN_INFO, starget,
5931 "logical id(0x%016llx), slot(%d)\n", handle, 6300 "handle(0x%04x), sas_addr(0x%016llx), "
5932 (unsigned long long)sas_device->sas_address, 6301 "enclosure logical id(0x%016llx), "
5933 (unsigned long long) 6302 "slot(%d)\n", handle,
5934 sas_device->enclosure_logical_id, 6303 (unsigned long long)sas_device->sas_address,
5935 sas_device->slot); 6304 (unsigned long long)
6305 sas_device->enclosure_logical_id,
6306 sas_device->slot);
5936 if (sas_device->handle == handle) 6307 if (sas_device->handle == handle)
5937 goto out; 6308 goto out;
5938 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 6309 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
@@ -6024,6 +6395,12 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
6024 starget_printk(KERN_INFO, raid_device->starget, 6395 starget_printk(KERN_INFO, raid_device->starget,
6025 "handle(0x%04x), wwid(0x%016llx)\n", handle, 6396 "handle(0x%04x), wwid(0x%016llx)\n", handle,
6026 (unsigned long long)raid_device->wwid); 6397 (unsigned long long)raid_device->wwid);
6398 /*
6399 * WARPDRIVE: The handles of the PDs might have changed
6400 * across the host reset so re-initialize the
6401 * required data for Direct IO
6402 */
6403 _scsih_init_warpdrive_properties(ioc, raid_device);
6027 if (raid_device->handle == handle) 6404 if (raid_device->handle == handle)
6028 goto out; 6405 goto out;
6029 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 6406 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
@@ -6085,18 +6462,20 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6085 } 6462 }
6086 6463
6087 /* refresh the pd_handles */ 6464 /* refresh the pd_handles */
6088 phys_disk_num = 0xFF; 6465 if (!ioc->is_warpdrive) {
6089 memset(ioc->pd_handles, 0, ioc->pd_handles_sz); 6466 phys_disk_num = 0xFF;
6090 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply, 6467 memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
6091 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM, 6468 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
6092 phys_disk_num))) { 6469 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
6093 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 6470 phys_disk_num))) {
6094 MPI2_IOCSTATUS_MASK; 6471 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6095 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 6472 MPI2_IOCSTATUS_MASK;
6096 break; 6473 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
6097 phys_disk_num = pd_pg0.PhysDiskNum; 6474 break;
6098 handle = le16_to_cpu(pd_pg0.DevHandle); 6475 phys_disk_num = pd_pg0.PhysDiskNum;
6099 set_bit(handle, ioc->pd_handles); 6476 handle = le16_to_cpu(pd_pg0.DevHandle);
6477 set_bit(handle, ioc->pd_handles);
6478 }
6100 } 6479 }
6101} 6480}
6102 6481
@@ -6242,6 +6621,50 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6242} 6621}
6243 6622
6244/** 6623/**
6624 * _scsih_hide_unhide_sas_devices - add/remove device to/from OS
6625 * @ioc: per adapter object
6626 *
6627 * Return nothing.
6628 */
6629static void
6630_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6631{
6632 struct _sas_device *sas_device, *sas_device_next;
6633
6634 if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag !=
6635 MFG_PAGE10_HIDE_IF_VOL_PRESENT)
6636 return;
6637
6638 if (ioc->hide_drives) {
6639 if (_scsih_get_num_volumes(ioc))
6640 return;
6641 ioc->hide_drives = 0;
6642 list_for_each_entry_safe(sas_device, sas_device_next,
6643 &ioc->sas_device_list, list) {
6644 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
6645 sas_device->sas_address_parent)) {
6646 _scsih_sas_device_remove(ioc, sas_device);
6647 } else if (!sas_device->starget) {
6648 mpt2sas_transport_port_remove(ioc,
6649 sas_device->sas_address,
6650 sas_device->sas_address_parent);
6651 _scsih_sas_device_remove(ioc, sas_device);
6652 }
6653 }
6654 } else {
6655 if (!_scsih_get_num_volumes(ioc))
6656 return;
6657 ioc->hide_drives = 1;
6658 list_for_each_entry_safe(sas_device, sas_device_next,
6659 &ioc->sas_device_list, list) {
6660 mpt2sas_transport_port_remove(ioc,
6661 sas_device->sas_address,
6662 sas_device->sas_address_parent);
6663 }
6664 }
6665}
6666
6667/**
6245 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih) 6668 * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
6246 * @ioc: per adapter object 6669 * @ioc: per adapter object
6247 * @reset_phase: phase 6670 * @reset_phase: phase
@@ -6325,6 +6748,7 @@ _firmware_event_work(struct work_struct *work)
6325 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, 6748 spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
6326 flags); 6749 flags);
6327 _scsih_remove_unresponding_sas_devices(ioc); 6750 _scsih_remove_unresponding_sas_devices(ioc);
6751 _scsih_hide_unhide_sas_devices(ioc);
6328 return; 6752 return;
6329 } 6753 }
6330 6754
@@ -6424,6 +6848,53 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
6424 (Mpi2EventDataIrVolume_t *) 6848 (Mpi2EventDataIrVolume_t *)
6425 mpi_reply->EventData); 6849 mpi_reply->EventData);
6426 break; 6850 break;
6851 case MPI2_EVENT_LOG_ENTRY_ADDED:
6852 {
6853 Mpi2EventDataLogEntryAdded_t *log_entry;
6854 u32 *log_code;
6855
6856 if (!ioc->is_warpdrive)
6857 break;
6858
6859 log_entry = (Mpi2EventDataLogEntryAdded_t *)
6860 mpi_reply->EventData;
6861 log_code = (u32 *)log_entry->LogData;
6862
6863 if (le16_to_cpu(log_entry->LogEntryQualifier)
6864 != MPT2_WARPDRIVE_LOGENTRY)
6865 break;
6866
6867 switch (le32_to_cpu(*log_code)) {
6868 case MPT2_WARPDRIVE_LC_SSDT:
6869 printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
6870 "IO Throttling has occurred in the WarpDrive "
6871 "subsystem. Check WarpDrive documentation for "
6872 "additional details.\n", ioc->name);
6873 break;
6874 case MPT2_WARPDRIVE_LC_SSDLW:
6875 printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
6876 "Program/Erase Cycles for the WarpDrive subsystem "
6877 "in degraded range. Check WarpDrive documentation "
6878 "for additional details.\n", ioc->name);
6879 break;
6880 case MPT2_WARPDRIVE_LC_SSDLF:
6881 printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
6882 "There are no Program/Erase Cycles for the "
6883 "WarpDrive subsystem. The storage device will be "
6884 "in read-only mode. Check WarpDrive documentation "
6885 "for additional details.\n", ioc->name);
6886 break;
6887 case MPT2_WARPDRIVE_LC_BRMF:
6888 printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
6889 "The Backup Rail Monitor has failed on the "
6890 "WarpDrive subsystem. Check WarpDrive "
6891 "documentation for additional details.\n",
6892 ioc->name);
6893 break;
6894 }
6895
6896 break;
6897 }
6427 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 6898 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
6428 case MPI2_EVENT_IR_OPERATION_STATUS: 6899 case MPI2_EVENT_IR_OPERATION_STATUS:
6429 case MPI2_EVENT_SAS_DISCOVERY: 6900 case MPI2_EVENT_SAS_DISCOVERY:
@@ -6582,7 +7053,8 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
6582 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION; 7053 mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
6583 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; 7054 mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
6584 7055
6585 printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name); 7056 if (!ioc->hide_ir_msg)
7057 printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
6586 init_completion(&ioc->scsih_cmds.done); 7058 init_completion(&ioc->scsih_cmds.done);
6587 mpt2sas_base_put_smid_default(ioc, smid); 7059 mpt2sas_base_put_smid_default(ioc, smid);
6588 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); 7060 wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
@@ -6596,10 +7068,11 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
6596 if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) { 7068 if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
6597 mpi_reply = ioc->scsih_cmds.reply; 7069 mpi_reply = ioc->scsih_cmds.reply;
6598 7070
6599 printk(MPT2SAS_INFO_FMT "IR shutdown (complete): " 7071 if (!ioc->hide_ir_msg)
6600 "ioc_status(0x%04x), loginfo(0x%08x)\n", 7072 printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
6601 ioc->name, le16_to_cpu(mpi_reply->IOCStatus), 7073 "ioc_status(0x%04x), loginfo(0x%08x)\n",
6602 le32_to_cpu(mpi_reply->IOCLogInfo)); 7074 ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
7075 le32_to_cpu(mpi_reply->IOCLogInfo));
6603 } 7076 }
6604 7077
6605 out: 7078 out:
@@ -6758,6 +7231,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
6758 spin_lock_irqsave(&ioc->sas_device_lock, flags); 7231 spin_lock_irqsave(&ioc->sas_device_lock, flags);
6759 list_move_tail(&sas_device->list, &ioc->sas_device_list); 7232 list_move_tail(&sas_device->list, &ioc->sas_device_list);
6760 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 7233 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
7234
7235 if (ioc->hide_drives)
7236 return;
6761 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7237 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
6762 sas_device->sas_address_parent)) { 7238 sas_device->sas_address_parent)) {
6763 _scsih_sas_device_remove(ioc, sas_device); 7239 _scsih_sas_device_remove(ioc, sas_device);
@@ -6811,6 +7287,9 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
6811 list_move_tail(&sas_device->list, &ioc->sas_device_list); 7287 list_move_tail(&sas_device->list, &ioc->sas_device_list);
6812 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 7288 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
6813 7289
7290 if (ioc->hide_drives)
7291 continue;
7292
6814 if (!mpt2sas_transport_port_add(ioc, sas_device->handle, 7293 if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
6815 sas_device->sas_address_parent)) { 7294 sas_device->sas_address_parent)) {
6816 _scsih_sas_device_remove(ioc, sas_device); 7295 _scsih_sas_device_remove(ioc, sas_device);
@@ -6881,6 +7360,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6881 ioc->id = mpt_ids++; 7360 ioc->id = mpt_ids++;
6882 sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); 7361 sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id);
6883 ioc->pdev = pdev; 7362 ioc->pdev = pdev;
7363 if (id->device == MPI2_MFGPAGE_DEVID_SSS6200) {
7364 ioc->is_warpdrive = 1;
7365 ioc->hide_ir_msg = 1;
7366 } else
7367 ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
6884 ioc->scsi_io_cb_idx = scsi_io_cb_idx; 7368 ioc->scsi_io_cb_idx = scsi_io_cb_idx;
6885 ioc->tm_cb_idx = tm_cb_idx; 7369 ioc->tm_cb_idx = tm_cb_idx;
6886 ioc->ctl_cb_idx = ctl_cb_idx; 7370 ioc->ctl_cb_idx = ctl_cb_idx;
@@ -6946,6 +7430,20 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6946 } 7430 }
6947 7431
6948 ioc->wait_for_port_enable_to_complete = 0; 7432 ioc->wait_for_port_enable_to_complete = 0;
7433 if (ioc->is_warpdrive) {
7434 if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
7435 ioc->hide_drives = 0;
7436 else if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_HIDE_ALL_DISKS)
7437 ioc->hide_drives = 1;
7438 else {
7439 if (_scsih_get_num_volumes(ioc))
7440 ioc->hide_drives = 1;
7441 else
7442 ioc->hide_drives = 0;
7443 }
7444 } else
7445 ioc->hide_drives = 0;
7446
6949 _scsih_probe_devices(ioc); 7447 _scsih_probe_devices(ioc);
6950 return 0; 7448 return 0;
6951 7449